@ -322,17 +322,19 @@ static void end_ebml_master(AVIOContext *pb, ebml_master master)
avio_seek ( pb , pos , SEEK_SET ) ;
}
static int start_ebml_master_crc32 ( AVIOContext * pb , AVIOContext * * dyn_cp , ebml_master * master ,
unsigned int elementid , uint64_t expectedsize )
static int start_ebml_master_crc32 ( AVIOContext * pb , AVIOContext * * dyn_cp , MatroskaMuxContext * mkv ,
ebml_master * master , unsigned int elementid , uint64_t expectedsize )
{
int ret ;
if ( ( ret = avio_open_dyn_buf ( dyn_cp ) ) < 0 )
return ret ;
if ( pb - > seekable )
if ( pb - > seekable ) {
* master = start_ebml_master ( pb , elementid , expectedsize ) ;
else
if ( mkv - > write_crc & & mkv - > mode ! = MODE_WEBM )
put_ebml_void ( * dyn_cp , 6 ) ; /* Reserve space for CRC32 so position/size calculations using avio_tell() take it into account */
} else
* master = start_ebml_master ( * dyn_cp , elementid , expectedsize ) ;
return 0 ;
@ -342,15 +344,16 @@ static void end_ebml_master_crc32(AVIOContext *pb, AVIOContext **dyn_cp, Matrosk
ebml_master master )
{
uint8_t * buf , crc [ 4 ] ;
int size ;
int size , skip = 0 ;
if ( pb - > seekable ) {
size = avio_close_dyn_buf ( * dyn_cp , & buf ) ;
if ( mkv - > write_crc & & mkv - > mode ! = MODE_WEBM ) {
AV_WL32 ( crc , av_crc ( av_crc_get_table ( AV_CRC_32_IEEE_LE ) , UINT32_MAX , buf , size ) ^ UINT32_MAX ) ;
skip = 6 ; /* Skip reserved 6-byte long void element from the dynamic buffer. */
AV_WL32 ( crc , av_crc ( av_crc_get_table ( AV_CRC_32_IEEE_LE ) , UINT32_MAX , buf + skip , size - skip ) ^ UINT32_MAX ) ;
put_ebml_binary ( pb , EBML_ID_CRC32 , crc , sizeof ( crc ) ) ;
}
avio_write ( pb , buf , size ) ;
avio_write ( pb , buf + skip , size - skip ) ;
end_ebml_master ( pb , master ) ;
} else {
end_ebml_master ( * dyn_cp , master ) ;
@ -465,7 +468,7 @@ static int64_t mkv_write_seekhead(AVIOContext *pb, MatroskaMuxContext *mkv)
}
}
if ( start_ebml_master_crc32 ( pb , & dyn_cp , & metaseek , MATROSKA_ID_SEEKHEAD ,
if ( start_ebml_master_crc32 ( pb , & dyn_cp , mkv , & metaseek , MATROSKA_ID_SEEKHEAD ,
seekhead - > reserved_size ) < 0 ) {
currentpos = - 1 ;
goto fail ;
@ -541,7 +544,7 @@ static int64_t mkv_write_cues(AVFormatContext *s, mkv_cues *cues, mkv_track *tra
int i , j , ret ;
currentpos = avio_tell ( pb ) ;
ret = start_ebml_master_crc32 ( pb , & dyn_cp , & cues_element , MATROSKA_ID_CUES , 0 ) ;
ret = start_ebml_master_crc32 ( pb , & dyn_cp , mkv , & cues_element , MATROSKA_ID_CUES , 0 ) ;
if ( ret < 0 )
return ret ;
@ -1269,7 +1272,7 @@ static int mkv_write_tracks(AVFormatContext *s)
if ( ret < 0 )
return ret ;
ret = start_ebml_master_crc32 ( pb , & dyn_cp , & tracks , MATROSKA_ID_TRACKS , 0 ) ;
ret = start_ebml_master_crc32 ( pb , & dyn_cp , mkv , & tracks , MATROSKA_ID_TRACKS , 0 ) ;
if ( ret < 0 )
return ret ;
@ -1300,7 +1303,7 @@ static int mkv_write_chapters(AVFormatContext *s)
ret = mkv_add_seekhead_entry ( mkv - > main_seekhead , MATROSKA_ID_CHAPTERS , avio_tell ( pb ) ) ;
if ( ret < 0 ) return ret ;
ret = start_ebml_master_crc32 ( pb , & dyn_cp , & chapters , MATROSKA_ID_CHAPTERS , 0 ) ;
ret = start_ebml_master_crc32 ( pb , & dyn_cp , mkv , & chapters , MATROSKA_ID_CHAPTERS , 0 ) ;
if ( ret < 0 ) return ret ;
editionentry = start_ebml_master ( dyn_cp , MATROSKA_ID_EDITIONENTRY , 0 ) ;
@ -1387,7 +1390,7 @@ static int mkv_write_tag_targets(AVFormatContext *s,
ret = mkv_add_seekhead_entry ( mkv - > main_seekhead , MATROSKA_ID_TAGS , avio_tell ( s - > pb ) ) ;
if ( ret < 0 ) return ret ;
start_ebml_master_crc32 ( s - > pb , & mkv - > tags_bc , tags , MATROSKA_ID_TAGS , 0 ) ;
start_ebml_master_crc32 ( s - > pb , & mkv - > tags_bc , mkv , tags , MATROSKA_ID_TAGS , 0 ) ;
}
pb = mkv - > tags_bc ;
@ -1524,7 +1527,7 @@ static int mkv_write_tags(AVFormatContext *s)
if ( mkv - > tags . pos ) {
if ( s - > pb - > seekable & & ! mkv - > is_live )
put_ebml_void ( s - > pb , avio_tell ( mkv - > tags_bc ) + ( ( mkv - > write_crc & & mkv - > mode ! = MODE_WEBM ) ? 2 /* ebml id + data size */ + 4 /* CRC32 */ : 0 ) ) ;
put_ebml_void ( s - > pb , avio_tell ( mkv - > tags_bc ) ) ;
else
end_ebml_master_crc32 ( s - > pb , & mkv - > tags_bc , mkv , mkv - > tags ) ;
}
@ -1551,7 +1554,7 @@ static int mkv_write_attachments(AVFormatContext *s)
ret = mkv_add_seekhead_entry ( mkv - > main_seekhead , MATROSKA_ID_ATTACHMENTS , avio_tell ( pb ) ) ;
if ( ret < 0 ) return ret ;
ret = start_ebml_master_crc32 ( pb , & dyn_cp , & attachments , MATROSKA_ID_ATTACHMENTS , 0 ) ;
ret = start_ebml_master_crc32 ( pb , & dyn_cp , mkv , & attachments , MATROSKA_ID_ATTACHMENTS , 0 ) ;
if ( ret < 0 ) return ret ;
for ( i = 0 ; i < s - > nb_streams ; i + + ) {
@ -1722,7 +1725,7 @@ static int mkv_write_header(AVFormatContext *s)
ret = mkv_add_seekhead_entry ( mkv - > main_seekhead , MATROSKA_ID_INFO , avio_tell ( pb ) ) ;
if ( ret < 0 ) goto fail ;
ret = start_ebml_master_crc32 ( pb , & mkv - > info_bc , & mkv - > info , MATROSKA_ID_INFO , 0 ) ;
ret = start_ebml_master_crc32 ( pb , & mkv - > info_bc , mkv , & mkv - > info , MATROSKA_ID_INFO , 0 ) ;
if ( ret < 0 )
return ret ;
pb = mkv - > info_bc ;
@ -1781,7 +1784,7 @@ static int mkv_write_header(AVFormatContext *s)
}
}
if ( s - > pb - > seekable )
put_ebml_void ( s - > pb , avio_tell ( pb ) + ( ( mkv - > write_crc & & mkv - > mode ! = MODE_WEBM ) ? 2 /* ebml id + data size */ + 4 /* CRC32 */ : 0 ) ) ;
put_ebml_void ( s - > pb , avio_tell ( pb ) ) ;
else
end_ebml_master_crc32 ( s - > pb , & mkv - > info_bc , mkv , mkv - > info ) ;
pb = s - > pb ;
@ -2097,7 +2100,7 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt, int add_
if ( mkv - > cluster_pos = = - 1 ) {
mkv - > cluster_pos = avio_tell ( s - > pb ) ;
ret = start_ebml_master_crc32 ( s - > pb , & mkv - > dyn_bc , & mkv - > cluster , MATROSKA_ID_CLUSTER , 0 ) ;
ret = start_ebml_master_crc32 ( s - > pb , & mkv - > dyn_bc , mkv , & mkv - > cluster , MATROSKA_ID_CLUSTER , 0 ) ;
if ( ret < 0 )
return ret ;
put_ebml_uint ( mkv - > dyn_bc , MATROSKA_ID_CLUSTERTIMECODE , FFMAX ( 0 , ts ) ) ;
@ -2105,7 +2108,7 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt, int add_
}
pb = mkv - > dyn_bc ;
relative_packet_pos = avio_tell ( s - > pb ) - mkv - > cluster . pos + avio_tell ( pb ) ;
relative_packet_pos = avio_tell ( pb ) ;
if ( par - > codec_type ! = AVMEDIA_TYPE_SUBTITLE ) {
mkv_write_block ( s , pb , MATROSKA_ID_SIMPLEBLOCK , pkt , keyframe ) ;