@ -304,9 +304,20 @@ typedef struct MatroskaLevel {
uint64_t length ;
} MatroskaLevel ;
typedef struct MatroskaBlock {
uint64_t duration ;
int64_t reference ;
uint64_t non_simple ;
EbmlBin bin ;
uint64_t additional_id ;
EbmlBin additional ;
int64_t discard_padding ;
} MatroskaBlock ;
typedef struct MatroskaCluster {
MatroskaBlock block ;
uint64_t timecode ;
EbmlList blocks ;
int64_t po s;
} MatroskaCluster ;
typedef struct MatroskaLevel1Element {
@ -356,8 +367,6 @@ typedef struct MatroskaDemuxContext {
MatroskaLevel1Element level1_elems [ 64 ] ;
int num_level1_elems ;
int current_cluster_num_blocks ;
int64_t current_cluster_pos ;
MatroskaCluster current_cluster ;
/* WebM DASH Manifest live flag */
@ -367,16 +376,6 @@ typedef struct MatroskaDemuxContext {
int bandwidth ;
} MatroskaDemuxContext ;
typedef struct MatroskaBlock {
uint64_t duration ;
int64_t reference ;
uint64_t non_simple ;
EbmlBin bin ;
uint64_t additional_id ;
EbmlBin additional ;
int64_t discard_padding ;
} MatroskaBlock ;
static const EbmlSyntax ebml_header [ ] = {
{ EBML_ID_EBMLREADVERSION , EBML_UINT , 0 , offsetof ( Ebml , version ) , { . u = EBML_VERSION } } ,
{ EBML_ID_EBMLMAXSIZELENGTH , EBML_UINT , 0 , offsetof ( Ebml , max_size ) , { . u = 8 } } ,
@ -705,9 +704,9 @@ static const EbmlSyntax matroska_blockgroup[] = {
} ;
static const EbmlSyntax matroska_cluster_parsing [ ] = {
{ MATROSKA_ID_CLUSTERTIMECODE , EBML_UINT , 0 , offsetof ( MatroskaCluster , timecode ) } ,
{ MATROSKA_ID_BLOCKGROUP , EBML_NEST , sizeof ( MatroskaBlock ) , offsetof ( MatroskaCluster , blocks ) , { . n = matroska_blockgroup } } ,
{ MATROSKA_ID_SIMPLEBLOCK , EBML_PASS , sizeof ( MatroskaBlock ) , offsetof ( MatroskaCluster , blocks ) , { . n = matroska_blockgroup } } ,
{ MATROSKA_ID_CLUSTERTIMECODE , EBML_UINT , 0 , offsetof ( MatroskaCluster , timecode ) } ,
{ MATROSKA_ID_BLOCKGROUP , EBML_NEST , 0 , 0 , { . n = matroska_blockgroup } } ,
{ MATROSKA_ID_SIMPLEBLOCK , EBML_PASS , 0 , 0 , { . n = matroska_blockgroup } } ,
{ MATROSKA_ID_CLUSTERPOSITION , EBML_NONE } ,
{ MATROSKA_ID_CLUSTERPREVSIZE , EBML_NONE } ,
{ MATROSKA_ID_INFO , EBML_NONE } ,
@ -3452,57 +3451,48 @@ end:
static int matroska_parse_cluster ( MatroskaDemuxContext * matroska )
{
EbmlList * blocks_list ;
MatroskaBlock * blocks ;
int i , res ;
MatroskaCluster * cluster = & matroska - > current_cluster ;
MatroskaBlock * block = & cluster - > block ;
int res ;
res = ebml_parse ( matroska ,
matroska_cluster_parsing ,
& matroska - > current_ cluster) ;
cluster ) ;
if ( res = = 1 ) {
/* New Cluster */
if ( matroska - > current_cluster_ pos)
if ( cluster - > pos )
ebml_level_end ( matroska ) ;
ebml_free ( matroska_cluster_parsing , & matroska - > current_cluster ) ;
memset ( & matroska - > current_cluster , 0 , sizeof ( MatroskaCluster ) ) ;
matroska - > current_cluster_num_blocks = 0 ;
matroska - > current_cluster_pos = avio_tell ( matroska - > ctx - > pb ) ;
cluster - > pos = avio_tell ( matroska - > ctx - > pb ) ;
/* sizeof the ID which was already read */
if ( matroska - > current_id )
matroska - > current_cluster_ pos - = 4 ;
cluster - > pos - = 4 ;
res = ebml_parse ( matroska ,
matroska_clusters ,
& matroska - > current_ cluster) ;
cluster ) ;
/* Try parsing the block again. */
if ( res = = 1 )
res = ebml_parse ( matroska ,
matroska_cluster_parsing ,
& matroska - > current_ cluster) ;
cluster ) ;
}
if ( ! res & &
matroska - > current_cluster_num_blocks <
matroska - > current_cluster . blocks . nb_elem ) {
blocks_list = & matroska - > current_cluster . blocks ;
blocks = blocks_list - > elem ;
if ( ! res & & block - > bin . size > 0 ) {
int is_keyframe = block - > non_simple ? block - > reference = = INT64_MIN : - 1 ;
uint8_t * additional = block - > additional . size > 0 ?
block - > additional . data : NULL ;
matroska - > current_cluster_num_blocks = blocks_list - > nb_elem ;
i = blocks_list - > nb_elem - 1 ;
if ( blocks [ i ] . bin . size > 0 & & blocks [ i ] . bin . data ) {
int is_keyframe = blocks [ i ] . non_simple ? blocks [ i ] . reference = = INT64_MIN : - 1 ;
uint8_t * additional = blocks [ i ] . additional . size > 0 ?
blocks [ i ] . additional . data : NULL ;
res = matroska_parse_block ( matroska , blocks [ i ] . bin . buf , blocks [ i ] . bin . data ,
blocks [ i ] . bin . size , blocks [ i ] . bin . pos ,
res = matroska_parse_block ( matroska , block - > bin . buf , block - > bin . data ,
block - > bin . size , block - > bin . pos ,
matroska - > current_cluster . timecode ,
blocks [ i ] . duration , is_keyframe ,
additional , blocks [ i ] . additional_id ,
blocks [ i ] . additional . size ,
matroska - > current_cluster_pos ,
blocks [ i ] . discard_padding ) ;
}
block - > duration , is_keyframe ,
additional , block - > additional_id ,
block - > additional . size ,
cluster - > pos ,
block - > discard_padding ) ;
}
ebml_free ( matroska_blockgroup , block ) ;
memset ( block , 0 , sizeof ( * block ) ) ;
return res ;
}
@ -3600,7 +3590,6 @@ static int matroska_read_close(AVFormatContext *s)
for ( n = 0 ; n < matroska - > tracks . nb_elem ; n + + )
if ( tracks [ n ] . type = = MATROSKA_TRACK_TYPE_AUDIO )
av_freep ( & tracks [ n ] . audio . buf ) ;
ebml_free ( matroska_cluster_parsing , & matroska - > current_cluster ) ;
ebml_free ( matroska_segment , matroska ) ;
return 0 ;