To subclass the IDeckLinkVideoFrame, I'm forced to implement all of the pure virtual methods even if I don't know how these are implemented under the covers. Am I really expected to do this? When I try to convert the 10bit yuv frame to an 8bit yuv frame, I get an EXC_BAD_ACCESS error.
I have included code that represents how I subclass the IDeckLinkVideoFrame and how I instantiate and use that new object.
Header file:
- Code: Select all
class MTBM8BitYUVVideoFrame : public IDeckLinkVideoFrame
{
private:
long _width;
long _height;
BMDPixelFormat _pixelFormat;
BMDFrameFlags _frameFlags;
void * _bufferPointer;
public:
MTBM8BitYUVVideoFrame(long width, long height, BMDPixelFormat pixelFormat, BMDFrameFlags flags);
virtual ~MTBM8BitYUVVideoFrame();
//override these methods for virtual
virtual long GetWidth (void);
virtual long GetHeight (void);
virtual long GetRowBytes (void);
virtual BMDPixelFormat GetPixelFormat (void);
virtual BMDFrameFlags GetFlags (void);
virtual HRESULT GetBytes (/* out */ void **buffer);
//Dummy implementations of remaining virtual methods
virtual HRESULT GetTimecode (/* in */ BMDTimecodeFormat format, /* out */ IDeckLinkTimecode **timecode) { return E_NOINTERFACE; };
virtual HRESULT GetAncillaryData (/* out */ IDeckLinkVideoFrameAncillary **ancillary) { return E_NOINTERFACE; } ;
//
// IUnknown interface (dummy implementation)
//
virtual HRESULT QueryInterface (REFIID iid, LPVOID *ppv) {return E_NOINTERFACE;}
virtual ULONG AddRef () {return 1;}
virtual ULONG Release () {return 1;}
};
CPP file
- Code: Select all
MTBM8BitYUVVideoFrame::MTBM8BitYUVVideoFrame(long width, long height, BMDPixelFormat pixelFormat, BMDFrameFlags frameFlags)
{
_width = width;
_height = height;
_pixelFormat = pixelFormat;
_frameFlags = frameFlags;
//this pointer size is only valid for bmdFormat8BitYUV
switch (_pixelFormat) {
case bmdFormat8BitYUV:
_bufferPointer = malloc((_width * 16 / 8) * _height);
break;
default:
break;
}
}
MTBM8BitYUVVideoFrame::~MTBM8BitYUVVideoFrame()
{
free(_bufferPointer);
}
long MTBM8BitYUVVideoFrame::GetWidth()
{
return _width;
}
long MTBM8BitYUVVideoFrame::GetHeight()
{
return _height;
}
long MTBM8BitYUVVideoFrame::GetRowBytes()
{
return (long)(_width * 16 / 8);
}
BMDPixelFormat MTBM8BitYUVVideoFrame::GetPixelFormat()
{
return _pixelFormat;
}
BMDFrameFlags MTBM8BitYUVVideoFrame::GetFlags()
{
return _frameFlags;
}
HRESULT MTBM8BitYUVVideoFrame::GetBytes (/* out */ void **buffer)
{
buffer = &_bufferPointer;
return S_OK;
}
I use this new class as follows
- Code: Select all
MTBM8BitYUVVideoFrame *eightBitVideoFrame = new MTBM8BitYUVVideoFrame(tenBitVideoFrame->GetWidth(),tenBitVideoFrame->GetHeight(),bmdFormat8BitYUV,tenBitVideoFrame->GetFlags());
IDeckLinkVideoConversion *videoConverter = CreateVideoConversionInstance();
HRESULT convertResult = videoConverter->ConvertFrame(tenBitVideoFrame,(IDeckLinkVideoFrame*)eightBitVideoFrame);