OSDN Git Service

Remove the set cpu count option as it doesn't do anything now
[handbrake-jp/handbrake-jp-git.git] / libhb / bd.c
1 /* $Id: dvd.c,v 1.12 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 "lang.h"
9 #include "hbffmpeg.h"
10
11 #include "libbluray/bluray.h"
12
13 struct hb_bd_s
14 {
15     char         * path;
16     BLURAY       * bd;
17     int            title_count;
18     uint64_t       pkt_count;
19     hb_stream_t  * stream;
20     int            chapter;
21     int            next_chap;
22 };
23
24 /***********************************************************************
25  * Local prototypes
26  **********************************************************************/
27 static int           next_packet( BLURAY *bd, uint8_t *pkt );
28
29 /***********************************************************************
30  * hb_bd_init
31  ***********************************************************************
32  *
33  **********************************************************************/
34 hb_bd_t * hb_bd_init( char * path )
35 {
36     hb_bd_t * d;
37
38     d = calloc( sizeof( hb_bd_t ), 1 );
39
40     /* Open device */
41     d->bd = bd_open( path, NULL );
42     if( d->bd == NULL )
43     {
44         /*
45          * Not an error, may be a stream - which we'll try in a moment.
46          */
47         hb_log( "bd: not a bd - trying as a stream/file instead" );
48         goto fail;
49     }
50
51     d->title_count = bd_get_titles( d->bd, TITLES_RELEVANT );
52     if ( d->title_count == 0 )
53     {
54         hb_log( "bd: not a bd - trying as a stream/file instead" );
55         goto fail;
56     }
57     d->path = strdup( path );
58
59     return d;
60
61 fail:
62     if( d->bd ) bd_close( d->bd );
63     free( d );
64     return NULL;
65 }
66
67 /***********************************************************************
68  * hb_bd_title_count
69  **********************************************************************/
70 int hb_bd_title_count( hb_bd_t * d )
71 {
72     return d->title_count;
73 }
74
75 /***********************************************************************
76  * hb_bd_title_scan
77  **********************************************************************/
78 hb_title_t * hb_bd_title_scan( hb_bd_t * d, int tt, uint64_t min_duration )
79 {
80
81     hb_title_t   * title;
82     hb_chapter_t * chapter;
83     int            ii;
84     BLURAY_TITLE_INFO * ti = NULL;
85
86     hb_log( "bd: scanning title %d", tt );
87
88     title = hb_title_init( d->path, tt );
89     title->demuxer = HB_MPEG2_TS_DEMUXER;
90     title->type = HB_BD_TYPE;
91     title->reg_desc = STR4_TO_UINT32("HDMV");
92
93     char * p_cur, * p_last = d->path;
94     for( p_cur = d->path; *p_cur; p_cur++ )
95     {
96         if( p_cur[0] == '/' && p_cur[1] )
97         {
98             p_last = &p_cur[1];
99         }
100     }
101     snprintf( title->name, sizeof( title->name ), "%s", p_last );
102     strncpy( title->path, d->path, 1024 );
103     title->path[1023] = 0;
104
105     title->vts = 0;
106     title->ttn = 0;
107
108     ti = bd_get_title_info( d->bd, tt - 1 );
109     if ( ti == NULL )
110     {
111         hb_log( "bd: invalid title" );
112         goto fail;
113     }
114     if ( ti->clip_count == 0 )
115     {
116         hb_log( "bd: stream has no clips" );
117         goto fail;
118     }
119     if ( ti->clips[0].video_stream_count == 0 )
120     {
121         hb_log( "bd: stream has no video" );
122         goto fail;
123     }
124
125     uint64_t pkt_count = 0;
126     for ( ii = 0; ii < ti->clip_count; ii++ )
127     {
128         pkt_count += ti->clips[ii].pkt_count;
129     }
130     title->block_start = 0;
131     title->block_end = pkt_count;
132     title->block_count = pkt_count;
133
134     title->angle_count = ti->angle_count;
135
136     /* Get duration */
137     title->duration = ti->duration;
138     title->hours    = title->duration / 90000 / 3600;
139     title->minutes  = ( ( title->duration / 90000 ) % 3600 ) / 60;
140     title->seconds  = ( title->duration / 90000 ) % 60;
141     hb_log( "bd: duration is %02d:%02d:%02d (%"PRId64" ms)",
142             title->hours, title->minutes, title->seconds,
143             title->duration / 90 );
144
145     /* ignore short titles because they're often stills */
146     if( ti->duration < min_duration )
147     {
148         hb_log( "bd: ignoring title (too short)" );
149         goto fail;
150     }
151
152     BLURAY_STREAM_INFO * bdvideo = &ti->clips[0].video_streams[0];
153
154     title->video_id = bdvideo->pid;
155     title->video_stream_type = bdvideo->coding_type;
156
157     hb_log( "bd: video id=%x, stream type=%s, format %s", title->video_id,
158             bdvideo->coding_type == BLURAY_STREAM_TYPE_VIDEO_MPEG1 ? "MPEG1" :
159             bdvideo->coding_type == BLURAY_STREAM_TYPE_VIDEO_MPEG2 ? "MPEG2" :
160             bdvideo->coding_type == BLURAY_STREAM_TYPE_VIDEO_VC1 ? "VC-1" :
161             bdvideo->coding_type == BLURAY_STREAM_TYPE_VIDEO_H264 ? "H264" :
162             "Unknown",
163             bdvideo->format == BLURAY_VIDEO_FORMAT_480I ? "480i" :
164             bdvideo->format == BLURAY_VIDEO_FORMAT_576I ? "576i" :
165             bdvideo->format == BLURAY_VIDEO_FORMAT_480P ? "480p" :
166             bdvideo->format == BLURAY_VIDEO_FORMAT_1080I ? "1080i" :
167             bdvideo->format == BLURAY_VIDEO_FORMAT_720P ? "720p" :
168             bdvideo->format == BLURAY_VIDEO_FORMAT_1080P ? "1080p" :
169             bdvideo->format == BLURAY_VIDEO_FORMAT_576P ? "576p" :
170             "Unknown"
171           );
172
173     if ( bdvideo->coding_type == BLURAY_STREAM_TYPE_VIDEO_VC1 &&
174        ( bdvideo->format == BLURAY_VIDEO_FORMAT_480I ||
175          bdvideo->format == BLURAY_VIDEO_FORMAT_576I ||
176          bdvideo->format == BLURAY_VIDEO_FORMAT_1080I ) )
177     {
178         hb_log( "bd: Interlaced VC-1 not supported" );
179         goto fail;
180     }
181
182     switch( bdvideo->coding_type )
183     {
184         case BLURAY_STREAM_TYPE_VIDEO_MPEG1:
185         case BLURAY_STREAM_TYPE_VIDEO_MPEG2:
186             title->video_codec = WORK_DECMPEG2;
187             title->video_codec_param = 0;
188             break;
189
190         case BLURAY_STREAM_TYPE_VIDEO_VC1:
191             title->video_codec = WORK_DECAVCODECV;
192             title->video_codec_param = CODEC_ID_VC1;
193             break;
194
195         case BLURAY_STREAM_TYPE_VIDEO_H264:
196             title->video_codec = WORK_DECAVCODECV;
197             title->video_codec_param = CODEC_ID_H264;
198             title->flags |= HBTF_NO_IDR;
199             break;
200
201         default:
202             hb_log( "scan: unknown video codec (%x)",
203                     bdvideo->coding_type );
204             goto fail;
205     }
206
207     switch ( bdvideo->aspect )
208     {
209         case BLURAY_ASPECT_RATIO_4_3:
210             title->container_aspect = 4. / 3.;
211             break;
212         case BLURAY_ASPECT_RATIO_16_9:
213             title->container_aspect = 16. / 9.;
214             break;
215         default:
216             hb_log( "bd: unknown aspect" );
217             goto fail;
218     }
219     hb_log( "bd: aspect = %g", title->container_aspect );
220
221     /* Detect audio */
222     // The BD may have clips that have no audio tracks, so scan
223     // the list of clips for one that has audio.
224     int most_audio = 0;
225     int audio_clip_index = 0;
226     for ( ii = 0; ii < ti->clip_count; ii++ )
227     {
228         if ( most_audio < ti->clips[ii].audio_stream_count )
229         {
230             most_audio = ti->clips[ii].audio_stream_count;
231             audio_clip_index = ii;
232         }
233     }
234     // Add all the audios found in the above clip.
235     for ( ii = 0; ii < ti->clips[audio_clip_index].audio_stream_count; ii++ )
236     {
237         hb_audio_t * audio;
238         iso639_lang_t * lang;
239         BLURAY_STREAM_INFO * bdaudio;
240
241         bdaudio = &ti->clips[audio_clip_index].audio_streams[ii];
242
243         hb_log( "bd: checking audio %d", ii + 1 );
244
245         audio = calloc( sizeof( hb_audio_t ), 1 );
246
247         audio->id = bdaudio->pid;
248
249         audio->config.in.stream_type = bdaudio->coding_type;
250         switch( bdaudio->coding_type )
251         {
252             case BLURAY_STREAM_TYPE_AUDIO_AC3:
253             case BLURAY_STREAM_TYPE_AUDIO_TRUHD:
254                 audio->config.in.codec = HB_ACODEC_AC3;
255                 audio->config.in.codec_param = 0;
256                 break;
257
258             case BLURAY_STREAM_TYPE_AUDIO_LPCM:
259                 audio->config.in.codec = HB_ACODEC_MPGA;
260                 audio->config.in.codec_param = CODEC_ID_PCM_BLURAY;
261                 break;
262
263             case BLURAY_STREAM_TYPE_AUDIO_AC3PLUS:
264                 audio->config.in.codec = HB_ACODEC_MPGA;
265                 audio->config.in.codec_param = CODEC_ID_EAC3;
266                 break;
267
268             case BLURAY_STREAM_TYPE_AUDIO_MPEG1:
269             case BLURAY_STREAM_TYPE_AUDIO_MPEG2:
270                 audio->config.in.codec = HB_ACODEC_MPGA;
271                 audio->config.in.codec_param = CODEC_ID_MP2;
272                 break;
273
274             case BLURAY_STREAM_TYPE_AUDIO_DTS:
275             case BLURAY_STREAM_TYPE_AUDIO_DTSHD:
276             case BLURAY_STREAM_TYPE_AUDIO_DTSHD_MASTER:
277                 audio->config.in.codec = HB_ACODEC_DCA;
278                 audio->config.in.codec_param = 0;
279                 break;
280
281             default:
282                 audio->config.in.codec = 0;
283                 hb_log( "scan: unknown audio codec (%x)",
284                         bdaudio->coding_type );
285                 break;
286         }
287
288         audio->config.lang.type = 0;
289         lang = lang_for_code2( (char*)bdaudio->lang );
290
291         snprintf( audio->config.lang.description, 
292             sizeof( audio->config.lang.description ), "%s (%s)",
293             strlen(lang->native_name) ? lang->native_name : 
294                                               lang->eng_name,
295             audio->config.in.codec == HB_ACODEC_AC3 ? "AC3" : 
296             ( audio->config.in.codec == HB_ACODEC_DCA ? "DTS" : 
297             ( audio->config.in.codec == HB_ACODEC_MPGA ? 
298                 ( audio->config.in.codec_param == CODEC_ID_PCM_BLURAY ? "LPCM" :
299                 ( audio->config.in.codec_param == CODEC_ID_EAC3 ? "E-AC3" :
300                 ( audio->config.in.codec_param == CODEC_ID_MP2 ? "MPEG" :
301                                                                "Unknown FFMpeg" 
302                 ) ) ) : "Unknown" 
303             ) ) );
304
305         snprintf( audio->config.lang.simple, 
306                   sizeof( audio->config.lang.simple ), "%s",
307                   strlen(lang->native_name) ? lang->native_name : 
308                                               lang->eng_name );
309
310         snprintf( audio->config.lang.iso639_2, 
311                   sizeof( audio->config.lang.iso639_2 ), "%s", lang->iso639_2);
312
313         hb_log( "bd: audio id=%x, lang=%s, 3cc=%s", audio->id,
314                 audio->config.lang.description, audio->config.lang.iso639_2 );
315
316         audio->config.in.track = ii;
317         hb_list_add( title->list_audio, audio );
318     }
319
320     /* Chapters */
321     for ( ii = 0; ii < ti->chapter_count; ii++ )
322     {
323         chapter = calloc( sizeof( hb_chapter_t ), 1 );
324
325         chapter->index = ii + 1;
326         chapter->duration = ti->chapters[ii].duration;
327         chapter->block_start = ti->chapters[ii].offset;
328
329         int seconds;
330         seconds            = ( chapter->duration + 45000 ) / 90000;
331         chapter->hours     = seconds / 3600;
332         chapter->minutes   = ( seconds % 3600 ) / 60;
333         chapter->seconds   = seconds % 60;
334
335         hb_log( "bd: chap %d packet=%"PRIu64", %"PRId64" ms",
336                 chapter->index,
337                 chapter->block_start,
338                 chapter->duration / 90 );
339
340         hb_list_add( title->list_chapter, chapter );
341     }
342     hb_log( "bd: title %d has %d chapters", tt, ti->chapter_count );
343
344     /* This title is ok so far */
345     goto cleanup;
346
347 fail:
348     hb_list_close( &title->list_audio );
349     free( title );
350     title = NULL;
351
352 cleanup:
353     if ( ti ) bd_free_title_info( ti );
354
355     return title;
356 }
357
358 /***********************************************************************
359  * hb_bd_main_feature
360  **********************************************************************/
361 int hb_bd_main_feature( hb_bd_t * d, hb_list_t * list_title )
362 {
363     int longest = 0;
364     int ii;
365     uint64_t longest_duration = 0;
366     int highest_rank = 0;
367     int rank[8] = {0, 1, 3, 2, 6, 5, 7, 4};
368     BLURAY_TITLE_INFO * ti;
369
370     for ( ii = 0; ii < hb_list_count( list_title ); ii++ )
371     {
372         hb_title_t * title = hb_list_item( list_title, ii );
373         ti = bd_get_title_info( d->bd, title->index - 1 );
374         if ( ti ) 
375         {
376             BLURAY_STREAM_INFO * bdvideo = &ti->clips[0].video_streams[0];
377             if ( title->duration > longest_duration * 0.7 && bdvideo->format < 8 )
378             {
379                 if (highest_rank < rank[bdvideo->format] ||
380                     ( title->duration > longest_duration &&
381                           highest_rank == rank[bdvideo->format]))
382                 {
383                     longest = title->index;
384                     longest_duration = title->duration;
385                     highest_rank = rank[bdvideo->format];
386                 }
387             }
388             bd_free_title_info( ti );
389         }
390         else if ( title->duration > longest_duration )
391         {
392             longest_duration = title->duration;
393             longest = title->index;
394         }
395     }
396     return longest;
397 }
398
399 /***********************************************************************
400  * hb_bd_start
401  ***********************************************************************
402  * Title and chapter start at 1
403  **********************************************************************/
404 int hb_bd_start( hb_bd_t * d, hb_title_t *title )
405 {
406     BD_EVENT event;
407
408     d->pkt_count = title->block_count;
409
410     // Calling bd_get_event initializes libbluray event queue.
411     bd_select_title( d->bd, title->index - 1 );
412     bd_get_event( d->bd, &event );
413     d->chapter = 1;
414     d->stream = hb_bd_stream_open( title );
415     if ( d->stream == NULL )
416     {
417         return 0;
418     }
419     return 1;
420 }
421
422 /***********************************************************************
423  * hb_bd_stop
424  ***********************************************************************
425  *
426  **********************************************************************/
427 void hb_bd_stop( hb_bd_t * d )
428 {
429     if( d->stream ) hb_stream_close( &d->stream );
430 }
431
432 /***********************************************************************
433  * hb_bd_seek
434  ***********************************************************************
435  *
436  **********************************************************************/
437 int hb_bd_seek( hb_bd_t * d, float f )
438 {
439     uint64_t packet = f * d->pkt_count;
440
441     bd_seek(d->bd, packet * 192);
442     d->next_chap = bd_get_current_chapter( d->bd ) + 1;
443     return 1;
444 }
445
446 int hb_bd_seek_pts( hb_bd_t * d, uint64_t pts )
447 {
448     bd_seek_time(d->bd, pts);
449     d->next_chap = bd_get_current_chapter( d->bd ) + 1;
450     return 1;
451 }
452
453 int hb_bd_seek_chapter( hb_bd_t * d, int c )
454 {
455     int64_t pos;
456     d->next_chap = c;
457     pos = bd_seek_chapter( d->bd, c - 1 );
458     return 1;
459 }
460
461 /***********************************************************************
462  * hb_bd_read
463  ***********************************************************************
464  *
465  **********************************************************************/
466 int hb_bd_read( hb_bd_t * d, hb_buffer_t * b )
467 {
468     int result;
469     int error_count = 0;
470     uint8_t buf[192];
471     BD_EVENT event;
472     uint64_t pos;
473
474     while ( 1 )
475     {
476         if ( d->next_chap != d->chapter )
477         {
478             b->new_chap = d->chapter = d->next_chap;
479         }
480         result = next_packet( d->bd, buf );
481         if ( result < 0 )
482         {
483             hb_error("bd: Read Error");
484             pos = bd_tell( d->bd );
485             bd_seek( d->bd, pos + 192 );
486             error_count++;
487             if (error_count > 10)
488             {
489                 hb_error("bd: Error, too many consecutive read errors");
490                 return 0;
491             }
492             continue;
493         }
494         else if ( result == 0 )
495         {
496             return 0;
497         }
498
499         error_count = 0;
500         while ( bd_get_event( d->bd, &event ) )
501         {
502             switch ( event.event )
503             {
504                 case BD_EVENT_CHAPTER:
505                     // The muxers expect to only get chapter 2 and above
506                     // They write chapter 1 when chapter 2 is detected.
507                     d->next_chap = event.param;
508                     break;
509
510                 default:
511                     break;
512             }
513         }
514         // buf+4 to skip the BD timestamp at start of packet
515         result = hb_ts_decode_pkt( d->stream, buf+4, b );
516         if ( result )
517         {
518             return 1;
519         }
520     }
521     return 0;
522 }
523
524 /***********************************************************************
525  * hb_bd_chapter
526  ***********************************************************************
527  * Returns in which chapter the next block to be read is.
528  * Chapter numbers start at 1.
529  **********************************************************************/
530 int hb_bd_chapter( hb_bd_t * d )
531 {
532     return d->next_chap;
533 }
534
535 /***********************************************************************
536  * hb_bd_close
537  ***********************************************************************
538  * Closes and frees everything
539  **********************************************************************/
540 void hb_bd_close( hb_bd_t ** _d )
541 {
542     hb_bd_t * d = *_d;
543
544     if( d->stream ) hb_stream_close( &d->stream );
545     if( d->bd ) bd_close( d->bd );
546
547     free( d );
548     *_d = NULL;
549 }
550
551 /***********************************************************************
552  * hb_bd_set_angle
553  ***********************************************************************
554  * Sets the angle to read
555  **********************************************************************/
556 void hb_bd_set_angle( hb_bd_t * d, int angle )
557 {
558
559     if ( !bd_select_angle( d->bd, angle) )
560     {
561         hb_log("bd_select_angle failed");
562     }
563 }
564
565 static int check_ts_sync(const uint8_t *buf)
566 {
567     // must have initial sync byte, no scrambling & a legal adaptation ctrl
568     return (buf[0] == 0x47) && ((buf[3] >> 6) == 0) && ((buf[3] >> 4) > 0);
569 }
570
571 static int have_ts_sync(const uint8_t *buf, int psize)
572 {
573     return check_ts_sync(&buf[0*psize]) && check_ts_sync(&buf[1*psize]) &&
574            check_ts_sync(&buf[2*psize]) && check_ts_sync(&buf[3*psize]) &&
575            check_ts_sync(&buf[4*psize]) && check_ts_sync(&buf[5*psize]) &&
576            check_ts_sync(&buf[6*psize]) && check_ts_sync(&buf[7*psize]);
577 }
578
579 #define MAX_HOLE 192*80
580
581 static uint64_t align_to_next_packet(BLURAY *bd, uint8_t *pkt)
582 {
583     uint8_t buf[MAX_HOLE];
584     uint64_t pos = 0;
585     uint64_t start = bd_tell(bd);
586     uint64_t orig;
587     uint64_t off = 192;
588
589     memcpy(buf, pkt, 192);
590     if ( start >= 192 ) {
591         start -= 192;
592     }
593     orig = start;
594
595     while (1)
596     {
597         if (bd_read(bd, buf+off, sizeof(buf)-off) == sizeof(buf)-off)
598         {
599             const uint8_t *bp = buf;
600             int i;
601
602             for ( i = sizeof(buf) - 8 * 192; --i >= 0; ++bp )
603             {
604                 if ( have_ts_sync( bp, 192 ) )
605                 {
606                     break;
607                 }
608             }
609             if ( i >= 0 )
610             {
611                 pos = ( bp - buf );
612                 break;
613             }
614             off = 8 * 192;
615             memcpy(buf, buf + sizeof(buf) - off, off);
616             start += sizeof(buf) - off;
617         }
618         else
619         {
620             return 0;
621         }
622     }
623     off = start + pos - 4;
624     // bd_seek seeks to the nearest access unit *before* the requested position
625     // we don't want to seek backwards, so we need to read until we get
626     // past that position.
627     bd_seek(bd, off);
628     while (off > bd_tell(bd))
629     {
630         if (bd_read(bd, buf, 192) != 192)
631         {
632             break;
633         }
634     }
635     return start - orig + pos;
636 }
637
638 static int next_packet( BLURAY *bd, uint8_t *pkt )
639 {
640     int result;
641
642     while ( 1 )
643     {
644         result = bd_read( bd, pkt, 192 );
645         if ( result < 0 )
646         {
647             return -1;
648         }
649         if ( result < 192 )
650         {
651             return 0;
652         }
653         // Sync byte is byte 4.  0-3 are timestamp.
654         if (pkt[4] == 0x47)
655         {
656             return 1;
657         }
658         // lost sync - back up to where we started then try to re-establish.
659         uint64_t pos = bd_tell(bd);
660         uint64_t pos2 = align_to_next_packet(bd, pkt);
661         if ( pos2 == 0 )
662         {
663             hb_log( "next_packet: eof while re-establishing sync @ %"PRId64, pos );
664             return 0;
665         }
666         hb_log( "next_packet: sync lost @ %"PRId64", regained after %"PRId64" bytes",
667                  pos, pos2 );
668     }
669 }
670