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 ) );
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
) );
83 hb_log( "scan: unrecognized file type" );
88 for( i
= 0; i
< hb_list_count( data
->list_title
); )
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
)
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! */
123 #define p state.param.scanning
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
);
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
);
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
);
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
&&
158 hb_list_rem( title
->list_audio
, audio
);
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
) &&
173 hb_log( "scan: removing audio with codec of 0x%x because of no bitrate",
175 hb_list_rem( title
->list_audio
, audio
);
182 /* Do we still have audio */
183 if( !hb_list_count( title
->list_audio
) )
185 hb_list_rem( data
->list_title
, title
);
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
;
205 /* Init jobs templates */
206 for( i
= 0; i
< hb_list_count( data
->list_title
); i
++ )
210 title
= hb_list_item( data
->list_title
, i
);
211 job
= calloc( sizeof( hb_job_t
), 1 );
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
);
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
);
248 job
->vcodec
= HB_VCODEC_FFMPEG
;
249 job
->vquality
= -1.0;
250 job
->vbitrate
= 1000;
252 job
->vrate
= title
->rate
;
253 job
->vrate_base
= title
->rate_base
;
258 job
->acodec
= HB_ACODEC_FAAC
;
264 job
->mux
= HB_MUX_MP4
;
269 hb_dvd_close( &data
->dvd
);
273 hb_stream_close(&data
->stream
);
280 /***********************************************************************
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
)
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
);
302 hb_dvd_start( data
->dvd
, title
->index
, 1 );
304 for( i
= 0; i
< 10; i
++ )
310 //hb_log("Seeking to: %f", (float) ( i + 1 ) / 11.0 );
314 if( !hb_dvd_seek( data
->dvd
, (float) ( i
+ 1 ) / 11.0 ) )
319 else if (data
->stream
)
321 if (!hb_stream_seek(data
->stream
, (float) ( i
+ 1 ) / 11.0 ) )
327 hb_log( "scan: preview %d", i
+ 1 );
329 mpeg2
= hb_libmpeg2_init();
331 for( j
= 0; j
< 10240 ; j
++ )
335 if( !hb_dvd_read( data
->dvd
, buf_ps
) )
340 else if (data
->stream
)
342 if ( !hb_stream_read(data
->stream
,buf_ps
) )
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
);
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 */
370 if( hb_list_count( list_raw
) &&
371 ( i
|| AllAC3AndDCAOK( title
) ) )
377 if( !hb_list_count( list_raw
) )
379 hb_log( "scan: could not get a decoded picture" );
383 /* Get size and rate infos */
384 title
->rate
= 27000000;
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.
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;
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)
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" );
441 fwrite( buf_raw
->data
, title
->width
* title
->height
* 3 / 2,
443 fclose( file_preview
);
447 hb_log( "scan: fopen failed (%s)", filename
);
450 #define Y buf_raw->data
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
)
463 for( k
= 0; k
< title
->crop
[1]; k
++ )
464 if( Y
[ ( title
->height
- k
- 1 ) *
465 title
->width
+ j
] > DARK
)
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
)
479 for( k
= 0; k
< title
->crop
[3]; k
++ )
480 if( Y
[ j
* title
->width
+
481 title
->width
- k
- 1 ] > DARK
)
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] );
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
);
526 hb_dvd_stop( data
->dvd
);
531 static void LookForAC3AndDCA( hb_title_t
* title
, hb_buffer_t
* b
)
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
) &&
563 /* Already done for this track */
567 for( i
= 0; i
< b
->size
- 7; i
++ )
570 if ( audio
->codec
== HB_ACODEC_AC3
)
574 if( a52_syncinfo( &b
->data
[i
], &flags
, &rate
, &bitrate
) )
576 hb_log( "scan: AC3, rate=%dHz, bitrate=%d", rate
, bitrate
);
578 audio
->bitrate
= bitrate
;
579 switch( flags
& A52_CHANNEL_MASK
)
585 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_MONO
;
590 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_STEREO
;
592 /* dolby (DPL1 aka Dolby Surround = 4.0 matrix-encoded) input */
594 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_DOLBY
;
598 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_3F2R
;
602 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_3F1R
;
606 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_3F
;
609 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_2F1R
;
612 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_2F2R
;
616 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_STEREO
;
619 /* add in our own LFE flag if the source has 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
;
633 if ( (flags
& A52_CHANNEL_MASK
) == A52_DOLBY
) {
634 sprintf( audio
->lang
+ strlen( audio
->lang
),
635 " (Dolby Surround)" );
637 sprintf( audio
->lang
+ strlen( audio
->lang
),
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
));
649 else if ( audio
->codec
== HB_ACODEC_DCA
)
652 hb_log( "scan: checking for DCA syncinfo" );
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
);
660 audio
->bitrate
= bitrate
;
661 switch( flags
& DCA_CHANNEL_MASK
)
665 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_MONO
;
670 case DCA_STEREO_SUMDIFF
:
671 case DCA_STEREO_TOTAL
:
672 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_STEREO
;
676 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_3F2R
;
680 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_3F1R
;
684 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_3F
;
687 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_2F1R
;
690 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_2F2R
;
693 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_4F2R
;
697 audio
->input_channel_layout
= HB_INPUT_CH_LAYOUT_STEREO
;
700 /* add in our own LFE flag if the source has 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
;
714 if ( (flags
& DCA_CHANNEL_MASK
) == DCA_DOLBY
) {
715 sprintf( audio
->lang
+ strlen( audio
->lang
),
716 " (Dolby Surround)" );
718 sprintf( audio
->lang
+ strlen( audio
->lang
),
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
));
732 static int AllAC3AndDCAOK( hb_title_t
* title
)
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
) &&