Revision 5b7e7544

View differences:

libavformat/mp3enc.c
24 24
#include "id3v1.h"
25 25
#include "id3v2.h"
26 26
#include "libavutil/intreadwrite.h"
27
#include "libavutil/opt.h"
27 28

  
28 29
static int id3v1_set_string(AVFormatContext *s, const char *key,
29 30
                            uint8_t *buf, int buf_size)
......
148 149
#endif
149 150

  
150 151
#if CONFIG_MP3_MUXER
151
static int id3v2_check_write_tag(AVFormatContext *s, AVMetadataTag *t, const char table[][4])
152
typedef struct MP3Context {
153
    const AVClass *class;
154
    int id3v2_version;
155
} MP3Context;
156

  
157
static const AVOption options[] = {
158
    { "id3v2_version", "Select ID3v2 version to write. Currently 3 and 4 are supported.",
159
      offsetof(MP3Context, id3v2_version), FF_OPT_TYPE_INT, 4, 3, 4, AV_OPT_FLAG_ENCODING_PARAM},
160
    { NULL },
161
};
162

  
163
static const AVClass mp3_muxer_class = {
164
    "MP3 muxer",
165
    av_default_item_name,
166
    options,
167
    LIBAVUTIL_VERSION_INT,
168
};
169

  
170
static int id3v2_check_write_tag(AVFormatContext *s, AVMetadataTag *t, const char table[][4],
171
                                 enum ID3v2Encoding enc)
152 172
{
153 173
    uint32_t tag;
154 174
    int i;
......
158 178
    tag = AV_RB32(t->key);
159 179
    for (i = 0; *table[i]; i++)
160 180
        if (tag == AV_RB32(table[i]))
161
            return id3v2_put_ttag(s, t->value, NULL, tag, ID3v2_ENCODING_UTF8);
181
            return id3v2_put_ttag(s, t->value, NULL, tag, enc);
162 182
    return -1;
163 183
}
164 184

  
165 185
/**
166
 * Write an ID3v2.4 header at beginning of stream
186
 * Write an ID3v2 header at beginning of stream
167 187
 */
168 188

  
169 189
static int mp3_write_header(struct AVFormatContext *s)
170 190
{
191
    MP3Context  *mp3 = s->priv_data;
171 192
    AVMetadataTag *t = NULL;
172
    int totlen = 0;
193
    int totlen = 0, enc = mp3->id3v2_version == 3 ? ID3v2_ENCODING_UTF16BOM :
194
                                                    ID3v2_ENCODING_UTF8;
173 195
    int64_t size_pos, cur_pos;
174 196

  
175
    put_be32(s->pb, MKBETAG('I', 'D', '3', 0x04)); /* ID3v2.4 */
197
    put_be32(s->pb, MKBETAG('I', 'D', '3', mp3->id3v2_version));
176 198
    put_byte(s->pb, 0);
177 199
    put_byte(s->pb, 0); /* flags */
178 200

  
......
181 203
    put_be32(s->pb, 0);
182 204

  
183 205
    ff_metadata_conv(&s->metadata, ff_id3v2_34_metadata_conv, NULL);
184
    ff_metadata_conv(&s->metadata, ff_id3v2_4_metadata_conv, NULL);
206
    if (mp3->id3v2_version == 4)
207
        ff_metadata_conv(&s->metadata, ff_id3v2_4_metadata_conv, NULL);
208

  
185 209
    while ((t = av_metadata_get(s->metadata, "", t, AV_METADATA_IGNORE_SUFFIX))) {
186 210
        int ret;
187 211

  
188
        if ((ret = id3v2_check_write_tag(s, t, ff_id3v2_tags)) > 0) {
212
        if ((ret = id3v2_check_write_tag(s, t, ff_id3v2_tags, enc)) > 0) {
189 213
            totlen += ret;
190 214
            continue;
191 215
        }
192
        if ((ret = id3v2_check_write_tag(s, t, ff_id3v2_4_tags)) > 0) {
216
        if ((ret = id3v2_check_write_tag(s, t, mp3->id3v2_version == 3 ?
217
                                               ff_id3v2_3_tags : ff_id3v2_4_tags, enc)) > 0) {
193 218
            totlen += ret;
194 219
            continue;
195 220
        }
196 221

  
197 222
        /* unknown tag, write as TXXX frame */
198
        if ((ret = id3v2_put_ttag(s, t->key, t->value, MKBETAG('T', 'X', 'X', 'X'),
199
                                  ID3v2_ENCODING_UTF8)) < 0)
223
        if ((ret = id3v2_put_ttag(s, t->key, t->value, MKBETAG('T', 'X', 'X', 'X'), enc)) < 0)
200 224
            return ret;
201 225
        totlen += ret;
202 226
    }
......
214 238
    NULL_IF_CONFIG_SMALL("MPEG audio layer 3"),
215 239
    "audio/x-mpeg",
216 240
    "mp3",
217
    0,
241
    sizeof(MP3Context),
218 242
    CODEC_ID_MP3,
219 243
    CODEC_ID_NONE,
220 244
    mp3_write_header,
221 245
    mp3_write_packet,
222 246
    mp3_write_trailer,
223 247
    AVFMT_NOTIMESTAMPS,
248
    .priv_class = &mp3_muxer_class,
224 249
};
225 250
#endif

Also available in: Unified diff