On Wed, 22 Feb 2017 23:46:51 +0100 Marton Balint <c...@passwd.hu> wrote:
> Signed-off-by: Marton Balint <c...@passwd.hu> > --- > libavdevice/decklink_enc.cpp | 78 > +++++++++++++++++++++----------------------- > libavdevice/decklink_enc_c.c | 4 +-- > libavdevice/version.h | 4 +-- > 3 files changed, 42 insertions(+), 44 deletions(-) > > diff --git a/libavdevice/decklink_enc.cpp b/libavdevice/decklink_enc.cpp > index 8fb6a9c..8892d19 100644 > --- a/libavdevice/decklink_enc.cpp > +++ b/libavdevice/decklink_enc.cpp > @@ -28,6 +28,7 @@ extern "C" { > #include "libavformat/avformat.h" > #include "libavformat/internal.h" > #include "libavutil/imgutils.h" > +#include "libavutil/atomic.h" > } > > #include "decklink_common.h" > @@ -38,33 +39,43 @@ extern "C" { > class decklink_frame : public IDeckLinkVideoFrame > { > public: > - decklink_frame(struct decklink_ctx *ctx, AVFrame *avframe, long width, > - long height, void *buffer) : > - _ctx(ctx), _avframe(avframe), _width(width), > - _height(height), _buffer(buffer), _refs(0) { } > - > - virtual long STDMETHODCALLTYPE GetWidth (void) { > return _width; } > - virtual long STDMETHODCALLTYPE GetHeight (void) { > return _height; } > - virtual long STDMETHODCALLTYPE GetRowBytes (void) { > return _width<<1; } > + decklink_frame(struct decklink_ctx *ctx, AVFrame *avframe) : > + _ctx(ctx), _avframe(avframe), _refs(1) { } > + > + virtual long STDMETHODCALLTYPE GetWidth (void) { > return _avframe->width; } > + virtual long STDMETHODCALLTYPE GetHeight (void) { > return _avframe->height; } > + virtual long STDMETHODCALLTYPE GetRowBytes (void) { > return _avframe->linesize[0] < 0 ? -_avframe->linesize[0] : > _avframe->linesize[0]; } > virtual BMDPixelFormat STDMETHODCALLTYPE GetPixelFormat(void) { > return bmdFormat8BitYUV; } > - virtual BMDFrameFlags STDMETHODCALLTYPE GetFlags (void) { > return bmdVideoOutputFlagDefault; } > - virtual HRESULT STDMETHODCALLTYPE GetBytes (void **buffer) { > *buffer = _buffer; return S_OK; } > + virtual BMDFrameFlags STDMETHODCALLTYPE GetFlags (void) { > return _avframe->linesize[0] < 0 ? bmdFrameFlagFlipVertical : > bmdFrameFlagDefault; } > + virtual HRESULT STDMETHODCALLTYPE GetBytes (void **buffer) > + { > + if (_avframe->linesize[0] < 0) > + *buffer = (void *)(_avframe->data[0] + _avframe->linesize[0] * > (_avframe->height - 1)); > + else > + *buffer = (void *)(_avframe->data[0]); > + return S_OK; > + } > > virtual HRESULT STDMETHODCALLTYPE GetTimecode (BMDTimecodeFormat > format, IDeckLinkTimecode **timecode) { return S_FALSE; } > virtual HRESULT STDMETHODCALLTYPE > GetAncillaryData(IDeckLinkVideoFrameAncillary **ancillary) { > return S_FALSE; } > > virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID > *ppv) { return E_NOINTERFACE; } > - virtual ULONG STDMETHODCALLTYPE AddRef(void) > { return ++_refs; } > - virtual ULONG STDMETHODCALLTYPE Release(void) > { if (!--_refs) {delete this; return 0;} return _refs; } > + virtual ULONG STDMETHODCALLTYPE AddRef(void) > { return avpriv_atomic_int_add_and_fetch(&_refs, 1); } > + virtual ULONG STDMETHODCALLTYPE Release(void) > + { > + int ret = avpriv_atomic_int_add_and_fetch(&_refs, -1); > + if (!ret) { > + av_frame_free(&_avframe); Wouldn't this normally be in a constructor? OK, probably doesn't matter. > + delete this; > + } > + return ret; > + } > > struct decklink_ctx *_ctx; > AVFrame *_avframe; > > private: > - long _width; > - long _height; > - void *_buffer; > - int _refs; > + volatile int _refs; > }; > > class decklink_output_callback : public IDeckLinkVideoOutputCallback > @@ -76,7 +87,7 @@ public: > struct decklink_ctx *ctx = frame->_ctx; > AVFrame *avframe = frame->_avframe; > > - av_frame_free(&avframe); > + av_frame_unref(avframe); > > sem_post(&ctx->semaphore); > > @@ -209,41 +220,27 @@ static int decklink_write_video_packet(AVFormatContext > *avctx, AVPacket *pkt) > { > struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data; > struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx; > - AVPicture *avpicture = (AVPicture *) pkt->data; > - AVFrame *avframe, *tmp; > + AVFrame *avframe, *tmp = (AVFrame *)pkt->data; > decklink_frame *frame; > buffercount_type buffered; > HRESULT hr; > > - /* HACK while av_uncoded_frame() isn't implemented */ > - int ret; > - > - tmp = av_frame_alloc(); > - if (!tmp) > - return AVERROR(ENOMEM); > - tmp->format = AV_PIX_FMT_UYVY422; > - tmp->width = ctx->bmd_width; > - tmp->height = ctx->bmd_height; > - ret = av_frame_get_buffer(tmp, 32); > - if (ret < 0) { > - av_frame_free(&tmp); > - return ret; > + if (tmp->format != AV_PIX_FMT_UYVY422 || > + tmp->width != ctx->bmd_width || > + tmp->height != ctx->bmd_height) { > + av_log(avctx, AV_LOG_ERROR, "Got a frame with invalid pixel format > or dimension.\n"); > + return AVERROR(EINVAL); > } > - av_image_copy(tmp->data, tmp->linesize, (const uint8_t **) > avpicture->data, > - avpicture->linesize, (AVPixelFormat) tmp->format, > tmp->width, > - tmp->height); > avframe = av_frame_clone(tmp); > - av_frame_free(&tmp); > if (!avframe) { > av_log(avctx, AV_LOG_ERROR, "Could not clone video frame.\n"); > return AVERROR(EIO); > } > - /* end HACK */ > > - frame = new decklink_frame(ctx, avframe, ctx->bmd_width, ctx->bmd_height, > - (void *) avframe->data[0]); > + frame = new decklink_frame(ctx, avframe); > if (!frame) { > av_log(avctx, AV_LOG_ERROR, "Could not create new frame.\n"); > + av_frame_free(&avframe); > return AVERROR(EIO); > } > > @@ -254,10 +251,11 @@ static int decklink_write_video_packet(AVFormatContext > *avctx, AVPacket *pkt) > hr = ctx->dlo->ScheduleVideoFrame((struct IDeckLinkVideoFrame *) frame, > pkt->pts * ctx->bmd_tb_num, > ctx->bmd_tb_num, ctx->bmd_tb_den); > + /* Pass ownership to DeckLink, or release on failure */ > + frame->Release(); > if (hr != S_OK) { > av_log(avctx, AV_LOG_ERROR, "Could not schedule video frame." > " error %08x.\n", (uint32_t) hr); > - frame->Release(); > return AVERROR(EIO); > } > > diff --git a/libavdevice/decklink_enc_c.c b/libavdevice/decklink_enc_c.c > index c3c9018..03734f8 100644 > --- a/libavdevice/decklink_enc_c.c > +++ b/libavdevice/decklink_enc_c.c > @@ -46,9 +46,9 @@ AVOutputFormat ff_decklink_muxer = { > .name = "decklink", > .long_name = NULL_IF_CONFIG_SMALL("Blackmagic DeckLink output"), > .audio_codec = AV_CODEC_ID_PCM_S16LE, > - .video_codec = AV_CODEC_ID_RAWVIDEO, > + .video_codec = AV_CODEC_ID_WRAPPED_AVFRAME, > .subtitle_codec = AV_CODEC_ID_NONE, > - .flags = AVFMT_NOFILE | AVFMT_RAWPICTURE, > + .flags = AVFMT_NOFILE, > .priv_class = &decklink_muxer_class, > .priv_data_size = sizeof(struct decklink_cctx), > .write_header = ff_decklink_write_header, > diff --git a/libavdevice/version.h b/libavdevice/version.h > index ceec2d4..a58cb0e 100644 > --- a/libavdevice/version.h > +++ b/libavdevice/version.h > @@ -28,8 +28,8 @@ > #include "libavutil/version.h" > > #define LIBAVDEVICE_VERSION_MAJOR 57 > -#define LIBAVDEVICE_VERSION_MINOR 2 > -#define LIBAVDEVICE_VERSION_MICRO 101 > +#define LIBAVDEVICE_VERSION_MINOR 3 > +#define LIBAVDEVICE_VERSION_MICRO 100 > > #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \ > LIBAVDEVICE_VERSION_MINOR, \ Can't say much about the rest of the patch, but it looks reasonable. And I really like that it gets rid of the last use of RAWPICTURE. _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel