It will be need by new functions called from mp3_write_trailer().
Unified · Split
| @@ -80,6 +80,55 @@ typedef struct MP3Context { · 79 unmodified lines | ||
| 80 | 80 | int64_t nb_frames_offset; |
| 81 | 81 | } MP3Context; |
| 82 | 82 | |
| 83 | +/* insert a dummy frame containing number of frames */ | |
| 84 | +static void mp3_write_xing(AVFormatContext *s) | |
| 85 | +{ | |
| 86 | + MP3Context *mp3 = s->priv_data; | |
| 87 | + AVCodecContext *codec = s->streams[0]->codec; | |
| 88 | + int bitrate_idx = 1; // 32 kbps | |
| 89 | + int64_t xing_offset = (codec->channels == 2) ? 32 : 17; | |
| 90 | + int32_t header; | |
| 91 | + MPADecodeHeader mpah; | |
| 92 | + int srate_idx, i, channels; | |
| 93 | + | |
| 94 | + if (!s->pb->seekable) | |
| 95 | + return; | |
| 96 | + | |
| 97 | + for (i = 0; i < FF_ARRAY_ELEMS(avpriv_mpa_freq_tab); i++) | |
| 98 | + if (avpriv_mpa_freq_tab[i] == codec->sample_rate) { | |
| 99 | + srate_idx = i; | |
| 100 | + break; | |
| 101 | + } | |
| 102 | + if (i == FF_ARRAY_ELEMS(avpriv_mpa_freq_tab)) { | |
| 103 | + av_log(s, AV_LOG_ERROR, "Unsupported sample rate.\n"); | |
| 104 | + return; | |
| 105 | + } | |
| 106 | + | |
| 107 | + switch (codec->channels) { | |
| 108 | + case 1: channels = MPA_MONO; break; | |
| 109 | + case 2: channels = MPA_STEREO; break; | |
| 110 | + default: av_log(s, AV_LOG_ERROR, "Unsupported number of channels.\n"); return; | |
| 111 | + } | |
| 112 | + | |
| 113 | + /* dummy MPEG audio header */ | |
| 114 | + header = 0xff << 24; // sync | |
| 115 | + header |= (0x7 << 5 | 0x3 << 3 | 0x1 << 1 | 0x1) << 16; // sync/mpeg-1/layer 3/no crc*/ | |
| 116 | + header |= (bitrate_idx << 4 | srate_idx << 2) << 8; | |
| 117 | + header |= channels << 6; | |
| 118 | + avio_wb32(s->pb, header); | |
| 119 | + | |
| 120 | + avpriv_mpegaudio_decode_header(&mpah, header); | |
| 121 | + | |
| 122 | + ffio_fill(s->pb, 0, xing_offset); | |
| 123 | + ffio_wfourcc(s->pb, "Xing"); | |
| 124 | + avio_wb32(s->pb, 0x1); // only number of frames | |
| 125 | + mp3->nb_frames_offset = avio_tell(s->pb); | |
| 126 | + avio_wb32(s->pb, 0); | |
| 127 | + | |
| 128 | + mpah.frame_size -= 4 + xing_offset + 4 + 4 + 4; | |
| 129 | + ffio_fill(s->pb, 0, mpah.frame_size); | |
| 130 | +} | |
| 131 | + | |
| 83 | 132 | static int mp3_write_trailer(struct AVFormatContext *s) |
| 84 | 133 | { |
| 85 | 134 | uint8_t buf[ID3v1_TAG_SIZE]; |
| @@ -132,51 +181,6 @@ static const AVClass mp3_muxer_class = { · 46 unmodified lines | ||
| 132 | 181 | .version = LIBAVUTIL_VERSION_INT, |
| 133 | 182 | }; |
| 134 | 183 | |
| 135 | −/* insert a dummy frame containing number of frames */ | |
| 136 | −static void mp3_write_xing(AVFormatContext *s) | |
| 137 | −{ | |
| 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; | |
| 150 | − } | |
| 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); | |
| 179 | −} | |
| 180 | 184 | |
| 181 | 185 | /** |
| 182 | 186 | * Write an ID3v2 header at beginning of stream |