~ubuntu-branches/ubuntu/trusty/gst-libav1.0/trusty-proposed

« back to all changes in this revision

Viewing changes to gst-libs/ext/libav/libavformat/mp3enc.c

  • Committer: Package Import Robot
  • Author(s): Sebastian Dröge
  • Date: 2013-09-24 17:07:00 UTC
  • mfrom: (1.1.17) (7.1.9 experimental)
  • Revision ID: package-import@ubuntu.com-20130924170700-4dg62s3pwl0pdakz
Tags: 1.2.0-1
* New upstream stable release:
  + debian/control:
    - Build depend on GStreamer and gst-plugins-base >= 1.2.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
#include "libavutil/intreadwrite.h"
32
32
#include "libavutil/opt.h"
33
33
#include "libavutil/dict.h"
 
34
#include "libavutil/avassert.h"
34
35
 
35
36
static int id3v1_set_string(AVFormatContext *s, const char *key,
36
37
                            uint8_t *buf, int buf_size)
73
74
    return count;
74
75
}
75
76
 
 
77
#define XING_NUM_BAGS 400
 
78
#define XING_TOC_SIZE 100
 
79
// maximum size of the xing frame: offset/Xing/flags/frames/size/TOC
 
80
#define XING_MAX_SIZE (32 + 4 + 4 + 4 + 4 + XING_TOC_SIZE)
 
81
 
76
82
typedef struct MP3Context {
77
83
    const AVClass *class;
 
84
    ID3v2EncContext id3;
78
85
    int id3v2_version;
79
86
    int write_id3v1;
80
 
    int64_t nb_frames_offset;
 
87
 
 
88
    /* xing header */
 
89
    int64_t xing_offset;
 
90
    int32_t frames;
 
91
    int32_t size;
 
92
    uint32_t want;
 
93
    uint32_t seen;
 
94
    uint32_t pos;
 
95
    uint64_t bag[XING_NUM_BAGS];
 
96
    int initial_bitrate;
 
97
    int has_variable_bitrate;
 
98
 
 
99
    /* index of the audio stream */
 
100
    int audio_stream_idx;
 
101
    /* number of attached pictures we still need to write */
 
102
    int pics_to_write;
 
103
 
 
104
    /* audio packets are queued here until we get all the attached pictures */
 
105
    AVPacketList *queue, *queue_end;
81
106
} MP3Context;
82
107
 
 
108
static const uint8_t xing_offtbl[2][2] = {{32, 17}, {17, 9}};
 
109
 
 
110
/*
 
111
 * Write an empty XING header and initialize respective data.
 
112
 */
 
113
static void mp3_write_xing(AVFormatContext *s)
 
114
{
 
115
    MP3Context       *mp3 = s->priv_data;
 
116
    AVCodecContext *codec = s->streams[mp3->audio_stream_idx]->codec;
 
117
    int32_t        header;
 
118
    MPADecodeHeader  mpah;
 
119
    int srate_idx, i, channels;
 
120
    int bitrate_idx;
 
121
    int xing_offset;
 
122
    int ver = 0;
 
123
 
 
124
    if (!s->pb->seekable)
 
125
        return;
 
126
 
 
127
    for (i = 0; i < FF_ARRAY_ELEMS(avpriv_mpa_freq_tab); i++) {
 
128
        const uint16_t base_freq = avpriv_mpa_freq_tab[i];
 
129
 
 
130
        if      (codec->sample_rate == base_freq)     ver = 0x3; // MPEG 1
 
131
        else if (codec->sample_rate == base_freq / 2) ver = 0x2; // MPEG 2
 
132
        else if (codec->sample_rate == base_freq / 4) ver = 0x0; // MPEG 2.5
 
133
        else continue;
 
134
 
 
135
        srate_idx = i;
 
136
        break;
 
137
    }
 
138
    if (i == FF_ARRAY_ELEMS(avpriv_mpa_freq_tab)) {
 
139
        av_log(s, AV_LOG_WARNING, "Unsupported sample rate, not writing Xing "
 
140
               "header.\n");
 
141
        return;
 
142
    }
 
143
 
 
144
    switch (codec->channels) {
 
145
    case 1:  channels = MPA_MONO;                                          break;
 
146
    case 2:  channels = MPA_STEREO;                                        break;
 
147
    default: av_log(s, AV_LOG_WARNING, "Unsupported number of channels, "
 
148
                    "not writing Xing header.\n");
 
149
             return;
 
150
    }
 
151
 
 
152
    /* 64 kbps frame, should be large enough */
 
153
    bitrate_idx = (ver == 3) ? 5 : 8;
 
154
 
 
155
    /* dummy MPEG audio header */
 
156
    header  =  0xff                                  << 24; // sync
 
157
    header |= (0x7 << 5 | ver << 3 | 0x1 << 1 | 0x1) << 16; // sync/audio-version/layer 3/no crc*/
 
158
    header |= (bitrate_idx << 4 | srate_idx << 2)    <<  8;
 
159
    header |= channels << 6;
 
160
    avio_wb32(s->pb, header);
 
161
 
 
162
    avpriv_mpegaudio_decode_header(&mpah, header);
 
163
 
 
164
    av_assert0(mpah.frame_size >= XING_MAX_SIZE);
 
165
 
 
166
    xing_offset = xing_offtbl[ver != 3][codec->channels == 1];
 
167
    ffio_fill(s->pb, 0, xing_offset);
 
168
    mp3->xing_offset = avio_tell(s->pb);
 
169
    ffio_wfourcc(s->pb, "Xing");
 
170
    avio_wb32(s->pb, 0x01 | 0x02 | 0x04);  // frames / size / TOC
 
171
 
 
172
    mp3->size = mpah.frame_size;
 
173
    mp3->want = 1;
 
174
 
 
175
    avio_wb32(s->pb, 0);  // frames
 
176
    avio_wb32(s->pb, 0);  // size
 
177
 
 
178
    // TOC
 
179
    for (i = 0; i < XING_TOC_SIZE; i++)
 
180
        avio_w8(s->pb, 255 * i / XING_TOC_SIZE);
 
181
 
 
182
    mpah.frame_size -= 4 + xing_offset + 4 + 4 + 4 + 4 + XING_TOC_SIZE;
 
183
    ffio_fill(s->pb, 0, mpah.frame_size);
 
184
}
 
185
 
 
186
/*
 
187
 * Add a frame to XING data.
 
188
 * Following lame's "VbrTag.c".
 
189
 */
 
190
static void mp3_xing_add_frame(MP3Context *mp3, AVPacket *pkt)
 
191
{
 
192
    int i;
 
193
 
 
194
    mp3->frames++;
 
195
    mp3->seen++;
 
196
    mp3->size += pkt->size;
 
197
 
 
198
    if (mp3->want == mp3->seen) {
 
199
        mp3->bag[mp3->pos] = mp3->size;
 
200
 
 
201
        if (XING_NUM_BAGS == ++mp3->pos) {
 
202
            /* shrink table to half size by throwing away each second bag. */
 
203
            for (i = 1; i < XING_NUM_BAGS; i += 2)
 
204
                mp3->bag[i / 2] = mp3->bag[i];
 
205
 
 
206
            /* double wanted amount per bag. */
 
207
            mp3->want *= 2;
 
208
            /* adjust current position to half of table size. */
 
209
            mp3->pos = XING_NUM_BAGS / 2;
 
210
        }
 
211
 
 
212
        mp3->seen = 0;
 
213
    }
 
214
}
 
215
 
 
216
static int mp3_write_audio_packet(AVFormatContext *s, AVPacket *pkt)
 
217
{
 
218
    MP3Context  *mp3 = s->priv_data;
 
219
 
 
220
    if (mp3->xing_offset && pkt->size >= 4) {
 
221
        MPADecodeHeader c;
 
222
 
 
223
        avpriv_mpegaudio_decode_header(&c, AV_RB32(pkt->data));
 
224
 
 
225
        if (!mp3->initial_bitrate)
 
226
            mp3->initial_bitrate = c.bit_rate;
 
227
        if ((c.bit_rate == 0) || (mp3->initial_bitrate != c.bit_rate))
 
228
            mp3->has_variable_bitrate = 1;
 
229
 
 
230
        mp3_xing_add_frame(mp3, pkt);
 
231
    }
 
232
 
 
233
    return ff_raw_write_packet(s, pkt);
 
234
}
 
235
 
 
236
static int mp3_queue_flush(AVFormatContext *s)
 
237
{
 
238
    MP3Context *mp3 = s->priv_data;
 
239
    AVPacketList *pktl;
 
240
    int ret = 0, write = 1;
 
241
 
 
242
    ff_id3v2_finish(&mp3->id3, s->pb);
 
243
    mp3_write_xing(s);
 
244
 
 
245
    while ((pktl = mp3->queue)) {
 
246
        if (write && (ret = mp3_write_audio_packet(s, &pktl->pkt)) < 0)
 
247
            write = 0;
 
248
        av_free_packet(&pktl->pkt);
 
249
        mp3->queue = pktl->next;
 
250
        av_freep(&pktl);
 
251
    }
 
252
    mp3->queue_end = NULL;
 
253
    return ret;
 
254
}
 
255
 
 
256
static void mp3_update_xing(AVFormatContext *s)
 
257
{
 
258
    MP3Context  *mp3 = s->priv_data;
 
259
    int i;
 
260
 
 
261
    /* replace "Xing" identification string with "Info" for CBR files. */
 
262
    if (!mp3->has_variable_bitrate) {
 
263
        avio_seek(s->pb, mp3->xing_offset, SEEK_SET);
 
264
        ffio_wfourcc(s->pb, "Info");
 
265
    }
 
266
 
 
267
    avio_seek(s->pb, mp3->xing_offset + 8, SEEK_SET);
 
268
    avio_wb32(s->pb, mp3->frames);
 
269
    avio_wb32(s->pb, mp3->size);
 
270
 
 
271
    avio_w8(s->pb, 0);  // first toc entry has to be zero.
 
272
 
 
273
    for (i = 1; i < XING_TOC_SIZE; ++i) {
 
274
        int j = i * mp3->pos / XING_TOC_SIZE;
 
275
        int seek_point = 256LL * mp3->bag[j] / mp3->size;
 
276
        avio_w8(s->pb, FFMIN(seek_point, 255));
 
277
    }
 
278
 
 
279
    avio_seek(s->pb, 0, SEEK_END);
 
280
}
 
281
 
83
282
static int mp3_write_trailer(struct AVFormatContext *s)
84
283
{
85
284
    uint8_t buf[ID3v1_TAG_SIZE];
86
285
    MP3Context *mp3 = s->priv_data;
87
286
 
 
287
    if (mp3->pics_to_write) {
 
288
        av_log(s, AV_LOG_WARNING, "No packets were sent for some of the "
 
289
               "attached pictures.\n");
 
290
        mp3_queue_flush(s);
 
291
    }
 
292
 
88
293
    /* write the id3v1 tag */
89
 
    if (mp3 && mp3->write_id3v1 && id3v1_create_tag(s, buf) > 0) {
 
294
    if (mp3->write_id3v1 && id3v1_create_tag(s, buf) > 0) {
90
295
        avio_write(s->pb, buf, ID3v1_TAG_SIZE);
91
296
    }
92
297
 
93
 
    /* write number of frames */
94
 
    if (mp3 && mp3->nb_frames_offset) {
95
 
        avio_seek(s->pb, mp3->nb_frames_offset, SEEK_SET);
96
 
        avio_wb32(s->pb, s->streams[0]->nb_frames);
97
 
        avio_seek(s->pb, 0, SEEK_END);
98
 
    }
99
 
 
100
 
    avio_flush(s->pb);
 
298
    if (mp3->xing_offset)
 
299
        mp3_update_xing(s);
101
300
 
102
301
    return 0;
103
302
}
105
304
#if CONFIG_MP2_MUXER
106
305
AVOutputFormat ff_mp2_muxer = {
107
306
    .name              = "mp2",
108
 
    .long_name         = NULL_IF_CONFIG_SMALL("MPEG audio layer 2"),
 
307
    .long_name         = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"),
109
308
    .mime_type         = "audio/x-mpeg",
110
309
    .extensions        = "mp2,m2a",
111
 
    .audio_codec       = CODEC_ID_MP2,
112
 
    .video_codec       = CODEC_ID_NONE,
 
310
    .audio_codec       = AV_CODEC_ID_MP2,
 
311
    .video_codec       = AV_CODEC_ID_NONE,
113
312
    .write_packet      = ff_raw_write_packet,
114
 
    .write_trailer     = mp3_write_trailer,
 
313
    .flags             = AVFMT_NOTIMESTAMPS,
115
314
};
116
315
#endif
117
316
 
119
318
 
120
319
static const AVOption options[] = {
121
320
    { "id3v2_version", "Select ID3v2 version to write. Currently 3 and 4 are supported.",
122
 
      offsetof(MP3Context, id3v2_version), AV_OPT_TYPE_INT, {.dbl = 4}, 3, 4, AV_OPT_FLAG_ENCODING_PARAM},
 
321
      offsetof(MP3Context, id3v2_version), AV_OPT_TYPE_INT, {.i64 = 4}, 3, 4, AV_OPT_FLAG_ENCODING_PARAM},
123
322
    { "write_id3v1", "Enable ID3v1 writing. ID3v1 tags are written in UTF-8 which may not be supported by most software.",
124
 
      offsetof(MP3Context, write_id3v1), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
 
323
      offsetof(MP3Context, write_id3v1), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
125
324
    { NULL },
126
325
};
127
326
 
132
331
    .version        = LIBAVUTIL_VERSION_INT,
133
332
};
134
333
 
135
 
/* insert a dummy frame containing number of frames */
136
 
static void mp3_write_xing(AVFormatContext *s)
 
334
static int mp3_write_packet(AVFormatContext *s, AVPacket *pkt)
137
335
{
138
 
    AVCodecContext *codec = s->streams[0]->codec;
139
 
    MP3Context       *mp3 = s->priv_data;
140
 
    int       bitrate_idx = 1;    // 32 kbps
141
 
    int64_t   xing_offset = (codec->channels == 2) ? 32 : 17;
142
 
    int32_t        header;
143
 
    MPADecodeHeader  mpah;
144
 
    int srate_idx, i, channels;
145
 
 
146
 
    for (i = 0; i < FF_ARRAY_ELEMS(avpriv_mpa_freq_tab); i++)
147
 
        if (avpriv_mpa_freq_tab[i] == codec->sample_rate) {
148
 
            srate_idx = i;
149
 
            break;
 
336
    MP3Context *mp3 = s->priv_data;
 
337
 
 
338
    if (pkt->stream_index == mp3->audio_stream_idx) {
 
339
        if (mp3->pics_to_write) {
 
340
            /* buffer audio packets until we get all the pictures */
 
341
            AVPacketList *pktl = av_mallocz(sizeof(*pktl));
 
342
            if (!pktl)
 
343
                return AVERROR(ENOMEM);
 
344
 
 
345
            pktl->pkt     = *pkt;
 
346
            pkt->destruct = NULL;
 
347
 
 
348
            if (mp3->queue_end)
 
349
                mp3->queue_end->next = pktl;
 
350
            else
 
351
                mp3->queue = pktl;
 
352
            mp3->queue_end = pktl;
 
353
        } else
 
354
            return mp3_write_audio_packet(s, pkt);
 
355
    } else {
 
356
        int ret;
 
357
 
 
358
        /* warn only once for each stream */
 
359
        if (s->streams[pkt->stream_index]->nb_frames == 1) {
 
360
            av_log(s, AV_LOG_WARNING, "Got more than one picture in stream %d,"
 
361
                   " ignoring.\n", pkt->stream_index);
150
362
        }
151
 
    if (i == FF_ARRAY_ELEMS(avpriv_mpa_freq_tab)) {
152
 
        av_log(s, AV_LOG_ERROR, "Unsupported sample rate.\n");
153
 
        return;
154
 
    }
155
 
 
156
 
    switch (codec->channels) {
157
 
    case 1:  channels = MPA_MONO;                                          break;
158
 
    case 2:  channels = MPA_STEREO;                                        break;
159
 
    default: av_log(s, AV_LOG_ERROR, "Unsupported number of channels.\n"); return;
160
 
    }
161
 
 
162
 
    /* dummy MPEG audio header */
163
 
    header  =  0xff                                  << 24; // sync
164
 
    header |= (0x7 << 5 | 0x3 << 3 | 0x1 << 1 | 0x1) << 16; // sync/mpeg-1/layer 3/no crc*/
165
 
    header |= (bitrate_idx << 4 | srate_idx << 2)    <<  8;
166
 
    header |= channels << 6;
167
 
    avio_wb32(s->pb, header);
168
 
 
169
 
    avpriv_mpegaudio_decode_header(&mpah, header);
170
 
 
171
 
    ffio_fill(s->pb, 0, xing_offset);
172
 
    ffio_wfourcc(s->pb, "Xing");
173
 
    avio_wb32(s->pb, 0x1);    // only number of frames
174
 
    mp3->nb_frames_offset = avio_tell(s->pb);
175
 
    avio_wb32(s->pb, 0);
176
 
 
177
 
    mpah.frame_size -= 4 + xing_offset + 4 + 4 + 4;
178
 
    ffio_fill(s->pb, 0, mpah.frame_size);
 
363
        if (!mp3->pics_to_write || s->streams[pkt->stream_index]->nb_frames >= 1)
 
364
            return 0;
 
365
 
 
366
        if ((ret = ff_id3v2_write_apic(s, &mp3->id3, pkt)) < 0)
 
367
            return ret;
 
368
        mp3->pics_to_write--;
 
369
 
 
370
        /* flush the buffered audio packets */
 
371
        if (!mp3->pics_to_write &&
 
372
            (ret = mp3_queue_flush(s)) < 0)
 
373
            return ret;
 
374
    }
 
375
 
 
376
    return 0;
179
377
}
180
378
 
181
379
/**
185
383
static int mp3_write_header(struct AVFormatContext *s)
186
384
{
187
385
    MP3Context  *mp3 = s->priv_data;
188
 
    int ret;
189
 
 
190
 
    ret = ff_id3v2_write(s, mp3->id3v2_version, ID3v2_DEFAULT_MAGIC);
 
386
    int ret, i;
 
387
 
 
388
    /* check the streams -- we want exactly one audio and arbitrary number of
 
389
     * video (attached pictures) */
 
390
    mp3->audio_stream_idx = -1;
 
391
    for (i = 0; i < s->nb_streams; i++) {
 
392
        AVStream *st = s->streams[i];
 
393
        if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
 
394
            if (mp3->audio_stream_idx >= 0 || st->codec->codec_id != AV_CODEC_ID_MP3) {
 
395
                av_log(s, AV_LOG_ERROR, "Invalid audio stream. Exactly one MP3 "
 
396
                       "audio stream is required.\n");
 
397
                return AVERROR(EINVAL);
 
398
            }
 
399
            mp3->audio_stream_idx = i;
 
400
        } else if (st->codec->codec_type != AVMEDIA_TYPE_VIDEO) {
 
401
            av_log(s, AV_LOG_ERROR, "Only audio streams and pictures are allowed in MP3.\n");
 
402
            return AVERROR(EINVAL);
 
403
        }
 
404
    }
 
405
    if (mp3->audio_stream_idx < 0) {
 
406
        av_log(s, AV_LOG_ERROR, "No audio stream present.\n");
 
407
        return AVERROR(EINVAL);
 
408
    }
 
409
    mp3->pics_to_write = s->nb_streams - 1;
 
410
 
 
411
    ff_id3v2_start(&mp3->id3, s->pb, mp3->id3v2_version, ID3v2_DEFAULT_MAGIC);
 
412
    ret = ff_id3v2_write_metadata(s, &mp3->id3);
191
413
    if (ret < 0)
192
414
        return ret;
193
415
 
194
 
    if (s->pb->seekable)
 
416
    if (!mp3->pics_to_write) {
 
417
        ff_id3v2_finish(&mp3->id3, s->pb);
195
418
        mp3_write_xing(s);
 
419
    }
196
420
 
197
421
    return 0;
198
422
}
199
423
 
200
424
AVOutputFormat ff_mp3_muxer = {
201
425
    .name              = "mp3",
202
 
    .long_name         = NULL_IF_CONFIG_SMALL("MPEG audio layer 3"),
 
426
    .long_name         = NULL_IF_CONFIG_SMALL("MP3 (MPEG audio layer 3)"),
203
427
    .mime_type         = "audio/x-mpeg",
204
428
    .extensions        = "mp3",
205
429
    .priv_data_size    = sizeof(MP3Context),
206
 
    .audio_codec       = CODEC_ID_MP3,
207
 
    .video_codec       = CODEC_ID_NONE,
 
430
    .audio_codec       = AV_CODEC_ID_MP3,
 
431
    .video_codec       = AV_CODEC_ID_PNG,
208
432
    .write_header      = mp3_write_header,
209
 
    .write_packet      = ff_raw_write_packet,
 
433
    .write_packet      = mp3_write_packet,
210
434
    .write_trailer     = mp3_write_trailer,
211
435
    .flags             = AVFMT_NOTIMESTAMPS,
212
 
    .priv_class = &mp3_muxer_class,
 
436
    .priv_class        = &mp3_muxer_class,
213
437
};
214
438
#endif