Commit 93028df6 authored by Jean-Paul Saman's avatar Jean-Paul Saman

codec/avcodec/video.c: do not use reorder opaque

Use AVPacket API to keep PTS and DTS with the picture frames. Part of
this commit is a manual backport of modification in videolan master repo.
parent 1ce28bdd
...@@ -93,8 +93,6 @@ struct decoder_sys_t ...@@ -93,8 +93,6 @@ struct decoder_sys_t
bool b_direct_rendering; bool b_direct_rendering;
int i_direct_rendering_used; int i_direct_rendering_used;
bool b_has_b_frames;
/* Hack to force display of still pictures */ /* Hack to force display of still pictures */
bool b_first_frame; bool b_first_frame;
...@@ -128,7 +126,6 @@ struct decoder_sys_t ...@@ -128,7 +126,6 @@ struct decoder_sys_t
static void ffmpeg_InitCodec ( decoder_t * ); static void ffmpeg_InitCodec ( decoder_t * );
static void ffmpeg_CopyPicture ( decoder_t *, picture_t *, AVFrame * ); static void ffmpeg_CopyPicture ( decoder_t *, picture_t *, AVFrame * );
static int ffmpeg_GetFrameBuf ( struct AVCodecContext *, AVFrame * ); static int ffmpeg_GetFrameBuf ( struct AVCodecContext *, AVFrame * );
static int ffmpeg_ReGetFrameBuf( struct AVCodecContext *, AVFrame * );
static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext *, AVFrame * ); static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext *, AVFrame * );
#ifdef HAVE_AVCODEC_VA #ifdef HAVE_AVCODEC_VA
...@@ -354,7 +351,7 @@ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context, ...@@ -354,7 +351,7 @@ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context,
/* Always use our get_buffer wrapper so we can calculate the /* Always use our get_buffer wrapper so we can calculate the
* PTS correctly */ * PTS correctly */
p_sys->p_context->get_buffer = ffmpeg_GetFrameBuf; p_sys->p_context->get_buffer = ffmpeg_GetFrameBuf;
p_sys->p_context->reget_buffer = ffmpeg_ReGetFrameBuf; p_sys->p_context->reget_buffer = avcodec_default_reget_buffer;
p_sys->p_context->release_buffer = ffmpeg_ReleaseFrameBuf; p_sys->p_context->release_buffer = ffmpeg_ReleaseFrameBuf;
p_sys->p_context->opaque = p_dec; p_sys->p_context->opaque = p_dec;
...@@ -407,7 +404,6 @@ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context, ...@@ -407,7 +404,6 @@ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context,
/* ***** misc init ***** */ /* ***** misc init ***** */
p_sys->i_pts = VLC_TS_INVALID; p_sys->i_pts = VLC_TS_INVALID;
p_sys->b_has_b_frames = false;
p_sys->b_first_frame = true; p_sys->b_first_frame = true;
p_sys->b_flush = false; p_sys->b_flush = false;
p_sys->i_late_frames = 0; p_sys->i_late_frames = 0;
...@@ -610,24 +606,19 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block ) ...@@ -610,24 +606,19 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
picture_t *p_pic; picture_t *p_pic;
AVPacket pkt; AVPacket pkt;
/* Set the PTS/DTS in the context reordered_opaque field */
if( p_block->i_pts > VLC_TS_INVALID )
p_context->reordered_opaque = (p_block->i_pts << 1) | 0;
else if( p_block->i_dts > VLC_TS_INVALID )
p_context->reordered_opaque = (p_block->i_dts << 1) | 1;
else
p_context->reordered_opaque = INT64_MIN;
p_sys->p_ff_pic->reordered_opaque = p_context->reordered_opaque;
/* Make sure we don't reuse the same timestamps twice */
p_block->i_pts =
p_block->i_dts = VLC_TS_INVALID;
post_mt( p_sys ); post_mt( p_sys );
av_init_packet( &pkt ); av_init_packet( &pkt );
pkt.data = p_block->p_buffer; pkt.data = p_block->p_buffer;
pkt.size = p_block->i_buffer; pkt.size = p_block->i_buffer;
pkt.flags = (p_block->i_flags & BLOCK_FLAG_TYPE_I) ? AV_PKT_FLAG_KEY : 0;
pkt.pts = p_block->i_pts;
pkt.dts = p_block->i_dts;
/* Make sure we don't reuse the same timestamps twice */
p_block->i_pts =
p_block->i_dts = VLC_TS_INVALID;
i_used = avcodec_decode_video2( p_context, p_sys->p_ff_pic, i_used = avcodec_decode_video2( p_context, p_sys->p_ff_pic,
&b_gotpicture, &pkt ); &b_gotpicture, &pkt );
...@@ -641,6 +632,11 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block ) ...@@ -641,6 +632,11 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
i_used = avcodec_decode_video2( p_context, p_sys->p_ff_pic, i_used = avcodec_decode_video2( p_context, p_sys->p_ff_pic,
&b_gotpicture, &pkt ); &b_gotpicture, &pkt );
} }
pkt.data = NULL;
pkt.size = 0;
av_destruct_packet(&pkt);
wait_mt( p_sys ); wait_mt( p_sys );
if( p_sys->b_flush ) if( p_sys->b_flush )
...@@ -674,40 +670,10 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block ) ...@@ -674,40 +670,10 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
continue; continue;
} }
/* Sanity check (seems to be needed for some streams) */
if( p_sys->p_ff_pic->pict_type == AV_PICTURE_TYPE_B)
{
p_sys->b_has_b_frames = true;
}
/* Compute the PTS */ /* Compute the PTS */
mtime_t i_pts = VLC_TS_INVALID; mtime_t i_pts = p_sys->p_ff_pic->pkt_pts;
if( p_sys->p_ff_pic->reordered_opaque != INT64_MIN ) if( i_pts <= VLC_TS_INVALID )
{ i_pts = p_sys->p_ff_pic->pkt_dts;
mtime_t i_ts = p_sys->p_ff_pic->reordered_opaque >> 1;
bool b_dts = p_sys->p_ff_pic->reordered_opaque & 1;
if( b_dts )
{
if( !p_context->has_b_frames ||
!p_sys->b_has_b_frames ||
!p_sys->p_ff_pic->reference ||
p_sys->i_pts <= VLC_TS_INVALID )
i_pts = i_ts;
/* Guess what ? The rules are different for Real Video :( */
if( (p_dec->fmt_in.i_codec == VLC_CODEC_RV30 ||
p_dec->fmt_in.i_codec == VLC_CODEC_RV40) &&
p_sys->b_has_b_frames )
{
i_pts = VLC_TS_INVALID;
if(p_sys->p_ff_pic->reference) i_pts = i_ts;
}
}
else
{
i_pts = i_ts;
}
}
if( i_pts <= VLC_TS_INVALID ) if( i_pts <= VLC_TS_INVALID )
i_pts = p_sys->i_pts; i_pts = p_sys->i_pts;
...@@ -722,9 +688,9 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block ) ...@@ -722,9 +688,9 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
p_dec->fmt_out.video.i_frame_rate_base > 0 ) p_dec->fmt_out.video.i_frame_rate_base > 0 )
{ {
p_sys->i_pts += INT64_C(1000000) * p_sys->i_pts += INT64_C(1000000) *
(2 + p_sys->p_ff_pic->repeat_pict) * (p_sys->p_ff_pic->repeat_pict) *
p_dec->fmt_out.video.i_frame_rate / p_dec->fmt_out.video.i_frame_rate /
(2 * p_dec->fmt_out.video.i_frame_rate_base); (p_dec->fmt_out.video.i_frame_rate_base);
} }
else if( p_context->time_base.num > 0 && else if( p_context->time_base.num > 0 &&
p_context->time_base.den > 0 ) p_context->time_base.den > 0 )
...@@ -734,9 +700,9 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block ) ...@@ -734,9 +700,9 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
i_tick = 1; i_tick = 1;
p_sys->i_pts += INT64_C(1000000) * p_sys->i_pts += INT64_C(1000000) *
(2 + p_sys->p_ff_pic->repeat_pict) * (p_sys->p_ff_pic->repeat_pict) *
(i_tick * p_context->time_base.num) / (i_tick * p_context->time_base.num) /
(2 * p_context->time_base.den); (p_context->time_base.den);
} }
} }
...@@ -1004,7 +970,6 @@ static int ffmpeg_GetFrameBuf( struct AVCodecContext *p_context, ...@@ -1004,7 +970,6 @@ static int ffmpeg_GetFrameBuf( struct AVCodecContext *p_context,
picture_t *p_pic; picture_t *p_pic;
/* */ /* */
p_ff_pic->reordered_opaque = p_context->reordered_opaque;
p_ff_pic->opaque = NULL; p_ff_pic->opaque = NULL;
if( p_sys->p_va ) if( p_sys->p_va )
...@@ -1149,13 +1114,6 @@ no_dr: ...@@ -1149,13 +1114,6 @@ no_dr:
post_mt( p_sys ); post_mt( p_sys );
return avcodec_default_get_buffer( p_context, p_ff_pic ); return avcodec_default_get_buffer( p_context, p_ff_pic );
} }
static int ffmpeg_ReGetFrameBuf( struct AVCodecContext *p_context, AVFrame *p_ff_pic )
{
p_ff_pic->reordered_opaque = p_context->reordered_opaque;
/* We always use default reget function, it works perfectly fine */
return avcodec_default_reget_buffer( p_context, p_ff_pic );
}
static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext *p_context, static void ffmpeg_ReleaseFrameBuf( struct AVCodecContext *p_context,
AVFrame *p_ff_pic ) AVFrame *p_ff_pic )
......
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