[vlc-commits] avcodec: reuse existing pixel format if possible (fixes #14621)
Rémi Denis-Courmont
git at videolan.org
Mon Oct 26 19:31:40 CET 2015
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Oct 3 13:38:40 2015 +0300| [17a10dc66037fd5f586c9e291186463019e23dea] | committer: Rémi Denis-Courmont
avcodec: reuse existing pixel format if possible (fixes #14621)
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=17a10dc66037fd5f586c9e291186463019e23dea
---
modules/codec/avcodec/video.c | 44 +++++++++++++++++++++++++++++++++++------
1 file changed, 38 insertions(+), 6 deletions(-)
diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c
index 25d1958..bd65a5e 100644
--- a/modules/codec/avcodec/video.c
+++ b/modules/codec/avcodec/video.c
@@ -77,6 +77,9 @@ struct decoder_sys_t
/* VA API */
vlc_va_t *p_va;
+ enum PixelFormat pix_fmt;
+ int profile;
+ int level;
vlc_sem_t sem_mt;
};
@@ -283,6 +286,9 @@ static int OpenVideoCodec( decoder_t *p_dec )
else if (p_sys->p_context->height != p_dec->fmt_in.video.i_height)
p_sys->p_context->coded_height = p_dec->fmt_in.video.i_height;
p_sys->p_context->bits_per_coded_sample = p_dec->fmt_in.video.i_bits_per_pixel;
+ p_sys->pix_fmt = AV_PIX_FMT_NONE;
+ p_sys->profile = -1;
+ p_sys->level = -1;
post_mt( p_sys );
ret = ffmpeg_OpenCodec( p_dec );
@@ -1096,12 +1102,7 @@ static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *p_context,
{
decoder_t *p_dec = p_context->opaque;
decoder_sys_t *p_sys = p_dec->p_sys;
-
- if (p_sys->p_va != NULL)
- {
- vlc_va_Delete(p_sys->p_va, p_context);
- p_sys->p_va = NULL;
- }
+ video_format_t fmt;
/* Enumerate available formats */
enum PixelFormat swfmt = avcodec_default_get_format(p_context, pi_fmt);
@@ -1120,6 +1121,35 @@ static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *p_context,
can_hwaccel = true;
}
+ /* If the format did not actually change (e.g. seeking), try to reuse the
+ * existing output format, and if present, hardware acceleration back-end.
+ * This avoids resetting the pipeline downstream. This also avoids
+ * needlessly probing for hardware acceleration support. */
+ if (p_sys->pix_fmt != AV_PIX_FMT_NONE
+ && lavc_GetVideoFormat(p_dec, &fmt, p_context, p_sys->pix_fmt, swfmt) == 0
+ && fmt.i_width == p_dec->fmt_out.video.i_width
+ && fmt.i_height == p_dec->fmt_out.video.i_height
+ && p_context->profile == p_sys->profile
+ && p_context->level <= p_sys->level)
+ {
+ for (size_t i = 0; pi_fmt[i] != AV_PIX_FMT_NONE; i++)
+ if (pi_fmt[i] == p_sys->pix_fmt)
+ {
+ msg_Dbg(p_dec, "reusing decoder output format %d", pi_fmt[i]);
+ return p_sys->pix_fmt;
+ }
+ }
+
+ if (p_sys->p_va != NULL)
+ {
+ msg_Err(p_dec, "existing hardware acceleration cannot be reused");
+ vlc_va_Delete(p_sys->p_va, p_context);
+ p_sys->p_va = NULL;
+ }
+
+ p_sys->profile = p_context->profile;
+ p_sys->level = p_context->level;
+
if (!can_hwaccel)
return swfmt;
@@ -1158,11 +1188,13 @@ static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *p_context,
msg_Info(p_dec, "Using %s for hardware decoding", va->description);
p_sys->p_va = va;
+ p_sys->pix_fmt = hwfmt;
p_context->draw_horiz_band = NULL;
return pi_fmt[i];
}
post_mt(p_sys);
/* Fallback to default behaviour */
+ p_sys->pix_fmt = swfmt;
return swfmt;
}
More information about the vlc-commits
mailing list