LCOV - code coverage report
Current view: top level - libavformat - mp3enc.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 171 287 59.6 %
Date: 2017-12-11 04:34:20 Functions: 8 11 72.7 %

          Line data    Source code
       1             : /*
       2             :  * MP3 muxer
       3             :  * Copyright (c) 2003 Fabrice Bellard
       4             :  *
       5             :  * This file is part of FFmpeg.
       6             :  *
       7             :  * FFmpeg is free software; you can redistribute it and/or
       8             :  * modify it under the terms of the GNU Lesser General Public
       9             :  * License as published by the Free Software Foundation; either
      10             :  * version 2.1 of the License, or (at your option) any later version.
      11             :  *
      12             :  * FFmpeg is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :  * Lesser General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU Lesser General Public
      18             :  * License along with FFmpeg; if not, write to the Free Software
      19             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      20             :  */
      21             : 
      22             : #include "avformat.h"
      23             : #include "avio_internal.h"
      24             : #include "id3v1.h"
      25             : #include "id3v2.h"
      26             : #include "rawenc.h"
      27             : #include "libavutil/avstring.h"
      28             : #include "libavcodec/mpegaudio.h"
      29             : #include "libavcodec/mpegaudiodata.h"
      30             : #include "libavcodec/mpegaudiodecheader.h"
      31             : #include "libavutil/intreadwrite.h"
      32             : #include "libavutil/opt.h"
      33             : #include "libavutil/dict.h"
      34             : #include "libavutil/avassert.h"
      35             : #include "libavutil/crc.h"
      36             : #include "libavutil/mathematics.h"
      37             : #include "libavutil/replaygain.h"
      38             : 
      39           0 : static int id3v1_set_string(AVFormatContext *s, const char *key,
      40             :                             uint8_t *buf, int buf_size)
      41             : {
      42             :     AVDictionaryEntry *tag;
      43           0 :     if ((tag = av_dict_get(s->metadata, key, NULL, 0)))
      44           0 :         av_strlcpy(buf, tag->value, buf_size);
      45           0 :     return !!tag;
      46             : }
      47             : 
      48           0 : static int id3v1_create_tag(AVFormatContext *s, uint8_t *buf)
      49             : {
      50             :     AVDictionaryEntry *tag;
      51           0 :     int i, count = 0;
      52             : 
      53           0 :     memset(buf, 0, ID3v1_TAG_SIZE); /* fail safe */
      54           0 :     buf[0] = 'T';
      55           0 :     buf[1] = 'A';
      56           0 :     buf[2] = 'G';
      57             :     /* we knowingly overspecify each tag length by one byte to compensate for the mandatory null byte added by av_strlcpy */
      58           0 :     count += id3v1_set_string(s, "TIT2",    buf +  3, 30 + 1);       //title
      59           0 :     count += id3v1_set_string(s, "TPE1",    buf + 33, 30 + 1);       //author|artist
      60           0 :     count += id3v1_set_string(s, "TALB",    buf + 63, 30 + 1);       //album
      61           0 :     count += id3v1_set_string(s, "TDRC",    buf + 93,  4 + 1);       //date
      62           0 :     count += id3v1_set_string(s, "comment", buf + 97, 30 + 1);
      63           0 :     if ((tag = av_dict_get(s->metadata, "TRCK", NULL, 0))) { //track
      64           0 :         buf[125] = 0;
      65           0 :         buf[126] = atoi(tag->value);
      66           0 :         count++;
      67             :     }
      68           0 :     buf[127] = 0xFF; /* default to unknown genre */
      69           0 :     if ((tag = av_dict_get(s->metadata, "TCON", NULL, 0))) { //genre
      70           0 :         for(i = 0; i <= ID3v1_GENRE_MAX; i++) {
      71           0 :             if (!av_strcasecmp(tag->value, ff_id3v1_genre_str[i])) {
      72           0 :                 buf[127] = i;
      73           0 :                 count++;
      74           0 :                 break;
      75             :             }
      76             :         }
      77             :     }
      78           0 :     return count;
      79             : }
      80             : 
      81             : #define XING_NUM_BAGS 400
      82             : #define XING_TOC_SIZE 100
      83             : // size of the XING/LAME data, starting from the Xing tag
      84             : #define XING_SIZE 156
      85             : 
      86             : typedef struct MP3Context {
      87             :     const AVClass *class;
      88             :     ID3v2EncContext id3;
      89             :     int id3v2_version;
      90             :     int write_id3v1;
      91             :     int write_xing;
      92             : 
      93             :     /* xing header */
      94             :     // a buffer containing the whole XING/LAME frame
      95             :     uint8_t *xing_frame;
      96             :     int      xing_frame_size;
      97             : 
      98             :     AVCRC    audio_crc;     // CRC of the audio data
      99             :     uint32_t audio_size;    // total size of the audio data
     100             : 
     101             :     // offset of the XING/LAME frame in the file
     102             :     int64_t  xing_frame_offset;
     103             :     // offset of the XING/INFO tag in the frame
     104             :     int xing_offset;
     105             : 
     106             :     int32_t frames;
     107             :     int32_t size;
     108             :     uint32_t want;
     109             :     uint32_t seen;
     110             :     uint32_t pos;
     111             :     uint64_t bag[XING_NUM_BAGS];
     112             :     int initial_bitrate;
     113             :     int has_variable_bitrate;
     114             :     int delay;
     115             :     int padding;
     116             : 
     117             :     /* index of the audio stream */
     118             :     int audio_stream_idx;
     119             :     /* number of attached pictures we still need to write */
     120             :     int pics_to_write;
     121             : 
     122             :     /* audio packets are queued here until we get all the attached pictures */
     123             :     AVPacketList *queue, *queue_end;
     124             : } MP3Context;
     125             : 
     126             : static const uint8_t xing_offtbl[2][2] = {{32, 17}, {17, 9}};
     127             : 
     128             : /*
     129             :  * Write an empty XING header and initialize respective data.
     130             :  */
     131           1 : static int mp3_write_xing(AVFormatContext *s)
     132             : {
     133           1 :     MP3Context       *mp3 = s->priv_data;
     134           1 :     AVCodecParameters *par = s->streams[mp3->audio_stream_idx]->codecpar;
     135           1 :     AVDictionaryEntry *enc = av_dict_get(s->streams[mp3->audio_stream_idx]->metadata, "encoder", NULL, 0);
     136             :     AVIOContext *dyn_ctx;
     137             :     int32_t        header;
     138             :     MPADecodeHeader  mpah;
     139             :     int srate_idx, i, channels;
     140             :     int bitrate_idx;
     141           1 :     int best_bitrate_idx = -1;
     142           1 :     int best_bitrate_error = INT_MAX;
     143             :     int ret;
     144           1 :     int ver = 0;
     145             :     int bytes_needed;
     146             : 
     147           1 :     if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) || !mp3->write_xing)
     148           0 :         return 0;
     149             : 
     150           6 :     for (i = 0; i < FF_ARRAY_ELEMS(avpriv_mpa_freq_tab); i++) {
     151           3 :         const uint16_t base_freq = avpriv_mpa_freq_tab[i];
     152             : 
     153           3 :         if      (par->sample_rate == base_freq)     ver = 0x3; // MPEG 1
     154           2 :         else if (par->sample_rate == base_freq / 2) ver = 0x2; // MPEG 2
     155           2 :         else if (par->sample_rate == base_freq / 4) ver = 0x0; // MPEG 2.5
     156           2 :         else continue;
     157             : 
     158           1 :         srate_idx = i;
     159           1 :         break;
     160             :     }
     161           1 :     if (i == FF_ARRAY_ELEMS(avpriv_mpa_freq_tab)) {
     162           0 :         av_log(s, AV_LOG_WARNING, "Unsupported sample rate, not writing Xing header.\n");
     163           0 :         return -1;
     164             :     }
     165             : 
     166           1 :     switch (par->channels) {
     167           1 :     case 1:  channels = MPA_MONO;                                          break;
     168           0 :     case 2:  channels = MPA_STEREO;                                        break;
     169           0 :     default: av_log(s, AV_LOG_WARNING, "Unsupported number of channels, "
     170             :                     "not writing Xing header.\n");
     171           0 :              return -1;
     172             :     }
     173             : 
     174             :     /* dummy MPEG audio header */
     175           1 :     header  =  0xffU                                 << 24; // sync
     176           1 :     header |= (0x7 << 5 | ver << 3 | 0x1 << 1 | 0x1) << 16; // sync/audio-version/layer 3/no crc*/
     177           1 :     header |= (srate_idx << 2) << 8;
     178           1 :     header |= channels << 6;
     179             : 
     180          15 :     for (bitrate_idx = 1; bitrate_idx < 15; bitrate_idx++) {
     181          14 :         int bit_rate = 1000 * avpriv_mpa_bitrate_tab[ver != 3][3 - 1][bitrate_idx];
     182          14 :         int error    = FFABS(bit_rate - par->bit_rate);
     183             : 
     184          14 :         if (error < best_bitrate_error) {
     185           3 :             best_bitrate_error = error;
     186           3 :             best_bitrate_idx   = bitrate_idx;
     187             :         }
     188             :     }
     189           1 :     av_assert0(best_bitrate_idx >= 0);
     190             : 
     191           1 :     for (bitrate_idx = best_bitrate_idx; ; bitrate_idx++) {
     192           1 :         int32_t mask = bitrate_idx << (4 + 8);
     193           1 :         if (15 == bitrate_idx)
     194           0 :             return -1;
     195           1 :         header |= mask;
     196             : 
     197           1 :         ret = avpriv_mpegaudio_decode_header(&mpah, header);
     198           1 :         av_assert0(ret >= 0);
     199           1 :         mp3->xing_offset = xing_offtbl[mpah.lsf == 1][mpah.nb_channels == 1] + 4;
     200           1 :         bytes_needed     = mp3->xing_offset + XING_SIZE;
     201             : 
     202           1 :         if (bytes_needed <= mpah.frame_size)
     203           1 :             break;
     204             : 
     205           0 :         header &= ~mask;
     206             :     }
     207             : 
     208           1 :     ret = avio_open_dyn_buf(&dyn_ctx);
     209           1 :     if (ret < 0)
     210           0 :         return ret;
     211             : 
     212           1 :     avio_wb32(dyn_ctx, header);
     213             : 
     214           1 :     ffio_fill(dyn_ctx, 0, mp3->xing_offset - 4);
     215           1 :     ffio_wfourcc(dyn_ctx, "Xing");
     216           1 :     avio_wb32(dyn_ctx, 0x01 | 0x02 | 0x04 | 0x08);  // frames / size / TOC / vbr scale
     217             : 
     218           1 :     mp3->size = mpah.frame_size;
     219           1 :     mp3->want=1;
     220           1 :     mp3->seen=0;
     221           1 :     mp3->pos=0;
     222             : 
     223           1 :     avio_wb32(dyn_ctx, 0);  // frames
     224           1 :     avio_wb32(dyn_ctx, 0);  // size
     225             : 
     226             :     // TOC
     227         101 :     for (i = 0; i < XING_TOC_SIZE; i++)
     228         100 :         avio_w8(dyn_ctx, (uint8_t)(255 * i / XING_TOC_SIZE));
     229             : 
     230             :     // vbr quality
     231             :     // we write it, because some (broken) tools always expect it to be present
     232           1 :     avio_wb32(dyn_ctx, 0);
     233             : 
     234             :     // encoder short version string
     235           1 :     if (enc) {
     236           0 :         uint8_t encoder_str[9] = { 0 };
     237           0 :         if (   strlen(enc->value) > sizeof(encoder_str)
     238           0 :             && !strcmp("Lavc libmp3lame", enc->value)) {
     239           0 :             memcpy(encoder_str, "Lavf lame", 9);
     240             :         } else
     241           0 :             memcpy(encoder_str, enc->value, FFMIN(strlen(enc->value), sizeof(encoder_str)));
     242             : 
     243           0 :         avio_write(dyn_ctx, encoder_str, sizeof(encoder_str));
     244             :     } else
     245           1 :         avio_write(dyn_ctx, "Lavf\0\0\0\0\0", 9);
     246             : 
     247           1 :     avio_w8(dyn_ctx, 0);      // tag revision 0 / unknown vbr method
     248           1 :     avio_w8(dyn_ctx, 0);      // unknown lowpass filter value
     249           1 :     ffio_fill(dyn_ctx, 0, 8); // empty replaygain fields
     250           1 :     avio_w8(dyn_ctx, 0);      // unknown encoding flags
     251           1 :     avio_w8(dyn_ctx, 0);      // unknown abr/minimal bitrate
     252           1 :     avio_wb24(dyn_ctx, 0);    // empty encoder delay/padding
     253             : 
     254           1 :     avio_w8(dyn_ctx,   0); // misc
     255           1 :     avio_w8(dyn_ctx,   0); // mp3gain
     256           1 :     avio_wb16(dyn_ctx, 0); // preset
     257             : 
     258             :     // audio length and CRCs (will be updated later)
     259           1 :     avio_wb32(dyn_ctx, 0); // music length
     260           1 :     avio_wb16(dyn_ctx, 0); // music crc
     261           1 :     avio_wb16(dyn_ctx, 0); // tag crc
     262             : 
     263           1 :     ffio_fill(dyn_ctx, 0, mpah.frame_size - bytes_needed);
     264             : 
     265           1 :     mp3->xing_frame_size   = avio_close_dyn_buf(dyn_ctx, &mp3->xing_frame);
     266           1 :     mp3->xing_frame_offset = avio_tell(s->pb);
     267           1 :     avio_write(s->pb, mp3->xing_frame, mp3->xing_frame_size);
     268             : 
     269           1 :     mp3->audio_size = mp3->xing_frame_size;
     270             : 
     271           1 :     return 0;
     272             : }
     273             : 
     274             : /*
     275             :  * Add a frame to XING data.
     276             :  * Following lame's "VbrTag.c".
     277             :  */
     278         150 : static void mp3_xing_add_frame(MP3Context *mp3, AVPacket *pkt)
     279             : {
     280             :     int i;
     281             : 
     282         150 :     mp3->frames++;
     283         150 :     mp3->seen++;
     284         150 :     mp3->size += pkt->size;
     285             : 
     286         150 :     if (mp3->want == mp3->seen) {
     287         150 :         mp3->bag[mp3->pos] = mp3->size;
     288             : 
     289         150 :         if (XING_NUM_BAGS == ++mp3->pos) {
     290             :             /* shrink table to half size by throwing away each second bag. */
     291           0 :             for (i = 1; i < XING_NUM_BAGS; i += 2)
     292           0 :                 mp3->bag[i >> 1] = mp3->bag[i];
     293             : 
     294             :             /* double wanted amount per bag. */
     295           0 :             mp3->want *= 2;
     296             :             /* adjust current position to half of table size. */
     297           0 :             mp3->pos = XING_NUM_BAGS / 2;
     298             :         }
     299             : 
     300         150 :         mp3->seen = 0;
     301             :     }
     302         150 : }
     303             : 
     304         150 : static int mp3_write_audio_packet(AVFormatContext *s, AVPacket *pkt)
     305             : {
     306         150 :     MP3Context  *mp3 = s->priv_data;
     307             : 
     308         150 :     if (pkt->data && pkt->size >= 4) {
     309             :         MPADecodeHeader mpah;
     310             :         int ret;
     311             :         int av_unused base;
     312             :         uint32_t h;
     313             : 
     314         150 :         h = AV_RB32(pkt->data);
     315         150 :         ret = avpriv_mpegaudio_decode_header(&mpah, h);
     316         150 :         if (ret >= 0) {
     317         150 :             if (!mp3->initial_bitrate)
     318           1 :                 mp3->initial_bitrate = mpah.bit_rate;
     319         150 :             if ((mpah.bit_rate == 0) || (mp3->initial_bitrate != mpah.bit_rate))
     320         140 :                 mp3->has_variable_bitrate = 1;
     321             :         } else {
     322           0 :             av_log(s, AV_LOG_WARNING, "Audio packet of size %d (starting with %08"PRIX32"...) "
     323             :                    "is invalid, writing it anyway.\n", pkt->size, h);
     324             :         }
     325             : 
     326             : #ifdef FILTER_VBR_HEADERS
     327             :         /* filter out XING and INFO headers. */
     328             :         base = 4 + xing_offtbl[mpah.lsf == 1][mpah.nb_channels == 1];
     329             : 
     330             :         if (base + 4 <= pkt->size) {
     331             :             uint32_t v = AV_RB32(pkt->data + base);
     332             : 
     333             :             if (MKBETAG('X','i','n','g') == v || MKBETAG('I','n','f','o') == v)
     334             :                 return 0;
     335             :         }
     336             : 
     337             :         /* filter out VBRI headers. */
     338             :         base = 4 + 32;
     339             : 
     340             :         if (base + 4 <= pkt->size && MKBETAG('V','B','R','I') == AV_RB32(pkt->data + base))
     341             :             return 0;
     342             : #endif
     343             : 
     344         150 :         if (mp3->xing_offset) {
     345         150 :             uint8_t *side_data = NULL;
     346         150 :             int side_data_size = 0;
     347             : 
     348         150 :             mp3_xing_add_frame(mp3, pkt);
     349         150 :             mp3->audio_size += pkt->size;
     350         300 :             mp3->audio_crc   = av_crc(av_crc_get_table(AV_CRC_16_ANSI_LE),
     351         300 :                                       mp3->audio_crc, pkt->data, pkt->size);
     352             : 
     353         150 :             side_data = av_packet_get_side_data(pkt,
     354             :                                                 AV_PKT_DATA_SKIP_SAMPLES,
     355             :                                                 &side_data_size);
     356         150 :             if (side_data && side_data_size >= 10) {
     357           0 :                 mp3->padding = FFMAX(AV_RL32(side_data + 4) + 528 + 1, 0);
     358           0 :                 if (!mp3->delay)
     359           0 :                     mp3->delay =  FFMAX(AV_RL32(side_data) - 528 - 1, 0);
     360             :             } else {
     361         150 :                 mp3->padding = 0;
     362             :             }
     363             :         }
     364             :     }
     365             : 
     366         150 :     return ff_raw_write_packet(s, pkt);
     367             : }
     368             : 
     369           0 : static int mp3_queue_flush(AVFormatContext *s)
     370             : {
     371           0 :     MP3Context *mp3 = s->priv_data;
     372             :     AVPacketList *pktl;
     373           0 :     int ret = 0, write = 1;
     374             : 
     375           0 :     ff_id3v2_finish(&mp3->id3, s->pb, s->metadata_header_padding);
     376           0 :     mp3_write_xing(s);
     377             : 
     378           0 :     while ((pktl = mp3->queue)) {
     379           0 :         if (write && (ret = mp3_write_audio_packet(s, &pktl->pkt)) < 0)
     380           0 :             write = 0;
     381           0 :         av_packet_unref(&pktl->pkt);
     382           0 :         mp3->queue = pktl->next;
     383           0 :         av_freep(&pktl);
     384             :     }
     385           0 :     mp3->queue_end = NULL;
     386           0 :     return ret;
     387             : }
     388             : 
     389           1 : static void mp3_update_xing(AVFormatContext *s)
     390             : {
     391           1 :     MP3Context  *mp3 = s->priv_data;
     392             :     AVReplayGain *rg;
     393             :     uint16_t tag_crc;
     394             :     uint8_t *toc;
     395             :     int i, rg_size;
     396             : 
     397             :     /* replace "Xing" identification string with "Info" for CBR files. */
     398           1 :     if (!mp3->has_variable_bitrate)
     399           0 :         AV_WL32(mp3->xing_frame + mp3->xing_offset, MKTAG('I', 'n', 'f', 'o'));
     400             : 
     401           1 :     AV_WB32(mp3->xing_frame + mp3->xing_offset + 8,  mp3->frames);
     402           1 :     AV_WB32(mp3->xing_frame + mp3->xing_offset + 12, mp3->size);
     403             : 
     404           1 :     toc    = mp3->xing_frame + mp3->xing_offset + 16;
     405           1 :     toc[0] = 0;  // first toc entry has to be zero.
     406         100 :     for (i = 1; i < XING_TOC_SIZE; ++i) {
     407          99 :         int j = i * mp3->pos / XING_TOC_SIZE;
     408          99 :         int seek_point = 256LL * mp3->bag[j] / mp3->size;
     409          99 :         toc[i] = FFMIN(seek_point, 255);
     410             :     }
     411             : 
     412             :     /* write replaygain */
     413           1 :     rg = (AVReplayGain*)av_stream_get_side_data(s->streams[0], AV_PKT_DATA_REPLAYGAIN,
     414             :                                                 &rg_size);
     415           1 :     if (rg && rg_size >= sizeof(*rg)) {
     416             :         uint16_t val;
     417             : 
     418           0 :         AV_WB32(mp3->xing_frame + mp3->xing_offset + 131,
     419             :                 av_rescale(rg->track_peak, 1 << 23, 100000));
     420             : 
     421           0 :         if (rg->track_gain != INT32_MIN) {
     422           0 :             val  = FFABS(rg->track_gain / 10000) & ((1 << 9) - 1);
     423           0 :             val |= (rg->track_gain < 0) << 9;
     424           0 :             val |= 1 << 13;
     425           0 :             AV_WB16(mp3->xing_frame + mp3->xing_offset + 135, val);
     426             :         }
     427             : 
     428           0 :         if (rg->album_gain != INT32_MIN) {
     429           0 :             val  = FFABS(rg->album_gain / 10000) & ((1 << 9) - 1);
     430           0 :             val |= (rg->album_gain < 0) << 9;
     431           0 :             val |= 1 << 14;
     432           0 :             AV_WB16(mp3->xing_frame + mp3->xing_offset + 137, val);
     433             :         }
     434             :     }
     435             : 
     436             :     /* write encoder delay/padding */
     437           1 :     if (mp3->delay >= 1 << 12) {
     438           0 :         mp3->delay = (1 << 12) - 1;
     439           0 :         av_log(s, AV_LOG_WARNING, "Too many samples of initial padding.\n");
     440             :     }
     441           1 :     if (mp3->padding >= 1 << 12) {
     442           0 :         mp3->padding = (1 << 12) - 1;
     443           0 :         av_log(s, AV_LOG_WARNING, "Too many samples of trailing padding.\n");
     444             :     }
     445           1 :     AV_WB24(mp3->xing_frame + mp3->xing_offset + 141, (mp3->delay << 12) + mp3->padding);
     446             : 
     447           1 :     AV_WB32(mp3->xing_frame + mp3->xing_offset + XING_SIZE - 8, mp3->audio_size);
     448           1 :     AV_WB16(mp3->xing_frame + mp3->xing_offset + XING_SIZE - 4, mp3->audio_crc);
     449             : 
     450           1 :     tag_crc = av_crc(av_crc_get_table(AV_CRC_16_ANSI_LE), 0, mp3->xing_frame, 190);
     451           1 :     AV_WB16(mp3->xing_frame + mp3->xing_offset + XING_SIZE - 2, tag_crc);
     452             : 
     453           1 :     avio_seek(s->pb,  mp3->xing_frame_offset, SEEK_SET);
     454           1 :     avio_write(s->pb, mp3->xing_frame, mp3->xing_frame_size);
     455           1 :     avio_seek(s->pb, 0, SEEK_END);
     456           1 : }
     457             : 
     458           1 : static int mp3_write_trailer(struct AVFormatContext *s)
     459             : {
     460             :     uint8_t buf[ID3v1_TAG_SIZE];
     461           1 :     MP3Context *mp3 = s->priv_data;
     462             : 
     463           1 :     if (mp3->pics_to_write) {
     464           0 :         av_log(s, AV_LOG_WARNING, "No packets were sent for some of the "
     465             :                "attached pictures.\n");
     466           0 :         mp3_queue_flush(s);
     467             :     }
     468             : 
     469             :     /* write the id3v1 tag */
     470           1 :     if (mp3->write_id3v1 && id3v1_create_tag(s, buf) > 0) {
     471           0 :         avio_write(s->pb, buf, ID3v1_TAG_SIZE);
     472             :     }
     473             : 
     474           1 :     if (mp3->xing_offset)
     475           1 :         mp3_update_xing(s);
     476             : 
     477           1 :     av_freep(&mp3->xing_frame);
     478             : 
     479           1 :     return 0;
     480             : }
     481             : 
     482           1 : static int query_codec(enum AVCodecID id, int std_compliance)
     483             : {
     484           1 :     const CodecMime *cm= ff_id3v2_mime_tags;
     485           5 :     while(cm->id != AV_CODEC_ID_NONE) {
     486           4 :         if(id == cm->id)
     487           1 :             return MKTAG('A', 'P', 'I', 'C');
     488           3 :         cm++;
     489             :     }
     490           0 :     return -1;
     491             : }
     492             : 
     493             : static const AVOption options[] = {
     494             :     { "id3v2_version", "Select ID3v2 version to write. Currently 3 and 4 are supported.",
     495             :       offsetof(MP3Context, id3v2_version), AV_OPT_TYPE_INT, {.i64 = 4}, 0, 4, AV_OPT_FLAG_ENCODING_PARAM},
     496             :     { "write_id3v1", "Enable ID3v1 writing. ID3v1 tags are written in UTF-8 which may not be supported by most software.",
     497             :       offsetof(MP3Context, write_id3v1), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
     498             :     { "write_xing",  "Write the Xing header containing file duration.",
     499             :       offsetof(MP3Context, write_xing),  AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
     500             :     { NULL },
     501             : };
     502             : 
     503             : static const AVClass mp3_muxer_class = {
     504             :     .class_name     = "MP3 muxer",
     505             :     .item_name      = av_default_item_name,
     506             :     .option         = options,
     507             :     .version        = LIBAVUTIL_VERSION_INT,
     508             : };
     509             : 
     510         150 : static int mp3_write_packet(AVFormatContext *s, AVPacket *pkt)
     511             : {
     512         150 :     MP3Context *mp3 = s->priv_data;
     513             : 
     514         150 :     if (pkt->stream_index == mp3->audio_stream_idx) {
     515         150 :         if (mp3->pics_to_write) {
     516             :             /* buffer audio packets until we get all the pictures */
     517           0 :             AVPacketList *pktl = av_mallocz(sizeof(*pktl));
     518             : 
     519           0 :             if (!pktl || av_packet_ref(&pktl->pkt, pkt) < 0) {
     520           0 :                 av_freep(&pktl);
     521           0 :                 av_log(s, AV_LOG_WARNING, "Not enough memory to buffer audio. Skipping picture streams\n");
     522           0 :                 mp3->pics_to_write = 0;
     523           0 :                 mp3_queue_flush(s);
     524           0 :                 return mp3_write_audio_packet(s, pkt);
     525             :             }
     526             : 
     527           0 :             if (mp3->queue_end)
     528           0 :                 mp3->queue_end->next = pktl;
     529             :             else
     530           0 :                 mp3->queue = pktl;
     531           0 :             mp3->queue_end = pktl;
     532             :         } else
     533         150 :             return mp3_write_audio_packet(s, pkt);
     534             :     } else {
     535             :         int ret;
     536             : 
     537             :         /* warn only once for each stream */
     538           0 :         if (s->streams[pkt->stream_index]->nb_frames == 1) {
     539           0 :             av_log(s, AV_LOG_WARNING, "Got more than one picture in stream %d,"
     540             :                    " ignoring.\n", pkt->stream_index);
     541             :         }
     542           0 :         if (!mp3->pics_to_write || s->streams[pkt->stream_index]->nb_frames >= 1)
     543           0 :             return 0;
     544             : 
     545           0 :         if ((ret = ff_id3v2_write_apic(s, &mp3->id3, pkt)) < 0)
     546           0 :             return ret;
     547           0 :         mp3->pics_to_write--;
     548             : 
     549             :         /* flush the buffered audio packets */
     550           0 :         if (!mp3->pics_to_write &&
     551             :             (ret = mp3_queue_flush(s)) < 0)
     552           0 :             return ret;
     553             :     }
     554             : 
     555           0 :     return 0;
     556             : }
     557             : 
     558             : /**
     559             :  * Write an ID3v2 header at beginning of stream
     560             :  */
     561             : 
     562           1 : static int mp3_write_header(struct AVFormatContext *s)
     563             : {
     564           1 :     MP3Context  *mp3 = s->priv_data;
     565             :     int ret, i;
     566             : 
     567           2 :     if (mp3->id3v2_version      &&
     568           2 :         mp3->id3v2_version != 3 &&
     569           1 :         mp3->id3v2_version != 4) {
     570           0 :         av_log(s, AV_LOG_ERROR, "Invalid ID3v2 version requested: %d. Only "
     571             :                "3, 4 or 0 (disabled) are allowed.\n", mp3->id3v2_version);
     572           0 :         return AVERROR(EINVAL);
     573             :     }
     574             : 
     575             :     /* check the streams -- we want exactly one audio and arbitrary number of
     576             :      * video (attached pictures) */
     577           1 :     mp3->audio_stream_idx = -1;
     578           2 :     for (i = 0; i < s->nb_streams; i++) {
     579           1 :         AVStream *st = s->streams[i];
     580           1 :         if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
     581           1 :             if (mp3->audio_stream_idx >= 0 || st->codecpar->codec_id != AV_CODEC_ID_MP3) {
     582           0 :                 av_log(s, AV_LOG_ERROR, "Invalid audio stream. Exactly one MP3 "
     583             :                        "audio stream is required.\n");
     584           0 :                 return AVERROR(EINVAL);
     585             :             }
     586           1 :             mp3->audio_stream_idx = i;
     587           0 :         } else if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO) {
     588           0 :             av_log(s, AV_LOG_ERROR, "Only audio streams and pictures are allowed in MP3.\n");
     589           0 :             return AVERROR(EINVAL);
     590             :         }
     591             :     }
     592           1 :     if (mp3->audio_stream_idx < 0) {
     593           0 :         av_log(s, AV_LOG_ERROR, "No audio stream present.\n");
     594           0 :         return AVERROR(EINVAL);
     595             :     }
     596           1 :     mp3->pics_to_write = s->nb_streams - 1;
     597             : 
     598           1 :     if (mp3->pics_to_write && !mp3->id3v2_version) {
     599           0 :         av_log(s, AV_LOG_ERROR, "Attached pictures were requested, but the "
     600             :                "ID3v2 header is disabled.\n");
     601           0 :         return AVERROR(EINVAL);
     602             :     }
     603             : 
     604           1 :     if (mp3->id3v2_version) {
     605           1 :         ff_id3v2_start(&mp3->id3, s->pb, mp3->id3v2_version, ID3v2_DEFAULT_MAGIC);
     606           1 :         ret = ff_id3v2_write_metadata(s, &mp3->id3);
     607           1 :         if (ret < 0)
     608           0 :             return ret;
     609             :     }
     610             : 
     611           1 :     if (!mp3->pics_to_write) {
     612           1 :         if (mp3->id3v2_version)
     613           1 :             ff_id3v2_finish(&mp3->id3, s->pb, s->metadata_header_padding);
     614           1 :         mp3_write_xing(s);
     615             :     }
     616             : 
     617           1 :     return 0;
     618             : }
     619             : 
     620             : AVOutputFormat ff_mp3_muxer = {
     621             :     .name              = "mp3",
     622             :     .long_name         = NULL_IF_CONFIG_SMALL("MP3 (MPEG audio layer 3)"),
     623             :     .mime_type         = "audio/mpeg",
     624             :     .extensions        = "mp3",
     625             :     .priv_data_size    = sizeof(MP3Context),
     626             :     .audio_codec       = AV_CODEC_ID_MP3,
     627             :     .video_codec       = AV_CODEC_ID_PNG,
     628             :     .write_header      = mp3_write_header,
     629             :     .write_packet      = mp3_write_packet,
     630             :     .write_trailer     = mp3_write_trailer,
     631             :     .query_codec       = query_codec,
     632             :     .flags             = AVFMT_NOTIMESTAMPS,
     633             :     .priv_class        = &mp3_muxer_class,
     634             : };

Generated by: LCOV version 1.13