OSDN Git Service

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