]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/cafdec.c
ffplay: get rid of void casts in the option table
[ffmpeg] / libavformat / cafdec.c
index 6fad878566d39a717393cb6d74aab6836d914aba..f1682b0d343007383279706ccbcd2ae36f2d5457 100644 (file)
@@ -29,6 +29,7 @@
 #include "internal.h"
 #include "riff.h"
 #include "isom.h"
+#include "mov_chan.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/intfloat.h"
 #include "libavutil/dict.h"
@@ -102,7 +103,7 @@ static int read_kuki_chunk(AVFormatContext *s, int64_t size)
     if (size < 0 || size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE)
         return -1;
 
-    if (st->codec->codec_id == CODEC_ID_AAC) {
+    if (st->codec->codec_id == AV_CODEC_ID_AAC) {
         /* The magic cookie format for AAC is an mp4 esds atom.
            The lavc AAC decoder requires the data from the codec specific
            description as extradata input. */
@@ -113,36 +114,48 @@ static int read_kuki_chunk(AVFormatContext *s, int64_t size)
         ff_mov_read_esds(s, pb, atom);
         skip = size - (avio_tell(pb) - strt);
         if (skip < 0 || !st->codec->extradata ||
-            st->codec->codec_id != CODEC_ID_AAC) {
+            st->codec->codec_id != AV_CODEC_ID_AAC) {
             av_log(s, AV_LOG_ERROR, "invalid AAC magic cookie\n");
             return AVERROR_INVALIDDATA;
         }
         avio_skip(pb, skip);
-    } else if (st->codec->codec_id == CODEC_ID_ALAC) {
+    } else if (st->codec->codec_id == AV_CODEC_ID_ALAC) {
 #define ALAC_PREAMBLE 12
 #define ALAC_HEADER   36
 #define ALAC_NEW_KUKI 24
-        if (size == ALAC_NEW_KUKI) {
-            st->codec->extradata = av_mallocz(ALAC_HEADER + FF_INPUT_BUFFER_PADDING_SIZE);
-            if (!st->codec->extradata)
-                return AVERROR(ENOMEM);
-            memcpy(st->codec->extradata, "\0\0\0\24alac", 8);
-            avio_read(pb, st->codec->extradata + ALAC_HEADER - ALAC_NEW_KUKI, ALAC_NEW_KUKI);
-            st->codec->extradata_size = ALAC_HEADER;
-        } else {
+        uint8_t preamble[12];
+        if (size < ALAC_NEW_KUKI) {
+            av_log(s, AV_LOG_ERROR, "invalid ALAC magic cookie\n");
+            avio_skip(pb, size);
+            return AVERROR_INVALIDDATA;
+        }
+        avio_read(pb, preamble, ALAC_PREAMBLE);
+
+        st->codec->extradata = av_mallocz(ALAC_HEADER + FF_INPUT_BUFFER_PADDING_SIZE);
+        if (!st->codec->extradata)
+            return AVERROR(ENOMEM);
+
+        /* For the old style cookie, we skip 12 bytes, then read 36 bytes.
+         * The new style cookie only contains the last 24 bytes of what was
+         * 36 bytes in the old style cookie, so we fabricate the first 12 bytes
+         * in that case to maintain compatibility. */
+        if (!memcmp(&preamble[4], "frmaalac", 8)) {
             if (size < ALAC_PREAMBLE + ALAC_HEADER) {
                 av_log(s, AV_LOG_ERROR, "invalid ALAC magic cookie\n");
-                avio_skip(pb, size);
+                av_freep(&st->codec->extradata);
                 return AVERROR_INVALIDDATA;
             }
-            avio_skip(pb, ALAC_PREAMBLE);
-            st->codec->extradata = av_mallocz(ALAC_HEADER + FF_INPUT_BUFFER_PADDING_SIZE);
-            if (!st->codec->extradata)
-                return AVERROR(ENOMEM);
             avio_read(pb, st->codec->extradata, ALAC_HEADER);
-            st->codec->extradata_size = ALAC_HEADER;
             avio_skip(pb, size - ALAC_PREAMBLE - ALAC_HEADER);
+        } else {
+            AV_WB32(st->codec->extradata, 36);
+            memcpy(&st->codec->extradata[4], "alac", 4);
+            AV_WB32(&st->codec->extradata[8], 0);
+            memcpy(&st->codec->extradata[12], preamble, 12);
+            avio_read(pb, &st->codec->extradata[24], ALAC_NEW_KUKI - 12);
+            avio_skip(pb, size - ALAC_NEW_KUKI);
         }
+        st->codec->extradata_size = ALAC_HEADER;
     } else {
         st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE);
         if (!st->codec->extradata)
@@ -160,8 +173,8 @@ static int read_pakt_chunk(AVFormatContext *s, int64_t size)
     AVIOContext *pb = s->pb;
     AVStream *st      = s->streams[0];
     CaffContext *caf  = s->priv_data;
-    int64_t pos = 0, ccount;
-    int num_packets, i;
+    int64_t pos = 0, ccount, num_packets;
+    int i;
 
     ccount = avio_tell(pb);
 
@@ -180,10 +193,11 @@ static int read_pakt_chunk(AVFormatContext *s, int64_t size)
         st->duration += caf->frames_per_packet ? caf->frames_per_packet : ff_mp4_read_descr_len(pb);
     }
 
-    if (avio_tell(pb) - ccount != size) {
+    if (avio_tell(pb) - ccount > size) {
         av_log(s, AV_LOG_ERROR, "error reading packet table\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
+    avio_skip(pb, ccount + size - avio_tell(pb));
 
     caf->num_bytes = pos;
     return 0;
@@ -253,6 +267,11 @@ static int read_header(AVFormatContext *s)
             found_data = 1;
             break;
 
+        case MKBETAG('c','h','a','n'):
+            if ((ret = ff_mov_read_chan(s, st, size)) < 0)
+                return ret;
+            break;
+
         /* magic cookie chunk */
         case MKBETAG('k','u','k','i'):
             if (read_kuki_chunk(s, size))
@@ -269,12 +288,6 @@ static int read_header(AVFormatContext *s)
             read_info_chunk(s, size);
             break;
 
-        case MKBETAG('c','h','a','n'):
-            if (size < 12)
-                return AVERROR_INVALIDDATA;
-            ff_mov_read_chan(s, size, st->codec);
-            break;
-
         default:
 #define _(x) ((x) >= ' ' ? (x) : ' ')
             av_log(s, AV_LOG_WARNING, "skipping CAF chunk: %08X (%c%c%c%c), size %"PRId64"\n",
@@ -404,7 +417,7 @@ static int read_seek(AVFormatContext *s, int stream_index,
 
 AVInputFormat ff_caf_demuxer = {
     .name           = "caf",
-    .long_name      = NULL_IF_CONFIG_SMALL("Apple Core Audio Format"),
+    .long_name      = NULL_IF_CONFIG_SMALL("Apple CAF (Core Audio Format)"),
     .priv_data_size = sizeof(CaffContext),
     .read_probe     = probe,
     .read_header    = read_header,