X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fcodec%2Flpcm.c;h=1360a4f1c44965e7d7eb0bab78188cbaadb399c9;hb=5a2f258ce8cd94f83fd6f0808be2154272e632f3;hp=4d1eb04f13c45733f0a64ca211661a5d26c41e8a;hpb=661c20f5694da6ff372c7819c1b6cb828bb66962;p=vlc diff --git a/modules/codec/lpcm.c b/modules/codec/lpcm.c index 4d1eb04f13..1360a4f1c4 100644 --- a/modules/codec/lpcm.c +++ b/modules/codec/lpcm.c @@ -9,6 +9,7 @@ * Christophe Massiot * Gildas Bazin * Lauren Aimar + * Steinar H. Gunderson * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -436,19 +437,29 @@ static int OpenEncoder( vlc_object_t *p_this ) encoder_sys_t *p_sys; /* We only support DVD LPCM yet. */ - if( p_enc->fmt_out.i_codec != VLC_CODEC_DVD_LPCM || - ( p_enc->fmt_in.audio.i_rate != 48000 && - p_enc->fmt_in.audio.i_rate != 96000 && - p_enc->fmt_in.audio.i_rate != 44100 && - p_enc->fmt_in.audio.i_rate != 32000 ) || - p_enc->fmt_in.audio.i_channels > 8 ) + if( p_enc->fmt_out.i_codec != VLC_CODEC_DVD_LPCM ) return VLC_EGENERIC; + if( p_enc->fmt_in.audio.i_rate != 48000 && + p_enc->fmt_in.audio.i_rate != 96000 && + p_enc->fmt_in.audio.i_rate != 44100 && + p_enc->fmt_in.audio.i_rate != 32000 ) + { + msg_Err( p_enc, "DVD LPCM supports only sample rates of 48, 96, 44.1 or 32 kHz" ); + return VLC_EGENERIC; + } + + if( p_enc->fmt_in.audio.i_channels > 8 ) + { + msg_Err( p_enc, "DVD LPCM supports a maximum of eight channels" ); + return VLC_EGENERIC; + } + /* Allocate the memory needed to store the encoder's structure */ if( ( p_enc->p_sys = p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL ) return VLC_ENOMEM; - + /* In DVD LCPM, a frame is always 150 PTS ticks. */ p_sys->i_frame_samples = p_enc->fmt_in.audio.i_rate * 150 / 90000; p_sys->p_buffer = (uint8_t *)malloc( @@ -460,7 +471,7 @@ static int OpenEncoder( vlc_object_t *p_this ) p_sys->i_channels = p_enc->fmt_in.audio.i_channels; p_sys->i_rate = p_enc->fmt_in.audio.i_rate; - + p_enc->pf_encode_audio = EncodeFrames; p_enc->fmt_in.i_codec = p_enc->fmt_out.i_codec; @@ -473,7 +484,7 @@ static int OpenEncoder( vlc_object_t *p_this ) p_enc->fmt_in.audio.i_bitspersample * (p_sys->i_frame_samples + LPCM_VOB_HEADER_LEN) / p_sys->i_frame_samples; - + return VLC_SUCCESS; } @@ -482,7 +493,11 @@ static int OpenEncoder( vlc_object_t *p_this ) *****************************************************************************/ static void CloseEncoder ( vlc_object_t *p_this ) { - VLC_UNUSED(p_this); + encoder_t *p_enc = (encoder_t *)p_this; + encoder_sys_t *p_sys = p_enc->p_sys; + + free( p_sys->p_buffer ); + free( p_sys ); } /***************************************************************************** @@ -517,6 +532,8 @@ static block_t *EncodeFrames( encoder_t *p_enc, aout_buffer_t *p_aout_buf ) case 32000: i_freq_code = 3; break; + default: + assert(0); } int i_bytes_consumed = 0; @@ -541,15 +558,20 @@ static block_t *EncodeFrames( encoder_t *p_enc, aout_buffer_t *p_aout_buf ) memcpy( frame + 6, p_sys->p_buffer, i_kept_bytes ); memcpy( frame + 6 + i_kept_bytes, p_aout_buf->p_buffer + i_bytes_consumed, i_consume_bytes ); - + p_sys->i_frame_num++; p_sys->i_buffer_used = 0; i_bytes_consumed += i_consume_bytes; - p_block->i_dts = p_block->i_pts = p_aout_buf->i_pts + + /* We need to find i_length by means of next_pts due to possible roundoff errors. */ + mtime_t this_pts = p_aout_buf->i_pts + (i * p_sys->i_frame_samples + i_start_offset) * CLOCK_FREQ / p_sys->i_rate; - p_block->i_length = p_sys->i_frame_samples * CLOCK_FREQ / p_sys->i_rate; - + mtime_t next_pts = p_aout_buf->i_pts + + ((i + 1) * p_sys->i_frame_samples + i_start_offset) * CLOCK_FREQ / p_sys->i_rate; + + p_block->i_pts = p_block->i_dts = this_pts; + p_block->i_length = next_pts - this_pts; + if( !p_first_block ) p_first_block = p_last_block = p_block; else