[FFmpeg-devel] [PATCH] Implement muxing AAC in a CAFF container
Lewis Fox
lrflew.coll at gmail.com
Sat Nov 10 05:58:41 EET 2018
From: Lewis Fox <LRFLEW at aol.com>
Signed-off-by: Lewis Fox <LRFLEW at aol.com>
---
libavformat/cafenc.c | 61 ++++++++++++++++++++++++++++++++++++------
libavformat/mov.c | 1 +
libavformat/mov_esds.c | 1 -
3 files changed, 54 insertions(+), 9 deletions(-)
diff --git a/libavformat/cafenc.c b/libavformat/cafenc.c
index 0f7c4ebbb3..0eb3c27ad6 100644
--- a/libavformat/cafenc.c
+++ b/libavformat/cafenc.c
@@ -83,6 +83,8 @@ static uint32_t samples_per_packet(enum AVCodecID codec_id, int channels, int bl
return 384;
case AV_CODEC_ID_OPUS:
return 960;
+ case AV_CODEC_ID_AAC:
+ return 1024;
case AV_CODEC_ID_MP2:
case AV_CODEC_ID_MP3:
return 1152;
@@ -102,10 +104,57 @@ static uint32_t samples_per_packet(enum AVCodecID codec_id, int channels, int bl
}
}
+static void put_descr(AVIOContext *pb, int tag, unsigned int size)
+{
+ int i = 3;
+ avio_w8(pb, tag);
+ for (; i > 0; i--)
+ avio_w8(pb, (size >> (7 * i)) | 0x80);
+ avio_w8(pb, size & 0x7F);
+}
+
+static void caf_write_aac_kuki(AVIOContext *pb, AVStream *stream) {
+ AVCodecParameters *par = stream->codecpar;
+ int decoder_specific_info_len = par->extradata_size ? 5 + par->extradata_size : 0;
+
+ ffio_wfourcc(pb, "kuki");
+ avio_wb64(pb, 5 + 3 + 5 + 13 + decoder_specific_info_len + 5 + 1); // size
+
+ // ES descriptor
+ put_descr(pb, MP4ESDescrTag, 3 + 5 + 13 + decoder_specific_info_len + 5 + 1);
+ avio_wb16(pb, 0);
+ avio_w8(pb, 0x00); // flags (= no flags)
+
+ // DecoderConfig descriptor
+ put_descr(pb, MP4DecConfigDescrTag, 13 + decoder_specific_info_len);
+
+ // Object type indication
+ avio_w8(pb, ff_codec_get_tag(ff_mp4_obj_type, par->codec_id));
+
+ // the following fields is made of 6 bits to identify the streamtype (5 for audio)
+ // plus 1 bit to indicate upstream and 1 bit set to 1 (reserved)
+ avio_w8(pb, 0x15); // flags (= Audiostream)
+
+ avio_wb24(pb, 6144); // Buffersize DB
+ avio_wb32(pb, par->bit_rate); // max bitrate (FIXME should be max rate in any 1 sec window)
+ avio_wb32(pb, par->bit_rate); // average bitrate (target bitrate, or 0 for VBR)
+
+ if (par->extradata_size) {
+ // DecoderSpecific info descriptor
+ put_descr(pb, MP4DecSpecificDescrTag, par->extradata_size);
+ avio_write(pb, par->extradata, par->extradata_size);
+ }
+
+ // SL descriptor
+ put_descr(pb, MP4SLDescrTag, 1);
+ avio_w8(pb, 0x02);
+}
+
static int caf_write_header(AVFormatContext *s)
{
AVIOContext *pb = s->pb;
- AVCodecParameters *par = s->streams[0]->codecpar;
+ AVStream *stream = s->streams[0];
+ AVCodecParameters *par = stream->codecpar;
CAFContext *caf = s->priv_data;
AVDictionaryEntry *t = NULL;
unsigned int codec_tag = ff_codec_get_tag(ff_codec_caf_tags, par->codec_id);
@@ -117,12 +166,6 @@ static int caf_write_header(AVFormatContext *s)
return AVERROR(EINVAL);
}
- switch (par->codec_id) {
- case AV_CODEC_ID_AAC:
- av_log(s, AV_LOG_ERROR, "muxing codec currently unsupported\n");
- return AVERROR_PATCHWELCOME;
- }
-
if (par->codec_id == AV_CODEC_ID_OPUS && par->channels > 2) {
av_log(s, AV_LOG_ERROR, "Only mono and stereo are supported for Opus\n");
return AVERROR_INVALIDDATA;
@@ -161,7 +204,9 @@ static int caf_write_header(AVFormatContext *s)
ff_mov_write_chan(pb, par->channel_layout);
}
- if (par->codec_id == AV_CODEC_ID_ALAC) {
+ if (par->codec_id == AV_CODEC_ID_AAC) {
+ caf_write_aac_kuki(pb, stream);
+ } else if (par->codec_id == AV_CODEC_ID_ALAC) {
ffio_wfourcc(pb, "kuki");
avio_wb64(pb, 12 + par->extradata_size);
avio_write(pb, "\0\0\0\14frmaalac", 12);
diff --git a/libavformat/mov.c b/libavformat/mov.c
index ec57a05803..f5f04d6ba6 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -776,6 +776,7 @@ static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
+ avio_rb32(pb); /* version + flags */
return ff_mov_read_esds(c->fc, pb);
}
diff --git a/libavformat/mov_esds.c b/libavformat/mov_esds.c
index a444d969c6..ae7f4b6cbf 100644
--- a/libavformat/mov_esds.c
+++ b/libavformat/mov_esds.c
@@ -29,7 +29,6 @@ int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb)
return 0;
st = fc->streams[fc->nb_streams-1];
- avio_rb32(pb); /* version + flags */
ff_mp4_read_descr(fc, pb, &tag);
if (tag == MP4ESDescrTag) {
ff_mp4_parse_es_descr(pb, NULL);
--
2.17.2 (Apple Git-113)
More information about the ffmpeg-devel
mailing list