From patchwork Wed Feb 22 22:46:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marton Balint X-Patchwork-Id: 2651 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.65.149 with SMTP id x21csp1098675vsf; Wed, 22 Feb 2017 14:47:24 -0800 (PST) X-Received: by 10.223.166.38 with SMTP id k35mr20710138wrc.134.1487803644037; Wed, 22 Feb 2017 14:47:24 -0800 (PST) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id 8si3450892wrt.162.2017.02.22.14.47.23; Wed, 22 Feb 2017 14:47:24 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 4EB38688319; Thu, 23 Feb 2017 00:47:02 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from iq.passwd.hu (iq.passwd.hu [217.27.212.140]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 513786882E5 for ; Thu, 23 Feb 2017 00:46:56 +0200 (EET) Received: from localhost (localhost [127.0.0.1]) by iq.passwd.hu (Postfix) with ESMTP id 58F38102D5C; Wed, 22 Feb 2017 23:47:04 +0100 (CET) X-Virus-Scanned: amavisd-new at passwd.hu Received: from iq.passwd.hu ([127.0.0.1]) by localhost (iq.passwd.hu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id bU6K32irKIFR; Wed, 22 Feb 2017 23:47:03 +0100 (CET) Received: from bluegene.passwd.hu (localhost [127.0.0.1]) by iq.passwd.hu (Postfix) with ESMTP id DE543100B4A; Wed, 22 Feb 2017 23:47:02 +0100 (CET) From: Marton Balint To: ffmpeg-devel@ffmpeg.org Date: Wed, 22 Feb 2017 23:46:51 +0100 Message-Id: <20170222224652.4505-3-cus@passwd.hu> X-Mailer: git-send-email 2.10.2 In-Reply-To: <20170222224652.4505-1-cus@passwd.hu> References: <20170222224652.4505-1-cus@passwd.hu> Subject: [FFmpeg-devel] [PATCH 3/4] avdevice/decklink_enc: convert AVFMT_RAWPICTURE to AV_CODEC_ID_WRAPPED_AVFRAME X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Marton Balint MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: Marton Balint --- 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); + 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, \