|
|
|
@ -55,6 +55,7 @@ |
|
|
|
|
#include "internal.h" |
|
|
|
|
#include "isom.h" |
|
|
|
|
#include "matroska.h" |
|
|
|
|
#include "oggdec.h" |
|
|
|
|
/* For ff_codec_get_id(). */ |
|
|
|
|
#include "riff.h" |
|
|
|
|
#include "rmsipr.h" |
|
|
|
@ -1443,6 +1444,7 @@ static int matroska_parse_flac(AVFormatContext *s, |
|
|
|
|
MatroskaTrack *track, |
|
|
|
|
int *offset) |
|
|
|
|
{ |
|
|
|
|
AVStream *st = track->stream; |
|
|
|
|
uint8_t *p = track->codec_priv.data; |
|
|
|
|
int size = track->codec_priv.size; |
|
|
|
|
|
|
|
|
@ -1454,6 +1456,42 @@ static int matroska_parse_flac(AVFormatContext *s, |
|
|
|
|
*offset = 8; |
|
|
|
|
track->codec_priv.size = 8 + FLAC_STREAMINFO_SIZE; |
|
|
|
|
|
|
|
|
|
p += track->codec_priv.size; |
|
|
|
|
size -= track->codec_priv.size; |
|
|
|
|
|
|
|
|
|
/* parse the remaining metadata blocks if present */ |
|
|
|
|
while (size >= 4) { |
|
|
|
|
int block_last, block_type, block_size; |
|
|
|
|
|
|
|
|
|
flac_parse_block_header(p, &block_last, &block_type, &block_size); |
|
|
|
|
|
|
|
|
|
p += 4; |
|
|
|
|
size -= 4; |
|
|
|
|
if (block_size > size) |
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
/* check for the channel mask */ |
|
|
|
|
if (block_type == FLAC_METADATA_TYPE_VORBIS_COMMENT) { |
|
|
|
|
AVDictionary *dict = NULL; |
|
|
|
|
AVDictionaryEntry *chmask; |
|
|
|
|
|
|
|
|
|
ff_vorbis_comment(s, &dict, p, block_size, 0); |
|
|
|
|
chmask = av_dict_get(dict, "WAVEFORMATEXTENSIBLE_CHANNEL_MASK", NULL, 0); |
|
|
|
|
if (chmask) { |
|
|
|
|
uint64_t mask = strtol(chmask->value, NULL, 0); |
|
|
|
|
if (!mask || mask & ~0x3ffffULL) { |
|
|
|
|
av_log(s, AV_LOG_WARNING, |
|
|
|
|
"Invalid value of WAVEFORMATEXTENSIBLE_CHANNEL_MASK\n"); |
|
|
|
|
} else |
|
|
|
|
st->codec->channel_layout = mask; |
|
|
|
|
} |
|
|
|
|
av_dict_free(&dict); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
p += block_size; |
|
|
|
|
size -= block_size; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|