Modifies CLI help message for audio track selection, to make it clearer how to specif...
[HandBrake.git] / libhb / scan.c
blob272f03ffbd72923ed342e1fb1fccb6fd1d56bd20
1 /* $Id: scan.c,v 1.52 2005/11/25 15:05:25 titer Exp $
3 This file is part of the HandBrake source code.
4 Homepage: <http://handbrake.m0k.org/>.
5 It may be used under the terms of the GNU General Public License. */
7 #include "hb.h"
8 #include "a52dec/a52.h"
9 #include "dca.h"
11 typedef struct
13 hb_handle_t * h;
15 char * path;
16 int title_index;
17 hb_list_t * list_title;
19 hb_dvd_t * dvd;
20 hb_stream_t * stream;
22 } hb_scan_t;
24 static void ScanFunc( void * );
25 static int DecodePreviews( hb_scan_t *, hb_title_t * title );
26 static void LookForAC3AndDCA( hb_title_t * title, hb_buffer_t * b );
27 static int AllAC3AndDCAOK( hb_title_t * title );
29 hb_thread_t * hb_scan_init( hb_handle_t * handle, const char * path,
30 int title_index, hb_list_t * list_title )
32 hb_scan_t * data = calloc( sizeof( hb_scan_t ), 1 );
34 data->h = handle;
35 data->path = strdup( path );
36 data->title_index = title_index;
37 data->list_title = list_title;
39 return hb_thread_init( "scan", ScanFunc, data, HB_NORMAL_PRIORITY );
42 static void ScanFunc( void * _data )
44 hb_scan_t * data = (hb_scan_t *) _data;
45 hb_title_t * title;
46 int i;
48 data->dvd = NULL;
49 data->stream = NULL;
51 /* Try to open the path as a DVD. If it fails, try as a file */
52 hb_log( "scan: trying to open with libdvdread" );
53 if( ( data->dvd = hb_dvd_init( data->path ) ) )
55 hb_log( "scan: DVD has %d title(s)",
56 hb_dvd_title_count( data->dvd ) );
57 if( data->title_index )
59 /* Scan this title only */
60 hb_list_add( data->list_title, hb_dvd_title_scan( data->dvd,
61 data->title_index ) );
63 else
65 /* Scan all titles */
66 for( i = 0; i < hb_dvd_title_count( data->dvd ); i++ )
68 hb_list_add( data->list_title,
69 hb_dvd_title_scan( data->dvd, i + 1 ) );
73 else
75 if ( hb_stream_is_stream_type(data->path) )
77 hb_log( "scan: trying to open as MPEG-2 Stream");
78 data->stream = hb_stream_open (data->path);
79 hb_list_add( data->list_title, hb_stream_title_scan( data->stream ) );
81 else
83 hb_log( "scan: unrecognized file type" );
84 return;
88 for( i = 0; i < hb_list_count( data->list_title ); )
90 int j;
91 hb_state_t state;
92 hb_audio_t * audio;
93 hb_title_t * title_tmp = NULL;
95 title = hb_list_item( data->list_title, i );
97 /* I've seen a DVD with strictly identical titles. Check this
98 here and ignore it if redundant */
99 for( j = 0; j < i; j++ )
101 title_tmp = hb_list_item( data->list_title, j );
102 if( title->vts == title_tmp->vts &&
103 title->block_start == title_tmp->block_start &&
104 title->block_end == title_tmp->block_end &&
105 title->block_count == title_tmp->block_count )
107 break;
109 else
111 title_tmp = NULL;
114 if( title_tmp )
116 hb_log( "scan: title %d is duplicate with title %d",
117 title->index, title_tmp->index );
118 hb_list_rem( data->list_title, title );
119 free( title ); /* This _will_ leak! */
120 continue;
123 #define p state.param.scanning
124 /* Update the UI */
125 state.state = HB_STATE_SCANNING;
126 p.title_cur = title->index;
127 p.title_count = data->dvd ? hb_dvd_title_count( data->dvd ) : hb_list_count(data->list_title);
128 hb_set_state( data->h, &state );
129 #undef p
131 /* Decode previews */
132 /* this will also detect more AC3 / DTS information */
133 if( !DecodePreviews( data, title ) )
135 /* TODO: free things */
136 hb_list_rem( data->list_title, title );
137 continue;
140 if (data->stream)
142 // Stream based processing uses PID's to handle the different audio options for a given title
143 for( j = 0; j < hb_list_count( title->list_audio ); j++ )
145 audio = hb_list_item( title->list_audio, j );
146 hb_stream_update_audio(data->stream, audio);
149 else if (data->dvd)
151 /* Make sure we found AC3 rates and bitrates */
152 for( j = 0; j < hb_list_count( title->list_audio ); )
154 audio = hb_list_item( title->list_audio, j );
155 if( audio->codec == HB_ACODEC_AC3 &&
156 !audio->bitrate )
158 hb_list_rem( title->list_audio, audio );
159 free( audio );
160 continue;
162 j++;
166 /* Make sure we found AC3 / DCA rates and bitrates */
167 for( j = 0; j < hb_list_count( title->list_audio ); )
169 audio = hb_list_item( title->list_audio, j );
170 if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&
171 !audio->bitrate )
173 hb_log( "scan: removing audio with codec of 0x%x because of no bitrate",
174 audio->codec );
175 hb_list_rem( title->list_audio, audio );
176 free( audio );
177 continue;
179 j++;
182 /* Do we still have audio */
183 if( !hb_list_count( title->list_audio ) )
185 hb_list_rem( data->list_title, title );
186 free( title );
187 continue;
190 /* set a default input channel layout of stereo for LPCM or MPEG2 audio */
191 /* AC3 and DCA will already have had their layout set via DecodePreviews above, */
192 /* which calls LookForAC3AndDCA */
193 for( j = 0; j < hb_list_count( title->list_audio ); j++ )
195 audio = hb_list_item( title->list_audio, j );
196 if( audio->codec == HB_ACODEC_LPCM || audio->codec == HB_ACODEC_MPGA )
198 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
202 i++;
205 /* Init jobs templates */
206 for( i = 0; i < hb_list_count( data->list_title ); i++ )
208 hb_job_t * job;
210 title = hb_list_item( data->list_title, i );
211 job = calloc( sizeof( hb_job_t ), 1 );
212 title->job = job;
214 job->title = title;
216 /* Set defaults settings */
217 job->chapter_start = 1;
218 job->chapter_end = hb_list_count( title->list_chapter );
220 /* Autocrop by default. Gnark gnark */
221 memcpy( job->crop, title->crop, 4 * sizeof( int ) );
223 if( title->aspect == 16 )
225 hb_reduce( &job->pixel_aspect_width, &job->pixel_aspect_height,
226 16 * title->height, 9 * title->width );
228 else
230 hb_reduce( &job->pixel_aspect_width, &job->pixel_aspect_height,
231 4 * title->height, 3 * title->width );
234 job->width = title->width - job->crop[2] - job->crop[3];
235 // job->height = title->height - job->crop[0] - job->crop[1];
236 hb_fix_aspect( job, HB_KEEP_WIDTH );
237 if( job->height > title->height - job->crop[0] - job->crop[1] )
239 job->height = title->height - job->crop[0] - job->crop[1];
240 hb_fix_aspect( job, HB_KEEP_HEIGHT );
243 hb_log( "scan: title (%d) job->width:%d, job->height:%d",
244 i,job->width, job->height );
246 job->keep_ratio = 1;
248 job->vcodec = HB_VCODEC_FFMPEG;
249 job->vquality = -1.0;
250 job->vbitrate = 1000;
251 job->pass = 0;
252 job->vrate = title->rate;
253 job->vrate_base = title->rate_base;
255 job->audios[0] = 0;
256 job->audios[1] = -1;
258 job->acodec = HB_ACODEC_FAAC;
259 job->abitrate = 128;
260 job->arate = 44100;
262 job->subtitle = -1;
264 job->mux = HB_MUX_MP4;
267 if( data->dvd )
269 hb_dvd_close( &data->dvd );
271 if (data->stream)
273 hb_stream_close(&data->stream);
275 free( data->path );
276 free( data );
277 _data = NULL;
280 /***********************************************************************
281 * DecodePreviews
282 ***********************************************************************
283 * Decode 10 pictures for the given title.
284 * It assumes that data->reader and data->vts have successfully been
285 * DVDOpen()ed and ifoOpen()ed.
286 **********************************************************************/
287 static int DecodePreviews( hb_scan_t * data, hb_title_t * title )
289 int i, ret;
290 hb_buffer_t * buf_ps, * buf_es, * buf_raw;
291 hb_list_t * list_es, * list_raw;
292 hb_libmpeg2_t * mpeg2;
293 int progressive_count = 0;
295 buf_ps = hb_buffer_init( HB_DVD_READ_BUFFER_SIZE );
296 list_es = hb_list_init();
297 list_raw = hb_list_init();
299 hb_log( "scan: decoding previews for title %d", title->index );
301 if (data->dvd)
302 hb_dvd_start( data->dvd, title->index, 1 );
304 for( i = 0; i < 10; i++ )
306 int j, k;
307 FILE * file_preview;
308 char filename[1024];
310 //hb_log("Seeking to: %f", (float) ( i + 1 ) / 11.0 );
312 if (data->dvd)
314 if( !hb_dvd_seek( data->dvd, (float) ( i + 1 ) / 11.0 ) )
316 goto error;
319 else if (data->stream)
321 if (!hb_stream_seek(data->stream, (float) ( i + 1 ) / 11.0 ) )
323 goto error;
327 hb_log( "scan: preview %d", i + 1 );
329 mpeg2 = hb_libmpeg2_init();
331 for( j = 0; j < 10240 ; j++ )
333 if (data->dvd)
335 if( !hb_dvd_read( data->dvd, buf_ps ) )
337 hb_log( "Warning: Could not read data for preview %d, skipped", i + 1 );
338 goto skip_preview;
341 else if (data->stream)
343 if ( !hb_stream_read(data->stream,buf_ps) )
345 hb_log( "Warning: Could not read data for preview %d, skipped", i + 1 );
346 goto skip_preview;
349 hb_demux_ps( buf_ps, list_es );
351 while( ( buf_es = hb_list_item( list_es, 0 ) ) )
353 hb_list_rem( list_es, buf_es );
354 if( buf_es->id == 0xE0 && !hb_list_count( list_raw ) )
356 hb_libmpeg2_decode( mpeg2, buf_es, list_raw );
358 else if( !i )
360 LookForAC3AndDCA( title, buf_es );
362 hb_buffer_close( &buf_es );
364 if( hb_list_count( list_raw ) &&
365 ( i || AllAC3AndDCAOK( title ) ) )
367 /* We got a picture */
368 break;
372 if( hb_list_count( list_raw ) &&
373 ( i || AllAC3AndDCAOK( title ) ) )
375 break;
379 if( !hb_list_count( list_raw ) )
381 hb_log( "scan: could not get a decoded picture" );
382 goto error;
385 /* Get size and rate infos */
386 title->rate = 27000000;
387 int ar;
388 hb_libmpeg2_info( mpeg2, &title->width, &title->height,
389 &title->rate_base, &ar );
391 if( title->rate_base == 1126125 )
393 /* Frame FPS is 23.976 (meaning it's progressive), so
394 start keeping track of how many are reporting at
395 that speed. When enough show up that way, we want
396 to make that the overall title FPS.
398 progressive_count++;
400 if( progressive_count < 6 )
402 /* Not enough frames are reporting as progressive,
403 which means we should be conservative and use
404 29.97 as the title's FPS for now.
406 title->rate_base = 900900;
408 else
410 /* A majority of the scan frames are progressive. Make that
411 the title's FPS, and announce it once to the log.
413 if( progressive_count == 6 )
415 hb_log("Title's mostly progressive NTSC, setting fps to 23.976");
417 title->rate_base = 1126125;
420 else if( title->rate_base == 900900 && progressive_count >= 6 )
423 * We've already deduced that the frame rate is 23.976, so set it
424 * back again.
426 title->rate_base = 1126125;
429 if( i == 2) // Use the third frame's info, so as to skip opening logos
431 // The aspect ratio may have already been set by parsing the VOB/IFO details on a DVD, however
432 // if we're working with program/transport streams that data needs to come from within the stream.
433 if (title->aspect <= 0)
434 title->aspect = ar;
435 title->crop[0] = title->crop[1] = title->height / 2;
436 title->crop[2] = title->crop[3] = title->width / 2;
439 hb_libmpeg2_close( &mpeg2 );
441 while( ( buf_es = hb_list_item( list_es, 0 ) ) )
443 hb_list_rem( list_es, buf_es );
444 hb_buffer_close( &buf_es );
447 buf_raw = hb_list_item( list_raw, 0 );
449 hb_get_tempory_filename( data->h, filename, "%x%d",
450 (intptr_t)title, i );
452 file_preview = fopen( filename, "w" );
453 if( file_preview )
455 fwrite( buf_raw->data, title->width * title->height * 3 / 2,
456 1, file_preview );
457 fclose( file_preview );
459 else
461 hb_log( "scan: fopen failed (%s)", filename );
464 #define Y buf_raw->data
465 #define DARK 64
467 /* Detect black borders */
469 for( j = 0; j < title->width; j++ )
471 for( k = 0; k < title->crop[0]; k++ )
472 if( Y[ k * title->width + j ] > DARK )
474 title->crop[0] = k;
475 break;
477 for( k = 0; k < title->crop[1]; k++ )
478 if( Y[ ( title->height - k - 1 ) *
479 title->width + j ] > DARK )
481 title->crop[1] = k;
482 break;
485 for( j = 0; j < title->height; j++ )
487 for( k = 0; k < title->crop[2]; k++ )
488 if( Y[ j * title->width + k ] > DARK )
490 title->crop[2] = k;
491 break;
493 for( k = 0; k < title->crop[3]; k++ )
494 if( Y[ j * title->width +
495 title->width - k - 1 ] > DARK )
497 title->crop[3] = k;
498 break;
502 skip_preview:
503 while( ( buf_raw = hb_list_item( list_raw, 0 ) ) )
505 hb_list_rem( list_raw, buf_raw );
506 hb_buffer_close( &buf_raw );
510 title->crop[0] = EVEN( title->crop[0] );
511 title->crop[1] = EVEN( title->crop[1] );
512 title->crop[2] = EVEN( title->crop[2] );
513 title->crop[3] = EVEN( title->crop[3] );
515 hb_log( "scan: %dx%d, %.3f fps, autocrop = %d/%d/%d/%d",
516 title->width, title->height, (float) title->rate /
517 (float) title->rate_base, title->crop[0], title->crop[1],
518 title->crop[2], title->crop[3] );
520 ret = 1;
521 goto cleanup;
523 error:
524 ret = 0;
526 cleanup:
527 hb_buffer_close( &buf_ps );
528 while( ( buf_es = hb_list_item( list_es, 0 ) ) )
530 hb_list_rem( list_es, buf_es );
531 hb_buffer_close( &buf_es );
533 hb_list_close( &list_es );
534 while( ( buf_raw = hb_list_item( list_raw, 0 ) ) )
536 hb_list_rem( list_raw, buf_raw );
537 hb_buffer_close( &buf_raw );
539 hb_list_close( &list_raw );
540 if (data->dvd)
541 hb_dvd_stop( data->dvd );
543 return ret;
546 static void LookForAC3AndDCA( hb_title_t * title, hb_buffer_t * b )
548 int i;
549 int flags;
550 int rate;
551 int bitrate;
552 int frame_length;
553 dca_state_t * state;
555 /* Figure out if this is a AC3 or DCA buffer for a known track */
556 hb_audio_t * audio = NULL;
557 for( i = 0; i < hb_list_count( title->list_audio ); i++ )
559 audio = hb_list_item( title->list_audio, i );
560 /* check if we have an AC3 or DCA which we recognise */
561 if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&
562 audio->id == b->id )
564 break;
566 else
568 audio = NULL;
571 if( !audio )
573 return;
576 if( audio->bitrate )
578 /* Already done for this track */
579 return;
582 for( i = 0; i < b->size - 7; i++ )
585 if ( audio->codec == HB_ACODEC_AC3 )
588 /* check for a52 */
589 if( a52_syncinfo( &b->data[i], &flags, &rate, &bitrate ) )
591 hb_log( "scan: AC3, rate=%dHz, bitrate=%d", rate, bitrate );
592 audio->rate = rate;
593 audio->bitrate = bitrate;
594 switch( flags & A52_CHANNEL_MASK )
596 /* mono sources */
597 case A52_MONO:
598 case A52_CHANNEL1:
599 case A52_CHANNEL2:
600 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_MONO;
601 break;
602 /* stereo input */
603 case A52_CHANNEL:
604 case A52_STEREO:
605 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
606 break;
607 /* dolby (DPL1 aka Dolby Surround = 4.0 matrix-encoded) input */
608 case A52_DOLBY:
609 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_DOLBY;
610 break;
611 /* 3F/2R input */
612 case A52_3F2R:
613 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
614 break;
615 /* 3F/1R input */
616 case A52_3F1R:
617 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
618 break;
619 /* other inputs */
620 case A52_3F:
621 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F;
622 break;
623 case A52_2F1R:
624 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
625 break;
626 case A52_2F2R:
627 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
628 break;
629 /* unknown */
630 default:
631 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
634 /* add in our own LFE flag if the source has LFE */
635 if (flags & A52_LFE)
637 audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
640 /* store the AC3 flags for future reference
641 This enables us to find out if we had a stereo or Dolby source later on */
642 audio->config.a52.ac3flags = flags;
644 /* store the ac3 flags in the public ac3flags property too, so we can access it from the GUI */
645 audio->ac3flags = audio->config.a52.ac3flags;
647 /* XXX */
648 if ( (flags & A52_CHANNEL_MASK) == A52_DOLBY ) {
649 sprintf( audio->lang + strlen( audio->lang ),
650 " (Dolby Surround)" );
651 } else {
652 sprintf( audio->lang + strlen( audio->lang ),
653 " (%d.%d ch)",
654 HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->input_channel_layout) +
655 HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->input_channel_layout),
656 HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->input_channel_layout));
659 break;
664 else if ( audio->codec == HB_ACODEC_DCA )
667 hb_log( "scan: checking for DCA syncinfo" );
669 /* check for dca */
670 state = dca_init( 0 );
671 if( dca_syncinfo( state, &b->data[i], &flags, &rate, &bitrate, &frame_length ) )
673 hb_log( "scan: DCA, rate=%dHz, bitrate=%d", rate, bitrate );
674 audio->rate = rate;
675 audio->bitrate = bitrate;
676 switch( flags & DCA_CHANNEL_MASK )
678 /* mono sources */
679 case DCA_MONO:
680 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_MONO;
681 break;
682 /* stereo input */
683 case DCA_CHANNEL:
684 case DCA_STEREO:
685 case DCA_STEREO_SUMDIFF:
686 case DCA_STEREO_TOTAL:
687 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
688 break;
689 /* 3F/2R input */
690 case DCA_3F2R:
691 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
692 break;
693 /* 3F/1R input */
694 case DCA_3F1R:
695 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
696 break;
697 /* other inputs */
698 case DCA_3F:
699 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F;
700 break;
701 case DCA_2F1R:
702 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
703 break;
704 case DCA_2F2R:
705 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
706 break;
707 case DCA_4F2R:
708 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_4F2R;
709 break;
710 /* unknown */
711 default:
712 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
715 /* add in our own LFE flag if the source has LFE */
716 if (flags & DCA_LFE)
718 audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
721 /* store the DCA flags for future reference
722 This enables us to find out if we had a stereo or Dolby source later on */
723 audio->config.dca.dcaflags = flags;
725 /* store the dca flags in the public dcaflags property too, so we can access it from the GUI */
726 audio->dcaflags = audio->config.dca.dcaflags;
728 /* XXX */
729 if ( (flags & DCA_CHANNEL_MASK) == DCA_DOLBY ) {
730 sprintf( audio->lang + strlen( audio->lang ),
731 " (Dolby Surround)" );
732 } else {
733 sprintf( audio->lang + strlen( audio->lang ),
734 " (%d.%d ch)",
735 HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->input_channel_layout) +
736 HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->input_channel_layout),
737 HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->input_channel_layout));
740 break;
747 static int AllAC3AndDCAOK( hb_title_t * title )
749 int i;
750 hb_audio_t * audio;
752 for( i = 0; i < hb_list_count( title->list_audio ); i++ )
754 audio = hb_list_item( title->list_audio, i );
755 if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&
756 !audio->bitrate )
758 return 0;
762 return 1;