diff options
Diffstat (limited to 'core/VorbisEnc.c')
-rw-r--r-- | core/VorbisEnc.c | 222 |
1 files changed, 68 insertions, 154 deletions
diff --git a/core/VorbisEnc.c b/core/VorbisEnc.c index c75b36850..8b7b10f8f 100644 --- a/core/VorbisEnc.c +++ b/core/VorbisEnc.c @@ -1,4 +1,4 @@ -/* $Id: VorbisEnc.c,v 1.5 2004/03/08 11:32:49 titer Exp $ +/* $Id: VorbisEnc.c,v 1.9 2004/05/02 16:25:00 titer Exp $ This file is part of the HandBrake source code. Homepage: <http://handbrake.m0k.org/>. @@ -11,7 +11,7 @@ #define OGGVORBIS_FRAME_SIZE 1024 -typedef struct HBVorbisEnc +struct HBWork { HB_WORK_COMMON_MEMBERS @@ -23,60 +23,46 @@ typedef struct HBVorbisEnc vorbis_comment vc; vorbis_dsp_state vd; vorbis_block vb; + float position; - HBBuffer *rawBuffer; - int rawBufferPos; /* in bytes */ - float position; int32_t * inputBuffer; - unsigned long samplesGot; - unsigned long inputSamples; - HBBuffer *vorbisBuffer; - - HBBuffer *header[3]; -} HBVorbisEnc; +}; /* Local prototypes */ static int VorbisEncWork( HBWork * ); -static int GetSamples( HBVorbisEnc * ); -HBWork *HBVorbisEncInit ( HBHandle *handle, HBAudio *audio ) +HBWork * HBVorbisEncInit ( HBHandle * handle, HBAudio * audio ) { - HBVorbisEnc *enc = malloc( sizeof( HBVorbisEnc ) ); - - enc->name = strdup( "VorbisEnc" ); - enc->work = VorbisEncWork; + HBWork * w = calloc( sizeof( HBWork ), 1 ); - enc->handle = handle; - enc->audio = audio; + w->name = strdup( "VorbisEnc" ); + w->work = VorbisEncWork; - enc->inited = 0; - enc->rawBuffer = NULL; - enc->inputSamples = 2 * OGGVORBIS_FRAME_SIZE; - enc->inputBuffer = malloc( 2 * OGGVORBIS_FRAME_SIZE * sizeof( int32_t ) ); - enc->samplesGot = 0; + w->handle = handle; + w->audio = audio; - enc->vorbisBuffer = NULL; + w->inputBuffer = malloc( 2 * OGGVORBIS_FRAME_SIZE * sizeof( int32_t ) ); - return (HBWork*) enc; + return w; } -void HBVorbisEncClose( HBWork **_enc ) +void HBVorbisEncClose( HBWork ** _w ) { - HBVorbisEnc *enc = (HBVorbisEnc*) *_enc; + HBWork * w = *_w; - if( enc->inited ) + if( w->inited ) { - vorbis_block_clear( &enc->vb ); - vorbis_dsp_clear( &enc->vd ); - vorbis_comment_clear( &enc->vc ); - vorbis_info_clear( &enc->vi ); + vorbis_block_clear( &w->vb ); + vorbis_dsp_clear( &w->vd ); + vorbis_comment_clear( &w->vc ); + vorbis_info_clear( &w->vi ); } - free( enc->name ); - free( enc ); + free( w->name ); + free( w ); - *_enc = NULL; + *_w = NULL; } static HBBuffer *PacketToBuffer( ogg_packet *op ) @@ -89,170 +75,98 @@ static HBBuffer *PacketToBuffer( ogg_packet *op ) return buf; } -static int VorbisEncWork( HBWork *w ) +static int VorbisEncWork( HBWork * w ) { - HBVorbisEnc *enc = (HBVorbisEnc*)w; - HBAudio *audio = enc->audio; - int didSomething = 0; + HBAudio * audio = w->audio; float **buffer; int i; + float inputBuffer[OGGVORBIS_FRAME_SIZE * 2]; + HBBuffer * vorbisBuffer; + if( HBFifoIsHalfFull( audio->outFifo ) ) + { + return 0; + } - if( !enc->inited ) + if( !w->inited ) { ogg_packet header[3]; - /* Get a first buffer so we know that audio->inSampleRate is correct */ - if( ( enc->rawBuffer = HBFifoPop( audio->rawFifo ) ) == NULL ) + if( !HBFifoSize( audio->resampleFifo ) ) { return 0; } - enc->inited = 1; - - didSomething = 1; - enc->rawBufferPos = 0; - enc->position = enc->rawBuffer->position; - /* No resampling */ - audio->outSampleRate = audio->inSampleRate; + w->inited = 1; /* init */ - vorbis_info_init( &enc->vi ); - if( vorbis_encode_setup_managed( &enc->vi, 2, - audio->inSampleRate, -1, 1000 * audio->outBitrate, -1 ) || - vorbis_encode_ctl( &enc->vi, OV_ECTL_RATEMANAGE_AVG, NULL ) || - vorbis_encode_setup_init( &enc->vi ) ) + vorbis_info_init( &w->vi ); + if( vorbis_encode_setup_managed( &w->vi, 2, + audio->outSampleRate, -1, 1000 * audio->outBitrate, -1 ) || + vorbis_encode_ctl( &w->vi, OV_ECTL_RATEMANAGE_AVG, NULL ) || + vorbis_encode_setup_init( &w->vi ) ) { - HBLog( "VorbisEnc: vorbis_encode_setup_managed failed" ); + HBLog( "HBVorbisEnc: vorbis_encode_setup_managed failed" ); return 0; } /* add a comment */ - vorbis_comment_init( &enc->vc ); - vorbis_comment_add_tag( &enc->vc, "ENCODER", "HandBrake"); + vorbis_comment_init( &w->vc ); + vorbis_comment_add_tag( &w->vc, "ENCODER", "HandBrake"); /* set up the analysis state and auxiliary encoding storage */ - vorbis_analysis_init( &enc->vd, &enc->vi); - vorbis_block_init( &enc->vd, &enc->vb); + vorbis_analysis_init( &w->vd, &w->vi); + vorbis_block_init( &w->vd, &w->vb); /* get the 3 headers */ - vorbis_analysis_headerout( &enc->vd, &enc->vc, + vorbis_analysis_headerout( &w->vd, &w->vc, &header[0], &header[1], &header[2] ); - - enc->header[0] = PacketToBuffer( &header[0] ); - enc->header[1] = PacketToBuffer( &header[1] ); - enc->header[2] = PacketToBuffer( &header[2] ); - } - - if( enc->header[0] ) - { - HBLog( "VorbisEncWork: sending header 1" ); - if( !HBFifoPush( audio->outFifo, &enc->header[0] ) ) - { - return didSomething; - } - didSomething = 1; - } - if( enc->header[1] ) - { - HBLog( "VorbisEncWork: sending header 2" ); - if( !HBFifoPush( audio->outFifo, &enc->header[1] ) ) - { - return didSomething; - } - didSomething = 1; - } - if( enc->header[2] ) - { - HBLog( "VorbisEncWork: sending header 3" ); - if( !HBFifoPush( audio->outFifo, &enc->header[2] ) ) - { - return didSomething; - } - didSomething = 1; - } - - /* Push already encoded data */ - if( enc->vorbisBuffer ) - { - if( !HBFifoPush( audio->outFifo, &enc->vorbisBuffer ) ) + for( i = 0; i < 3; i++ ) { - return didSomething; + vorbisBuffer = PacketToBuffer( &header[i] ); + if( !HBFifoPush( audio->outFifo, &vorbisBuffer ) ) + { + HBLog( "HBVorbisEnc: HBFifoPush failed" ); + } } } /* Try to extract more data */ - if( vorbis_analysis_blockout( &enc->vd, &enc->vb ) == 1 ) + if( vorbis_analysis_blockout( &w->vd, &w->vb ) == 1 ) { ogg_packet op; - vorbis_analysis( &enc->vb, NULL ); - vorbis_bitrate_addblock( &enc->vb ); + vorbis_analysis( &w->vb, NULL ); + vorbis_bitrate_addblock( &w->vb ); - if( vorbis_bitrate_flushpacket( &enc->vd, &op ) ) + if( vorbis_bitrate_flushpacket( &w->vd, &op ) ) { - enc->vorbisBuffer = PacketToBuffer( &op ); - enc->vorbisBuffer->position = enc->position; + vorbisBuffer = PacketToBuffer( &op ); + vorbisBuffer->position = w->position; + if( !HBFifoPush( audio->outFifo, &vorbisBuffer ) ) + { + HBLog( "HBVorbisEnc: HBFifoPush failed" ); + } return 1; } } - /* FUCK -Werror ! */ - if( !GetSamples( enc ) ) + if( !HBFifoGetBytes( audio->resampleFifo, (uint8_t*) inputBuffer, + OGGVORBIS_FRAME_SIZE * 2 * sizeof( float ), + &w->position ) ) { - return didSomething; + return 0; } - didSomething = 1; - - buffer = vorbis_analysis_buffer( &enc->vd, OGGVORBIS_FRAME_SIZE ); + buffer = vorbis_analysis_buffer( &w->vd, OGGVORBIS_FRAME_SIZE ); for( i = 0; i < OGGVORBIS_FRAME_SIZE; i++ ) { - buffer[0][i] = (float)enc->inputBuffer[2 * i + 0]/32768.f; - buffer[1][i] = (float)enc->inputBuffer[2 * i + 1]/32768.f; + buffer[0][i] = inputBuffer[2*i] / 32768.f; + buffer[1][i] = inputBuffer[2*i+1] / 32768.f; } - vorbis_analysis_wrote( &enc->vd, OGGVORBIS_FRAME_SIZE ); - - enc->samplesGot = 0; + vorbis_analysis_wrote( &w->vd, OGGVORBIS_FRAME_SIZE ); return 1; } -static int GetSamples( HBVorbisEnc * f ) -{ - while( f->samplesGot < f->inputSamples ) - { - int i, copy; - - if( !f->rawBuffer ) - { - if( !( f->rawBuffer = HBFifoPop( f->audio->rawFifo ) ) ) - { - return 0; - } - - f->rawBufferPos = 0; - f->position = f->rawBuffer->position; - } - - copy = MIN( f->inputSamples - f->samplesGot, - ( f->rawBuffer->samples - f->rawBufferPos ) * 2 ); - - for( i = 0; i < copy; i += 2 ) - { - f->inputBuffer[f->samplesGot++] = - f->rawBuffer->left[f->rawBufferPos]; - f->inputBuffer[f->samplesGot++] = - f->rawBuffer->right[f->rawBufferPos]; - f->rawBufferPos++; - } - - if( f->rawBufferPos == f->rawBuffer->samples ) - { - HBBufferClose( &f->rawBuffer ); - } - } - - return 1; -} |