From 1f32250629c990859b0f6a7d70bcbe3bd2d6afae Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 22 Dec 2012 21:46:53 +0100 Subject: vd_lavc: make non-reference frames writeable This allows avoiding a copy. The logic about using the AVFrame.reference field if buffer hints are not available is similar to mplayer-svn's direct rendering code. This is needed because h264 decoding doesn't set buffer hints. michaelni: couldn't it set buffer hints from AVFrame.reference then? i see no reason ATM why that wouldnt be possible OK... --- video/decode/lavc_dr1.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'video') diff --git a/video/decode/lavc_dr1.c b/video/decode/lavc_dr1.c index 34aad2e030..e81b723a70 100644 --- a/video/decode/lavc_dr1.c +++ b/video/decode/lavc_dr1.c @@ -48,6 +48,7 @@ typedef struct FrameBuffer { int h, w; int pix_fmt; + int used_by_decoder, needed_by_decoder; int refcount; struct FramePool *pool; struct FrameBuffer *next; @@ -155,6 +156,15 @@ int mp_codec_get_buffer(AVCodecContext *s, AVFrame *frame) frame->type = FF_BUFFER_TYPE_USER; frame->extended_data = frame->data; + buf->used_by_decoder = buf->needed_by_decoder = 1; + if (frame->buffer_hints & FF_BUFFER_HINTS_VALID) { + buf->needed_by_decoder = + (frame->buffer_hints & FF_BUFFER_HINTS_PRESERVE) || + (frame->buffer_hints & FF_BUFFER_HINTS_REUSABLE); + } else { + buf->needed_by_decoder = !!frame->reference; + } + for (i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) { frame->base[i] = buf->base[i]; // XXX h264.c uses base though it shouldn't frame->data[i] = buf->data[i]; @@ -192,7 +202,12 @@ void mp_buffer_unref(struct FrameBuffer *buf) bool mp_buffer_is_unique(struct FrameBuffer *buf) { - return buf->refcount == 1; + int refcount = buf->refcount; + // Decoder has a reference, but doesn't want to use it. (ffmpeg has no good + // way of transferring frame ownership to the user.) + if (buf->used_by_decoder && !buf->needed_by_decoder) + refcount--; + return refcount == 1; } void mp_codec_release_buffer(AVCodecContext *s, AVFrame *frame) @@ -205,6 +220,8 @@ void mp_codec_release_buffer(AVCodecContext *s, AVFrame *frame) return; } + buf->used_by_decoder = buf->needed_by_decoder = 0; + for (i = 0; i < FF_ARRAY_ELEMS(frame->data); i++) frame->data[i] = NULL; -- cgit v1.2.3