[FFmpeg-devel] [PATCH 1/2] avdevice/decklink_dec: use a custom memory allocator
Dave Rice
dave at dericed.com
Tue Jun 5 18:06:00 EEST 2018
> On Jun 4, 2018, at 4:21 PM, Marton Balint <cus at passwd.hu> wrote:
>
> The default memory allocator is limited in the max number of frames available,
> and therefore caused frame drops if the frames were not freed fast enough.
I’ve been testing this patchset today. Yesterday I was occasionally getting “Decklink input buffer overrun!” errors with this command:
/usr/local/opt/ffmpegdecklink/bin/ffmpeg-dl -v info -nostdin -nostats -t 1980 -f decklink -draw_bars 0 -audio_input embedded -video_input sdi -format_code ntsc -channels 8 -raw_format yuv422p10 -i "UltraStudio Express" -metadata:s:v:0 encoder="FFV1 version 3" -color_primaries smpte170m -color_trc bt709 -colorspace smpte170m -color_range mpeg -metadata creation_time=now -f_strict unofficial -c:v ffv1 -level 3 -g 1 -slices 16 -slicecrc 1 -c:a pcm_s24le -filter_complex "[0:v:0]setfield=bff,setsar=40/27,setdar=4/3; [0:a:0]pan=stereo| c0=c0 | c1=c1[stereo1];[0:a:0]pan=stereo| c0=c2 | c1=c3[stereo2]" -map "[stereo1]" -map "[stereo2]" -f matroska output.mkv -an -f framemd5 output.framemd5
With the patchset applied, I haven’t had that buffer overrun error re-occur.
> Signed-off-by: Marton Balint <cus at passwd.hu>
> ---
> libavdevice/decklink_dec.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 50 insertions(+)
>
> diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp
> index 510637676c..897fca1003 100644
> --- a/libavdevice/decklink_dec.cpp
> +++ b/libavdevice/decklink_dec.cpp
> @@ -21,6 +21,9 @@
> * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> */
>
> +#include <atomic>
> +using std::atomic;
> +
> /* Include internal.h first to avoid conflict between winsock.h (used by
> * DeckLink headers) and winsock2.h (used by libavformat) in MSVC++ builds */
> extern "C" {
> @@ -98,6 +101,44 @@ static VANCLineNumber vanc_line_numbers[] = {
> {bmdModeUnknown, 0, -1, -1, -1}
> };
>
> +class decklink_allocator : public IDeckLinkMemoryAllocator
> +{
> +public:
> + decklink_allocator(): _refs(1) { }
> + virtual ~decklink_allocator() { }
> +
> + // IDeckLinkMemoryAllocator methods
> + virtual HRESULT STDMETHODCALLTYPE AllocateBuffer(unsigned int bufferSize, void* *allocatedBuffer)
> + {
> + void *buf = av_malloc(bufferSize + AV_INPUT_BUFFER_PADDING_SIZE);
> + if (!buf)
> + return E_OUTOFMEMORY;
> + *allocatedBuffer = buf;
> + return S_OK;
> + }
> + virtual HRESULT STDMETHODCALLTYPE ReleaseBuffer(void* buffer)
> + {
> + av_free(buffer);
> + return S_OK;
> + }
> + virtual HRESULT STDMETHODCALLTYPE Commit() { return S_OK; }
> + virtual HRESULT STDMETHODCALLTYPE Decommit() { return S_OK; }
> +
> + // IUnknown methods
> + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv) { return E_NOINTERFACE; }
> + virtual ULONG STDMETHODCALLTYPE AddRef(void) { return ++_refs; }
> + virtual ULONG STDMETHODCALLTYPE Release(void)
> + {
> + int ret = --_refs;
> + if (!ret)
> + delete this;
> + return ret;
> + }
> +
> +private:
> + std::atomic<int> _refs;
> +};
> +
> extern "C" {
> static void decklink_object_free(void *opaque, uint8_t *data)
> {
> @@ -924,6 +965,7 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx)
> {
> struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
> struct decklink_ctx *ctx;
> + class decklink_allocator *allocator;
> AVStream *st;
> HRESULT result;
> char fname[1024];
> @@ -1017,6 +1059,14 @@ av_cold int ff_decklink_read_header(AVFormatContext *avctx)
> ctx->input_callback = new decklink_input_callback(avctx);
> ctx->dli->SetCallback(ctx->input_callback);
>
> + allocator = new decklink_allocator();
> + ret = (ctx->dli->SetVideoInputFrameMemoryAllocator(allocator) == S_OK ? 0 : AVERROR_EXTERNAL);
> + allocator->Release();
> + if (ret < 0) {
> + av_log(avctx, AV_LOG_ERROR, "Cannot set custom memory allocator\n");
> + goto error;
> + }
> +
> if (mode_num == 0 && !cctx->format_code) {
> if (decklink_autodetect(cctx) < 0) {
> av_log(avctx, AV_LOG_ERROR, "Cannot Autodetect input stream or No signal\n");
> --
> 2.16.3
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
More information about the ffmpeg-devel
mailing list