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. */
8 #include "a52dec/a52.h"
17 hb_list_t * list_title;
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 );
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;
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 ) );
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 if ( (data->stream = hb_stream_open (data->path)) != NULL )
75 hb_list_add( data->list_title, hb_stream_title_scan( data->stream ) );
79 hb_log( "scan: unrecognized file type" );
83 for( i = 0; i < hb_list_count( data->list_title ); )
88 hb_title_t * title_tmp = NULL;
90 title = hb_list_item( data->list_title, i );
92 /* I've seen a DVD with strictly identical titles. Check this
93 here and ignore it if redundant */
94 for( j = 0; j < i; j++ )
96 title_tmp = hb_list_item( data->list_title, j );
97 if( title->vts == title_tmp->vts &&
98 title->block_start == title_tmp->block_start &&
99 title->block_end == title_tmp->block_end &&
100 title->block_count == title_tmp->block_count )
111 hb_log( "scan: title %d is duplicate with title %d",
112 title->index, title_tmp->index );
113 hb_list_rem( data->list_title, title );
114 free( title ); /* This _will_ leak! */
118 #define p state.param.scanning
120 state.state = HB_STATE_SCANNING;
121 p.title_cur = title->index;
122 p.title_count = data->dvd ? hb_dvd_title_count( data->dvd ) : hb_list_count(data->list_title);
123 hb_set_state( data->h, &state );
126 /* Decode previews */
127 /* this will also detect more AC3 / DTS information */
128 if( !DecodePreviews( data, title ) )
130 /* TODO: free things */
131 hb_list_rem( data->list_title, title );
137 // Stream based processing uses PID's to handle the different audio options for a given title
138 for( j = 0; j < hb_list_count( title->list_audio ); j++ )
140 audio = hb_list_item( title->list_audio, j );
141 hb_stream_update_audio(data->stream, audio);
146 /* Make sure we found AC3 rates and bitrates */
147 for( j = 0; j < hb_list_count( title->list_audio ); )
149 audio = hb_list_item( title->list_audio, j );
150 if( audio->codec == HB_ACODEC_AC3 &&
153 hb_list_rem( title->list_audio, audio );
161 /* Make sure we found AC3 / DCA rates and bitrates */
162 for( j = 0; j < hb_list_count( title->list_audio ); )
164 audio = hb_list_item( title->list_audio, j );
165 if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&
168 hb_log( "scan: removing audio with codec of 0x%x because of no bitrate",
170 hb_list_rem( title->list_audio, audio );
177 /* Do we still have audio */
178 if( !hb_list_count( title->list_audio ) )
180 hb_list_rem( data->list_title, title );
185 /* set a default input channel layout of stereo for LPCM or MPEG2 audio */
186 /* AC3 and DCA will already have had their layout set via DecodePreviews above, */
187 /* which calls LookForAC3AndDCA */
188 for( j = 0; j < hb_list_count( title->list_audio ); j++ )
190 audio = hb_list_item( title->list_audio, j );
191 if( audio->codec == HB_ACODEC_LPCM || audio->codec == HB_ACODEC_MPGA )
193 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
200 /* Init jobs templates */
201 for( i = 0; i < hb_list_count( data->list_title ); i++ )
205 title = hb_list_item( data->list_title, i );
206 job = calloc( sizeof( hb_job_t ), 1 );
211 /* Set defaults settings */
212 job->chapter_start = 1;
213 job->chapter_end = hb_list_count( title->list_chapter );
215 /* Autocrop by default. Gnark gnark */
216 memcpy( job->crop, title->crop, 4 * sizeof( int ) );
218 if( title->aspect == 16 )
220 hb_reduce( &job->pixel_aspect_width, &job->pixel_aspect_height,
221 16 * title->height, 9 * title->width );
225 hb_reduce( &job->pixel_aspect_width, &job->pixel_aspect_height,
226 4 * title->height, 3 * title->width );
229 job->width = title->width - job->crop[2] - job->crop[3];
230 // job->height = title->height - job->crop[0] - job->crop[1];
231 hb_fix_aspect( job, HB_KEEP_WIDTH );
232 if( job->height > title->height - job->crop[0] - job->crop[1] )
234 job->height = title->height - job->crop[0] - job->crop[1];
235 hb_fix_aspect( job, HB_KEEP_HEIGHT );
238 hb_log( "scan: title (%d) job->width:%d, job->height:%d",
239 i,job->width, job->height );
243 job->vcodec = HB_VCODEC_FFMPEG;
244 job->vquality = -1.0;
245 job->vbitrate = 1000;
247 job->vrate = title->rate;
248 job->vrate_base = title->rate_base;
253 job->acodec = HB_ACODEC_FAAC;
259 job->mux = HB_MUX_MP4;
264 hb_dvd_close( &data->dvd );
268 hb_stream_close(&data->stream);
275 /***********************************************************************
277 ***********************************************************************
278 * Decode 10 pictures for the given title.
279 * It assumes that data->reader and data->vts have successfully been
280 * DVDOpen()ed and ifoOpen()ed.
281 **********************************************************************/
282 static int DecodePreviews( hb_scan_t * data, hb_title_t * title )
284 int i, npreviews = 0;
285 hb_buffer_t * buf_ps, * buf_es, * buf_raw;
286 hb_list_t * list_es, * list_raw;
287 hb_libmpeg2_t * mpeg2;
288 int progressive_count = 0;
289 int ar16_count = 0, ar4_count = 0;
291 buf_ps = hb_buffer_init( HB_DVD_READ_BUFFER_SIZE );
292 list_es = hb_list_init();
293 list_raw = hb_list_init();
295 hb_log( "scan: decoding previews for title %d", title->index );
298 hb_dvd_start( data->dvd, title->index, 1 );
300 for( i = 0; i < 10; i++ )
306 //hb_log("Seeking to: %f", (float) ( i + 1 ) / 11.0 );
310 if( !hb_dvd_seek( data->dvd, (float) ( i + 1 ) / 11.0 ) )
315 else if (data->stream)
317 if (!hb_stream_seek(data->stream, (float) ( i + 1 ) / 11.0 ) )
323 hb_log( "scan: preview %d", i + 1 );
325 mpeg2 = hb_libmpeg2_init();
327 for( j = 0; j < 10240 ; j++ )
331 if( !hb_dvd_read( data->dvd, buf_ps ) )
333 hb_log( "Warning: Could not read data for preview %d, skipped", i + 1 );
337 else if (data->stream)
339 if ( !hb_stream_read(data->stream,buf_ps) )
341 hb_log( "Warning: Could not read data for preview %d, skipped", i + 1 );
345 hb_demux_ps( buf_ps, list_es );
347 while( ( buf_es = hb_list_item( list_es, 0 ) ) )
349 hb_list_rem( list_es, buf_es );
350 if( buf_es->id == 0xE0 && !hb_list_count( list_raw ) )
352 hb_libmpeg2_decode( mpeg2, buf_es, list_raw );
353 int ar = hb_libmpeg2_clear_aspect_ratio( mpeg2 );
356 ( ar == (HB_ASPECT_BASE * 4 / 3) ) ?
357 ++ar4_count : ++ar16_count ;
362 LookForAC3AndDCA( title, buf_es );
364 hb_buffer_close( &buf_es );
366 if( hb_list_count( list_raw ) &&
367 ( i || AllAC3AndDCAOK( title ) ) )
369 /* We got a picture */
374 if( hb_list_count( list_raw ) &&
375 ( i || AllAC3AndDCAOK( title ) ) )
381 if( !hb_list_count( list_raw ) )
383 hb_log( "scan: could not get a decoded picture" );
387 /* Get size and rate infos */
388 title->rate = 27000000;
390 hb_libmpeg2_info( mpeg2, &title->width, &title->height,
391 &title->rate_base, &ar );
393 /* if we found mostly 4:3 previews use that as the aspect ratio otherwise
395 title->aspect = ar4_count > ar16_count ?
396 HB_ASPECT_BASE * 4 / 3 : HB_ASPECT_BASE * 16 / 9;
398 if( title->rate_base == 1126125 )
400 /* Frame FPS is 23.976 (meaning it's progressive), so
401 start keeping track of how many are reporting at
402 that speed. When enough show up that way, we want
403 to make that the overall title FPS.
407 if( progressive_count < 6 )
409 /* Not enough frames are reporting as progressive,
410 which means we should be conservative and use
411 29.97 as the title's FPS for now.
413 title->rate_base = 900900;
417 /* A majority of the scan frames are progressive. Make that
418 the title's FPS, and announce it once to the log.
420 if( progressive_count == 6 )
422 hb_log("Title's mostly progressive NTSC, setting fps to 23.976");
424 title->rate_base = 1126125;
427 else if( title->rate_base == 900900 && progressive_count >= 6 )
430 * We've already deduced that the frame rate is 23.976, so set it
433 title->rate_base = 1126125;
436 // start from third frame to skip opening logos
439 title->crop[0] = title->crop[1] = title->height / 2;
440 title->crop[2] = title->crop[3] = title->width / 2;
443 hb_libmpeg2_close( &mpeg2 );
445 while( ( buf_es = hb_list_item( list_es, 0 ) ) )
447 hb_list_rem( list_es, buf_es );
448 hb_buffer_close( &buf_es );
451 buf_raw = hb_list_item( list_raw, 0 );
453 hb_get_tempory_filename( data->h, filename, "%x%d",
454 (intptr_t)title, i );
456 file_preview = fopen( filename, "w" );
459 fwrite( buf_raw->data, title->width * title->height * 3 / 2,
461 fclose( file_preview );
465 hb_log( "scan: fopen failed (%s)", filename );
468 #define Y buf_raw->data
471 /* Detect black borders */
473 for( j = 0; j < title->width; j++ )
475 for( k = 0; k < title->crop[0]; k++ )
476 if( Y[ k * title->width + j ] > DARK )
481 for( k = 0; k < title->crop[1]; k++ )
482 if( Y[ ( title->height - k - 1 ) *
483 title->width + j ] > DARK )
489 for( j = 0; j < title->height; j++ )
491 for( k = 0; k < title->crop[2]; k++ )
492 if( Y[ j * title->width + k ] > DARK )
497 for( k = 0; k < title->crop[3]; k++ )
498 if( Y[ j * title->width +
499 title->width - k - 1 ] > DARK )
508 while( ( buf_raw = hb_list_item( list_raw, 0 ) ) )
510 hb_list_rem( list_raw, buf_raw );
511 hb_buffer_close( &buf_raw );
515 title->crop[0] = EVEN( title->crop[0] );
516 title->crop[1] = EVEN( title->crop[1] );
517 title->crop[2] = EVEN( title->crop[2] );
518 title->crop[3] = EVEN( title->crop[3] );
520 hb_log( "scan: %d previews, %dx%d, %.3f fps, autocrop = %d/%d/%d/%d, aspect %s",
521 npreviews, title->width, title->height, (float) title->rate /
522 (float) title->rate_base, title->crop[0], title->crop[1],
523 title->crop[2], title->crop[3],
524 title->aspect == HB_ASPECT_BASE * 16 / 9 ? "16:9" :
525 title->aspect == HB_ASPECT_BASE * 4 / 3 ? "4:3" : "none" );
532 hb_buffer_close( &buf_ps );
533 while( ( buf_es = hb_list_item( list_es, 0 ) ) )
535 hb_list_rem( list_es, buf_es );
536 hb_buffer_close( &buf_es );
538 hb_list_close( &list_es );
539 while( ( buf_raw = hb_list_item( list_raw, 0 ) ) )
541 hb_list_rem( list_raw, buf_raw );
542 hb_buffer_close( &buf_raw );
544 hb_list_close( &list_raw );
546 hb_dvd_stop( data->dvd );
551 static void LookForAC3AndDCA( hb_title_t * title, hb_buffer_t * b )
560 /* Figure out if this is a AC3 or DCA buffer for a known track */
561 hb_audio_t * audio = NULL;
562 for( i = 0; i < hb_list_count( title->list_audio ); i++ )
564 audio = hb_list_item( title->list_audio, i );
565 /* check if we have an AC3 or DCA which we recognise */
566 if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&
583 /* Already done for this track */
587 for( i = 0; i < b->size - 7; i++ )
590 if ( audio->codec == HB_ACODEC_AC3 )
594 if( a52_syncinfo( &b->data[i], &flags, &rate, &bitrate ) )
596 hb_log( "scan: AC3, rate=%dHz, bitrate=%d", rate, bitrate );
598 audio->bitrate = bitrate;
599 switch( flags & A52_CHANNEL_MASK )
605 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_MONO;
610 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
612 /* dolby (DPL1 aka Dolby Surround = 4.0 matrix-encoded) input */
614 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_DOLBY;
618 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
622 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
626 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F;
629 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
632 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
636 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
639 /* add in our own LFE flag if the source has LFE */
642 audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
645 /* store the AC3 flags for future reference
646 This enables us to find out if we had a stereo or Dolby source later on */
647 audio->config.a52.ac3flags = flags;
649 /* store the ac3 flags in the public ac3flags property too, so we can access it from the GUI */
650 audio->ac3flags = audio->config.a52.ac3flags;
653 if ( (flags & A52_CHANNEL_MASK) == A52_DOLBY ) {
654 sprintf( audio->lang + strlen( audio->lang ),
655 " (Dolby Surround)" );
657 sprintf( audio->lang + strlen( audio->lang ),
659 HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->input_channel_layout) +
660 HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->input_channel_layout),
661 HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->input_channel_layout));
669 else if ( audio->codec == HB_ACODEC_DCA )
672 hb_log( "scan: checking for DCA syncinfo" );
675 state = dca_init( 0 );
676 if( dca_syncinfo( state, &b->data[i], &flags, &rate, &bitrate, &frame_length ) )
678 hb_log( "scan: DCA, rate=%dHz, bitrate=%d", rate, bitrate );
680 audio->bitrate = bitrate;
681 switch( flags & DCA_CHANNEL_MASK )
685 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_MONO;
690 case DCA_STEREO_SUMDIFF:
691 case DCA_STEREO_TOTAL:
692 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
696 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
700 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
704 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F;
707 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
710 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
713 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_4F2R;
717 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
720 /* add in our own LFE flag if the source has LFE */
723 audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
726 /* store the DCA flags for future reference
727 This enables us to find out if we had a stereo or Dolby source later on */
728 audio->config.dca.dcaflags = flags;
730 /* store the dca flags in the public dcaflags property too, so we can access it from the GUI */
731 audio->dcaflags = audio->config.dca.dcaflags;
734 if ( (flags & DCA_CHANNEL_MASK) == DCA_DOLBY ) {
735 sprintf( audio->lang + strlen( audio->lang ),
736 " (Dolby Surround)" );
738 sprintf( audio->lang + strlen( audio->lang ),
740 HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->input_channel_layout) +
741 HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->input_channel_layout),
742 HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->input_channel_layout));
752 static int AllAC3AndDCAOK( hb_title_t * title )
757 for( i = 0; i < hb_list_count( title->list_audio ); i++ )
759 audio = hb_list_item( title->list_audio, i );
760 if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&