FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavformat/flvdec.c
Date: 2022-11-26 13:19:19
Exec Total Coverage
Lines: 518 866 59.8%
Branches: 343 729 47.1%

Line Branch Exec Source
1 /*
2 * FLV demuxer
3 * Copyright (c) 2003 The FFmpeg Project
4 *
5 * This demuxer will generate a 1 byte extradata for VP6F content.
6 * It is composed of:
7 * - upper 4 bits: difference between encoded width and visible width
8 * - lower 4 bits: difference between encoded height and visible height
9 *
10 * This file is part of FFmpeg.
11 *
12 * FFmpeg is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
16 *
17 * FFmpeg is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with FFmpeg; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 */
26
27 #include "libavutil/avassert.h"
28 #include "libavutil/avstring.h"
29 #include "libavutil/channel_layout.h"
30 #include "libavutil/dict.h"
31 #include "libavutil/dict_internal.h"
32 #include "libavutil/opt.h"
33 #include "libavutil/internal.h"
34 #include "libavutil/intfloat.h"
35 #include "libavutil/intreadwrite.h"
36 #include "libavutil/mathematics.h"
37 #include "avformat.h"
38 #include "demux.h"
39 #include "internal.h"
40 #include "flv.h"
41
42 #define VALIDATE_INDEX_TS_THRESH 2500
43
44 #define RESYNC_BUFFER_SIZE (1<<20)
45
46 #define MAX_DEPTH 16 ///< arbitrary limit to prevent unbounded recursion
47
48 typedef struct FLVContext {
49 const AVClass *class; ///< Class for private options.
50 int trust_metadata; ///< configure streams according onMetaData
51 int trust_datasize; ///< trust data size of FLVTag
52 int dump_full_metadata; ///< Dump full metadata of the onMetadata
53 int wrong_dts; ///< wrong dts due to negative cts
54 uint8_t *new_extradata[FLV_STREAM_TYPE_NB];
55 int new_extradata_size[FLV_STREAM_TYPE_NB];
56 int last_sample_rate;
57 int last_channels;
58 struct {
59 int64_t dts;
60 int64_t pos;
61 } validate_index[2];
62 int validate_next;
63 int validate_count;
64 int searched_for_end;
65
66 uint8_t resync_buffer[2*RESYNC_BUFFER_SIZE];
67
68 int broken_sizes;
69 int64_t sum_flv_tag_size;
70
71 int last_keyframe_stream_index;
72 int keyframe_count;
73 int64_t video_bit_rate;
74 int64_t audio_bit_rate;
75 int64_t *keyframe_times;
76 int64_t *keyframe_filepositions;
77 int missing_streams;
78 AVRational framerate;
79 int64_t last_ts;
80 int64_t time_offset;
81 int64_t time_pos;
82 } FLVContext;
83
84 /* AMF date type */
85 typedef struct amf_date {
86 double milliseconds;
87 int16_t timezone;
88 } amf_date;
89
90 13560 static int probe(const AVProbeData *p, int live)
91 {
92 13560 const uint8_t *d = p->buf;
93 13560 unsigned offset = AV_RB32(d + 5);
94
95
2/2
✓ Branch 0 taken 120 times.
✓ Branch 1 taken 13440 times.
13560 if (d[0] == 'F' &&
96
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 60 times.
120 d[1] == 'L' &&
97
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 d[2] == 'V' &&
98
2/4
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 60 times.
✗ Branch 3 not taken.
60 d[3] < 5 && d[5] == 0 &&
99
2/4
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 60 times.
✗ Branch 3 not taken.
60 offset + 100 < p->buf_size &&
100 offset > 8) {
101 60 int is_live = !memcmp(d + offset + 40, "NGINX RTMP", 10);
102
103
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 30 times.
60 if (live == is_live)
104 30 return AVPROBE_SCORE_MAX;
105 }
106 13530 return 0;
107 }
108
109 6780 static int flv_probe(const AVProbeData *p)
110 {
111 6780 return probe(p, 0);
112 }
113
114 6780 static int live_flv_probe(const AVProbeData *p)
115 {
116 6780 return probe(p, 1);
117 }
118
119 6780 static int kux_probe(const AVProbeData *p)
120 {
121 6780 const uint8_t *d = p->buf;
122
123
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 6777 times.
6780 if (d[0] == 'K' &&
124
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 d[1] == 'D' &&
125 d[2] == 'K' &&
126 d[3] == 0 &&
127 d[4] == 0) {
128 return AVPROBE_SCORE_EXTENSION + 1;
129 }
130 6780 return 0;
131 }
132
133 35 static void add_keyframes_index(AVFormatContext *s)
134 {
135 35 FLVContext *flv = s->priv_data;
136 35 AVStream *stream = NULL;
137 35 unsigned int i = 0;
138
139
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 32 times.
35 if (flv->last_keyframe_stream_index < 0) {
140 3 av_log(s, AV_LOG_DEBUG, "keyframe stream hasn't been created\n");
141 3 return;
142 }
143
144
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 av_assert0(flv->last_keyframe_stream_index <= s->nb_streams);
145 32 stream = s->streams[flv->last_keyframe_stream_index];
146
147
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 if (ffstream(stream)->nb_index_entries == 0) {
148
2/2
✓ Branch 0 taken 173 times.
✓ Branch 1 taken 32 times.
205 for (i = 0; i < flv->keyframe_count; i++) {
149 173 av_log(s, AV_LOG_TRACE, "keyframe filepositions = %"PRId64" times = %"PRId64"\n",
150 173 flv->keyframe_filepositions[i], flv->keyframe_times[i]);
151 173 av_add_index_entry(stream, flv->keyframe_filepositions[i],
152 173 flv->keyframe_times[i], 0, 0, AVINDEX_KEYFRAME);
153 }
154 } else
155 av_log(s, AV_LOG_WARNING, "Skipping duplicate index\n");
156
157
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 8 times.
32 if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
158 24 av_freep(&flv->keyframe_times);
159 24 av_freep(&flv->keyframe_filepositions);
160 24 flv->keyframe_count = 0;
161 }
162 }
163
164 32 static AVStream *create_stream(AVFormatContext *s, int codec_type)
165 {
166 32 FLVContext *flv = s->priv_data;
167 32 AVStream *st = avformat_new_stream(s, NULL);
168
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 if (!st)
169 return NULL;
170 32 st->codecpar->codec_type = codec_type;
171
3/4
✓ Branch 0 taken 32 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 30 times.
32 if (s->nb_streams>=3 ||( s->nb_streams==2
172
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 && s->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE
173
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 && s->streams[1]->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE
174
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 && s->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_DATA
175
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 && s->streams[1]->codecpar->codec_type != AVMEDIA_TYPE_DATA))
176 2 s->ctx_flags &= ~AVFMTCTX_NOHEADER;
177
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 24 times.
32 if (codec_type == AVMEDIA_TYPE_AUDIO) {
178 8 st->codecpar->bit_rate = flv->audio_bit_rate;
179 8 flv->missing_streams &= ~FLV_HEADER_FLAG_HASAUDIO;
180 }
181
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 8 times.
32 if (codec_type == AVMEDIA_TYPE_VIDEO) {
182 24 st->codecpar->bit_rate = flv->video_bit_rate;
183 24 flv->missing_streams &= ~FLV_HEADER_FLAG_HASVIDEO;
184 24 st->avg_frame_rate = flv->framerate;
185 }
186
187
188 32 avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */
189 32 flv->last_keyframe_stream_index = s->nb_streams - 1;
190 32 add_keyframes_index(s);
191 32 return st;
192 }
193
194 2232 static int flv_same_audio_codec(AVCodecParameters *apar, int flags)
195 {
196
1/2
✓ Branch 0 taken 2232 times.
✗ Branch 1 not taken.
2232 int bits_per_coded_sample = (flags & FLV_AUDIO_SAMPLESIZE_MASK) ? 16 : 8;
197 2232 int flv_codecid = flags & FLV_AUDIO_CODECID_MASK;
198 int codec_id;
199
200
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2232 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2232 if (!apar->codec_id && !apar->codec_tag)
201 return 1;
202
203
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2232 times.
2232 if (apar->bits_per_coded_sample != bits_per_coded_sample)
204 return 0;
205
206
3/10
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 253 times.
✓ Branch 3 taken 284 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1695 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
2232 switch (flv_codecid) {
207 // no distinction between S16 and S8 PCM codec flags
208 case FLV_CODECID_PCM:
209 codec_id = bits_per_coded_sample == 8
210 ? AV_CODEC_ID_PCM_U8
211 #if HAVE_BIGENDIAN
212 : AV_CODEC_ID_PCM_S16BE;
213 #else
214 : AV_CODEC_ID_PCM_S16LE;
215 #endif
216 return codec_id == apar->codec_id;
217 case FLV_CODECID_PCM_LE:
218 codec_id = bits_per_coded_sample == 8
219 ? AV_CODEC_ID_PCM_U8
220 : AV_CODEC_ID_PCM_S16LE;
221 return codec_id == apar->codec_id;
222 253 case FLV_CODECID_AAC:
223 253 return apar->codec_id == AV_CODEC_ID_AAC;
224 284 case FLV_CODECID_ADPCM:
225 284 return apar->codec_id == AV_CODEC_ID_ADPCM_SWF;
226 case FLV_CODECID_SPEEX:
227 return apar->codec_id == AV_CODEC_ID_SPEEX;
228 case FLV_CODECID_MP3:
229 return apar->codec_id == AV_CODEC_ID_MP3;
230 1695 case FLV_CODECID_NELLYMOSER_8KHZ_MONO:
231 case FLV_CODECID_NELLYMOSER_16KHZ_MONO:
232 case FLV_CODECID_NELLYMOSER:
233 1695 return apar->codec_id == AV_CODEC_ID_NELLYMOSER;
234 case FLV_CODECID_PCM_MULAW:
235 return apar->sample_rate == 8000 &&
236 apar->codec_id == AV_CODEC_ID_PCM_MULAW;
237 case FLV_CODECID_PCM_ALAW:
238 return apar->sample_rate == 8000 &&
239 apar->codec_id == AV_CODEC_ID_PCM_ALAW;
240 default:
241 return apar->codec_tag == (flv_codecid >> FLV_AUDIO_CODECID_OFFSET);
242 }
243 }
244
245 2240 static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream,
246 AVCodecParameters *apar, int flv_codecid)
247 {
248
4/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 254 times.
✓ Branch 3 taken 288 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 376 times.
✓ Branch 8 taken 1322 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
2240 switch (flv_codecid) {
249 // no distinction between S16 and S8 PCM codec flags
250 case FLV_CODECID_PCM:
251 apar->codec_id = apar->bits_per_coded_sample == 8
252 ? AV_CODEC_ID_PCM_U8
253 #if HAVE_BIGENDIAN
254 : AV_CODEC_ID_PCM_S16BE;
255 #else
256 : AV_CODEC_ID_PCM_S16LE;
257 #endif
258 break;
259 case FLV_CODECID_PCM_LE:
260 apar->codec_id = apar->bits_per_coded_sample == 8
261 ? AV_CODEC_ID_PCM_U8
262 : AV_CODEC_ID_PCM_S16LE;
263 break;
264 254 case FLV_CODECID_AAC:
265 254 apar->codec_id = AV_CODEC_ID_AAC;
266 254 break;
267 288 case FLV_CODECID_ADPCM:
268 288 apar->codec_id = AV_CODEC_ID_ADPCM_SWF;
269 288 break;
270 case FLV_CODECID_SPEEX:
271 apar->codec_id = AV_CODEC_ID_SPEEX;
272 apar->sample_rate = 16000;
273 break;
274 case FLV_CODECID_MP3:
275 apar->codec_id = AV_CODEC_ID_MP3;
276 ffstream(astream)->need_parsing = AVSTREAM_PARSE_FULL;
277 break;
278 case FLV_CODECID_NELLYMOSER_8KHZ_MONO:
279 // in case metadata does not otherwise declare samplerate
280 apar->sample_rate = 8000;
281 apar->codec_id = AV_CODEC_ID_NELLYMOSER;
282 break;
283 376 case FLV_CODECID_NELLYMOSER_16KHZ_MONO:
284 376 apar->sample_rate = 16000;
285 376 apar->codec_id = AV_CODEC_ID_NELLYMOSER;
286 376 break;
287 1322 case FLV_CODECID_NELLYMOSER:
288 1322 apar->codec_id = AV_CODEC_ID_NELLYMOSER;
289 1322 break;
290 case FLV_CODECID_PCM_MULAW:
291 apar->sample_rate = 8000;
292 apar->codec_id = AV_CODEC_ID_PCM_MULAW;
293 break;
294 case FLV_CODECID_PCM_ALAW:
295 apar->sample_rate = 8000;
296 apar->codec_id = AV_CODEC_ID_PCM_ALAW;
297 break;
298 default:
299 avpriv_request_sample(s, "Audio codec (%x)",
300 flv_codecid >> FLV_AUDIO_CODECID_OFFSET);
301 apar->codec_tag = flv_codecid >> FLV_AUDIO_CODECID_OFFSET;
302 }
303 2240 }
304
305 2154 static int flv_same_video_codec(AVCodecParameters *vpar, int flags)
306 {
307 2154 int flv_codecid = flags & FLV_VIDEO_CODECID_MASK;
308
309
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2154 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2154 if (!vpar->codec_id && !vpar->codec_tag)
310 return 1;
311
312
5/7
✓ Branch 0 taken 493 times.
✓ Branch 1 taken 271 times.
✓ Branch 2 taken 196 times.
✓ Branch 3 taken 173 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1021 times.
✗ Branch 6 not taken.
2154 switch (flv_codecid) {
313 493 case FLV_CODECID_H263:
314 493 return vpar->codec_id == AV_CODEC_ID_FLV1;
315 271 case FLV_CODECID_SCREEN:
316 271 return vpar->codec_id == AV_CODEC_ID_FLASHSV;
317 196 case FLV_CODECID_SCREEN2:
318 196 return vpar->codec_id == AV_CODEC_ID_FLASHSV2;
319 173 case FLV_CODECID_VP6:
320 173 return vpar->codec_id == AV_CODEC_ID_VP6F;
321 case FLV_CODECID_VP6A:
322 return vpar->codec_id == AV_CODEC_ID_VP6A;
323 1021 case FLV_CODECID_H264:
324 1021 return vpar->codec_id == AV_CODEC_ID_H264;
325 default:
326 return vpar->codec_tag == flv_codecid;
327 }
328 }
329
330 1890 static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream,
331 int flv_codecid, int read)
332 {
333 1890 FFStream *const vstreami = ffstream(vstream);
334 1890 int ret = 0;
335 1890 AVCodecParameters *par = vstream->codecpar;
336 1890 enum AVCodecID old_codec_id = vstream->codecpar->codec_id;
337
5/9
✓ Branch 0 taken 503 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 276 times.
✓ Branch 3 taken 200 times.
✓ Branch 4 taken 174 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 737 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
1890 switch (flv_codecid) {
338 503 case FLV_CODECID_H263:
339 503 par->codec_id = AV_CODEC_ID_FLV1;
340 503 break;
341 case FLV_CODECID_REALH263:
342 par->codec_id = AV_CODEC_ID_H263;
343 break; // Really mean it this time
344 276 case FLV_CODECID_SCREEN:
345 276 par->codec_id = AV_CODEC_ID_FLASHSV;
346 276 break;
347 200 case FLV_CODECID_SCREEN2:
348 200 par->codec_id = AV_CODEC_ID_FLASHSV2;
349 200 break;
350 174 case FLV_CODECID_VP6:
351 174 par->codec_id = AV_CODEC_ID_VP6F;
352 174 case FLV_CODECID_VP6A:
353
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 174 times.
174 if (flv_codecid == FLV_CODECID_VP6A)
354 par->codec_id = AV_CODEC_ID_VP6A;
355
1/2
✓ Branch 0 taken 174 times.
✗ Branch 1 not taken.
174 if (read) {
356
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 173 times.
174 if (par->extradata_size != 1) {
357 1 ff_alloc_extradata(par, 1);
358 }
359
1/2
✓ Branch 0 taken 174 times.
✗ Branch 1 not taken.
174 if (par->extradata)
360 174 par->extradata[0] = avio_r8(s->pb);
361 else
362 avio_skip(s->pb, 1);
363 }
364 174 ret = 1; // 1 byte body size adjustment for flv_read_packet()
365 174 break;
366 737 case FLV_CODECID_H264:
367 737 par->codec_id = AV_CODEC_ID_H264;
368 737 vstreami->need_parsing = AVSTREAM_PARSE_HEADERS;
369 737 ret = 3; // not 4, reading packet type will consume one byte
370 737 break;
371 case FLV_CODECID_MPEG4:
372 par->codec_id = AV_CODEC_ID_MPEG4;
373 ret = 3;
374 break;
375 default:
376 avpriv_request_sample(s, "Video codec (%x)", flv_codecid);
377 par->codec_tag = flv_codecid;
378 }
379
380
3/4
✓ Branch 0 taken 1861 times.
✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1861 times.
1890 if (!vstreami->need_context_update && par->codec_id != old_codec_id) {
381 avpriv_request_sample(s, "Changing the codec id midstream");
382 return AVERROR_PATCHWELCOME;
383 }
384
385 1890 return ret;
386 }
387
388 349 static int amf_get_string(AVIOContext *ioc, char *buffer, int buffsize)
389 {
390 int ret;
391 349 int length = avio_rb16(ioc);
392
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 349 times.
349 if (length >= buffsize) {
393 avio_skip(ioc, length);
394 return -1;
395 }
396
397 349 ret = avio_read(ioc, buffer, length);
398
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 349 times.
349 if (ret < 0)
399 return ret;
400
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 349 times.
349 if (ret < length)
401 return AVERROR_INVALIDDATA;
402
403 349 buffer[length] = '\0';
404
405 349 return length;
406 }
407
408 3 static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, int64_t max_pos)
409 {
410 3 FLVContext *flv = s->priv_data;
411 3 unsigned int timeslen = 0, fileposlen = 0, i;
412 char str_val[256];
413 3 int64_t *times = NULL;
414 3 int64_t *filepositions = NULL;
415 3 int ret = AVERROR(ENOSYS);
416 3 int64_t initial_pos = avio_tell(ioc);
417
418
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (flv->keyframe_count > 0) {
419 av_log(s, AV_LOG_DEBUG, "keyframes have been parsed\n");
420 return 0;
421 }
422
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 av_assert0(!flv->keyframe_times);
423
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 av_assert0(!flv->keyframe_filepositions);
424
425
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (s->flags & AVFMT_FLAG_IGNIDX)
426 return 0;
427
428
2/4
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
12 while (avio_tell(ioc) < max_pos - 2 &&
429 6 amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {
430 int64_t **current_array;
431 unsigned int arraylen;
432 int factor;
433
434 // Expect array object in context
435
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (avio_r8(ioc) != AMF_DATA_TYPE_ARRAY)
436 break;
437
438 6 arraylen = avio_rb32(ioc);
439
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (arraylen>>28)
440 break;
441
442
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
6 if (!strcmp(KEYFRAMES_TIMESTAMP_TAG , str_val) && !times) {
443 3 current_array = &times;
444 3 timeslen = arraylen;
445 3 factor = 1000;
446
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 } else if (!strcmp(KEYFRAMES_BYTEOFFSET_TAG, str_val) &&
447
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 !filepositions) {
448 3 current_array = &filepositions;
449 3 fileposlen = arraylen;
450 3 factor = 1;
451 } else
452 // unexpected metatag inside keyframes, will not use such
453 // metadata for indexing
454 break;
455
456
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (!(*current_array = av_mallocz(sizeof(**current_array) * arraylen))) {
457 ret = AVERROR(ENOMEM);
458 goto finish;
459 }
460
461
3/4
✓ Branch 0 taken 346 times.
✓ Branch 1 taken 6 times.
✓ Branch 3 taken 346 times.
✗ Branch 4 not taken.
352 for (i = 0; i < arraylen && avio_tell(ioc) < max_pos - 1; i++) {
462 double d;
463
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 346 times.
346 if (avio_r8(ioc) != AMF_DATA_TYPE_NUMBER)
464 goto invalid;
465 346 d = av_int2double(avio_rb64(ioc)) * factor;
466
3/6
✓ Branch 0 taken 346 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 346 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 346 times.
346 if (isnan(d) || d < INT64_MIN || d > INT64_MAX)
467 goto invalid;
468
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 346 times.
346 if (avio_feof(ioc))
469 goto invalid;
470 346 current_array[0][i] = d;
471 }
472
4/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
6 if (times && filepositions) {
473 // All done, exiting at a position allowing amf_parse_object
474 // to finish parsing the object
475 3 ret = 0;
476 3 break;
477 }
478 }
479
480
3/6
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
3 if (timeslen == fileposlen && fileposlen>1 && max_pos <= filepositions[0]) {
481
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 3 times.
9 for (i = 0; i < FFMIN(2,fileposlen); i++) {
482 6 flv->validate_index[i].pos = filepositions[i];
483 6 flv->validate_index[i].dts = times[i];
484 6 flv->validate_count = i + 1;
485 }
486 3 flv->keyframe_times = times;
487 3 flv->keyframe_filepositions = filepositions;
488 3 flv->keyframe_count = timeslen;
489 3 times = NULL;
490 3 filepositions = NULL;
491 } else {
492 invalid:
493 av_log(s, AV_LOG_WARNING, "Invalid keyframes object, skipping.\n");
494 }
495
496 3 finish:
497 3 av_freep(&times);
498 3 av_freep(&filepositions);
499 3 avio_seek(ioc, initial_pos, SEEK_SET);
500 3 return ret;
501 }
502
503 647 static int amf_parse_object(AVFormatContext *s, AVStream *astream,
504 AVStream *vstream, const char *key,
505 int64_t max_pos, int depth)
506 {
507 AVCodecParameters *apar, *vpar;
508 647 FLVContext *flv = s->priv_data;
509 AVIOContext *ioc;
510 AMFDataType amf_type;
511 char str_val[1024];
512 double num_val;
513 amf_date date;
514
515
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 647 times.
647 if (depth > MAX_DEPTH)
516 return AVERROR_PATCHWELCOME;
517
518 647 num_val = 0;
519 647 ioc = s->pb;
520
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 647 times.
647 if (avio_feof(ioc))
521 return AVERROR_EOF;
522 647 amf_type = avio_r8(ioc);
523
524
7/9
✓ Branch 0 taken 574 times.
✓ Branch 1 taken 23 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 30 times.
✓ Branch 6 taken 7 times.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
647 switch (amf_type) {
525 574 case AMF_DATA_TYPE_NUMBER:
526 574 num_val = av_int2double(avio_rb64(ioc));
527 574 break;
528 23 case AMF_DATA_TYPE_BOOL:
529 23 num_val = avio_r8(ioc);
530 23 break;
531 9 case AMF_DATA_TYPE_STRING:
532
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
9 if (amf_get_string(ioc, str_val, sizeof(str_val)) < 0) {
533 av_log(s, AV_LOG_ERROR, "AMF_DATA_TYPE_STRING parsing failed\n");
534 return -1;
535 }
536 9 break;
537 3 case AMF_DATA_TYPE_OBJECT:
538
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (key &&
539
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 (ioc->seekable & AVIO_SEEKABLE_NORMAL) &&
540
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 !strcmp(KEYFRAMES_TAG, key) && depth == 1)
541
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (parse_keyframes_index(s, ioc, max_pos) < 0)
542 av_log(s, AV_LOG_ERROR, "Keyframe index parsing failed\n");
543 else
544 3 add_keyframes_index(s);
545
3/4
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 3 times.
18 while (avio_tell(ioc) < max_pos - 2 &&
546 9 amf_get_string(ioc, str_val, sizeof(str_val)) > 0)
547
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
6 if (amf_parse_object(s, astream, vstream, str_val, max_pos,
548 depth + 1) < 0)
549 return -1; // if we couldn't skip, bomb out.
550
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
3 if (avio_r8(ioc) != AMF_END_OF_OBJECT) {
551 av_log(s, AV_LOG_ERROR, "Missing AMF_END_OF_OBJECT in AMF_DATA_TYPE_OBJECT\n");
552 return -1;
553 }
554 3 break;
555 case AMF_DATA_TYPE_NULL:
556 case AMF_DATA_TYPE_UNDEFINED:
557 case AMF_DATA_TYPE_UNSUPPORTED:
558 break; // these take up no additional space
559 30 case AMF_DATA_TYPE_MIXEDARRAY:
560 {
561 unsigned v;
562 30 avio_skip(ioc, 4); // skip 32-bit max array index
563
3/4
✓ Branch 1 taken 295 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 265 times.
✓ Branch 4 taken 30 times.
590 while (avio_tell(ioc) < max_pos - 2 &&
564 295 amf_get_string(ioc, str_val, sizeof(str_val)) > 0)
565 // this is the only case in which we would want a nested
566 // parse to not skip over the object
567
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 265 times.
265 if (amf_parse_object(s, astream, vstream, str_val, max_pos,
568 depth + 1) < 0)
569 return -1;
570 30 v = avio_r8(ioc);
571
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if (v != AMF_END_OF_OBJECT) {
572 av_log(s, AV_LOG_ERROR, "Missing AMF_END_OF_OBJECT in AMF_DATA_TYPE_MIXEDARRAY, found %d\n", v);
573 return -1;
574 }
575 30 break;
576 }
577 7 case AMF_DATA_TYPE_ARRAY:
578 {
579 unsigned int arraylen, i;
580
581 7 arraylen = avio_rb32(ioc);
582
3/4
✓ Branch 0 taken 346 times.
✓ Branch 1 taken 7 times.
✓ Branch 3 taken 346 times.
✗ Branch 4 not taken.
353 for (i = 0; i < arraylen && avio_tell(ioc) < max_pos - 1; i++)
583
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 346 times.
346 if (amf_parse_object(s, NULL, NULL, NULL, max_pos,
584 depth + 1) < 0)
585 return -1; // if we couldn't skip, bomb out.
586 }
587 7 break;
588 1 case AMF_DATA_TYPE_DATE:
589 // timestamp (double) and UTC offset (int16)
590 1 date.milliseconds = av_int2double(avio_rb64(ioc));
591 1 date.timezone = avio_rb16(ioc);
592 1 break;
593 default: // unsupported type, we couldn't skip
594 av_log(s, AV_LOG_ERROR, "unsupported amf type %d\n", amf_type);
595 return -1;
596 }
597
598
2/2
✓ Branch 0 taken 301 times.
✓ Branch 1 taken 346 times.
647 if (key) {
599
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 301 times.
301 apar = astream ? astream->codecpar : NULL;
600
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 301 times.
301 vpar = vstream ? vstream->codecpar : NULL;
601
602 // stream info doesn't live any deeper than the first object
603
2/2
✓ Branch 0 taken 265 times.
✓ Branch 1 taken 36 times.
301 if (depth == 1) {
604
4/4
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 228 times.
✓ Branch 2 taken 23 times.
✓ Branch 3 taken 14 times.
265 if (amf_type == AMF_DATA_TYPE_NUMBER ||
605 amf_type == AMF_DATA_TYPE_BOOL) {
606
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 221 times.
251 if (!strcmp(key, "duration"))
607 30 s->duration = num_val * AV_TIME_BASE;
608
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 197 times.
221 else if (!strcmp(key, "videodatarate") &&
609
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 0 <= (int)(num_val * 1024.0))
610 24 flv->video_bit_rate = num_val * 1024.0;
611
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 189 times.
197 else if (!strcmp(key, "audiodatarate") &&
612
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 0 <= (int)(num_val * 1024.0))
613 8 flv->audio_bit_rate = num_val * 1024.0;
614
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 189 times.
189 else if (!strcmp(key, "datastream")) {
615 AVStream *st = create_stream(s, AVMEDIA_TYPE_SUBTITLE);
616 if (!st)
617 return AVERROR(ENOMEM);
618 st->codecpar->codec_id = AV_CODEC_ID_TEXT;
619
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 165 times.
189 } else if (!strcmp(key, "framerate")) {
620 24 flv->framerate = av_d2q(num_val, 1000);
621
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 if (vstream)
622 vstream->avg_frame_rate = flv->framerate;
623
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 165 times.
165 } else if (flv->trust_metadata) {
624 if (!strcmp(key, "videocodecid") && vpar) {
625 int ret = flv_set_video_codec(s, vstream, num_val, 0);
626 if (ret < 0)
627 return ret;
628 } else if (!strcmp(key, "audiocodecid") && apar) {
629 int id = ((int)num_val) << FLV_AUDIO_CODECID_OFFSET;
630 flv_set_audio_codec(s, astream, apar, id);
631 } else if (!strcmp(key, "audiosamplerate") && apar) {
632 apar->sample_rate = num_val;
633 } else if (!strcmp(key, "audiosamplesize") && apar) {
634 apar->bits_per_coded_sample = num_val;
635 } else if (!strcmp(key, "stereo") && apar) {
636 av_channel_layout_default(&apar->ch_layout, num_val + 1);
637 } else if (!strcmp(key, "width") && vpar) {
638 vpar->width = num_val;
639 } else if (!strcmp(key, "height") && vpar) {
640 vpar->height = num_val;
641 }
642 }
643 }
644
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 256 times.
265 if (amf_type == AMF_DATA_TYPE_STRING) {
645
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 6 times.
9 if (!strcmp(key, "encoder")) {
646 3 int version = -1;
647
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (1 == sscanf(str_val, "Open Broadcaster Software v0.%d", &version)) {
648 if (version > 0 && version <= 655)
649 flv->broken_sizes = 1;
650 }
651
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 } else if (!strcmp(key, "metadatacreator")) {
652
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if ( !strcmp (str_val, "MEGA")
653
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 || !strncmp(str_val, "FlixEngine", 10))
654 flv->broken_sizes = 1;
655 }
656 }
657 }
658
659
3/6
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 298 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
301 if (amf_type == AMF_DATA_TYPE_OBJECT && s->nb_streams == 1 &&
660 ((!apar && !strcmp(key, "audiocodecid")) ||
661 (!vpar && !strcmp(key, "videocodecid"))))
662 s->ctx_flags &= ~AVFMTCTX_NOHEADER; //If there is either audio/video missing, codecid will be an empty object
663
664
2/2
✓ Branch 0 taken 271 times.
✓ Branch 1 taken 30 times.
301 if ((!strcmp(key, "duration") ||
665
2/2
✓ Branch 0 taken 242 times.
✓ Branch 1 taken 29 times.
271 !strcmp(key, "filesize") ||
666
2/2
✓ Branch 0 taken 218 times.
✓ Branch 1 taken 24 times.
242 !strcmp(key, "width") ||
667
2/2
✓ Branch 0 taken 194 times.
✓ Branch 1 taken 24 times.
218 !strcmp(key, "height") ||
668
2/2
✓ Branch 0 taken 170 times.
✓ Branch 1 taken 24 times.
194 !strcmp(key, "videodatarate") ||
669
2/2
✓ Branch 0 taken 146 times.
✓ Branch 1 taken 24 times.
170 !strcmp(key, "framerate") ||
670
2/2
✓ Branch 0 taken 122 times.
✓ Branch 1 taken 24 times.
146 !strcmp(key, "videocodecid") ||
671
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 8 times.
122 !strcmp(key, "audiodatarate") ||
672
2/2
✓ Branch 0 taken 107 times.
✓ Branch 1 taken 7 times.
114 !strcmp(key, "audiosamplerate") ||
673
2/2
✓ Branch 0 taken 100 times.
✓ Branch 1 taken 7 times.
107 !strcmp(key, "audiosamplesize") ||
674
2/2
✓ Branch 0 taken 93 times.
✓ Branch 1 taken 7 times.
100 !strcmp(key, "stereo") ||
675
2/2
✓ Branch 0 taken 85 times.
✓ Branch 1 taken 8 times.
93 !strcmp(key, "audiocodecid") ||
676
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 85 times.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
301 !strcmp(key, "datastream")) && !flv->dump_full_metadata)
677 216 return 0;
678
679 85 s->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
680
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 69 times.
85 if (amf_type == AMF_DATA_TYPE_BOOL) {
681
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
16 av_strlcpy(str_val, num_val > 0 ? "true" : "false",
682 sizeof(str_val));
683 16 av_dict_set(&s->metadata, key, str_val, 0);
684
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 50 times.
69 } else if (amf_type == AMF_DATA_TYPE_NUMBER) {
685 19 snprintf(str_val, sizeof(str_val), "%.f", num_val);
686 19 av_dict_set(&s->metadata, key, str_val, 0);
687
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 41 times.
50 } else if (amf_type == AMF_DATA_TYPE_STRING) {
688 9 av_dict_set(&s->metadata, key, str_val, 0);
689
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 40 times.
41 } else if ( amf_type == AMF_DATA_TYPE_DATE
690
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 && isfinite(date.milliseconds)
691
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 && date.milliseconds > INT64_MIN/1000
692
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 && date.milliseconds < INT64_MAX/1000
693 ) {
694 // timezone is ignored, since there is no easy way to offset the UTC
695 // timestamp into the specified timezone
696 1 avpriv_dict_set_timestamp(&s->metadata, key, 1000 * (int64_t)date.milliseconds);
697 }
698 }
699
700 431 return 0;
701 }
702
703 #define TYPE_ONTEXTDATA 1
704 #define TYPE_ONCAPTION 2
705 #define TYPE_ONCAPTIONINFO 3
706 #define TYPE_UNKNOWN 9
707
708 30 static int flv_read_metabody(AVFormatContext *s, int64_t next_pos)
709 {
710 30 FLVContext *flv = s->priv_data;
711 AMFDataType type;
712 AVStream *stream, *astream, *vstream;
713 AVStream av_unused *dstream;
714 AVIOContext *ioc;
715 int i;
716 char buffer[32];
717
718 30 astream = NULL;
719 30 vstream = NULL;
720 30 dstream = NULL;
721 30 ioc = s->pb;
722
723 // first object needs to be "onMetaData" string
724 30 type = avio_r8(ioc);
725
2/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
60 if (type != AMF_DATA_TYPE_STRING ||
726 30 amf_get_string(ioc, buffer, sizeof(buffer)) < 0)
727 return TYPE_UNKNOWN;
728
729
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if (!strcmp(buffer, "onTextData"))
730 return TYPE_ONTEXTDATA;
731
732
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if (!strcmp(buffer, "onCaption"))
733 return TYPE_ONCAPTION;
734
735
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if (!strcmp(buffer, "onCaptionInfo"))
736 return TYPE_ONCAPTIONINFO;
737
738
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
30 if (strcmp(buffer, "onMetaData") && strcmp(buffer, "onCuePoint") && strcmp(buffer, "|RtmpSampleAccess")) {
739 av_log(s, AV_LOG_DEBUG, "Unknown type %s\n", buffer);
740 return TYPE_UNKNOWN;
741 }
742
743 // find the streams now so that amf_parse_object doesn't need to do
744 // the lookup every time it is called.
745
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 for (i = 0; i < s->nb_streams; i++) {
746 stream = s->streams[i];
747 if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
748 vstream = stream;
749 flv->last_keyframe_stream_index = i;
750 } else if (stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
751 astream = stream;
752 if (flv->last_keyframe_stream_index == -1)
753 flv->last_keyframe_stream_index = i;
754 } else if (stream->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
755 dstream = stream;
756 }
757
758 // parse the second object (we want a mixed array)
759
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
30 if (amf_parse_object(s, astream, vstream, buffer, next_pos, 0) < 0)
760 return -1;
761
762 30 return 0;
763 }
764
765 30 static int flv_read_header(AVFormatContext *s)
766 {
767 int flags;
768 30 FLVContext *flv = s->priv_data;
769 int offset;
770 30 int pre_tag_size = 0;
771
772 /* Actual FLV data at 0xe40000 in KUX file */
773
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if(!strcmp(s->iformat->name, "kux"))
774 avio_skip(s->pb, 0xe40000);
775
776 30 avio_skip(s->pb, 4);
777 30 flags = avio_r8(s->pb);
778
779 30 flv->missing_streams = flags & (FLV_HEADER_FLAG_HASVIDEO | FLV_HEADER_FLAG_HASAUDIO);
780
781 30 s->ctx_flags |= AVFMTCTX_NOHEADER;
782
783 30 offset = avio_rb32(s->pb);
784 30 avio_seek(s->pb, offset, SEEK_SET);
785
786 /* Annex E. The FLV File Format
787 * E.3 TheFLVFileBody
788 * Field Type Comment
789 * PreviousTagSize0 UI32 Always 0
790 * */
791 30 pre_tag_size = avio_rb32(s->pb);
792
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if (pre_tag_size) {
793 av_log(s, AV_LOG_WARNING, "Read FLV header error, input file is not a standard flv format, first PreviousTagSize0 always is 0\n");
794 }
795
796 30 s->start_time = 0;
797 30 flv->sum_flv_tag_size = 0;
798 30 flv->last_keyframe_stream_index = -1;
799
800 30 return 0;
801 }
802
803 30 static int flv_read_close(AVFormatContext *s)
804 {
805 int i;
806 30 FLVContext *flv = s->priv_data;
807
2/2
✓ Branch 0 taken 120 times.
✓ Branch 1 taken 30 times.
150 for (i=0; i<FLV_STREAM_TYPE_NB; i++)
808 120 av_freep(&flv->new_extradata[i]);
809 30 av_freep(&flv->keyframe_times);
810 30 av_freep(&flv->keyframe_filepositions);
811 30 return 0;
812 }
813
814 5 static int flv_get_extradata(AVFormatContext *s, AVStream *st, int size)
815 {
816 int ret;
817
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (!size)
818 return 0;
819
820
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
5 if ((ret = ff_get_extradata(s, st->codecpar, s->pb, size)) < 0)
821 return ret;
822 5 ffstream(st)->need_context_update = 1;
823 5 return 0;
824 }
825
826 2 static int flv_queue_extradata(FLVContext *flv, AVIOContext *pb, int stream,
827 int size)
828 {
829
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!size)
830 return 0;
831
832 2 av_free(flv->new_extradata[stream]);
833 2 flv->new_extradata[stream] = av_mallocz(size +
834 AV_INPUT_BUFFER_PADDING_SIZE);
835
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!flv->new_extradata[stream])
836 return AVERROR(ENOMEM);
837 2 flv->new_extradata_size[stream] = size;
838 2 avio_read(pb, flv->new_extradata[stream], size);
839 2 return 0;
840 }
841
842 1 static void clear_index_entries(AVFormatContext *s, int64_t pos)
843 {
844 1 av_log(s, AV_LOG_WARNING,
845 "Found invalid index entries, clearing the index.\n");
846
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 for (unsigned i = 0; i < s->nb_streams; i++) {
847 1 FFStream *const sti = ffstream(s->streams[i]);
848 1 int out = 0;
849 /* Remove all index entries that point to >= pos */
850
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 1 times.
133 for (int j = 0; j < sti->nb_index_entries; j++)
851
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 131 times.
132 if (sti->index_entries[j].pos < pos)
852 1 sti->index_entries[out++] = sti->index_entries[j];
853 1 sti->nb_index_entries = out;
854 }
855 1 }
856
857 static int amf_skip_tag(AVIOContext *pb, AMFDataType type, int depth)
858 {
859 int nb = -1, ret, parse_name = 1;
860
861 if (depth > MAX_DEPTH)
862 return AVERROR_PATCHWELCOME;
863
864 if (avio_feof(pb))
865 return AVERROR_EOF;
866
867 switch (type) {
868 case AMF_DATA_TYPE_NUMBER:
869 avio_skip(pb, 8);
870 break;
871 case AMF_DATA_TYPE_BOOL:
872 avio_skip(pb, 1);
873 break;
874 case AMF_DATA_TYPE_STRING:
875 avio_skip(pb, avio_rb16(pb));
876 break;
877 case AMF_DATA_TYPE_ARRAY:
878 parse_name = 0;
879 case AMF_DATA_TYPE_MIXEDARRAY:
880 nb = avio_rb32(pb);
881 if (nb < 0)
882 return AVERROR_INVALIDDATA;
883 case AMF_DATA_TYPE_OBJECT:
884 while(!pb->eof_reached && (nb-- > 0 || type != AMF_DATA_TYPE_ARRAY)) {
885 if (parse_name) {
886 int size = avio_rb16(pb);
887 if (!size) {
888 avio_skip(pb, 1);
889 break;
890 }
891 avio_skip(pb, size);
892 }
893 if ((ret = amf_skip_tag(pb, avio_r8(pb), depth + 1)) < 0)
894 return ret;
895 }
896 break;
897 case AMF_DATA_TYPE_NULL:
898 case AMF_DATA_TYPE_OBJECT_END:
899 break;
900 default:
901 return AVERROR_INVALIDDATA;
902 }
903 return 0;
904 }
905
906 static int flv_data_packet(AVFormatContext *s, AVPacket *pkt,
907 int64_t dts, int64_t next)
908 {
909 AVIOContext *pb = s->pb;
910 AVStream *st = NULL;
911 char buf[20];
912 int ret = AVERROR_INVALIDDATA;
913 int i, length = -1;
914 int array = 0;
915
916 switch (avio_r8(pb)) {
917 case AMF_DATA_TYPE_ARRAY:
918 array = 1;
919 case AMF_DATA_TYPE_MIXEDARRAY:
920 avio_seek(pb, 4, SEEK_CUR);
921 case AMF_DATA_TYPE_OBJECT:
922 break;
923 default:
924 goto skip;
925 }
926
927 while (array || (ret = amf_get_string(pb, buf, sizeof(buf))) > 0) {
928 AMFDataType type = avio_r8(pb);
929 if (type == AMF_DATA_TYPE_STRING && (array || !strcmp(buf, "text"))) {
930 length = avio_rb16(pb);
931 ret = av_get_packet(pb, pkt, length);
932 if (ret < 0)
933 goto skip;
934 else
935 break;
936 } else {
937 if ((ret = amf_skip_tag(pb, type, 0)) < 0)
938 goto skip;
939 }
940 }
941
942 if (length < 0) {
943 ret = AVERROR_INVALIDDATA;
944 goto skip;
945 }
946
947 for (i = 0; i < s->nb_streams; i++) {
948 st = s->streams[i];
949 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
950 break;
951 }
952
953 if (i == s->nb_streams) {
954 st = create_stream(s, AVMEDIA_TYPE_SUBTITLE);
955 if (!st)
956 return AVERROR(ENOMEM);
957 st->codecpar->codec_id = AV_CODEC_ID_TEXT;
958 }
959
960 pkt->dts = dts;
961 pkt->pts = dts;
962 pkt->size = ret;
963
964 pkt->stream_index = st->index;
965 pkt->flags |= AV_PKT_FLAG_KEY;
966
967 skip:
968 avio_seek(s->pb, next + 4, SEEK_SET);
969
970 return ret;
971 }
972
973 static int resync(AVFormatContext *s)
974 {
975 FLVContext *flv = s->priv_data;
976 int64_t i;
977 int64_t pos = avio_tell(s->pb);
978
979 for (i=0; !avio_feof(s->pb); i++) {
980 int j = i & (RESYNC_BUFFER_SIZE-1);
981 int j1 = j + RESYNC_BUFFER_SIZE;
982 flv->resync_buffer[j ] =
983 flv->resync_buffer[j1] = avio_r8(s->pb);
984
985 if (i >= 8 && pos) {
986 uint8_t *d = flv->resync_buffer + j1 - 8;
987 if (d[0] == 'F' &&
988 d[1] == 'L' &&
989 d[2] == 'V' &&
990 d[3] < 5 && d[5] == 0) {
991 av_log(s, AV_LOG_WARNING, "Concatenated FLV detected, might fail to demux, decode and seek %"PRId64"\n", flv->last_ts);
992 flv->time_offset = flv->last_ts + 1;
993 flv->time_pos = avio_tell(s->pb);
994 }
995 }
996
997 if (i > 22) {
998 unsigned lsize2 = AV_RB32(flv->resync_buffer + j1 - 4);
999 if (lsize2 >= 11 && lsize2 + 8LL < FFMIN(i, RESYNC_BUFFER_SIZE)) {
1000 unsigned size2 = AV_RB24(flv->resync_buffer + j1 - lsize2 + 1 - 4);
1001 unsigned lsize1 = AV_RB32(flv->resync_buffer + j1 - lsize2 - 8);
1002 if (lsize1 >= 11 && lsize1 + 8LL + lsize2 < FFMIN(i, RESYNC_BUFFER_SIZE)) {
1003 unsigned size1 = AV_RB24(flv->resync_buffer + j1 - lsize1 + 1 - lsize2 - 8);
1004 if (size1 == lsize1 - 11 && size2 == lsize2 - 11) {
1005 avio_seek(s->pb, pos + i - lsize1 - lsize2 - 8, SEEK_SET);
1006 return 1;
1007 }
1008 }
1009 }
1010 }
1011 }
1012 return AVERROR_EOF;
1013 }
1014
1015 4508 static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
1016 {
1017 4508 FLVContext *flv = s->priv_data;
1018 int ret, i, size, flags;
1019 enum FlvTagType type;
1020 4508 int stream_type=-1;
1021 int64_t next, pos, meta_pos;
1022 4508 int64_t dts, pts = AV_NOPTS_VALUE;
1023 4508 int av_uninit(channels);
1024 4508 int av_uninit(sample_rate);
1025 4508 AVStream *st = NULL;
1026 4508 int last = -1;
1027 int orig_size;
1028
1029 4508 retry:
1030 /* pkt size is repeated at end. skip it */
1031 4508 pos = avio_tell(s->pb);
1032 4508 type = (avio_r8(s->pb) & 0x1F);
1033 4508 orig_size =
1034 4508 size = avio_rb24(s->pb);
1035 4508 flv->sum_flv_tag_size += size + 11LL;
1036 4508 dts = avio_rb24(s->pb);
1037 4508 dts |= (unsigned)avio_r8(s->pb) << 24;
1038 4508 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));
1039
2/2
✓ Branch 1 taken 60 times.
✓ Branch 2 taken 4448 times.
4508 if (avio_feof(s->pb))
1040 60 return AVERROR_EOF;
1041 4448 avio_skip(s->pb, 3); /* stream id, always 0 */
1042 4448 flags = 0;
1043
1044
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 4429 times.
4448 if (flv->validate_next < flv->validate_count) {
1045 19 int64_t validate_pos = flv->validate_index[flv->validate_next].pos;
1046
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 14 times.
19 if (pos == validate_pos) {
1047
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 if (FFABS(dts - flv->validate_index[flv->validate_next].dts) <=
1048 VALIDATE_INDEX_TS_THRESH) {
1049 5 flv->validate_next++;
1050 } else {
1051 clear_index_entries(s, validate_pos);
1052 flv->validate_count = 0;
1053 }
1054
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 13 times.
14 } else if (pos > validate_pos) {
1055 1 clear_index_entries(s, validate_pos);
1056 1 flv->validate_count = 0;
1057 }
1058 }
1059
1060
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4448 times.
4448 if (size == 0) {
1061 ret = FFERROR_REDO;
1062 goto leave;
1063 }
1064
1065 4448 next = size + avio_tell(s->pb);
1066
1067
2/2
✓ Branch 0 taken 2240 times.
✓ Branch 1 taken 2208 times.
4448 if (type == FLV_TAG_TYPE_AUDIO) {
1068 2240 stream_type = FLV_STREAM_TYPE_AUDIO;
1069 2240 flags = avio_r8(s->pb);
1070 2240 size--;
1071
2/2
✓ Branch 0 taken 2178 times.
✓ Branch 1 taken 30 times.
2208 } else if (type == FLV_TAG_TYPE_VIDEO) {
1072 2178 stream_type = FLV_STREAM_TYPE_VIDEO;
1073 2178 flags = avio_r8(s->pb);
1074 2178 size--;
1075
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2178 times.
2178 if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_VIDEO_INFO_CMD)
1076 goto skip;
1077
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 } else if (type == FLV_TAG_TYPE_META) {
1078 30 stream_type=FLV_STREAM_TYPE_SUBTITLE;
1079
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if (size > 13 + 1 + 4) { // Header-type metadata stuff
1080 int type;
1081 30 meta_pos = avio_tell(s->pb);
1082 30 type = flv_read_metabody(s, next);
1083
2/6
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
30 if (type == 0 && dts == 0 || type < 0) {
1084
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
30 if (type < 0 && flv->validate_count &&
1085 flv->validate_index[0].pos > next &&
1086 flv->validate_index[0].pos - 4 < next) {
1087 av_log(s, AV_LOG_WARNING, "Adjusting next position due to index mismatch\n");
1088 next = flv->validate_index[0].pos - 4;
1089 }
1090 30 goto skip;
1091 } else if (type == TYPE_ONTEXTDATA) {
1092 avpriv_request_sample(s, "OnTextData packet");
1093 return flv_data_packet(s, pkt, dts, next);
1094 } else if (type == TYPE_ONCAPTION) {
1095 return flv_data_packet(s, pkt, dts, next);
1096 } else if (type == TYPE_UNKNOWN) {
1097 stream_type = FLV_STREAM_TYPE_DATA;
1098 }
1099 avio_seek(s->pb, meta_pos, SEEK_SET);
1100 }
1101 } else {
1102 av_log(s, AV_LOG_DEBUG,
1103 "Skipping flv packet: type %d, size %d, flags %d.\n",
1104 type, size, flags);
1105 30 skip:
1106
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
30 if (avio_seek(s->pb, next, SEEK_SET) != next) {
1107 // This can happen if flv_read_metabody above read past
1108 // next, on a non-seekable input, and the preceding data has
1109 // been flushed out from the IO buffer.
1110 av_log(s, AV_LOG_ERROR, "Unable to seek to the next packet\n");
1111 return AVERROR_INVALIDDATA;
1112 }
1113 30 ret = FFERROR_REDO;
1114 30 goto leave;
1115 }
1116
1117 /* skip empty data packets */
1118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4418 times.
4418 if (!size) {
1119 ret = FFERROR_REDO;
1120 goto leave;
1121 }
1122
1123 /* now find stream */
1124
2/2
✓ Branch 0 taken 5595 times.
✓ Branch 1 taken 32 times.
5627 for (i = 0; i < s->nb_streams; i++) {
1125 5595 st = s->streams[i];
1126
2/2
✓ Branch 0 taken 3441 times.
✓ Branch 1 taken 2154 times.
5595 if (stream_type == FLV_STREAM_TYPE_AUDIO) {
1127
2/2
✓ Branch 0 taken 2232 times.
✓ Branch 1 taken 1209 times.
3441 if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
1128
2/4
✓ Branch 0 taken 2232 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2232 times.
2232 (s->audio_codec_id || flv_same_audio_codec(st->codecpar, flags)))
1129 break;
1130
1/2
✓ Branch 0 taken 2154 times.
✗ Branch 1 not taken.
2154 } else if (stream_type == FLV_STREAM_TYPE_VIDEO) {
1131
1/2
✓ Branch 0 taken 2154 times.
✗ Branch 1 not taken.
2154 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
1132
2/4
✓ Branch 0 taken 2154 times.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2154 times.
2154 (s->video_codec_id || flv_same_video_codec(st->codecpar, flags)))
1133 break;
1134 } else if (stream_type == FLV_STREAM_TYPE_SUBTITLE) {
1135 if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
1136 break;
1137 } else if (stream_type == FLV_STREAM_TYPE_DATA) {
1138 if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA)
1139 break;
1140 }
1141 }
1142
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 4386 times.
4418 if (i == s->nb_streams) {
1143 static const enum AVMediaType stream_types[] = {AVMEDIA_TYPE_VIDEO, AVMEDIA_TYPE_AUDIO, AVMEDIA_TYPE_SUBTITLE, AVMEDIA_TYPE_DATA};
1144 32 st = create_stream(s, stream_types[stream_type]);
1145
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32 times.
32 if (!st)
1146 return AVERROR(ENOMEM);
1147 }
1148 4418 av_log(s, AV_LOG_TRACE, "%d %X %d \n", stream_type, flags, st->discard);
1149
1150
1/2
✓ Branch 0 taken 4418 times.
✗ Branch 1 not taken.
4418 if (flv->time_pos <= pos) {
1151 4418 dts += flv->time_offset;
1152 }
1153
1154
1/2
✓ Branch 0 taken 4418 times.
✗ Branch 1 not taken.
4418 if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
1155
4/4
✓ Branch 0 taken 3657 times.
✓ Branch 1 taken 761 times.
✓ Branch 2 taken 1952 times.
✓ Branch 3 taken 1705 times.
4418 ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY ||
1156 stream_type == FLV_STREAM_TYPE_AUDIO))
1157 2713 av_add_index_entry(st, pos, dts, size, 0, AVINDEX_KEYFRAME);
1158
1159
5/6
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 4130 times.
✓ Branch 2 taken 278 times.
✓ Branch 3 taken 10 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 278 times.
4418 if ((st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || stream_type == FLV_STREAM_TYPE_AUDIO)) ||
1160
3/6
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 4130 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
4140 (st->discard >= AVDISCARD_BIDIR && ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && stream_type == FLV_STREAM_TYPE_VIDEO)) ||
1161
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 4130 times.
4140 st->discard >= AVDISCARD_ALL) {
1162 288 avio_seek(s->pb, next, SEEK_SET);
1163 288 ret = FFERROR_REDO;
1164 288 goto leave;
1165 }
1166
1167 // if not streamed and no duration from metadata then seek to end to find
1168 // the duration from the timestamps
1169
1/2
✓ Branch 0 taken 4130 times.
✗ Branch 1 not taken.
4130 if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
1170
2/4
✓ Branch 0 taken 4130 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4130 times.
4130 (!s->duration || s->duration == AV_NOPTS_VALUE) &&
1171 !flv->searched_for_end) {
1172 int size;
1173 const int64_t pos = avio_tell(s->pb);
1174 // Read the last 4 bytes of the file, this should be the size of the
1175 // previous FLV tag. Use the timestamp of its payload as duration.
1176 int64_t fsize = avio_size(s->pb);
1177 retry_duration:
1178 avio_seek(s->pb, fsize - 4, SEEK_SET);
1179 size = avio_rb32(s->pb);
1180 if (size > 0 && size < fsize) {
1181 // Seek to the start of the last FLV tag at position (fsize - 4 - size)
1182 // but skip the byte indicating the type.
1183 avio_seek(s->pb, fsize - 3 - size, SEEK_SET);
1184 if (size == avio_rb24(s->pb) + 11) {
1185 uint32_t ts = avio_rb24(s->pb);
1186 ts |= (unsigned)avio_r8(s->pb) << 24;
1187 if (ts)
1188 s->duration = ts * (int64_t)AV_TIME_BASE / 1000;
1189 else if (fsize >= 8 && fsize - 8 >= size) {
1190 fsize -= size+4;
1191 goto retry_duration;
1192 }
1193 }
1194 }
1195
1196 avio_seek(s->pb, pos, SEEK_SET);
1197 flv->searched_for_end = 1;
1198 }
1199
1200
2/2
✓ Branch 0 taken 2240 times.
✓ Branch 1 taken 1890 times.
4130 if (stream_type == FLV_STREAM_TYPE_AUDIO) {
1201 int bits_per_coded_sample;
1202
2/2
✓ Branch 0 taken 542 times.
✓ Branch 1 taken 1698 times.
2240 channels = (flags & FLV_AUDIO_CHANNEL_MASK) == FLV_STEREO ? 2 : 1;
1203 2240 sample_rate = 44100 << ((flags & FLV_AUDIO_SAMPLERATE_MASK) >>
1204 FLV_AUDIO_SAMPLERATE_OFFSET) >> 3;
1205
1/2
✓ Branch 0 taken 2240 times.
✗ Branch 1 not taken.
2240 bits_per_coded_sample = (flags & FLV_AUDIO_SAMPLESIZE_MASK) ? 16 : 8;
1206
2/2
✓ Branch 1 taken 2232 times.
✓ Branch 2 taken 8 times.
2240 if (!av_channel_layout_check(&st->codecpar->ch_layout) ||
1207
1/2
✓ Branch 0 taken 2232 times.
✗ Branch 1 not taken.
2232 !st->codecpar->sample_rate ||
1208
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2232 times.
2232 !st->codecpar->bits_per_coded_sample) {
1209 8 av_channel_layout_default(&st->codecpar->ch_layout, channels);
1210 8 st->codecpar->sample_rate = sample_rate;
1211 8 st->codecpar->bits_per_coded_sample = bits_per_coded_sample;
1212 }
1213
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2232 times.
2240 if (!st->codecpar->codec_id) {
1214 8 flv_set_audio_codec(s, st, st->codecpar,
1215 flags & FLV_AUDIO_CODECID_MASK);
1216 8 flv->last_sample_rate =
1217 8 sample_rate = st->codecpar->sample_rate;
1218 8 flv->last_channels =
1219 8 channels = st->codecpar->ch_layout.nb_channels;
1220 } else {
1221 2232 AVCodecParameters *par = avcodec_parameters_alloc();
1222
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2232 times.
2232 if (!par) {
1223 ret = AVERROR(ENOMEM);
1224 goto leave;
1225 }
1226 2232 par->sample_rate = sample_rate;
1227 2232 par->bits_per_coded_sample = bits_per_coded_sample;
1228 2232 flv_set_audio_codec(s, st, par, flags & FLV_AUDIO_CODECID_MASK);
1229 2232 sample_rate = par->sample_rate;
1230 2232 avcodec_parameters_free(&par);
1231 }
1232
1/2
✓ Branch 0 taken 1890 times.
✗ Branch 1 not taken.
1890 } else if (stream_type == FLV_STREAM_TYPE_VIDEO) {
1233 1890 int ret = flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK, 1);
1234
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1890 times.
1890 if (ret < 0)
1235 return ret;
1236 1890 size -= ret;
1237 } else if (stream_type == FLV_STREAM_TYPE_SUBTITLE) {
1238 st->codecpar->codec_id = AV_CODEC_ID_TEXT;
1239 } else if (stream_type == FLV_STREAM_TYPE_DATA) {
1240 st->codecpar->codec_id = AV_CODEC_ID_NONE; // Opaque AMF data
1241 }
1242
1243
2/2
✓ Branch 0 taken 3876 times.
✓ Branch 1 taken 254 times.
4130 if (st->codecpar->codec_id == AV_CODEC_ID_AAC ||
1244
2/2
✓ Branch 0 taken 3139 times.
✓ Branch 1 taken 737 times.
3876 st->codecpar->codec_id == AV_CODEC_ID_H264 ||
1245
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3139 times.
3139 st->codecpar->codec_id == AV_CODEC_ID_MPEG4) {
1246 991 int type = avio_r8(s->pb);
1247 991 size--;
1248
1249
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 991 times.
991 if (size < 0) {
1250 ret = AVERROR_INVALIDDATA;
1251 goto leave;
1252 }
1253
1254
3/4
✓ Branch 0 taken 254 times.
✓ Branch 1 taken 737 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 254 times.
991 if (st->codecpar->codec_id == AV_CODEC_ID_H264 || st->codecpar->codec_id == AV_CODEC_ID_MPEG4) {
1255 // sign extension
1256 737 int32_t cts = (avio_rb24(s->pb) + 0xff800000) ^ 0xff800000;
1257 737 pts = av_sat_add64(dts, cts);
1258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 737 times.
737 if (cts < 0) { // dts might be wrong
1259 if (!flv->wrong_dts)
1260 av_log(s, AV_LOG_WARNING,
1261 "Negative cts, previous timestamps might be wrong.\n");
1262 flv->wrong_dts = 1;
1263
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 737 times.
737 } else if (FFABS(dts - pts) > 1000*60*15) {
1264 av_log(s, AV_LOG_WARNING,
1265 "invalid timestamps %"PRId64" %"PRId64"\n", dts, pts);
1266 dts = pts = AV_NOPTS_VALUE;
1267 }
1268 }
1269
6/6
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 984 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
991 if (type == 0 && (!st->codecpar->extradata || st->codecpar->codec_id == AV_CODEC_ID_AAC ||
1270
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 st->codecpar->codec_id == AV_CODEC_ID_H264)) {
1271 AVDictionaryEntry *t;
1272
1273
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 5 times.
7 if (st->codecpar->extradata) {
1274
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if ((ret = flv_queue_extradata(flv, s->pb, stream_type, size)) < 0)
1275 return ret;
1276 2 ret = FFERROR_REDO;
1277 2 goto leave;
1278 }
1279
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
5 if ((ret = flv_get_extradata(s, st, size)) < 0)
1280 return ret;
1281
1282 /* Workaround for buggy Omnia A/XE encoder */
1283 5 t = av_dict_get(s->metadata, "Encoder", NULL, 0);
1284
3/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
5 if (st->codecpar->codec_id == AV_CODEC_ID_AAC && t && !strcmp(t->value, "Omnia A/XE"))
1285 st->codecpar->extradata_size = 2;
1286
1287 5 ret = FFERROR_REDO;
1288 5 goto leave;
1289 }
1290 }
1291
1292 /* skip empty data packets */
1293
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4119 times.
4123 if (!size) {
1294 4 ret = FFERROR_REDO;
1295 4 goto leave;
1296 }
1297
1298 4119 ret = av_get_packet(s->pb, pkt, size);
1299
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4119 times.
4119 if (ret < 0)
1300 return ret;
1301 4119 pkt->dts = dts;
1302
2/2
✓ Branch 0 taken 3391 times.
✓ Branch 1 taken 728 times.
4119 pkt->pts = pts == AV_NOPTS_VALUE ? dts : pts;
1303 4119 pkt->stream_index = st->index;
1304 4119 pkt->pos = pos;
1305
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4117 times.
4119 if (flv->new_extradata[stream_type]) {
1306 2 int ret = av_packet_add_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA,
1307 flv->new_extradata[stream_type],
1308 2 flv->new_extradata_size[stream_type]);
1309
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (ret >= 0) {
1310 2 flv->new_extradata[stream_type] = NULL;
1311 2 flv->new_extradata_size[stream_type] = 0;
1312 }
1313 }
1314
2/2
✓ Branch 0 taken 2238 times.
✓ Branch 1 taken 1881 times.
4119 if (stream_type == FLV_STREAM_TYPE_AUDIO &&
1315
1/2
✓ Branch 0 taken 2238 times.
✗ Branch 1 not taken.
2238 (sample_rate != flv->last_sample_rate ||
1316
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2238 times.
2238 channels != flv->last_channels)) {
1317 flv->last_sample_rate = sample_rate;
1318 flv->last_channels = channels;
1319 ff_add_param_change(pkt, channels, 0, sample_rate, 0, 0);
1320 }
1321
1322
2/2
✓ Branch 0 taken 1881 times.
✓ Branch 1 taken 2238 times.
4119 if (stream_type == FLV_STREAM_TYPE_AUDIO ||
1323
3/4
✓ Branch 0 taken 1427 times.
✓ Branch 1 taken 454 times.
✓ Branch 2 taken 1427 times.
✗ Branch 3 not taken.
1881 (flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY ||
1324
1/2
✓ Branch 0 taken 1427 times.
✗ Branch 1 not taken.
1427 stream_type == FLV_STREAM_TYPE_SUBTITLE ||
1325 stream_type == FLV_STREAM_TYPE_DATA)
1326 2692 pkt->flags |= AV_PKT_FLAG_KEY;
1327
1328 1427 leave:
1329 4448 last = avio_rb32(s->pb);
1330
1/2
✓ Branch 0 taken 4448 times.
✗ Branch 1 not taken.
4448 if (!flv->trust_datasize) {
1331
4/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4447 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
4449 if (last != orig_size + 11 && last != orig_size + 10 &&
1332
0/2
✗ Branch 1 not taken.
✗ Branch 2 not taken.
1 !avio_feof(s->pb) &&
1333 (last != orig_size || !last) && last != flv->sum_flv_tag_size &&
1334 !flv->broken_sizes) {
1335 av_log(s, AV_LOG_ERROR, "Packet mismatch %d %d %"PRId64"\n", last, orig_size + 11, flv->sum_flv_tag_size);
1336 avio_seek(s->pb, pos + 1, SEEK_SET);
1337 ret = resync(s);
1338 av_packet_unref(pkt);
1339 if (ret >= 0) {
1340 goto retry;
1341 }
1342 }
1343 }
1344
1345
2/2
✓ Branch 0 taken 4119 times.
✓ Branch 1 taken 329 times.
4448 if (ret >= 0)
1346 4119 flv->last_ts = pkt->dts;
1347
1348 4448 return ret;
1349 }
1350
1351 289 static int flv_read_seek(AVFormatContext *s, int stream_index,
1352 int64_t ts, int flags)
1353 {
1354 289 FLVContext *flv = s->priv_data;
1355 289 flv->validate_count = 0;
1356 289 return avio_seek_time(s->pb, stream_index, ts, flags);
1357 }
1358
1359 #define OFFSET(x) offsetof(FLVContext, x)
1360 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
1361 static const AVOption options[] = {
1362 { "flv_metadata", "Allocate streams according to the onMetaData array", OFFSET(trust_metadata), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VD },
1363 { "flv_full_metadata", "Dump full metadata of the onMetadata", OFFSET(dump_full_metadata), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VD },
1364 { "flv_ignore_prevtag", "Ignore the Size of previous tag", OFFSET(trust_datasize), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VD },
1365 { "missing_streams", "", OFFSET(missing_streams), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 0xFF, VD | AV_OPT_FLAG_EXPORT | AV_OPT_FLAG_READONLY },
1366 { NULL }
1367 };
1368
1369 static const AVClass flv_kux_class = {
1370 .class_name = "(live) flv/kux demuxer",
1371 .item_name = av_default_item_name,
1372 .option = options,
1373 .version = LIBAVUTIL_VERSION_INT,
1374 };
1375
1376 const AVInputFormat ff_flv_demuxer = {
1377 .name = "flv",
1378 .long_name = NULL_IF_CONFIG_SMALL("FLV (Flash Video)"),
1379 .priv_data_size = sizeof(FLVContext),
1380 .read_probe = flv_probe,
1381 .read_header = flv_read_header,
1382 .read_packet = flv_read_packet,
1383 .read_seek = flv_read_seek,
1384 .read_close = flv_read_close,
1385 .extensions = "flv",
1386 .priv_class = &flv_kux_class,
1387 };
1388
1389 const AVInputFormat ff_live_flv_demuxer = {
1390 .name = "live_flv",
1391 .long_name = NULL_IF_CONFIG_SMALL("live RTMP FLV (Flash Video)"),
1392 .priv_data_size = sizeof(FLVContext),
1393 .read_probe = live_flv_probe,
1394 .read_header = flv_read_header,
1395 .read_packet = flv_read_packet,
1396 .read_seek = flv_read_seek,
1397 .read_close = flv_read_close,
1398 .extensions = "flv",
1399 .priv_class = &flv_kux_class,
1400 .flags = AVFMT_TS_DISCONT
1401 };
1402
1403 const AVInputFormat ff_kux_demuxer = {
1404 .name = "kux",
1405 .long_name = NULL_IF_CONFIG_SMALL("KUX (YouKu)"),
1406 .priv_data_size = sizeof(FLVContext),
1407 .read_probe = kux_probe,
1408 .read_header = flv_read_header,
1409 .read_packet = flv_read_packet,
1410 .read_seek = flv_read_seek,
1411 .read_close = flv_read_close,
1412 .extensions = "kux",
1413 .priv_class = &flv_kux_class,
1414 };
1415