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 4bits: difference between encoded width and visible width
8 * - lower 4bits: 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
39
40 #define VALIDATE_INDEX_TS_THRESH 2500
41
43 const AVClass *
class;
///< Class for private options.
50 struct {
53 } validate_index[2];
58
60 {
62
64 if (d[0] ==
'F' && d[1] ==
'L' && d[2] ==
'V' && d[3] < 5 && d[5]==0 &&
AV_RB32(d+5)>8) {
66 }
67 return 0;
68 }
69
71 {
73 if (!st)
74 return NULL;
80
82 return st;
83 }
85 {
89
91 return 1;
92
94 return 0;
95
96 switch(flv_codecid) {
97 //no distinction between S16 and S8 PCM codec flags
100 #if HAVE_BIGENDIAN
102 #else
104 #endif
105 return codec_id == acodec->
codec_id;
108 return codec_id == acodec->
codec_id;
127 default:
129 }
130 }
131
133 switch(flv_codecid) {
134 //no distinction between S16 and S8 PCM codec flags
137 #if HAVE_BIGENDIAN
139 #else
141 #endif
142 break;
150 break;
153 acodec->
sample_rate = 8000;
//in case metadata does not otherwise declare samplerate
155 break;
159 break;
162 break;
166 break;
170 break;
171 default:
174 }
175 }
176
178 {
180
182 return 1;
183
184 switch (flv_codecid) {
197 default:
199 }
200 }
201
204 switch(flv_codecid) {
213 if (read) {
218 }
221 else
223 }
224 return 1; // 1 byte body size adjustment for flv_read_packet()
227 return 3; // not 4, reading packet type will consume one byte
230 return 3;
231 default:
234 }
235
236 return 0;
237 }
238
241 if(length >= buffsize) {
243 return -1;
244 }
245
247
249
251 }
252
255 unsigned int timeslen = 0, fileposlen = 0, i;
256 char str_val[256];
257 int64_t *times = NULL;
258 int64_t *filepositions = NULL;
261
264 return 0;
265 }
266
268 return 0;
269
271 int64_t** current_array;
272 unsigned int arraylen;
273
274 // Expect array object in context
276 break;
277
279 if(arraylen>>28)
280 break;
281
283 current_array= ×
284 timeslen= arraylen;
286 current_array= &filepositions;
287 fileposlen= arraylen;
288 }else // unexpected metatag inside keyframes, will not use such metadata for indexing
289 break;
290
291 if (!(*current_array =
av_mallocz(
sizeof(**current_array) * arraylen))) {
294 }
295
296 for (i = 0; i < arraylen &&
avio_tell(ioc) < max_pos - 1; i++) {
298 goto invalid;
300 }
301 if (times && filepositions) {
302 // All done, exiting at a position allowing amf_parse_object
303 // to finish parsing the object
304 ret = 0;
305 break;
306 }
307 }
308
309 if (timeslen == fileposlen && fileposlen>1 && max_pos <= filepositions[0]) {
310 for (i = 0; i < fileposlen; i++) {
313 if (i < 2) {
317 }
318 }
319 } else {
320 invalid:
322 }
323
329 }
330
336 char str_val[256];
337 double num_val;
338
339 num_val = 0;
341
343
344 switch(amf_type) {
351 return -1;
352 break;
356 max_pos) < 0)
358
361 return -1; //if we couldn't skip, bomb out.
362 }
364 return -1;
365 break;
369 break; //these take up no additional space
371 avio_skip(ioc, 4);
//skip 32-bit max array index
373 //this is the only case in which we would want a nested parse to not skip over the object
375 return -1;
376 }
378 return -1;
379 break;
381 unsigned int arraylen, i;
382
384 for(i = 0; i < arraylen &&
avio_tell(ioc) < max_pos - 1; i++) {
386 return -1; //if we couldn't skip, bomb out.
387 }
388 }
389 break;
391 avio_skip(ioc, 8 + 2);
//timestamp (double) and UTC offset (int16)
392 break;
393 default: //unsupported type, we couldn't skip
394 return -1;
395 }
396
397 if(depth == 1 && key) { //only look for metadata values when we are not nested and key != NULL
398 acodec = astream ? astream->
codec : NULL;
399 vcodec = vstream ? vstream->
codec : NULL;
400
402 if (!strcmp(key, "duration"))
404 else if (!strcmp(key, "videodatarate") && vcodec && 0 <= (int)(num_val * 1024.0))
405 vcodec->
bit_rate = num_val * 1024.0;
406 else if (!strcmp(key, "audiodatarate") && acodec && 0 <= (int)(num_val * 1024.0))
407 acodec->
bit_rate = num_val * 1024.0;
408 else if (!strcmp(key, "datastream")) {
410 if (!st)
414 if (!strcmp(key, "videocodecid") && vcodec) {
416 } else
417 if (!strcmp(key, "audiocodecid") && acodec) {
420 } else
421 if (!strcmp(key, "audiosamplerate") && acodec) {
423 } else if (!strcmp(key, "audiosamplesize") && acodec) {
425 } else if (!strcmp(key, "stereo") && acodec) {
430 } else
431 if (!strcmp(key, "width") && vcodec) {
432 vcodec->
width = num_val;
433 } else
434 if (!strcmp(key, "height") && vcodec) {
436 }
437 }
438 }
439
441 ((!acodec && !strcmp(key, "audiocodecid")) ||
442 (!vcodec && !strcmp(key, "videocodecid"))))
444
445 if (!strcmp(key, "duration") ||
446 !strcmp(key, "filesize") ||
447 !strcmp(key, "width") ||
448 !strcmp(key, "height") ||
449 !strcmp(key, "videodatarate") ||
450 !strcmp(key, "framerate") ||
451 !strcmp(key, "videocodecid") ||
452 !strcmp(key, "audiodatarate") ||
453 !strcmp(key, "audiosamplerate") ||
454 !strcmp(key, "audiosamplesize") ||
455 !strcmp(key, "stereo") ||
456 !strcmp(key, "audiocodecid"))
457 return 0;
458
460 av_strlcpy(str_val, num_val > 0 ?
"true" :
"false",
sizeof(str_val));
463 snprintf(str_val,
sizeof(str_val),
"%.f", num_val);
467 }
468
469 return 0;
470 }
471
474 AVStream *stream, *astream, *vstream, *dstream;
476 int i;
477 char buffer[11];
//only needs to hold the string "onMetaData". Anything longer is something we don't want.
478
479 vstream = astream = dstream = NULL;
481
482 //first object needs to be "onMetaData" string
486 return -1;
487
488 if (!strcmp(buffer, "onTextData"))
489 return 1;
490
491 if (strcmp(buffer, "onMetaData"))
492 return -1;
493
494 //find the streams now so that amf_parse_object doesn't need to do the lookup every time it is called.
500 }
501
502 //parse the second object (we want a mixed array)
504 return -1;
505
506 return 0;
507 }
508
510 {
512
515 /* old flvtool cleared this field */
516 /* FIXME: better fix needed */
517 if (!flags) {
520 }
521
523
527 }
531 }
532 // Flag doesn't indicate whether or not there is script-data present. Must
533 // create that stream if it's encountered.
534
538
540
541 return 0;
542 }
543
545 {
546 int i;
550 return 0;
551 }
552
554 {
561 return 0;
562 }
563
566 {
573 return 0;
574 }
575
577 {
582 /* Remove all index entries that point to >= pos */
583 out = 0;
587 }
589 }
590 }
591
592
594 int64_t dts, int64_t next)
595 {
602
608
612
614 //FIXME parse it as codec_id
618
621 if (ret < 0) {
624 }
625
629 break;
630 }
631
634 if (!st)
637 }
638
642
645
649 }
650
652 {
655 int stream_type=-1;
656 int64_t next, pos, meta_pos;
661
662 for(;;
avio_skip(s->
pb, 4)){
/* pkt size is repeated at end. skip it */
668 av_dlog(s,
"type:%d, size:%d, dts:%"PRId64
"\n", type, size, dts);
672 flags = 0;
673
676 if (pos == validate_pos) {
680 } else {
683 }
684 } else if (pos > validate_pos) {
687 }
688 }
689
690 if(size == 0)
691 continue;
692
694
698 size--;
702 size--;
704 goto skip;
707 if (size > 13+1+4 && dts == 0) { // Header-type metadata stuff
710 goto skip;
711 }
713 }
714 } else {
715 av_log(s,
AV_LOG_DEBUG,
"skipping flv packet: type %d, size %d, flags %d\n", type, size, flags);
716 skip:
718 continue;
719 }
720
721 /* skip empty data packets */
722 if (!size)
723 continue;
724
725 /* now find stream */
731 break;
732 }
733 } else
737 break;
738 }
741 break;
742 }
743 }
748 stream_types[stream_type]);
749 if (!st)
751
752 }
757 ){
759 continue;
760 }
763 break;
764 }
765
766 // if not streamed and no duration from metadata then seek to end to find the duration from the timestamps
771 retry_duration:
778 if(ts)
780 else if (fsize >= 8 && fsize - 8 >= size){
781 fsize -= size+4;
782 goto retry_duration;
783 }
784 }
785
788 }
789
791 int bits_per_coded_sample;
801 }
806 } else {
811 }
814 }
815
820 size--;
823 pts = dts + cts;
824 if (cts < 0) { // dts are wrong
827 }
830 }
836 goto leave;
837 }
848 else
850 av_dlog(s,
"mp4a config channels %d sample rate %d\n",
852 }
853 }
854
856 goto leave;
857 }
858 }
859
860 /* skip empty data packets */
861 if (!size) {
863 goto leave;
864 }
865
867 if (ret < 0)
875 if (side) {
880 }
881 }
887 }
888
893
894 leave:
897 }
898
900 int64_t ts,
int flags)
901 {
905 }
906
907 #define OFFSET(x) offsetof(FLVContext, x)
908 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
910 {
"flv_metadata",
"Allocate streams according the onMetaData array",
OFFSET(trust_metadata),
AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1,
VD},
911 { NULL }
912 };
913
919 };
920
930 .extensions = "flv",
931 .priv_class = &flv_class,
932 };