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 | int64_t nb_frames_offset; | 80 | int64_t nb_frames_offset; |
| 81 | } MP3Context; | 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 | static int mp3_write_trailer(struct AVFormatContext *s) | 132 | static int mp3_write_trailer(struct AVFormatContext *s) |
| 84 | { | 133 | { |
| 85 | uint8_t buf[ID3v1_TAG_SIZE]; | 134 | uint8_t buf[ID3v1_TAG_SIZE]; |
| @@ -132,51 +181,6 @@ static const AVClass mp3_muxer_class = { · 46 unmodified lines | |||
| 132 | .version = LIBAVUTIL_VERSION_INT, | 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 | * Write an ID3v2 header at beginning of stream | 186 | * Write an ID3v2 header at beginning of stream |