OSDN Git Service

6834d4614a6a06306ab2a62b8f7b64468e2e09c7
[handbrake-jp/handbrake-jp-git.git] / libhb / scan.c
1 /* $Id: scan.c,v 1.52 2005/11/25 15:05:25 titer Exp $
2
3    This file is part of the HandBrake source code.
4    Homepage: <http://handbrake.fr/>.
5    It may be used under the terms of the GNU General Public License. */
6
7 #include "hb.h"
8 #include "a52dec/a52.h"
9 #include "dca.h"
10
11 typedef struct
12 {
13     hb_handle_t * h;
14
15     char        * path;
16     int           title_index;
17     hb_list_t   * list_title;
18
19     hb_dvd_t    * dvd;
20         hb_stream_t * stream;
21
22 } hb_scan_t;
23
24 static void ScanFunc( void * );
25 static int  DecodePreviews( hb_scan_t *, hb_title_t * title );
26 static void LookForAudio( hb_title_t * title, hb_buffer_t * b );
27 static int  AllAudioOK( hb_title_t * title );
28
29 hb_thread_t * hb_scan_init( hb_handle_t * handle, const char * path,
30                             int title_index, hb_list_t * list_title )
31 {
32     hb_scan_t * data = calloc( sizeof( hb_scan_t ), 1 );
33
34     data->h            = handle;
35     data->path         = strdup( path );
36     data->title_index  = title_index;
37     data->list_title   = list_title;
38
39     return hb_thread_init( "scan", ScanFunc, data, HB_NORMAL_PRIORITY );
40 }
41
42 static void ScanFunc( void * _data )
43 {
44     hb_scan_t  * data = (hb_scan_t *) _data;
45     hb_title_t * title;
46     int          i;
47
48         data->dvd = NULL;
49         data->stream = NULL;
50
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 ) ) )
54     {
55         hb_log( "scan: DVD has %d title(s)",
56                 hb_dvd_title_count( data->dvd ) );
57         if( data->title_index )
58         {
59             /* Scan this title only */
60             hb_list_add( data->list_title, hb_dvd_title_scan( data->dvd,
61                             data->title_index ) );
62         }
63         else
64         {
65             /* Scan all titles */
66             for( i = 0; i < hb_dvd_title_count( data->dvd ); i++ )
67             {
68                 hb_list_add( data->list_title,
69                              hb_dvd_title_scan( data->dvd, i + 1 ) );
70             }
71         }
72     }
73     else if ( (data->stream = hb_stream_open( data->path, 0 ) ) != NULL )
74     {
75         hb_list_add( data->list_title, hb_stream_title_scan( data->stream ) );
76     }
77     else
78     {
79         hb_log( "scan: unrecognized file type" );
80         return;
81     }
82
83     for( i = 0; i < hb_list_count( data->list_title ); )
84     {
85         int j;
86         hb_state_t state;
87         hb_audio_t * audio;
88         hb_title_t * title_tmp = NULL;
89
90         title = hb_list_item( data->list_title, i );
91
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++ )
95         {
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 )
101             {
102                 break;
103             }
104             else
105             {
106                 title_tmp = NULL;
107             }
108         }
109         if( title_tmp )
110         {
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! */
115             continue;
116         }
117
118 #define p state.param.scanning
119         /* Update the UI */
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 );
124 #undef p
125
126         /* Decode previews */
127         /* this will also detect more AC3 / DTS information */
128         if( !DecodePreviews( data, title ) )
129         {
130             /* TODO: free things */
131             hb_list_rem( data->list_title, title );
132             continue;
133         }
134
135         /* Make sure we found audio rates and bitrates */
136         for( j = 0; j < hb_list_count( title->list_audio ); )
137         {
138             audio = hb_list_item( title->list_audio, j );
139             if( !audio->config.in.bitrate )
140             {
141                 hb_log( "scan: removing audio 0x%x because no bitrate found",
142                         audio->id );
143                 hb_list_rem( title->list_audio, audio );
144                 free( audio );
145                 continue;
146             }
147             j++;
148         }
149
150         /* If we don't have any audio streams left, remove the title */
151         if( !hb_list_count( title->list_audio ) )
152         {
153             hb_list_rem( data->list_title, title );
154             free( title );
155             continue;
156         }
157
158         i++;
159     }
160
161     /* Init jobs templates */
162     for( i = 0; i < hb_list_count( data->list_title ); i++ )
163     {
164         hb_job_t * job;
165
166         title      = hb_list_item( data->list_title, i );
167         job        = calloc( sizeof( hb_job_t ), 1 );
168         title->job = job;
169
170         job->title = title;
171
172         /* Set defaults settings */
173         job->chapter_start = 1;
174         job->chapter_end   = hb_list_count( title->list_chapter );
175
176         /* Autocrop by default. Gnark gnark */
177         memcpy( job->crop, title->crop, 4 * sizeof( int ) );
178
179         if( title->aspect == 16 && !job->pixel_aspect_width && !job->pixel_aspect_height)
180         {
181             hb_reduce( &job->pixel_aspect_width, &job->pixel_aspect_height,
182                        16 * title->height, 9 * title->width );
183         }
184         else if( !job->pixel_aspect_width && !job->pixel_aspect_height )
185         {
186             hb_reduce( &job->pixel_aspect_width, &job->pixel_aspect_height,
187                        4 * title->height, 3 * title->width );
188         }
189
190         job->width = title->width - job->crop[2] - job->crop[3];
191         hb_fix_aspect( job, HB_KEEP_WIDTH );
192         if( job->height > title->height - job->crop[0] - job->crop[1] )
193         {
194             job->height = title->height - job->crop[0] - job->crop[1];
195             hb_fix_aspect( job, HB_KEEP_HEIGHT );
196         }
197
198         hb_log( "scan: title (%d) job->width:%d, job->height:%d",
199                 i, job->width, job->height );
200
201         job->keep_ratio = 1;
202
203         job->vcodec     = HB_VCODEC_FFMPEG;
204         job->vquality   = -1.0;
205         job->vbitrate   = 1000;
206         job->pass       = 0;
207         job->vrate      = title->rate;
208         job->vrate_base = title->rate_base;
209
210         job->list_audio = hb_list_init();
211
212         job->subtitle = -1;
213
214         job->mux = HB_MUX_MP4;
215     }
216
217     if( data->dvd )
218     {
219         hb_dvd_close( &data->dvd );
220     }
221         if (data->stream)
222         {
223                 hb_stream_close(&data->stream);
224         }
225     free( data->path );
226     free( data );
227     _data = NULL;
228 }
229
230 /***********************************************************************
231  * DecodePreviews
232  ***********************************************************************
233  * Decode 10 pictures for the given title.
234  * It assumes that data->reader and data->vts have successfully been
235  * DVDOpen()ed and ifoOpen()ed.
236  **********************************************************************/
237 static int DecodePreviews( hb_scan_t * data, hb_title_t * title )
238 {
239     int             i, npreviews = 0;
240     hb_buffer_t   * buf_ps, * buf_es;
241     hb_list_t     * list_es;
242     int progressive_count = 0;
243     int interlaced_preview_count = 0;
244     double last_ar = 0;
245     int ar16_count = 0, ar4_count = 0;
246
247     buf_ps   = hb_buffer_init( HB_DVD_READ_BUFFER_SIZE );
248     list_es  = hb_list_init();
249
250     hb_log( "scan: decoding previews for title %d", title->index );
251
252     if (data->dvd)
253       hb_dvd_start( data->dvd, title->index, 1 );
254
255     for( i = 0; i < 10; i++ )
256     {
257         int j, k;
258         FILE * file_preview;
259         char   filename[1024];
260
261         if (data->dvd)
262         {
263           if( !hb_dvd_seek( data->dvd, (float) ( i + 1 ) / 11.0 ) )
264           {
265               continue;
266           }
267         }
268         else if (data->stream)
269         {
270           /* we start reading streams at zero rather than 1/11 because
271            * short streams may have only one sequence header in the entire
272            * file and we need it to decode any previews. */
273           if (!hb_stream_seek(data->stream, (float) i / 11.0 ) )
274           {
275               continue;
276           }
277         }
278
279         hb_log( "scan: preview %d", i + 1 );
280
281         int vcodec = title->video_codec? title->video_codec : WORK_DECMPEG2;
282         hb_work_object_t *vid_decoder = hb_get_work( vcodec );
283         vid_decoder->codec_param = title->video_codec_param;
284         vid_decoder->init( vid_decoder, NULL );
285         hb_buffer_t * vid_buf = NULL;
286
287         for( j = 0; j < 10240 ; j++ )
288         {
289             if (data->dvd)
290             {
291               if( !hb_dvd_read( data->dvd, buf_ps ) )
292               {
293                   hb_log( "Warning: Could not read data for preview %d, skipped", i + 1 );
294                   goto skip_preview;
295               }
296             }
297             else if (data->stream)
298             {
299               if ( !hb_stream_read(data->stream,buf_ps) )
300               {
301                   hb_log( "Warning: Could not read data for preview %d, skipped", i + 1 );
302                   goto skip_preview;
303               }
304             }
305             if ( title->demuxer == HB_NULL_DEMUXER )
306             {
307                 hb_demux_null( buf_ps, list_es, 0 );
308             }
309             else
310             {
311                 hb_demux_ps( buf_ps, list_es, 0 );
312             }
313
314             while( ( buf_es = hb_list_item( list_es, 0 ) ) )
315             {
316                 hb_list_rem( list_es, buf_es );
317                 if( buf_es->id == title->video_id && vid_buf == NULL )
318                 {
319                     vid_decoder->work( vid_decoder, &buf_es, &vid_buf );
320                 }
321                 else if( ! AllAudioOK( title ) )
322                 {
323                     LookForAudio( title, buf_es );
324                 }
325                 if ( buf_es )
326                     hb_buffer_close( &buf_es );
327             }
328
329             if( vid_buf && AllAudioOK( title ) )
330                 break;
331         }
332
333         if( ! vid_buf )
334         {
335             hb_log( "scan: could not get a decoded picture" );
336             continue;
337         }
338
339         /* Get size and rate infos */
340
341         hb_work_info_t vid_info;
342         vid_decoder->info( vid_decoder, &vid_info );
343         vid_decoder->close( vid_decoder );
344         free( vid_decoder );
345
346         title->width = vid_info.width;
347         title->height = vid_info.height;
348         title->rate = vid_info.rate;
349         title->rate_base = vid_info.rate_base;
350         if ( vid_info.aspect != 0 )
351         {
352             if ( vid_info.aspect != last_ar && last_ar != 0 )
353             {
354                 hb_log( "aspect ratio changed from %g to %g",
355                         last_ar, vid_info.aspect );
356             }
357             switch ( (int)vid_info.aspect )
358             {
359                 case HB_ASPECT_BASE * 4 / 3:
360                     ++ar4_count;
361                     break;
362                 case HB_ASPECT_BASE * 16 / 9:
363                     ++ar16_count;
364                     break;
365                 default:
366                     hb_log( "unknown aspect ratio %g", vid_info.aspect );
367                     /* if the aspect is closer to 4:3 use that
368                      * otherwise use 16:9 */
369                     vid_info.aspect < HB_ASPECT_BASE * 14 / 9 ? ++ar4_count :
370                                                                 ++ar16_count;
371                     break;
372             }
373             last_ar = vid_info.aspect;
374         }
375
376         if( title->rate_base == 1126125 )
377         {
378             /* Frame FPS is 23.976 (meaning it's progressive), so
379                start keeping track of how many are reporting at
380                that speed. When enough show up that way, we want
381                to make that the overall title FPS.
382             */
383             progressive_count++;
384
385             if( progressive_count < 6 )
386             {
387                 /* Not enough frames are reporting as progressive,
388                    which means we should be conservative and use
389                    29.97 as the title's FPS for now.
390                 */
391                 title->rate_base = 900900;
392             }
393             else
394             {
395                 /* A majority of the scan frames are progressive. Make that
396                     the title's FPS, and announce it once to the log.
397                 */
398                 if( progressive_count == 6 )
399                 {
400                     hb_log("Title's mostly NTSC Film, setting fps to 23.976");
401                 }
402                 title->rate_base = 1126125;
403             }
404         }
405         else if( title->rate_base == 900900 && progressive_count >= 6 )
406         {
407             /*
408              * We've already deduced that the frame rate is 23.976, so set it
409              * back again.
410              */
411             title->rate_base = 1126125;
412         }
413
414         // start from third frame to skip opening logos
415         if( i == 2)
416         {
417             title->crop[0] = title->crop[1] = title->height / 2;
418             title->crop[2] = title->crop[3] = title->width / 2;
419         }
420
421         while( ( buf_es = hb_list_item( list_es, 0 ) ) )
422         {
423             hb_list_rem( list_es, buf_es );
424             hb_buffer_close( &buf_es );
425         }
426
427         /* Check preview for interlacing artifacts */
428         if( hb_detect_comb( vid_buf, title->width, title->height, 10, 30, 9, 10, 30, 9 ) )
429         {
430             hb_log("Interlacing detected in preview frame %i", i);
431             interlaced_preview_count++;
432         }
433
434         hb_get_tempory_filename( data->h, filename, "%x%d",
435                                  (intptr_t)title, i );
436
437         file_preview = fopen( filename, "w" );
438         if( file_preview )
439         {
440             fwrite( vid_buf->data, title->width * title->height * 3 / 2,
441                     1, file_preview );
442             fclose( file_preview );
443         }
444         else
445         {
446             hb_log( "scan: fopen failed (%s)", filename );
447         }
448
449 #define Y    vid_buf->data
450 #define DARK 64
451
452         /* Detect black borders */
453
454         for( j = 0; j < title->width; j++ )
455         {
456             for( k = 2; k < title->crop[0]; k++ )
457                 if( Y[ k * title->width + j ] > DARK )
458                 {
459                     title->crop[0] = k;
460                     break;
461                 }
462             for( k = 0; k < title->crop[1]; k++ )
463                 if( Y[ ( title->height - k - 1 ) *
464                        title->width + j ] > DARK )
465                 {
466                     title->crop[1] = k;
467                     break;
468                 }
469         }
470         for( j = 0; j < title->height; j++ )
471         {
472             for( k = 0; k < title->crop[2]; k++ )
473                 if( Y[ j * title->width + k ] > DARK )
474                 {
475                     title->crop[2] = k;
476                     break;
477                 }
478             for( k = 0; k < title->crop[3]; k++ )
479                 if( Y[ j * title->width +
480                         title->width - k - 1 ] > DARK )
481                 {
482                     title->crop[3] = k;
483                     break;
484                 }
485         }
486         ++npreviews;
487
488 skip_preview:
489         if ( vid_buf )
490             hb_buffer_close( &vid_buf );
491     }
492
493     /* if we found mostly 4:3 previews use that as the aspect ratio otherwise
494        use 16:9 */
495     title->aspect = ar4_count > ar16_count ?
496                         HB_ASPECT_BASE * 4 / 3 : HB_ASPECT_BASE * 16 / 9;
497
498     title->crop[0] = EVEN( title->crop[0] );
499     title->crop[1] = EVEN( title->crop[1] );
500     title->crop[2] = EVEN( title->crop[2] );
501     title->crop[3] = EVEN( title->crop[3] );
502
503     hb_log( "scan: %d previews, %dx%d, %.3f fps, autocrop = %d/%d/%d/%d, aspect %s",
504             npreviews, title->width, title->height, (float) title->rate /
505             (float) title->rate_base, title->crop[0], title->crop[1],
506             title->crop[2], title->crop[3],
507             title->aspect == HB_ASPECT_BASE * 16 / 9 ? "16:9" :
508                 title->aspect == HB_ASPECT_BASE * 4 / 3 ? "4:3" : "none" );
509
510     if( interlaced_preview_count >= ( npreviews / 2 ) )
511     {
512         hb_log("Title is likely interlaced or telecined (%i out of %i previews). You should do something about that.",
513                interlaced_preview_count, npreviews);
514         title->detected_interlacing = 1;
515     }
516     else
517     {
518         title->detected_interlacing = 0;
519     }
520
521     hb_buffer_close( &buf_ps );
522     while( ( buf_es = hb_list_item( list_es, 0 ) ) )
523     {
524         hb_list_rem( list_es, buf_es );
525         hb_buffer_close( &buf_es );
526     }
527     hb_list_close( &list_es );
528     if (data->dvd)
529       hb_dvd_stop( data->dvd );
530
531     return npreviews;
532 }
533
534 /*
535  * This routine is called for every frame from a non-video elementary stream.
536  * These are a mix of audio & subtitle streams, some of which we want & some
537  * we're ignoring. This routine checks the frame against all our audio streams
538  * to see if it's one we want and haven't identified yet. If yes, it passes the
539  * frame to a codec-specific id routine which is responsible for filling in
540  * the sample rate, bit rate, channels & other audio parameters.
541  *
542  * Since a sample rate is essential for further audio processing, any audio
543  * stream which isn't successfully id'd by is deleted at the end of the scan.
544  * This is necessary to avoid ambiguities where things that might be audio
545  * aren't (e.g., some European DVD Teletext streams use the same IDs as US ATSC
546  * AC-3 audio).
547  */
548 static void LookForAudio( hb_title_t * title, hb_buffer_t * b )
549 {
550     int i;
551
552     hb_audio_t * audio = NULL;
553     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
554     {
555         audio = hb_list_item( title->list_audio, i );
556         /* check if this elementary stream is one we want */
557         if ( audio->id == b->id )
558         {
559             break;
560         }
561         else
562         {
563             audio = NULL;
564         }
565     }
566     if( !audio || audio->config.in.bitrate != 0 )
567     {
568         /* not found or already done */
569         return;
570     }
571
572     hb_work_object_t *w = hb_codec_decoder( audio->config.in.codec );
573
574     if ( w == NULL || w->bsinfo == NULL )
575     {
576         hb_log( "Internal error in scan: unhandled audio type %d for id 0x%x",
577                 audio->config.in.codec, audio->id );
578         goto drop_audio;
579     }
580
581     hb_work_info_t info;
582     w->audio = audio;
583     w->codec_param = audio->config.in.codec_param;
584     int ret = w->bsinfo( w, b, &info );
585     if ( ret < 0 )
586     {
587         hb_log( "no info on audio type %d/0x%x for id 0x%x",
588                 audio->config.in.codec, audio->config.in.codec_param,
589                 audio->id );
590         goto drop_audio;
591     }
592     if ( !info.bitrate )
593     {
594         /* didn't find any info */
595         return;
596     }
597     audio->config.in.samplerate = info.rate;
598     audio->config.in.bitrate = info.bitrate;
599     audio->config.in.channel_layout = info.channel_layout;
600     audio->config.flags.ac3 = info.flags;
601
602     // update the audio description string based on the info we found
603     if ( audio->config.flags.ac3 & AUDIO_F_DOLBY )
604     {
605         strcat( audio->config.lang.description, " (Dolby Surround)" );
606     }
607     else
608     {
609         int layout = audio->config.in.channel_layout;
610         char *desc = audio->config.lang.description +
611                         strlen( audio->config.lang.description );
612         sprintf( desc, " (%d.%d ch)",
613                  HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(layout) +
614                      HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(layout),
615                  HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(layout) );
616     }
617
618     hb_log( "scan: audio 0x%x: %s, rate=%dHz, bitrate=%d %s", audio->id,
619             info.name, audio->config.in.samplerate, audio->config.in.bitrate,
620             audio->config.lang.description );
621  
622     free( w );
623     return;
624
625     // We get here if there's no hope of finding info on an audio bitstream,
626     // either because we don't have a decoder (or a decoder with a bitstream
627     // info proc) or because the decoder's info proc said that the stream
628     // wasn't something it could handle. Delete the item from the title's
629     // audio list so we won't keep reading packets while trying to get its
630     // bitstream info.
631  drop_audio:
632     if ( w )
633         free( w );
634
635     hb_list_rem( title->list_audio, audio );
636 }
637
638 /*
639  * This routine checks to see if we've ID'd all the audio streams associated
640  * with a title. It returns 0 if there are more to ID & 1 if all are done.
641  */
642 static int  AllAudioOK( hb_title_t * title )
643 {
644     int i;
645     hb_audio_t * audio;
646
647     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
648     {
649         audio = hb_list_item( title->list_audio, i );
650         if( audio->config.in.bitrate == 0 )
651         {
652             return 0;
653         }
654     }
655     return 1;
656 }