X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=libhb%2Fmuxcommon.c;h=b09c5c58fc5952bb8c82ecddb0f0e3f06cc9d2d9;hb=c5c381e3579de78ead6a777da6c8b934aeaba19e;hp=d6a8270da637a50ec55625399ff92fbc39b5ab50;hpb=cd65e8ebdf229f5033bcb324bdbd567814cd4b5d;p=handbrake-jp%2Fhandbrake-jp-git.git diff --git a/libhb/muxcommon.c b/libhb/muxcommon.c index d6a8270d..b09c5c58 100644 --- a/libhb/muxcommon.c +++ b/libhb/muxcommon.c @@ -1,7 +1,7 @@ /* $Id: muxcommon.c,v 1.23 2005/03/30 17:27:19 titer Exp $ This file is part of the HandBrake source code. - Homepage: . + Homepage: . It may be used under the terms of the GNU General Public License. */ #include "hb.h" @@ -24,10 +24,10 @@ typedef struct hb_mux_data_t * mux_data; uint64_t frames; uint64_t bytes; - + int eof; } hb_track_t; -static hb_track_t * GetTrack( hb_list_t * list ) +static hb_track_t * GetTrack( hb_list_t * list, hb_job_t *job ) { hb_buffer_t * buf; hb_track_t * track = NULL, * track2; @@ -37,18 +37,59 @@ static hb_track_t * GetTrack( hb_list_t * list ) for( i = 0; i < hb_list_count( list ); i++ ) { track2 = hb_list_item( list, i ); - buf = hb_fifo_see( track2->fifo ); - if( !buf ) + if ( ! track2->eof ) { - return NULL; + buf = hb_fifo_see( track2->fifo ); + if( !buf ) + { + // XXX the libmkv muxer will produce unplayable files if the + // audio & video are far out of sync. To keep them in sync we require + // that *all* fifos have a buffer then we take the oldest. + // Unfortunately this means we can hang in a deadlock with the + // reader process filling the fifos. + if ( job->mux == HB_MUX_MKV ) + { + return NULL; + } + + // To make sure we don't camp on one fifo & prevent the others + // from making progress we take the earliest data of all the + // data that's currently available but we don't care if some + // fifos don't have data. + continue; + } + if ( buf->size <= 0 ) + { + // EOF - mark this track as done + buf = hb_fifo_get( track2->fifo ); + hb_buffer_close( &buf ); + track2->eof = 1; + continue; + } + if( !track || buf->start < pts ) + { + track = track2; + pts = buf->start; + } } - if( !track || buf->start < pts ) + } + return track; +} + +static int AllTracksDone( hb_list_t * list ) +{ + hb_track_t * track; + int i; + + for( i = 0; i < hb_list_count( list ); i++ ) + { + track = hb_list_item( list, i ); + if ( track->eof == 0 ) { - track = track2; - pts = buf->start; + return 0; } } - return track; + return 1; } static void MuxerFunc( void * _mux ) @@ -85,34 +126,6 @@ static void MuxerFunc( void * _mux ) } } - /* Wait for one buffer for each track */ - while( !*job->die && !job->done ) - { - int ready; - - ready = 1; - if( !hb_fifo_size( job->fifo_mpeg4 ) ) - { - ready = 0; - } - for( i = 0; i < hb_list_count( title->list_audio ); i++ ) - { - audio = hb_list_item( title->list_audio, i ); - if( !hb_fifo_size( audio->fifo_out ) ) - { - ready = 0; - break; - } - } - - if( ready ) - { - break; - } - - hb_snooze( 50 ); - } - /* Create file, write headers */ if( job->pass == 0 || job->pass == 2 ) { @@ -131,21 +144,24 @@ static void MuxerFunc( void * _mux ) { audio = hb_list_item( title->list_audio, i ); track = calloc( sizeof( hb_track_t ), 1 ); - track->fifo = audio->fifo_out; - track->mux_data = audio->mux_data; + track->fifo = audio->priv.fifo_out; + track->mux_data = audio->priv.mux_data; hb_list_add( list, track ); } int thread_sleep_interval = 50; - while( !*job->die && !job->done ) + while( !*job->die ) { - if( !( track = GetTrack( list ) ) ) + if( !( track = GetTrack( list, job ) ) ) { + if ( AllTracksDone( list ) ) + { + // all our input fifos have signaled EOF + break; + } hb_snooze( thread_sleep_interval ); -// thread_sleep_interval += 1; continue; } -// thread_sleep_interval = MAX(1, (thread_sleep_interval - 1)); buf = hb_fifo_get( track->fifo ); if( job->pass == 0 || job->pass == 2 ) @@ -174,20 +190,20 @@ static void MuxerFunc( void * _mux ) if( !stat( job->file, &sb ) ) { - hb_log( "mux: file size, %lld bytes", (uint64_t) sb.st_size ); + hb_deep_log( 2, "mux: file size, %lld bytes", (uint64_t) sb.st_size ); bytes_total = 0; frames_total = 0; for( i = 0; i < hb_list_count( list ); i++ ) { track = hb_list_item( list, i ); - hb_log( "mux: track %d, %lld bytes, %.2f kbps", + hb_deep_log( 2, "mux: track %d, %lld bytes, %.2f kbps", i, track->bytes, 90000.0 * track->bytes / mux->pts / 125 ); if( !i && ( job->vquality < 0.0 || job->vquality > 1.0 ) ) { /* Video */ - hb_log( "mux: video bitrate error, %+lld bytes", + hb_deep_log( 2, "mux: video bitrate error, %+lld bytes", track->bytes - mux->pts * job->vbitrate * 125 / 90000 ); } @@ -197,7 +213,7 @@ static void MuxerFunc( void * _mux ) if( bytes_total && frames_total ) { - hb_log( "mux: overhead, %.2f bytes per frame", + hb_deep_log( 2, "mux: overhead, %.2f bytes per frame", (float) ( sb.st_size - bytes_total ) / frames_total ); }