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