FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/flvdec.c
Date: 2025-04-25 22:50:00
Exec Total Coverage
Lines: 788 1240 63.5%
Functions: 23 27 85.2%
Branches: 541 1007 53.7%

Line Branch Exec Source
1 /*
2 * FLV demuxer
3 * Copyright (c) 2003 The FFmpeg Project
4 *
5 * This demuxer will generate a 1 byte extradata for VP6F content.
6 * It is composed of:
7 * - upper 4 bits: difference between encoded width and visible width
8 * - lower 4 bits: difference between encoded height and visible height
9 *
10 * This file is part of FFmpeg.
11 *
12 * FFmpeg is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
16 *
17 * FFmpeg is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with FFmpeg; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 */
26
27 #include "libavutil/avassert.h"
28 #include "libavutil/avstring.h"
29 #include "libavutil/channel_layout.h"
30 #include "libavutil/dict.h"
31 #include "libavutil/mem.h"
32 #include "libavutil/opt.h"
33 #include "libavutil/internal.h"
34 #include "libavutil/intfloat.h"
35 #include "libavutil/intreadwrite.h"
36 #include "libavutil/mastering_display_metadata.h"
37 #include "avformat.h"
38 #include "demux.h"
39 #include "internal.h"
40 #include "flv.h"
41
42 #define VALIDATE_INDEX_TS_THRESH 2500
43
44 #define RESYNC_BUFFER_SIZE (1<<20)
45
46 #define MAX_DEPTH 16 ///< arbitrary limit to prevent unbounded recursion
47
48 typedef struct FLVMasteringMeta {
49 float r_x;
50 float r_y;
51 float g_x;
52 float g_y;
53 float b_x;
54 float b_y;
55 float white_x;
56 float white_y;
57 float max_luminance;
58 float min_luminance;
59 } FLVMasteringMeta;
60
61 typedef struct FLVMetaVideoColor {
62 enum AVColorSpace matrix_coefficients;
63 enum AVColorTransferCharacteristic trc;
64 enum AVColorPrimaries primaries;
65 uint16_t max_cll;
66 uint16_t max_fall;
67 FLVMasteringMeta mastering_meta;
68 } FLVMetaVideoColor;
69
70 enum FLVMetaColorInfoFlag {
71 FLV_COLOR_INFO_FLAG_NONE = 0,
72 FLV_COLOR_INFO_FLAG_GOT = 1,
73 FLV_COLOR_INFO_FLAG_PARSING = 2,
74 };
75
76 typedef struct FLVContext {
77 const AVClass *class; ///< Class for private options.
78 int trust_metadata; ///< configure streams according onMetaData
79 int trust_datasize; ///< trust data size of FLVTag
80 int dump_full_metadata; ///< Dump full metadata of the onMetadata
81 int wrong_dts; ///< wrong dts due to negative cts
82 uint8_t *new_extradata[FLV_STREAM_TYPE_NB];
83 int new_extradata_size[FLV_STREAM_TYPE_NB];
84 int last_sample_rate;
85 int last_channels;
86 struct {
87 int64_t dts;
88 int64_t pos;
89 } validate_index[2];
90 int validate_next;
91 int validate_count;
92 int searched_for_end;
93
94 uint8_t resync_buffer[2*RESYNC_BUFFER_SIZE];
95
96 int broken_sizes;
97 int64_t sum_flv_tag_size;
98
99 int last_keyframe_stream_index;
100 int keyframe_count;
101 int64_t video_bit_rate;
102 int64_t audio_bit_rate;
103 int64_t *keyframe_times;
104 int64_t *keyframe_filepositions;
105 AVRational framerate;
106 int64_t last_ts;
107 int64_t time_offset;
108 int64_t time_pos;
109
110 FLVMetaVideoColor meta_color_info;
111 enum FLVMetaColorInfoFlag meta_color_info_flag;
112
113 uint8_t **mt_extradata;
114 int *mt_extradata_sz;
115 int mt_extradata_cnt;
116 } FLVContext;
117
118 /* AMF date type */
119 typedef struct amf_date {
120 double milliseconds;
121 int16_t timezone;
122 } amf_date;
123
124 14422 static int probe(const AVProbeData *p, int live)
125 {
126 14422 const uint8_t *d = p->buf;
127 14422 unsigned offset = AV_RB32(d + 5);
128
129
2/2
✓ Branch 0 taken 136 times.
✓ Branch 1 taken 14286 times.
14422 if (d[0] == 'F' &&
130
2/2
✓ Branch 0 taken 76 times.
✓ Branch 1 taken 60 times.
136 d[1] == 'L' &&
131
1/2
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
76 d[2] == 'V' &&
132
2/4
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 76 times.
✗ Branch 3 not taken.
76 d[3] < 5 && d[5] == 0 &&
133
2/4
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 76 times.
✗ Branch 3 not taken.
76 offset + 100 < p->buf_size &&
134 offset > 8) {
135 76 int is_live = !memcmp(d + offset + 40, "NGINX RTMP", 10);
136
137
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 38 times.
76 if (live == is_live)
138 38 return AVPROBE_SCORE_MAX;
139 }
140 14384 return 0;
141 }
142
143 7211 static int flv_probe(const AVProbeData *p)
144 {
145 7211 return probe(p, 0);
146 }
147
148 7211 static int live_flv_probe(const AVProbeData *p)
149 {
150 7211 return probe(p, 1);
151 }
152
153 7211 static int kux_probe(const AVProbeData *p)
154 {
155 7211 const uint8_t *d = p->buf;
156
157
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 7208 times.
7211 if (d[0] == 'K' &&
158
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 d[1] == 'D' &&
159 d[2] == 'K' &&
160 d[3] == 0 &&
161 d[4] == 0) {
162 return AVPROBE_SCORE_EXTENSION + 1;
163 }
164 7211 return 0;
165 }
166
167 48 static void add_keyframes_index(AVFormatContext *s)
168 {
169 48 FLVContext *flv = s->priv_data;
170 48 AVStream *stream = NULL;
171 48 unsigned int i = 0;
172
173
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 45 times.
48 if (flv->last_keyframe_stream_index < 0) {
174 3 av_log(s, AV_LOG_DEBUG, "keyframe stream hasn't been created\n");
175 3 return;
176 }
177
178
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
45 av_assert0(flv->last_keyframe_stream_index <= s->nb_streams);
179 45 stream = s->streams[flv->last_keyframe_stream_index];
180
181
1/2
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
45 if (ffstream(stream)->nb_index_entries == 0) {
182
2/2
✓ Branch 0 taken 173 times.
✓ Branch 1 taken 45 times.
218 for (i = 0; i < flv->keyframe_count; i++) {
183 173 av_log(s, AV_LOG_TRACE, "keyframe filepositions = %"PRId64" times = %"PRId64"\n",
184 173 flv->keyframe_filepositions[i], flv->keyframe_times[i]);
185 173 av_add_index_entry(stream, flv->keyframe_filepositions[i],
186 173 flv->keyframe_times[i], 0, 0, AVINDEX_KEYFRAME);
187 }
188 } else
189 av_log(s, AV_LOG_WARNING, "Skipping duplicate index\n");
190
191
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 12 times.
45 if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
192 33 av_freep(&flv->keyframe_times);
193 33 av_freep(&flv->keyframe_filepositions);
194 33 flv->keyframe_count = 0;
195 }
196 }
197
198 69 static AVStream *create_stream(AVFormatContext *s, int codec_type, int track_idx)
199 {
200 69 FFFormatContext *const si = ffformatcontext(s);
201 69 FLVContext *flv = s->priv_data;
202 69 AVStream *st = avformat_new_stream(s, NULL);
203
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 if (!st)
204 return NULL;
205 69 st->codecpar->codec_type = codec_type;
206 69 st->id = track_idx;
207 69 avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
208
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 45 times.
69 if (track_idx)
209 24 return st;
210
211
3/4
✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 39 times.
45 if (s->nb_streams>=3 ||( s->nb_streams==2
212
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 && s->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE
213
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 && s->streams[1]->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE
214
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 && s->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_DATA
215
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 && s->streams[1]->codecpar->codec_type != AVMEDIA_TYPE_DATA))
216 6 s->ctx_flags &= ~AVFMTCTX_NOHEADER;
217
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 33 times.
45 if (codec_type == AVMEDIA_TYPE_AUDIO) {
218 12 st->codecpar->bit_rate = flv->audio_bit_rate;
219 12 si->missing_streams &= ~FLV_HEADER_FLAG_HASAUDIO;
220 }
221
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 12 times.
45 if (codec_type == AVMEDIA_TYPE_VIDEO) {
222 33 st->codecpar->bit_rate = flv->video_bit_rate;
223 33 si->missing_streams &= ~FLV_HEADER_FLAG_HASVIDEO;
224 33 st->avg_frame_rate = flv->framerate;
225 }
226
227 45 flv->last_keyframe_stream_index = s->nb_streams - 1;
228 45 add_keyframes_index(s);
229 45 return st;
230 }
231
232 4905 static int flv_same_audio_codec(AVCodecParameters *apar, int flags, uint32_t codec_fourcc)
233 {
234
2/2
✓ Branch 0 taken 2592 times.
✓ Branch 1 taken 2313 times.
4905 int bits_per_coded_sample = (flags & FLV_AUDIO_SAMPLESIZE_MASK) ? 16 : 8;
235 4905 int flv_codecid = flags & FLV_AUDIO_CODECID_MASK;
236 int codec_id;
237
238
5/8
✓ Branch 0 taken 1110 times.
✓ Branch 1 taken 465 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 165 times.
✓ Branch 4 taken 573 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2592 times.
✗ Branch 7 not taken.
4905 switch (codec_fourcc) {
239 1110 case MKBETAG('m', 'p', '4', 'a'):
240 1110 return apar->codec_id == AV_CODEC_ID_AAC;
241 465 case MKBETAG('O', 'p', 'u', 's'):
242 465 return apar->codec_id == AV_CODEC_ID_OPUS;
243 case MKBETAG('.', 'm', 'p', '3'):
244 return apar->codec_id == AV_CODEC_ID_MP3;
245 165 case MKBETAG('f', 'L', 'a', 'C'):
246 165 return apar->codec_id == AV_CODEC_ID_FLAC;
247 573 case MKBETAG('a', 'c', '-', '3'):
248 573 return apar->codec_id == AV_CODEC_ID_AC3;
249 case MKBETAG('e', 'c', '-', '3'):
250 return apar->codec_id == AV_CODEC_ID_EAC3;
251 2592 case 0:
252 // Not enhanced flv, continue as normal.
253 2592 break;
254 default:
255 // Unknown FOURCC
256 return 0;
257 }
258
259
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2592 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2592 if (!apar->codec_id && !apar->codec_tag)
260 return 1;
261
262
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2592 times.
2592 if (apar->bits_per_coded_sample != bits_per_coded_sample)
263 return 0;
264
265
3/10
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 613 times.
✓ Branch 3 taken 284 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1695 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
2592 switch (flv_codecid) {
266 // no distinction between S16 and S8 PCM codec flags
267 case FLV_CODECID_PCM:
268 codec_id = bits_per_coded_sample == 8
269 ? AV_CODEC_ID_PCM_U8
270 #if HAVE_BIGENDIAN
271 : AV_CODEC_ID_PCM_S16BE;
272 #else
273 : AV_CODEC_ID_PCM_S16LE;
274 #endif
275 return codec_id == apar->codec_id;
276 case FLV_CODECID_PCM_LE:
277 codec_id = bits_per_coded_sample == 8
278 ? AV_CODEC_ID_PCM_U8
279 : AV_CODEC_ID_PCM_S16LE;
280 return codec_id == apar->codec_id;
281 613 case FLV_CODECID_AAC:
282 613 return apar->codec_id == AV_CODEC_ID_AAC;
283 284 case FLV_CODECID_ADPCM:
284 284 return apar->codec_id == AV_CODEC_ID_ADPCM_SWF;
285 case FLV_CODECID_SPEEX:
286 return apar->codec_id == AV_CODEC_ID_SPEEX;
287 case FLV_CODECID_MP3:
288 return apar->codec_id == AV_CODEC_ID_MP3;
289 1695 case FLV_CODECID_NELLYMOSER_8KHZ_MONO:
290 case FLV_CODECID_NELLYMOSER_16KHZ_MONO:
291 case FLV_CODECID_NELLYMOSER:
292 1695 return apar->codec_id == AV_CODEC_ID_NELLYMOSER;
293 case FLV_CODECID_PCM_MULAW:
294 return apar->sample_rate == 8000 &&
295 apar->codec_id == AV_CODEC_ID_PCM_MULAW;
296 case FLV_CODECID_PCM_ALAW:
297 return apar->sample_rate == 8000 &&
298 apar->codec_id == AV_CODEC_ID_PCM_ALAW;
299 default:
300 return apar->codec_tag == (flv_codecid >> FLV_AUDIO_CODECID_OFFSET);
301 }
302 }
303
304 2616 static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream,
305 AVCodecParameters *apar, int flv_codecid)
306 {
307
8/18
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 618 times.
✓ Branch 3 taken 288 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 376 times.
✓ Branch 8 taken 1322 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 3 times.
✓ Branch 12 taken 3 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 3 times.
✓ Branch 15 taken 3 times.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
2616 switch (flv_codecid) {
308 // no distinction between S16 and S8 PCM codec flags
309 case FLV_CODECID_PCM:
310 apar->codec_id = apar->bits_per_coded_sample == 8
311 ? AV_CODEC_ID_PCM_U8
312 #if HAVE_BIGENDIAN
313 : AV_CODEC_ID_PCM_S16BE;
314 #else
315 : AV_CODEC_ID_PCM_S16LE;
316 #endif
317 break;
318 case FLV_CODECID_PCM_LE:
319 apar->codec_id = apar->bits_per_coded_sample == 8
320 ? AV_CODEC_ID_PCM_U8
321 : AV_CODEC_ID_PCM_S16LE;
322 break;
323 618 case FLV_CODECID_AAC:
324 618 apar->codec_id = AV_CODEC_ID_AAC;
325 618 break;
326 288 case FLV_CODECID_ADPCM:
327 288 apar->codec_id = AV_CODEC_ID_ADPCM_SWF;
328 288 break;
329 case FLV_CODECID_SPEEX:
330 apar->codec_id = AV_CODEC_ID_SPEEX;
331 apar->sample_rate = 16000;
332 break;
333 case FLV_CODECID_MP3:
334 apar->codec_id = AV_CODEC_ID_MP3;
335 ffstream(astream)->need_parsing = AVSTREAM_PARSE_FULL;
336 break;
337 case FLV_CODECID_NELLYMOSER_8KHZ_MONO:
338 // in case metadata does not otherwise declare samplerate
339 apar->sample_rate = 8000;
340 apar->codec_id = AV_CODEC_ID_NELLYMOSER;
341 break;
342 376 case FLV_CODECID_NELLYMOSER_16KHZ_MONO:
343 376 apar->sample_rate = 16000;
344 376 apar->codec_id = AV_CODEC_ID_NELLYMOSER;
345 376 break;
346 1322 case FLV_CODECID_NELLYMOSER:
347 1322 apar->codec_id = AV_CODEC_ID_NELLYMOSER;
348 1322 break;
349 case FLV_CODECID_PCM_MULAW:
350 apar->sample_rate = 8000;
351 apar->codec_id = AV_CODEC_ID_PCM_MULAW;
352 break;
353 case FLV_CODECID_PCM_ALAW:
354 apar->sample_rate = 8000;
355 apar->codec_id = AV_CODEC_ID_PCM_ALAW;
356 break;
357 3 case MKBETAG('m', 'p', '4', 'a'):
358 3 apar->codec_id = AV_CODEC_ID_AAC;
359 3 return;
360 3 case MKBETAG('O', 'p', 'u', 's'):
361 3 apar->codec_id = AV_CODEC_ID_OPUS;
362 3 apar->sample_rate = 48000;
363 3 return;
364 case MKBETAG('.', 'm', 'p', '3'):
365 apar->codec_id = AV_CODEC_ID_MP3;
366 return;
367 3 case MKBETAG('f', 'L', 'a', 'C'):
368 3 apar->codec_id = AV_CODEC_ID_FLAC;
369 3 return;
370 3 case MKBETAG('a', 'c', '-', '3'):
371 3 apar->codec_id = AV_CODEC_ID_AC3;
372 3 return;
373 case MKBETAG('e', 'c', '-', '3'):
374 apar->codec_id = AV_CODEC_ID_EAC3;
375 return;
376 default:
377 avpriv_request_sample(s, "Audio codec (%x)",
378 flv_codecid >> FLV_AUDIO_CODECID_OFFSET);
379 apar->codec_tag = flv_codecid >> FLV_AUDIO_CODECID_OFFSET;
380 }
381 }
382
383 3967 static int flv_same_video_codec(AVCodecParameters *vpar, uint32_t flv_codecid)
384 {
385
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3967 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3967 if (!vpar->codec_id && !vpar->codec_tag)
386 return 1;
387
388
8/10
✓ Branch 0 taken 552 times.
✓ Branch 1 taken 330 times.
✓ Branch 2 taken 229 times.
✓ Branch 3 taken 493 times.
✓ Branch 4 taken 271 times.
✓ Branch 5 taken 196 times.
✓ Branch 6 taken 173 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1723 times.
✗ Branch 9 not taken.
3967 switch (flv_codecid) {
389 552 case FLV_CODECID_X_HEVC:
390 case MKBETAG('h', 'v', 'c', '1'):
391 552 return vpar->codec_id == AV_CODEC_ID_HEVC;
392 330 case MKBETAG('a', 'v', '0', '1'):
393 330 return vpar->codec_id == AV_CODEC_ID_AV1;
394 229 case MKBETAG('v', 'p', '0', '9'):
395 229 return vpar->codec_id == AV_CODEC_ID_VP9;
396 493 case FLV_CODECID_H263:
397 493 return vpar->codec_id == AV_CODEC_ID_FLV1;
398 271 case FLV_CODECID_SCREEN:
399 271 return vpar->codec_id == AV_CODEC_ID_FLASHSV;
400 196 case FLV_CODECID_SCREEN2:
401 196 return vpar->codec_id == AV_CODEC_ID_FLASHSV2;
402 173 case FLV_CODECID_VP6:
403 173 return vpar->codec_id == AV_CODEC_ID_VP6F;
404 case FLV_CODECID_VP6A:
405 return vpar->codec_id == AV_CODEC_ID_VP6A;
406 1723 case FLV_CODECID_H264:
407 case MKBETAG('a', 'v', 'c', '1'):
408 1723 return vpar->codec_id == AV_CODEC_ID_H264;
409 default:
410 return vpar->codec_tag == flv_codecid;
411 }
412 }
413
414 2655 static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
415 uint32_t flv_codecid, int read)
416 {
417 2655 FFStream *const vstreami = ffstream(vstream);
418 2655 int ret = 0;
419 2655 AVCodecParameters *par = vstream->codecpar;
420 2655 enum AVCodecID old_codec_id = vstream->codecpar->codec_id;
421
422
8/12
✓ Branch 0 taken 227 times.
✓ Branch 1 taken 176 times.
✓ Branch 2 taken 122 times.
✓ Branch 3 taken 503 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 276 times.
✓ Branch 6 taken 200 times.
✓ Branch 7 taken 174 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 977 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
2655 switch (flv_codecid) {
423 227 case FLV_CODECID_X_HEVC:
424 case MKBETAG('h', 'v', 'c', '1'):
425 227 par->codec_id = AV_CODEC_ID_HEVC;
426 227 vstreami->need_parsing = AVSTREAM_PARSE_HEADERS;
427 227 break;
428 176 case MKBETAG('a', 'v', '0', '1'):
429 176 par->codec_id = AV_CODEC_ID_AV1;
430 176 vstreami->need_parsing = AVSTREAM_PARSE_HEADERS;
431 176 break;
432 122 case MKBETAG('v', 'p', '0', '9'):
433 122 par->codec_id = AV_CODEC_ID_VP9;
434 122 vstreami->need_parsing = AVSTREAM_PARSE_HEADERS;
435 122 break;
436 503 case FLV_CODECID_H263:
437 503 par->codec_id = AV_CODEC_ID_FLV1;
438 503 break;
439 case FLV_CODECID_REALH263:
440 par->codec_id = AV_CODEC_ID_H263;
441 break; // Really mean it this time
442 276 case FLV_CODECID_SCREEN:
443 276 par->codec_id = AV_CODEC_ID_FLASHSV;
444 276 break;
445 200 case FLV_CODECID_SCREEN2:
446 200 par->codec_id = AV_CODEC_ID_FLASHSV2;
447 200 break;
448 174 case FLV_CODECID_VP6:
449 174 par->codec_id = AV_CODEC_ID_VP6F;
450 174 case FLV_CODECID_VP6A:
451
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 174 times.
174 if (flv_codecid == FLV_CODECID_VP6A)
452 par->codec_id = AV_CODEC_ID_VP6A;
453
1/2
✓ Branch 0 taken 174 times.
✗ Branch 1 not taken.
174 if (read) {
454
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 173 times.
174 if (par->extradata_size != 1) {
455 1 ff_alloc_extradata(par, 1);
456 }
457
1/2
✓ Branch 0 taken 174 times.
✗ Branch 1 not taken.
174 if (par->extradata)
458 174 par->extradata[0] = avio_r8(s->pb);
459 else
460 avio_skip(s->pb, 1);
461 }
462 174 ret = 1; // 1 byte body size adjustment for flv_read_packet()
463 174 break;
464 977 case FLV_CODECID_H264:
465 case MKBETAG('a', 'v', 'c', '1'):
466 977 par->codec_id = AV_CODEC_ID_H264;
467 977 vstreami->need_parsing = AVSTREAM_PARSE_HEADERS;
468 977 break;
469 case FLV_CODECID_MPEG4:
470 par->codec_id = AV_CODEC_ID_MPEG4;
471 break;
472 default:
473 avpriv_request_sample(s, "Video codec (%x)", flv_codecid);
474 par->codec_tag = flv_codecid;
475 }
476
477
3/4
✓ Branch 0 taken 2587 times.
✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2587 times.
2655 if (!vstreami->need_context_update && par->codec_id != old_codec_id) {
478 avpriv_request_sample(s, "Changing the codec id midstream");
479 return AVERROR_PATCHWELCOME;
480 }
481
482 2655 return ret;
483 }
484
485 574 static int amf_get_string(AVIOContext *ioc, char *buffer, int buffsize)
486 {
487 int ret;
488 574 int length = avio_rb16(ioc);
489
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 574 times.
574 if (length >= buffsize) {
490 avio_skip(ioc, length);
491 return AVERROR_INVALIDDATA;
492 }
493
494 574 ret = avio_read(ioc, buffer, length);
495
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 574 times.
574 if (ret < 0)
496 return ret;
497
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 574 times.
574 if (ret < length)
498 return AVERROR_INVALIDDATA;
499
500 574 buffer[length] = '\0';
501
502 574 return length;
503 }
504
505 3 static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, int64_t max_pos)
506 {
507 3 FLVContext *flv = s->priv_data;
508 3 unsigned int timeslen = 0, fileposlen = 0, i;
509 char str_val[256];
510 3 int64_t *times = NULL;
511 3 int64_t *filepositions = NULL;
512 3 int ret = AVERROR(ENOSYS);
513 3 int64_t initial_pos = avio_tell(ioc);
514
515
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (flv->keyframe_count > 0) {
516 av_log(s, AV_LOG_DEBUG, "keyframes have been parsed\n");
517 return 0;
518 }
519
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 av_assert0(!flv->keyframe_times);
520
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 av_assert0(!flv->keyframe_filepositions);
521
522
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (s->flags & AVFMT_FLAG_IGNIDX)
523 return 0;
524
525
2/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
12 while (avio_tell(ioc) < max_pos - 2 &&
526 6 amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {
527 int64_t **current_array;
528 unsigned int arraylen;
529 int factor;
530
531 // Expect array object in context
532
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (avio_r8(ioc) != AMF_DATA_TYPE_ARRAY)
533 break;
534
535 6 arraylen = avio_rb32(ioc);
536
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (arraylen>>28)
537 break;
538
539
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
6 if (!strcmp(KEYFRAMES_TIMESTAMP_TAG , str_val) && !times) {
540 3 current_array = &times;
541 3 timeslen = arraylen;
542 3 factor = 1000;
543
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 } else if (!strcmp(KEYFRAMES_BYTEOFFSET_TAG, str_val) &&
544
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 !filepositions) {
545 3 current_array = &filepositions;
546 3 fileposlen = arraylen;
547 3 factor = 1;
548 } else
549 // unexpected metatag inside keyframes, will not use such
550 // metadata for indexing
551 break;
552
553
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (!(*current_array = av_mallocz(sizeof(**current_array) * arraylen))) {
554 ret = AVERROR(ENOMEM);
555 goto finish;
556 }
557
558
3/4
✓ Branch 0 taken 346 times.
✓ Branch 1 taken 6 times.
✓ Branch 3 taken 346 times.
✗ Branch 4 not taken.
352 for (i = 0; i < arraylen && avio_tell(ioc) < max_pos - 1; i++) {
559 double d;
560
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 346 times.
346 if (avio_r8(ioc) != AMF_DATA_TYPE_NUMBER)
561 goto invalid;
562 346 d = av_int2double(avio_rb64(ioc)) * factor;
563
3/6
✓ Branch 0 taken 346 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 346 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 346 times.
346 if (isnan(d) || d < INT64_MIN || d > INT64_MAX)
564 goto invalid;
565
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 346 times.
346 if (avio_feof(ioc))
566 goto invalid;
567 346 current_array[0][i] = d;
568 }
569
4/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
6 if (times && filepositions) {
570 // All done, exiting at a position allowing amf_parse_object
571 // to finish parsing the object
572 3 ret = 0;
573 3 break;
574 }
575 }
576
577
3/6
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
3 if (timeslen == fileposlen && fileposlen>1 && max_pos <= filepositions[0]) {
578
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
9 for (i = 0; i < FFMIN(2,fileposlen); i++) {
579 6 flv->validate_index[i].pos = filepositions[i];
580 6 flv->validate_index[i].dts = times[i];
581 6 flv->validate_count = i + 1;
582 }
583 3 flv->keyframe_times = times;
584 3 flv->keyframe_filepositions = filepositions;
585 3 flv->keyframe_count = timeslen;
586 3 times = NULL;
587 3 filepositions = NULL;
588 } else {
589 invalid:
590 av_log(s, AV_LOG_WARNING, "Invalid keyframes object, skipping.\n");
591 }
592
593 3 finish:
594 3 av_freep(&times);
595 3 av_freep(&filepositions);
596 3 avio_seek(ioc, initial_pos, SEEK_SET);
597 3 return ret;
598 }
599
600 812 static int amf_parse_object(AVFormatContext *s, AVStream *astream,
601 AVStream *vstream, const char *key,
602 int64_t max_pos, int depth)
603 {
604 AVCodecParameters *apar, *vpar;
605 812 FLVContext *flv = s->priv_data;
606 AVIOContext *ioc;
607 AMFDataType amf_type;
608 char str_val[1024];
609 double num_val;
610 amf_date date;
611
612
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812 times.
812 if (depth > MAX_DEPTH)
613 return AVERROR_PATCHWELCOME;
614
615 812 num_val = 0;
616 812 ioc = s->pb;
617
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 812 times.
812 if (avio_feof(ioc))
618 return AVERROR_EOF;
619 812 amf_type = avio_r8(ioc);
620
621
7/9
✓ Branch 0 taken 675 times.
✓ Branch 1 taken 27 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 35 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 39 times.
✓ Branch 6 taken 7 times.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
812 switch (amf_type) {
622 675 case AMF_DATA_TYPE_NUMBER:
623 675 num_val = av_int2double(avio_rb64(ioc));
624 675 break;
625 27 case AMF_DATA_TYPE_BOOL:
626 27 num_val = avio_r8(ioc);
627 27 break;
628 28 case AMF_DATA_TYPE_STRING:
629
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
28 if (amf_get_string(ioc, str_val, sizeof(str_val)) < 0) {
630 av_log(s, AV_LOG_ERROR, "AMF_DATA_TYPE_STRING parsing failed\n");
631 return -1;
632 }
633 28 break;
634 35 case AMF_DATA_TYPE_OBJECT:
635
1/2
✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
35 if (key &&
636
1/2
✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
35 (ioc->seekable & AVIO_SEEKABLE_NORMAL) &&
637
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
35 !strcmp(KEYFRAMES_TAG, key) && depth == 1)
638
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (parse_keyframes_index(s, ioc, max_pos) < 0)
639 av_log(s, AV_LOG_ERROR, "Keyframe index parsing failed\n");
640 else
641 3 add_keyframes_index(s);
642
3/4
✓ Branch 1 taken 82 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 47 times.
✓ Branch 4 taken 35 times.
164 while (avio_tell(ioc) < max_pos - 2 &&
643 82 amf_get_string(ioc, str_val, sizeof(str_val)) > 0)
644
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 47 times.
47 if (amf_parse_object(s, astream, vstream, str_val, max_pos,
645 depth + 1) < 0)
646 return -1; // if we couldn't skip, bomb out.
647
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 35 times.
35 if (avio_r8(ioc) != AMF_END_OF_OBJECT) {
648 av_log(s, AV_LOG_ERROR, "Missing AMF_END_OF_OBJECT in AMF_DATA_TYPE_OBJECT\n");
649 return -1;
650 }
651 35 break;
652 case AMF_DATA_TYPE_NULL:
653 case AMF_DATA_TYPE_UNDEFINED:
654 case AMF_DATA_TYPE_UNSUPPORTED:
655 break; // these take up no additional space
656 39 case AMF_DATA_TYPE_MIXEDARRAY:
657 {
658 unsigned v;
659 39 avio_skip(ioc, 4); // skip 32-bit max array index
660
3/4
✓ Branch 1 taken 404 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 365 times.
✓ Branch 4 taken 39 times.
808 while (avio_tell(ioc) < max_pos - 2 &&
661 404 amf_get_string(ioc, str_val, sizeof(str_val)) > 0)
662 // this is the only case in which we would want a nested
663 // parse to not skip over the object
664
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 365 times.
365 if (amf_parse_object(s, astream, vstream, str_val, max_pos,
665 depth + 1) < 0)
666 return -1;
667 39 v = avio_r8(ioc);
668
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 if (v != AMF_END_OF_OBJECT) {
669 av_log(s, AV_LOG_ERROR, "Missing AMF_END_OF_OBJECT in AMF_DATA_TYPE_MIXEDARRAY, found %d\n", v);
670 return -1;
671 }
672 39 break;
673 }
674 7 case AMF_DATA_TYPE_ARRAY:
675 {
676 unsigned int arraylen, i;
677
678 7 arraylen = avio_rb32(ioc);
679
3/4
✓ Branch 0 taken 346 times.
✓ Branch 1 taken 7 times.
✓ Branch 3 taken 346 times.
✗ Branch 4 not taken.
353 for (i = 0; i < arraylen && avio_tell(ioc) < max_pos - 1; i++)
680
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 346 times.
346 if (amf_parse_object(s, NULL, NULL, NULL, max_pos,
681 depth + 1) < 0)
682 return -1; // if we couldn't skip, bomb out.
683 }
684 7 break;
685 1 case AMF_DATA_TYPE_DATE:
686 // timestamp (double) and UTC offset (int16)
687 1 date.milliseconds = av_int2double(avio_rb64(ioc));
688 1 date.timezone = avio_rb16(ioc);
689 1 break;
690 default: // unsupported type, we couldn't skip
691 av_log(s, AV_LOG_ERROR, "unsupported amf type %d\n", amf_type);
692 return -1;
693 }
694
695
2/2
✓ Branch 0 taken 466 times.
✓ Branch 1 taken 346 times.
812 if (key) {
696
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 466 times.
466 apar = astream ? astream->codecpar : NULL;
697
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 466 times.
466 vpar = vstream ? vstream->codecpar : NULL;
698
699 // stream info doesn't live any deeper than the first object
700
2/2
✓ Branch 0 taken 382 times.
✓ Branch 1 taken 84 times.
466 if (depth == 1) {
701
4/4
✓ Branch 0 taken 77 times.
✓ Branch 1 taken 305 times.
✓ Branch 2 taken 27 times.
✓ Branch 3 taken 50 times.
382 if (amf_type == AMF_DATA_TYPE_NUMBER ||
702 amf_type == AMF_DATA_TYPE_BOOL) {
703
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 293 times.
332 if (!strcmp(key, "duration"))
704 39 s->duration = num_val * AV_TIME_BASE;
705
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 260 times.
293 else if (!strcmp(key, "videodatarate") &&
706
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 0 <= (int)(num_val * 1024.0))
707 33 flv->video_bit_rate = num_val * 1024.0;
708
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 248 times.
260 else if (!strcmp(key, "audiodatarate") &&
709
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 0 <= (int)(num_val * 1024.0))
710 12 flv->audio_bit_rate = num_val * 1024.0;
711
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 217 times.
248 else if (!strcmp(key, "framerate")) {
712 31 flv->framerate = av_d2q(num_val, 1000);
713
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if (vstream)
714 vstream->avg_frame_rate = flv->framerate;
715
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 217 times.
217 } else if (flv->trust_metadata) {
716 if (!strcmp(key, "videocodecid") && vpar) {
717 int ret = flv_set_video_codec(s, vstream, num_val, 0);
718 if (ret < 0)
719 return ret;
720 } else if (!strcmp(key, "audiocodecid") && apar) {
721 int id = ((int)num_val) << FLV_AUDIO_CODECID_OFFSET;
722 flv_set_audio_codec(s, astream, apar, id);
723 } else if (!strcmp(key, "audiosamplerate") && apar) {
724 apar->sample_rate = num_val;
725 } else if (!strcmp(key, "audiosamplesize") && apar) {
726 apar->bits_per_coded_sample = num_val;
727 } else if (!strcmp(key, "stereo") && apar) {
728 av_channel_layout_default(&apar->ch_layout, num_val + 1);
729 } else if (!strcmp(key, "width") && vpar) {
730 vpar->width = num_val;
731 } else if (!strcmp(key, "height") && vpar) {
732 vpar->height = num_val;
733 } else if (!strcmp(key, "datastream")) {
734 AVStream *st = create_stream(s, AVMEDIA_TYPE_SUBTITLE, 0);
735 if (!st)
736 return AVERROR(ENOMEM);
737 st->codecpar->codec_id = AV_CODEC_ID_TEXT;
738 }
739 }
740 }
741
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 354 times.
382 if (amf_type == AMF_DATA_TYPE_STRING) {
742
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 24 times.
28 if (!strcmp(key, "encoder")) {
743 4 int version = -1;
744
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (1 == sscanf(str_val, "Open Broadcaster Software v0.%d", &version)) {
745 if (version > 0 && version <= 655)
746 flv->broken_sizes = 1;
747 }
748
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 23 times.
24 } else if (!strcmp(key, "metadatacreator")) {
749
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if ( !strcmp (str_val, "MEGA")
750
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 || !strncmp(str_val, "FlixEngine", 10))
751 flv->broken_sizes = 1;
752 }
753 }
754 }
755
756
4/4
✓ Branch 0 taken 329 times.
✓ Branch 1 taken 137 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 305 times.
466 if (amf_type == AMF_DATA_TYPE_NUMBER && flv->meta_color_info_flag == FLV_COLOR_INFO_FLAG_PARSING) {
757 24 FLVMetaVideoColor *meta_video_color = &flv->meta_color_info;
758
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 20 times.
24 if (!strcmp(key, "colorPrimaries")) {
759 4 meta_video_color->primaries = num_val;
760
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 16 times.
20 } else if (!strcmp(key, "transferCharacteristics")) {
761 4 meta_video_color->trc = num_val;
762
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 12 times.
16 } else if (!strcmp(key, "matrixCoefficients")) {
763 4 meta_video_color->matrix_coefficients = num_val;
764
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 11 times.
12 } else if (!strcmp(key, "maxFall")) {
765 1 meta_video_color->max_fall = num_val;
766
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 10 times.
11 } else if (!strcmp(key, "maxCLL")) {
767 1 meta_video_color->max_cll = num_val;
768
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 9 times.
10 } else if (!strcmp(key, "redX")) {
769 1 meta_video_color->mastering_meta.r_x = num_val;
770
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8 times.
9 } else if (!strcmp(key, "redY")) {
771 1 meta_video_color->mastering_meta.r_y = num_val;
772
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
8 } else if (!strcmp(key, "greenX")) {
773 1 meta_video_color->mastering_meta.g_x = num_val;
774
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
7 } else if (!strcmp(key, "greenY")) {
775 1 meta_video_color->mastering_meta.g_y = num_val;
776
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 } else if (!strcmp(key, "blueX")) {
777 1 meta_video_color->mastering_meta.b_x = num_val;
778
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
5 } else if (!strcmp(key, "blueY")) {
779 1 meta_video_color->mastering_meta.b_y = num_val;
780
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 } else if (!strcmp(key, "whitePointX")) {
781 1 meta_video_color->mastering_meta.white_x = num_val;
782
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 } else if (!strcmp(key, "whitePointY")) {
783 1 meta_video_color->mastering_meta.white_y = num_val;
784
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 } else if (!strcmp(key, "maxLuminance")) {
785 1 meta_video_color->mastering_meta.max_luminance = num_val;
786
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 } else if (!strcmp(key, "minLuminance")) {
787 1 meta_video_color->mastering_meta.min_luminance = num_val;
788 }
789 }
790
791
5/6
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 431 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 23 times.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
466 if (amf_type == AMF_DATA_TYPE_OBJECT && s->nb_streams == 1 &&
792
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 ((!apar && !strcmp(key, "audiocodecid")) ||
793
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 (!vpar && !strcmp(key, "videocodecid"))))
794 s->ctx_flags &= ~AVFMTCTX_NOHEADER; //If there is either audio/video missing, codecid will be an empty object
795
796
2/2
✓ Branch 0 taken 427 times.
✓ Branch 1 taken 39 times.
466 if ((!strcmp(key, "duration") ||
797
2/2
✓ Branch 0 taken 389 times.
✓ Branch 1 taken 38 times.
427 !strcmp(key, "filesize") ||
798
2/2
✓ Branch 0 taken 356 times.
✓ Branch 1 taken 33 times.
389 !strcmp(key, "width") ||
799
2/2
✓ Branch 0 taken 323 times.
✓ Branch 1 taken 33 times.
356 !strcmp(key, "height") ||
800
2/2
✓ Branch 0 taken 290 times.
✓ Branch 1 taken 33 times.
323 !strcmp(key, "videodatarate") ||
801
2/2
✓ Branch 0 taken 259 times.
✓ Branch 1 taken 31 times.
290 !strcmp(key, "framerate") ||
802
2/2
✓ Branch 0 taken 226 times.
✓ Branch 1 taken 33 times.
259 !strcmp(key, "videocodecid") ||
803
2/2
✓ Branch 0 taken 214 times.
✓ Branch 1 taken 12 times.
226 !strcmp(key, "audiodatarate") ||
804
2/2
✓ Branch 0 taken 203 times.
✓ Branch 1 taken 11 times.
214 !strcmp(key, "audiosamplerate") ||
805
2/2
✓ Branch 0 taken 192 times.
✓ Branch 1 taken 11 times.
203 !strcmp(key, "audiosamplesize") ||
806
2/2
✓ Branch 0 taken 181 times.
✓ Branch 1 taken 11 times.
192 !strcmp(key, "stereo") ||
807
2/2
✓ Branch 0 taken 169 times.
✓ Branch 1 taken 12 times.
181 !strcmp(key, "audiocodecid") ||
808
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 169 times.
✓ Branch 2 taken 297 times.
✗ Branch 3 not taken.
466 !strcmp(key, "datastream")) && !flv->dump_full_metadata)
809 297 return 0;
810
811 169 s->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
812
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 153 times.
169 if (amf_type == AMF_DATA_TYPE_BOOL) {
813
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
16 av_strlcpy(str_val, num_val > 0 ? "true" : "false",
814 sizeof(str_val));
815 16 av_dict_set(&s->metadata, key, str_val, 0);
816
2/2
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 110 times.
153 } else if (amf_type == AMF_DATA_TYPE_NUMBER) {
817 43 snprintf(str_val, sizeof(str_val), "%.f", num_val);
818 43 av_dict_set(&s->metadata, key, str_val, 0);
819
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 82 times.
110 } else if (amf_type == AMF_DATA_TYPE_STRING) {
820 28 av_dict_set(&s->metadata, key, str_val, 0);
821
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 81 times.
82 } else if ( amf_type == AMF_DATA_TYPE_DATE
822
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 && isfinite(date.milliseconds)
823
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 && date.milliseconds > INT64_MIN/1000
824
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 && date.milliseconds < INT64_MAX/1000
825 ) {
826 // timezone is ignored, since there is no easy way to offset the UTC
827 // timestamp into the specified timezone
828 1 ff_dict_set_timestamp(&s->metadata, key, 1000 * (int64_t)date.milliseconds);
829 }
830 }
831
832 515 return 0;
833 }
834
835 #define TYPE_ONTEXTDATA 1
836 #define TYPE_ONCAPTION 2
837 #define TYPE_ONCAPTIONINFO 3
838 #define TYPE_UNKNOWN 9
839
840 39 static int flv_read_metabody(AVFormatContext *s, int64_t next_pos)
841 {
842 39 FLVContext *flv = s->priv_data;
843 AMFDataType type;
844 AVStream *stream, *astream, *vstream;
845 AVStream av_unused *dstream;
846 AVIOContext *ioc;
847 int i;
848 char buffer[32];
849
850 39 astream = NULL;
851 39 vstream = NULL;
852 39 dstream = NULL;
853 39 ioc = s->pb;
854
855 // first object needs to be "onMetaData" string
856 39 type = avio_r8(ioc);
857
2/4
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 39 times.
78 if (type != AMF_DATA_TYPE_STRING ||
858 39 amf_get_string(ioc, buffer, sizeof(buffer)) < 0)
859 return TYPE_UNKNOWN;
860
861
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 if (!strcmp(buffer, "onTextData"))
862 return TYPE_ONTEXTDATA;
863
864
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 if (!strcmp(buffer, "onCaption"))
865 return TYPE_ONCAPTION;
866
867
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 if (!strcmp(buffer, "onCaptionInfo"))
868 return TYPE_ONCAPTIONINFO;
869
870
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
39 if (strcmp(buffer, "onMetaData") && strcmp(buffer, "onCuePoint") && strcmp(buffer, "|RtmpSampleAccess")) {
871 av_log(s, AV_LOG_DEBUG, "Unknown type %s\n", buffer);
872 return TYPE_UNKNOWN;
873 }
874
875 // find the streams now so that amf_parse_object doesn't need to do
876 // the lookup every time it is called.
877
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 for (i = 0; i < s->nb_streams; i++) {
878 stream = s->streams[i];
879 if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
880 vstream = stream;
881 flv->last_keyframe_stream_index = i;
882 } else if (stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
883 astream = stream;
884 if (flv->last_keyframe_stream_index == -1)
885 flv->last_keyframe_stream_index = i;
886 } else if (stream->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
887 dstream = stream;
888 }
889
890 // parse the second object (we want a mixed array)
891
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
39 if (amf_parse_object(s, astream, vstream, buffer, next_pos, 0) < 0)
892 return -1;
893
894 39 return 0;
895 }
896
897 39 static int flv_read_header(AVFormatContext *s)
898 {
899 39 FFFormatContext *const si = ffformatcontext(s);
900 int flags;
901 39 FLVContext *flv = s->priv_data;
902 int offset;
903 39 int pre_tag_size = 0;
904
905 /* Actual FLV data at 0xe40000 in KUX file */
906
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 if(!strcmp(s->iformat->name, "kux"))
907 avio_skip(s->pb, 0xe40000);
908
909 39 avio_skip(s->pb, 4);
910 39 flags = avio_r8(s->pb);
911
912 39 si->missing_streams = flags & (FLV_HEADER_FLAG_HASVIDEO | FLV_HEADER_FLAG_HASAUDIO);
913
914 39 s->ctx_flags |= AVFMTCTX_NOHEADER;
915
916 39 offset = avio_rb32(s->pb);
917 39 avio_seek(s->pb, offset, SEEK_SET);
918
919 /* Annex E. The FLV File Format
920 * E.3 TheFLVFileBody
921 * Field Type Comment
922 * PreviousTagSize0 UI32 Always 0
923 * */
924 39 pre_tag_size = avio_rb32(s->pb);
925
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 if (pre_tag_size) {
926 av_log(s, AV_LOG_WARNING, "Read FLV header error, input file is not a standard flv format, first PreviousTagSize0 always is 0\n");
927 }
928
929 39 s->start_time = 0;
930 39 flv->sum_flv_tag_size = 0;
931 39 flv->last_keyframe_stream_index = -1;
932
933 39 return 0;
934 }
935
936 39 static int flv_read_close(AVFormatContext *s)
937 {
938 int i;
939 39 FLVContext *flv = s->priv_data;
940
2/2
✓ Branch 0 taken 156 times.
✓ Branch 1 taken 39 times.
195 for (i = 0; i < FLV_STREAM_TYPE_NB; i++)
941 156 av_freep(&flv->new_extradata[i]);
942
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 39 times.
42 for (i = 0; i < flv->mt_extradata_cnt; i++)
943 3 av_freep(&flv->mt_extradata[i]);
944 39 av_freep(&flv->mt_extradata);
945 39 av_freep(&flv->mt_extradata_sz);
946 39 av_freep(&flv->keyframe_times);
947 39 av_freep(&flv->keyframe_filepositions);
948 39 return 0;
949 }
950
951 39 static int flv_get_extradata(AVFormatContext *s, AVStream *st, int size)
952 {
953 int ret;
954
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
39 if (!size)
955 return 0;
956
957
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
39 if ((ret = ff_get_extradata(s, st->codecpar, s->pb, size)) < 0)
958 return ret;
959 39 ffstream(st)->need_context_update = 1;
960 39 return 0;
961 }
962
963 3 static int flv_queue_extradata(FLVContext *flv, AVIOContext *pb, int stream,
964 int size, int multitrack)
965 {
966
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!size)
967 return 0;
968
969
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (!multitrack) {
970 2 av_free(flv->new_extradata[stream]);
971 2 flv->new_extradata[stream] = av_mallocz(size +
972 AV_INPUT_BUFFER_PADDING_SIZE);
973
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!flv->new_extradata[stream])
974 return AVERROR(ENOMEM);
975 2 flv->new_extradata_size[stream] = size;
976 2 avio_read(pb, flv->new_extradata[stream], size);
977 } else {
978 1 int new_count = stream + 1;
979
980
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (flv->mt_extradata_cnt < new_count) {
981 1 void *tmp = av_realloc_array(flv->mt_extradata, new_count,
982 sizeof(*flv->mt_extradata));
983
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!tmp)
984 return AVERROR(ENOMEM);
985 1 flv->mt_extradata = tmp;
986
987 1 tmp = av_realloc_array(flv->mt_extradata_sz, new_count,
988 sizeof(*flv->mt_extradata_sz));
989
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!tmp)
990 return AVERROR(ENOMEM);
991 1 flv->mt_extradata_sz = tmp;
992
993 // Set newly allocated pointers/sizes to 0
994
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 for (int i = flv->mt_extradata_cnt; i < new_count; i++) {
995 3 flv->mt_extradata[i] = NULL;
996 3 flv->mt_extradata_sz[i] = 0;
997 }
998 1 flv->mt_extradata_cnt = new_count;
999 }
1000
1001 1 av_free(flv->mt_extradata[stream]);
1002 1 flv->mt_extradata[stream] = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE);
1003
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!flv->mt_extradata[stream])
1004 return AVERROR(ENOMEM);
1005 1 flv->mt_extradata_sz[stream] = size;
1006 1 avio_read(pb, flv->mt_extradata[stream], size);
1007 }
1008
1009 3 return 0;
1010 }
1011
1012 1 static void clear_index_entries(AVFormatContext *s, int64_t pos)
1013 {
1014 1 av_log(s, AV_LOG_WARNING,
1015 "Found invalid index entries, clearing the index.\n");
1016
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 for (unsigned i = 0; i < s->nb_streams; i++) {
1017 1 FFStream *const sti = ffstream(s->streams[i]);
1018 1 int out = 0;
1019 /* Remove all index entries that point to >= pos */
1020
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 1 times.
133 for (int j = 0; j < sti->nb_index_entries; j++)
1021
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 131 times.
132 if (sti->index_entries[j].pos < pos)
1022 1 sti->index_entries[out++] = sti->index_entries[j];
1023 1 sti->nb_index_entries = out;
1024 }
1025 1 }
1026
1027 static int amf_skip_tag(AVIOContext *pb, AMFDataType type, int depth)
1028 {
1029 int nb = -1, ret, parse_name = 1;
1030
1031 if (depth > MAX_DEPTH)
1032 return AVERROR_PATCHWELCOME;
1033
1034 if (avio_feof(pb))
1035 return AVERROR_EOF;
1036
1037 switch (type) {
1038 case AMF_DATA_TYPE_NUMBER:
1039 avio_skip(pb, 8);
1040 break;
1041 case AMF_DATA_TYPE_BOOL:
1042 avio_skip(pb, 1);
1043 break;
1044 case AMF_DATA_TYPE_STRING:
1045 avio_skip(pb, avio_rb16(pb));
1046 break;
1047 case AMF_DATA_TYPE_ARRAY:
1048 parse_name = 0;
1049 case AMF_DATA_TYPE_MIXEDARRAY:
1050 nb = avio_rb32(pb);
1051 if (nb < 0)
1052 return AVERROR_INVALIDDATA;
1053 case AMF_DATA_TYPE_OBJECT:
1054 while(!pb->eof_reached && (nb-- > 0 || type != AMF_DATA_TYPE_ARRAY)) {
1055 if (parse_name) {
1056 int size = avio_rb16(pb);
1057 if (!size) {
1058 avio_skip(pb, 1);
1059 break;
1060 }
1061 avio_skip(pb, size);
1062 }
1063 if ((ret = amf_skip_tag(pb, avio_r8(pb), depth + 1)) < 0)
1064 return ret;
1065 }
1066 break;
1067 case AMF_DATA_TYPE_NULL:
1068 case AMF_DATA_TYPE_OBJECT_END:
1069 break;
1070 default:
1071 return AVERROR_INVALIDDATA;
1072 }
1073 return 0;
1074 }
1075
1076 static int flv_data_packet(AVFormatContext *s, AVPacket *pkt,
1077 int64_t dts, int64_t next)
1078 {
1079 AVIOContext *pb = s->pb;
1080 AVStream *st = NULL;
1081 char buf[20];
1082 int ret = AVERROR_INVALIDDATA;
1083 int i, length = -1;
1084 int array = 0;
1085
1086 switch (avio_r8(pb)) {
1087 case AMF_DATA_TYPE_ARRAY:
1088 array = 1;
1089 case AMF_DATA_TYPE_MIXEDARRAY:
1090 avio_seek(pb, 4, SEEK_CUR);
1091 case AMF_DATA_TYPE_OBJECT:
1092 break;
1093 default:
1094 goto skip;
1095 }
1096
1097 while (array || (ret = amf_get_string(pb, buf, sizeof(buf))) > 0) {
1098 AMFDataType type = avio_r8(pb);
1099 if (type == AMF_DATA_TYPE_STRING && (array || !strcmp(buf, "text"))) {
1100 length = avio_rb16(pb);
1101 ret = av_get_packet(pb, pkt, length);
1102 if (ret < 0)
1103 goto skip;
1104 else
1105 break;
1106 } else {
1107 if ((ret = amf_skip_tag(pb, type, 0)) < 0)
1108 goto skip;
1109 }
1110 }
1111
1112 if (length < 0) {
1113 ret = AVERROR_INVALIDDATA;
1114 goto skip;
1115 }
1116
1117 for (i = 0; i < s->nb_streams; i++) {
1118 st = s->streams[i];
1119 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
1120 break;
1121 }
1122
1123 if (i == s->nb_streams) {
1124 st = create_stream(s, AVMEDIA_TYPE_SUBTITLE, 0);
1125 if (!st)
1126 return AVERROR(ENOMEM);
1127 st->codecpar->codec_id = AV_CODEC_ID_TEXT;
1128 }
1129
1130 pkt->dts = dts;
1131 pkt->pts = dts;
1132 pkt->size = ret;
1133
1134 pkt->stream_index = st->index;
1135 pkt->flags |= AV_PKT_FLAG_KEY;
1136
1137 skip:
1138 avio_seek(s->pb, next + 4, SEEK_SET);
1139
1140 return ret;
1141 }
1142
1143 static int resync(AVFormatContext *s)
1144 {
1145 FLVContext *flv = s->priv_data;
1146 int64_t i;
1147 int64_t pos = avio_tell(s->pb);
1148
1149 for (i=0; !avio_feof(s->pb); i++) {
1150 int j = i & (RESYNC_BUFFER_SIZE-1);
1151 int j1 = j + RESYNC_BUFFER_SIZE;
1152 flv->resync_buffer[j ] =
1153 flv->resync_buffer[j1] = avio_r8(s->pb);
1154
1155 if (i >= 8 && pos) {
1156 uint8_t *d = flv->resync_buffer + j1 - 8;
1157 if (d[0] == 'F' &&
1158 d[1] == 'L' &&
1159 d[2] == 'V' &&
1160 d[3] < 5 && d[5] == 0) {
1161 av_log(s, AV_LOG_WARNING, "Concatenated FLV detected, might fail to demux, decode and seek %"PRId64"\n", flv->last_ts);
1162 flv->time_offset = flv->last_ts + 1;
1163 flv->time_pos = avio_tell(s->pb);
1164 }
1165 }
1166
1167 if (i > 22) {
1168 unsigned lsize2 = AV_RB32(flv->resync_buffer + j1 - 4);
1169 if (lsize2 >= 11 && lsize2 + 8LL < FFMIN(i, RESYNC_BUFFER_SIZE)) {
1170 unsigned size2 = AV_RB24(flv->resync_buffer + j1 - lsize2 + 1 - 4);
1171 unsigned lsize1 = AV_RB32(flv->resync_buffer + j1 - lsize2 - 8);
1172 if (lsize1 >= 11 && lsize1 + 8LL + lsize2 < FFMIN(i, RESYNC_BUFFER_SIZE)) {
1173 unsigned size1 = AV_RB24(flv->resync_buffer + j1 - lsize1 + 1 - lsize2 - 8);
1174 if (size1 == lsize1 - 11 && size2 == lsize2 - 11) {
1175 avio_seek(s->pb, pos + i - lsize1 - lsize2 - 8, SEEK_SET);
1176 return 1;
1177 }
1178 }
1179 }
1180 }
1181 }
1182 return AVERROR_EOF;
1183 }
1184
1185 15 static int flv_parse_video_color_info(AVFormatContext *s, AVStream *st, int64_t next_pos)
1186 {
1187 int ret;
1188 15 FLVContext *flv = s->priv_data;
1189 AMFDataType type;
1190 AVIOContext *ioc;
1191 char buffer[32];
1192 15 ioc = s->pb;
1193
1194 // first object needs to be "colorInfo" string
1195 15 type = avio_r8(ioc);
1196
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if (type != AMF_DATA_TYPE_STRING) {
1197 av_log(s, AV_LOG_WARNING, "Ignore invalid colorInfo\n");
1198 return 0;
1199 }
1200
1201 15 ret = amf_get_string(ioc, buffer, sizeof(buffer));
1202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if (ret < 0)
1203 return ret;
1204
1205
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if (strcmp(buffer, "colorInfo") != 0) {
1206 av_log(s, AV_LOG_WARNING, "Ignore invalid colorInfo type %s\n", buffer);
1207 return 0;
1208 }
1209
1210 15 flv->meta_color_info_flag = FLV_COLOR_INFO_FLAG_PARSING;
1211 15 ret = amf_parse_object(s, NULL, NULL, buffer, next_pos, 0); // parse metadata
1212
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if (ret < 0) {
1213 flv->meta_color_info_flag = FLV_COLOR_INFO_FLAG_NONE;
1214 return ret;
1215 }
1216
1217 15 flv->meta_color_info_flag = FLV_COLOR_INFO_FLAG_GOT;
1218
1219 15 return 0;
1220 }
1221
1222 15 static int flv_update_video_color_info(AVFormatContext *s, AVStream *st)
1223 {
1224 15 FLVContext *flv = s->priv_data;
1225 15 const FLVMetaVideoColor* meta_video_color = &flv->meta_color_info;
1226 15 const FLVMasteringMeta *mastering_meta = &meta_video_color->mastering_meta;
1227
1228 int has_mastering_primaries, has_mastering_luminance;
1229 // Mastering primaries are CIE 1931 coords, and must be > 0.
1230 15 has_mastering_primaries =
1231
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 mastering_meta->r_x > 0 && mastering_meta->r_y > 0 &&
1232
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 mastering_meta->g_x > 0 && mastering_meta->g_y > 0 &&
1233
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 mastering_meta->b_x > 0 && mastering_meta->b_y > 0 &&
1234
4/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
16 mastering_meta->white_x > 0 && mastering_meta->white_y > 0;
1235
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
15 has_mastering_luminance = mastering_meta->max_luminance > 0 && mastering_meta->min_luminance > 0;
1236
1237
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 if (meta_video_color->matrix_coefficients != AVCOL_SPC_RESERVED)
1238 15 st->codecpar->color_space = meta_video_color->matrix_coefficients;
1239
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 if (meta_video_color->primaries != AVCOL_PRI_RESERVED &&
1240
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 11 times.
15 meta_video_color->primaries != AVCOL_PRI_RESERVED0)
1241 4 st->codecpar->color_primaries = meta_video_color->primaries;
1242
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 if (meta_video_color->trc != AVCOL_TRC_RESERVED &&
1243
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 11 times.
15 meta_video_color->trc != AVCOL_TRC_RESERVED0)
1244 4 st->codecpar->color_trc = meta_video_color->trc;
1245
1246
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
15 if (meta_video_color->max_cll && meta_video_color->max_fall) {
1247 1 size_t size = 0;
1248 1 AVContentLightMetadata *metadata = av_content_light_metadata_alloc(&size);
1249
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!metadata)
1250 return AVERROR(ENOMEM);
1251
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (!av_packet_side_data_add(&st->codecpar->coded_side_data, &st->codecpar->nb_coded_side_data,
1252 AV_PKT_DATA_CONTENT_LIGHT_LEVEL, metadata, size, 0)) {
1253 av_freep(&metadata);
1254 return AVERROR(ENOMEM);
1255 }
1256 1 metadata->MaxCLL = meta_video_color->max_cll;
1257 1 metadata->MaxFALL = meta_video_color->max_fall;
1258 }
1259
1260
3/4
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
15 if (has_mastering_primaries || has_mastering_luminance) {
1261 1 size_t size = 0;
1262 1 AVMasteringDisplayMetadata *metadata = av_mastering_display_metadata_alloc_size(&size);
1263 AVPacketSideData *sd;
1264
1265
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!metadata)
1266 return AVERROR(ENOMEM);
1267
1268 1 sd = av_packet_side_data_add(&st->codecpar->coded_side_data,
1269 1 &st->codecpar->nb_coded_side_data,
1270 AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
1271 metadata, size, 0);
1272
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (!sd) {
1273 av_freep(&metadata);
1274 return AVERROR(ENOMEM);
1275 }
1276
1277 // hdrCll
1278
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (has_mastering_luminance) {
1279 1 metadata->max_luminance = av_d2q(mastering_meta->max_luminance, INT_MAX);
1280 1 metadata->min_luminance = av_d2q(mastering_meta->min_luminance, INT_MAX);
1281 1 metadata->has_luminance = 1;
1282 }
1283 // hdrMdcv
1284
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (has_mastering_primaries) {
1285 1 metadata->display_primaries[0][0] = av_d2q(mastering_meta->r_x, INT_MAX);
1286 1 metadata->display_primaries[0][1] = av_d2q(mastering_meta->r_y, INT_MAX);
1287 1 metadata->display_primaries[1][0] = av_d2q(mastering_meta->g_x, INT_MAX);
1288 1 metadata->display_primaries[1][1] = av_d2q(mastering_meta->g_y, INT_MAX);
1289 1 metadata->display_primaries[2][0] = av_d2q(mastering_meta->b_x, INT_MAX);
1290 1 metadata->display_primaries[2][1] = av_d2q(mastering_meta->b_y, INT_MAX);
1291 1 metadata->white_point[0] = av_d2q(mastering_meta->white_x, INT_MAX);
1292 1 metadata->white_point[1] = av_d2q(mastering_meta->white_y, INT_MAX);
1293 1 metadata->has_primaries = 1;
1294 }
1295 }
1296 15 return 0;
1297 }
1298
1299 static int flv_parse_mod_ex_data(AVFormatContext *s, int *pkt_type, int *size, int64_t *dts)
1300 {
1301 int ex_type, ret;
1302 uint8_t *ex_data;
1303
1304 int ex_size = (uint8_t)avio_r8(s->pb) + 1;
1305 *size -= 1;
1306
1307 if (ex_size == 256) {
1308 ex_size = (uint16_t)avio_rb16(s->pb) + 1;
1309 *size -= 2;
1310 }
1311
1312 if (ex_size >= *size) {
1313 av_log(s, AV_LOG_WARNING, "ModEx size larger than remaining data!\n");
1314 return AVERROR(EINVAL);
1315 }
1316
1317 ex_data = av_malloc(ex_size);
1318 if (!ex_data)
1319 return AVERROR(ENOMEM);
1320
1321 ret = avio_read(s->pb, ex_data, ex_size);
1322 if (ret < 0) {
1323 av_free(ex_data);
1324 return ret;
1325 }
1326 *size -= ex_size;
1327
1328 ex_type = (uint8_t)avio_r8(s->pb);
1329 *size -= 1;
1330
1331 *pkt_type = ex_type & 0x0f;
1332 ex_type &= 0xf0;
1333
1334 if (ex_type == PacketModExTypeTimestampOffsetNano) {
1335 uint32_t nano_offset;
1336
1337 if (ex_size != 3) {
1338 av_log(s, AV_LOG_WARNING, "Invalid ModEx size for Type TimestampOffsetNano!\n");
1339 nano_offset = 0;
1340 } else {
1341 nano_offset = (ex_data[0] << 16) | (ex_data[1] << 8) | ex_data[2];
1342 }
1343
1344 // this is not likely to ever add anything, but right now timestamps are with ms precision
1345 *dts += nano_offset / 1000000;
1346 } else {
1347 av_log(s, AV_LOG_INFO, "Unknown ModEx type: %d", ex_type);
1348 }
1349
1350 av_free(ex_data);
1351
1352 return 0;
1353 }
1354
1355 6340 static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
1356 {
1357 6340 FLVContext *flv = s->priv_data;
1358 6340 int ret = AVERROR_BUG, i, size, flags;
1359 6340 int res = 0;
1360 enum FlvTagType type;
1361 6340 int stream_type = -1;
1362 int64_t next, pos, meta_pos;
1363 6340 int64_t dts, pts = AV_NOPTS_VALUE;
1364 6340 int av_uninit(channels);
1365 6340 int av_uninit(sample_rate);
1366 6340 AVStream *st = NULL;
1367 6340 int last = -1;
1368 int orig_size;
1369 6340 int enhanced_flv = 0;
1370 6340 int multitrack = 0;
1371 6340 int pkt_type = 0;
1372 6340 uint8_t track_idx = 0;
1373 6340 uint32_t codec_id = 0;
1374 6340 int multitrack_type = MultitrackTypeOneTrack;
1375
1376 6340 retry:
1377 /* pkt size is repeated at end. skip it */
1378 6340 pos = avio_tell(s->pb);
1379 6340 type = (avio_r8(s->pb) & 0x1F);
1380 6340 orig_size =
1381 6340 size = avio_rb24(s->pb);
1382 6340 flv->sum_flv_tag_size += size + 11LL;
1383 6340 dts = avio_rb24(s->pb);
1384 6340 dts |= (unsigned)avio_r8(s->pb) << 24;
1385 6340 av_log(s, AV_LOG_TRACE, "type:%d, size:%d, last:%d, dts:%"PRId64" pos:%"PRId64"\n", type, size, last, dts, avio_tell(s->pb));
1386
2/2
✓ Branch 1 taken 76 times.
✓ Branch 2 taken 6264 times.
6340 if (avio_feof(s->pb))
1387 76 return AVERROR_EOF;
1388 6264 avio_skip(s->pb, 3); /* stream id, always 0 */
1389 6264 flags = 0;
1390
1391
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 6245 times.
6264 if (flv->validate_next < flv->validate_count) {
1392 19 int64_t validate_pos = flv->validate_index[flv->validate_next].pos;
1393
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 14 times.
19 if (pos == validate_pos) {
1394
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 if (FFABS(dts - flv->validate_index[flv->validate_next].dts) <=
1395 VALIDATE_INDEX_TS_THRESH) {
1396 5 flv->validate_next++;
1397 } else {
1398 clear_index_entries(s, validate_pos);
1399 flv->validate_count = 0;
1400 }
1401
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 13 times.
14 } else if (pos > validate_pos) {
1402 1 clear_index_entries(s, validate_pos);
1403 1 flv->validate_count = 0;
1404 }
1405 }
1406
1407
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6264 times.
6264 if (size == 0) {
1408 ret = FFERROR_REDO;
1409 goto leave;
1410 }
1411
1412 6264 next = size + avio_tell(s->pb);
1413
1414
2/2
✓ Branch 0 taken 3267 times.
✓ Branch 1 taken 2997 times.
6264 if (type == FLV_TAG_TYPE_AUDIO) {
1415 3267 stream_type = FLV_STREAM_TYPE_AUDIO;
1416 3267 flags = avio_r8(s->pb);
1417 3267 size--;
1418
1419
2/2
✓ Branch 0 taken 663 times.
✓ Branch 1 taken 2604 times.
3267 if ((flags & FLV_AUDIO_CODECID_MASK) == FLV_CODECID_EX_HEADER) {
1420 663 enhanced_flv = 1;
1421 663 pkt_type = flags & ~FLV_AUDIO_CODECID_MASK;
1422
1423
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 663 times.
663 while (pkt_type == PacketTypeModEx) {
1424 ret = flv_parse_mod_ex_data(s, &pkt_type, &size, &dts);
1425 if (ret < 0)
1426 goto leave;
1427 }
1428
1429
2/2
✓ Branch 0 taken 660 times.
✓ Branch 1 taken 3 times.
663 if (pkt_type == AudioPacketTypeMultitrack) {
1430 660 uint8_t types = avio_r8(s->pb);
1431 660 multitrack_type = types & 0xF0;
1432 660 pkt_type = types & 0xF;
1433
1434 660 multitrack = 1;
1435 660 size--;
1436 }
1437
1438 663 codec_id = avio_rb32(s->pb);
1439 663 size -= 4;
1440
1441
2/2
✓ Branch 0 taken 660 times.
✓ Branch 1 taken 3 times.
663 if (multitrack) {
1442 660 track_idx = avio_r8(s->pb);
1443 660 size--;
1444 }
1445 }
1446
2/2
✓ Branch 0 taken 2958 times.
✓ Branch 1 taken 39 times.
2997 } else if (type == FLV_TAG_TYPE_VIDEO) {
1447 2958 stream_type = FLV_STREAM_TYPE_VIDEO;
1448 2958 flags = avio_r8(s->pb);
1449 2958 codec_id = flags & FLV_VIDEO_CODECID_MASK;
1450 /*
1451 * Reference Enhancing FLV 2023-03-v1.0.0-B.8
1452 * https://github.com/veovera/enhanced-rtmp/blob/main/enhanced-rtmp-v1.pdf
1453 * */
1454 2958 enhanced_flv = (flags >> 7) & 1;
1455
2/2
✓ Branch 0 taken 657 times.
✓ Branch 1 taken 2301 times.
2958 pkt_type = enhanced_flv ? codec_id : 0;
1456 2958 size--;
1457
1458
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2958 times.
2958 while (pkt_type == PacketTypeModEx) {
1459 ret = flv_parse_mod_ex_data(s, &pkt_type, &size, &dts);
1460 if (ret < 0)
1461 goto leave;
1462 }
1463
1464
4/4
✓ Branch 0 taken 657 times.
✓ Branch 1 taken 2301 times.
✓ Branch 2 taken 642 times.
✓ Branch 3 taken 15 times.
2958 if (enhanced_flv && pkt_type != PacketTypeMetadata &&
1465
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 642 times.
642 (flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_VIDEO_INFO_CMD)
1466 goto skip;
1467
1468
2/2
✓ Branch 0 taken 450 times.
✓ Branch 1 taken 2508 times.
2958 if (pkt_type == PacketTypeMultitrack) {
1469 450 uint8_t types = avio_r8(s->pb);
1470 450 multitrack_type = types & 0xF0;
1471 450 pkt_type = types & 0xF;
1472
1473 450 multitrack = 1;
1474 450 size--;
1475 }
1476
1477
2/2
✓ Branch 0 taken 657 times.
✓ Branch 1 taken 2301 times.
2958 if (enhanced_flv) {
1478 657 codec_id = avio_rb32(s->pb);
1479 657 size -= 4;
1480 }
1481
2/2
✓ Branch 0 taken 450 times.
✓ Branch 1 taken 2508 times.
2958 if (multitrack) {
1482 450 track_idx = avio_r8(s->pb);
1483 450 size--;
1484 }
1485
1486
4/4
✓ Branch 0 taken 657 times.
✓ Branch 1 taken 2301 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 642 times.
2958 if (enhanced_flv && (flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_VIDEO_INFO_CMD) {
1487
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 if (pkt_type == PacketTypeMetadata) {
1488 15 ret = flv_parse_video_color_info(s, st, next);
1489
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if (ret < 0)
1490 goto leave;
1491 }
1492 15 goto skip;
1493
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2943 times.
2943 } else if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_VIDEO_INFO_CMD) {
1494 goto skip;
1495 }
1496
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 } else if (type == FLV_TAG_TYPE_META) {
1497 39 stream_type=FLV_STREAM_TYPE_SUBTITLE;
1498
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 if (size > 13 + 1 + 4) { // Header-type metadata stuff
1499 int type;
1500 39 meta_pos = avio_tell(s->pb);
1501 39 type = flv_read_metabody(s, next);
1502
2/6
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 39 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
39 if (type == 0 && dts == 0 || type < 0) {
1503
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
39 if (type < 0 && flv->validate_count &&
1504 flv->validate_index[0].pos > next &&
1505 flv->validate_index[0].pos - 4 < next) {
1506 av_log(s, AV_LOG_WARNING, "Adjusting next position due to index mismatch\n");
1507 next = flv->validate_index[0].pos - 4;
1508 }
1509 39 goto skip;
1510 } else if (type == TYPE_ONTEXTDATA) {
1511 avpriv_request_sample(s, "OnTextData packet");
1512 return flv_data_packet(s, pkt, dts, next);
1513 } else if (type == TYPE_ONCAPTION) {
1514 return flv_data_packet(s, pkt, dts, next);
1515 } else if (type == TYPE_UNKNOWN) {
1516 stream_type = FLV_STREAM_TYPE_DATA;
1517 }
1518 avio_seek(s->pb, meta_pos, SEEK_SET);
1519 }
1520 } else {
1521 av_log(s, AV_LOG_DEBUG,
1522 "Skipping flv packet: type %d, size %d, flags %d.\n",
1523 type, size, flags);
1524 54 skip:
1525
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 54 times.
54 if (avio_seek(s->pb, next, SEEK_SET) != next) {
1526 // This can happen if flv_read_metabody above read past
1527 // next, on a non-seekable input, and the preceding data has
1528 // been flushed out from the IO buffer.
1529 av_log(s, AV_LOG_ERROR, "Unable to seek to the next packet\n");
1530 return AVERROR_INVALIDDATA;
1531 }
1532 54 ret = FFERROR_REDO;
1533 54 goto leave;
1534 }
1535
1536 /* skip empty data packets */
1537
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 6206 times.
6210 if (!size) {
1538 4 ret = FFERROR_REDO;
1539 4 goto leave;
1540 }
1541
1542 for (;;) {
1543 6206 int track_size = size;
1544
1545
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6206 times.
6206 if (multitrack_type != MultitrackTypeOneTrack) {
1546 track_size = avio_rb24(s->pb);
1547 size -= 3;
1548 }
1549
1550 /* now find stream */
1551
2/2
✓ Branch 0 taken 13969 times.
✓ Branch 1 taken 69 times.
14038 for (i = 0; i < s->nb_streams; i++) {
1552 13969 st = s->streams[i];
1553
2/2
✓ Branch 0 taken 8803 times.
✓ Branch 1 taken 5166 times.
13969 if (stream_type == FLV_STREAM_TYPE_AUDIO) {
1554
2/2
✓ Branch 0 taken 4905 times.
✓ Branch 1 taken 3898 times.
8803 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
1555
3/4
✓ Branch 0 taken 4905 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 3461 times.
✓ Branch 4 taken 1444 times.
4905 (s->audio_codec_id || flv_same_audio_codec(st->codecpar, flags, codec_id)) &&
1556
2/2
✓ Branch 0 taken 3239 times.
✓ Branch 1 taken 222 times.
3461 st->id == track_idx)
1557 3239 break;
1558
1/2
✓ Branch 0 taken 5166 times.
✗ Branch 1 not taken.
5166 } else if (stream_type == FLV_STREAM_TYPE_VIDEO) {
1559
2/2
✓ Branch 0 taken 4032 times.
✓ Branch 1 taken 1134 times.
5166 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
1560
4/4
✓ Branch 0 taken 3967 times.
✓ Branch 1 taken 65 times.
✓ Branch 3 taken 2950 times.
✓ Branch 4 taken 1017 times.
4032 (s->video_codec_id || flv_same_video_codec(st->codecpar, codec_id)) &&
1561
2/2
✓ Branch 0 taken 2898 times.
✓ Branch 1 taken 117 times.
3015 st->id == track_idx)
1562 2898 break;
1563 } else if (stream_type == FLV_STREAM_TYPE_SUBTITLE) {
1564 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
1565 break;
1566 } else if (stream_type == FLV_STREAM_TYPE_DATA) {
1567 if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA)
1568 break;
1569 }
1570 }
1571
2/2
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 6137 times.
6206 if (i == s->nb_streams) {
1572 static const enum AVMediaType stream_types[] = {AVMEDIA_TYPE_VIDEO, AVMEDIA_TYPE_AUDIO, AVMEDIA_TYPE_SUBTITLE, AVMEDIA_TYPE_DATA};
1573 69 st = create_stream(s, stream_types[stream_type], track_idx);
1574
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 if (!st)
1575 return AVERROR(ENOMEM);
1576 }
1577 6206 av_log(s, AV_LOG_TRACE, "%d %X %d \n", stream_type, flags, st->discard);
1578
1579
1/2
✓ Branch 0 taken 6206 times.
✗ Branch 1 not taken.
6206 if (flv->time_pos <= pos) {
1580 6206 dts += flv->time_offset;
1581 }
1582
1583
1/2
✓ Branch 0 taken 6206 times.
✗ Branch 1 not taken.
6206 if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
1584
4/4
✓ Branch 0 taken 4725 times.
✓ Branch 1 taken 1481 times.
✓ Branch 2 taken 2316 times.
✓ Branch 3 taken 2409 times.
6206 ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY ||
1585 stream_type == FLV_STREAM_TYPE_AUDIO))
1586 3797 av_add_index_entry(st, pos, dts, track_size, 0, AVINDEX_KEYFRAME);
1587
1588
5/6
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 5918 times.
✓ Branch 2 taken 278 times.
✓ Branch 3 taken 10 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 278 times.
6206 if ((st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || stream_type == FLV_STREAM_TYPE_AUDIO)) ||
1589
3/6
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 5918 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
5928 (st->discard >= AVDISCARD_BIDIR && ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && stream_type == FLV_STREAM_TYPE_VIDEO)) ||
1590
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 5918 times.
5928 st->discard >= AVDISCARD_ALL) {
1591 288 avio_seek(s->pb, next, SEEK_SET);
1592 288 ret = FFERROR_REDO;
1593 288 goto leave;
1594 }
1595
1596 // if not streamed and no duration from metadata then seek to end to find
1597 // the duration from the timestamps
1598
1/2
✓ Branch 0 taken 5918 times.
✗ Branch 1 not taken.
5918 if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
1599
2/4
✓ Branch 0 taken 5918 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5918 times.
5918 (!s->duration || s->duration == AV_NOPTS_VALUE) &&
1600 !flv->searched_for_end) {
1601 int final_size;
1602 const int64_t pos = avio_tell(s->pb);
1603 // Read the last 4 bytes of the file, this should be the size of the
1604 // previous FLV tag. Use the timestamp of its payload as duration.
1605 int64_t fsize = avio_size(s->pb);
1606 retry_duration:
1607 avio_seek(s->pb, fsize - 4, SEEK_SET);
1608 final_size = avio_rb32(s->pb);
1609 if (final_size > 0 && final_size < fsize) {
1610 // Seek to the start of the last FLV tag at position (fsize - 4 - final_size)
1611 // but skip the byte indicating the type.
1612 avio_seek(s->pb, fsize - 3 - final_size, SEEK_SET);
1613 if (final_size == avio_rb24(s->pb) + 11) {
1614 uint32_t ts = avio_rb24(s->pb);
1615 ts |= (unsigned)avio_r8(s->pb) << 24;
1616 if (ts)
1617 s->duration = ts * (int64_t)AV_TIME_BASE / 1000;
1618 else if (fsize >= 8 && fsize - 8 >= final_size) {
1619 fsize -= final_size+4;
1620 goto retry_duration;
1621 }
1622 }
1623 }
1624
1625 avio_seek(s->pb, pos, SEEK_SET);
1626 flv->searched_for_end = 1;
1627 }
1628
1629
4/4
✓ Branch 0 taken 3263 times.
✓ Branch 1 taken 2655 times.
✓ Branch 2 taken 2604 times.
✓ Branch 3 taken 659 times.
8522 if (stream_type == FLV_STREAM_TYPE_AUDIO && !enhanced_flv) {
1630 int bits_per_coded_sample;
1631
2/2
✓ Branch 0 taken 906 times.
✓ Branch 1 taken 1698 times.
2604 channels = (flags & FLV_AUDIO_CHANNEL_MASK) == FLV_STEREO ? 2 : 1;
1632 2604 sample_rate = 44100 << ((flags & FLV_AUDIO_SAMPLERATE_MASK) >>
1633 FLV_AUDIO_SAMPLERATE_OFFSET) >> 3;
1634
1/2
✓ Branch 0 taken 2604 times.
✗ Branch 1 not taken.
2604 bits_per_coded_sample = (flags & FLV_AUDIO_SAMPLESIZE_MASK) ? 16 : 8;
1635
2/2
✓ Branch 1 taken 2592 times.
✓ Branch 2 taken 12 times.
2604 if (!av_channel_layout_check(&st->codecpar->ch_layout) ||
1636
1/2
✓ Branch 0 taken 2592 times.
✗ Branch 1 not taken.
2592 !st->codecpar->sample_rate ||
1637
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2592 times.
2592 !st->codecpar->bits_per_coded_sample) {
1638 12 av_channel_layout_default(&st->codecpar->ch_layout, channels);
1639 12 st->codecpar->sample_rate = sample_rate;
1640 12 st->codecpar->bits_per_coded_sample = bits_per_coded_sample;
1641 }
1642
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2592 times.
2604 if (!st->codecpar->codec_id) {
1643 12 flv_set_audio_codec(s, st, st->codecpar,
1644 flags & FLV_AUDIO_CODECID_MASK);
1645 12 flv->last_sample_rate =
1646 12 sample_rate = st->codecpar->sample_rate;
1647 12 flv->last_channels =
1648 12 channels = st->codecpar->ch_layout.nb_channels;
1649 } else {
1650 2592 AVCodecParameters *par = avcodec_parameters_alloc();
1651
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2592 times.
2592 if (!par) {
1652 ret = AVERROR(ENOMEM);
1653 goto leave;
1654 }
1655 2592 par->sample_rate = sample_rate;
1656 2592 par->bits_per_coded_sample = bits_per_coded_sample;
1657 2592 flv_set_audio_codec(s, st, par, flags & FLV_AUDIO_CODECID_MASK);
1658 2592 sample_rate = par->sample_rate;
1659 2592 avcodec_parameters_free(&par);
1660 }
1661
2/2
✓ Branch 0 taken 659 times.
✓ Branch 1 taken 2655 times.
3314 } else if (stream_type == FLV_STREAM_TYPE_AUDIO) {
1662
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 647 times.
659 if (!st->codecpar->codec_id)
1663
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 flv_set_audio_codec(s, st, st->codecpar,
1664 codec_id ? codec_id : (flags & FLV_AUDIO_CODECID_MASK));
1665
1666 // These are not signalled in the flags anymore
1667 659 channels = 0;
1668 659 sample_rate = 0;
1669
1670
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 643 times.
659 if (pkt_type == AudioPacketTypeMultichannelConfig) {
1671 16 int channel_order = avio_r8(s->pb);
1672 16 channels = avio_r8(s->pb);
1673 16 size -= 2;
1674 16 track_size -= 2;
1675
1676 16 av_channel_layout_uninit(&st->codecpar->ch_layout);
1677
1678
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (channel_order == AudioChannelOrderCustom) {
1679 ret = av_channel_layout_custom_init(&st->codecpar->ch_layout, channels);
1680 if (ret < 0)
1681 return ret;
1682
1683 for (i = 0; i < channels; i++) {
1684 uint8_t id = avio_r8(s->pb);
1685 size--;
1686 track_size--;
1687
1688 if (id < 18)
1689 st->codecpar->ch_layout.u.map[i].id = id;
1690 else if (id >= 18 && id <= 23)
1691 st->codecpar->ch_layout.u.map[i].id = id - 18 + AV_CHAN_LOW_FREQUENCY_2;
1692 else if (id == 0xFE)
1693 st->codecpar->ch_layout.u.map[i].id = AV_CHAN_UNUSED;
1694 else
1695 st->codecpar->ch_layout.u.map[i].id = AV_CHAN_UNKNOWN;
1696 }
1697
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 3 times.
16 } else if (channel_order == AudioChannelOrderNative) {
1698 13 uint64_t mask = avio_rb32(s->pb);
1699 13 size -= 4;
1700 13 track_size -= 4;
1701
1702 // The first 18 entries in the mask match ours, but the remaining 6 entries start at AV_CHAN_LOW_FREQUENCY_2
1703 13 mask = (mask & 0x3FFFF) | ((mask & 0xFC0000) << (AV_CHAN_LOW_FREQUENCY_2 - 18));
1704 13 ret = av_channel_layout_from_mask(&st->codecpar->ch_layout, mask);
1705
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (ret < 0)
1706 return ret;
1707 } else {
1708 3 av_channel_layout_default(&st->codecpar->ch_layout, channels);
1709 }
1710
1711 16 av_log(s, AV_LOG_DEBUG, "Set channel data from MultiChannel info.\n");
1712
1713 16 goto next_track;
1714 }
1715
1/2
✓ Branch 0 taken 2655 times.
✗ Branch 1 not taken.
2655 } else if (stream_type == FLV_STREAM_TYPE_VIDEO) {
1716 2655 int sret = flv_set_video_codec(s, st, codec_id, 1);
1717
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2655 times.
2655 if (sret < 0)
1718 return sret;
1719 2655 size -= sret;
1720 2655 track_size -= sret;
1721 } else if (stream_type == FLV_STREAM_TYPE_SUBTITLE) {
1722 st->codecpar->codec_id = AV_CODEC_ID_TEXT;
1723 } else if (stream_type == FLV_STREAM_TYPE_DATA) {
1724 st->codecpar->codec_id = AV_CODEC_ID_NONE; // Opaque AMF data
1725 }
1726
1727
2/2
✓ Branch 0 taken 5065 times.
✓ Branch 1 taken 837 times.
5902 if (st->codecpar->codec_id == AV_CODEC_ID_AAC ||
1728
2/2
✓ Branch 0 taken 4834 times.
✓ Branch 1 taken 231 times.
5065 st->codecpar->codec_id == AV_CODEC_ID_OPUS ||
1729
2/2
✓ Branch 0 taken 4782 times.
✓ Branch 1 taken 52 times.
4834 st->codecpar->codec_id == AV_CODEC_ID_FLAC ||
1730
2/2
✓ Branch 0 taken 3805 times.
✓ Branch 1 taken 977 times.
4782 st->codecpar->codec_id == AV_CODEC_ID_H264 ||
1731
1/2
✓ Branch 0 taken 3805 times.
✗ Branch 1 not taken.
3805 st->codecpar->codec_id == AV_CODEC_ID_MPEG4 ||
1732
2/2
✓ Branch 0 taken 3578 times.
✓ Branch 1 taken 227 times.
3805 st->codecpar->codec_id == AV_CODEC_ID_HEVC ||
1733
2/2
✓ Branch 0 taken 3402 times.
✓ Branch 1 taken 176 times.
3578 st->codecpar->codec_id == AV_CODEC_ID_AV1 ||
1734
2/2
✓ Branch 0 taken 122 times.
✓ Branch 1 taken 3280 times.
3402 st->codecpar->codec_id == AV_CODEC_ID_VP9) {
1735 2622 int type = 0;
1736
2/2
✓ Branch 0 taken 1144 times.
✓ Branch 1 taken 1478 times.
2622 if (enhanced_flv) {
1737 1144 type = pkt_type;
1738 } else {
1739 1478 type = avio_r8(s->pb);
1740 1478 size--;
1741 1478 track_size--;
1742 }
1743
1744
2/4
✓ Branch 0 taken 2622 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2622 times.
2622 if (size < 0 || track_size < 0) {
1745 ret = AVERROR_INVALIDDATA;
1746 goto leave;
1747 }
1748
1749
4/4
✓ Branch 0 taken 1144 times.
✓ Branch 1 taken 1478 times.
✓ Branch 2 taken 642 times.
✓ Branch 3 taken 502 times.
2622 if (enhanced_flv && stream_type == FLV_STREAM_TYPE_VIDEO &&
1750
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 627 times.
642 flv->meta_color_info_flag == FLV_COLOR_INFO_FLAG_GOT) {
1751 15 flv_update_video_color_info(s, st); // update av packet side data
1752 15 flv->meta_color_info_flag = FLV_COLOR_INFO_FLAG_NONE;
1753 }
1754
1755
1/2
✓ Branch 0 taken 2622 times.
✗ Branch 1 not taken.
2622 if (st->codecpar->codec_id == AV_CODEC_ID_MPEG4 ||
1756
6/6
✓ Branch 0 taken 1645 times.
✓ Branch 1 taken 977 times.
✓ Branch 2 taken 227 times.
✓ Branch 3 taken 1418 times.
✓ Branch 4 taken 344 times.
✓ Branch 5 taken 860 times.
2622 ((st->codecpar->codec_id == AV_CODEC_ID_H264 || st->codecpar->codec_id == AV_CODEC_ID_HEVC) &&
1757
2/2
✓ Branch 0 taken 277 times.
✓ Branch 1 taken 67 times.
344 (!enhanced_flv || type == PacketTypeCodedFrames))) {
1758 // sign extension
1759 1137 int32_t cts = (avio_rb24(s->pb) + 0xff800000) ^ 0xff800000;
1760 1137 pts = av_sat_add64(dts, cts);
1761
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1137 times.
1137 if (cts < 0) { // dts might be wrong
1762 if (!flv->wrong_dts)
1763 av_log(s, AV_LOG_WARNING,
1764 "Negative cts, previous timestamps might be wrong.\n");
1765 flv->wrong_dts = 1;
1766
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1137 times.
1137 } else if (FFABS(dts - pts) > 1000*60*15) {
1767 av_log(s, AV_LOG_WARNING,
1768 "invalid timestamps %"PRId64" %"PRId64"\n", dts, pts);
1769 dts = pts = AV_NOPTS_VALUE;
1770 }
1771 1137 size -= 3;
1772 1137 track_size -= 3;
1773 }
1774
6/6
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 2580 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 39 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 1 times.
2622 if (type == 0 && (!st->codecpar->extradata || st->codecpar->codec_id == AV_CODEC_ID_AAC ||
1775
3/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
2 st->codecpar->codec_id == AV_CODEC_ID_OPUS || st->codecpar->codec_id == AV_CODEC_ID_FLAC ||
1776
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1 st->codecpar->codec_id == AV_CODEC_ID_H264 || st->codecpar->codec_id == AV_CODEC_ID_HEVC ||
1777 st->codecpar->codec_id == AV_CODEC_ID_AV1 || st->codecpar->codec_id == AV_CODEC_ID_VP9)) {
1778 AVDictionaryEntry *t;
1779
1780
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 39 times.
42 if (st->codecpar->extradata) {
1781
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
3 if ((ret = flv_queue_extradata(flv, s->pb, multitrack ? track_idx : stream_type, track_size, multitrack)) < 0)
1782 return ret;
1783 3 ret = FFERROR_REDO;
1784 3 goto leave;
1785 }
1786
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
39 if ((ret = flv_get_extradata(s, st, track_size)) < 0)
1787 return ret;
1788
1789 /* Workaround for buggy Omnia A/XE encoder */
1790 39 t = av_dict_get(s->metadata, "Encoder", NULL, 0);
1791
5/6
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 31 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
39 if (st->codecpar->codec_id == AV_CODEC_ID_AAC && t && !strcmp(t->value, "Omnia A/XE"))
1792 st->codecpar->extradata_size = 2;
1793
1794 39 ret = FFERROR_REDO;
1795 39 goto leave;
1796 }
1797 }
1798
1799 /* skip empty or broken data packets */
1800
3/4
✓ Branch 0 taken 5850 times.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5850 times.
5860 if (size <= 0 || track_size < 0) {
1801 10 ret = FFERROR_REDO;
1802 10 goto leave;
1803 }
1804
1805 /* skip empty data track */
1806
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5850 times.
5850 if (!track_size)
1807 goto next_track;
1808
1809 5850 ret = av_get_packet(s->pb, pkt, track_size);
1810
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5850 times.
5850 if (ret < 0)
1811 return ret;
1812
1813 5850 track_size -= ret;
1814 5850 size -= ret;
1815
1816 5850 pkt->dts = dts;
1817
2/2
✓ Branch 0 taken 4731 times.
✓ Branch 1 taken 1119 times.
5850 pkt->pts = pts == AV_NOPTS_VALUE ? dts : pts;
1818 5850 pkt->stream_index = st->index;
1819 5850 pkt->pos = pos;
1820
4/4
✓ Branch 0 taken 4779 times.
✓ Branch 1 taken 1071 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 4777 times.
5850 if (!multitrack && flv->new_extradata[stream_type]) {
1821 2 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA,
1822 flv->new_extradata[stream_type],
1823 2 flv->new_extradata_size[stream_type]);
1824
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (ret < 0)
1825 return ret;
1826
1827 2 flv->new_extradata[stream_type] = NULL;
1828 2 flv->new_extradata_size[stream_type] = 0;
1829
2/2
✓ Branch 0 taken 1071 times.
✓ Branch 1 taken 4777 times.
5848 } else if (multitrack &&
1830
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1071 times.
1071 flv->mt_extradata_cnt > track_idx &&
1831 flv->mt_extradata[track_idx]) {
1832 ret = av_packet_add_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA,
1833 flv->mt_extradata[track_idx],
1834 flv->mt_extradata_sz[track_idx]);
1835 if (ret < 0)
1836 return ret;
1837
1838 flv->mt_extradata[track_idx] = NULL;
1839 flv->mt_extradata_sz[track_idx] = 0;
1840 }
1841
4/4
✓ Branch 0 taken 3231 times.
✓ Branch 1 taken 2619 times.
✓ Branch 2 taken 2598 times.
✓ Branch 3 taken 633 times.
5850 if (stream_type == FLV_STREAM_TYPE_AUDIO && !enhanced_flv &&
1842
1/2
✓ Branch 0 taken 2598 times.
✗ Branch 1 not taken.
2598 (sample_rate != flv->last_sample_rate ||
1843
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2598 times.
2598 channels != flv->last_channels)) {
1844 flv->last_sample_rate = sample_rate;
1845 flv->last_channels = channels;
1846 ff_add_param_change(pkt, channels, 0, sample_rate, 0, 0);
1847 }
1848
1849
2/2
✓ Branch 0 taken 2619 times.
✓ Branch 1 taken 3231 times.
5850 if (stream_type == FLV_STREAM_TYPE_AUDIO ||
1850
3/4
✓ Branch 0 taken 2131 times.
✓ Branch 1 taken 488 times.
✓ Branch 2 taken 2131 times.
✗ Branch 3 not taken.
2619 (flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY ||
1851
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2131 times.
2131 stream_type == FLV_STREAM_TYPE_SUBTITLE ||
1852 stream_type == FLV_STREAM_TYPE_DATA)
1853 3719 pkt->flags |= AV_PKT_FLAG_KEY;
1854
1855 5850 ret = ff_buffer_packet(s, pkt);
1856
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5850 times.
5850 if (ret < 0)
1857 return ret;
1858 5850 res = FFERROR_REDO;
1859
1860 5866 next_track:
1861
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5865 times.
5866 if (track_size) {
1862 1 av_log(s, AV_LOG_WARNING, "Track size mismatch: %d!\n", track_size);
1863 1 avio_skip(s->pb, track_size);
1864 1 size -= track_size;
1865 }
1866
1867
1/2
✓ Branch 0 taken 5866 times.
✗ Branch 1 not taken.
5866 if (!size)
1868 5866 break;
1869
1870 if (multitrack_type == MultitrackTypeOneTrack) {
1871 av_log(s, AV_LOG_ERROR, "Attempted to read next track in single-track mode.\n");
1872 ret = FFERROR_REDO;
1873 goto leave;
1874 }
1875
1876 if (multitrack_type == MultitrackTypeManyTracksManyCodecs) {
1877 codec_id = avio_rb32(s->pb);
1878 size -= 4;
1879 }
1880
1881 track_idx = avio_r8(s->pb);
1882 size--;
1883
1884 if (avio_feof(s->pb)) {
1885 av_log(s, AV_LOG_WARNING, "Premature EOF\n");
1886 /* return REDO so that any potentially queued up packages can be drained first */
1887 return FFERROR_REDO;
1888 }
1889 }
1890
1891 5866 ret = 0;
1892 6264 leave:
1893 6264 last = avio_rb32(s->pb);
1894
1/2
✓ Branch 0 taken 6264 times.
✗ Branch 1 not taken.
6264 if (!flv->trust_datasize) {
1895
4/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6263 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
6265 if (last != orig_size + 11 && last != orig_size + 10 &&
1896
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
1 !avio_feof(s->pb) &&
1897 (last != orig_size || !last) && last != flv->sum_flv_tag_size &&
1898 !flv->broken_sizes) {
1899 av_log(s, AV_LOG_ERROR, "Packet mismatch %d %d %"PRId64"\n", last, orig_size + 11, flv->sum_flv_tag_size);
1900 avio_seek(s->pb, pos + 1, SEEK_SET);
1901 ret = resync(s);
1902 av_packet_unref(pkt);
1903 if (ret >= 0) {
1904 goto retry;
1905 }
1906 }
1907 }
1908
1909
2/2
✓ Branch 0 taken 5866 times.
✓ Branch 1 taken 398 times.
6264 if (ret >= 0)
1910 5866 flv->last_ts = pkt->dts;
1911
1912
2/2
✓ Branch 0 taken 398 times.
✓ Branch 1 taken 5866 times.
6264 return ret ? ret : res;
1913 }
1914
1915 289 static int flv_read_seek(AVFormatContext *s, int stream_index,
1916 int64_t ts, int flags)
1917 {
1918 289 FLVContext *flv = s->priv_data;
1919 289 flv->validate_count = 0;
1920 289 return avio_seek_time(s->pb, stream_index, ts, flags);
1921 }
1922
1923 #define OFFSET(x) offsetof(FLVContext, x)
1924 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
1925 static const AVOption options[] = {
1926 { "flv_metadata", "Allocate streams according to the onMetaData array", OFFSET(trust_metadata), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VD },
1927 { "flv_full_metadata", "Dump full metadata of the onMetadata", OFFSET(dump_full_metadata), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VD },
1928 { "flv_ignore_prevtag", "Ignore the Size of previous tag", OFFSET(trust_datasize), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VD },
1929 { NULL }
1930 };
1931
1932 static const AVClass flv_kux_class = {
1933 .class_name = "(live) flv/kux demuxer",
1934 .item_name = av_default_item_name,
1935 .option = options,
1936 .version = LIBAVUTIL_VERSION_INT,
1937 };
1938
1939 const FFInputFormat ff_flv_demuxer = {
1940 .p.name = "flv",
1941 .p.long_name = NULL_IF_CONFIG_SMALL("FLV (Flash Video)"),
1942 .p.extensions = "flv",
1943 .p.priv_class = &flv_kux_class,
1944 .priv_data_size = sizeof(FLVContext),
1945 .read_probe = flv_probe,
1946 .read_header = flv_read_header,
1947 .read_packet = flv_read_packet,
1948 .read_seek = flv_read_seek,
1949 .read_close = flv_read_close,
1950 };
1951
1952 const FFInputFormat ff_live_flv_demuxer = {
1953 .p.name = "live_flv",
1954 .p.long_name = NULL_IF_CONFIG_SMALL("live RTMP FLV (Flash Video)"),
1955 .p.extensions = "flv",
1956 .p.priv_class = &flv_kux_class,
1957 .p.flags = AVFMT_TS_DISCONT,
1958 .priv_data_size = sizeof(FLVContext),
1959 .read_probe = live_flv_probe,
1960 .read_header = flv_read_header,
1961 .read_packet = flv_read_packet,
1962 .read_seek = flv_read_seek,
1963 .read_close = flv_read_close,
1964 };
1965
1966 const FFInputFormat ff_kux_demuxer = {
1967 .p.name = "kux",
1968 .p.long_name = NULL_IF_CONFIG_SMALL("KUX (YouKu)"),
1969 .p.extensions = "kux",
1970 .p.priv_class = &flv_kux_class,
1971 .priv_data_size = sizeof(FLVContext),
1972 .read_probe = kux_probe,
1973 .read_header = flv_read_header,
1974 .read_packet = flv_read_packet,
1975 .read_seek = flv_read_seek,
1976 .read_close = flv_read_close,
1977 };
1978