FFmpeg
Loading...
Searching...
No Matches
reader.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2005 Michael Ahlberg, Måns Rullgård
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include <stdio.h>
26#include <string.h>
27
28#include "libavutil/avstring.h"
29#include "libavutil/base64.h"
30#include "libavutil/dict.h"
31#include "libavutil/mem.h"
32
34
36#include "libavformat/demux.h"
41
42static int ogm_chapter(AVFormatContext *as, const uint8_t *key, const uint8_t *val)
43{
44 int i, cnum, h, m, s, ms, keylen = strlen(key);
45 AVChapter *chapter = NULL;
46
47 if (keylen < 9 || av_strncasecmp(key, "CHAPTER", 7) || sscanf(key+7, "%03d", &cnum) != 1)
48 return 0;
49
50 if (keylen <= 10) {
51 if (sscanf(val, "%02d:%02d:%02d.%03d", &h, &m, &s, &ms) < 4)
52 return 0;
53
54 avpriv_new_chapter(as, cnum, (AVRational) { 1, 1000 },
55 ms + 1000 * (s + 60 * (m + 60 * h)),
57 } else if (!av_strcasecmp(key + keylen - 4, "NAME")) {
58 for (i = 0; i < as->nb_chapters; i++)
59 if (as->chapters[i]->id == cnum) {
60 chapter = as->chapters[i];
61 break;
62 }
63 if (!chapter)
64 return 0;
65
66 av_dict_set(&chapter->metadata, "title", val, 0);
67 } else
68 return 0;
69
70 return 1;
71}
72
74 const uint8_t *buf, int size)
75{
76 int updates = ff_vorbis_comment_read(as, &st->metadata, buf, size, 1);
77
78 if (updates > 0) {
80 }
81
82 return updates;
83}
84
85/**
86 * This function temporarily modifies the (const qualified) input buffer
87 * and reverts its changes before return. The input buffer needs to have
88 * at least one byte of padding.
89 */
91 const uint8_t *buf, uint32_t size,
92 int *updates, int parse_picture)
93{
94 char *t = (char*)buf, *v = memchr(t, '=', size);
95 int tl, vl;
96 char backup;
97
98 if (!v)
99 return 0;
100
101 tl = v - t;
102 vl = size - tl - 1;
103 v++;
104
105 if (!tl || !vl)
106 return 0;
107
108 t[tl] = 0;
109
110 backup = v[vl];
111 v[vl] = 0;
112
113 /* The format in which the pictures are stored is the FLAC format.
114 * Xiph says: "The binary FLAC picture structure is base64 encoded
115 * and placed within a VorbisComment with the tag name
116 * 'METADATA_BLOCK_PICTURE'. This is the preferred and
117 * recommended way of embedding cover art within VorbisComments."
118 */
119 if (!av_strcasecmp(t, "METADATA_BLOCK_PICTURE") && parse_picture) {
120 int ret, len = AV_BASE64_DECODE_SIZE(vl);
121 uint8_t *pict = av_malloc(len + AV_INPUT_BUFFER_PADDING_SIZE);
122
123 if (!pict) {
124 av_log(as, AV_LOG_WARNING, "out-of-memory error. Skipping cover art block.\n");
125 goto end;
126 }
127 ret = av_base64_decode(pict, v, len);
128 if (ret > 0)
129 ret = ff_flac_parse_picture(as, &pict, ret, 0);
130 av_freep(&pict);
131 if (ret < 0) {
132 av_log(as, AV_LOG_WARNING, "Failed to parse cover art block.\n");
133 goto end;
134 }
135 } else if (!ogm_chapter(as, t, v)) {
136 (*updates)++;
137 if (av_dict_get(*m, t, NULL, 0))
138 av_dict_set(m, t, ";", AV_DICT_APPEND);
139 av_dict_set(m, t, v, AV_DICT_APPEND);
140 }
141end:
142 t[tl] = '=';
143 v[vl] = backup;
144
145 return 0;
146}
147
149 const uint8_t *buf, int size,
150 int parse_picture)
151{
152 const uint8_t *p = buf;
153 const uint8_t *end = buf + size;
154 int updates = 0;
155 unsigned n;
156 int s, ret;
157
158 /* must have vendor_length and user_comment_list_length */
159 if (size < 8)
160 return AVERROR_INVALIDDATA;
161
162 s = bytestream_get_le32(&p);
163
164 if (end - p - 4 < s || s < 0)
165 return AVERROR_INVALIDDATA;
166
167 p += s;
168
169 n = bytestream_get_le32(&p);
170
171 while (end - p >= 4 && n > 0) {
172 s = bytestream_get_le32(&p);
173
174 if (end - p < s || s < 0)
175 break;
176
177 ret = vorbis_parse_single_comment(as, m, p, s, &updates, parse_picture);
178 if (ret < 0)
179 return ret;
180 p += s;
181 n--;
182 }
183
184 if (p != end)
186 "%td bytes of comment header remain\n", end - p);
187 if (n > 0)
189 "truncated comment header, %i comments not found\n", n);
190
192
193 return updates;
194}
static double val(void *priv, double ch)
Definition aeval.c:77
Main libavformat public API header.
#define AVSTREAM_EVENT_FLAG_METADATA_UPDATED
Definition avformat.h:886
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
const AVMetadataConv ff_vorbis_comment_metadata_conv[]
VorbisComment metadata conversion mapping.
Definition writer.c:34
#define NULL
Definition coverity.c:32
AVChapter * avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base, int64_t start, int64_t end, const char *title)
Add a new chapter.
Definition demux_utils.c:46
Public dictionary API.
const char * key
int ret
Definition ffplay.c:391
int ff_flac_parse_picture(AVFormatContext *s, uint8_t **bufp, int buf_size, int truncate_workaround)
Parse a FLAC METADATA_BLOCK_PICTURE.
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
Definition defs.h:40
#define AV_BASE64_DECODE_SIZE(x)
Calculate the output size in bytes needed to decode a base64 string with length x to a data buffer.
Definition base64.h:48
int av_base64_decode(uint8_t *out, const char *in_str, int out_size)
Decode a base64-encoded string.
Definition base64.c:86
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:61
#define AV_DICT_APPEND
If the entry already exists, append to it.
Definition dict.h:82
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:87
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_INFO
Standard information.
Definition log.h:221
int av_strcasecmp(const char *a, const char *b)
Locale-independent case-insensitive compare.
Definition avstring.c:208
int av_strncasecmp(const char *a, const char *b, size_t n)
Locale-independent case-insensitive compare.
Definition avstring.c:218
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
Memory handling functions.
void ff_metadata_conv(AVDictionary **pm, const AVMetadataConv *d_conv, const AVMetadataConv *s_conv)
Definition metadata.c:26
internal metadata API header see avformat.h or the public API!
#define av_malloc(s)
Definition ops_static.c:52
int64_t id
unique ID to identify the chapter
Definition avformat.h:1361
AVDictionary * metadata
Definition avformat.h:1364
Format I/O context.
Definition avformat.h:1401
unsigned int nb_chapters
Number of chapters in AVChapter array.
Definition avformat.h:1502
AVChapter ** chapters
Definition avformat.h:1503
Rational number (pair of numerator and denominator).
Definition rational.h:58
Stream structure.
Definition avformat.h:768
AVDictionary * metadata
Definition avformat.h:848
int event_flags
Flags indicating events happening on the stream, a combination of AVSTREAM_EVENT_FLAG_*.
Definition avformat.h:879
#define av_freep(p)
#define av_log(a,...)
int size
int ff_vorbis_comment_read_stream(AVFormatContext *as, AVStream *st, const uint8_t *buf, int size)
Parse Vorbis comments and add metadata to an AVStream.
Definition reader.c:73
static int ogm_chapter(AVFormatContext *as, const uint8_t *key, const uint8_t *val)
Definition reader.c:42
static int vorbis_parse_single_comment(AVFormatContext *as, AVDictionary **m, const uint8_t *buf, uint32_t size, int *updates, int parse_picture)
This function temporarily modifies the (const qualified) input buffer and reverts its changes before ...
Definition reader.c:90
int ff_vorbis_comment_read(AVFormatContext *as, AVDictionary **m, const uint8_t *buf, int size, int parse_picture)
Parse Vorbis comments.
Definition reader.c:148
int len