1 /*
2 * probe.c - probe input file for parameters
3 * Written by Andrew Church <achurch@achurch.org>
4 *
5 * This file is part of transcode, a video stream processing tool.
6 * transcode is free software, distributable under the terms of the GNU
7 * General Public License (version 2 or later). See the file COPYING
8 * for details.
9 */
10
11 #include "transcode.h"
12 #include "probe.h"
13 #include "libtc/libtc.h"
14 #include "libtc/tccodecs.h"
15 #include "libtc/ratiocodes.h"
16 #include "import/magic.h"
17
18 #include <sys/wait.h> // for waitpid()
19
20 /*************************************************************************/
21
22 /* Handy macro to check whether the probe flags allow setting of a
23 * particular field (pass the flag name without TC_PROBE_NO_): */
24 #define MAY_SET(flagname) (!(flags & TC_PROBE_NO_##flagname))
25
26 /* Internal routine declarations: */
27
28 static int do_probe(const char *file, const char *nav_seek_file, int title,
29 int range, int mplayer_flag, int verbose_flag,
30 ProbeInfo *info_ret);
31 static void select_modules(int flags, vob_t *vob);
32
33 /*************************************************************************/
34 /*************************************************************************/
35
36 /* External interfaces */
37
38 /*************************************************************************/
39
40 /**
41 * probe_stream_data: Probe a single source file and store the stream
42 * informations in data structure.
43 *
44 * Parameters:
45 * file: File name to probe.
46 * range: Amount of input file to probe, in MB.
47 * info: Structure to be filled in with probed data.
48 * Return value:
49 * Nonzero on success, zero on error.
50 * Preconditions:
51 * info != NULL, range > 0
52 */
probe_stream_data(const char * file,int range,ProbeInfo * info)53 int probe_stream_data(const char *file, int range, ProbeInfo *info)
54 {
55 if (!info || range <= 0) {
56 tc_log_error(PACKAGE, "wrong probing parameters");
57 return 0;
58 }
59
60 if (!file) {
61 tc_log_warn(PACKAGE, "missing source to probe");
62 memset(info, 0, sizeof(ProbeInfo));
63 } else {
64 if (!do_probe(file, NULL, 0, range, 0,
65 (verbose >= TC_DEBUG) ? verbose : 0, info)
66 ) {
67 if (verbose & TC_DEBUG) {
68 tc_log_warn(PACKAGE, "(%s) failed to probe stream '%s'",
69 __FILE__, file);
70 }
71 return 0;
72 }
73 }
74 return 1;
75 }
76
77
78 /**
79 * probe_source: Probe the given input file(s) and store the results in
80 * the global data structure.
81 *
82 * Parameters:
83 * vid_file: Video file name, or NULL if none.
84 * aud_file: Audio file name, or NULL if none.
85 * range: Amount of input files to probe, in MB.
86 * flags: Flags indicating which global parameters should be left
87 * alone (TC_PROBE_NO_xxx flags).
88 * vob: Pointer to global data structure.
89 * Return value:
90 * Nonzero on success, zero on error.
91 * Preconditions:
92 * vob != NULL
93 */
94
probe_source(const char * vid_file,const char * aud_file,int range,int flags,vob_t * vob)95 int probe_source(const char *vid_file, const char *aud_file, int range,
96 int flags, vob_t *vob)
97 {
98 ProbeInfo vinfo, ainfo; // video and audio info structures
99
100 /* Probe the video file, if present */
101 if (vid_file) {
102 if (!do_probe(vid_file, vob->nav_seek_file, vob->dvd_title, range,
103 (flags & TC_PROBE_NO_BUILTIN),
104 (verbose >= TC_DEBUG) ? verbose : 0, &vinfo)
105 ) {
106 if (verbose & TC_DEBUG) {
107 tc_log_warn(PACKAGE, "(%s) failed to probe video source",
108 __FILE__);
109 }
110 return 0;
111 }
112 } else {
113 vob->has_video = 0;
114 }
115
116 /* Probe the audio file, if present */
117 if (aud_file) {
118 if (!do_probe(aud_file, vob->nav_seek_file, vob->dvd_title, range,
119 (flags & TC_PROBE_NO_BUILTIN),
120 (verbose >= TC_DEBUG) ? verbose : 0, &ainfo)
121 ) {
122 if (verbose & TC_DEBUG) {
123 tc_log_warn(PACKAGE, "(%s) failed to probe audio source",
124 __FILE__);
125 }
126 return 0;
127 }
128 } /* else it might be contained in the video file */
129
130 /* Set global parameters based on probed data */
131 probe_to_vob(vid_file ? &vinfo : NULL, aud_file ? &ainfo : NULL,
132 flags, vob);
133 if (verbose & TC_DEBUG) {
134 tc_log_info(PACKAGE, "(%s) V magic=0x%lx, A magic=0x%lx,"
135 " V codec=0x%lx, A codec=0x%lx", __FILE__,
136 vob->v_format_flag, vob->a_format_flag,
137 vob->v_codec_flag, vob->a_codec_flag);
138 tc_log_info(PACKAGE, "(%s) V magic=%s, A magic=%s, V codec=%s,"
139 " A codec=%s", __FILE__,
140 mformat2str(vob->v_format_flag),
141 mformat2str(vob->a_format_flag),
142 tc_codec_to_comment(vob->v_codec_flag),
143 tc_codec_to_comment(vob->a_codec_flag));
144 }
145
146 /* All done, return success */
147 return 1;
148 }
149
150 /*************************************************************************/
151
152 /**
153 * probe_source_xml: Probe video or audio parameters from an XML file as
154 * specified by the vob_t data structure.
155 *
156 * Parameters:
157 * vob: Global vob_t data structure.
158 * which: PROBE_XML_VIDEO or PROBE_XML_AUDIO.
159 * Return value:
160 * Nonzero on success, zero on error.
161 * Side effects:
162 * Prints an error message on error.
163 */
164
165 /* FIXME: is this the right place for these? */
166
probe_source_xml(vob_t * vob,int which)167 int probe_source_xml(vob_t *vob, int which)
168 {
169 int retval = 1;
170 #ifdef HAVE_LIBXML2
171 int tochild[2], fromchild[2]; /* pipes */
172 pid_t pid;
173 int resize;
174
175 if (pipe(tochild) == -1) {
176 tc_log_perror(PACKAGE, "probe_source_xml(): pipe(tochild) failed");
177 return 0;
178 }
179 if (pipe(fromchild) == -1) {
180 tc_log_perror(PACKAGE, "probe_source_xml(): pipe(fromchild) failed");
181 close(tochild[0]);
182 close(tochild[1]);
183 return 0;
184 }
185 pid = fork();
186 if (pid == -1) {
187 tc_log_perror(PACKAGE, "probe_source_xml(): fork failed");
188 return 0;
189 } else if (pid > 0) {
190 /* Child process */
191 const char *new_argv[6];
192 close(tochild[1]);
193 close(fromchild[0]);
194 if (tochild[0] != 0) {
195 if (dup2(tochild[0], 0) == -1) {
196 tc_log_perror(PACKAGE, "probe_source_xml(): dup2(0) failed");
197 exit(-1);
198 }
199 close(tochild[0]);
200 }
201 if (fromchild[1] != 1) { // theoretically always true, but JIC
202 if (dup2(fromchild[1], 1) == -1) {
203 tc_log_perror(PACKAGE, "probe_source_xml(): dup2(1) failed");
204 exit(-1);
205 }
206 close(fromchild[1]);
207 }
208 new_argv[0] = "tcxmlcheck";
209 new_argv[1] = "-i";
210 new_argv[2] = vob->video_in_file;
211 new_argv[3] = "-B";
212 new_argv[4] = (which==PROBE_XML_VIDEO ? "-V" : "-A");
213 new_argv[5] = NULL;
214 execvp("tcxmlcheck", (char **)new_argv);
215 tc_log_perror(PACKAGE, "probe_source_xml(): exec(tcxmlcheck) failed");
216 exit(-1);
217 }
218 /* Parent process */
219 retval = 0;
220 close(tochild[0]);
221 close(fromchild[1]);
222 if (write(tochild[1], vob, sizeof(vob_t)) != sizeof(vob_t)) {
223 tc_log_error(PACKAGE, "Error writing data to tcxmlcheck: %s",
224 strerror(errno));
225 close(tochild[1]);
226 close(fromchild[0]);
227 /* Can't just return--need to reap the child */
228 goto reapchild;
229 }
230 close(tochild[1]);
231 if (read(fromchild[0], vob, sizeof(vob_t)) != sizeof(vob_t)) {
232 tc_log_error(PACKAGE, "Error reading data from tcxmlcheck");
233 close(fromchild[0]);
234 goto reapchild;
235 }
236 if (read(fromchild[0], &resize, sizeof(int)) != sizeof(int)) {
237 tc_log_error(PACKAGE, "Error reading data from tcxmlcheck 2");
238 close(fromchild[0]);
239 goto reapchild;
240 }
241 close(fromchild[0]);
242 if (which == PROBE_XML_VIDEO && resize == 2) {
243 // XML forced resize, clear command line parameters
244 resize1 = TC_FALSE;
245 resize2 = TC_FALSE;
246 zoom = TC_FALSE;
247 vob->resize1_mult = 32;
248 vob->vert_resize1 = 0;
249 vob->hori_resize1 = 0;
250 vob->resize2_mult = 32;
251 vob->vert_resize2 = 0;
252 vob->hori_resize2 = 0;
253 vob->zoom_width = 0;
254 vob->zoom_height = 0;
255 vob->zoom_filter = TCV_ZOOM_LANCZOS3;
256 }
257 retval = 1;
258
259 reapchild: // clean up after the child process
260 waitpid(pid, NULL, 0);
261 #endif // HAVE_LIBXML2
262
263 return retval;
264 }
265
266 /*************************************************************************/
267
268 /**
269 * mformat2str: Return a descriptive
270 * string for the given video format flag.
271 *
272 * Parameters:
273 * flag: Flag to return string for.
274 * Return value:
275 * String describing `flag'.
276 */
277
278
mformat2str(int flag)279 const char *mformat2str(int flag)
280 {
281 switch (flag) {
282 case TC_MAGIC_PAL: return "PAL";
283 case TC_MAGIC_NTSC: return "NTSC";
284 case TC_MAGIC_TS: return "MPEG transport stream";
285 case TC_MAGIC_YUV4MPEG: return "YUV4MPEG";
286 case TC_MAGIC_NUV: return "NuppelVideo";
287 case TC_MAGIC_DVD_PAL: return "DVD PAL";
288 case TC_MAGIC_DVD_NTSC: return "DVD NTSC";
289 case TC_MAGIC_AVI: return "RIFF data, AVI";
290 case TC_MAGIC_MOV: return "QuickTime";
291 case TC_MAGIC_XML: return "XML file";
292 case TC_MAGIC_TIFF1: return "TIFF image";
293 case TC_MAGIC_TIFF2: return "TIFF image";
294 case TC_MAGIC_JPEG: return "JPEG image";
295 case TC_MAGIC_BMP: return "BMP image";
296 case TC_MAGIC_PNG: return "PNG image";
297 case TC_MAGIC_GIF: return "GIF image";
298 case TC_MAGIC_PPM: return "PPM image";
299 case TC_MAGIC_PGM: return "PGM image";
300 case TC_MAGIC_CDXA: return "RIFF data, CDXA";
301 case TC_MAGIC_AC3: return "AC3";
302 case TC_MAGIC_MP3: return "MP3";
303 case TC_MAGIC_MP2: return "MP2";
304 case TC_MAGIC_OGG: return "OGG stream";
305 case TC_MAGIC_WAV: return "RIFF data, WAVE";
306 case TC_MAGIC_V4L_VIDEO: return "V4L,video";
307 case TC_MAGIC_V4L_AUDIO: return "V4L,audio";
308 case TC_MAGIC_PVN: return "PVN video";
309 }
310 return "";
311 }
312
313 /*************************************************************************/
314 /*************************************************************************/
315
316 /* Internal routines */
317
318 /*************************************************************************/
319
320 /**
321 * do_probe: Perform the actual probing of the source file.
322 *
323 * Parameters:
324 * file: Filename to probe.
325 * nav_seek_file: Navigation file for `file', or NULL if none.
326 * title: Title to probe for DVD probing.
327 * range: Amount of file to probe, in MB.
328 * mplayer_flag: If nonzero, use mplayer to probe file.
329 * verbose_flag: Verbosity flag to pass to tcprobe.
330 * info_ret: Structure to be filled in with probed data.
331 * Return value:
332 * Nonzero on success, zero on failure.
333 * Preconditions:
334 * file != NULL
335 */
336
do_probe(const char * file,const char * nav_seek_file,int title,int range,int mplayer_flag,int verbose_flag,ProbeInfo * info_ret)337 static int do_probe(const char *file, const char *nav_seek_file, int title,
338 int range, int mplayer_flag, int verbose_flag,
339 ProbeInfo *info_ret)
340 {
341 char cmdbuf[PATH_MAX+1000];
342 FILE *pipe;
343
344 if (mplayer_flag) {
345 if (tc_snprintf(cmdbuf, sizeof(cmdbuf),
346 "tcprobe -B -M -i \"%s\" -d %d",
347 file, verbose_flag) < 0)
348 return 0;
349 } else {
350 if (tc_snprintf(cmdbuf, sizeof(cmdbuf),
351 "tcprobe -B -i \"%s\" -T %d -H %d -d %d",
352 file, title, range, verbose_flag) < 0)
353 return 0;
354 if (nav_seek_file
355 && tc_snprintf(cmdbuf+strlen(cmdbuf), sizeof(cmdbuf)-strlen(cmdbuf),
356 " -f \"%s\"", nav_seek_file) < 0)
357 return 0;
358 }
359 pipe = popen(cmdbuf, "r");
360 if (!pipe)
361 return 0;
362 if (fread(&tc_probe_pid, sizeof(pid_t), 1, pipe) != 1) {
363 pclose(pipe);
364 return 0;
365 }
366 if (fread(info_ret, sizeof(*info_ret), 1, pipe) != 1) {
367 pclose(pipe);
368 return 0;
369 }
370 pclose(pipe);
371 return 1;
372 }
373
374 /*************************************************************************/
375
376 /**
377 * probe_to_vob: Use the results of probing the input files to set global
378 * parameters.
379 *
380 * Parameters:
381 * vinfo: Pointer to probe results for video file, or NULL if no video
382 * file.
383 * ainfo: Pointer to probe results for audio file, or NULL if no audio
384 * file.
385 * flags: TC_PROBE_NO_xxx flags.
386 * vob: Pointer to global data structure.
387 * Return value:
388 * None.
389 * Preconditions:
390 * vob != NULL
391 */
392
probe_to_vob(ProbeInfo * vinfo,ProbeInfo * ainfo,int flags,vob_t * vob)393 void probe_to_vob(ProbeInfo *vinfo, ProbeInfo *ainfo, int flags, vob_t *vob)
394 {
395 int track; // user-selected audio track, sanity-checked
396
397 track = vob->a_track;
398 if (track < 0 || track >= TC_MAX_AUD_TRACKS)
399 track = 0;
400
401 if (vinfo) {
402 int D_arg, D_arg_ms; // for setting A/V sync
403
404 /* Set frame size */
405 if (MAY_SET(FRAMESIZE)) {
406 if (vinfo->width > 0)
407 vob->im_v_width = vinfo->width;
408 if (vinfo->height > 0)
409 vob->im_v_height = vinfo->height;
410 }
411
412 /* Set frame rate */
413 if (MAY_SET(FPS)) {
414 if (vinfo->frc > 0) {
415 vob->im_frc = vinfo->frc;
416 tc_frc_code_to_value(vob->im_frc, &vob->fps);
417 } else if (vinfo->fps > 0)
418 vob->fps = vinfo->fps;
419 }
420
421 /* Set aspect ratio */
422 if (MAY_SET(IMASR)) {
423 if (vinfo->asr > 0)
424 vob->im_asr = vinfo->asr;
425 }
426
427 /* Set additional attributes */
428 if (vinfo->attributes)
429 vob->attributes = vinfo->attributes;
430
431 /* Clear demux sync flag if appropriate */
432 if (MAY_SET(DEMUX) && (vob->attributes & TC_INFO_NO_DEMUX)) {
433 vob->demuxer = 0;
434 }
435
436 /* Calculate A/V sync correction */
437 if (vinfo->pts_start > 0 && vinfo->track[track].pts_start > 0) {
438 double pts_diff = vinfo->pts_start - vinfo->track[track].pts_start;
439 D_arg = (int)(vob->fps * pts_diff);
440 D_arg_ms = (int)((pts_diff - D_arg/vob->fps) * 1000);
441 } else {
442 D_arg = 0;
443 D_arg_ms = 0;
444 }
445 /* This voodoo to determine whether to set the A/V sync parameters
446 * is from the original probe.c, with the following comments:
447 * - case 1: demuxer disabled needs PTS sync mode
448 * - case 2: check if PTS of requested audio track requires
449 * video frame dropping
450 * vob->demuxer>0 and audio_pts > video_pts
451 * - case 3: fully PTS based sync modes requested
452 */
453 if ((MAY_SET(DEMUX) && (vob->attributes & TC_INFO_NO_DEMUX))
454 || (MAY_SET(DEMUX) && (vinfo->pts_start < vinfo->track[track].pts_start))
455 || (vob->demuxer == 3 || vob->demuxer == 4)
456 ) {
457 if (MAY_SET(AVSHIFT))
458 vob->sync = D_arg;
459 if (MAY_SET(AV_FINE))
460 vob->sync_ms = D_arg_ms;
461 }
462
463 /* Set starting presentation unit */
464 if (MAY_SET(SEEK)) {
465 if (vinfo->unit_cnt > 0)
466 vob->ps_unit = vinfo->unit_cnt;
467 }
468
469 /* Set format/codec flags and miscellaneous fields */
470 if (vinfo->magic)
471 vob->v_format_flag = vinfo->magic;
472 if (vinfo->codec)
473 vob->v_codec_flag = vinfo->codec;
474 vob->pts_start = vinfo->pts_start;
475
476 /* If the width or height are 0, assume no video was detected
477 * (FIXME: what about -g?) */
478 if (vinfo->width == 0 || vinfo->height == 0)
479 vob->has_video = 0;
480
481 /* If no separate audio file was found, use the video file for
482 * audio processing */
483 if (!ainfo)
484 ainfo = vinfo;
485
486 } // if (vinfo)
487
488 if (ainfo) {
489
490 /* Set audio format parameters */
491 if (MAY_SET(RATE)) {
492 if (ainfo->track[track].samplerate > 0)
493 vob->a_rate = ainfo->track[track].samplerate;
494 }
495 if (MAY_SET(BITS)) {
496 if (ainfo->track[track].bits > 0)
497 vob->a_bits = ainfo->track[track].bits;
498 }
499 if (MAY_SET(CHAN)) {
500 if (ainfo->track[track].chan > 0)
501 vob->a_chan = ainfo->track[track].chan;
502 }
503
504 /* Set audio codec, if not set by user */
505 if (MAY_SET(ACODEC)) {
506 if (ainfo->track[track].format > 0)
507 vob->a_codec_flag = ainfo->track[track].format;
508 }
509
510 /* Set format flag and miscellaneous fields */
511 if (ainfo->magic)
512 vob->a_format_flag = ainfo->magic;
513 if (ainfo->track[track].bitrate > 0)
514 vob->a_stream_bitrate = ainfo->track[track].bitrate;
515 if (ainfo->track[track].padrate > 0)
516 vob->a_padrate = ainfo->track[track].padrate;
517 if (ainfo->track[track].lang > 0)
518 vob->lang_code = ainfo->track[track].lang;
519
520 /* See if audio was detected */
521 if (ainfo->num_tracks == 0)
522 vob->has_audio = 0;
523 if (ainfo->track[track].format == CODEC_NULL)
524 vob->has_audio_track = 0;
525
526 /* Set video format/codec fields as well if no video present */
527 if (!vinfo) {
528 if (ainfo->magic)
529 vob->v_format_flag = ainfo->magic;
530 if (ainfo->codec)
531 vob->v_codec_flag = ainfo->codec;
532 }
533
534 } // if (ainfo)
535
536 /* Make note of whether the input is an XML file */
537 if (vinfo && vinfo->magic != vinfo->magic_xml)
538 vob->vmod_probed_xml = "xml";
539 else
540 vob->vmod_probed_xml = NULL;
541 if (ainfo && ainfo->magic != ainfo->magic_xml)
542 vob->amod_probed_xml = "xml";
543 else
544 vob->amod_probed_xml = NULL;
545
546 if (MAY_SET(MODULES)) {
547 /* Select appropriate import modules */
548 select_modules(flags, vob);
549 }
550 }
551
552 /*************************************************************************/
553
554 /**
555 * select_modules: Use the results of probing the input files to set
556 * global parameters.
557 *
558 * Parameters:
559 * flags: TC_PROBE_NO_xxx flags.
560 * vob: Pointer to global data structure.
561 * Return value:
562 * None.
563 * Preconditions:
564 * vob != NULL
565 */
566
select_modules(int flags,vob_t * vob)567 static void select_modules(int flags, vob_t *vob)
568 {
569 char *default_amod;
570
571
572 vob->vmod_probed = NULL;
573 vob->amod_probed = NULL;
574
575 /* If no video or audio, use null module */
576 if (!vob->has_video) {
577 vob->vmod_probed = "null";
578 vob->im_v_width = 0;
579 vob->im_v_height = 0;
580 }
581 if (!vob->has_audio) {
582 vob->amod_probed = "null";
583 vob->a_rate = 0;
584 vob->a_chan = 0;
585 }
586
587 /* Choose a default audio module based on the audio codec */
588 switch (vob->a_codec_flag) {
589 case CODEC_MP2: default_amod = "mp3"; break;
590 case CODEC_MP3: default_amod = "mp3"; break;
591 case CODEC_AC3: default_amod = "ac3"; break;
592 case CODEC_PCM: default_amod = "raw"; break;
593 case CODEC_VORBIS: default_amod = "ogg"; break;
594 case CODEC_VAG: default_amod = "vag"; break;
595 default: default_amod = "null"; break;
596 }
597
598 /* Choose modules based on file format */
599
600 switch (vob->v_format_flag) {
601
602 case TC_MAGIC_MPLAYER:
603 vob->vmod_probed = "mplayer";
604 vob->amod_probed = "mplayer";
605 break;
606
607 case TC_MAGIC_V4L_VIDEO:
608 vob->vmod_probed = "v4l";
609 if (MAY_SET(FRAMESIZE)) {
610 vob->im_v_width = PAL_W/2;
611 vob->im_v_height = PAL_H/2;
612 if (vob->im_v_codec != CODEC_RGB)
613 vob->im_v_width &= -16;
614 }
615 break;
616
617 case TC_MAGIC_V4L2_VIDEO:
618 vob->vmod_probed = "v4l2";
619 vob->amod_probed = "v4l2";
620 if (MAY_SET(FRAMESIZE)) {
621 vob->im_v_width = PAL_W/2;
622 vob->im_v_height = PAL_H/2;
623 if (vob->im_v_codec != CODEC_RGB)
624 vob->im_v_width &= -16;
625 }
626 break;
627
628 case TC_MAGIC_BKTR_VIDEO:
629 vob->vmod_probed = "bktr";
630 if (MAY_SET(FRAMESIZE) && !(vob->im_v_width>0 && vob->im_v_height>0)) {
631 vob->im_v_width = PAL_W/2;
632 vob->im_v_height = PAL_H/2;
633 if (vob->im_v_codec != CODEC_RGB)
634 vob->im_v_width &= -16;
635 }
636 break;
637
638 case TC_MAGIC_YUV4MPEG:
639 vob->vmod_probed = "yuv4mpeg";
640 break;
641
642 case TC_MAGIC_BSDAV:
643 vob->vmod_probed = "bsdav";
644 break;
645
646 case TC_MAGIC_NUV:
647 vob->vmod_probed = "nuv";
648 vob->amod_probed = "nuv";
649 break;
650
651 case TC_MAGIC_OGG:
652 vob->vmod_probed = "ogg";
653 vob->amod_probed = "ogg";
654
655 case TC_MAGIC_DVD_NTSC:
656 if (MAY_SET(DEMUX)) {
657 if (vob->demuxer < 0)
658 vob->demuxer = 1;
659 /* Activate special handling for 24fps video */
660 if (vob->fps < PAL_FPS && (vob->demuxer==1 || vob->demuxer==3))
661 vob->demuxer++;
662 }
663 /* Fall through to common DVD handling */
664 case TC_MAGIC_DVD_PAL:
665 vob->vmod_probed = "dvd";
666 vob->amod_probed = "dvd";
667 break;
668
669 case TC_MAGIC_AVI:
670 if (vob->pass_flag & TC_VIDEO)
671 vob->vmod_probed = "avi";
672 break;
673
674 case TC_MAGIC_MOV:
675 vob->vmod_probed = "mov";
676 break;
677
678 case TC_MAGIC_TS:
679 vob->vmod_probed = "ts";
680
681 case TC_MAGIC_TIFF1:
682 case TC_MAGIC_TIFF2:
683 case TC_MAGIC_JPEG:
684 case TC_MAGIC_PPM:
685 case TC_MAGIC_PGM:
686 case TC_MAGIC_BMP:
687 case TC_MAGIC_PNG:
688 case TC_MAGIC_GIF:
689 case TC_MAGIC_SGI:
690 vob->vmod_probed = "im";
691 break;
692
693 case TC_MAGIC_DV_NTSC:
694 case TC_MAGIC_DV_PAL:
695 if (vob->pass_flag & TC_VIDEO)
696 vob->vmod_probed = "dv";
697 break;
698
699 case TC_MAGIC_CDXA:
700 vob->vmod_probed = "vob";
701 vob->amod_probed = "vob";
702 break;
703
704 case TC_MAGIC_MP3:
705 vob->amod_probed = "mp3";
706 break;
707
708 case TC_MAGIC_AC3:
709 vob->amod_probed = "ac3";
710 break;
711
712 case TC_MAGIC_PV3:
713 vob->vmod_probed = "pv3";
714 vob->amod_probed = "pv3"; // really just BE raw after demuxing
715 break;
716
717 case TC_MAGIC_PVN:
718 vob->vmod_probed = "pvn";
719 break;
720
721 case TC_MAGIC_X11:
722 vob->vmod_probed = "x11";
723 break;
724
725 } // switch (vob->v_format_flag)
726
727 switch (vob->a_format_flag) {
728 case TC_MAGIC_V4L_AUDIO: vob->amod_probed = "v4l"; break;
729 case TC_MAGIC_V4L2_AUDIO: vob->amod_probed = "v4l2"; break;
730 case TC_MAGIC_SUNAU_AUDIO: vob->amod_probed = "sunau"; break;
731 case TC_MAGIC_BSDAV: vob->amod_probed = "bsdav"; break;
732 case TC_MAGIC_WAV: vob->amod_probed = "raw"; break;
733 case TC_MAGIC_MOV: vob->amod_probed = "mov"; break;
734 case TC_MAGIC_TS: vob->amod_probed = "ts"; break;
735 case TC_MAGIC_MP3: vob->amod_probed = "mp3"; break;
736 case TC_MAGIC_AC3: vob->amod_probed = "ac3"; break;
737 case TC_MAGIC_OSS_AUDIO:
738 if (!vob->amod_probed)
739 vob->amod_probed = "oss";
740 break;
741 case TC_MAGIC_AVI:
742 if (vob->pass_flag & TC_AUDIO)
743 vob->amod_probed = "avi";
744 break;
745 } // switch (vob->a_format_flag)
746
747 /* Choose modules based on codec */
748 switch (vob->v_codec_flag) {
749
750 case TC_CODEC_DV:
751 if (!vob->vmod_probed)
752 vob->vmod_probed = "dv";
753 if (!vob->amod_probed) {
754 if (vob->v_format_flag == TC_MAGIC_AVI)
755 vob->amod_probed = default_amod;
756 else
757 vob->amod_probed = "dv";
758 }
759 break;
760
761 case TC_CODEC_MPEG:
762 case TC_CODEC_M2V:
763 case TC_CODEC_MPEG1:
764 if (!vob->vmod_probed)
765 vob->vmod_probed = "mpeg2";
766 if (!vob->amod_probed)
767 vob->amod_probed = default_amod;
768 break;
769
770 case TC_CODEC_MPEG2:
771 if (!vob->vmod_probed) {
772 vob->vmod_probed = "vob";
773 if (MAY_SET(DEMUX)) {
774 if (vob->demuxer < 0)
775 vob->demuxer = 1;
776 /* Activate special handling for 24fps video */
777 if (vob->fps < PAL_FPS && (vob->demuxer==1 || vob->demuxer==3))
778 vob->demuxer++;
779 }
780 }
781 if (!vob->amod_probed)
782 vob->amod_probed = vob->has_audio ? "vob" : "null";
783 break;
784
785 case TC_CODEC_MJPEG:
786 case TC_CODEC_MPG1:
787 case TC_CODEC_MP42:
788 case TC_CODEC_MP43:
789 case TC_CODEC_RV10:
790 case TC_CODEC_ASV1:
791 case TC_CODEC_ASV2:
792 case TC_CODEC_FFV1:
793 case TC_CODEC_H264:
794 if (!vob->vmod_probed)
795 vob->vmod_probed = "ffmpeg";
796 if (!vob->amod_probed)
797 vob->amod_probed = default_amod;
798 break;
799
800 case TC_CODEC_LZO1:
801 case TC_CODEC_LZO2:
802 /* Overwrite video import module selected from format */
803 vob->vmod_probed = "lzo";
804 if (!vob->amod_probed)
805 vob->amod_probed = default_amod;
806 break;
807
808 case TC_CODEC_THEORA:
809 if (vob->v_format_flag != TC_MAGIC_OGG && !vob->vmod_probed)
810 vob->vmod_probed = "mplayer";
811 if (!vob->amod_probed)
812 vob->amod_probed = default_amod;
813 break;
814
815 case TC_CODEC_DIVX3:
816 case TC_CODEC_DIVX4:
817 case TC_CODEC_DIVX5:
818 case TC_CODEC_XVID:
819 if (vob->v_format_flag != TC_MAGIC_OGG && !vob->vmod_probed)
820 vob->vmod_probed = "ffmpeg";
821 if (!vob->amod_probed)
822 vob->amod_probed = default_amod;
823 break;
824
825 case TC_CODEC_YUV420P:
826 case TC_CODEC_YUV422P:
827 case TC_CODEC_RGB:
828 if (!vob->vmod_probed)
829 vob->vmod_probed = "raw";
830 if (!vob->amod_probed)
831 vob->amod_probed = default_amod;
832 break;
833
834 } // switch (vob->v_codec_flag)
835
836 /* If still not known, default to the null module */
837 if (!vob->vmod_probed)
838 vob->vmod_probed = "null";
839 if (!vob->amod_probed)
840 vob->amod_probed = "null";
841
842 /* Set XML import modules */
843 if (!vob->vmod_probed_xml)
844 vob->vmod_probed_xml = vob->vmod_probed;
845 if (!vob->amod_probed_xml)
846 vob->amod_probed_xml = vob->amod_probed;
847 }
848
849 /*************************************************************************/
850
851 /*
852 * Local variables:
853 * c-file-style: "stroustrup"
854 * c-file-offsets: ((case-label . *) (statement-case-intro . *))
855 * indent-tabs-mode: nil
856 * End:
857 *
858 * vim: expandtab shiftwidth=4:
859 */
860