../../../ffmpeg/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
815 / 1275
63.9%
Branches:
567 / 1039
54.6%
Functions:
23 / 27
85.2%

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