xref: /third_party/ffmpeg/libavformat/adtsenc.c (revision cabdff1a)
1/*
2 * ADTS muxer.
3 * Copyright (c) 2006 Baptiste Coudurier <baptiste.coudurier@smartjog.com>
4 *                    Mans Rullgard <mans@mansr.com>
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include "libavcodec/get_bits.h"
24#include "libavcodec/put_bits.h"
25#include "libavcodec/codec_id.h"
26#include "libavcodec/codec_par.h"
27#include "libavcodec/packet.h"
28#include "libavcodec/mpeg4audio.h"
29#include "libavutil/opt.h"
30#include "avformat.h"
31#include "apetag.h"
32#include "id3v2.h"
33
34#define ADTS_HEADER_SIZE 7
35
36typedef struct ADTSContext {
37    AVClass *class;
38    int write_adts;
39    int objecttype;
40    int sample_rate_index;
41    int channel_conf;
42    int pce_size;
43    int apetag;
44    int id3v2tag;
45    int mpeg_id;
46    uint8_t pce_data[MAX_PCE_SIZE];
47} ADTSContext;
48
49#define ADTS_MAX_FRAME_BYTES ((1 << 14) - 1)
50
51static int adts_decode_extradata(AVFormatContext *s, ADTSContext *adts, const uint8_t *buf, int size)
52{
53    GetBitContext gb;
54    PutBitContext pb;
55    MPEG4AudioConfig m4ac;
56    int off, ret;
57
58    ret = init_get_bits8(&gb, buf, size);
59    if (ret < 0)
60        return ret;
61    off = avpriv_mpeg4audio_get_config2(&m4ac, buf, size, 1, s);
62    if (off < 0)
63        return off;
64    skip_bits_long(&gb, off);
65    adts->objecttype        = m4ac.object_type - 1;
66    adts->sample_rate_index = m4ac.sampling_index;
67    adts->channel_conf      = m4ac.chan_config;
68
69    if (adts->objecttype > 3U) {
70        av_log(s, AV_LOG_ERROR, "MPEG-4 AOT %d is not allowed in ADTS\n", adts->objecttype+1);
71        return AVERROR_INVALIDDATA;
72    }
73    if (adts->sample_rate_index == 15) {
74        av_log(s, AV_LOG_ERROR, "Escape sample rate index illegal in ADTS\n");
75        return AVERROR_INVALIDDATA;
76    }
77    if (get_bits(&gb, 1)) {
78        av_log(s, AV_LOG_ERROR, "960/120 MDCT window is not allowed in ADTS\n");
79        return AVERROR_INVALIDDATA;
80    }
81    if (get_bits(&gb, 1)) {
82        av_log(s, AV_LOG_ERROR, "Scalable configurations are not allowed in ADTS\n");
83        return AVERROR_INVALIDDATA;
84    }
85    if (get_bits(&gb, 1)) {
86        av_log(s, AV_LOG_ERROR, "Extension flag is not allowed in ADTS\n");
87        return AVERROR_INVALIDDATA;
88    }
89    if (!adts->channel_conf) {
90        init_put_bits(&pb, adts->pce_data, MAX_PCE_SIZE);
91
92        put_bits(&pb, 3, 5); //ID_PCE
93        adts->pce_size = (ff_copy_pce_data(&pb, &gb) + 3) / 8;
94        flush_put_bits(&pb);
95    }
96
97    adts->write_adts = 1;
98
99    return 0;
100}
101
102static int adts_init(AVFormatContext *s)
103{
104    ADTSContext *adts = s->priv_data;
105    AVCodecParameters *par = s->streams[0]->codecpar;
106
107    if (par->codec_id != AV_CODEC_ID_AAC) {
108        av_log(s, AV_LOG_ERROR, "Only AAC streams can be muxed by the ADTS muxer\n");
109        return AVERROR(EINVAL);
110    }
111    if (par->extradata_size > 0)
112        return adts_decode_extradata(s, adts, par->extradata,
113                                     par->extradata_size);
114
115    return 0;
116}
117
118static int adts_write_header(AVFormatContext *s)
119{
120    ADTSContext *adts = s->priv_data;
121
122    if (adts->id3v2tag)
123        ff_id3v2_write_simple(s, 4, ID3v2_DEFAULT_MAGIC);
124
125    return 0;
126}
127
128static int adts_write_frame_header(ADTSContext *ctx,
129                                   uint8_t *buf, int size, int pce_size)
130{
131    PutBitContext pb;
132
133    unsigned full_frame_size = (unsigned)ADTS_HEADER_SIZE + size + pce_size;
134    if (full_frame_size > ADTS_MAX_FRAME_BYTES) {
135        av_log(NULL, AV_LOG_ERROR, "ADTS frame size too large: %u (max %d)\n",
136               full_frame_size, ADTS_MAX_FRAME_BYTES);
137        return AVERROR_INVALIDDATA;
138    }
139
140    init_put_bits(&pb, buf, ADTS_HEADER_SIZE);
141
142    /* adts_fixed_header */
143    put_bits(&pb, 12, 0xfff);   /* syncword */
144    put_bits(&pb, 1, ctx->mpeg_id); /* ID */
145    put_bits(&pb, 2, 0);        /* layer */
146    put_bits(&pb, 1, 1);        /* protection_absent */
147    put_bits(&pb, 2, ctx->objecttype); /* profile_objecttype */
148    put_bits(&pb, 4, ctx->sample_rate_index);
149    put_bits(&pb, 1, 0);        /* private_bit */
150    put_bits(&pb, 3, ctx->channel_conf); /* channel_configuration */
151    put_bits(&pb, 1, 0);        /* original_copy */
152    put_bits(&pb, 1, 0);        /* home */
153
154    /* adts_variable_header */
155    put_bits(&pb, 1, 0);        /* copyright_identification_bit */
156    put_bits(&pb, 1, 0);        /* copyright_identification_start */
157    put_bits(&pb, 13, full_frame_size); /* aac_frame_length */
158    put_bits(&pb, 11, 0x7ff);   /* adts_buffer_fullness */
159    put_bits(&pb, 2, 0);        /* number_of_raw_data_blocks_in_frame */
160
161    flush_put_bits(&pb);
162
163    return 0;
164}
165
166static int adts_write_packet(AVFormatContext *s, AVPacket *pkt)
167{
168    ADTSContext *adts = s->priv_data;
169    AVCodecParameters *par = s->streams[0]->codecpar;
170    AVIOContext *pb = s->pb;
171    uint8_t buf[ADTS_HEADER_SIZE];
172
173    if (!pkt->size)
174        return 0;
175    if (!par->extradata_size) {
176        uint8_t *side_data;
177        size_t side_data_size;
178        int ret;
179
180        side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA,
181                                            &side_data_size);
182        if (side_data_size) {
183            ret = adts_decode_extradata(s, adts, side_data, side_data_size);
184            if (ret < 0)
185                return ret;
186            ret = ff_alloc_extradata(par, side_data_size);
187            if (ret < 0)
188                return ret;
189            memcpy(par->extradata, side_data, side_data_size);
190        }
191    }
192    if (adts->write_adts) {
193        int err = adts_write_frame_header(adts, buf, pkt->size,
194                                             adts->pce_size);
195        if (err < 0)
196            return err;
197        avio_write(pb, buf, ADTS_HEADER_SIZE);
198        if (adts->pce_size) {
199            avio_write(pb, adts->pce_data, adts->pce_size);
200            adts->pce_size = 0;
201        }
202    }
203    avio_write(pb, pkt->data, pkt->size);
204
205    return 0;
206}
207
208static int adts_write_trailer(AVFormatContext *s)
209{
210    ADTSContext *adts = s->priv_data;
211
212    if (adts->apetag)
213        ff_ape_write_tag(s);
214
215    return 0;
216}
217
218#define ENC AV_OPT_FLAG_ENCODING_PARAM
219#define OFFSET(obj) offsetof(ADTSContext, obj)
220static const AVOption options[] = {
221    { "write_id3v2",  "Enable ID3v2 tag writing",   OFFSET(id3v2tag), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, ENC},
222    { "write_apetag", "Enable APE tag writing",     OFFSET(apetag),   AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, ENC},
223    { "write_mpeg2",  "Set MPEG version to MPEG-2", OFFSET(mpeg_id),  AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, ENC},
224    { NULL },
225};
226
227static const AVClass adts_muxer_class = {
228    .class_name     = "ADTS muxer",
229    .item_name      = av_default_item_name,
230    .option         = options,
231    .version        = LIBAVUTIL_VERSION_INT,
232};
233
234const AVOutputFormat ff_adts_muxer = {
235    .name              = "adts",
236    .long_name         = NULL_IF_CONFIG_SMALL("ADTS AAC (Advanced Audio Coding)"),
237    .mime_type         = "audio/aac",
238    .extensions        = "aac,adts",
239    .priv_data_size    = sizeof(ADTSContext),
240    .audio_codec       = AV_CODEC_ID_AAC,
241    .video_codec       = AV_CODEC_ID_NONE,
242    .init              = adts_init,
243    .write_header      = adts_write_header,
244    .write_packet      = adts_write_packet,
245    .write_trailer     = adts_write_trailer,
246    .priv_class        = &adts_muxer_class,
247    .flags             = AVFMT_NOTIMESTAMPS,
248};
249