summaryrefslogtreecommitdiffstats
path: root/video/decode/vd_lavc.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-09-22 22:47:15 +0200
committerwm4 <wm4@nowhere>2013-09-25 13:53:42 +0200
commit7c3f1ffc44b532590e661315b42fea5b6d1ae40c (patch)
tree30f96bfb61b5cd46d36cae0480de58bb7de8b8b5 /video/decode/vd_lavc.c
parent39d1ab82e5a3ac30e5495c6b6773823c2ff56594 (diff)
downloadmpv-7c3f1ffc44b532590e661315b42fea5b6d1ae40c.tar.bz2
mpv-7c3f1ffc44b532590e661315b42fea5b6d1ae40c.tar.xz
vd_lavc: allow process_image to change image format
This will allow GPU read-back with process_image. We have to restructure how init_vo() works. Instead of initializing the VO before process_image is called, rename init_vo() to update_image_params(), and let it update the params only. Then we really initialize the VO after process_image. As a consequence of these changes, already decoded hw frames are correctly unreferenced if creation of the filter chain fails. This could trigger assertions on VO uninitialization, because it's not allowed to reference hw frames past VO lifetime.
Diffstat (limited to 'video/decode/vd_lavc.c')
-rw-r--r--video/decode/vd_lavc.c37
1 files changed, 20 insertions, 17 deletions
diff --git a/video/decode/vd_lavc.c b/video/decode/vd_lavc.c
index 1838582d04..c658d92a35 100644
--- a/video/decode/vd_lavc.c
+++ b/video/decode/vd_lavc.c
@@ -344,7 +344,8 @@ static void init_avctx(sh_video_t *sh, const char *decoder,
ctx->do_dr1 = ctx->do_hw_dr1 = 0;
ctx->pix_fmt = PIX_FMT_NONE;
- ctx->vo_initialized = 0;
+ ctx->image_params = (struct mp_image_params){0};
+ ctx->vo_image_params = (struct mp_image_params){0};
ctx->hwdec = hwdec;
ctx->pic = avcodec_alloc_frame();
ctx->avctx = avcodec_alloc_context3(lavc_codec);
@@ -465,7 +466,7 @@ static void uninit(sh_video_t *sh)
talloc_free(ctx);
}
-static int init_vo(sh_video_t *sh, AVFrame *frame)
+static void update_image_params(sh_video_t *sh, AVFrame *frame)
{
vd_ffmpeg_ctx *ctx = sh->context;
int width = frame->width;
@@ -479,10 +480,9 @@ static int init_vo(sh_video_t *sh, AVFrame *frame)
if (av_cmp_q(frame->sample_aspect_ratio, ctx->last_sample_aspect_ratio) ||
width != sh->disp_w || height != sh->disp_h ||
- pix_fmt != ctx->pix_fmt || !ctx->vo_initialized)
+ pix_fmt != ctx->pix_fmt || !ctx->image_params.imgfmt)
{
mp_image_pool_clear(ctx->non_dr1_pool);
- ctx->vo_initialized = 0;
mp_msg(MSGT_DECVIDEO, MSGL_V, "[ffmpeg] aspect_ratio: %f\n", aspect);
// Do not overwrite s->aspect on the first call, so that a container
@@ -512,13 +512,7 @@ static int init_vo(sh_video_t *sh, AVFrame *frame)
.chroma_location =
avchroma_location_to_mp(ctx->avctx->chroma_sample_location),
};
-
- if (mpcodecs_reconfig_vo(sh, &ctx->image_params) < 0)
- return -1;
-
- ctx->vo_initialized = 1;
}
- return 0;
}
static enum PixelFormat get_format_hwdec(struct AVCodecContext *avctx,
@@ -740,16 +734,25 @@ static int decode(struct sh_video *sh, struct demux_packet *packet,
if (!got_picture)
return 0; // skipped image
- if (init_vo(sh, pic) < 0)
- return -1;
+ update_image_params(sh, pic);
struct mp_image *mpi = image_from_decoder(sh);
assert(mpi->planes[0]);
+ mp_image_set_params(mpi, &ctx->image_params);
if (ctx->hwdec && ctx->hwdec->process_image)
mpi = ctx->hwdec->process_image(ctx, mpi);
- mp_image_set_params(mpi, &ctx->image_params);
+ struct mp_image_params vo_params;
+ mp_image_params_from_image(&vo_params, mpi);
+
+ if (!mp_image_params_equals(&vo_params, &ctx->vo_image_params)) {
+ if (mpcodecs_reconfig_vo(sh, &vo_params) < 0) {
+ talloc_free(mpi);
+ return -1;
+ }
+ ctx->vo_image_params = vo_params;
+ }
*out_image = mpi;
return 1;
@@ -803,12 +806,12 @@ static int control(sh_video_t *sh, int cmd, void *arg)
*(int *)arg = delay;
return CONTROL_TRUE;
case VDCTRL_REINIT_VO:
- if (ctx->vo_initialized)
- mpcodecs_reconfig_vo(sh, &ctx->image_params);
+ if (ctx->vo_image_params.imgfmt)
+ mpcodecs_reconfig_vo(sh, &ctx->vo_image_params);
return true;
case VDCTRL_GET_PARAMS:
- *(struct mp_image_params *)arg = ctx->image_params;
- return ctx->vo_initialized ? true : CONTROL_NA;
+ *(struct mp_image_params *)arg = ctx->vo_image_params;
+ return ctx->vo_image_params.imgfmt ? true : CONTROL_NA;
}
return CONTROL_UNKNOWN;
}