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 
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  av_free(geob);
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 = NULL;
365  char *key = NULL;
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  goto error;
392 
393  av_dict_set(metadata, key, text, 0);
394 
395  ok = 1;
396 error:
397  if (!ok)
398  av_log(s, AV_LOG_ERROR, "Error reading lyrics, skipped\n");
399  av_free(descriptor);
400  av_free(text);
401  av_free(key);
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 /**
447  * Parse GEOB tag into a ID3v2ExtraMetaGEOB struct.
448  */
449 static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen,
450  const char *tag, ID3v2ExtraMeta **extra_meta,
451  int isv34)
452 {
453  ID3v2ExtraMetaGEOB *geob_data = NULL;
454  ID3v2ExtraMeta *new_extra = NULL;
455  char encoding;
456  unsigned int len;
457 
458  if (taglen < 1)
459  return;
460 
461  geob_data = av_mallocz(sizeof(ID3v2ExtraMetaGEOB));
462  if (!geob_data) {
463  av_log(s, AV_LOG_ERROR, "Failed to alloc %"SIZE_SPECIFIER" bytes\n",
464  sizeof(ID3v2ExtraMetaGEOB));
465  return;
466  }
467 
468  new_extra = av_mallocz(sizeof(ID3v2ExtraMeta));
469  if (!new_extra) {
470  av_log(s, AV_LOG_ERROR, "Failed to alloc %"SIZE_SPECIFIER" bytes\n",
471  sizeof(ID3v2ExtraMeta));
472  goto fail;
473  }
474 
475  /* read encoding type byte */
476  encoding = avio_r8(pb);
477  taglen--;
478 
479  /* read MIME type (always ISO-8859) */
480  if (decode_str(s, pb, ID3v2_ENCODING_ISO8859, &geob_data->mime_type,
481  &taglen) < 0 ||
482  taglen <= 0)
483  goto fail;
484 
485  /* read file name */
486  if (decode_str(s, pb, encoding, &geob_data->file_name, &taglen) < 0 ||
487  taglen <= 0)
488  goto fail;
489 
490  /* read content description */
491  if (decode_str(s, pb, encoding, &geob_data->description, &taglen) < 0 ||
492  taglen < 0)
493  goto fail;
494 
495  if (taglen) {
496  /* save encapsulated binary data */
497  geob_data->data = av_malloc(taglen);
498  if (!geob_data->data) {
499  av_log(s, AV_LOG_ERROR, "Failed to alloc %d bytes\n", taglen);
500  goto fail;
501  }
502  if ((len = avio_read(pb, geob_data->data, taglen)) < taglen)
504  "Error reading GEOB frame, data truncated.\n");
505  geob_data->datasize = len;
506  } else {
507  geob_data->data = NULL;
508  geob_data->datasize = 0;
509  }
510 
511  /* add data to the list */
512  new_extra->tag = "GEOB";
513  new_extra->data = geob_data;
514  new_extra->next = *extra_meta;
515  *extra_meta = new_extra;
516 
517  return;
518 
519 fail:
520  av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", tag);
521  free_geobtag(geob_data);
522  av_free(new_extra);
523  return;
524 }
525 
526 static int is_number(const char *str)
527 {
528  while (*str >= '0' && *str <= '9')
529  str++;
530  return !*str;
531 }
532 
534 {
536  if ((t = av_dict_get(m, tag, NULL, AV_DICT_MATCH_CASE)) &&
537  strlen(t->value) == 4 && is_number(t->value))
538  return t;
539  return NULL;
540 }
541 
542 static void merge_date(AVDictionary **m)
543 {
545  char date[17] = { 0 }; // YYYY-MM-DD hh:mm
546 
547  if (!(t = get_date_tag(*m, "TYER")) &&
548  !(t = get_date_tag(*m, "TYE")))
549  return;
550  av_strlcpy(date, t->value, 5);
551  av_dict_set(m, "TYER", NULL, 0);
552  av_dict_set(m, "TYE", NULL, 0);
553 
554  if (!(t = get_date_tag(*m, "TDAT")) &&
555  !(t = get_date_tag(*m, "TDA")))
556  goto finish;
557  snprintf(date + 4, sizeof(date) - 4, "-%.2s-%.2s", t->value + 2, t->value);
558  av_dict_set(m, "TDAT", NULL, 0);
559  av_dict_set(m, "TDA", NULL, 0);
560 
561  if (!(t = get_date_tag(*m, "TIME")) &&
562  !(t = get_date_tag(*m, "TIM")))
563  goto finish;
564  snprintf(date + 10, sizeof(date) - 10,
565  " %.2s:%.2s", t->value, t->value + 2);
566  av_dict_set(m, "TIME", NULL, 0);
567  av_dict_set(m, "TIM", NULL, 0);
568 
569 finish:
570  if (date[0])
571  av_dict_set(m, "date", date, 0);
572 }
573 
574 static void free_apic(void *obj)
575 {
576  ID3v2ExtraMetaAPIC *apic = obj;
577  av_buffer_unref(&apic->buf);
578  av_freep(&apic->description);
579  av_freep(&apic);
580 }
581 
582 static void rstrip_spaces(char *buf)
583 {
584  size_t len = strlen(buf);
585  while (len > 0 && buf[len - 1] == ' ')
586  buf[--len] = 0;
587 }
588 
589 static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen,
590  const char *tag, ID3v2ExtraMeta **extra_meta,
591  int isv34)
592 {
593  int enc, pic_type;
594  char mimetype[64] = {0};
595  const CodecMime *mime = ff_id3v2_mime_tags;
596  enum AVCodecID id = AV_CODEC_ID_NONE;
597  ID3v2ExtraMetaAPIC *apic = NULL;
598  ID3v2ExtraMeta *new_extra = NULL;
599  int64_t end = avio_tell(pb) + taglen;
600 
601  if (taglen <= 4 || (!isv34 && taglen <= 6))
602  goto fail;
603 
604  new_extra = av_mallocz(sizeof(*new_extra));
605  apic = av_mallocz(sizeof(*apic));
606  if (!new_extra || !apic)
607  goto fail;
608 
609  enc = avio_r8(pb);
610  taglen--;
611 
612  /* mimetype */
613  if (isv34) {
614  int ret = avio_get_str(pb, taglen, mimetype, sizeof(mimetype));
615  if (ret < 0 || ret >= taglen)
616  goto fail;
617  taglen -= ret;
618  } else {
619  if (avio_read(pb, mimetype, 3) < 0)
620  goto fail;
621 
622  mimetype[3] = 0;
623  taglen -= 3;
624  }
625 
626  while (mime->id != AV_CODEC_ID_NONE) {
627  if (!av_strncasecmp(mime->str, mimetype, sizeof(mimetype))) {
628  id = mime->id;
629  break;
630  }
631  mime++;
632  }
633  if (id == AV_CODEC_ID_NONE) {
635  "Unknown attached picture mimetype: %s, skipping.\n", mimetype);
636  goto fail;
637  }
638  apic->id = id;
639 
640  /* picture type */
641  pic_type = avio_r8(pb);
642  taglen--;
643  if (pic_type < 0 || pic_type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types)) {
644  av_log(s, AV_LOG_WARNING, "Unknown attached picture type %d.\n",
645  pic_type);
646  pic_type = 0;
647  }
648  apic->type = ff_id3v2_picture_types[pic_type];
649 
650  /* description and picture data */
651  if (decode_str(s, pb, enc, &apic->description, &taglen) < 0) {
653  "Error decoding attached picture description.\n");
654  goto fail;
655  }
656 
658  if (!apic->buf || !taglen || avio_read(pb, apic->buf->data, taglen) != taglen)
659  goto fail;
660  memset(apic->buf->data + taglen, 0, AV_INPUT_BUFFER_PADDING_SIZE);
661 
662  new_extra->tag = "APIC";
663  new_extra->data = apic;
664  new_extra->next = *extra_meta;
665  *extra_meta = new_extra;
666 
667  // The description must be unique, and some ID3v2 tag writers add spaces
668  // to write several APIC entries with the same description.
669  rstrip_spaces(apic->description);
670 
671  return;
672 
673 fail:
674  if (apic)
675  free_apic(apic);
676  av_freep(&new_extra);
677  avio_seek(pb, end, SEEK_SET);
678 }
679 
680 static void free_chapter(void *obj)
681 {
682  ID3v2ExtraMetaCHAP *chap = obj;
683  av_freep(&chap->element_id);
684  av_dict_free(&chap->meta);
685  av_freep(&chap);
686 }
687 
688 static void read_chapter(AVFormatContext *s, AVIOContext *pb, int len, const char *ttag, ID3v2ExtraMeta **extra_meta, int isv34)
689 {
690  int taglen;
691  char tag[5];
692  ID3v2ExtraMeta *new_extra = NULL;
693  ID3v2ExtraMetaCHAP *chap = NULL;
694 
695  new_extra = av_mallocz(sizeof(*new_extra));
696  chap = av_mallocz(sizeof(*chap));
697 
698  if (!new_extra || !chap)
699  goto fail;
700 
701  if (decode_str(s, pb, 0, &chap->element_id, &len) < 0)
702  goto fail;
703 
704  if (len < 16)
705  goto fail;
706 
707  chap->start = avio_rb32(pb);
708  chap->end = avio_rb32(pb);
709  avio_skip(pb, 8);
710 
711  len -= 16;
712  while (len > 10) {
713  if (avio_read(pb, tag, 4) < 4)
714  goto fail;
715  tag[4] = 0;
716  taglen = avio_rb32(pb);
717  avio_skip(pb, 2);
718  len -= 10;
719  if (taglen < 0 || taglen > len)
720  goto fail;
721  if (tag[0] == 'T')
722  read_ttag(s, pb, taglen, &chap->meta, tag);
723  else
724  avio_skip(pb, taglen);
725  len -= taglen;
726  }
727 
730 
731  new_extra->tag = "CHAP";
732  new_extra->data = chap;
733  new_extra->next = *extra_meta;
734  *extra_meta = new_extra;
735 
736  return;
737 
738 fail:
739  if (chap)
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  av_freep(&priv);
750 }
751 
752 static void read_priv(AVFormatContext *s, AVIOContext *pb, int taglen,
753  const char *tag, ID3v2ExtraMeta **extra_meta, int isv34)
754 {
755  ID3v2ExtraMeta *meta;
756  ID3v2ExtraMetaPRIV *priv;
757 
758  meta = av_mallocz(sizeof(*meta));
759  priv = av_mallocz(sizeof(*priv));
760 
761  if (!meta || !priv)
762  goto fail;
763 
764  if (decode_str(s, pb, ID3v2_ENCODING_ISO8859, &priv->owner, &taglen) < 0)
765  goto fail;
766 
767  priv->data = av_malloc(taglen);
768  if (!priv->data)
769  goto fail;
770 
771  priv->datasize = taglen;
772 
773  if (avio_read(pb, priv->data, priv->datasize) != priv->datasize)
774  goto fail;
775 
776  meta->tag = "PRIV";
777  meta->data = priv;
778  meta->next = *extra_meta;
779  *extra_meta = meta;
780 
781  return;
782 
783 fail:
784  if (priv)
785  free_priv(priv);
786  av_freep(&meta);
787 }
788 
789 typedef struct ID3v2EMFunc {
790  const char *tag3;
791  const char *tag4;
792  void (*read)(AVFormatContext *s, AVIOContext *pb, int taglen,
793  const char *tag, ID3v2ExtraMeta **extra_meta,
794  int isv34);
795  void (*free)(void *obj);
796 } ID3v2EMFunc;
797 
799  { "GEO", "GEOB", read_geobtag, free_geobtag },
800  { "PIC", "APIC", read_apic, free_apic },
801  { "CHAP","CHAP", read_chapter, free_chapter },
802  { "PRIV","PRIV", read_priv, free_priv },
803  { NULL }
804 };
805 
806 /**
807  * Get the corresponding ID3v2EMFunc struct for a tag.
808  * @param isv34 Determines if v2.2 or v2.3/4 strings are used
809  * @return A pointer to the ID3v2EMFunc struct if found, NULL otherwise.
810  */
811 static const ID3v2EMFunc *get_extra_meta_func(const char *tag, int isv34)
812 {
813  int i = 0;
814  while (id3v2_extra_meta_funcs[i].tag3) {
815  if (tag && !memcmp(tag,
816  (isv34 ? id3v2_extra_meta_funcs[i].tag4 :
817  id3v2_extra_meta_funcs[i].tag3),
818  (isv34 ? 4 : 3)))
819  return &id3v2_extra_meta_funcs[i];
820  i++;
821  }
822  return NULL;
823 }
824 
825 static void id3v2_parse(AVIOContext *pb, AVDictionary **metadata,
827  uint8_t flags, ID3v2ExtraMeta **extra_meta)
828 {
829  int isv34, unsync;
830  unsigned tlen;
831  char tag[5];
832  int64_t next, end = avio_tell(pb);
833  int taghdrlen;
834  const char *reason = NULL;
835  AVIOContext pb_local;
836  AVIOContext *pbx;
837  unsigned char *buffer = NULL;
838  int buffer_size = 0;
839  const ID3v2EMFunc *extra_func = NULL;
840  unsigned char *uncompressed_buffer = NULL;
841  av_unused int uncompressed_buffer_size = 0;
842  const char *comm_frame;
843 
844  if (end > INT64_MAX - len - 10)
845  return;
846  end += len;
847 
848  av_log(s, AV_LOG_DEBUG, "id3v2 ver:%d flags:%02X len:%d\n", version, flags, len);
849 
850  switch (version) {
851  case 2:
852  if (flags & 0x40) {
853  reason = "compression";
854  goto error;
855  }
856  isv34 = 0;
857  taghdrlen = 6;
858  comm_frame = "COM";
859  break;
860 
861  case 3:
862  case 4:
863  isv34 = 1;
864  taghdrlen = 10;
865  comm_frame = "COMM";
866  break;
867 
868  default:
869  reason = "version";
870  goto error;
871  }
872 
873  unsync = flags & 0x80;
874 
875  if (isv34 && flags & 0x40) { /* Extended header present, just skip over it */
876  int extlen = get_size(pb, 4);
877  if (version == 4)
878  /* In v2.4 the length includes the length field we just read. */
879  extlen -= 4;
880 
881  if (extlen < 0) {
882  reason = "invalid extended header length";
883  goto error;
884  }
885  avio_skip(pb, extlen);
886  len -= extlen + 4;
887  if (len < 0) {
888  reason = "extended header too long.";
889  goto error;
890  }
891  }
892 
893  while (len >= taghdrlen) {
894  unsigned int tflags = 0;
895  int tunsync = 0;
896  int tcomp = 0;
897  int tencr = 0;
898  unsigned long av_unused dlen;
899 
900  if (isv34) {
901  if (avio_read(pb, tag, 4) < 4)
902  break;
903  tag[4] = 0;
904  if (version == 3) {
905  tlen = avio_rb32(pb);
906  } else {
907  /* some encoders incorrectly uses v3 sizes instead of syncsafe ones
908  * so check the next tag to see which one to use */
909  tlen = avio_rb32(pb);
910  if (tlen > 0x7f) {
911  if (tlen < len) {
912  int64_t cur = avio_tell(pb);
913 
914  if (ffio_ensure_seekback(pb, 2 /* tflags */ + tlen + 4 /* next tag */))
915  break;
916 
917  if (check_tag(pb, cur + 2 + size_to_syncsafe(tlen), 4) == 1)
918  tlen = size_to_syncsafe(tlen);
919  else if (check_tag(pb, cur + 2 + tlen, 4) != 1)
920  break;
921  avio_seek(pb, cur, SEEK_SET);
922  } else
923  tlen = size_to_syncsafe(tlen);
924  }
925  }
926  tflags = avio_rb16(pb);
927  tunsync = tflags & ID3v2_FLAG_UNSYNCH;
928  } else {
929  if (avio_read(pb, tag, 3) < 3)
930  break;
931  tag[3] = 0;
932  tlen = avio_rb24(pb);
933  }
934  if (tlen > (1<<28))
935  break;
936  len -= taghdrlen + tlen;
937 
938  if (len < 0)
939  break;
940 
941  next = avio_tell(pb) + tlen;
942 
943  if (!tlen) {
944  if (tag[0])
945  av_log(s, AV_LOG_DEBUG, "Invalid empty frame %s, skipping.\n",
946  tag);
947  continue;
948  }
949 
950  if (tflags & ID3v2_FLAG_DATALEN) {
951  if (tlen < 4)
952  break;
953  dlen = avio_rb32(pb);
954  tlen -= 4;
955  } else
956  dlen = tlen;
957 
958  tcomp = tflags & ID3v2_FLAG_COMPRESSION;
959  tencr = tflags & ID3v2_FLAG_ENCRYPTION;
960 
961  /* skip encrypted tags and, if no zlib, compressed tags */
962  if (tencr || (!CONFIG_ZLIB && tcomp)) {
963  const char *type;
964  if (!tcomp)
965  type = "encrypted";
966  else if (!tencr)
967  type = "compressed";
968  else
969  type = "encrypted and compressed";
970 
971  av_log(s, AV_LOG_WARNING, "Skipping %s ID3v2 frame %s.\n", type, tag);
972  avio_skip(pb, tlen);
973  /* check for text tag or supported special meta tag */
974  } else if (tag[0] == 'T' ||
975  !memcmp(tag, "USLT", 4) ||
976  !strcmp(tag, comm_frame) ||
977  (extra_meta &&
978  (extra_func = get_extra_meta_func(tag, isv34)))) {
979  pbx = pb;
980 
981  if (unsync || tunsync || tcomp) {
982  av_fast_malloc(&buffer, &buffer_size, tlen);
983  if (!buffer) {
984  av_log(s, AV_LOG_ERROR, "Failed to alloc %d bytes\n", tlen);
985  goto seek;
986  }
987  }
988  if (unsync || tunsync) {
989  uint8_t *b = buffer;
990  uint8_t *t = buffer;
991  uint8_t *end = t + tlen;
992 
993  if (avio_read(pb, buffer, tlen) != tlen) {
994  av_log(s, AV_LOG_ERROR, "Failed to read tag data\n");
995  goto seek;
996  }
997 
998  while (t != end) {
999  *b++ = *t++;
1000  if (t != end && t[-1] == 0xff && !t[0])
1001  t++;
1002  }
1003 
1004  ffio_init_context(&pb_local, buffer, b - buffer, 0, NULL, NULL, NULL,
1005  NULL);
1006  tlen = b - buffer;
1007  pbx = &pb_local; // read from sync buffer
1008  }
1009 
1010 #if CONFIG_ZLIB
1011  if (tcomp) {
1012  int err;
1013 
1014  av_log(s, AV_LOG_DEBUG, "Compresssed frame %s tlen=%d dlen=%ld\n", tag, tlen, dlen);
1015 
1016  if (tlen <= 0)
1017  goto seek;
1018 
1019  av_fast_malloc(&uncompressed_buffer, &uncompressed_buffer_size, dlen);
1020  if (!uncompressed_buffer) {
1021  av_log(s, AV_LOG_ERROR, "Failed to alloc %ld bytes\n", dlen);
1022  goto seek;
1023  }
1024 
1025  if (!(unsync || tunsync)) {
1026  err = avio_read(pb, buffer, tlen);
1027  if (err < 0) {
1028  av_log(s, AV_LOG_ERROR, "Failed to read compressed tag\n");
1029  goto seek;
1030  }
1031  tlen = err;
1032  }
1033 
1034  err = uncompress(uncompressed_buffer, &dlen, buffer, tlen);
1035  if (err != Z_OK) {
1036  av_log(s, AV_LOG_ERROR, "Failed to uncompress tag: %d\n", err);
1037  goto seek;
1038  }
1039  ffio_init_context(&pb_local, uncompressed_buffer, dlen, 0, NULL, NULL, NULL, NULL);
1040  tlen = dlen;
1041  pbx = &pb_local; // read from sync buffer
1042  }
1043 #endif
1044  if (tag[0] == 'T')
1045  /* parse text tag */
1046  read_ttag(s, pbx, tlen, metadata, tag);
1047  else if (!memcmp(tag, "USLT", 4))
1048  read_uslt(s, pbx, tlen, metadata);
1049  else if (!strcmp(tag, comm_frame))
1050  read_comment(s, pbx, tlen, metadata);
1051  else
1052  /* parse special meta tag */
1053  extra_func->read(s, pbx, tlen, tag, extra_meta, isv34);
1054  } else if (!tag[0]) {
1055  if (tag[1])
1056  av_log(s, AV_LOG_WARNING, "invalid frame id, assuming padding\n");
1057  avio_skip(pb, tlen);
1058  break;
1059  }
1060  /* Skip to end of tag */
1061 seek:
1062  avio_seek(pb, next, SEEK_SET);
1063  }
1064 
1065  /* Footer preset, always 10 bytes, skip over it */
1066  if (version == 4 && flags & 0x10)
1067  end += 10;
1068 
1069 error:
1070  if (reason)
1071  av_log(s, AV_LOG_INFO, "ID3v2.%d tag skipped, cannot handle %s\n",
1072  version, reason);
1073  avio_seek(pb, end, SEEK_SET);
1074  av_free(buffer);
1075  av_free(uncompressed_buffer);
1076  return;
1077 }
1078 
1079 static void id3v2_read_internal(AVIOContext *pb, AVDictionary **metadata,
1080  AVFormatContext *s, const char *magic,
1081  ID3v2ExtraMeta **extra_meta, int64_t max_search_size)
1082 {
1083  int len, ret;
1085  int found_header;
1086  int64_t start, off;
1087 
1088  if (max_search_size && max_search_size < ID3v2_HEADER_SIZE)
1089  return;
1090 
1091  start = avio_tell(pb);
1092  do {
1093  /* save the current offset in case there's nothing to read/skip */
1094  off = avio_tell(pb);
1095  if (max_search_size && off - start >= max_search_size - ID3v2_HEADER_SIZE) {
1096  avio_seek(pb, off, SEEK_SET);
1097  break;
1098  }
1099 
1101  if (ret >= 0)
1103  if (ret != ID3v2_HEADER_SIZE) {
1104  avio_seek(pb, off, SEEK_SET);
1105  break;
1106  }
1107  found_header = ff_id3v2_match(buf, magic);
1108  if (found_header) {
1109  /* parse ID3v2 header */
1110  len = ((buf[6] & 0x7f) << 21) |
1111  ((buf[7] & 0x7f) << 14) |
1112  ((buf[8] & 0x7f) << 7) |
1113  (buf[9] & 0x7f);
1114  id3v2_parse(pb, metadata, s, len, buf[3], buf[5], extra_meta);
1115  } else {
1116  avio_seek(pb, off, SEEK_SET);
1117  }
1118  } while (found_header);
1122  merge_date(metadata);
1123 }
1124 
1126  const char *magic, ID3v2ExtraMeta **extra_meta)
1127 {
1128  id3v2_read_internal(pb, metadata, NULL, magic, extra_meta, 0);
1129 }
1130 
1131 void ff_id3v2_read(AVFormatContext *s, const char *magic,
1132  ID3v2ExtraMeta **extra_meta, unsigned int max_search_size)
1133 {
1134  id3v2_read_internal(s->pb, &s->metadata, s, magic, extra_meta, max_search_size);
1135 }
1136 
1138 {
1139  ID3v2ExtraMeta *current = *extra_meta, *next;
1140  const ID3v2EMFunc *extra_func;
1141 
1142  while (current) {
1143  if ((extra_func = get_extra_meta_func(current->tag, 1)))
1144  extra_func->free(current->data);
1145  next = current->next;
1146  av_freep(&current);
1147  current = next;
1148  }
1149 
1150  *extra_meta = NULL;
1151 }
1152 
1154 {
1155  ID3v2ExtraMeta *cur;
1156 
1157  for (cur = *extra_meta; cur; cur = cur->next) {
1158  ID3v2ExtraMetaAPIC *apic;
1159  AVStream *st;
1160 
1161  if (strcmp(cur->tag, "APIC"))
1162  continue;
1163  apic = cur->data;
1164 
1165  if (!(st = avformat_new_stream(s, NULL)))
1166  return AVERROR(ENOMEM);
1167 
1170  st->codecpar->codec_id = apic->id;
1171 
1172  if (AV_RB64(apic->buf->data) == PNGSIG)
1174 
1175  if (apic->description[0])
1176  av_dict_set(&st->metadata, "title", apic->description, 0);
1177 
1178  av_dict_set(&st->metadata, "comment", apic->type, 0);
1179 
1181  st->attached_pic.buf = apic->buf;
1182  st->attached_pic.data = apic->buf->data;
1184  st->attached_pic.stream_index = st->index;
1186 
1187  apic->buf = NULL;
1188  }
1189 
1190  return 0;
1191 }
1192 
1194 {
1195  int ret = 0;
1196  ID3v2ExtraMeta *cur;
1197  AVRational time_base = {1, 1000};
1198  ID3v2ExtraMetaCHAP **chapters = NULL;
1199  int num_chapters = 0;
1200  int i;
1201 
1202  // since extra_meta is a linked list where elements are prepended,
1203  // we need to reverse the order of chapters
1204  for (cur = *extra_meta; cur; cur = cur->next) {
1205  ID3v2ExtraMetaCHAP *chap;
1206 
1207  if (strcmp(cur->tag, "CHAP"))
1208  continue;
1209  chap = cur->data;
1210 
1211  if ((ret = av_dynarray_add_nofree(&chapters, &num_chapters, chap)) < 0)
1212  goto end;
1213  }
1214 
1215  for (i = 0; i < (num_chapters / 2); i++) {
1216  ID3v2ExtraMetaCHAP *right;
1217  int right_index;
1218 
1219  right_index = (num_chapters - 1) - i;
1220  right = chapters[right_index];
1221 
1222  chapters[right_index] = chapters[i];
1223  chapters[i] = right;
1224  }
1225 
1226  for (i = 0; i < num_chapters; i++) {
1227  ID3v2ExtraMetaCHAP *chap;
1228  AVChapter *chapter;
1229 
1230  chap = chapters[i];
1231  chapter = avpriv_new_chapter(s, i, time_base, chap->start, chap->end, chap->element_id);
1232  if (!chapter)
1233  continue;
1234 
1235  if ((ret = av_dict_copy(&chapter->metadata, chap->meta, 0)) < 0)
1236  goto end;
1237  }
1238 
1239 end:
1240  av_freep(&chapters);
1241  return ret;
1242 }
1243 
1245 {
1246  ID3v2ExtraMeta *cur;
1248 
1249  for (cur = *extra_meta; cur; cur = cur->next) {
1250  if (!strcmp(cur->tag, "PRIV")) {
1251  ID3v2ExtraMetaPRIV *priv = cur->data;
1252  AVBPrint bprint;
1253  char *escaped, *key;
1254  int i, ret;
1255 
1256  if ((key = av_asprintf(ID3v2_PRIV_METADATA_PREFIX "%s", priv->owner)) == NULL) {
1257  return AVERROR(ENOMEM);
1258  }
1259 
1260  av_bprint_init(&bprint, priv->datasize + 1, AV_BPRINT_SIZE_UNLIMITED);
1261 
1262  for (i = 0; i < priv->datasize; i++) {
1263  if (priv->data[i] < 32 || priv->data[i] > 126 || priv->data[i] == '\\') {
1264  av_bprintf(&bprint, "\\x%02x", priv->data[i]);
1265  } else {
1266  av_bprint_chars(&bprint, priv->data[i], 1);
1267  }
1268  }
1269 
1270  if ((ret = av_bprint_finalize(&bprint, &escaped)) < 0) {
1271  av_free(key);
1272  return ret;
1273  }
1274 
1275  if ((ret = av_dict_set(metadata, key, escaped, dict_flags)) < 0) {
1276  return ret;
1277  }
1278  }
1279  }
1280 
1281  return 0;
1282 }
1283 
1285 {
1286  return ff_id3v2_parse_priv_dict(&s->metadata, extra_meta);
1287 }
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
PUT_UTF8
#define PUT_UTF8(val, tmp, PUT_BYTE)
Definition: common.h:438
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:1244
av_buffer_alloc
AVBufferRef * av_buffer_alloc(int size)
Allocate an AVBuffer of the given size using av_malloc().
Definition: buffer.c:67
AVChapter::metadata
AVDictionary * metadata
Definition: avformat.h:1303
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
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4480
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: avcodec.h:3953
ID3v2ExtraMeta::next
struct ID3v2ExtraMeta * next
Definition: id3v2.h:60
free_chapter
static void free_chapter(void *obj)
Definition: id3v2.c:680
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:582
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: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:89
AV_DISPOSITION_ATTACHED_PIC
#define AV_DISPOSITION_ATTACHED_PIC
The stream is stored in the file as an attached picture/"cover art" (e.g.
Definition: avformat.h:838
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:1284
ID3v2EMFunc::read
void(* read)(AVFormatContext *s, AVIOContext *pb, int taglen, const char *tag, ID3v2ExtraMeta **extra_meta, int isv34)
Definition: id3v2.c:792
ch
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(const uint8_t *) pi - 0x80U))<< 56) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(const int16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(const int16_t *) pi)<< 48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(const int32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(const int32_t *) pi)<< 32) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S64,(*(const int64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0f/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(const float *) pi *(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(const double *) pi *(INT64_C(1)<< 63))) #define FMT_PAIR_FUNC(out, in) static conv_func_type *const fmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB *AV_SAMPLE_FMT_NB]={ FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64), };static void cpy1(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, len);} static void cpy2(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 2 *len);} static void cpy4(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 4 *len);} static void cpy8(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 8 *len);} AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, const int *ch_map, int flags) { AudioConvert *ctx;conv_func_type *f=fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt)+AV_SAMPLE_FMT_NB *av_get_packed_sample_fmt(in_fmt)];if(!f) return NULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) return NULL;if(channels==1){ in_fmt=av_get_planar_sample_fmt(in_fmt);out_fmt=av_get_planar_sample_fmt(out_fmt);} ctx->channels=channels;ctx->conv_f=f;ctx->ch_map=ch_map;if(in_fmt==AV_SAMPLE_FMT_U8||in_fmt==AV_SAMPLE_FMT_U8P) memset(ctx->silence, 0x80, sizeof(ctx->silence));if(out_fmt==in_fmt &&!ch_map) { switch(av_get_bytes_per_sample(in_fmt)){ case 1:ctx->simd_f=cpy1;break;case 2:ctx->simd_f=cpy2;break;case 4:ctx->simd_f=cpy4;break;case 8:ctx->simd_f=cpy8;break;} } if(HAVE_X86ASM &&1) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels);if(ARCH_ARM) swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);if(ARCH_AARCH64) swri_audio_convert_init_aarch64(ctx, out_fmt, in_fmt, channels);return ctx;} void swri_audio_convert_free(AudioConvert **ctx) { av_freep(ctx);} int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len) { int ch;int off=0;const int os=(out->planar ? 1 :out->ch_count) *out->bps;unsigned misaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask) { int planes=in->planar ? in->ch_count :1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) in->ch[ch];misaligned|=m &ctx->in_simd_align_mask;} if(ctx->out_simd_align_mask) { int planes=out->planar ? out->ch_count :1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) out->ch[ch];misaligned|=m &ctx->out_simd_align_mask;} if(ctx->simd_f &&!ctx->ch_map &&!misaligned){ off=len &~15;av_assert1(off >=0);av_assert1(off<=len);av_assert2(ctx->channels==SWR_CH_MAX||!in->ch[ctx->channels]);if(off >0){ if(out->planar==in->planar){ int planes=out->planar ? out->ch_count :1;for(ch=0;ch< planes;ch++){ ctx->simd_f(out-> ch ch
Definition: audioconvert.c:56
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:125
id3v2.h
end
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:26
ID3v1_GENRE_MAX
#define ID3v1_GENRE_MAX
Definition: id3v1.h:29
AVPacket::data
uint8_t * data
Definition: avcodec.h:1477
b
#define b
Definition: input.c:41
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:1131
AVMetadataConv
Definition: metadata.h:34
ID3v2ExtraMetaAPIC::id
enum AVCodecID id
Definition: id3v2.h:75
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
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1509
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:63
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
free_apic
static void free_apic(void *obj)
Definition: id3v2.c:574
AVBufferRef::size
int size
Size of data in bytes.
Definition: buffer.h:93
CodecMime
Definition: internal.h:49
ID3v2EMFunc::tag3
const char * tag3
Definition: id3v2.c:790
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:1153
finish
static void finish(void)
Definition: movenc.c:345
fail
#define fail()
Definition: checkasm.h:120
start
void INT64 start
Definition: avisynth_c.h:767
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:557
AVChapter
Definition: avformat.h:1299
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:84
avio_rl16
unsigned int avio_rl16(AVIOContext *s)
Definition: aviobuf.c:753
AVStream::attached_pic
AVPacket attached_pic
For streams with AV_DISPOSITION_ATTACHED_PIC disposition, this packet will contain the attached pictu...
Definition: avformat.h:952
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:74
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:1415
get_date_tag
static AVDictionaryEntry * get_date_tag(AVDictionary *m, const char *tag)
Definition: id3v2.c:533
avio_rb32
unsigned int avio_rb32(AVIOContext *s)
Definition: aviobuf.c:800
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
buf
void * buf
Definition: avisynth_c.h:766
id3v2_parse
static void id3v2_parse(AVIOContext *pb, AVDictionary **metadata, AVFormatContext *s, int len, uint8_t version, uint8_t flags, ID3v2ExtraMeta **extra_meta)
Definition: id3v2.c:825
ID3v2ExtraMeta
Definition: id3v2.h:57
ID3v2_ENCODING_UTF8
@ ID3v2_ENCODING_UTF8
Definition: id3v2.h:48
ID3v2ExtraMetaCHAP::element_id
uint8_t * element_id
Definition: id3v2.h:85
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:1386
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: avcodec.h:296
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:304
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
ID3v2ExtraMetaAPIC::buf
AVBufferRef * buf
Definition: id3v2.h:72
free_priv
static void free_priv(void *obj)
Definition: id3v2.c:744
key
const char * key
Definition: hwcontext_opencl.c:168
version
int version
Definition: avisynth_c.h:858
ID3v2_FLAG_DATALEN
#define ID3v2_FLAG_DATALEN
Definition: id3v2.h:37
ID3v2ExtraMetaGEOB::datasize
uint32_t datasize
Definition: id3v2.h:64
AV_CODEC_ID_PNG
@ AV_CODEC_ID_PNG
Definition: avcodec.h:279
ID3v2ExtraMeta::tag
const char * tag
Definition: id3v2.h:58
AVFormatContext
Format I/O context.
Definition: avformat.h:1342
internal.h
AVPacket::buf
AVBufferRef * buf
A reference to the reference-counted buffer where the packet data is stored.
Definition: avcodec.h:1460
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1017
NULL
#define NULL
Definition: coverity.c:32
ID3v2EMFunc::free
void(* free)(void *obj)
Definition: id3v2.c:795
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:125
ID3v2ExtraMetaPRIV::data
uint8_t * data
Definition: id3v2.h:80
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
ID3v2ExtraMetaGEOB::mime_type
uint8_t * mime_type
Definition: id3v2.h:65
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:934
AV_DICT_DONT_OVERWRITE
#define AV_DICT_DONT_OVERWRITE
Don't overwrite existing entries.
Definition: dict.h:76
avio_w8
void avio_w8(AVIOContext *s, int b)
Definition: aviobuf.c:196
read_chapter
static void read_chapter(AVFormatContext *s, AVIOContext *pb, int len, const char *ttag, ID3v2ExtraMeta **extra_meta, int isv34)
Definition: id3v2.c:688
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
error
static void error(const char *err)
Definition: target_dec_fuzzer.c:61
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: avcodec.h:215
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:223
ID3v2ExtraMetaGEOB::file_name
uint8_t * file_name
Definition: id3v2.h:66
AVIOContext
Bytestream IO Context.
Definition: avio.h:161
ffio_init_context
int ffio_init_context(AVIOContext *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
avio_rb24
unsigned int avio_rb24(AVIOContext *s)
Definition: aviobuf.c:793
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:526
ID3v2_ENCODING_UTF16BOM
@ ID3v2_ENCODING_UTF16BOM
Definition: id3v2.h:46
AVPacket::size
int size
Definition: avcodec.h:1478
id
enum AVCodecID id
Definition: extract_extradata_bsf.c:329
ID3v2ExtraMetaCHAP::start
uint32_t start
Definition: id3v2.h:86
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:879
merge_date
static void merge_date(AVDictionary **m)
Definition: id3v2.c:542
size
int size
Definition: twinvq_data.h:11134
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:92
ff_id3v2_34_metadata_conv
const AVMetadataConv ff_id3v2_34_metadata_conv[]
Definition: id3v2.c:45
ID3v2ExtraMeta::data
void * data
Definition: id3v2.h:59
avio_r8
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:638
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:1051
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
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1483
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
ID3v2ExtraMetaAPIC
Definition: id3v2.h:71
PNGSIG
#define PNGSIG
Definition: png.h:47
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:187
AV_CODEC_ID_GIF
@ AV_CODEC_ID_GIF
Definition: avcodec.h:315
AV_CODEC_ID_MJPEG
@ AV_CODEC_ID_MJPEG
Definition: avcodec.h:225
bprint.h
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: avcodec.h:216
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
avio_rl24
unsigned int avio_rl24(AVIOContext *s)
Definition: aviobuf.c:761
avio_internal.h
avpriv_new_chapter
AVChapter * avpriv_new_chapter(AVFormatContext *s, int id, AVRational time_base, int64_t start, int64_t end, const char *title)
Add a new chapter.
Definition: utils.c:4608
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:1125
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:27
uint8_t
uint8_t
Definition: audio_convert.c:194
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:410
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:236
len
int len
Definition: vorbis_enc_data.h:452
ID3v2ExtraMetaPRIV::datasize
uint32_t datasize
Definition: id3v2.h:81
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:811
id3v2_read_internal
static void id3v2_read_internal(AVIOContext *pb, AVDictionary **metadata, AVFormatContext *s, const char *magic, ID3v2ExtraMeta **extra_meta, int64_t max_search_size)
Definition: id3v2.c:1079
ID3v2_ENCODING_UTF16BE
@ ID3v2_ENCODING_UTF16BE
Definition: id3v2.h:47
language
Undefined Behavior In the C language
Definition: undefined.txt:3
AVStream::disposition
int disposition
AV_DISPOSITION_* bit field.
Definition: avformat.h:923
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:1496
ffio_free_dyn_buf
void ffio_free_dyn_buf(AVIOContext **s)
Free a dynamic buffer.
Definition: aviobuf.c:1445
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:870
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:246
avio_rb16
unsigned int avio_rb16(AVIOContext *s)
Definition: aviobuf.c:785
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: avcodec.h:790
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
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen_template.c:38
AV_DICT_MATCH_CASE
#define AV_DICT_MATCH_CASE
Only get an entry with exact-case key match.
Definition: dict.h:69
ID3v2ExtraMetaGEOB::description
uint8_t * description
Definition: id3v2.h:67
SIZE_SPECIFIER
#define SIZE_SPECIFIER
Definition: internal.h:264
av_dynarray_add_nofree
int av_dynarray_add_nofree(void *tab_ptr, int *nb_ptr, void *elem)
Add an element to a dynamic array.
Definition: mem.c:294
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:871
ID3v2ExtraMetaAPIC::type
const char * type
Definition: id3v2.h:73
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
config.h
avio_read
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:647
ID3v2ExtraMetaGEOB::data
uint8_t * data
Definition: id3v2.h:68
AVPacket::stream_index
int stream_index
Definition: avcodec.h:1479
avio_skip
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:331
CodecMime::str
char str[32]
Definition: internal.h:50
CodecMime::id
enum AVCodecID id
Definition: internal.h:51
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:251
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
ID3v2_FLAG_COMPRESSION
#define ID3v2_FLAG_COMPRESSION
Definition: id3v2.h:40
ID3v2EMFunc
Definition: id3v2.c:789
id3v2_extra_meta_funcs
static const ID3v2EMFunc id3v2_extra_meta_funcs[]
Definition: id3v2.c:798
ID3v2ExtraMetaCHAP::end
uint32_t end
Definition: id3v2.h:86
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVDictionaryEntry
Definition: dict.h:81
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: avcodec.h:3957
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:500
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:1137
read_priv
static void read_priv(AVFormatContext *s, AVIOContext *pb, int taglen, const char *tag, ID3v2ExtraMeta **extra_meta, int isv34)
Definition: id3v2.c:752
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:565
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
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:59
id3v2_2_metadata_conv
static const AVMetadataConv id3v2_2_metadata_conv[]
Definition: id3v2.c:75
AV_CODEC_ID_TIFF
@ AV_CODEC_ID_TIFF
Definition: avcodec.h:314
AVDictionaryEntry::value
char * value
Definition: dict.h:83
avstring.h
ff_id3v2_parse_chapters
int ff_id3v2_parse_chapters(AVFormatContext *s, ID3v2ExtraMeta **extra_meta)
Create chapters for all CHAP tags found in the ID3v2 header.
Definition: id3v2.c:1193
ID3v2EMFunc::tag4
const char * tag4
Definition: id3v2.c:791
read_geobtag
static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen, const char *tag, ID3v2ExtraMeta **extra_meta, int isv34)
Parse GEOB tag into a ID3v2ExtraMetaGEOB struct.
Definition: id3v2.c:449
int
int
Definition: ffmpeg_filter.c:191
snprintf
#define snprintf
Definition: snprintf.h:34
ID3v2ExtraMetaCHAP::meta
AVDictionary * meta
Definition: id3v2.h:87
ID3v2ExtraMetaPRIV
Definition: id3v2.h:78
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:91
ID3v2ExtraMetaPRIV::owner
uint8_t * owner
Definition: id3v2.h:79
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:72
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
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:74
av_init_packet
void av_init_packet(AVPacket *pkt)
Initialize optional fields of a packet with default values.
Definition: avpacket.c:33
read_apic
static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, const char *tag, ID3v2ExtraMeta **extra_meta, int isv34)
Definition: id3v2.c:589