Index: libhb/decmpeg2.c =================================================================== --- libhb/decmpeg2.c (revision 1364) +++ libhb/decmpeg2.c (working copy) @@ -100,28 +100,18 @@ m->width = m->info->sequence->width; m->height = m->info->sequence->height; m->rate = m->info->sequence->frame_period; - } - if ( m->aspect_ratio <= 0 ) - { - // We can parse out the aspect ratio from the Sequence Start Header data in buf_es->data - - // Make sure we have the correct data in the buffer - if ((buf_es->data[0] == 0x00) && (buf_es->data[1] == 0x00) && (buf_es->data[2] == 0x01) && (buf_es->data[3] == 0xb3)) - { - unsigned char ar_fr = buf_es->data[7]; // Top 4 bits == aspect ratio flag - bottom 4 bits == rate flags - switch ((ar_fr & 0xf0) >> 4) + if ( m->aspect_ratio <= 0 && m->height && + m->info->sequence->pixel_height ) { - case 2: - m->aspect_ratio = HB_ASPECT_BASE * 4 / 3; // 4:3 - break; - case 3: - m->aspect_ratio = HB_ASPECT_BASE * 16 / 9; // 16:9 - break; - default: - hb_log("hb_libmpeg2_decode - STATE_SEQUENCE unexpected aspect ratio/frame rate 0x%x\n", ar_fr); - break; + /* mpeg2_parse doesn't store the aspect ratio. Instead + * it keeps the pixel width & height that would cause + * the storage width & height to come out in the correct + * aspect ratio. Convert these back to aspect ratio. + */ + m->aspect_ratio = ( m->width * m->info->sequence->pixel_width * + HB_ASPECT_BASE ) / m->height / + m->info->sequence->pixel_height; } - } } } else if( state == STATE_GOP && m->look_for_break == 2) Index: libhb/scan.c =================================================================== --- libhb/scan.c (revision 1364) +++ libhb/scan.c (working copy) @@ -134,38 +134,24 @@ if (data->stream) { - // Stream based processing uses PID's to handle the different audio options for a given title + // Stream based processing uses PID's to handle the different + // audio options for a given title for( j = 0; j < hb_list_count( title->list_audio ); j++ ) { audio = hb_list_item( title->list_audio, j ); hb_stream_update_audio(data->stream, audio); } } - else if (data->dvd) - { - /* Make sure we found AC3 rates and bitrates */ - for( j = 0; j < hb_list_count( title->list_audio ); ) - { - audio = hb_list_item( title->list_audio, j ); - if( audio->codec == HB_ACODEC_AC3 && - !audio->bitrate ) - { - hb_list_rem( title->list_audio, audio ); - free( audio ); - continue; - } - j++; - } - } - /* Make sure we found AC3 / DCA rates and bitrates */ + /* Make sure we found AC3 / DCA / LPCM rates and bitrates */ for( j = 0; j < hb_list_count( title->list_audio ); ) { audio = hb_list_item( title->list_audio, j ); - if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) && - !audio->bitrate ) + if( !audio->bitrate && + ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA || + audio->codec == HB_ACODEC_DCA ) ) { - hb_log( "scan: removing audio with codec of 0x%x because of no bitrate", + hb_log( "scan: removing audio 0x%x because of no bitrate", audio->codec ); hb_list_rem( title->list_audio, audio ); free( audio ); @@ -182,15 +168,17 @@ continue; } - /* set a default input channel layout of stereo for LPCM or MPEG2 audio */ - /* AC3 and DCA will already have had their layout set via DecodePreviews above, */ - /* which calls LookForAC3AndDCA */ + /* set a default input channel layout of stereo for MPEG2 audio */ + /* AC3, DCA & LPCM will already have had their layout set via + * DecodePreviews above, which calls LookForAC3AndDCA */ for( j = 0; j < hb_list_count( title->list_audio ); j++ ) { audio = hb_list_item( title->list_audio, j ); - if( audio->codec == HB_ACODEC_LPCM || audio->codec == HB_ACODEC_MPGA ) + if( audio->codec == HB_ACODEC_MPGA ) { audio->input_channel_layout = HB_INPUT_CH_LAYOUT_STEREO; + audio->rate = 48000; + audio->bitrate = 384000; } } @@ -316,7 +304,10 @@ } else if (data->stream) { - if (!hb_stream_seek(data->stream, (float) ( i + 1 ) / 11.0 ) ) + /* we start reading streams at zero rather than 1/11 because + * short streams may have only one sequence header in the entire + * file and we need it to decode any previews. */ + if (!hb_stream_seek(data->stream, (float) i / 11.0 ) ) { goto error; } @@ -359,22 +350,20 @@ ++ar4_count : ++ar16_count ; } } - else if( !i ) + else if( ! AllAC3AndDCAOK( title ) ) { LookForAC3AndDCA( title, buf_es ); } hb_buffer_close( &buf_es ); - if( hb_list_count( list_raw ) && - ( i || AllAC3AndDCAOK( title ) ) ) + if( hb_list_count( list_raw ) && AllAC3AndDCAOK( title ) ) { /* We got a picture */ break; } } - if( hb_list_count( list_raw ) && - ( i || AllAC3AndDCAOK( title ) ) ) + if( hb_list_count( list_raw ) && AllAC3AndDCAOK( title ) ) { break; } @@ -383,7 +372,7 @@ if( !hb_list_count( list_raw ) ) { hb_log( "scan: could not get a decoded picture" ); - goto error; + continue; } /* Get size and rate infos */ @@ -583,9 +572,11 @@ for( i = 0; i < hb_list_count( title->list_audio ); i++ ) { audio = hb_list_item( title->list_audio, i ); - /* check if we have an AC3 or DCA which we recognise */ - if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) && - audio->id == b->id ) + /* check if we have an AC3, DCA or LPCM which we recognise */ + if ( audio->id == b->id && + ( audio->codec == HB_ACODEC_AC3 || + audio->codec == HB_ACODEC_DCA || + audio->codec == HB_ACODEC_LPCM ) ) { break; } @@ -766,6 +757,39 @@ break; } } + else if ( i == 0 && audio->codec == HB_ACODEC_LPCM ) + { + // LPCM doesn't have a sync pattern like AC3 or DCA but every + // LPCM elementary stream packet starts with a 7 byte header + // giving the characteristics of the stream. + // See libhb/declpcm.c for a description of the LPCM header. + static const int hdr2samplerate[] = { 48000, 96000, 44100, 32000 }; + static const int hdr2samplesize[] = { 16, 20, 24, 16 }; + static const int hdr2layout[] = { + HB_INPUT_CH_LAYOUT_MONO, HB_INPUT_CH_LAYOUT_STEREO, + HB_INPUT_CH_LAYOUT_2F1R, HB_INPUT_CH_LAYOUT_2F2R, + HB_INPUT_CH_LAYOUT_3F2R, HB_INPUT_CH_LAYOUT_4F2R, + HB_INPUT_CH_LAYOUT_STEREO, HB_INPUT_CH_LAYOUT_STEREO, + }; + + int nchannels = ( b->data[4] & 7 ) + 1; + int sample_size = hdr2samplesize[b->data[4] >> 6]; + + rate = hdr2samplerate[ ( b->data[4] >> 4 ) & 0x3 ]; + bitrate = rate * sample_size * nchannels; + + hb_log( "scan: LPCM, rate=%dHz, bitrate=%d", rate, bitrate ); + audio->rate = rate; + audio->bitrate = bitrate; + + audio->input_channel_layout = hdr2layout[nchannels - 1]; + sprintf( audio->lang + strlen( audio->lang ), + " (%d.%d ch)", + HB_INPUT_CH_LAYOUT_GET_DISCRETE_FRONT_COUNT(audio->input_channel_layout) + + HB_INPUT_CH_LAYOUT_GET_DISCRETE_REAR_COUNT(audio->input_channel_layout), + HB_INPUT_CH_LAYOUT_GET_DISCRETE_LFE_COUNT(audio->input_channel_layout)); + break; + } } } @@ -778,12 +802,12 @@ for( i = 0; i < hb_list_count( title->list_audio ); i++ ) { audio = hb_list_item( title->list_audio, i ); - if( ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA ) && - !audio->bitrate ) + if( ! audio->bitrate && + ( audio->codec == HB_ACODEC_AC3 || audio->codec == HB_ACODEC_DCA || + audio->codec == HB_ACODEC_LPCM ) ) { return 0; } } - return 1; }