FFmpeg
id3v2enc.c
Go to the documentation of this file.
1 /*
2  * ID3v2 header writer
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <stdint.h>
22 #include <string.h>
23 
24 #include "libavutil/avstring.h"
25 #include "libavutil/dict.h"
26 #include "libavutil/intreadwrite.h"
27 #include "avformat.h"
28 #include "avio.h"
29 #include "avio_internal.h"
30 #include "id3v2.h"
31 #include "mux.h"
32 
33 static void id3v2_put_size(AVIOContext *pb, int size)
34 {
35  avio_w8(pb, size >> 21 & 0x7f);
36  avio_w8(pb, size >> 14 & 0x7f);
37  avio_w8(pb, size >> 7 & 0x7f);
38  avio_w8(pb, size & 0x7f);
39 }
40 
41 static int string_is_ascii(const uint8_t *str)
42 {
43  while (*str && *str < 128) str++;
44  return !*str;
45 }
46 
47 static void id3v2_encode_string(AVIOContext *pb, const uint8_t *str,
48  enum ID3v2Encoding enc)
49 {
50  int (*put)(AVIOContext*, const char*);
51 
52  if (enc == ID3v2_ENCODING_UTF16BOM) {
53  avio_wl16(pb, 0xFEFF); /* BOM */
54  put = avio_put_str16le;
55  } else
56  put = avio_put_str;
57 
58  put(pb, str);
59 }
60 
61 /**
62  * Write a text frame with one (normal frames) or two (TXXX frames) strings
63  * according to encoding (only UTF-8 or UTF-16+BOM supported).
64  * @return number of bytes written or a negative error code.
65  */
66 static int id3v2_put_ttag(ID3v2EncContext *id3, AVIOContext *avioc, const char *str1, const char *str2,
67  uint32_t tag, enum ID3v2Encoding enc)
68 {
69  int len, ret;
70  uint8_t *pb;
71  AVIOContext *dyn_buf;
72  if ((ret = avio_open_dyn_buf(&dyn_buf)) < 0)
73  return ret;
74 
75  /* check if the strings are ASCII-only and use UTF16 only if
76  * they're not */
77  if (enc == ID3v2_ENCODING_UTF16BOM && string_is_ascii(str1) &&
78  (!str2 || string_is_ascii(str2)))
80 
81  avio_w8(dyn_buf, enc);
82  id3v2_encode_string(dyn_buf, str1, enc);
83  if (str2)
84  id3v2_encode_string(dyn_buf, str2, enc);
85  len = avio_get_dyn_buf(dyn_buf, &pb);
86 
87  avio_wb32(avioc, tag);
88  /* ID3v2.3 frame size is not sync-safe */
89  if (id3->version == 3)
90  avio_wb32(avioc, len);
91  else
92  id3v2_put_size(avioc, len);
93  avio_wb16(avioc, 0);
94  avio_write(avioc, pb, len);
95 
96  ffio_free_dyn_buf(&dyn_buf);
97  return len + ID3v2_HEADER_SIZE;
98 }
99 
100 /**
101  * Write a priv frame with owner and data. 'key' is the owner prepended with
102  * ID3v2_PRIV_METADATA_PREFIX. 'data' is provided as a string. Any \xXX
103  * (where 'X' is a valid hex digit) will be unescaped to the byte value.
104  */
105 static int id3v2_put_priv(ID3v2EncContext *id3, AVIOContext *avioc, const char *key, const char *data)
106 {
107  int len, ret;
108  uint8_t *pb;
109  AVIOContext *dyn_buf;
110 
112  return 0;
113  }
114 
115  if ((ret = avio_open_dyn_buf(&dyn_buf)) < 0)
116  return ret;
117 
118  // owner + null byte.
119  avio_write(dyn_buf, key, strlen(key) + 1);
120 
121  while (*data) {
122  if (av_strstart(data, "\\x", &data)) {
123  if (data[0] && data[1] && av_isxdigit(data[0]) && av_isxdigit(data[1])) {
124  char digits[] = {data[0], data[1], 0};
125  avio_w8(dyn_buf, strtol(digits, NULL, 16));
126  data += 2;
127  } else {
128  ffio_free_dyn_buf(&dyn_buf);
129  av_log(avioc, AV_LOG_ERROR, "Invalid escape '\\x%.2s' in metadata tag '"
130  ID3v2_PRIV_METADATA_PREFIX "%s'.\n", data, key);
131  return AVERROR(EINVAL);
132  }
133  } else {
134  avio_write(dyn_buf, data++, 1);
135  }
136  }
137 
138  len = avio_get_dyn_buf(dyn_buf, &pb);
139 
140  avio_wb32(avioc, MKBETAG('P', 'R', 'I', 'V'));
141  if (id3->version == 3)
142  avio_wb32(avioc, len);
143  else
144  id3v2_put_size(avioc, len);
145  avio_wb16(avioc, 0);
146  avio_write(avioc, pb, len);
147 
148  ffio_free_dyn_buf(&dyn_buf);
149 
150  return len + ID3v2_HEADER_SIZE;
151 }
152 
154  const char table[][4], enum ID3v2Encoding enc)
155 {
156  uint32_t tag;
157  int i;
158 
159  if (t->key[0] != 'T' || strlen(t->key) != 4)
160  return -1;
161  tag = AV_RB32(t->key);
162  for (i = 0; *table[i]; i++)
163  if (tag == AV_RB32(table[i]))
164  return id3v2_put_ttag(id3, pb, t->value, NULL, tag, enc);
165  return -1;
166 }
167 
169 {
170  const AVDictionaryEntry *mtag = NULL;
171  AVDictionary *dst = NULL;
172  const char *key, *value;
173  char year[5] = {0}, day_month[5] = {0};
174  int i;
175 
176  while ((mtag = av_dict_iterate(*pm, mtag))) {
177  key = mtag->key;
178  if (!av_strcasecmp(key, "date")) {
179  /* split date tag using "YYYY-MM-DD" format into year and month/day segments */
180  value = mtag->value;
181  i = 0;
182  while (value[i] >= '0' && value[i] <= '9') i++;
183  if (value[i] == '\0' || value[i] == '-') {
184  av_strlcpy(year, value, sizeof(year));
185  av_dict_set(&dst, "TYER", year, 0);
186 
187  if (value[i] == '-' &&
188  value[i+1] >= '0' && value[i+1] <= '1' &&
189  value[i+2] >= '0' && value[i+2] <= '9' &&
190  value[i+3] == '-' &&
191  value[i+4] >= '0' && value[i+4] <= '3' &&
192  value[i+5] >= '0' && value[i+5] <= '9' &&
193  (value[i+6] == '\0' || value[i+6] == ' ')) {
194  snprintf(day_month, sizeof(day_month), "%.2s%.2s", value + i + 4, value + i + 1);
195  av_dict_set(&dst, "TDAT", day_month, 0);
196  }
197  } else
198  av_dict_set(&dst, key, value, 0);
199  } else
200  av_dict_set(&dst, key, mtag->value, 0);
201  }
202  av_dict_free(pm);
203  *pm = dst;
204 }
205 
206 void ff_id3v2_start(ID3v2EncContext *id3, AVIOContext *pb, int id3v2_version,
207  const char *magic)
208 {
209  id3->version = id3v2_version;
210 
211  avio_wb32(pb, MKBETAG(magic[0], magic[1], magic[2], id3v2_version));
212  avio_w8(pb, 0);
213  avio_w8(pb, 0); /* flags */
214 
215  /* reserve space for size */
216  id3->size_pos = avio_tell(pb);
217  avio_wb32(pb, 0);
218 }
219 
220 static int write_metadata(AVIOContext *pb, AVDictionary **metadata,
221  ID3v2EncContext *id3, int enc)
222 {
223  const AVDictionaryEntry *t = NULL;
224  int ret;
225 
227  if (id3->version == 3)
228  id3v2_3_metadata_split_date(metadata);
229  else if (id3->version == 4)
231 
232  while ((t = av_dict_iterate(*metadata, t))) {
233  if ((ret = id3v2_check_write_tag(id3, pb, t, ff_id3v2_tags, enc)) > 0) {
234  id3->len += ret;
235  continue;
236  }
237  if ((ret = id3v2_check_write_tag(id3, pb, t, id3->version == 3 ?
238  ff_id3v2_3_tags : ff_id3v2_4_tags, enc)) > 0) {
239  id3->len += ret;
240  continue;
241  }
242 
243  if ((ret = id3v2_put_priv(id3, pb, t->key, t->value)) > 0) {
244  id3->len += ret;
245  continue;
246  } else if (ret < 0) {
247  return ret;
248  }
249 
250  /* unknown tag, write as TXXX frame */
251  if ((ret = id3v2_put_ttag(id3, pb, t->key, t->value, MKBETAG('T', 'X', 'X', 'X'), enc)) < 0)
252  return ret;
253  id3->len += ret;
254  }
255 
256  return 0;
257 }
258 
259 static int write_ctoc(AVFormatContext *s, ID3v2EncContext *id3, int enc)
260 {
261  uint8_t *dyn_buf;
262  AVIOContext *dyn_bc;
263  char name[123];
264  int len, ret;
265 
266  if (s->nb_chapters == 0)
267  return 0;
268 
269  if ((ret = avio_open_dyn_buf(&dyn_bc)) < 0)
270  return ret;
271 
272  avio_put_str(dyn_bc, "toc");
273  avio_w8(dyn_bc, 0x03);
274  avio_w8(dyn_bc, s->nb_chapters);
275  for (int i = 0; i < s->nb_chapters; i++) {
276  snprintf(name, 122, "ch%d", i);
277  avio_put_str(dyn_bc, name);
278  }
279  len = avio_get_dyn_buf(dyn_bc, &dyn_buf);
280  id3->len += len + ID3v2_HEADER_SIZE;
281 
282  avio_wb32(s->pb, MKBETAG('C', 'T', 'O', 'C'));
283  avio_wb32(s->pb, len);
284  avio_wb16(s->pb, 0);
285  avio_write(s->pb, dyn_buf, len);
286 
287  ffio_free_dyn_buf(&dyn_bc);
288 
289  return ret;
290 }
291 
292 static int write_chapter(AVFormatContext *s, ID3v2EncContext *id3, int id, int enc)
293 {
294  const AVRational time_base = {1, 1000};
295  AVChapter *ch = s->chapters[id];
296  uint8_t *dyn_buf;
297  AVIOContext *dyn_bc;
298  char name[123];
299  int len, start, end, ret;
300 
301  if ((ret = avio_open_dyn_buf(&dyn_bc)) < 0)
302  return ret;
303 
304  start = av_rescale_q(ch->start, ch->time_base, time_base);
305  end = av_rescale_q(ch->end, ch->time_base, time_base);
306 
307  snprintf(name, 122, "ch%d", id);
308  id3->len += avio_put_str(dyn_bc, name);
309  avio_wb32(dyn_bc, start);
310  avio_wb32(dyn_bc, end);
311  avio_wb32(dyn_bc, 0xFFFFFFFFu);
312  avio_wb32(dyn_bc, 0xFFFFFFFFu);
313 
314  if ((ret = write_metadata(dyn_bc, &ch->metadata, id3, enc)) < 0)
315  goto fail;
316 
317  len = avio_get_dyn_buf(dyn_bc, &dyn_buf);
318  id3->len += 16 + ID3v2_HEADER_SIZE;
319 
320  avio_wb32(s->pb, MKBETAG('C', 'H', 'A', 'P'));
321  avio_wb32(s->pb, len);
322  avio_wb16(s->pb, 0);
323  avio_write(s->pb, dyn_buf, len);
324 
325 fail:
326  ffio_free_dyn_buf(&dyn_bc);
327 
328  return ret;
329 }
330 
332 {
333  int enc = id3->version == 3 ? ID3v2_ENCODING_UTF16BOM :
335  int i, ret;
336 
338  if ((ret = write_metadata(s->pb, &s->metadata, id3, enc)) < 0)
339  return ret;
340 
341  if ((ret = write_ctoc(s, id3, enc)) < 0)
342  return ret;
343 
344  for (i = 0; i < s->nb_chapters; i++) {
345  if ((ret = write_chapter(s, id3, i, enc)) < 0)
346  return ret;
347  }
348 
349  return 0;
350 }
351 
353 {
354  AVStream *st = s->streams[pkt->stream_index];
356 
357  AVIOContext *dyn_buf;
358  uint8_t *buf;
359  const CodecMime *mime = ff_id3v2_mime_tags;
360  const char *mimetype = NULL, *desc = "";
361  int enc = id3->version == 3 ? ID3v2_ENCODING_UTF16BOM :
363  int i, len, type = 0, ret;
364 
365  /* get the mimetype*/
366  while (mime->id != AV_CODEC_ID_NONE) {
367  if (mime->id == st->codecpar->codec_id) {
368  mimetype = mime->str;
369  break;
370  }
371  mime++;
372  }
373  if (!mimetype) {
374  av_log(s, AV_LOG_ERROR, "No mimetype is known for stream %d, cannot "
375  "write an attached picture.\n", st->index);
376  return AVERROR(EINVAL);
377  }
378 
379  /* get the picture type */
380  e = av_dict_get(st->metadata, "comment", NULL, 0);
381  for (i = 0; e && i < FF_ARRAY_ELEMS(ff_id3v2_picture_types); i++) {
383  type = i;
384  break;
385  }
386  }
387 
388  /* get the description */
389  if ((e = av_dict_get(st->metadata, "title", NULL, 0)))
390  desc = e->value;
391 
392  /* use UTF16 only for non-ASCII strings */
395 
396  /* start writing */
397  if ((ret = avio_open_dyn_buf(&dyn_buf)) < 0)
398  return ret;
399 
400  avio_w8(dyn_buf, enc);
401  avio_put_str(dyn_buf, mimetype);
402  avio_w8(dyn_buf, type);
403  id3v2_encode_string(dyn_buf, desc, enc);
404  avio_write(dyn_buf, pkt->data, pkt->size);
405  len = avio_get_dyn_buf(dyn_buf, &buf);
406 
407  avio_wb32(s->pb, MKBETAG('A', 'P', 'I', 'C'));
408  if (id3->version == 3)
409  avio_wb32(s->pb, len);
410  else
411  id3v2_put_size(s->pb, len);
412  avio_wb16(s->pb, 0);
413  avio_write(s->pb, buf, len);
414  ffio_free_dyn_buf(&dyn_buf);
415 
416  id3->len += len + ID3v2_HEADER_SIZE;
417 
418  return 0;
419 }
420 
422  int padding_bytes)
423 {
424  int64_t cur_pos;
425 
426  if (padding_bytes < 0)
427  padding_bytes = 10;
428 
429  /* The ID3v2.3 specification states that 28 bits are used to represent the
430  * size of the whole tag. Therefore the current size of the tag needs to be
431  * subtracted from the upper limit of 2^28-1 to clip the value correctly. */
432  /* The minimum of 10 is an arbitrary amount of padding at the end of the tag
433  * to fix cover art display with some software such as iTunes, Traktor,
434  * Serato, Torq. */
435  padding_bytes = av_clip(padding_bytes, 10, 268435455 - id3->len);
436  ffio_fill(pb, 0, padding_bytes);
437  id3->len += padding_bytes;
438 
439  cur_pos = avio_tell(pb);
440  avio_seek(pb, id3->size_pos, SEEK_SET);
441  id3v2_put_size(pb, id3->len);
442  avio_seek(pb, cur_pos, SEEK_SET);
443 }
444 
445 int ff_id3v2_write_simple(struct AVFormatContext *s, int id3v2_version,
446  const char *magic)
447 {
448  ID3v2EncContext id3 = { 0 };
449  int ret;
450 
451  ff_id3v2_start(&id3, s->pb, id3v2_version, magic);
452  if ((ret = ff_id3v2_write_metadata(s, &id3)) < 0)
453  return ret;
454  ff_id3v2_finish(&id3, s->pb, s->metadata_header_padding);
455 
456  return 0;
457 }
av_isxdigit
static av_const int av_isxdigit(int c)
Locale-independent conversion of ASCII isxdigit.
Definition: avstring.h:247
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
av_clip
#define av_clip
Definition: common.h:98
ID3v2EncContext
Definition: id3v2.h:51
AVChapter::metadata
AVDictionary * metadata
Definition: avformat.h:1218
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
write_metadata
static int write_metadata(AVIOContext *pb, AVDictionary **metadata, ID3v2EncContext *id3, int enc)
Definition: id3v2enc.c:220
ID3v2EncContext::len
int len
size of the tag written so far
Definition: id3v2.h:54
ff_id3v2_4_tags
const char ff_id3v2_4_tags[][4]
ID3v2.4-only text information frames.
Definition: id3v2.c:97
av_strcasecmp
int av_strcasecmp(const char *a, const char *b)
Locale-independent case-insensitive compare.
Definition: avstring.c:207
id3v2.h
ff_metadata_conv
void ff_metadata_conv(AVDictionary **pm, const AVMetadataConv *d_conv, const AVMetadataConv *s_conv)
Definition: metadata.c:26
AVPacket::data
uint8_t * data
Definition: packet.h:522
ID3v2EncContext::version
int version
ID3v2 minor version, either 3 or 4.
Definition: id3v2.h:52
table
static const uint16_t table[]
Definition: prosumer.c:205
AVChapter::start
int64_t start
Definition: avformat.h:1217
data
const char data[16]
Definition: mxf.c:148
ff_id3v2_finish
void ff_id3v2_finish(ID3v2EncContext *id3, AVIOContext *pb, int padding_bytes)
Finalize an opened ID3v2 tag.
Definition: id3v2enc.c:421
AVDictionary
Definition: dict.c:34
avio_get_dyn_buf
int avio_get_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition: aviobuf.c:1373
ff_id3v2_write_metadata
int ff_id3v2_write_metadata(AVFormatContext *s, ID3v2EncContext *id3)
Convert and write all global metadata from s into an ID3v2 tag.
Definition: id3v2enc.c:331
avio_wl16
void avio_wl16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:436
CodecMime
Definition: internal.h:53
id3v2_encode_string
static void id3v2_encode_string(AVIOContext *pb, const uint8_t *str, enum ID3v2Encoding enc)
Definition: id3v2enc.c:47
fail
#define fail()
Definition: checkasm.h:179
id3v2_put_ttag
static int id3v2_put_ttag(ID3v2EncContext *id3, AVIOContext *avioc, const char *str1, const char *str2, uint32_t tag, enum ID3v2Encoding enc)
Write a text frame with one (normal frames) or two (TXXX frames) strings according to encoding (only ...
Definition: id3v2enc.c:66
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
AVChapter
Definition: avformat.h:1214
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
ID3v2_PRIV_METADATA_PREFIX
#define ID3v2_PRIV_METADATA_PREFIX
Definition: id3v2.h:42
pkt
AVPacket * pkt
Definition: movenc.c:59
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
ff_id3v2_write_simple
int ff_id3v2_write_simple(struct AVFormatContext *s, int id3v2_version, const char *magic)
Write an ID3v2 tag containing all global metadata from s.
Definition: id3v2enc.c:445
ID3v2_ENCODING_UTF8
@ ID3v2_ENCODING_UTF8
Definition: id3v2.h:48
av_dict_get
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition: dict.c:62
avio_open_dyn_buf
int avio_open_dyn_buf(AVIOContext **s)
Open a write only memory stream.
Definition: aviobuf.c:1361
AVChapter::end
int64_t end
chapter start/end time in time_base units
Definition: avformat.h:1217
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
id3v2_put_size
static void id3v2_put_size(AVIOContext *pb, int size)
Definition: id3v2enc.c:33
AVDictionaryEntry::key
char * key
Definition: dict.h:90
id3v2_3_metadata_split_date
static void id3v2_3_metadata_split_date(AVDictionary **pm)
Definition: id3v2enc.c:168
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
id3v2_put_priv
static int id3v2_put_priv(ID3v2EncContext *id3, AVIOContext *avioc, const char *key, const char *data)
Write a priv frame with owner and data.
Definition: id3v2enc.c:105
key
const char * key
Definition: hwcontext_opencl.c:189
if
if(ret)
Definition: filter_design.txt:179
AVFormatContext
Format I/O context.
Definition: avformat.h:1255
ff_id3v2_start
void ff_id3v2_start(ID3v2EncContext *id3, AVIOContext *pb, int id3v2_version, const char *magic)
Initialize an ID3v2 tag.
Definition: id3v2enc.c:206
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:766
NULL
#define NULL
Definition: coverity.c:32
ID3v2Encoding
ID3v2Encoding
Definition: id3v2.h:44
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
ID3v2EncContext::size_pos
int64_t size_pos
offset of the tag total size
Definition: id3v2.h:53
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:823
avio_w8
void avio_w8(AVIOContext *s, int b)
Definition: aviobuf.c:178
ffio_fill
void ffio_fill(AVIOContext *s, int b, int64_t count)
Definition: aviobuf.c:186
ff_id3v2_picture_types
const char *const ff_id3v2_picture_types[21]
Definition: id3v2.c:108
ID3v2_HEADER_SIZE
#define ID3v2_HEADER_SIZE
Definition: id3v2.h:30
ff_id3v2_3_tags
const char ff_id3v2_3_tags[][4]
ID3v2.3-only text information frames.
Definition: id3v2.c:103
ff_id3v2_mime_tags
const CodecMime ff_id3v2_mime_tags[]
Definition: id3v2.c:132
id3v2_check_write_tag
static int id3v2_check_write_tag(ID3v2EncContext *id3, AVIOContext *pb, const AVDictionaryEntry *t, const char table[][4], enum ID3v2Encoding enc)
Definition: id3v2enc.c:153
ff_id3v2_tags
const char ff_id3v2_tags[][4]
A list of text information frames allowed in both ID3 v2.3 and v2.4 http://www.id3....
Definition: id3v2.c:89
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
ID3v2_ENCODING_UTF16BOM
@ ID3v2_ENCODING_UTF16BOM
Definition: id3v2.h:46
AVPacket::size
int size
Definition: packet.h:523
ff_standardize_creation_time
int ff_standardize_creation_time(AVFormatContext *s)
Standardize creation_time metadata in AVFormatContext to an ISO-8601 timestamp string.
Definition: mux_utils.c:133
size
int size
Definition: twinvq_data.h:10344
avio.h
MKBETAG
#define MKBETAG(a, b, c, d)
Definition: macros.h:56
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
ff_id3v2_34_metadata_conv
const AVMetadataConv ff_id3v2_34_metadata_conv[]
Definition: id3v2.c:45
write_ctoc
static int write_ctoc(AVFormatContext *s, ID3v2EncContext *id3, int enc)
Definition: id3v2enc.c:259
avio_write
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:200
avio_wb32
void avio_wb32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:364
av_dict_free
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:223
av_strstart
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition: avstring.c:36
ff_id3v2_write_apic
int ff_id3v2_write_apic(AVFormatContext *s, ID3v2EncContext *id3, AVPacket *pkt)
Write an attached picture from pkt into an ID3v2 tag.
Definition: id3v2enc.c:352
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
avio_internal.h
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
len
int len
Definition: vorbis_enc_data.h:426
tag
uint32_t tag
Definition: movenc.c:1786
ffio_free_dyn_buf
void ffio_free_dyn_buf(AVIOContext **s)
Free a dynamic buffer.
Definition: aviobuf.c:1434
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:743
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:230
avformat.h
dict.h
id
enum AVCodecID id
Definition: dts2pts.c:364
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:749
ff_id3v2_4_metadata_conv
const AVMetadataConv ff_id3v2_4_metadata_conv[]
Definition: id3v2.c:64
AVPacket::stream_index
int stream_index
Definition: packet.h:524
CodecMime::str
char str[32]
Definition: internal.h:54
CodecMime::id
enum AVCodecID id
Definition: internal.h:55
desc
const char * desc
Definition: libsvtav1.c:73
string_is_ascii
static int string_is_ascii(const uint8_t *str)
Definition: id3v2enc.c:41
AVDictionaryEntry
Definition: dict.h:89
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
AVPacket
This structure stores compressed data.
Definition: packet.h:499
av_dict_set
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:88
avio_put_str16le
int avio_put_str16le(AVIOContext *s, const char *str)
Convert an UTF-8 string to UTF-16LE and write it.
avio_wb16
void avio_wb16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:442
av_strlcpy
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition: avstring.c:85
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVDictionaryEntry::value
char * value
Definition: dict.h:91
avstring.h
AVChapter::time_base
AVRational time_base
time base in which the start/end timestamps are specified
Definition: avformat.h:1216
avio_put_str
int avio_put_str(AVIOContext *s, const char *str)
Write a NULL-terminated string.
Definition: aviobuf.c:372
int
int
Definition: ffmpeg_filter.c:425
snprintf
#define snprintf
Definition: snprintf.h:34
write_chapter
static int write_chapter(AVFormatContext *s, ID3v2EncContext *id3, int id, int enc)
Definition: id3v2enc.c:292
av_dict_iterate
const AVDictionaryEntry * av_dict_iterate(const AVDictionary *m, const AVDictionaryEntry *prev)
Iterate over a dictionary.
Definition: dict.c:44
ID3v2_ENCODING_ISO8859
@ ID3v2_ENCODING_ISO8859
Definition: id3v2.h:45
mux.h