]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/matroskadec.c
avcodec/mpegvideo: fix edge emulation with uvlinesize below 25
[ffmpeg] / libavformat / matroskadec.c
index 77c4eb0f077585bf4488c3d5d40b491bd5459865..213767c646828065f50c59b9a688732d89c452c1 100644 (file)
@@ -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;
 }
 
@@ -2980,7 +3018,7 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index,
                 tracks[i].stream, st->index_entries[index].timestamp,
                 AVSEEK_FLAG_BACKWARD);
             while (index_sub >= 0 &&
-                  index_min >= 0 &&
+                  index_min > 0 &&
                   tracks[i].stream->index_entries[index_sub].pos < st->index_entries[index_min].pos &&
                   st->index_entries[index].timestamp - tracks[i].stream->index_entries[index_sub].timestamp < 30000000000 / matroska->time_scale)
                 index_min--;