summaryrefslogtreecommitdiff
path: root/libavformat/matroskadec.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavformat/matroskadec.c')
-rw-r--r--libavformat/matroskadec.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index 77c4eb0f07..65847fa17b 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -56,6 +56,7 @@
#include "internal.h"
#include "isom.h"
#include "matroska.h"
+#include "oggdec.h"
/* For ff_codec_get_id(). */
#include "riff.h"
#include "rmsipr.h"
@@ -1575,6 +1576,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;
@@ -1586,6 +1588,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;
}