summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2012-12-22 21:46:53 +0100
committerwm4 <wm4@nowhere>2013-01-13 20:04:10 +0100
commit1f32250629c990859b0f6a7d70bcbe3bd2d6afae (patch)
treebd4b294ace0079f594611c93f0865f2efce7e622 /video
parent1b9d4a771a27d6017d826ed03dfbbc7ee976bf77 (diff)
downloadmpv-1f32250629c990859b0f6a7d70bcbe3bd2d6afae.tar.bz2
mpv-1f32250629c990859b0f6a7d70bcbe3bd2d6afae.tar.xz
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. <wm4> michaelni: couldn't it set buffer hints from AVFrame.reference then? <michaelni> i see no reason ATM why that wouldnt be possible OK...
Diffstat (limited to 'video')
-rw-r--r--video/decode/lavc_dr1.c19
1 files changed, 18 insertions, 1 deletions
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;