aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2013-11-21 14:25:47 +0100
committerMichael Niedermayer <michaelni@gmx.at>2013-11-21 14:40:10 +0100
commit78bfc417d4305f2f30cd21a4eb76cde5988ba77d (patch)
tree3f566c50363670acbacc5e9eeca5534e12f9f315
parentfdc0b3f8c19f854119a70f2b8805fbd9903b0a5f (diff)
parent973b1a6b9070e2bf17d17568cbaf4043ce931f51 (diff)
downloadffmpeg-78bfc417d4305f2f30cd21a4eb76cde5988ba77d.tar.gz
Merge branch 'master' of https://github.com/upsuper/ffmpeg-vdadec
Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--libavcodec/vda_h264_dec.c57
1 files changed, 46 insertions, 11 deletions
diff --git a/libavcodec/vda_h264_dec.c b/libavcodec/vda_h264_dec.c
index 9463f6a6a7..e5fa8071b3 100644
--- a/libavcodec/vda_h264_dec.c
+++ b/libavcodec/vda_h264_dec.c
@@ -56,6 +56,15 @@ typedef struct {
int h264_initialized;
struct vda_context vda_ctx;
enum AVPixelFormat pix_fmt;
+
+ /* for backing-up fields set by user.
+ * we have to gain full control of such fields here */
+ void *hwaccel_context;
+ enum AVPixelFormat (*get_format)(struct AVCodecContext *s, const enum AVPixelFormat * fmt);
+ int (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags);
+#if FF_API_GET_BUFFER
+ int (*get_buffer)(struct AVCodecContext *c, AVFrame *pic);
+#endif
} VDADecoderContext;
static enum AVPixelFormat get_format(struct AVCodecContext *avctx,
@@ -90,6 +99,32 @@ static int get_buffer2(AVCodecContext *avctx, AVFrame *pic, int flag)
return 0;
}
+static inline void set_context(AVCodecContext *avctx)
+{
+ VDADecoderContext *ctx = avctx->priv_data;
+ ctx->hwaccel_context = avctx->hwaccel_context;
+ avctx->hwaccel_context = &ctx->vda_ctx;
+ ctx->get_format = avctx->get_format;
+ avctx->get_format = get_format;
+ ctx->get_buffer2 = avctx->get_buffer2;
+ avctx->get_buffer2 = get_buffer2;
+#if FF_API_GET_BUFFER
+ ctx->get_buffer = avctx->get_buffer;
+ avctx->get_buffer = NULL;
+#endif
+}
+
+static inline void restore_context(AVCodecContext *avctx)
+{
+ VDADecoderContext *ctx = avctx->priv_data;
+ avctx->hwaccel_context = ctx->hwaccel_context;
+ avctx->get_format = ctx->get_format;
+ avctx->get_buffer2 = ctx->get_buffer2;
+#if FF_API_GET_BUFFER
+ avctx->get_buffer = ctx->get_buffer;
+#endif
+}
+
static int vdadec_decode(AVCodecContext *avctx,
void *data, int *got_frame, AVPacket *avpkt)
{
@@ -97,7 +132,9 @@ static int vdadec_decode(AVCodecContext *avctx,
AVFrame *pic = data;
int ret;
+ set_context(avctx);
ret = ff_h264_decoder.decode(avctx, data, got_frame, avpkt);
+ restore_context(avctx);
if (*got_frame) {
AVBufferRef *buffer = pic->buf[0];
VDABufferContext *context = av_buffer_get_opaque(buffer);
@@ -130,8 +167,11 @@ static av_cold int vdadec_close(AVCodecContext *avctx)
/* release buffers and decoder */
ff_vda_destroy_decoder(&ctx->vda_ctx);
/* close H.264 decoder */
- if (ctx->h264_initialized)
+ if (ctx->h264_initialized) {
+ set_context(avctx);
ff_h264_decoder.close(avctx);
+ restore_context(avctx);
+ }
return 0;
}
@@ -184,18 +224,11 @@ static av_cold int vdadec_init(AVCodecContext *avctx)
"Failed to init VDA decoder: %d.\n", status);
goto failed;
}
- avctx->hwaccel_context = vda_ctx;
-
- /* changes callback functions */
- avctx->get_format = get_format;
- avctx->get_buffer2 = get_buffer2;
-#if FF_API_GET_BUFFER
- // force the old get_buffer to be empty
- avctx->get_buffer = NULL;
-#endif
/* init H.264 decoder */
+ set_context(avctx);
ret = ff_h264_decoder.init(avctx);
+ restore_context(avctx);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Failed to open H.264 decoder.\n");
goto failed;
@@ -211,7 +244,9 @@ failed:
static void vdadec_flush(AVCodecContext *avctx)
{
- return ff_h264_decoder.flush(avctx);
+ set_context(avctx);
+ ff_h264_decoder.flush(avctx);
+ restore_context(avctx);
}
AVCodec ff_h264_vda_decoder = {