aboutsummaryrefslogtreecommitdiffstats
path: root/common/rfb/H264WinDecoderContext.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'common/rfb/H264WinDecoderContext.cxx')
-rw-r--r--common/rfb/H264WinDecoderContext.cxx80
1 files changed, 20 insertions, 60 deletions
diff --git a/common/rfb/H264WinDecoderContext.cxx b/common/rfb/H264WinDecoderContext.cxx
index a9b13942..71086fad 100644
--- a/common/rfb/H264WinDecoderContext.cxx
+++ b/common/rfb/H264WinDecoderContext.cxx
@@ -22,48 +22,38 @@
#include <config.h>
#endif
+#include <stdexcept>
+
#include <mfapi.h>
#include <mferror.h>
#include <wmcodecdsp.h>
#define SAFE_RELEASE(obj) if (obj) { obj->Release(); obj = nullptr; }
-#include <os/Mutex.h>
-#include <rfb/LogWriter.h>
#include <rfb/PixelBuffer.h>
#include <rfb/H264WinDecoderContext.h>
using namespace rfb;
-static LogWriter vlog("H264WinDecoderContext");
-
// Older MinGW lacks this definition
#ifndef HAVE_VIDEO_PROCESSOR_MFT
static GUID CLSID_VideoProcessorMFT = { 0x88753b26, 0x5b24, 0x49bd, { 0xb2, 0xe7, 0xc, 0x44, 0x5c, 0x78, 0xc9, 0x82 } };
#endif
-bool H264WinDecoderContext::initCodec() {
- os::AutoMutex lock(&mutex);
-
+H264WinDecoderContext::H264WinDecoderContext(const core::Rect &r)
+ : H264DecoderContext(r)
+{
if (FAILED(MFStartup(MF_VERSION, MFSTARTUP_LITE)))
- {
- vlog.error("Could not initialize MediaFoundation");
- return false;
- }
+ throw std::runtime_error("Could not initialize MediaFoundation");
if (FAILED(CoCreateInstance(CLSID_CMSH264DecoderMFT, nullptr, CLSCTX_INPROC_SERVER, IID_IMFTransform, (LPVOID*)&decoder)))
- {
- vlog.error("MediaFoundation H264 codec not found");
- return false;
- }
+ throw std::runtime_error("MediaFoundation H264 codec not found");
if (FAILED(CoCreateInstance(CLSID_VideoProcessorMFT, nullptr, CLSCTX_INPROC_SERVER, IID_IMFTransform, (LPVOID*)&converter)))
{
- vlog.error("Cannot create MediaFoundation Video Processor (available only on Windows 8+). Trying ColorConvert DMO.");
if (FAILED(CoCreateInstance(CLSID_CColorConvertDMO, nullptr, CLSCTX_INPROC_SERVER, IID_IMFTransform, (LPVOID*)&converter)))
{
decoder->Release();
- vlog.error("ColorConvert DMO not found");
- return false;
+ throw std::runtime_error("MediaFoundation H264 codec not found");
}
}
@@ -72,10 +62,7 @@ bool H264WinDecoderContext::initCodec() {
if (SUCCEEDED(decoder->GetAttributes(&attributes)))
{
GUID MF_LOW_LATENCY = { 0x9c27891a, 0xed7a, 0x40e1, { 0x88, 0xe8, 0xb2, 0x27, 0x27, 0xa0, 0x24, 0xee } };
- if (SUCCEEDED(attributes->SetUINT32(MF_LOW_LATENCY, TRUE)))
- {
- vlog.info("Enabled low latency mode");
- }
+ attributes->SetUINT32(MF_LOW_LATENCY, TRUE);
attributes->Release();
}
@@ -85,8 +72,7 @@ bool H264WinDecoderContext::initCodec() {
{
decoder->Release();
converter->Release();
- vlog.error("Could not create MF MediaType");
- return false;
+ throw std::runtime_error("Could not create MF MediaType");
}
input_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video);
input_type->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264);
@@ -113,8 +99,7 @@ bool H264WinDecoderContext::initCodec() {
decoder->Release();
converter->Release();
input_type->Release();
- vlog.error("Could not start H264 decoder");
- return false;
+ throw std::runtime_error("Could not start H264 decoder");
}
MFT_OUTPUT_STREAM_INFO info;
@@ -134,22 +119,14 @@ bool H264WinDecoderContext::initCodec() {
SAFE_RELEASE(converted_sample);
SAFE_RELEASE(input_buffer);
SAFE_RELEASE(decoded_buffer);
- vlog.error("Could not allocate media samples/buffers");
- return false;
+ throw std::runtime_error("Could not allocate media samples/buffers");
}
input_sample->AddBuffer(input_buffer);
decoded_sample->AddBuffer(decoded_buffer);
-
- initialized = true;
- return true;
}
-void H264WinDecoderContext::freeCodec() {
- os::AutoMutex lock(&mutex);
-
- if (!initialized)
- return;
+H264WinDecoderContext::~H264WinDecoderContext() {
SAFE_RELEASE(decoder)
SAFE_RELEASE(converter)
SAFE_RELEASE(input_sample)
@@ -159,24 +136,16 @@ void H264WinDecoderContext::freeCodec() {
SAFE_RELEASE(decoded_buffer)
SAFE_RELEASE(converted_buffer)
MFShutdown();
- initialized = false;
}
void H264WinDecoderContext::decode(const uint8_t* h264_buffer,
uint32_t len,
ModifiablePixelBuffer* pb) {
- os::AutoMutex lock(&mutex);
- if (!initialized)
- return;
-
if (FAILED(input_buffer->SetCurrentLength(len)))
{
input_buffer->Release();
if (FAILED(MFCreateMemoryBuffer(len, &input_buffer)))
- {
- vlog.error("Could not allocate media buffer");
- return;
- }
+ throw std::runtime_error("Could not allocate media buffer");
input_buffer->SetCurrentLength(len);
input_sample->RemoveAllBuffers();
input_sample->AddBuffer(input_buffer);
@@ -187,14 +156,12 @@ void H264WinDecoderContext::decode(const uint8_t* h264_buffer,
memcpy(locked, h264_buffer, len);
input_buffer->Unlock();
- vlog.debug("Received %u bytes, decoding", len);
-
// extract actual size, including possible cropping
ParseSPS(h264_buffer, len);
if (FAILED(decoder->ProcessInput(0, input_sample, 0)))
{
- vlog.error("Error sending a packet to decoding");
+ // Silently ignore errors, hoping its a temporary encoding glitch
return;
}
@@ -219,7 +186,6 @@ void H264WinDecoderContext::decode(const uint8_t* h264_buffer,
if (SUCCEEDED(hr))
{
- vlog.debug("Frame decoded");
// successfully decoded next frame
// but do not exit loop, try again if there is next frame
decoded = true;
@@ -259,7 +225,7 @@ void H264WinDecoderContext::decode(const uint8_t* h264_buffer,
UINT32 width, height;
if FAILED(MFGetAttributeSize(output_type, MF_MT_FRAME_SIZE, &width, &height))
{
- vlog.error("Error getting output type size");
+ // Silently ignore errors, hoping its a temporary encoding glitch
output_type->Release();
break;
}
@@ -279,13 +245,11 @@ void H264WinDecoderContext::decode(const uint8_t* h264_buffer,
crop_height = height;
}
- vlog.debug("Setting up decoded output with %ux%u size", crop_width, crop_height);
-
// input type to converter, BGRX pixel format
IMFMediaType* converted_type;
if (FAILED(MFCreateMediaType(&converted_type)))
{
- vlog.error("Error creating media type");
+ // Silently ignore errors, hoping its a temporary encoding glitch
}
else
{
@@ -310,7 +274,7 @@ void H264WinDecoderContext::decode(const uint8_t* h264_buffer,
if (FAILED(MFCreateMemoryBuffer(info.cbSize, &converted_buffer)))
{
- vlog.error("Error creating media buffer");
+ // Silently ignore errors, hoping its a temporary encoding glitch
}
else
{
@@ -327,7 +291,7 @@ void H264WinDecoderContext::decode(const uint8_t* h264_buffer,
{
if (FAILED(converter->ProcessInput(0, decoded_sample, 0)))
{
- vlog.error("Error sending a packet to converter");
+ // Silently ignore errors, hoping its a temporary encoding glitch
return;
}
@@ -343,12 +307,10 @@ void H264WinDecoderContext::decode(const uint8_t* h264_buffer,
if (FAILED(hr))
{
- vlog.error("Error converting to RGB");
+ // Silently ignore errors, hoping its a temporary encoding glitch
}
else
{
- vlog.debug("Frame converted to RGB");
-
BYTE* out;
DWORD buflen;
converted_buffer->Lock(&out, nullptr, &buflen);
@@ -528,8 +490,6 @@ void H264WinDecoderContext::ParseSPS(const uint8_t* buffer, int length)
offset_x = frame_crop_left_offset;
offset_y = frame_crop_bottom_offset;
- vlog.debug("SPS parsing - full=%dx%d, cropped=%dx%d, offset=%d,%d", full_width, full_height, crop_width, crop_height, offset_x, offset_y);
-
#undef SKIP_BITS
#undef SKIP_UE
#undef GET_BITS