1 /*
2 * fileinfo.c
3 *
4 * Copyright (C) Thomas Oestreich - June 2001
5 *
6 * This file is part of transcode, a video stream processing tool
7 *
8 * transcode is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * transcode is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with GNU Make; see the file COPYING. If not, write to
20 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
24 #include "config.h"
25
26 #ifdef HAVE_LIBDV
27 #include <libdv/dv.h>
28 #endif
29
30 #include <sys/types.h>
31 #include <unistd.h>
32 #include <fcntl.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include "libtc/libtc.h"
36 #include "libtc/xio.h"
37 #include "ioaux.h"
38 #include "tc.h"
39
40 /* forward declaration */
41 static int scan_header_dv(const char *buf);
42
43 unsigned char asfhdrguid[16]={0x30,0x26,0xB2,0x75,0x8E,0x66,0xCF,0x11,0xA6,0xD9,0x00,0xAA,0x00,0x62,0xCE,0x6C};
44
45 unsigned char mxfmagic[]={0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01};
46
47 unsigned char zero_pad[4]={0,0,0,0};
48
cmp_32_bits(char * buf,long x)49 static int cmp_32_bits(char *buf, long x)
50 {
51
52 if(0) {
53 tc_log_msg(__FILE__, "MAGIC: 0x%02lx 0x%02lx 0x%02lx 0x%02lx %s", (x >> 24) & 0xff, ((x >> 16) & 0xff), ((x >> 8) & 0xff), ((x ) & 0xff), filetype(x));
54 tc_log_msg(__FILE__, " FILE: 0x%02x 0x%02x 0x%02x 0x%02x", buf[0] & 0xff, buf[1] & 0xff, buf[2] & 0xff, buf[3] & 0xff);
55 }
56
57 if ((uint8_t)buf[0] != ((x >> 24) & 0xff))
58 return 0;
59 if ((uint8_t)buf[1] != ((x >> 16) & 0xff))
60 return 0;
61 if ((uint8_t)buf[2] != ((x >> 8) & 0xff))
62 return 0;
63 if ((uint8_t)buf[3] != ((x ) & 0xff))
64 return 0;
65
66 // OK found it
67 return 1;
68 }
69
cmp_28_bits(char * buf,long x)70 static int cmp_28_bits(char *buf, long x)
71 {
72
73 if(0) {
74 tc_log_msg(__FILE__, "MAGIC: 0x%02lx 0x%02lx 0x%02lx 0x%02lx %s", (x >> 24) & 0xff, ((x >> 16) & 0xff), ((x >> 8) & 0xff), ((x ) & 0xff), filetype(x));
75 tc_log_msg(__FILE__, " FILE: 0x%02x 0x%02x 0x%02x 0x%02x", buf[0] & 0xff, buf[1] & 0xff, buf[2] & 0xff, buf[3] & 0xff);
76 }
77
78 if ((uint8_t)buf[0] != ((x >> 24) & 0xff))
79 return 0;
80 if ((uint8_t)buf[1] != ((x >> 16) & 0xff))
81 return 0;
82 if ((uint8_t)buf[2] != ((x >> 8) & 0xff))
83 return 0;
84 if ((uint8_t)(buf[3] & 0xf0) != ((x ) & 0xff))
85 return 0;
86
87 // OK found it
88 return 1;
89 }
90
91
cmp_16_bits(char * buf,long x)92 static int cmp_16_bits(char *buf, long x)
93 {
94
95 int16_t sync_word=0;
96
97 if(0) {
98 tc_log_msg(__FILE__, "MAGIC: 0x%02lx 0x%02lx 0x%02lx 0x%02lx %s", (x >> 24) & 0xff, ((x >> 16) & 0xff), ((x >> 8) & 0xff), ((x ) & 0xff), filetype(x));
99 tc_log_msg(__FILE__, " FILE: 0x%02x 0x%02x 0x%02x 0x%02x", buf[0] & 0xff, buf[1] & 0xff, buf[2] & 0xff, buf[3] & 0xff);
100 }
101
102 sync_word = (sync_word << 8) + (uint8_t) buf[0];
103 sync_word = (sync_word << 8) + (uint8_t) buf[1];
104
105 if(sync_word == (int16_t) x) return 1;
106
107 // not found;
108 return 0;
109 }
110
save_read(char * buf,int bytes,off_t offset,int fdes)111 static int save_read(char *buf, int bytes, off_t offset, int fdes)
112 {
113
114 // returns 0 if ok, 1 on failure to read first bytes
115
116 // rewind
117 if(xio_lseek(fdes, offset, SEEK_SET)<0) {
118 tc_log_warn(__FILE__, "[%s:%d] file seek error: %s",
119 __FILE__, __LINE__, strerror(errno));
120 return(1);
121 }
122
123 if(xio_read(fdes, buf, bytes)<bytes) {
124 tc_log_warn(__FILE__, "[%s:%d] file read error: %s",
125 __FILE__, __LINE__, strerror(errno));
126 return(1);
127 }
128
129 return(0);
130 }
131
132 #define MAX_PROBE_BYTES 4096
133
fileinfo(int fdes,int skip)134 long fileinfo(int fdes, int skip)
135 {
136
137 char buf[MAX_PROBE_BYTES];
138
139 off_t off=0;
140
141 int cc=0;
142
143 long id=TC_MAGIC_UNKNOWN, offset;
144
145 // assume this is a valid file descriptor
146
147 // are we at offset defined by skip?
148 if((offset = xio_lseek(fdes, skip, SEEK_CUR)) < 0) {
149 if(errno==ESPIPE) return(TC_MAGIC_PIPE);
150 return(TC_MAGIC_ERROR);
151 }
152
153 // refuse to work with a file not at offset 0
154 if(offset != skip) {
155 tc_log_error(__FILE__, "file pointer not at requested offset %d - exit", skip);
156 return(TC_MAGIC_ERROR);
157 }
158
159 off +=skip;
160
161 /* -------------------------------------------------------------------
162 *
163 * zero padding detection
164 *
165 *-------------------------------------------------------------------*/
166
167 if(save_read(buf, 4, off, fdes)) goto exit;
168
169 while(memcmp(buf, zero_pad, 4)==0) {
170 off +=4; //preserves byte order
171 if(off> TC_MAX_SEEK_BYTES) goto exit;
172 if(save_read(buf, 4, off, fdes)) goto exit;
173 }
174
175 if(off<0) goto exit;
176
177 //tc_log_msg(__FILE__, "off=%d '%c' '%c' '%c' '%c'", off, buf[0], buf[1], buf[2], buf[3]);
178
179
180 /* -------------------------------------------------------------------
181 *
182 * 2 byte section, read 4 bytes
183 *
184 *-------------------------------------------------------------------*/
185
186 if(save_read(buf, 4, off, fdes)) goto exit;
187
188 // AC3
189
190 if(cmp_16_bits(buf, TC_MAGIC_AC3)) {
191 id = TC_MAGIC_AC3;
192 goto exit;
193 }
194
195 // MP3 audio
196
197 if(cmp_16_bits(buf, TC_MAGIC_MP3)) {
198 id = TC_MAGIC_MP3;
199 goto exit;
200 }
201
202 if(cmp_16_bits(buf, TC_MAGIC_MP3_2_5)) {
203 id = TC_MAGIC_MP3_2_5;
204 goto exit;
205 }
206
207 if(cmp_16_bits(buf, TC_MAGIC_MP3_2)) {
208 id = TC_MAGIC_MP3_2;
209 goto exit;
210 }
211
212 // MP2 audio
213
214 if(cmp_16_bits(buf, TC_MAGIC_MP2) || cmp_16_bits(buf, TC_MAGIC_MP2_FC)) {
215 id = TC_MAGIC_MP2;
216 goto exit;
217 }
218
219 if ( ((((buf[0]<<8)&0xff00)|buf[1])&0xfff8) == 0xfff0) {
220 if ( (buf[1]&0x02) == 0x02) {
221 id = TC_MAGIC_MP3;
222 goto exit;
223 }
224 if ( (buf[1]&0x01) == 0x01) {
225 id = TC_MAGIC_MP2;
226 goto exit;
227 }
228 }
229
230 // TIFF image
231
232 if (cmp_16_bits(buf, TC_MAGIC_TIFF1)) {
233 id = TC_MAGIC_TIFF1;
234 goto exit;
235 }
236 if (cmp_16_bits(buf, TC_MAGIC_TIFF2)) {
237 id = TC_MAGIC_TIFF2;
238 goto exit;
239 }
240
241 // BMP image
242
243 if (cmp_16_bits(buf, TC_MAGIC_BMP)) {
244 id = TC_MAGIC_BMP;
245 goto exit;
246 }
247
248 // SGI image
249
250 if (cmp_16_bits(buf, TC_MAGIC_SGI)) {
251 id = TC_MAGIC_SGI;
252 goto exit;
253 }
254
255 // PPM image
256
257 if (strncmp (buf, "P6", 2)==0) {
258 id = TC_MAGIC_PPM;
259 goto exit;
260 }
261
262 // PGM image
263
264 if (strncmp (buf, "P5", 2)==0) {
265 id = TC_MAGIC_PGM;
266 goto exit;
267 }
268
269 // SGI image
270
271 if (cmp_16_bits(buf, TC_MAGIC_SGI)) {
272 id = TC_MAGIC_SGI;
273 goto exit;
274 }
275
276
277 // transport stream
278
279 if (buf[0] == (uint8_t) TC_MAGIC_TS) {
280 id = TC_MAGIC_TS;
281 goto exit;
282 }
283
284
285 /* -------------------------------------------------------------------
286 *
287 * 4 byte section
288 *
289 *-------------------------------------------------------------------*/
290
291 if(save_read(buf, 4, off, fdes)) goto exit;
292
293
294 // DTS
295
296 if(cmp_32_bits(buf, TC_MAGIC_DTS)) {
297 id = TC_MAGIC_DTS;
298 goto exit;
299 }
300
301 // VOB
302
303 if(cmp_32_bits(buf, TC_MAGIC_VOB)) {
304 id = TC_MAGIC_VOB;
305 goto exit;
306 }
307
308 // MPEG Video / .VDR
309
310 if(cmp_28_bits(buf, TC_MAGIC_MPEG)) {
311 id = TC_MAGIC_MPEG; /* FIXME: it's PES? */
312 goto exit;
313 }
314
315 // DV
316
317 if(cmp_32_bits(buf, TC_MAGIC_DV_NTSC)) {
318 id = TC_MAGIC_DV_NTSC;
319 goto exit;
320 }
321
322 // DV
323
324 if(cmp_32_bits(buf, TC_MAGIC_DV_PAL)) {
325 id = TC_MAGIC_DV_PAL;
326 goto exit;
327 }
328
329 // OGG stream
330
331 if (strncmp (buf, "OggS", 4)==0) {
332 id = TC_MAGIC_OGG;
333 goto exit;
334 }
335
336 // M2V
337
338 if(cmp_32_bits(buf, TC_MAGIC_M2V)) {
339 id = TC_MAGIC_MPEG_ES;
340 goto exit;
341 }
342
343 // NUV
344
345 if(cmp_32_bits(buf, TC_MAGIC_NUV)) {
346 id = TC_MAGIC_NUV;
347 goto exit;
348 }
349
350 // OGG
351
352 if (strncasecmp(buf, "OggS", 4) == 0) {
353 id = TC_MAGIC_OGG;
354 goto exit;
355 }
356
357 // Real Media
358 if(strncasecmp(buf,".RMF", 4)==0) {
359 id = TC_MAGIC_RMF;
360 goto exit;
361 }
362
363 // PV3
364 if (memcmp(buf, "PV3\1", 4) == 0 || memcmp(buf, "PV3\2", 4) == 0) {
365 id = TC_MAGIC_PV3;
366 goto exit;
367 }
368
369 // PVN
370 if (buf[0]=='P' && buf[1]=='V'
371 && (buf[2]>='4' && buf[2]<='6')
372 && (buf[3]=='a' || buf[3]=='b' || buf[3]=='d' || buf[3]=='f')
373 ) {
374 id = TC_MAGIC_PVN;
375 goto exit;
376 }
377
378
379 // MP3 audio + odd 0 padding
380
381 if(cmp_16_bits(buf+1, TC_MAGIC_MP3)) {
382 id = TC_MAGIC_MP3;
383 goto exit;
384 }
385
386 if(cmp_16_bits(buf+1, TC_MAGIC_MP3_2_5)) {
387 id = TC_MAGIC_MP3_2_5;
388 goto exit;
389 }
390
391 if(cmp_16_bits(buf+1, TC_MAGIC_MP3_2)) {
392 id = TC_MAGIC_MP3_2;
393 goto exit;
394 }
395
396 if(cmp_16_bits(buf+2, TC_MAGIC_MP3)) {
397 id = TC_MAGIC_MP3;
398 goto exit;
399 }
400
401 if(cmp_16_bits(buf+2, TC_MAGIC_MP3_2_5)) {
402 id = TC_MAGIC_MP3_2_5;
403 goto exit;
404 }
405
406 if(cmp_16_bits(buf+2, TC_MAGIC_MP3_2)) {
407 id = TC_MAGIC_MP3_2;
408 goto exit;
409 }
410
411 if(cmp_32_bits(buf, TC_MAGIC_ID3)) {
412 id = TC_MAGIC_ID3;
413 goto exit;
414 }
415
416 // iTunes sets an ID3 header that way at the beginning. We search for an
417 // syncword first so it should just work.
418 if (buf[0] == 'I' && buf[1] == 'D' && buf[2] == '3' && buf[3] == 0x02) {
419 id = TC_MAGIC_MP3;
420 goto exit;
421 }
422
423 /* -------------------------------------------------------------------
424 *
425 * 8 byte section
426 *
427 *-------------------------------------------------------------------*/
428
429 if(save_read(buf, 8, off, fdes)) goto exit;
430
431 // YUV4MPEG
432
433 if (strncmp (buf, "YUV4MPEG", 8)==0) {
434 id = TC_MAGIC_YUV4MPEG;
435 goto exit;
436 }
437
438 // BSDAV
439
440 if (strncmp (buf, "BSDAV", 5)==0) {
441 id = TC_MAGIC_BSDAV;
442 goto exit;
443 }
444
445 // MOV
446
447 if(strncasecmp(buf+4,"moov", 4) ==0 ||
448 strncasecmp(buf+4,"cmov", 4) ==0 ||
449 strncasecmp(buf+4,"mdat", 4) ==0 ||
450 strncasecmp(buf+4,"ftyp", 4) ==0 ||
451 strncasecmp(buf+4,"pnot", 4) ==0) {
452 id = TC_MAGIC_MOV;
453 goto exit;
454 }
455
456 // PNG
457
458 if (cmp_32_bits(buf, TC_MAGIC_PNG) &&
459 cmp_32_bits(buf+4, 0x0D0A1A0A)) {
460 id = TC_MAGIC_PNG;
461 goto exit;
462 }
463
464 // GIF
465
466 if (strncasecmp(buf, "GIF87a", 6) == 0 ||
467 strncasecmp(buf, "GIF89a", 6) == 0) {
468 id = TC_MAGIC_GIF;
469 goto exit;
470 }
471
472 // XML
473
474 if(strncasecmp(buf,"<?xml", 5) ==0) {
475 id = TC_MAGIC_XML;
476 goto exit;
477 }
478
479 // vncrec log file
480
481 if(strncasecmp(buf,"vncLog",6) ==0 ) {
482 id = TC_MAGIC_VNC;
483 goto exit;
484 }
485
486
487 /* -------------------------------------------------------------------
488 *
489 * 12 byte section
490 *
491 *-------------------------------------------------------------------*/
492
493
494 if(save_read(buf, 12, off, fdes)) goto exit;
495
496 // YUV4MPEG2
497
498 if (strncmp (buf, "YUV4MPEG2", 9)==0) {
499 id = TC_MAGIC_YUV4MPEG;
500 goto exit;
501 }
502
503 // AVI
504 if(strncasecmp(buf ,"RIFF",4) ==0 &&
505 strncasecmp(buf+8,"AVI ",4) ==0 ) {
506 id = TC_MAGIC_AVI;
507 goto exit;
508 }
509
510 // JPEG
511 if (cmp_32_bits(buf, TC_MAGIC_JPEG) &&
512 strncasecmp(buf+6, "JFIF", 4) == 0) {
513 id = TC_MAGIC_JPEG;
514 goto exit;
515 }
516 if (cmp_16_bits(buf, 0xFFD8)) {
517 id = TC_MAGIC_JPEG;
518 goto exit;
519 }
520
521 // WAVE
522 if(strncasecmp(buf ,"RIFF",4) ==0 &&
523 strncasecmp(buf+8,"WAVE",4) ==0 ) {
524 id = TC_MAGIC_WAV;
525 goto exit;
526 }
527
528 // CDXA
529 if(strncasecmp(buf ,"RIFF",4) ==0 &&
530 strncasecmp(buf+8,"CDXA",4) ==0 ) {
531 id = TC_MAGIC_CDXA;
532 goto exit;
533 }
534
535
536 /* -------------------------------------------------------------------
537 *
538 * 16 byte section
539 *
540 *-------------------------------------------------------------------*/
541
542 if(save_read(buf, 16, off, fdes)) goto exit;
543
544 //ASF
545 if(memcmp(asfhdrguid,buf,16)==0) {
546 id = TC_MAGIC_ASF;
547 goto exit;
548 }
549
550 //MXF
551 if(memcmp(mxfmagic,buf,sizeof(mxfmagic))==0) {
552 id = TC_MAGIC_MXF;
553 goto exit;
554 }
555
556 // MOV
557
558 if(strncasecmp(buf+12,"moov", 4) ==0 ||
559 strncasecmp(buf+12,"cmov", 4) ==0 ||
560 strncasecmp(buf+12,"mdat", 4) ==0 ||
561 strncasecmp(buf+12,"pnot", 4) ==0) {
562 id = TC_MAGIC_MOV;
563 goto exit;
564 }
565
566 /* -------------------------------------------------------------------
567 *
568 * more tests
569 *
570 *-------------------------------------------------------------------*/
571
572 if(save_read(buf, MAX_PROBE_BYTES, off, fdes)) goto exit;
573
574 //DV
575 cc=scan_header_dv(buf);
576
577 if(cc==1) {
578 id = TC_MAGIC_DV_PAL;
579 goto exit;
580 }
581
582 if(cc==2) {
583 id = TC_MAGIC_DV_NTSC;
584 goto exit;
585 }
586
587 /* -------------------------------------------------------------------
588 *
589 * exit
590 *
591 *-------------------------------------------------------------------*/
592
593 exit:
594 // reset file pointer
595 xio_lseek(fdes, 0, SEEK_SET);
596 return(id);
597 }
598
streaminfo(int fdes)599 long streaminfo(int fdes)
600 {
601
602 char buf[64];
603
604 long id=TC_MAGIC_UNKNOWN;
605
606 // assume this is a valid file descriptor
607
608 int bytes=16, ret=0;
609
610 if( (ret = tc_pread(fdes, buf, bytes))<bytes) {
611 if (ret)
612 tc_log_error(__FILE__, "File too short (must be 16 bytes at least)");
613 else
614 tc_log_error(__FILE__, "stream read error: %s", strerror(errno));
615 return(TC_MAGIC_ERROR);
616 }
617
618 /* -------------------------------------------------------------------
619 *
620 * 2 byte section
621 *
622 *-------------------------------------------------------------------*/
623
624 // AC3
625
626 if(cmp_16_bits(buf, TC_MAGIC_AC3)) {
627 id = TC_MAGIC_AC3;
628 goto exit;
629 }
630
631 // MPEG audio
632
633 if(cmp_16_bits(buf, TC_MAGIC_MP3)) {
634 id = TC_MAGIC_MP3;
635 goto exit;
636 }
637
638 if(cmp_16_bits(buf, TC_MAGIC_MP3_2_5)) {
639 id = TC_MAGIC_MP3_2_5;
640 goto exit;
641 }
642
643 if(cmp_16_bits(buf, TC_MAGIC_MP3_2)) {
644 id = TC_MAGIC_MP3_2;
645 goto exit;
646 }
647
648 // transport stream
649
650 if (buf[0] == (uint8_t) TC_MAGIC_TS) {
651 id = TC_MAGIC_TS;
652 goto exit;
653 }
654
655 /* -------------------------------------------------------------------
656 *
657 * 4 byte section
658 *
659 *-------------------------------------------------------------------*/
660
661 // DTS
662
663 if(cmp_32_bits(buf, TC_MAGIC_DTS)) {
664 id = TC_MAGIC_DTS;
665 goto exit;
666 }
667
668 // VOB
669
670 if(cmp_32_bits(buf, TC_MAGIC_VOB)) {
671 id = TC_MAGIC_VOB;
672 goto exit;
673 }
674
675 // DV
676
677 if(cmp_32_bits(buf, TC_MAGIC_DV_NTSC)) {
678 id = TC_MAGIC_DV_NTSC;
679 goto exit;
680 }
681
682 // DV
683
684 if(cmp_32_bits(buf, TC_MAGIC_DV_PAL)) {
685 id = TC_MAGIC_DV_PAL;
686 goto exit;
687 }
688
689 // M2V
690
691 if(cmp_32_bits(buf, TC_MAGIC_M2V)) {
692 id = TC_MAGIC_MPEG_ES;
693 goto exit;
694 }
695
696 // MPEG Video / .VDR
697
698 if(cmp_32_bits(buf, TC_MAGIC_MPEG)) {
699 id = TC_MAGIC_MPEG; /* FIXME: it's PES? */
700 goto exit;
701 }
702
703 // NUV
704
705 if(cmp_32_bits(buf, TC_MAGIC_NUV)) {
706 id = TC_MAGIC_NUV;
707 goto exit;
708 }
709
710 // MP3 audio + odd 0 padding
711
712 if(cmp_16_bits(buf+1, TC_MAGIC_MP3)) {
713 id = TC_MAGIC_MP3;
714 goto exit;
715 }
716
717 if(cmp_16_bits(buf+1, TC_MAGIC_MP3_2_5)) {
718 id = TC_MAGIC_MP3_2_5;
719 goto exit;
720 }
721
722 if(cmp_16_bits(buf+1, TC_MAGIC_MP3_2)) {
723 id = TC_MAGIC_MP3_2;
724 goto exit;
725 }
726
727 if(cmp_16_bits(buf+2, TC_MAGIC_MP3)) {
728 id = TC_MAGIC_MP3;
729 goto exit;
730 }
731
732 if(cmp_16_bits(buf+2, TC_MAGIC_MP3_2_5)) {
733 id = TC_MAGIC_MP3_2_5;
734 goto exit;
735 }
736
737 if(cmp_16_bits(buf+2, TC_MAGIC_MP3_2)) {
738 id = TC_MAGIC_MP3_2;
739 goto exit;
740 }
741
742 // transport stream
743
744 if (cmp_16_bits(buf, TC_MAGIC_TS)) {
745 id = TC_MAGIC_TS;
746 goto exit;
747 }
748
749
750 /* -------------------------------------------------------------------
751 *
752 * 8 byte section
753 *
754 *-------------------------------------------------------------------*/
755
756 // YUV4MPEG
757
758 if (strncmp (buf, "YUV4MPEG", 8)==0) {
759 id = TC_MAGIC_YUV4MPEG;
760 goto exit;
761 }
762
763 // MOV
764
765 if(strncasecmp(buf+4,"moov", 4) ==0 ||
766 strncasecmp(buf+4,"cmov", 4) ==0 ||
767 strncasecmp(buf+4,"mdat", 4) ==0 ||
768 strncasecmp(buf+4,"pnot", 4) ==0) {
769 id = TC_MAGIC_MOV;
770 goto exit;
771 }
772
773
774 /* -------------------------------------------------------------------
775 *
776 * 12 byte section
777 *
778 *-------------------------------------------------------------------*/
779
780 // WAVE
781 if(strncasecmp(buf ,"RIFF",4) ==0 &&
782 strncasecmp(buf+8,"WAVE",4) ==0 ) {
783 id = TC_MAGIC_WAV;
784 goto exit;
785 }
786
787 // OGG
788
789 if (strncasecmp(buf, "OggS", 4) == 0) {
790 id = TC_MAGIC_OGG;
791 goto exit;
792 }
793
794 /* -------------------------------------------------------------------
795 *
796 * 16 byte section
797 *
798 *-------------------------------------------------------------------*/
799
800 if(memcmp(asfhdrguid,buf,16)==0) {
801 id = TC_MAGIC_ASF;
802 goto exit;
803 }
804
805 //MXF
806 if(memcmp(mxfmagic,buf,sizeof(mxfmagic))==0) {
807 id = TC_MAGIC_MXF;
808 goto exit;
809 }
810
811 /* -------------------------------------------------------------------
812 *
813 * exit
814 *
815 *-------------------------------------------------------------------*/
816
817 exit:
818
819 return(id);
820 }
821
filetype(uint32_t magic)822 const char *filetype(uint32_t magic)
823 {
824
825 switch(magic) {
826
827 case TC_MAGIC_TS: return("MPEG transport stream (TS)");
828 case TC_MAGIC_MPEG_PS: /* fallthrough */
829 case TC_MAGIC_VOB: return("MPEG program stream (PS)");
830 case TC_MAGIC_MPEG_ES: /* fallthrough */
831 case TC_MAGIC_M2V: return("MPEG elementary stream (ES)");
832 case TC_MAGIC_MPEG_PES: /* fallthrough */
833 case TC_MAGIC_MPEG: return("MPEG packetized elementary stream (PES)");
834 case TC_MAGIC_AVI: return("RIFF data, AVI video");
835 case TC_MAGIC_WAV: return("RIFF data, WAVE audio");
836 case TC_MAGIC_CDXA: return("RIFF data, CDXA");
837 case TC_MAGIC_MOV: return("Apple QuickTime movie file");
838 case TC_MAGIC_ASF: return("advanced streaming format ASF");
839 case TC_MAGIC_TIFF1:
840 case TC_MAGIC_TIFF2: return("TIFF image");
841 case TC_MAGIC_JPEG: return("JPEG image");
842 case TC_MAGIC_BMP: return("BMP image");
843 case TC_MAGIC_PNG: return("PNG image");
844 case TC_MAGIC_GIF: return("GIF image");
845 case TC_MAGIC_PPM: return("PPM image");
846 case TC_MAGIC_PGM: return("PGM image");
847 case TC_MAGIC_SGI: return("SGI image");
848 case TC_MAGIC_RMF: return("Real Media");
849 case TC_MAGIC_XML: return("XML file, need to analyze the content");
850 case TC_MAGIC_MXF: return("The Material eXchange Format");
851 case TC_MAGIC_OGG: return("OGG Multimedia Container");
852
853 case TC_MAGIC_RAW: return("RAW stream");
854 case TC_MAGIC_AC3: return("AC3 stream");
855 case TC_MAGIC_DTS: return("DTS stream");
856 case TC_MAGIC_MP3: return("MPEG-1 layer-3 stream");
857 case TC_MAGIC_MP3_2: return("MPEG-2 layer-3 stream");
858 case TC_MAGIC_MP3_2_5: return("MPEG-2.5 layer-3 stream");
859 case TC_MAGIC_MP2: return("MP2 stream");
860 case TC_MAGIC_ID3: return("MPEG audio ID3 tag");
861
862 case TC_MAGIC_DV_NTSC: return("Digital Video (NTSC)");
863 case TC_MAGIC_DV_PAL: return("Digital Video (PAL)");
864 case TC_MAGIC_DVD: return("DVD image/device");
865 case TC_MAGIC_DVD_PAL: return("PAL DVD image/device");
866 case TC_MAGIC_DVD_NTSC: return("NTSC DVD image/device");
867 case TC_MAGIC_YUV4MPEG: return("YUV4MPEG stream");
868 case TC_MAGIC_NUV: return("NuppelVideo stream");
869 case TC_MAGIC_VNC: return("VNCrec logfile");
870 case TC_MAGIC_PV3: return("PV3 video");
871
872 case TC_MAGIC_V4L_AUDIO: return("V4L audio device");
873 case TC_MAGIC_V4L_VIDEO: return("V4L video device");
874 case TC_MAGIC_BKTR_VIDEO: return("bktr video device");
875 case TC_MAGIC_SUNAU_AUDIO: return("sunau audio device");
876 case TC_MAGIC_BSDAV: return("bsdav stream");
877 case TC_MAGIC_OSS_AUDIO: return("OSS audio device");
878 case TC_MAGIC_PIPE: return("pipe/fifo (not seekable)");
879 case TC_MAGIC_MPLAYER: return("probed by mplayer");
880 case TC_MAGIC_X11: return("X11 display source");
881 case TC_MAGIC_ERROR: return("error");
882 case TC_MAGIC_UNKNOWN:
883 default: return("unknown file type");
884 }
885 }
886
scan_header_dv(const char * buf)887 static int scan_header_dv(const char *buf)
888 {
889 int cc = -1;
890 #ifdef HAVE_LIBDV
891 dv_decoder_t *dv_decoder = dv_decoder_new(TRUE, FALSE, FALSE);
892
893 // Initialize DV decoder
894
895 if (dv_decoder == NULL) {
896 tc_log_error(__FILE__, "dv decoder init failed");
897 return(-1);
898 }
899
900 dv_decoder->prev_frame_decoded = 0;
901 cc = dv_parse_header(dv_decoder, buf);
902
903 dv_decoder_free(dv_decoder);
904 #endif
905 return(cc);
906 }
907
908