[vlc-commits] packetizer: mpegvideo: refactor frame output
Francois Cartegnie
git at videolan.org
Thu Sep 26 12:16:26 CEST 2019
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Thu Sep 26 11:32:56 2019 +0200| [269fc9bc45d3252d11ebfe445eb98801e9eeb860] | committer: Francois Cartegnie
packetizer: mpegvideo: refactor frame output
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=269fc9bc45d3252d11ebfe445eb98801e9eeb860
---
modules/packetizer/mpegvideo.c | 405 ++++++++++++++++++++++-------------------
1 file changed, 213 insertions(+), 192 deletions(-)
diff --git a/modules/packetizer/mpegvideo.c b/modules/packetizer/mpegvideo.c
index d449e4204b..547a1d337e 100644
--- a/modules/packetizer/mpegvideo.c
+++ b/modules/packetizer/mpegvideo.c
@@ -349,6 +349,217 @@ static block_t *GetCc( decoder_t *p_dec, decoder_cc_desc_t *p_desc )
return p_cc;
}
+/*****************************************************************************
+ * OutputFrame: assemble and tag frame
+ *****************************************************************************/
+static block_t *OutputFrame( decoder_t *p_dec )
+{
+ decoder_sys_t *p_sys = p_dec->p_sys;
+ block_t *p_pic = NULL;
+
+ if( !p_sys->p_frame )
+ return NULL;
+
+ p_pic = block_ChainGather( p_sys->p_frame );
+ if( p_pic == NULL )
+ {
+ p_sys->p_frame = NULL;
+ p_sys->pp_last = &p_sys->p_frame;
+ p_sys->b_frame_slice = false;
+ return p_pic;
+ }
+
+ unsigned i_num_fields;
+
+ if( !p_sys->b_seq_progressive && p_sys->i_picture_structure != 0x03 /* Field Picture */ )
+ i_num_fields = 1;
+ else
+ i_num_fields = 2;
+
+ if( p_sys->b_seq_progressive )
+ {
+ if( p_sys->i_top_field_first == 0 &&
+ p_sys->i_repeat_first_field == 1 )
+ {
+ i_num_fields *= 2;
+ }
+ else if( p_sys->i_top_field_first == 1 &&
+ p_sys->i_repeat_first_field == 1 )
+ {
+ i_num_fields *= 3;
+ }
+ }
+ else
+ {
+ if( p_sys->i_picture_structure == 0x03 /* Frame Picture */ )
+ {
+ if( p_sys->i_progressive_frame && p_sys->i_repeat_first_field )
+ {
+ i_num_fields += 1;
+ }
+ }
+ }
+
+ switch ( p_sys->i_picture_type )
+ {
+ case 0x01:
+ p_pic->i_flags |= BLOCK_FLAG_TYPE_I;
+ break;
+ case 0x02:
+ p_pic->i_flags |= BLOCK_FLAG_TYPE_P;
+ break;
+ case 0x03:
+ p_pic->i_flags |= BLOCK_FLAG_TYPE_B;
+ break;
+ }
+
+ if( !p_sys->b_seq_progressive )
+ {
+ if( p_sys->i_picture_structure < 0x03 )
+ {
+ p_pic->i_flags |= BLOCK_FLAG_SINGLE_FIELD;
+ p_pic->i_flags |= (p_sys->i_picture_structure == 0x01) ? BLOCK_FLAG_TOP_FIELD_FIRST
+ : BLOCK_FLAG_BOTTOM_FIELD_FIRST;
+ }
+ else /* if( p_sys->i_picture_structure == 0x03 ) */
+ {
+ p_pic->i_flags |= (p_sys->i_top_field_first) ? BLOCK_FLAG_TOP_FIELD_FIRST
+ : BLOCK_FLAG_BOTTOM_FIELD_FIRST;
+ }
+ }
+
+ /* Special case for DVR-MS where we need to fully build pts from scratch
+ * and only use first dts as it does not monotonically increase
+ * This will NOT work with frame repeats and such, as we would need to fully
+ * fill the DPB to get accurate pts timings. */
+ if( unlikely( p_dec->fmt_in.i_original_fourcc == VLC_FOURCC( 'D','V','R',' ') ) )
+ {
+ const bool b_first_xmited = (p_sys->i_prev_temporal_ref != p_sys->i_temporal_ref );
+
+ if( ( p_pic->i_flags & BLOCK_FLAG_TYPE_I ) && b_first_xmited )
+ {
+ if( date_Get( &p_sys->prev_iframe_dts ) == VLC_TICK_INVALID )
+ {
+ if( p_sys->i_dts != VLC_TICK_INVALID )
+ {
+ date_Set( &p_sys->dts, p_sys->i_dts );
+ }
+ else
+ {
+ if( date_Get( &p_sys->dts ) == VLC_TICK_INVALID )
+ {
+ date_Set( &p_sys->dts, VLC_TICK_0 );
+ }
+ }
+ }
+ p_sys->prev_iframe_dts = p_sys->dts;
+ }
+
+ p_pic->i_dts = date_Get( &p_sys->dts );
+
+ /* Compute pts from poc */
+ date_t datepts = p_sys->prev_iframe_dts;
+ date_Increment( &datepts, (1 + p_sys->i_temporal_ref) * 2 );
+
+ /* Field picture second field case */
+ if( p_sys->i_picture_structure != 0x03 )
+ {
+ /* first sent is not the first in display order */
+ if( (p_sys->i_picture_structure >> 1) != !p_sys->i_top_field_first &&
+ b_first_xmited )
+ {
+ date_Increment( &datepts, 2 );
+ }
+ }
+
+ p_pic->i_pts = date_Get( &datepts );
+
+ if( date_Get( &p_sys->dts ) != VLC_TICK_INVALID )
+ {
+ date_Increment( &p_sys->dts, i_num_fields );
+
+ p_pic->i_length = date_Get( &p_sys->dts ) - p_pic->i_dts;
+ }
+ p_sys->i_prev_temporal_ref = p_sys->i_temporal_ref;
+ }
+ else /* General case, use demuxer's dts/pts when set or interpolate */
+ {
+ if( p_sys->b_low_delay || p_sys->i_picture_type == 0x03 )
+ {
+ /* Trivial case (DTS == PTS) */
+ /* Correct interpolated dts when we receive a new pts/dts */
+ if( p_sys->i_pts != VLC_TICK_INVALID )
+ date_Set( &p_sys->dts, p_sys->i_pts );
+ if( p_sys->i_dts != VLC_TICK_INVALID )
+ date_Set( &p_sys->dts, p_sys->i_dts );
+ }
+ else
+ {
+ /* Correct interpolated dts when we receive a new pts/dts */
+ if(p_sys->i_last_ref_pts != VLC_TICK_INVALID && !p_sys->b_second_field)
+ date_Set( &p_sys->dts, p_sys->i_last_ref_pts );
+ if( p_sys->i_dts != VLC_TICK_INVALID )
+ date_Set( &p_sys->dts, p_sys->i_dts );
+
+ if( !p_sys->b_second_field )
+ p_sys->i_last_ref_pts = p_sys->i_pts;
+ }
+
+ p_pic->i_dts = date_Get( &p_sys->dts );
+
+ /* Set PTS only if we have a B frame or if it comes from the stream */
+ if( p_sys->i_pts != VLC_TICK_INVALID )
+ {
+ p_pic->i_pts = p_sys->i_pts;
+ }
+ else if( p_sys->i_picture_type == 0x03 )
+ {
+ p_pic->i_pts = p_pic->i_dts;
+ }
+ else
+ {
+ p_pic->i_pts = VLC_TICK_INVALID;
+ }
+
+ if( date_Get( &p_sys->dts ) != VLC_TICK_INVALID )
+ {
+ date_Increment( &p_sys->dts, i_num_fields );
+
+ p_pic->i_length = date_Get( &p_sys->dts ) - p_pic->i_dts;
+ }
+ }
+
+#if 0
+ msg_Dbg( p_dec, "pic: type=%d ref=%d nf=%d tff=%d dts=%"PRId64" ptsdiff=%"PRId64" len=%"PRId64,
+ p_sys->i_picture_structure, p_sys->i_temporal_ref, i_num_fields,
+ p_sys->i_top_field_first,
+ p_pic->i_dts , (p_pic->i_pts != VLC_TICK_INVALID) ? p_pic->i_pts - p_pic->i_dts : 0, p_pic->i_length );
+#endif
+
+
+ /* Reset context */
+ p_sys->p_frame = NULL;
+ p_sys->pp_last = &p_sys->p_frame;
+ p_sys->b_frame_slice = false;
+
+ if( p_sys->i_picture_structure != 0x03 )
+ {
+ p_sys->b_second_field = !p_sys->b_second_field;
+ }
+ else
+ {
+ p_sys->b_second_field = 0;
+ }
+
+ /* CC */
+ p_sys->b_cc_reset = true;
+ p_sys->i_cc_pts = p_pic->i_pts;
+ p_sys->i_cc_dts = p_pic->i_dts;
+ p_sys->i_cc_flags = p_pic->i_flags & BLOCK_FLAG_TYPE_MASK;
+
+ return p_pic;
+}
+
/*****************************************************************************
* Helpers:
*****************************************************************************/
@@ -461,200 +672,10 @@ static block_t *ParseMPEGBlock( decoder_t *p_dec, block_t *p_frag )
p_frag = NULL;
}
- p_pic = block_ChainGather( p_sys->p_frame );
- if( p_pic == NULL )
- return p_pic;
+ p_pic = OutputFrame( p_dec );
- if( b_eos )
+ if( p_pic && b_eos )
p_pic->i_flags |= BLOCK_FLAG_END_OF_SEQUENCE;
-
- unsigned i_num_fields;
-
- if( !p_sys->b_seq_progressive && p_sys->i_picture_structure != 0x03 /* Field Picture */ )
- i_num_fields = 1;
- else
- i_num_fields = 2;
-
- if( p_sys->b_seq_progressive )
- {
- if( p_sys->i_top_field_first == 0 &&
- p_sys->i_repeat_first_field == 1 )
- {
- i_num_fields *= 2;
- }
- else if( p_sys->i_top_field_first == 1 &&
- p_sys->i_repeat_first_field == 1 )
- {
- i_num_fields *= 3;
- }
- }
- else
- {
- if( p_sys->i_picture_structure == 0x03 /* Frame Picture */ )
- {
- if( p_sys->i_progressive_frame && p_sys->i_repeat_first_field )
- {
- i_num_fields += 1;
- }
- }
- }
-
- switch ( p_sys->i_picture_type )
- {
- case 0x01:
- p_pic->i_flags |= BLOCK_FLAG_TYPE_I;
- break;
- case 0x02:
- p_pic->i_flags |= BLOCK_FLAG_TYPE_P;
- break;
- case 0x03:
- p_pic->i_flags |= BLOCK_FLAG_TYPE_B;
- break;
- }
-
- if( !p_sys->b_seq_progressive )
- {
- if( p_sys->i_picture_structure < 0x03 )
- {
- p_pic->i_flags |= BLOCK_FLAG_SINGLE_FIELD;
- p_pic->i_flags |= (p_sys->i_picture_structure == 0x01) ? BLOCK_FLAG_TOP_FIELD_FIRST
- : BLOCK_FLAG_BOTTOM_FIELD_FIRST;
- }
- else /* if( p_sys->i_picture_structure == 0x03 ) */
- {
- p_pic->i_flags |= (p_sys->i_top_field_first) ? BLOCK_FLAG_TOP_FIELD_FIRST
- : BLOCK_FLAG_BOTTOM_FIELD_FIRST;
- }
- }
-
- /* Special case for DVR-MS where we need to fully build pts from scratch
- * and only use first dts as it does not monotonically increase
- * This will NOT work with frame repeats and such, as we would need to fully
- * fill the DPB to get accurate pts timings. */
- if( unlikely( p_dec->fmt_in.i_original_fourcc == VLC_FOURCC( 'D','V','R',' ') ) )
- {
- const bool b_first_xmited = (p_sys->i_prev_temporal_ref != p_sys->i_temporal_ref );
-
- if( ( p_pic->i_flags & BLOCK_FLAG_TYPE_I ) && b_first_xmited )
- {
- if( date_Get( &p_sys->prev_iframe_dts ) == VLC_TICK_INVALID )
- {
- if( p_sys->i_dts != VLC_TICK_INVALID )
- {
- date_Set( &p_sys->dts, p_sys->i_dts );
- }
- else
- {
- if( date_Get( &p_sys->dts ) == VLC_TICK_INVALID )
- {
- date_Set( &p_sys->dts, VLC_TICK_0 );
- }
- }
- }
- p_sys->prev_iframe_dts = p_sys->dts;
- }
-
- p_pic->i_dts = date_Get( &p_sys->dts );
-
- /* Compute pts from poc */
- date_t datepts = p_sys->prev_iframe_dts;
- date_Increment( &datepts, (1 + p_sys->i_temporal_ref) * 2 );
-
- /* Field picture second field case */
- if( p_sys->i_picture_structure != 0x03 )
- {
- /* first sent is not the first in display order */
- if( (p_sys->i_picture_structure >> 1) != !p_sys->i_top_field_first &&
- b_first_xmited )
- {
- date_Increment( &datepts, 2 );
- }
- }
-
- p_pic->i_pts = date_Get( &datepts );
-
- if( date_Get( &p_sys->dts ) != VLC_TICK_INVALID )
- {
- date_Increment( &p_sys->dts, i_num_fields );
-
- p_pic->i_length = date_Get( &p_sys->dts ) - p_pic->i_dts;
- }
- p_sys->i_prev_temporal_ref = p_sys->i_temporal_ref;
- }
- else /* General case, use demuxer's dts/pts when set or interpolate */
- {
- if( p_sys->b_low_delay || p_sys->i_picture_type == 0x03 )
- {
- /* Trivial case (DTS == PTS) */
- /* Correct interpolated dts when we receive a new pts/dts */
- if( p_sys->i_pts != VLC_TICK_INVALID )
- date_Set( &p_sys->dts, p_sys->i_pts );
- if( p_sys->i_dts != VLC_TICK_INVALID )
- date_Set( &p_sys->dts, p_sys->i_dts );
- }
- else
- {
- /* Correct interpolated dts when we receive a new pts/dts */
- if(p_sys->i_last_ref_pts != VLC_TICK_INVALID && !p_sys->b_second_field)
- date_Set( &p_sys->dts, p_sys->i_last_ref_pts );
- if( p_sys->i_dts != VLC_TICK_INVALID )
- date_Set( &p_sys->dts, p_sys->i_dts );
-
- if( !p_sys->b_second_field )
- p_sys->i_last_ref_pts = p_sys->i_pts;
- }
-
- p_pic->i_dts = date_Get( &p_sys->dts );
-
- /* Set PTS only if we have a B frame or if it comes from the stream */
- if( p_sys->i_pts != VLC_TICK_INVALID )
- {
- p_pic->i_pts = p_sys->i_pts;
- }
- else if( p_sys->i_picture_type == 0x03 )
- {
- p_pic->i_pts = p_pic->i_dts;
- }
- else
- {
- p_pic->i_pts = VLC_TICK_INVALID;
- }
-
- if( date_Get( &p_sys->dts ) != VLC_TICK_INVALID )
- {
- date_Increment( &p_sys->dts, i_num_fields );
-
- p_pic->i_length = date_Get( &p_sys->dts ) - p_pic->i_dts;
- }
- }
-
-#if 0
- msg_Dbg( p_dec, "pic: type=%d ref=%d nf=%d tff=%d dts=%"PRId64" ptsdiff=%"PRId64" len=%"PRId64,
- p_sys->i_picture_structure, p_sys->i_temporal_ref, i_num_fields,
- p_sys->i_top_field_first,
- p_pic->i_dts , (p_pic->i_pts != VLC_TICK_INVALID) ? p_pic->i_pts - p_pic->i_dts : 0, p_pic->i_length );
-#endif
-
-
- /* Reset context */
- p_sys->p_frame = NULL;
- p_sys->pp_last = &p_sys->p_frame;
- p_sys->b_frame_slice = false;
-
- if( p_sys->i_picture_structure != 0x03 )
- {
- p_sys->b_second_field = !p_sys->b_second_field;
- }
- else
- {
- p_sys->b_second_field = 0;
- }
-
- /* CC */
- p_sys->b_cc_reset = true;
- p_sys->i_cc_pts = p_pic->i_pts;
- p_sys->i_cc_dts = p_pic->i_dts;
- p_sys->i_cc_flags = p_pic->i_flags & BLOCK_FLAG_TYPE_MASK;
}
if( !p_pic && p_sys->b_cc_reset )
More information about the vlc-commits
mailing list