Moves the filters' logging info to work.c, adds parameter info. I also changed the...
[HandBrake.git] / libhb / scan.c
blobcda52e3751660e830e5a523c89724e5287e649fb
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 goto error;
340 else if (data->stream)
342 if ( !hb_stream_read(data->stream,buf_ps) )
344 goto error;
347 hb_demux_ps( buf_ps, list_es );
349 while( ( buf_es = hb_list_item( list_es, 0 ) ) )
351 hb_list_rem( list_es, buf_es );
352 if( buf_es->id == 0xE0 && !hb_list_count( list_raw ) )
354 hb_libmpeg2_decode( mpeg2, buf_es, list_raw );
356 else if( !i )
358 LookForAC3AndDCA( title, buf_es );
360 hb_buffer_close( &buf_es );
362 if( hb_list_count( list_raw ) &&
363 ( i || AllAC3AndDCAOK( title ) ) )
365 /* We got a picture */
366 break;
370 if( hb_list_count( list_raw ) &&
371 ( i || AllAC3AndDCAOK( title ) ) )
373 break;
377 if( !hb_list_count( list_raw ) )
379 hb_log( "scan: could not get a decoded picture" );
380 goto error;
383 /* Get size and rate infos */
384 title->rate = 27000000;
385 int ar;
386 hb_libmpeg2_info( mpeg2, &title->width, &title->height,
387 &title->rate_base, &ar );
389 if (title->rate_base == 1126125)
391 /* Frame FPS is 23.976 (meaning it's progressive), so
392 start keeping track of how many are reporting at
393 that speed. When enough show up that way, we want
394 to make that the overall title FPS.
396 progressive_count++;
398 if (progressive_count < 6)
399 /* Not enough frames are reporting as progressive,
400 which means we should be conservative and use
401 29.97 as the title's FPS for now.
403 title->rate_base = 900900;
404 else
406 /* A majority of the scan frames are progressive. Make that
407 the title's FPS, and announce it once to the log.
409 if (progressive_count == 6)
410 hb_log("Title's mostly progressive NTSC, setting fps to 23.976");
411 title->rate_base = 1126125;
415 if( i == 2) // Use the third frame's info, so as to skip opening logos
417 // The aspect ratio may have already been set by parsing the VOB/IFO details on a DVD, however
418 // if we're working with program/transport streams that data needs to come from within the stream.
419 if (title->aspect <= 0)
420 title->aspect = ar;
421 title->crop[0] = title->crop[1] = title->height / 2;
422 title->crop[2] = title->crop[3] = title->width / 2;
425 hb_libmpeg2_close( &mpeg2 );
427 while( ( buf_es = hb_list_item( list_es, 0 ) ) )
429 hb_list_rem( list_es, buf_es );
430 hb_buffer_close( &buf_es );
433 buf_raw = hb_list_item( list_raw, 0 );
435 hb_get_tempory_filename( data->h, filename, "%x%d",
436 (intptr_t)title, i );
438 file_preview = fopen( filename, "w" );
439 if( file_preview )
441 fwrite( buf_raw->data, title->width * title->height * 3 / 2,
442 1, file_preview );
443 fclose( file_preview );
445 else
447 hb_log( "scan: fopen failed (%s)", filename );
450 #define Y buf_raw->data
451 #define DARK 64
453 /* Detect black borders */
455 for( j = 0; j < title->width; j++ )
457 for( k = 0; k < title->crop[0]; k++ )
458 if( Y[ k * title->width + j ] > DARK )
460 title->crop[0] = k;
461 break;
463 for( k = 0; k < title->crop[1]; k++ )
464 if( Y[ ( title->height - k - 1 ) *
465 title->width + j ] > DARK )
467 title->crop[1] = k;
468 break;
471 for( j = 0; j < title->height; j++ )
473 for( k = 0; k < title->crop[2]; k++ )
474 if( Y[ j * title->width + k ] > DARK )
476 title->crop[2] = k;
477 break;
479 for( k = 0; k < title->crop[3]; k++ )
480 if( Y[ j * title->width +
481 title->width - k - 1 ] > DARK )
483 title->crop[3] = k;
484 break;
488 while( ( buf_raw = hb_list_item( list_raw, 0 ) ) )
490 hb_list_rem( list_raw, buf_raw );
491 hb_buffer_close( &buf_raw );
495 title->crop[0] = EVEN( title->crop[0] );
496 title->crop[1] = EVEN( title->crop[1] );
497 title->crop[2] = EVEN( title->crop[2] );
498 title->crop[3] = EVEN( title->crop[3] );
500 hb_log( "scan: %dx%d, %.3f fps, autocrop = %d/%d/%d/%d",
501 title->width, title->height, (float) title->rate /
502 (float) title->rate_base, title->crop[0], title->crop[1],
503 title->crop[2], title->crop[3] );
505 ret = 1;
506 goto cleanup;
508 error:
509 ret = 0;
511 cleanup:
512 hb_buffer_close( &buf_ps );
513 while( ( buf_es = hb_list_item( list_es, 0 ) ) )
515 hb_list_rem( list_es, buf_es );
516 hb_buffer_close( &buf_es );
518 hb_list_close( &list_es );
519 while( ( buf_raw = hb_list_item( list_raw, 0 ) ) )
521 hb_list_rem( list_raw, buf_raw );
522 hb_buffer_close( &buf_raw );
524 hb_list_close( &list_raw );
525 if (data->dvd)
526 hb_dvd_stop( data->dvd );
528 return ret;
531 static void LookForAC3AndDCA( hb_title_t * title, hb_buffer_t * b )
533 int i;
534 int flags;
535 int rate;
536 int bitrate;
537 int frame_length;
538 dca_state_t * state;
540 /* Figure out if this is a AC3 or DCA buffer for a known track */
541 hb_audio_t * audio = NULL;
542 for( i = 0; i < hb_list_count( title->list_audio ); i++ )
544 audio = hb_list_item( title->list_audio, i );
545 /* check if we have an AC3 or DCA which we recognise */
546 if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&
547 audio->id == b->id )
549 break;
551 else
553 audio = NULL;
556 if( !audio )
558 return;
561 if( audio->bitrate )
563 /* Already done for this track */
564 return;
567 for( i = 0; i < b->size - 7; i++ )
570 if ( audio->codec == HB_ACODEC_AC3 )
573 /* check for a52 */
574 if( a52_syncinfo( &b->data[i], &flags, &rate, &bitrate ) )
576 hb_log( "scan: AC3, rate=%dHz, bitrate=%d", rate, bitrate );
577 audio->rate = rate;
578 audio->bitrate = bitrate;
579 switch( flags & A52_CHANNEL_MASK )
581 /* mono sources */
582 case A52_MONO:
583 case A52_CHANNEL1:
584 case A52_CHANNEL2:
585 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_MONO;
586 break;
587 /* stereo input */
588 case A52_CHANNEL:
589 case A52_STEREO:
590 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
591 break;
592 /* dolby (DPL1 aka Dolby Surround = 4.0 matrix-encoded) input */
593 case A52_DOLBY:
594 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_DOLBY;
595 break;
596 /* 3F/2R input */
597 case A52_3F2R:
598 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
599 break;
600 /* 3F/1R input */
601 case A52_3F1R:
602 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
603 break;
604 /* other inputs */
605 case A52_3F:
606 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F;
607 break;
608 case A52_2F1R:
609 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
610 break;
611 case A52_2F2R:
612 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
613 break;
614 /* unknown */
615 default:
616 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
619 /* add in our own LFE flag if the source has LFE */
620 if (flags & A52_LFE)
622 audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
625 /* store the AC3 flags for future reference
626 This enables us to find out if we had a stereo or Dolby source later on */
627 audio->config.a52.ac3flags = flags;
629 /* store the ac3 flags in the public ac3flags property too, so we can access it from the GUI */
630 audio->ac3flags = audio->config.a52.ac3flags;
632 /* XXX */
633 if ( (flags & A52_CHANNEL_MASK) == A52_DOLBY ) {
634 sprintf( audio->lang + strlen( audio->lang ),
635 " (Dolby Surround)" );
636 } else {
637 sprintf( audio->lang + strlen( audio->lang ),
638 " (%d.%d ch)",
639 HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->input_channel_layout) +
640 HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->input_channel_layout),
641 HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->input_channel_layout));
644 break;
649 else if ( audio->codec == HB_ACODEC_DCA )
652 hb_log( "scan: checking for DCA syncinfo" );
654 /* check for dca */
655 state = dca_init( 0 );
656 if( dca_syncinfo( state, &b->data[i], &flags, &rate, &bitrate, &frame_length ) )
658 hb_log( "scan: DCA, rate=%dHz, bitrate=%d", rate, bitrate );
659 audio->rate = rate;
660 audio->bitrate = bitrate;
661 switch( flags & DCA_CHANNEL_MASK )
663 /* mono sources */
664 case DCA_MONO:
665 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_MONO;
666 break;
667 /* stereo input */
668 case DCA_CHANNEL:
669 case DCA_STEREO:
670 case DCA_STEREO_SUMDIFF:
671 case DCA_STEREO_TOTAL:
672 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
673 break;
674 /* 3F/2R input */
675 case DCA_3F2R:
676 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F2R;
677 break;
678 /* 3F/1R input */
679 case DCA_3F1R:
680 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F1R;
681 break;
682 /* other inputs */
683 case DCA_3F:
684 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_3F;
685 break;
686 case DCA_2F1R:
687 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F1R;
688 break;
689 case DCA_2F2R:
690 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_2F2R;
691 break;
692 case DCA_4F2R:
693 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_4F2R;
694 break;
695 /* unknown */
696 default:
697 audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
700 /* add in our own LFE flag if the source has LFE */
701 if (flags & DCA_LFE)
703 audio->input_channel_layout = audio->input_channel_layout | HB_INPUT_CH_LAYOUT_HAS_LFE;
706 /* store the DCA flags for future reference
707 This enables us to find out if we had a stereo or Dolby source later on */
708 audio->config.dca.dcaflags = flags;
710 /* store the dca flags in the public dcaflags property too, so we can access it from the GUI */
711 audio->dcaflags = audio->config.dca.dcaflags;
713 /* XXX */
714 if ( (flags & DCA_CHANNEL_MASK) == DCA_DOLBY ) {
715 sprintf( audio->lang + strlen( audio->lang ),
716 " (Dolby Surround)" );
717 } else {
718 sprintf( audio->lang + strlen( audio->lang ),
719 " (%d.%d ch)",
720 HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->input_channel_layout) +
721 HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->input_channel_layout),
722 HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->input_channel_layout));
725 break;
732 static int AllAC3AndDCAOK( hb_title_t * title )
734 int i;
735 hb_audio_t * audio;
737 for( i = 0; i < hb_list_count( title->list_audio ); i++ )
739 audio = hb_list_item( title->list_audio, i );
740 if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) &&
741 !audio->bitrate )
743 return 0;
747 return 1;