summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-04-15 15:07:02 +0200
committerwm4 <wm4@nowhere>2016-04-15 15:07:02 +0200
commitbbaedfd0c5d59a22762c80c96406d5887f8ca488 (patch)
tree1ecfc2a57a46bbdb374a5fe43b3295530d76723d
parent607ba5f235b62ab485b9fd4a1073bca9c1b25263 (diff)
downloadmpv-bbaedfd0c5d59a22762c80c96406d5887f8ca488.tar.bz2
mpv-bbaedfd0c5d59a22762c80c96406d5887f8ca488.tar.xz
mp_image: pass through AVHWFramesContext
In both directions.
-rw-r--r--video/mp_image.c24
-rw-r--r--video/mp_image.h2
2 files changed, 22 insertions, 4 deletions
diff --git a/video/mp_image.c b/video/mp_image.c
index 565de18ca6..0238a102f6 100644
--- a/video/mp_image.c
+++ b/video/mp_image.c
@@ -94,6 +94,7 @@ static void mp_image_destructor(void *ptr)
mp_image_t *mpi = ptr;
for (int p = 0; p < MP_MAX_PLANES; p++)
av_buffer_unref(&mpi->bufs[p]);
+ av_buffer_unref(&mpi->hwctx);
}
int mp_chroma_div_up(int size, int shift)
@@ -174,6 +175,9 @@ void mp_image_steal_data(struct mp_image *dst, struct mp_image *src)
dst->bufs[p] = src->bufs[p];
src->bufs[p] = NULL;
}
+ av_buffer_unref(&dst->hwctx);
+ dst->hwctx = src->hwctx;
+ src->hwctx = NULL;
talloc_free(src);
}
@@ -199,6 +203,11 @@ struct mp_image *mp_image_new_ref(struct mp_image *img)
fail = true;
}
}
+ if (new->hwctx) {
+ new->hwctx = av_buffer_ref(new->hwctx);
+ if (!new->hwctx)
+ fail = true;
+ }
if (!fail)
return new;
@@ -232,6 +241,7 @@ struct mp_image *mp_image_new_dummy_ref(struct mp_image *img)
*new = *img;
for (int p = 0; p < MP_MAX_PLANES; p++)
new->bufs[p] = NULL;
+ new->hwctx = NULL;
return new;
}
@@ -720,6 +730,9 @@ struct mp_image *mp_image_from_av_frame(struct AVFrame *av_frame)
mp_image_copy_fields_from_av_frame(&t, av_frame);
for (int p = 0; p < MP_MAX_PLANES; p++)
t.bufs[p] = av_frame->buf[p];
+#if HAVE_AVUTIL_HAS_HWCONTEXT
+ t.hwctx = av_frame->hw_frames_ctx;
+#endif
return mp_image_new_ref(&t);
}
@@ -730,13 +743,12 @@ struct mp_image *mp_image_from_av_frame(struct AVFrame *av_frame)
// On failure, img is only unreffed.
struct AVFrame *mp_image_to_av_frame_and_unref(struct mp_image *img)
{
- struct mp_image *new_ref = mp_image_new_ref(img); // ensure it's refcounted
+ struct mp_image *new_ref = mp_image_new_ref(img);
talloc_free(img);
- if (!new_ref)
- return NULL;
AVFrame *frame = av_frame_alloc();
- if (!frame) {
+ if (!frame || !new_ref) {
talloc_free(new_ref);
+ av_frame_free(&frame);
return NULL;
}
mp_image_copy_fields_to_av_frame(frame, new_ref);
@@ -744,6 +756,10 @@ struct AVFrame *mp_image_to_av_frame_and_unref(struct mp_image *img)
frame->buf[p] = new_ref->bufs[p];
new_ref->bufs[p] = NULL;
}
+#if HAVE_AVUTIL_HAS_HWCONTEXT
+ frame->hw_frames_ctx = new_ref->hwctx;
+#endif
+ new_ref->hwctx = NULL;
talloc_free(new_ref);
return frame;
}
diff --git a/video/mp_image.h b/video/mp_image.h
index c00c78a459..c96674b290 100644
--- a/video/mp_image.h
+++ b/video/mp_image.h
@@ -100,6 +100,8 @@ typedef struct mp_image {
// All mp_* functions manage this automatically; do not mess with it.
// (See also AVFrame.buf.)
struct AVBufferRef *bufs[MP_MAX_PLANES];
+ // Points to AVHWFramesContext* (same as AVFrame.hw_frames_ctx)
+ struct AVBufferRef *hwctx;
} mp_image_t;
int mp_chroma_div_up(int size, int shift);