FFmpeg
id3v2.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2003 Fabrice Bellard
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 /**
22  * @file
23  * ID3v2 header parser
24  *
25  * Specifications available at:
26  * http://id3.org/Developer_Information
27  */
28 
29 #include "config.h"
30 
31 #if CONFIG_ZLIB
32 #include <zlib.h>
33 #endif
34 
35 #include "libavutil/avstring.h"
36 #include "libavutil/bprint.h"
37 #include "libavutil/dict.h"
38 #include "libavutil/intreadwrite.h"
39 #include "libavcodec/png.h"
40 #include "avio_internal.h"
41 #include "demux.h"
42 #include "id3v1.h"
43 #include "id3v2.h"
44 
46  { "TALB", "album" },
47  { "TCOM", "composer" },
48  { "TCON", "genre" },
49  { "TCOP", "copyright" },
50  { "TENC", "encoded_by" },
51  { "TIT2", "title" },
52  { "TLAN", "language" },
53  { "TPE1", "artist" },
54  { "TPE2", "album_artist" },
55  { "TPE3", "performer" },
56  { "TPOS", "disc" },
57  { "TPUB", "publisher" },
58  { "TRCK", "track" },
59  { "TSSE", "encoder" },
60  { "USLT", "lyrics" },
61  { 0 }
62 };
63 
65  { "TCMP", "compilation" },
66  { "TDRC", "date" },
67  { "TDRL", "date" },
68  { "TDEN", "creation_time" },
69  { "TSOA", "album-sort" },
70  { "TSOP", "artist-sort" },
71  { "TSOT", "title-sort" },
72  { "TIT1", "grouping" },
73  { 0 }
74 };
75 
77  { "TAL", "album" },
78  { "TCO", "genre" },
79  { "TCP", "compilation" },
80  { "TT2", "title" },
81  { "TEN", "encoded_by" },
82  { "TP1", "artist" },
83  { "TP2", "album_artist" },
84  { "TP3", "performer" },
85  { "TRK", "track" },
86  { 0 }
87 };
88 
89 const char ff_id3v2_tags[][4] = {
90  "TALB", "TBPM", "TCOM", "TCON", "TCOP", "TDLY", "TENC", "TEXT",
91  "TFLT", "TIT1", "TIT2", "TIT3", "TKEY", "TLAN", "TLEN", "TMED",
92  "TOAL", "TOFN", "TOLY", "TOPE", "TOWN", "TPE1", "TPE2", "TPE3",
93  "TPE4", "TPOS", "TPUB", "TRCK", "TRSN", "TRSO", "TSRC", "TSSE",
94  { 0 },
95 };
96 
97 const char ff_id3v2_4_tags[][4] = {
98  "TDEN", "TDOR", "TDRC", "TDRL", "TDTG", "TIPL", "TMCL", "TMOO",
99  "TPRO", "TSOA", "TSOP", "TSOT", "TSST",
100  { 0 },
101 };
102 
103 const char ff_id3v2_3_tags[][4] = {
104  "TDAT", "TIME", "TORY", "TRDA", "TSIZ", "TYER",
105  { 0 },
106 };
107 
108 const char * const ff_id3v2_picture_types[21] = {
109  "Other",
110  "32x32 pixels 'file icon'",
111  "Other file icon",
112  "Cover (front)",
113  "Cover (back)",
114  "Leaflet page",
115  "Media (e.g. label side of CD)",
116  "Lead artist/lead performer/soloist",
117  "Artist/performer",
118  "Conductor",
119  "Band/Orchestra",
120  "Composer",
121  "Lyricist/text writer",
122  "Recording Location",
123  "During recording",
124  "During performance",
125  "Movie/video screen capture",
126  "A bright coloured fish",
127  "Illustration",
128  "Band/artist logotype",
129  "Publisher/Studio logotype",
130 };
131 
133  { "image/gif", AV_CODEC_ID_GIF },
134  { "image/jpeg", AV_CODEC_ID_MJPEG },
135  { "image/jpg", AV_CODEC_ID_MJPEG },
136  { "image/png", AV_CODEC_ID_PNG },
137  { "image/tiff", AV_CODEC_ID_TIFF },
138  { "image/bmp", AV_CODEC_ID_BMP },
139  { "JPG", AV_CODEC_ID_MJPEG }, /* ID3v2.2 */
140  { "PNG", AV_CODEC_ID_PNG }, /* ID3v2.2 */
141  { "", AV_CODEC_ID_NONE },
142 };
143 
144 int ff_id3v2_match(const uint8_t *buf, const char *magic)
145 {
146  return buf[0] == magic[0] &&
147  buf[1] == magic[1] &&
148  buf[2] == magic[2] &&
149  buf[3] != 0xff &&
150  buf[4] != 0xff &&
151  (buf[6] & 0x80) == 0 &&
152  (buf[7] & 0x80) == 0 &&
153  (buf[8] & 0x80) == 0 &&
154  (buf[9] & 0x80) == 0;
155 }
156 
157 int ff_id3v2_tag_len(const uint8_t *buf)
158 {
159  int len = ((buf[6] & 0x7f) << 21) +
160  ((buf[7] & 0x7f) << 14) +
161  ((buf[8] & 0x7f) << 7) +
162  (buf[9] & 0x7f) +
164  if (buf[5] & 0x10)
166  return len;
167 }
168 
169 static unsigned int get_size(AVIOContext *s, int len)
170 {
171  int v = 0;
172  while (len--)
173  v = (v << 7) + (avio_r8(s) & 0x7F);
174  return v;
175 }
176 
177 static unsigned int size_to_syncsafe(unsigned int size)
178 {
179  return (((size) & (0x7f << 0)) >> 0) +
180  (((size) & (0x7f << 8)) >> 1) +
181  (((size) & (0x7f << 16)) >> 2) +
182  (((size) & (0x7f << 24)) >> 3);
183 }
184 
185 /* No real verification, only check that the tag consists of
186  * a combination of capital alpha-numerical characters */
187 static int is_tag(const char *buf, unsigned int len)
188 {
189  if (!len)
190  return 0;
191 
192  while (len--)
193  if ((buf[len] < 'A' ||
194  buf[len] > 'Z') &&
195  (buf[len] < '0' ||
196  buf[len] > '9'))
197  return 0;
198 
199  return 1;
200 }
201 
202 /**
203  * Return 1 if the tag of length len at the given offset is valid, 0 if not, -1 on error
204  */
205 static int check_tag(AVIOContext *s, int offset, unsigned int len)
206 {
207  char tag[4];
208 
209  if (len > 4 ||
210  avio_seek(s, offset, SEEK_SET) < 0 ||
211  avio_read(s, tag, len) < (int)len)
212  return -1;
213  else if (!AV_RB32(tag) || is_tag(tag, len))
214  return 1;
215 
216  return 0;
217 }
218 
219 /**
220  * Free GEOB type extra metadata.
221  */
222 static void free_geobtag(void *obj)
223 {
224  ID3v2ExtraMetaGEOB *geob = obj;
225  av_freep(&geob->mime_type);
226  av_freep(&geob->file_name);
227  av_freep(&geob->description);
228  av_freep(&geob->data);
229 }
230 
231 /**
232  * Decode characters to UTF-8 according to encoding type. The decoded buffer is
233  * always null terminated. Stop reading when either *maxread bytes are read from
234  * pb or U+0000 character is found.
235  *
236  * @param dst Pointer where the address of the buffer with the decoded bytes is
237  * stored. Buffer must be freed by caller.
238  * @param maxread Pointer to maximum number of characters to read from the
239  * AVIOContext. After execution the value is decremented by the number of bytes
240  * actually read.
241  * @returns 0 if no error occurred, dst is uninitialized on error
242  */
243 static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding,
244  uint8_t **dst, int *maxread)
245 {
246  int ret;
247  uint8_t tmp;
248  uint32_t ch = 1;
249  int left = *maxread;
250  unsigned int (*get)(AVIOContext*) = avio_rb16;
251  AVIOContext *dynbuf;
252 
253  if ((ret = avio_open_dyn_buf(&dynbuf)) < 0) {
254  av_log(s, AV_LOG_ERROR, "Error opening memory stream\n");
255  return ret;
256  }
257 
258  switch (encoding) {
260  while (left && ch) {
261  ch = avio_r8(pb);
262  PUT_UTF8(ch, tmp, avio_w8(dynbuf, tmp);)
263  left--;
264  }
265  break;
266 
268  if ((left -= 2) < 0) {
269  av_log(s, AV_LOG_ERROR, "Cannot read BOM value, input too short\n");
270  ffio_free_dyn_buf(&dynbuf);
271  *dst = NULL;
272  return AVERROR_INVALIDDATA;
273  }
274  switch (avio_rb16(pb)) {
275  case 0xfffe:
276  get = avio_rl16;
277  case 0xfeff:
278  break;
279  default:
280  av_log(s, AV_LOG_ERROR, "Incorrect BOM value\n");
281  ffio_free_dyn_buf(&dynbuf);
282  *dst = NULL;
283  *maxread = left;
284  return AVERROR_INVALIDDATA;
285  }
286  // fall-through
287 
289  while ((left > 1) && ch) {
290  GET_UTF16(ch, ((left -= 2) >= 0 ? get(pb) : 0), break;)
291  PUT_UTF8(ch, tmp, avio_w8(dynbuf, tmp);)
292  }
293  if (left < 0)
294  left += 2; /* did not read last char from pb */
295  break;
296 
297  case ID3v2_ENCODING_UTF8:
298  while (left && ch) {
299  ch = avio_r8(pb);
300  avio_w8(dynbuf, ch);
301  left--;
302  }
303  break;
304  default:
305  av_log(s, AV_LOG_WARNING, "Unknown encoding\n");
306  }
307 
308  if (ch)
309  avio_w8(dynbuf, 0);
310 
311  avio_close_dyn_buf(dynbuf, dst);
312  *maxread = left;
313 
314  return 0;
315 }
316 
317 /**
318  * Parse a text tag.
319  */
320 static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen,
321  AVDictionary **metadata, const char *key)
322 {
323  uint8_t *dst;
324  int encoding, dict_flags = AV_DICT_DONT_OVERWRITE | AV_DICT_DONT_STRDUP_VAL;
325  unsigned genre;
326 
327  if (taglen < 1)
328  return;
329 
330  encoding = avio_r8(pb);
331  taglen--; /* account for encoding type byte */
332 
333  if (decode_str(s, pb, encoding, &dst, &taglen) < 0) {
334  av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", key);
335  return;
336  }
337 
338  if (!(strcmp(key, "TCON") && strcmp(key, "TCO")) &&
339  (sscanf(dst, "(%d)", &genre) == 1 || sscanf(dst, "%d", &genre) == 1) &&
340  genre <= ID3v1_GENRE_MAX) {
341  av_freep(&dst);
342  dst = av_strdup(ff_id3v1_genre_str[genre]);
343  } else if (!(strcmp(key, "TXXX") && strcmp(key, "TXX"))) {
344  /* dst now contains the key, need to get value */
345  key = dst;
346  if (decode_str(s, pb, encoding, &dst, &taglen) < 0) {
347  av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", key);
348  av_freep(&key);
349  return;
350  }
351  dict_flags |= AV_DICT_DONT_STRDUP_KEY;
352  } else if (!*dst)
353  av_freep(&dst);
354 
355  if (dst)
356  av_dict_set(metadata, key, dst, dict_flags);
357 }
358 
359 static void read_uslt(AVFormatContext *s, AVIOContext *pb, int taglen,
360  AVDictionary **metadata)
361 {
362  uint8_t lang[4];
363  uint8_t *descriptor = NULL; // 'Content descriptor'
364  uint8_t *text;
365  char *key;
366  int encoding;
367  int ok = 0;
368 
369  if (taglen < 1)
370  goto error;
371 
372  encoding = avio_r8(pb);
373  taglen--;
374 
375  if (avio_read(pb, lang, 3) < 3)
376  goto error;
377  lang[3] = '\0';
378  taglen -= 3;
379 
380  if (decode_str(s, pb, encoding, &descriptor, &taglen) < 0)
381  goto error;
382 
383  if (decode_str(s, pb, encoding, &text, &taglen) < 0)
384  goto error;
385 
386  // FFmpeg does not support hierarchical metadata, so concatenate the keys.
387  key = av_asprintf("lyrics-%s%s%s", descriptor[0] ? (char *)descriptor : "",
388  descriptor[0] ? "-" : "",
389  lang);
390  if (!key) {
391  av_free(text);
392  goto error;
393  }
394 
395  av_dict_set(metadata, key, text,
397 
398  ok = 1;
399 error:
400  if (!ok)
401  av_log(s, AV_LOG_ERROR, "Error reading lyrics, skipped\n");
402  av_free(descriptor);
403 }
404 
405 /**
406  * Parse a comment tag.
407  */
408 static void read_comment(AVFormatContext *s, AVIOContext *pb, int taglen,
409  AVDictionary **metadata)
410 {
411  const char *key = "comment";
412  uint8_t *dst;
413  int encoding, dict_flags = AV_DICT_DONT_OVERWRITE | AV_DICT_DONT_STRDUP_VAL;
414  av_unused int language;
415 
416  if (taglen < 4)
417  return;
418 
419  encoding = avio_r8(pb);
420  language = avio_rl24(pb);
421  taglen -= 4;
422 
423  if (decode_str(s, pb, encoding, &dst, &taglen) < 0) {
424  av_log(s, AV_LOG_ERROR, "Error reading comment frame, skipped\n");
425  return;
426  }
427 
428  if (dst && !*dst)
429  av_freep(&dst);
430 
431  if (dst) {
432  key = (const char *) dst;
433  dict_flags |= AV_DICT_DONT_STRDUP_KEY;
434  }
435 
436  if (decode_str(s, pb, encoding, &dst, &taglen) < 0) {
437  av_log(s, AV_LOG_ERROR, "Error reading comment frame, skipped\n");
438  if (dict_flags & AV_DICT_DONT_STRDUP_KEY)
439  av_freep((void*)&key);
440  return;
441  }
442 
443  if (dst)
444  av_dict_set(metadata, key, (const char *) dst, dict_flags);
445 }
446 
447 typedef struct ExtraMetaList {
449 } ExtraMetaList;
450 
452 {
453  if (list->tail)
454  list->tail->next = new_elem;
455  else
456  list->head = new_elem;
457  list->tail = new_elem;
458 }
459 
460 /**
461  * Parse GEOB tag into a ID3v2ExtraMetaGEOB struct.
462  */
463 static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen,
464  const char *tag, ExtraMetaList *extra_meta, int isv34)
465 {
466  ID3v2ExtraMetaGEOB *geob_data = NULL;
467  ID3v2ExtraMeta *new_extra = NULL;
468  char encoding;
469  unsigned int len;
470 
471  if (taglen < 1)
472  return;
473 
474  new_extra = av_mallocz(sizeof(ID3v2ExtraMeta));
475  if (!new_extra) {
476  av_log(s, AV_LOG_ERROR, "Failed to alloc %"SIZE_SPECIFIER" bytes\n",
477  sizeof(ID3v2ExtraMeta));
478  return;
479  }
480 
481  geob_data = &new_extra->data.geob;
482 
483  /* read encoding type byte */
484  encoding = avio_r8(pb);
485  taglen--;
486 
487  /* read MIME type (always ISO-8859) */
488  if (decode_str(s, pb, ID3v2_ENCODING_ISO8859, &geob_data->mime_type,
489  &taglen) < 0 ||
490  taglen <= 0)
491  goto fail;
492 
493  /* read file name */
494  if (decode_str(s, pb, encoding, &geob_data->file_name, &taglen) < 0 ||
495  taglen <= 0)
496  goto fail;
497 
498  /* read content description */
499  if (decode_str(s, pb, encoding, &geob_data->description, &taglen) < 0 ||
500  taglen < 0)
501  goto fail;
502 
503  if (taglen) {
504  /* save encapsulated binary data */
505  geob_data->data = av_malloc(taglen);
506  if (!geob_data->data) {
507  av_log(s, AV_LOG_ERROR, "Failed to alloc %d bytes\n", taglen);
508  goto fail;
509  }
510  if ((len = avio_read(pb, geob_data->data, taglen)) < taglen)
512  "Error reading GEOB frame, data truncated.\n");
513  geob_data->datasize = len;
514  } else {
515  geob_data->data = NULL;
516  geob_data->datasize = 0;
517  }
518 
519  /* add data to the list */
520  new_extra->tag = "GEOB";
521  list_append(new_extra, extra_meta);
522 
523  return;
524 
525 fail:
526  av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", tag);
527  free_geobtag(geob_data);
528  av_free(new_extra);
529  return;
530 }
531 
532 static int is_number(const char *str)
533 {
534  while (*str >= '0' && *str <= '9')
535  str++;
536  return !*str;
537 }
538 
540 {
542  if ((t = av_dict_get(m, tag, NULL, AV_DICT_MATCH_CASE)) &&
543  strlen(t->value) == 4 && is_number(t->value))
544  return t;
545  return NULL;
546 }
547 
548 static void merge_date(AVDictionary **m)
549 {
551  char date[17] = { 0 }; // YYYY-MM-DD hh:mm
552 
553  if (!(t = get_date_tag(*m, "TYER")) &&
554  !(t = get_date_tag(*m, "TYE")))
555  return;
556  av_strlcpy(date, t->value, 5);
557  av_dict_set(m, "TYER", NULL, 0);
558  av_dict_set(m, "TYE", NULL, 0);
559 
560  if (!(t = get_date_tag(*m, "TDAT")) &&
561  !(t = get_date_tag(*m, "TDA")))
562  goto finish;
563  snprintf(date + 4, sizeof(date) - 4, "-%.2s-%.2s", t->value + 2, t->value);
564  av_dict_set(m, "TDAT", NULL, 0);
565  av_dict_set(m, "TDA", NULL, 0);
566 
567  if (!(t = get_date_tag(*m, "TIME")) &&
568  !(t = get_date_tag(*m, "TIM")))
569  goto finish;
570  snprintf(date + 10, sizeof(date) - 10,
571  " %.2s:%.2s", t->value, t->value + 2);
572  av_dict_set(m, "TIME", NULL, 0);
573  av_dict_set(m, "TIM", NULL, 0);
574 
575 finish:
576  if (date[0])
577  av_dict_set(m, "date", date, 0);
578 }
579 
580 static void free_apic(void *obj)
581 {
582  ID3v2ExtraMetaAPIC *apic = obj;
583  av_buffer_unref(&apic->buf);
584  av_freep(&apic->description);
585 }
586 
587 static void rstrip_spaces(char *buf)
588 {
589  size_t len = strlen(buf);
590  while (len > 0 && buf[len - 1] == ' ')
591  buf[--len] = 0;
592 }
593 
594 static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen,
595  const char *tag, ExtraMetaList *extra_meta, int isv34)
596 {
597  int enc, pic_type;
598  char mimetype[64] = {0};
599  const CodecMime *mime = ff_id3v2_mime_tags;
600  enum AVCodecID id = AV_CODEC_ID_NONE;
601  ID3v2ExtraMetaAPIC *apic = NULL;
602  ID3v2ExtraMeta *new_extra = NULL;
603  int64_t end = avio_tell(pb) + taglen;
604 
605  if (taglen <= 4 || (!isv34 && taglen <= 6))
606  goto fail;
607 
608  new_extra = av_mallocz(sizeof(*new_extra));
609  if (!new_extra)
610  goto fail;
611 
612  apic = &new_extra->data.apic;
613 
614  enc = avio_r8(pb);
615  taglen--;
616 
617  /* mimetype */
618  if (isv34) {
619  int ret = avio_get_str(pb, taglen, mimetype, sizeof(mimetype));
620  if (ret < 0 || ret >= taglen)
621  goto fail;
622  taglen -= ret;
623  } else {
624  if (avio_read(pb, mimetype, 3) < 0)
625  goto fail;
626 
627  mimetype[3] = 0;
628  taglen -= 3;
629  }
630 
631  while (mime->id != AV_CODEC_ID_NONE) {
632  if (!av_strncasecmp(mime->str, mimetype, sizeof(mimetype))) {
633  id = mime->id;
634  break;
635  }
636  mime++;
637  }
638  if (id == AV_CODEC_ID_NONE) {
640  "Unknown attached picture mimetype: %s, skipping.\n", mimetype);
641  goto fail;
642  }
643  apic->id = id;
644 
645  /* picture type */
646  pic_type = avio_r8(pb);
647  taglen--;
648  if (pic_type < 0 || pic_type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types)) {
649  av_log(s, AV_LOG_WARNING, "Unknown attached picture type %d.\n",
650  pic_type);
651  pic_type = 0;
652  }
653  apic->type = ff_id3v2_picture_types[pic_type];
654 
655  /* description and picture data */
656  if (decode_str(s, pb, enc, &apic->description, &taglen) < 0) {
658  "Error decoding attached picture description.\n");
659  goto fail;
660  }
661 
663  if (!apic->buf || !taglen || avio_read(pb, apic->buf->data, taglen) != taglen)
664  goto fail;
665  memset(apic->buf->data + taglen, 0, AV_INPUT_BUFFER_PADDING_SIZE);
666 
667  new_extra->tag = "APIC";
668 
669  // The description must be unique, and some ID3v2 tag writers add spaces
670  // to write several APIC entries with the same description.
671  rstrip_spaces(apic->description);
672  list_append(new_extra, extra_meta);
673 
674  return;
675 
676 fail:
677  if (apic)
678  free_apic(apic);
679  av_freep(&new_extra);
680  avio_seek(pb, end, SEEK_SET);
681 }
682 
683 static void free_chapter(void *obj)
684 {
685  ID3v2ExtraMetaCHAP *chap = obj;
686  av_freep(&chap->element_id);
687  av_dict_free(&chap->meta);
688 }
689 
691  const char *ttag, ExtraMetaList *extra_meta, int isv34)
692 {
693  int taglen;
694  char tag[5];
695  ID3v2ExtraMeta *new_extra = NULL;
696  ID3v2ExtraMetaCHAP *chap = NULL;
697 
698  new_extra = av_mallocz(sizeof(*new_extra));
699  if (!new_extra)
700  return;
701 
702  chap = &new_extra->data.chap;
703 
704  if (decode_str(s, pb, 0, &chap->element_id, &len) < 0)
705  goto fail;
706 
707  if (len < 16)
708  goto fail;
709 
710  chap->start = avio_rb32(pb);
711  chap->end = avio_rb32(pb);
712  avio_skip(pb, 8);
713 
714  len -= 16;
715  while (len > 10) {
716  if (avio_read(pb, tag, 4) < 4)
717  goto fail;
718  tag[4] = 0;
719  taglen = avio_rb32(pb);
720  avio_skip(pb, 2);
721  len -= 10;
722  if (taglen < 0 || taglen > len)
723  goto fail;
724  if (tag[0] == 'T')
725  read_ttag(s, pb, taglen, &chap->meta, tag);
726  else
727  avio_skip(pb, taglen);
728  len -= taglen;
729  }
730 
733 
734  new_extra->tag = "CHAP";
735  list_append(new_extra, extra_meta);
736 
737  return;
738 
739 fail:
740  free_chapter(chap);
741  av_freep(&new_extra);
742 }
743 
744 static void free_priv(void *obj)
745 {
746  ID3v2ExtraMetaPRIV *priv = obj;
747  av_freep(&priv->owner);
748  av_freep(&priv->data);
749 }
750 
751 static void read_priv(AVFormatContext *s, AVIOContext *pb, int taglen,
752  const char *tag, ExtraMetaList *extra_meta, int isv34)
753 {
754  ID3v2ExtraMeta *meta;
755  ID3v2ExtraMetaPRIV *priv;
756 
757  meta = av_mallocz(sizeof(*meta));
758  if (!meta)
759  return;
760 
761  priv = &meta->data.priv;
762 
763  if (decode_str(s, pb, ID3v2_ENCODING_ISO8859, &priv->owner, &taglen) < 0)
764  goto fail;
765 
766  priv->data = av_malloc(taglen);
767  if (!priv->data)
768  goto fail;
769 
770  priv->datasize = taglen;
771 
772  if (avio_read(pb, priv->data, priv->datasize) != priv->datasize)
773  goto fail;
774 
775  meta->tag = "PRIV";
776  list_append(meta, extra_meta);
777 
778  return;
779 
780 fail:
781  free_priv(priv);
782  av_freep(&meta);
783 }
784 
785 typedef struct ID3v2EMFunc {
786  const char *tag3;
787  const char *tag4;
788  void (*read)(AVFormatContext *s, AVIOContext *pb, int taglen,
789  const char *tag, ExtraMetaList *extra_meta,
790  int isv34);
791  void (*free)(void *obj);
792 } ID3v2EMFunc;
793 
795  { "GEO", "GEOB", read_geobtag, free_geobtag },
796  { "PIC", "APIC", read_apic, free_apic },
797  { "CHAP","CHAP", read_chapter, free_chapter },
798  { "PRIV","PRIV", read_priv, free_priv },
799  { NULL }
800 };
801 
802 /**
803  * Get the corresponding ID3v2EMFunc struct for a tag.
804  * @param isv34 Determines if v2.2 or v2.3/4 strings are used
805  * @return A pointer to the ID3v2EMFunc struct if found, NULL otherwise.
806  */
807 static const ID3v2EMFunc *get_extra_meta_func(const char *tag, int isv34)
808 {
809  int i = 0;
810  while (id3v2_extra_meta_funcs[i].tag3) {
811  if (tag && !memcmp(tag,
812  (isv34 ? id3v2_extra_meta_funcs[i].tag4 :
813  id3v2_extra_meta_funcs[i].tag3),
814  (isv34 ? 4 : 3)))
815  return &id3v2_extra_meta_funcs[i];
816  i++;
817  }
818  return NULL;
819 }
820 
821 static void id3v2_parse(AVIOContext *pb, AVDictionary **metadata,
822  AVFormatContext *s, int len, uint8_t version,
823  uint8_t flags, ExtraMetaList *extra_meta)
824 {
825  int isv34, unsync;
826  unsigned tlen;
827  char tag[5];
828  int64_t next, end = avio_tell(pb);
829  int taghdrlen;
830  const char *reason = NULL;
831  FFIOContext pb_local;
832  AVIOContext *pbx;
833  unsigned char *buffer = NULL;
834  int buffer_size = 0;
835  const ID3v2EMFunc *extra_func = NULL;
836  unsigned char *uncompressed_buffer = NULL;
837  av_unused int uncompressed_buffer_size = 0;
838  const char *comm_frame;
839 
840  if (end > INT64_MAX - len - 10)
841  return;
842  end += len;
843 
844  av_log(s, AV_LOG_DEBUG, "id3v2 ver:%d flags:%02X len:%d\n", version, flags, len);
845 
846  switch (version) {
847  case 2:
848  if (flags & 0x40) {
849  reason = "compression";
850  goto error;
851  }
852  isv34 = 0;
853  taghdrlen = 6;
854  comm_frame = "COM";
855  break;
856 
857  case 3:
858  case 4:
859  isv34 = 1;
860  taghdrlen = 10;
861  comm_frame = "COMM";
862  break;
863 
864  default:
865  reason = "version";
866  goto error;
867  }
868 
869  unsync = flags & 0x80;
870 
871  if (isv34 && flags & 0x40) { /* Extended header present, just skip over it */
872  int extlen = get_size(pb, 4);
873  if (version == 4)
874  /* In v2.4 the length includes the length field we just read. */
875  extlen -= 4;
876 
877  if (extlen < 0) {
878  reason = "invalid extended header length";
879  goto error;
880  }
881  avio_skip(pb, extlen);
882  len -= extlen + 4;
883  if (len < 0) {
884  reason = "extended header too long.";
885  goto error;
886  }
887  }
888 
889  while (len >= taghdrlen) {
890  unsigned int tflags = 0;
891  int tunsync = 0;
892  int tcomp = 0;
893  int tencr = 0;
894  unsigned long av_unused dlen;
895 
896  if (isv34) {
897  if (avio_read(pb, tag, 4) < 4)
898  break;
899  tag[4] = 0;
900  if (version == 3) {
901  tlen = avio_rb32(pb);
902  } else {
903  /* some encoders incorrectly uses v3 sizes instead of syncsafe ones
904  * so check the next tag to see which one to use */
905  tlen = avio_rb32(pb);
906  if (tlen > 0x7f) {
907  if (tlen < len) {
908  int64_t cur = avio_tell(pb);
909 
910  if (ffio_ensure_seekback(pb, 2 /* tflags */ + tlen + 4 /* next tag */))
911  break;
912 
913  if (check_tag(pb, cur + 2 + size_to_syncsafe(tlen), 4) == 1)
914  tlen = size_to_syncsafe(tlen);
915  else if (check_tag(pb, cur + 2 + tlen, 4) != 1)
916  break;
917  avio_seek(pb, cur, SEEK_SET);
918  } else
919  tlen = size_to_syncsafe(tlen);
920  }
921  }
922  tflags = avio_rb16(pb);
923  tunsync = tflags & ID3v2_FLAG_UNSYNCH;
924  } else {
925  if (avio_read(pb, tag, 3) < 3)
926  break;
927  tag[3] = 0;
928  tlen = avio_rb24(pb);
929  }
930  if (tlen > (1<<28))
931  break;
932  len -= taghdrlen + tlen;
933 
934  if (len < 0)
935  break;
936 
937  next = avio_tell(pb) + tlen;
938 
939  if (!tlen) {
940  if (tag[0])
941  av_log(s, AV_LOG_DEBUG, "Invalid empty frame %s, skipping.\n",
942  tag);
943  continue;
944  }
945 
946  if (tflags & ID3v2_FLAG_DATALEN) {
947  if (tlen < 4)
948  break;
949  dlen = avio_rb32(pb);
950  tlen -= 4;
951  } else
952  dlen = tlen;
953 
954  tcomp = tflags & ID3v2_FLAG_COMPRESSION;
955  tencr = tflags & ID3v2_FLAG_ENCRYPTION;
956 
957  /* skip encrypted tags and, if no zlib, compressed tags */
958  if (tencr || (!CONFIG_ZLIB && tcomp)) {
959  const char *type;
960  if (!tcomp)
961  type = "encrypted";
962  else if (!tencr)
963  type = "compressed";
964  else
965  type = "encrypted and compressed";
966 
967  av_log(s, AV_LOG_WARNING, "Skipping %s ID3v2 frame %s.\n", type, tag);
968  avio_skip(pb, tlen);
969  /* check for text tag or supported special meta tag */
970  } else if (tag[0] == 'T' ||
971  !memcmp(tag, "USLT", 4) ||
972  !strcmp(tag, comm_frame) ||
973  (extra_meta &&
974  (extra_func = get_extra_meta_func(tag, isv34)))) {
975  pbx = pb;
976 
977  if (unsync || tunsync || tcomp) {
978  av_fast_malloc(&buffer, &buffer_size, tlen);
979  if (!buffer) {
980  av_log(s, AV_LOG_ERROR, "Failed to alloc %d bytes\n", tlen);
981  goto seek;
982  }
983  }
984  if (unsync || tunsync) {
985  uint8_t *b = buffer;
986  uint8_t *t = buffer;
987  uint8_t *end = t + tlen;
988 
989  if (avio_read(pb, buffer, tlen) != tlen) {
990  av_log(s, AV_LOG_ERROR, "Failed to read tag data\n");
991  goto seek;
992  }
993 
994  while (t != end) {
995  *b++ = *t++;
996  if (t != end && t[-1] == 0xff && !t[0])
997  t++;
998  }
999 
1000  ffio_init_context(&pb_local, buffer, b - buffer, 0, NULL, NULL, NULL,
1001  NULL);
1002  tlen = b - buffer;
1003  pbx = &pb_local.pub; // read from sync buffer
1004  }
1005 
1006 #if CONFIG_ZLIB
1007  if (tcomp) {
1008  int err;
1009 
1010  av_log(s, AV_LOG_DEBUG, "Compresssed frame %s tlen=%d dlen=%ld\n", tag, tlen, dlen);
1011 
1012  if (tlen <= 0)
1013  goto seek;
1014  if (dlen / 32768 > tlen)
1015  goto seek;
1016 
1017  av_fast_malloc(&uncompressed_buffer, &uncompressed_buffer_size, dlen);
1018  if (!uncompressed_buffer) {
1019  av_log(s, AV_LOG_ERROR, "Failed to alloc %ld bytes\n", dlen);
1020  goto seek;
1021  }
1022 
1023  if (!(unsync || tunsync)) {
1024  err = avio_read(pb, buffer, tlen);
1025  if (err < 0) {
1026  av_log(s, AV_LOG_ERROR, "Failed to read compressed tag\n");
1027  goto seek;
1028  }
1029  tlen = err;
1030  }
1031 
1032  err = uncompress(uncompressed_buffer, &dlen, buffer, tlen);
1033  if (err != Z_OK) {
1034  av_log(s, AV_LOG_ERROR, "Failed to uncompress tag: %d\n", err);
1035  goto seek;
1036  }
1037  ffio_init_context(&pb_local, uncompressed_buffer, dlen, 0, NULL, NULL, NULL, NULL);
1038  tlen = dlen;
1039  pbx = &pb_local.pub; // read from sync buffer
1040  }
1041 #endif
1042  if (tag[0] == 'T')
1043  /* parse text tag */
1044  read_ttag(s, pbx, tlen, metadata, tag);
1045  else if (!memcmp(tag, "USLT", 4))
1046  read_uslt(s, pbx, tlen, metadata);
1047  else if (!strcmp(tag, comm_frame))
1048  read_comment(s, pbx, tlen, metadata);
1049  else
1050  /* parse special meta tag */
1051  extra_func->read(s, pbx, tlen, tag, extra_meta, isv34);
1052  } else if (!tag[0]) {
1053  if (tag[1])
1054  av_log(s, AV_LOG_WARNING, "invalid frame id, assuming padding\n");
1055  avio_skip(pb, tlen);
1056  break;
1057  }
1058  /* Skip to end of tag */
1059 seek:
1060  avio_seek(pb, next, SEEK_SET);
1061  }
1062 
1063  /* Footer preset, always 10 bytes, skip over it */
1064  if (version == 4 && flags & 0x10)
1065  end += 10;
1066 
1067 error:
1068  if (reason)
1069  av_log(s, AV_LOG_INFO, "ID3v2.%d tag skipped, cannot handle %s\n",
1070  version, reason);
1071  avio_seek(pb, end, SEEK_SET);
1072  av_free(buffer);
1073  av_free(uncompressed_buffer);
1074  return;
1075 }
1076 
1077 static void id3v2_read_internal(AVIOContext *pb, AVDictionary **metadata,
1078  AVFormatContext *s, const char *magic,
1079  ID3v2ExtraMeta **extra_metap, int64_t max_search_size)
1080 {
1081  int len, ret;
1082  uint8_t buf[ID3v2_HEADER_SIZE];
1083  ExtraMetaList extra_meta = { NULL };
1084  int found_header;
1085  int64_t start, off;
1086 
1087  if (extra_metap)
1088  *extra_metap = NULL;
1089 
1090  if (max_search_size && max_search_size < ID3v2_HEADER_SIZE)
1091  return;
1092 
1093  start = avio_tell(pb);
1094  do {
1095  /* save the current offset in case there's nothing to read/skip */
1096  off = avio_tell(pb);
1097  if (max_search_size && off - start >= max_search_size - ID3v2_HEADER_SIZE) {
1098  avio_seek(pb, off, SEEK_SET);
1099  break;
1100  }
1101 
1103  if (ret >= 0)
1104  ret = avio_read(pb, buf, ID3v2_HEADER_SIZE);
1105  if (ret != ID3v2_HEADER_SIZE) {
1106  avio_seek(pb, off, SEEK_SET);
1107  break;
1108  }
1109  found_header = ff_id3v2_match(buf, magic);
1110  if (found_header) {
1111  /* parse ID3v2 header */
1112  len = ((buf[6] & 0x7f) << 21) |
1113  ((buf[7] & 0x7f) << 14) |
1114  ((buf[8] & 0x7f) << 7) |
1115  (buf[9] & 0x7f);
1116  id3v2_parse(pb, metadata, s, len, buf[3], buf[5],
1117  extra_metap ? &extra_meta : NULL);
1118  } else {
1119  avio_seek(pb, off, SEEK_SET);
1120  }
1121  } while (found_header);
1125  merge_date(metadata);
1126  if (extra_metap)
1127  *extra_metap = extra_meta.head;
1128 }
1129 
1131  const char *magic, ID3v2ExtraMeta **extra_meta)
1132 {
1133  id3v2_read_internal(pb, metadata, NULL, magic, extra_meta, 0);
1134 }
1135 
1136 void ff_id3v2_read(AVFormatContext *s, const char *magic,
1137  ID3v2ExtraMeta **extra_meta, unsigned int max_search_size)
1138 {
1139  id3v2_read_internal(s->pb, &s->metadata, s, magic, extra_meta, max_search_size);
1140 }
1141 
1143 {
1144  ID3v2ExtraMeta *current = *extra_meta, *next;
1145  const ID3v2EMFunc *extra_func;
1146 
1147  while (current) {
1148  if ((extra_func = get_extra_meta_func(current->tag, 1)))
1149  extra_func->free(&current->data);
1150  next = current->next;
1151  av_freep(&current);
1152  current = next;
1153  }
1154 
1155  *extra_meta = NULL;
1156 }
1157 
1159 {
1160  ID3v2ExtraMeta *cur;
1161 
1162  for (cur = extra_meta; cur; cur = cur->next) {
1163  ID3v2ExtraMetaAPIC *apic;
1164  AVStream *st;
1165  int ret;
1166 
1167  if (strcmp(cur->tag, "APIC"))
1168  continue;
1169  apic = &cur->data.apic;
1170 
1171  ret = ff_add_attached_pic(s, NULL, NULL, &apic->buf, 0);
1172  if (ret < 0)
1173  return ret;
1174  st = s->streams[s->nb_streams - 1];
1175  st->codecpar->codec_id = apic->id;
1176 
1177  if (AV_RB64(st->attached_pic.data) == PNGSIG)
1179 
1180  if (apic->description[0])
1181  av_dict_set(&st->metadata, "title", apic->description, 0);
1182 
1183  av_dict_set(&st->metadata, "comment", apic->type, 0);
1184  }
1185 
1186  return 0;
1187 }
1188 
1190 {
1191  AVRational time_base = {1, 1000};
1192  int ret;
1193 
1194  for (unsigned i = 0; cur; cur = cur->next) {
1195  ID3v2ExtraMetaCHAP *chap;
1196  AVChapter *chapter;
1197 
1198  if (strcmp(cur->tag, "CHAP"))
1199  continue;
1200 
1201  chap = &cur->data.chap;
1202  chapter = avpriv_new_chapter(s, i++, time_base, chap->start,
1203  chap->end, chap->element_id);
1204  if (!chapter)
1205  continue;
1206 
1207  if ((ret = av_dict_copy(&chapter->metadata, chap->meta, 0)) < 0)
1208  return ret;
1209  }
1210 
1211  return 0;
1212 }
1213 
1215 {
1216  ID3v2ExtraMeta *cur;
1218 
1219  for (cur = extra_meta; cur; cur = cur->next) {
1220  if (!strcmp(cur->tag, "PRIV")) {
1221  ID3v2ExtraMetaPRIV *priv = &cur->data.priv;
1222  AVBPrint bprint;
1223  char *escaped, *key;
1224  int i, ret;
1225 
1226  if ((key = av_asprintf(ID3v2_PRIV_METADATA_PREFIX "%s", priv->owner)) == NULL) {
1227  return AVERROR(ENOMEM);
1228  }
1229 
1230  av_bprint_init(&bprint, priv->datasize + 1, AV_BPRINT_SIZE_UNLIMITED);
1231 
1232  for (i = 0; i < priv->datasize; i++) {
1233  if (priv->data[i] < 32 || priv->data[i] > 126 || priv->data[i] == '\\') {
1234  av_bprintf(&bprint, "\\x%02x", priv->data[i]);
1235  } else {
1236  av_bprint_chars(&bprint, priv->data[i], 1);
1237  }
1238  }
1239 
1240  if ((ret = av_bprint_finalize(&bprint, &escaped)) < 0) {
1241  av_free(key);
1242  return ret;
1243  }
1244 
1245  if ((ret = av_dict_set(metadata, key, escaped, dict_flags)) < 0) {
1246  return ret;
1247  }
1248  }
1249  }
1250 
1251  return 0;
1252 }
1253 
1255 {
1256  return ff_id3v2_parse_priv_dict(&s->metadata, extra_meta);
1257 }
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:31
avpriv_new_chapter
AVChapter * avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base, int64_t start, int64_t end, const char *title)
Add a new chapter.
Definition: demux_utils.c:42
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
PUT_UTF8
#define PUT_UTF8(val, tmp, PUT_BYTE)
Definition: common.h:522
ID3v2ExtraMeta::geob
ID3v2ExtraMetaGEOB geob
Definition: id3v2.h:90
AVChapter::metadata
AVDictionary * metadata
Definition: avformat.h:1176
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
ID3v2ExtraMeta::next
struct ID3v2ExtraMeta * next
Definition: id3v2.h:86
free_chapter
static void free_chapter(void *obj)
Definition: id3v2.c:683
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
rstrip_spaces
static void rstrip_spaces(char *buf)
Definition: id3v2.c:587
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
free_geobtag
static void free_geobtag(void *obj)
Free GEOB type extra metadata.
Definition: id3v2.c:222
size_to_syncsafe
static unsigned int size_to_syncsafe(unsigned int size)
Definition: id3v2.c:177
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
av_asprintf
char * av_asprintf(const char *fmt,...)
Definition: avstring.c:116
ff_id3v2_4_tags
const char ff_id3v2_4_tags[][4]
ID3v2.4-only text information frames.
Definition: id3v2.c:97
av_unused
#define av_unused
Definition: attributes.h:131
id3v2.h
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
list_append
static void list_append(ID3v2ExtraMeta *new_elem, ExtraMetaList *list)
Definition: id3v2.c:451
ID3v1_GENRE_MAX
#define ID3v1_GENRE_MAX
Definition: id3v1.h:29
AVPacket::data
uint8_t * data
Definition: packet.h:374
b
#define b
Definition: input.c:34
ff_id3v2_read
void ff_id3v2_read(AVFormatContext *s, const char *magic, ID3v2ExtraMeta **extra_meta, unsigned int max_search_size)
Read an ID3v2 tag, including supported extra metadata.
Definition: id3v2.c:1136
AVMetadataConv
Definition: metadata.h:34
read_apic
static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, const char *tag, ExtraMetaList *extra_meta, int isv34)
Definition: id3v2.c:594
ID3v2ExtraMetaAPIC::id
enum AVCodecID id
Definition: id3v2.h:69
read_ttag
static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen, AVDictionary **metadata, const char *key)
Parse a text tag.
Definition: id3v2.c:320
AVDictionary
Definition: dict.c:30
ID3v2_FLAG_ENCRYPTION
#define ID3v2_FLAG_ENCRYPTION
Definition: id3v2.h:39
id3v1.h
FFIOContext
Definition: avio_internal.h:29
decode_str
static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding, uint8_t **dst, int *maxread)
Decode characters to UTF-8 according to encoding type.
Definition: id3v2.c:243
ID3v2ExtraMetaGEOB
Definition: id3v2.h:57
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
free_apic
static void free_apic(void *obj)
Definition: id3v2.c:580
ExtraMetaList
Definition: id3v2.c:447
CodecMime
Definition: internal.h:55
ID3v2EMFunc::tag3
const char * tag3
Definition: id3v2.c:786
finish
static void finish(void)
Definition: movenc.c:342
ExtraMetaList::tail
ID3v2ExtraMeta * tail
Definition: id3v2.c:448
fail
#define fail()
Definition: checkasm.h:131
check_tag
static int check_tag(AVIOContext *s, int offset, unsigned int len)
Return 1 if the tag of length len at the given offset is valid, 0 if not, -1 on error.
Definition: id3v2.c:205
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:505
AVChapter
Definition: avformat.h:1172
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
ID3v2ExtraMetaCHAP
Definition: id3v2.h:78
ID3v2ExtraMeta::apic
ID3v2ExtraMetaAPIC apic
Definition: id3v2.h:88
avio_rl16
unsigned int avio_rl16(AVIOContext *s)
Definition: aviobuf.c:743
AVStream::attached_pic
AVPacket attached_pic
For streams with AV_DISPOSITION_ATTACHED_PIC disposition, this packet will contain the attached pictu...
Definition: avformat.h:1037
ff_id3v2_parse_chapters
int ff_id3v2_parse_chapters(AVFormatContext *s, ID3v2ExtraMeta *cur)
Create chapters for all CHAP tags found in the ID3v2 header.
Definition: id3v2.c:1189
AV_DICT_DONT_STRDUP_VAL
#define AV_DICT_DONT_STRDUP_VAL
Take ownership of a value that's been allocated with av_malloc() or another memory allocation functio...
Definition: dict.h:72
ID3v2_PRIV_METADATA_PREFIX
#define ID3v2_PRIV_METADATA_PREFIX
Definition: id3v2.h:42
avio_close_dyn_buf
int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition: aviobuf.c:1528
get_date_tag
static AVDictionaryEntry * get_date_tag(AVDictionary *m, const char *tag)
Definition: id3v2.c:539
avio_rb32
unsigned int avio_rb32(AVIOContext *s)
Definition: aviobuf.c:790
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
read_chapter
static void read_chapter(AVFormatContext *s, AVIOContext *pb, int len, const char *ttag, ExtraMetaList *extra_meta, int isv34)
Definition: id3v2.c:690
ID3v2ExtraMeta
Definition: id3v2.h:84
ID3v2_ENCODING_UTF8
@ ID3v2_ENCODING_UTF8
Definition: id3v2.h:48
ID3v2ExtraMetaCHAP::element_id
uint8_t * element_id
Definition: id3v2.h:79
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:40
avio_open_dyn_buf
int avio_open_dyn_buf(AVIOContext **s)
Open a write only memory stream.
Definition: aviobuf.c:1483
ff_add_attached_pic
int ff_add_attached_pic(AVFormatContext *s, AVStream *st, AVIOContext *pb, AVBufferRef **buf, int size)
Add an attached pic to an AVStream.
Definition: demux_utils.c:116
read_comment
static void read_comment(AVFormatContext *s, AVIOContext *pb, int taglen, AVDictionary **metadata)
Parse a comment tag.
Definition: id3v2.c:408
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:256
AV_CODEC_ID_BMP
@ AV_CODEC_ID_BMP
Definition: codec_id.h:128
ID3v2_FLAG_UNSYNCH
#define ID3v2_FLAG_UNSYNCH
Definition: id3v2.h:38
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ID3v2ExtraMetaAPIC::buf
AVBufferRef * buf
Definition: id3v2.h:66
free_priv
static void free_priv(void *obj)
Definition: id3v2.c:744
key
const char * key
Definition: hwcontext_opencl.c:174
ID3v2_FLAG_DATALEN
#define ID3v2_FLAG_DATALEN
Definition: id3v2.h:37
ID3v2ExtraMetaGEOB::datasize
uint32_t datasize
Definition: id3v2.h:58
AV_CODEC_ID_PNG
@ AV_CODEC_ID_PNG
Definition: codec_id.h:111
ID3v2ExtraMeta::tag
const char * tag
Definition: id3v2.h:85
AVFormatContext
Format I/O context.
Definition: avformat.h:1213
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1108
id3v2_read_internal
static void id3v2_read_internal(AVIOContext *pb, AVDictionary **metadata, AVFormatContext *s, const char *magic, ID3v2ExtraMeta **extra_metap, int64_t max_search_size)
Definition: id3v2.c:1077
NULL
#define NULL
Definition: coverity.c:32
ID3v2EMFunc::free
void(* free)(void *obj)
Definition: id3v2.c:791
av_buffer_unref
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition: buffer.c:139
ID3v2ExtraMetaPRIV::data
uint8_t * data
Definition: id3v2.h:74
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
ID3v2ExtraMetaGEOB::mime_type
uint8_t * mime_type
Definition: id3v2.h:59
ff_id3v2_parse_apic
int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta *extra_meta)
Create a stream for each APIC (attached picture) extracted from the ID3v2 header.
Definition: id3v2.c:1158
ExtraMetaList::head
ID3v2ExtraMeta * head
Definition: id3v2.c:448
list
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 list
Definition: filter_design.txt:25
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:1019
AV_DICT_DONT_OVERWRITE
#define AV_DICT_DONT_OVERWRITE
Don't overwrite existing entries.
Definition: dict.h:74
avio_w8
void avio_w8(AVIOContext *s, int b)
Definition: aviobuf.c:210
get
static void get(const uint8_t *pixels, int stride, int16_t *block)
Definition: proresenc_anatoliy.c:308
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
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:47
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
av_strncasecmp
int av_strncasecmp(const char *a, const char *b, size_t n)
Locale-independent case-insensitive compare.
Definition: avstring.c:228
ID3v2ExtraMetaGEOB::file_name
uint8_t * file_name
Definition: id3v2.h:60
AVIOContext
Bytestream IO Context.
Definition: avio.h:162
avio_rb24
unsigned int avio_rb24(AVIOContext *s)
Definition: aviobuf.c:783
get_size
static unsigned int get_size(AVIOContext *s, int len)
Definition: id3v2.c:169
is_number
static int is_number(const char *str)
Definition: id3v2.c:532
ID3v2_ENCODING_UTF16BOM
@ ID3v2_ENCODING_UTF16BOM
Definition: id3v2.h:46
id
enum AVCodecID id
Definition: extract_extradata_bsf.c:324
ID3v2ExtraMetaCHAP::start
uint32_t start
Definition: id3v2.h:80
FFIOContext::pub
AVIOContext pub
Definition: avio_internal.h:30
is_tag
static int is_tag(const char *buf, unsigned int len)
Definition: id3v2.c:187
avio_get_str
int avio_get_str(AVIOContext *pb, int maxlen, char *buf, int buflen)
Read a string from pb into buf.
Definition: aviobuf.c:895
merge_date
static void merge_date(AVDictionary **m)
Definition: id3v2.c:548
size
int size
Definition: twinvq_data.h:10344
ID3v2ExtraMeta::data
union ID3v2ExtraMeta::@270 data
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
avio_r8
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:632
ffio_ensure_seekback
int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
Ensures that the requested seekback buffer size will be available.
Definition: aviobuf.c:1055
offset
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 offset
Definition: writing_filters.txt:86
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:203
av_buffer_alloc
AVBufferRef * av_buffer_alloc(size_t size)
Allocate an AVBuffer of the given size using av_malloc().
Definition: buffer.c:77
version
version
Definition: libkvazaar.c:313
ID3v2ExtraMetaAPIC
Definition: id3v2.h:65
ID3v2ExtraMeta::chap
ID3v2ExtraMetaCHAP chap
Definition: id3v2.h:89
PNGSIG
#define PNGSIG
Definition: png.h:49
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
AV_CODEC_ID_GIF
@ AV_CODEC_ID_GIF
Definition: codec_id.h:147
AV_CODEC_ID_MJPEG
@ AV_CODEC_ID_MJPEG
Definition: codec_id.h:57
bprint.h
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:48
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
avio_rl24
unsigned int avio_rl24(AVIOContext *s)
Definition: aviobuf.c:751
avio_internal.h
ffio_init_context
void ffio_init_context(FFIOContext *s, unsigned char *buffer, int buffer_size, int write_flag, void *opaque, int(*read_packet)(void *opaque, uint8_t *buf, int buf_size), int(*write_packet)(void *opaque, uint8_t *buf, int buf_size), int64_t(*seek)(void *opaque, int64_t offset, int whence))
Definition: aviobuf.c:81
ff_id3v2_read_dict
void ff_id3v2_read_dict(AVIOContext *pb, AVDictionary **metadata, const char *magic, ID3v2ExtraMeta **extra_meta)
Read an ID3v2 tag into specified dictionary and retrieve supported extra metadata.
Definition: id3v2.c:1130
ff_metadata_conv
void ff_metadata_conv(AVDictionary **pm, const AVMetadataConv *d_conv, const AVMetadataConv *s_conv)
Definition: metadata.c:26
ff_id3v1_genre_str
const char *const ff_id3v1_genre_str[ID3v1_GENRE_MAX+1]
ID3v1 genres.
Definition: id3v1.c:26
id3v2_parse
static void id3v2_parse(AVIOContext *pb, AVDictionary **metadata, AVFormatContext *s, int len, uint8_t version, uint8_t flags, ExtraMetaList *extra_meta)
Definition: id3v2.c:821
GET_UTF16
#define GET_UTF16(val, GET_16BIT, ERROR)
Convert a UTF-16 character (2 or 4 bytes) to its 32-bit UCS-4 encoded form.
Definition: common.h:494
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:264
demux.h
len
int len
Definition: vorbis_enc_data.h:426
ID3v2ExtraMetaPRIV::datasize
uint32_t datasize
Definition: id3v2.h:75
get_extra_meta_func
static const ID3v2EMFunc * get_extra_meta_func(const char *tag, int isv34)
Get the corresponding ID3v2EMFunc struct for a tag.
Definition: id3v2.c:807
ID3v2_ENCODING_UTF16BE
@ ID3v2_ENCODING_UTF16BE
Definition: id3v2.h:47
language
Undefined Behavior In the C language
Definition: undefined.txt:3
ff_id3v2_tag_len
int ff_id3v2_tag_len(const uint8_t *buf)
Get the length of an ID3v2 tag.
Definition: id3v2.c:157
tag
uint32_t tag
Definition: movenc.c:1646
ffio_free_dyn_buf
void ffio_free_dyn_buf(AVIOContext **s)
Free a dynamic buffer.
Definition: aviobuf.c:1556
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:948
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:260
avio_rb16
unsigned int avio_rb16(AVIOContext *s)
Definition: aviobuf.c:775
av_bprintf
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:94
dict.h
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
left
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
Definition: snow.txt:386
AV_DICT_MATCH_CASE
#define AV_DICT_MATCH_CASE
Only get an entry with exact-case key match.
Definition: dict.h:67
ID3v2ExtraMetaGEOB::description
uint8_t * description
Definition: id3v2.h:61
SIZE_SPECIFIER
#define SIZE_SPECIFIER
Definition: internal.h:195
ID3v2ExtraMetaAPIC::type
const char * type
Definition: id3v2.h:67
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
ff_id3v2_4_metadata_conv
const AVMetadataConv ff_id3v2_4_metadata_conv[]
Definition: id3v2.c:64
avio_read
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:641
ID3v2ExtraMetaGEOB::data
uint8_t * data
Definition: id3v2.h:62
avio_skip
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:347
read_geobtag
static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen, const char *tag, ExtraMetaList *extra_meta, int isv34)
Parse GEOB tag into a ID3v2ExtraMetaGEOB struct.
Definition: id3v2.c:463
CodecMime::str
char str[32]
Definition: internal.h:56
CodecMime::id
enum AVCodecID id
Definition: internal.h:57
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:280
ID3v2_FLAG_COMPRESSION
#define ID3v2_FLAG_COMPRESSION
Definition: id3v2.h:40
read_priv
static void read_priv(AVFormatContext *s, AVIOContext *pb, int taglen, const char *tag, ExtraMetaList *extra_meta, int isv34)
Definition: id3v2.c:751
ID3v2EMFunc
Definition: id3v2.c:785
id3v2_extra_meta_funcs
static const ID3v2EMFunc id3v2_extra_meta_funcs[]
Definition: id3v2.c:794
ID3v2ExtraMetaCHAP::end
uint32_t end
Definition: id3v2.h:80
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
AVDictionaryEntry
Definition: dict.h:79
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:61
png.h
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
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:70
av_fast_malloc
void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size)
Allocate a buffer, reusing the given one if large enough.
Definition: mem.c:565
av_dict_copy
int av_dict_copy(AVDictionary **dst, const AVDictionary *src, int flags)
Copy entries from one AVDictionary struct into another.
Definition: dict.c:217
ff_id3v2_free_extra_meta
void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta)
Free memory allocated parsing special (non-text) metadata.
Definition: id3v2.c:1142
convert_header.str
string str
Definition: convert_header.py:20
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
ID3v2EMFunc::read
void(* read)(AVFormatContext *s, AVIOContext *pb, int taglen, const char *tag, ExtraMetaList *extra_meta, int isv34)
Definition: id3v2.c:788
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:86
ff_id3v2_parse_priv
int ff_id3v2_parse_priv(AVFormatContext *s, ID3v2ExtraMeta *extra_meta)
Add metadata for all PRIV tags in the ID3v2 header.
Definition: id3v2.c:1254
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
id3v2_2_metadata_conv
static const AVMetadataConv id3v2_2_metadata_conv[]
Definition: id3v2.c:76
AV_CODEC_ID_TIFF
@ AV_CODEC_ID_TIFF
Definition: codec_id.h:146
AVDictionaryEntry::value
char * value
Definition: dict.h:81
avstring.h
ID3v2EMFunc::tag4
const char * tag4
Definition: id3v2.c:787
int
int
Definition: ffmpeg_filter.c:155
ff_id3v2_parse_priv_dict
int ff_id3v2_parse_priv_dict(AVDictionary **metadata, ID3v2ExtraMeta *extra_meta)
Parse PRIV tags into a dictionary.
Definition: id3v2.c:1214
snprintf
#define snprintf
Definition: snprintf.h:34
ID3v2ExtraMetaCHAP::meta
AVDictionary * meta
Definition: id3v2.h:81
ID3v2ExtraMetaPRIV
Definition: id3v2.h:72
av_bprint_chars
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.
Definition: bprint.c:140
AV_RB64
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_RB64
Definition: bytestream.h:95
ID3v2ExtraMetaPRIV::owner
uint8_t * owner
Definition: id3v2.h:73
AV_DICT_DONT_STRDUP_KEY
#define AV_DICT_DONT_STRDUP_KEY
Take ownership of a key that's been allocated with av_malloc() or another memory allocation function.
Definition: dict.h:70
ID3v2_ENCODING_ISO8859
@ ID3v2_ENCODING_ISO8859
Definition: id3v2.h:45
ff_id3v2_match
int ff_id3v2_match(const uint8_t *buf, const char *magic)
Detect ID3v2 Header.
Definition: id3v2.c:144
read_uslt
static void read_uslt(AVFormatContext *s, AVIOContext *pb, int taglen, AVDictionary **metadata)
Definition: id3v2.c:359
ID3v2ExtraMetaAPIC::description
uint8_t * description
Definition: id3v2.h:68
ID3v2ExtraMeta::priv
ID3v2ExtraMetaPRIV priv
Definition: id3v2.h:91