Commit adf9ce6d authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

avcodec: split video output format update

parent e7f7c9cb
...@@ -118,76 +118,94 @@ static uint32_t ffmpeg_CodecTag( vlc_fourcc_t fcc ) ...@@ -118,76 +118,94 @@ static uint32_t ffmpeg_CodecTag( vlc_fourcc_t fcc )
/** /**
* Sets the decoder output format. * Sets the decoder output format.
*/ */
static int lavc_UpdateVideoFormat( decoder_t *p_dec, AVCodecContext *p_context, static int lavc_GetVideoFormat(decoder_t *dec, video_format_t *restrict fmt,
bool hwaccel ) AVCodecContext *ctx, enum AVPixelFormat pix_fmt,
enum AVPixelFormat sw_pix_fmt)
{ {
int width = p_context->coded_width; int width = ctx->coded_width;
int height = p_context->coded_height; int height = ctx->coded_height;
if( !hwaccel ) video_format_Init(fmt, 0);
{
if (pix_fmt == sw_pix_fmt)
{ /* software decoding */
int aligns[AV_NUM_DATA_POINTERS]; int aligns[AV_NUM_DATA_POINTERS];
if (GetVlcChroma(&p_dec->fmt_out.video, p_context->pix_fmt)) if (GetVlcChroma(fmt, pix_fmt))
return -1; return -1;
avcodec_align_dimensions2(p_context, &width, &height, aligns); avcodec_align_dimensions2(ctx, &width, &height, aligns);
} }
p_dec->fmt_out.i_codec = p_dec->fmt_out.video.i_chroma; else /* hardware decoding */
fmt->i_chroma = vlc_va_GetChroma(pix_fmt, sw_pix_fmt);
if( width == 0 || height == 0 || width > 8192 || height > 8192 ) if( width == 0 || height == 0 || width > 8192 || height > 8192 )
{ {
msg_Err( p_dec, "Invalid frame size %dx%d.", width, height ); msg_Err(dec, "Invalid frame size %dx%d.", width, height);
return -1; /* invalid display size */ return -1; /* invalid display size */
} }
p_dec->fmt_out.video.i_width = width;
p_dec->fmt_out.video.i_height = height; fmt->i_width = width;
p_dec->fmt_out.video.i_visible_width = p_context->width; fmt->i_height = height;
p_dec->fmt_out.video.i_visible_height = p_context->height; fmt->i_visible_width = ctx->width;
fmt->i_visible_height = ctx->height;
/* If an aspect-ratio was specified in the input format then force it */ /* If an aspect-ratio was specified in the input format then force it */
if( p_dec->fmt_in.video.i_sar_num > 0 && p_dec->fmt_in.video.i_sar_den > 0 ) if (dec->fmt_in.video.i_sar_num > 0 && dec->fmt_in.video.i_sar_den > 0)
{ {
p_dec->fmt_out.video.i_sar_num = p_dec->fmt_in.video.i_sar_num; fmt->i_sar_num = dec->fmt_in.video.i_sar_num;
p_dec->fmt_out.video.i_sar_den = p_dec->fmt_in.video.i_sar_den; fmt->i_sar_den = dec->fmt_in.video.i_sar_den;
} }
else else
{ {
p_dec->fmt_out.video.i_sar_num = p_context->sample_aspect_ratio.num; fmt->i_sar_num = ctx->sample_aspect_ratio.num;
p_dec->fmt_out.video.i_sar_den = p_context->sample_aspect_ratio.den; fmt->i_sar_den = ctx->sample_aspect_ratio.den;
if( !p_dec->fmt_out.video.i_sar_num || !p_dec->fmt_out.video.i_sar_den ) if (fmt->i_sar_num == 0 || fmt->i_sar_den == 0)
{ fmt->i_sar_num = fmt->i_sar_den = 1;
p_dec->fmt_out.video.i_sar_num = 1;
p_dec->fmt_out.video.i_sar_den = 1;
}
} }
if( p_dec->fmt_in.video.i_frame_rate > 0 && if (dec->fmt_in.video.i_frame_rate > 0
p_dec->fmt_in.video.i_frame_rate_base > 0 ) && dec->fmt_in.video.i_frame_rate_base > 0)
{ {
p_dec->fmt_out.video.i_frame_rate = fmt->i_frame_rate = dec->fmt_in.video.i_frame_rate;
p_dec->fmt_in.video.i_frame_rate; fmt->i_frame_rate_base = dec->fmt_in.video.i_frame_rate_base;
p_dec->fmt_out.video.i_frame_rate_base =
p_dec->fmt_in.video.i_frame_rate_base;
} }
#if LIBAVCODEC_VERSION_CHECK( 56, 5, 0, 7, 100 ) #if LIBAVCODEC_VERSION_CHECK( 56, 5, 0, 7, 100 )
else if( p_context->framerate.num > 0 && p_context->framerate.den > 0 ) else if (ctx->framerate.num > 0 && ctx->framerate.den > 0)
{ {
p_dec->fmt_out.video.i_frame_rate = p_context->framerate.num; fmt->i_frame_rate = ctx->framerate.num;
p_dec->fmt_out.video.i_frame_rate_base = p_context->framerate.den; fmt->i_frame_rate_base = ctx->framerate.den;
# if LIBAVCODEC_VERSION_MICRO < 100 # if LIBAVCODEC_VERSION_MICRO < 100
// for some reason libav don't thinkg framerate presents actually same thing as in ffmpeg // for some reason libav don't thinkg framerate presents actually same thing as in ffmpeg
p_dec->fmt_out.video.i_frame_rate_base *= __MAX( p_context->ticks_per_frame, 1 ); fmt->i_frame_rate_base *= __MAX(ctx->ticks_per_frame, 1);
# endif # endif
} }
#endif #endif
else if( p_context->time_base.num > 0 && p_context->time_base.den > 0 ) else if (ctx->time_base.num > 0 && ctx->time_base.den > 0)
{ {
p_dec->fmt_out.video.i_frame_rate = p_context->time_base.den; fmt->i_frame_rate = ctx->time_base.den;
p_dec->fmt_out.video.i_frame_rate_base = p_context->time_base.num * __MAX( p_context->ticks_per_frame, 1 ); fmt->i_frame_rate_base = ctx->time_base.num
* __MAX(ctx->ticks_per_frame, 1);
} }
return decoder_UpdateVideoFormat( p_dec ); return 0;
}
static int lavc_UpdateVideoFormat(decoder_t *dec, AVCodecContext *ctx,
enum AVPixelFormat fmt,
enum AVPixelFormat swfmt)
{
video_format_t fmt_out;
int val;
val = lavc_GetVideoFormat(dec, &fmt_out, ctx, fmt, swfmt);
if (val)
return val;
es_format_Clean(&dec->fmt_out);
es_format_Init(&dec->fmt_out, VIDEO_ES, fmt_out.i_chroma);
dec->fmt_out.video = fmt_out;
return decoder_UpdateVideoFormat(dec);
} }
/** /**
...@@ -759,7 +777,8 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block ) ...@@ -759,7 +777,8 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
* might not be called. The output video format must be set here * might not be called. The output video format must be set here
* then picture buffer can be allocated. */ * then picture buffer can be allocated. */
if (p_sys->p_va == NULL if (p_sys->p_va == NULL
&& lavc_UpdateVideoFormat(p_dec, p_context, false) == 0) && lavc_UpdateVideoFormat(p_dec, p_context, p_context->pix_fmt,
p_context->pix_fmt) == 0)
p_pic = decoder_GetPicture(p_dec); p_pic = decoder_GetPicture(p_dec);
if( !p_pic ) if( !p_pic )
...@@ -1049,7 +1068,7 @@ static int lavc_GetFrame(struct AVCodecContext *ctx, AVFrame *frame, int flags) ...@@ -1049,7 +1068,7 @@ static int lavc_GetFrame(struct AVCodecContext *ctx, AVFrame *frame, int flags)
/* Most unaccelerated decoders do not call get_format(), so we need to /* Most unaccelerated decoders do not call get_format(), so we need to
* update the output video format here. The MT semaphore must be held * update the output video format here. The MT semaphore must be held
* to protect p_dec->fmt_out. */ * to protect p_dec->fmt_out. */
if (lavc_UpdateVideoFormat(dec, ctx, false)) if (lavc_UpdateVideoFormat(dec, ctx, ctx->pix_fmt, ctx->pix_fmt))
{ {
post_mt(sys); post_mt(sys);
return -1; return -1;
...@@ -1118,7 +1137,7 @@ static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *p_context, ...@@ -1118,7 +1137,7 @@ static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *p_context,
msg_Err(p_dec, "unspecified video dimensions"); msg_Err(p_dec, "unspecified video dimensions");
continue; continue;
} }
if (lavc_UpdateVideoFormat(p_dec, p_context, true)) if (lavc_UpdateVideoFormat(p_dec, p_context, hwfmt, swfmt))
continue; /* Unsupported brand of hardware acceleration */ continue; /* Unsupported brand of hardware acceleration */
post_mt(p_sys); post_mt(p_sys);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment