[vlc-commits] demux: asf: read DVR sample extension timing (fix #17959)
Francois Cartegnie
git at videolan.org
Tue Jan 31 13:12:18 CET 2017
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue Jan 31 13:05:54 2017 +0100| [b69b561bfae13919bbeb3b7a13092cf14beb47d9] | committer: Francois Cartegnie
demux: asf: read DVR sample extension timing (fix #17959)
Undocumented, so no clue about the spec for
that extension. Guess from libavformat.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=b69b561bfae13919bbeb3b7a13092cf14beb47d9
---
modules/demux/asf/asfpacket.c | 70 ++++++++++++++++++++++++++++-------------
modules/demux/asf/libasf_guid.h | 3 ++
2 files changed, 52 insertions(+), 21 deletions(-)
diff --git a/modules/demux/asf/asfpacket.c b/modules/demux/asf/asfpacket.c
index a5f5bcc..e76332b 100644
--- a/modules/demux/asf/asfpacket.c
+++ b/modules/demux/asf/asfpacket.c
@@ -122,7 +122,8 @@ static int DemuxSubPayload( asf_packet_sys_t *p_packetsys,
static void ParsePayloadExtensions( asf_packet_sys_t *p_packetsys,
const asf_track_info_t *p_tkinfo,
const asf_packet_t *pkt,
- uint32_t i_length, bool *b_keyframe )
+ uint32_t i_length, bool *b_keyframe,
+ int64_t *pi_extension_pts )
{
demux_t *p_demux = p_packetsys->p_demux;
@@ -178,6 +179,19 @@ static void ParsePayloadExtensions( asf_packet_sys_t *p_packetsys,
p_packetsys->pf_setaspectratio( p_packetsys, p_tkinfo->p_sp->i_stream_number,
p_data[0], p_data[1] );
}
+ else if ( guidcmp( &p_ext->i_extension_id, &asf_dvr_sampleextension_timing_rep_data_guid ) )
+ {
+ if ( i_payload_extensions_size != 48 ) goto sizeerror;
+ const int64_t i_pts = GetQWLE(&p_data[8]);
+ if(i_pts != -1)
+ *pi_extension_pts = i_pts / 10000;
+ }
+#if 0
+ else
+ {
+ msg_Dbg( p_demux, "Unknown extension " GUID_FMT, GUID_PRINT( p_ext->i_extension_id ) );
+ }
+#endif
i_length -= i_payload_extensions_size;
p_data += i_payload_extensions_size;
}
@@ -212,8 +226,9 @@ static int DemuxPayload(asf_packet_sys_t *p_packetsys, asf_packet_t *pkt, int i_
if (GetValue2b(&i_replicated_data_length, pkt->p_peek, &pkt->i_skip, pkt->left - pkt->i_skip, pkt->property) < 0)
return -1;
- mtime_t i_base_pts;
- uint8_t i_pts_delta = 0;
+ int64_t i_pkt_time;
+ uint8_t i_pkt_time_delta = 0;
+ int64_t i_extension_pts = -1;
uint32_t i_payload_data_length = 0;
uint32_t i_temp_payload_length = 0;
*p_packetsys->pi_preroll = __MIN( *p_packetsys->pi_preroll, INT64_MAX );
@@ -231,13 +246,16 @@ static int DemuxPayload(asf_packet_sys_t *p_packetsys, asf_packet_t *pkt, int i_
/* Non compressed */
if( i_replicated_data_length > 7 ) // should be at least 8 bytes
{
- /* Followed by 2 optional DWORDS, offset in media and presentation time */
- i_base_pts = (mtime_t)GetDWLE( pkt->p_peek + pkt->i_skip + 4 );
+ /* Followed by 2 optional DWORDS, offset in media and *media* presentation time */
+ i_pkt_time = (mtime_t)GetDWLE( pkt->p_peek + pkt->i_skip + 4 );
/* Parsing extensions, See 7.3.1 */
ParsePayloadExtensions( p_packetsys, p_tkinfo, pkt,
- i_replicated_data_length, &b_packet_keyframe );
- i_base_pts -= *p_packetsys->pi_preroll;
+ i_replicated_data_length, &b_packet_keyframe,
+ &i_extension_pts );
+ i_pkt_time -= *p_packetsys->pi_preroll;
+ if(i_extension_pts != -1)
+ i_extension_pts -= *p_packetsys->pi_preroll;
pkt->i_skip += i_replicated_data_length;
if( ! pkt->left || pkt->i_skip >= pkt->left )
@@ -246,17 +264,17 @@ static int DemuxPayload(asf_packet_sys_t *p_packetsys, asf_packet_t *pkt, int i_
else if ( i_replicated_data_length == 0 )
{
/* optional DWORDS missing */
- i_base_pts = (mtime_t)pkt->send_time;
+ i_pkt_time = (mtime_t)pkt->send_time;
}
/* Compressed payload */
else if( i_replicated_data_length == 1 )
{
- /* i_media_object_offset is presentation time */
- /* Next byte is Presentation Time Delta */
- i_pts_delta = pkt->p_peek[pkt->i_skip];
+ /* i_media_object_offset is *media* presentation time */
+ /* Next byte is *media* Presentation Time Delta */
+ i_pkt_time_delta = pkt->p_peek[pkt->i_skip];
b_ignore_pts = false;
- i_base_pts = (mtime_t)i_media_object_offset;
- i_base_pts -= *p_packetsys->pi_preroll;
+ i_pkt_time = (mtime_t)i_media_object_offset;
+ i_pkt_time -= *p_packetsys->pi_preroll;
pkt->i_skip++;
i_media_object_offset = 0;
}
@@ -270,8 +288,8 @@ static int DemuxPayload(asf_packet_sys_t *p_packetsys, asf_packet_t *pkt, int i_
bool b_preroll_done = ( pkt->send_time > (*p_packetsys->pi_preroll_start/1000 + *p_packetsys->pi_preroll) );
- if (i_base_pts < 0) i_base_pts = 0; // FIXME?
- i_base_pts *= 1000;
+ if (i_pkt_time < 0) i_pkt_time = 0; // FIXME?
+ i_pkt_time *= 1000;
if( pkt->multiple ) {
if (GetValue2b(&i_temp_payload_length, pkt->p_peek, &pkt->i_skip, pkt->left - pkt->i_skip, pkt->length_type) < 0)
@@ -287,7 +305,8 @@ static int DemuxPayload(asf_packet_sys_t *p_packetsys, asf_packet_t *pkt, int i_
i_payload + 1, i_stream_number, i_media_object_number,
i_media_object_offset, i_replicated_data_length, i_payload_data_length );
msg_Dbg( p_demux,
- " pts=%"PRId64" st=%"PRIu32, i_base_pts, pkt->send_time );
+ " extpts=%"PRId64" pkttime=%"PRId64" st=%"PRIu32,
+ (i_extension_pts >= 0) ? i_extension_pts * 1000 : -1, i_pkt_time, pkt->send_time );
#endif
if( ! i_payload_data_length || i_payload_data_length > pkt->left )
@@ -302,7 +321,7 @@ static int DemuxPayload(asf_packet_sys_t *p_packetsys, asf_packet_t *pkt, int i_
if ( b_preroll_done )
{
- mtime_t i_track_time = i_base_pts;
+ mtime_t i_track_time = i_pkt_time;
if ( p_packetsys->pf_updatetime )
p_packetsys->pf_updatetime( p_packetsys, i_stream_number, i_track_time );
@@ -323,11 +342,20 @@ static int DemuxPayload(asf_packet_sys_t *p_packetsys, asf_packet_t *pkt, int i_
SkipBytes( p_demux->s, pkt->i_skip );
- mtime_t i_payload_pts = i_base_pts + (mtime_t)i_pts_delta * i_subpayload_count * 1000;
- if ( p_tkinfo->p_sp )
- i_payload_pts -= p_tkinfo->p_sp->i_time_offset * 10;
+ mtime_t i_payload_pts;
+ if( i_extension_pts != -1 )
+ {
+ i_payload_pts = i_extension_pts * 1000;
+ b_ignore_pts = false;
+ }
+ else
+ {
+ i_payload_pts = i_pkt_time + (mtime_t)i_pkt_time_delta * i_subpayload_count * 1000;
+ if ( p_tkinfo->p_sp )
+ i_payload_pts -= p_tkinfo->p_sp->i_time_offset * 10;
+ }
- mtime_t i_payload_dts = i_base_pts;
+ mtime_t i_payload_dts = i_pkt_time;
if ( p_tkinfo->p_sp )
i_payload_dts -= p_tkinfo->p_sp->i_time_offset * 10;
diff --git a/modules/demux/asf/libasf_guid.h b/modules/demux/asf/libasf_guid.h
index 9d1f2bd..ff327af 100644
--- a/modules/demux/asf/libasf_guid.h
+++ b/modules/demux/asf/libasf_guid.h
@@ -255,6 +255,9 @@ static const guid_t mfasf_sampleextension_encryptionkeyid_guid =
static const guid_t asf_dvr_sampleextension_videoframe_guid =
{0xDD6432CC, 0xE229, 0x40DB, {0x80, 0xF6, 0xD2, 0x63, 0x28, 0xD2, 0x76, 0x1F}};
+static const guid_t asf_dvr_sampleextension_timing_rep_data_guid =
+{0xFD3CC02A, 0x06DB, 0x4CFA, {0x80, 0x1C, 0x72, 0x12, 0xd3, 0x87, 0x45, 0xE4}};
+
/****************************************************************************
* GUID functions
****************************************************************************/
More information about the vlc-commits
mailing list