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