avformat: use avpriv_mpeg4audio_get_config2()
[ffmpeg.git] / libavformat / matroskaenc.c
index 15164bd..a64ffdb 100644 (file)
@@ -58,9 +58,8 @@
 #include "libavcodec/internal.h"
 
 typedef struct ebml_master {
-    int64_t         pos;                ///< absolute offset in the containing AVIOContext where the size field starts
-                                        ///< for level 1 elements or else where the master's elements start
-    int             sizebytes;          ///< how many bytes were reserved/shall be used for the size
+    int64_t         pos;                ///< absolute offset in the containing AVIOContext where the master's elements start
+    int             sizebytes;          ///< how many bytes were reserved for the size
 } ebml_master;
 
 typedef struct mkv_seekhead_entry {
@@ -122,15 +121,14 @@ typedef struct MatroskaMuxContext {
     const AVClass   *class;
     int             mode;
     AVIOContext     *tags_bc;
-    ebml_master     tags;
+    int64_t         tags_pos;
     AVIOContext     *info_bc;
-    ebml_master     info;
+    int64_t         info_pos;
     AVIOContext     *tracks_bc;
-    ebml_master     tracks_master;
+    int64_t         tracks_pos;
     ebml_master     segment;
     int64_t         segment_offset;
     AVIOContext     *cluster_bc;
-    ebml_master     cluster;
     int64_t         cluster_pos;        ///< file offset of the current cluster
     int64_t         cluster_pts;
     int64_t         duration_offset;
@@ -334,29 +332,27 @@ static void end_ebml_master(AVIOContext *pb, ebml_master master)
 }
 
 static int start_ebml_master_crc32(AVIOContext *pb, AVIOContext **dyn_cp, MatroskaMuxContext *mkv,
-                                   ebml_master *master, uint32_t elementid, uint64_t expectedsize)
+                                   uint32_t elementid)
 {
-    int ret, bytes = expectedsize ? ebml_num_size(expectedsize) : 8;
+    int ret;
 
     if ((ret = avio_open_dyn_buf(dyn_cp)) < 0)
         return ret;
 
     put_ebml_id(pb, elementid);
-    *master = (ebml_master) { avio_tell(pb), bytes };
     if (mkv->write_crc)
         put_ebml_void(*dyn_cp, 6); /* Reserve space for CRC32 so position/size calculations using avio_tell() take it into account */
 
     return 0;
 }
 
-static void end_ebml_master_crc32(AVIOContext *pb, AVIOContext **dyn_cp, MatroskaMuxContext *mkv,
-                                  ebml_master master)
+static void end_ebml_master_crc32(AVIOContext *pb, AVIOContext **dyn_cp, MatroskaMuxContext *mkv)
 {
     uint8_t *buf, crc[4];
     int size, skip = 0;
 
     size = avio_close_dyn_buf(*dyn_cp, &buf);
-    put_ebml_num(pb, size, master.sizebytes);
+    put_ebml_num(pb, size, 0);
     if (mkv->write_crc) {
         skip = 6; /* Skip reserved 6-byte long void element from the dynamic buffer. */
         AV_WL32(crc, av_crc(av_crc_get_table(AV_CRC_32_IEEE_LE), UINT32_MAX, buf + skip, size - skip) ^ UINT32_MAX);
@@ -372,12 +368,14 @@ static void end_ebml_master_crc32(AVIOContext *pb, AVIOContext **dyn_cp, Matrosk
 * Complete ebml master without destroying the buffer, allowing for later updates
 */
 static void end_ebml_master_crc32_preliminary(AVIOContext *pb, AVIOContext **dyn_cp, MatroskaMuxContext *mkv,
-                                              ebml_master master)
+                                              int64_t *pos)
 {
     uint8_t *buf;
     int size = avio_get_dyn_buf(*dyn_cp, &buf);
 
-    put_ebml_num(pb, size, master.sizebytes);
+    *pos = avio_tell(pb);
+
+    put_ebml_num(pb, size, 0);
     avio_write(pb, buf, size);
 }
 
@@ -489,7 +487,7 @@ static int64_t mkv_write_seekhead(AVIOContext *pb, MatroskaMuxContext *mkv)
 {
     AVIOContext *dyn_cp;
     mkv_seekhead *seekhead = mkv->seekhead;
-    ebml_master metaseek, seekentry;
+    ebml_master seekentry;
     int64_t currentpos;
     int i;
 
@@ -502,8 +500,7 @@ static int64_t mkv_write_seekhead(AVIOContext *pb, MatroskaMuxContext *mkv)
         }
     }
 
-    if (start_ebml_master_crc32(pb, &dyn_cp, mkv, &metaseek, MATROSKA_ID_SEEKHEAD,
-                                seekhead->reserved_size) < 0) {
+    if (start_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_SEEKHEAD) < 0) {
         currentpos = -1;
         goto fail;
     }
@@ -520,7 +517,7 @@ static int64_t mkv_write_seekhead(AVIOContext *pb, MatroskaMuxContext *mkv)
         put_ebml_uint(dyn_cp, MATROSKA_ID_SEEKPOSITION, entry->segmentpos);
         end_ebml_master(dyn_cp, seekentry);
     }
-    end_ebml_master_crc32(pb, &dyn_cp, mkv, metaseek);
+    end_ebml_master_crc32(pb, &dyn_cp, mkv);
 
     if (seekhead->reserved_size > 0) {
         uint64_t remaining = seekhead->filepos + seekhead->reserved_size - avio_tell(pb);
@@ -573,12 +570,11 @@ static int64_t mkv_write_cues(AVFormatContext *s, mkv_cues *cues, mkv_track *tra
 {
     MatroskaMuxContext *mkv = s->priv_data;
     AVIOContext *dyn_cp, *pb = s->pb;
-    ebml_master cues_element;
     int64_t currentpos;
     int i, j, ret;
 
     currentpos = avio_tell(pb);
-    ret = start_ebml_master_crc32(pb, &dyn_cp, mkv, &cues_element, MATROSKA_ID_CUES, 0);
+    ret = start_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_CUES);
     if (ret < 0)
         return ret;
 
@@ -624,7 +620,7 @@ static int64_t mkv_write_cues(AVFormatContext *s, mkv_cues *cues, mkv_track *tra
         i += j - 1;
         end_ebml_master(dyn_cp, cuepoint);
     }
-    end_ebml_master_crc32(pb, &dyn_cp, mkv, cues_element);
+    end_ebml_master_crc32(pb, &dyn_cp, mkv);
 
     return currentpos;
 }
@@ -721,8 +717,7 @@ static int get_aac_sample_rates(AVFormatContext *s, uint8_t *extradata, int extr
     MPEG4AudioConfig mp4ac;
     int ret;
 
-    ret = avpriv_mpeg4audio_get_config(&mp4ac, extradata,
-                                       extradata_size * 8, 1);
+    ret = avpriv_mpeg4audio_get_config2(&mp4ac, extradata, extradata_size, 1, s);
     /* Don't abort if the failure is because of missing extradata. Assume in that
      * case a bitstream filter will provide the muxer with the extradata in the
      * first packet.
@@ -1454,7 +1449,7 @@ static int mkv_write_tracks(AVFormatContext *s)
     if (ret < 0)
         return ret;
 
-    ret = start_ebml_master_crc32(pb, &mkv->tracks_bc, mkv, &mkv->tracks_master, MATROSKA_ID_TRACKS, 0);
+    ret = start_ebml_master_crc32(pb, &mkv->tracks_bc, mkv, MATROSKA_ID_TRACKS);
     if (ret < 0)
         return ret;
 
@@ -1469,9 +1464,9 @@ static int mkv_write_tracks(AVFormatContext *s)
     }
 
     if ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live)
-        end_ebml_master_crc32_preliminary(pb, &mkv->tracks_bc, mkv, mkv->tracks_master);
+        end_ebml_master_crc32_preliminary(pb, &mkv->tracks_bc, mkv, &mkv->tracks_pos);
     else
-        end_ebml_master_crc32(pb, &mkv->tracks_bc, mkv, mkv->tracks_master);
+        end_ebml_master_crc32(pb, &mkv->tracks_bc, mkv);
 
     return 0;
 }
@@ -1480,7 +1475,7 @@ static int mkv_write_chapters(AVFormatContext *s)
 {
     MatroskaMuxContext *mkv = s->priv_data;
     AVIOContext *dyn_cp, *pb = s->pb;
-    ebml_master chapters, editionentry;
+    ebml_master editionentry;
     AVRational scale = {1, 1E9};
     int i, ret;
 
@@ -1490,7 +1485,7 @@ static int mkv_write_chapters(AVFormatContext *s)
     ret = mkv_add_seekhead_entry(mkv->seekhead, MATROSKA_ID_CHAPTERS, avio_tell(pb));
     if (ret < 0) return ret;
 
-    ret = start_ebml_master_crc32(pb, &dyn_cp, mkv, &chapters, MATROSKA_ID_CHAPTERS, 0);
+    ret = start_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_CHAPTERS);
     if (ret < 0) return ret;
 
     editionentry = start_ebml_master(dyn_cp, MATROSKA_ID_EDITIONENTRY, 0);
@@ -1528,7 +1523,7 @@ static int mkv_write_chapters(AVFormatContext *s)
         end_ebml_master(dyn_cp, chapteratom);
     }
     end_ebml_master(dyn_cp, editionentry);
-    end_ebml_master_crc32(pb, &dyn_cp, mkv, chapters);
+    end_ebml_master_crc32(pb, &dyn_cp, mkv);
 
     mkv->wrote_chapters = 1;
     return 0;
@@ -1569,19 +1564,18 @@ static int mkv_write_simpletag(AVIOContext *pb, AVDictionaryEntry *t)
 }
 
 static int mkv_write_tag_targets(AVFormatContext *s, uint32_t elementid,
-                                 unsigned int uid, ebml_master *tags,
-                                 ebml_master* tag)
+                                 unsigned int uid, ebml_master *tag)
 {
     AVIOContext *pb;
     MatroskaMuxContext *mkv = s->priv_data;
     ebml_master targets;
     int ret;
 
-    if (!tags->pos) {
+    if (!mkv->tags_bc) {
         ret = mkv_add_seekhead_entry(mkv->seekhead, MATROSKA_ID_TAGS, avio_tell(s->pb));
         if (ret < 0) return ret;
 
-        start_ebml_master_crc32(s->pb, &mkv->tags_bc, mkv, tags, MATROSKA_ID_TAGS, 0);
+        start_ebml_master_crc32(s->pb, &mkv->tags_bc, mkv, MATROSKA_ID_TAGS);
     }
     pb = mkv->tags_bc;
 
@@ -1608,14 +1602,14 @@ static int mkv_check_tag_name(const char *name, uint32_t elementid)
 }
 
 static int mkv_write_tag(AVFormatContext *s, AVDictionary *m, uint32_t elementid,
-                         unsigned int uid, ebml_master *tags)
+                         unsigned int uid)
 {
     MatroskaMuxContext *mkv = s->priv_data;
     ebml_master tag;
     int ret;
     AVDictionaryEntry *t = NULL;
 
-    ret = mkv_write_tag_targets(s, elementid, uid, tags, &tag);
+    ret = mkv_write_tag_targets(s, elementid, uid, &tag);
     if (ret < 0)
         return ret;
 
@@ -1650,7 +1644,7 @@ static int mkv_write_tags(AVFormatContext *s)
     ff_metadata_conv_ctx(s, ff_mkv_metadata_conv, NULL);
 
     if (mkv_check_tag(s->metadata, 0)) {
-        ret = mkv_write_tag(s, s->metadata, 0, 0, &mkv->tags);
+        ret = mkv_write_tag(s, s->metadata, 0, 0);
         if (ret < 0) return ret;
     }
 
@@ -1663,7 +1657,7 @@ static int mkv_write_tags(AVFormatContext *s)
         if (!mkv_check_tag(st->metadata, MATROSKA_ID_TAGTARGETS_TRACKUID))
             continue;
 
-        ret = mkv_write_tag(s, st->metadata, MATROSKA_ID_TAGTARGETS_TRACKUID, i + 1, &mkv->tags);
+        ret = mkv_write_tag(s, st->metadata, MATROSKA_ID_TAGTARGETS_TRACKUID, i + 1);
         if (ret < 0) return ret;
     }
 
@@ -1677,7 +1671,7 @@ static int mkv_write_tags(AVFormatContext *s)
             if (st->codecpar->codec_type == AVMEDIA_TYPE_ATTACHMENT)
                 continue;
 
-            mkv_write_tag_targets(s, MATROSKA_ID_TAGTARGETS_TRACKUID, i + 1, &mkv->tags, &tag_target);
+            mkv_write_tag_targets(s, MATROSKA_ID_TAGTARGETS_TRACKUID, i + 1, &tag_target);
             pb = mkv->tags_bc;
 
             tag = start_ebml_master(pb, MATROSKA_ID_SIMPLETAG, 0);
@@ -1699,7 +1693,7 @@ static int mkv_write_tags(AVFormatContext *s)
             if (!mkv_check_tag(ch->metadata, MATROSKA_ID_TAGTARGETS_CHAPTERUID))
                 continue;
 
-            ret = mkv_write_tag(s, ch->metadata, MATROSKA_ID_TAGTARGETS_CHAPTERUID, ch->id + mkv->chapter_id_offset, &mkv->tags);
+            ret = mkv_write_tag(s, ch->metadata, MATROSKA_ID_TAGTARGETS_CHAPTERUID, ch->id + mkv->chapter_id_offset);
             if (ret < 0)
                 return ret;
         }
@@ -1713,17 +1707,17 @@ static int mkv_write_tags(AVFormatContext *s)
             if (!mkv_check_tag(st->metadata, MATROSKA_ID_TAGTARGETS_ATTACHUID))
                 continue;
 
-            ret = mkv_write_tag(s, st->metadata, MATROSKA_ID_TAGTARGETS_ATTACHUID, attachment->fileuid, &mkv->tags);
+            ret = mkv_write_tag(s, st->metadata, MATROSKA_ID_TAGTARGETS_ATTACHUID, attachment->fileuid);
             if (ret < 0)
                 return ret;
         }
     }
 
-    if (mkv->tags.pos) {
+    if (mkv->tags_bc) {
         if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live)
-            end_ebml_master_crc32_preliminary(s->pb, &mkv->tags_bc, mkv, mkv->tags);
+            end_ebml_master_crc32_preliminary(s->pb, &mkv->tags_bc, mkv, &mkv->tags_pos);
         else
-            end_ebml_master_crc32(s->pb, &mkv->tags_bc, mkv, mkv->tags);
+            end_ebml_master_crc32(s->pb, &mkv->tags_bc, mkv);
     }
     return 0;
 }
@@ -1732,7 +1726,6 @@ static int mkv_write_attachments(AVFormatContext *s)
 {
     MatroskaMuxContext *mkv = s->priv_data;
     AVIOContext *dyn_cp, *pb = s->pb;
-    ebml_master attachments;
     AVLFG c;
     int i, ret;
 
@@ -1748,7 +1741,7 @@ static int mkv_write_attachments(AVFormatContext *s)
     ret = mkv_add_seekhead_entry(mkv->seekhead, MATROSKA_ID_ATTACHMENTS, avio_tell(pb));
     if (ret < 0) return ret;
 
-    ret = start_ebml_master_crc32(pb, &dyn_cp, mkv, &attachments, MATROSKA_ID_ATTACHMENTS, 0);
+    ret = start_ebml_master_crc32(pb, &dyn_cp, mkv, MATROSKA_ID_ATTACHMENTS);
     if (ret < 0) return ret;
 
     for (i = 0; i < s->nb_streams; i++) {
@@ -1821,7 +1814,7 @@ static int mkv_write_attachments(AVFormatContext *s)
         mkv->attachments->entries[mkv->attachments->num_entries].stream_idx = i;
         mkv->attachments->entries[mkv->attachments->num_entries++].fileuid  = fileuid;
     }
-    end_ebml_master_crc32(pb, &dyn_cp, mkv, attachments);
+    end_ebml_master_crc32(pb, &dyn_cp, mkv);
 
     return 0;
 }
@@ -1907,7 +1900,7 @@ static int mkv_write_header(AVFormatContext *s)
     ret = mkv_add_seekhead_entry(mkv->seekhead, MATROSKA_ID_INFO, avio_tell(pb));
     if (ret < 0) goto fail;
 
-    ret = start_ebml_master_crc32(pb, &mkv->info_bc, mkv, &mkv->info, MATROSKA_ID_INFO, 0);
+    ret = start_ebml_master_crc32(pb, &mkv->info_bc, mkv, MATROSKA_ID_INFO);
     if (ret < 0)
         return ret;
     pb = mkv->info_bc;
@@ -1966,9 +1959,9 @@ static int mkv_write_header(AVFormatContext *s)
         }
     }
     if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) && !mkv->is_live)
-        end_ebml_master_crc32_preliminary(s->pb, &mkv->info_bc, mkv, mkv->info);
+        end_ebml_master_crc32_preliminary(s->pb, &mkv->info_bc, mkv, &mkv->info_pos);
     else
-        end_ebml_master_crc32(s->pb, &mkv->info_bc, mkv, mkv->info);
+        end_ebml_master_crc32(s->pb, &mkv->info_bc, mkv);
     pb = s->pb;
 
     // initialize stream_duration fields
@@ -2125,10 +2118,14 @@ static void mkv_write_block(AVFormatContext *s, AVIOContext *pb,
 
     ts += mkv->tracks[pkt->stream_index].ts_offset;
 
-    av_log(s, AV_LOG_DEBUG, "Writing block at offset %" PRIu64 ", size %d, "
-           "pts %" PRId64 ", dts %" PRId64 ", duration %" PRId64 ", keyframe %d\n",
-           avio_tell(pb), pkt->size, pkt->pts, pkt->dts, pkt->duration,
-           keyframe != 0);
+    /* The following string is identical to the one in mkv_write_vtt_blocks
+     * so that only one copy needs to exist in binaries. */
+    av_log(s, AV_LOG_DEBUG,
+           "Writing block of size %d with pts %" PRId64 ", dts %" PRId64 ", "
+           "duration %" PRId64 " at relative offset %" PRId64 " in cluster "
+           "at offset %" PRId64 ". TrackNumber %d, keyframe %d\n",
+           pkt->size, pkt->pts, pkt->dts, pkt->duration, avio_tell(pb),
+           mkv->cluster_pos, track_number, keyframe != 0);
     if (par->codec_id == AV_CODEC_ID_H264 && par->extradata_size > 0 &&
         (AV_RB24(par->extradata) == 1 || AV_RB32(par->extradata) == 1))
         ff_avc_parse_nal_units_buf(pkt->data, &data, &size);
@@ -2232,9 +2229,14 @@ static int mkv_write_vtt_blocks(AVFormatContext *s, AVIOContext *pb, AVPacket *p
 
     size = id_size + 1 + settings_size + 1 + pkt->size;
 
-    av_log(s, AV_LOG_DEBUG, "Writing block at offset %" PRIu64 ", size %d, "
-           "pts %" PRId64 ", dts %" PRId64 ", duration %" PRId64 ", flags %d\n",
-           avio_tell(pb), size, pkt->pts, pkt->dts, pkt->duration, flags);
+    /* The following string is identical to the one in mkv_write_block so that
+     * only one copy needs to exist in binaries. */
+    av_log(s, AV_LOG_DEBUG,
+           "Writing block of size %d with pts %" PRId64 ", dts %" PRId64 ", "
+           "duration %" PRId64 " at relative offset %" PRId64 " in cluster "
+           "at offset %" PRId64 ". TrackNumber %d, keyframe %d\n",
+           size, pkt->pts, pkt->dts, pkt->duration, avio_tell(pb),
+           mkv->cluster_pos, pkt->stream_index + 1, 1);
 
     blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, mkv_blockgroup_size(size));
 
@@ -2255,7 +2257,7 @@ static void mkv_start_new_cluster(AVFormatContext *s, AVPacket *pkt)
 {
     MatroskaMuxContext *mkv = s->priv_data;
 
-    end_ebml_master_crc32(s->pb, &mkv->cluster_bc, mkv, mkv->cluster);
+    end_ebml_master_crc32(s->pb, &mkv->cluster_bc, mkv);
     mkv->cluster_pos = -1;
     av_log(s, AV_LOG_DEBUG,
            "Starting new cluster at offset %" PRIu64 " bytes, "
@@ -2400,7 +2402,7 @@ static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt, int add_
 
     if (mkv->cluster_pos == -1) {
         mkv->cluster_pos = avio_tell(s->pb);
-        ret = start_ebml_master_crc32(s->pb, &mkv->cluster_bc, mkv, &mkv->cluster, MATROSKA_ID_CLUSTER, 0);
+        ret = start_ebml_master_crc32(s->pb, &mkv->cluster_bc, mkv, MATROSKA_ID_CLUSTER);
         if (ret < 0)
             return ret;
         put_ebml_uint(mkv->cluster_bc, MATROSKA_ID_CLUSTERTIMECODE, FFMAX(0, ts));
@@ -2536,7 +2538,7 @@ static int mkv_write_flush_packet(AVFormatContext *s, AVPacket *pkt)
 
     if (!pkt) {
         if (mkv->cluster_pos != -1) {
-            end_ebml_master_crc32(s->pb, &mkv->cluster_bc, mkv, mkv->cluster);
+            end_ebml_master_crc32(s->pb, &mkv->cluster_bc, mkv);
             mkv->cluster_pos = -1;
             av_log(s, AV_LOG_DEBUG,
                    "Flushing cluster at offset %" PRIu64 " bytes\n",
@@ -2567,7 +2569,7 @@ static int mkv_write_trailer(AVFormatContext *s)
     }
 
     if (mkv->cluster_bc) {
-        end_ebml_master_crc32(pb, &mkv->cluster_bc, mkv, mkv->cluster);
+        end_ebml_master_crc32(pb, &mkv->cluster_bc, mkv);
     }
 
     ret = mkv_write_chapters(s);
@@ -2615,12 +2617,12 @@ static int mkv_write_trailer(AVFormatContext *s)
         currentpos = avio_tell(pb);
         avio_seek(mkv->info_bc, mkv->duration_offset, SEEK_SET);
         put_ebml_float(mkv->info_bc, MATROSKA_ID_DURATION, mkv->duration);
-        avio_seek(pb, mkv->info.pos, SEEK_SET);
-        end_ebml_master_crc32(pb, &mkv->info_bc, mkv, mkv->info);
+        avio_seek(pb, mkv->info_pos, SEEK_SET);
+        end_ebml_master_crc32(pb, &mkv->info_bc, mkv);
 
         // write tracks master
-        avio_seek(pb, mkv->tracks_master.pos, SEEK_SET);
-        end_ebml_master_crc32(pb, &mkv->tracks_bc, mkv, mkv->tracks_master);
+        avio_seek(pb, mkv->tracks_pos, SEEK_SET);
+        end_ebml_master_crc32(pb, &mkv->tracks_bc, mkv);
 
         // update stream durations
         if (!mkv->is_live && mkv->stream_durations) {
@@ -2647,9 +2649,9 @@ static int mkv_write_trailer(AVFormatContext *s)
             }
             avio_seek(mkv->tags_bc, curr, SEEK_SET);
         }
-        if (mkv->tags.pos && !mkv->is_live) {
-            avio_seek(pb, mkv->tags.pos, SEEK_SET);
-            end_ebml_master_crc32(pb, &mkv->tags_bc, mkv, mkv->tags);
+        if (mkv->tags_bc && !mkv->is_live) {
+            avio_seek(pb, mkv->tags_pos, SEEK_SET);
+            end_ebml_master_crc32(pb, &mkv->tags_bc, mkv);
         }
 
         avio_seek(pb, currentpos, SEEK_SET);