summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2011-11-14 23:50:18 +0000
committerjstebbins <[email protected]>2011-11-14 23:50:18 +0000
commitc557fe3d54da7141e898aae7f57f9897d92ba64c (patch)
treea5f6658d3817adf92f56e7fe0d358cc41ab6e429
parentcc95c30563cae17eff94e974f3e3dd07f1e2b309 (diff)
Fix interleaving of subtitles in muxer
Specifically, this affects closed captions which are pushed into the pipeline very late. CC's are dribbled in 2 bytes per video frame. The entire CC that we put into a subtitle frame isn't available till we see the signal for the end of the CC. This can be several seconds after it began. So I have established a minimum buffer size that the muxer accumulates before it outputs any data. This allows CCs to get into the pipeline before the muxer outputs the interleave interval that they belong in. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@4351 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--libhb/fifo.c15
-rw-r--r--libhb/internal.h1
-rw-r--r--libhb/muxcommon.c24
3 files changed, 32 insertions, 8 deletions
diff --git a/libhb/fifo.c b/libhb/fifo.c
index 42af6d9eb..7b5660673 100644
--- a/libhb/fifo.c
+++ b/libhb/fifo.c
@@ -196,6 +196,21 @@ void hb_buffer_realloc( hb_buffer_t * b, int size )
}
}
+void hb_buffer_reduce( hb_buffer_t * b, int size )
+{
+ if ( size < b->alloc / 8 || b->data == NULL )
+ {
+ uint32_t orig = b->alloc;
+ size = size_to_pool( size )->buffer_size;
+ b->data = realloc( b->data, size );
+ b->alloc = size;
+
+ hb_lock(buffers.lock);
+ buffers.allocated += size - orig;
+ hb_unlock(buffers.lock);
+ }
+}
+
// Frees the specified buffer list.
void hb_buffer_close( hb_buffer_t ** _b )
{
diff --git a/libhb/internal.h b/libhb/internal.h
index ee6bdccb2..00a7b3eb9 100644
--- a/libhb/internal.h
+++ b/libhb/internal.h
@@ -111,6 +111,7 @@ void hb_buffer_pool_free( void );
hb_buffer_t * hb_buffer_init( int size );
void hb_buffer_realloc( hb_buffer_t *, int size );
+void hb_buffer_reduce( hb_buffer_t * b, int size );
void hb_buffer_close( hb_buffer_t ** );
void hb_buffer_copy_settings( hb_buffer_t * dst,
const hb_buffer_t * src );
diff --git a/libhb/muxcommon.c b/libhb/muxcommon.c
index 98a978d0d..39f56dc6b 100644
--- a/libhb/muxcommon.c
+++ b/libhb/muxcommon.c
@@ -6,6 +6,7 @@
#include "hb.h"
+#define MIN_BUFFERING (1024*1024*10)
#define MAX_BUFFERING (1024*1024*50)
struct hb_mux_object_s
@@ -48,6 +49,7 @@ typedef struct
// allocated but the eof & rdy logic has to
// be changed to handle more than 32 tracks
// anyway so we keep it simple and fast.
+ int buffered_size;
} hb_mux_t;
struct hb_work_private_s
@@ -120,6 +122,7 @@ static void mf_push( hb_mux_t * mux, int tk, hb_buffer_t *buf )
uint32_t mask = track->mf.flen - 1;
uint32_t in = track->mf.in;
+ hb_buffer_reduce( buf, buf->size );
if ( track->buffered_size > MAX_BUFFERING )
{
mux->rdy = mux->allRdy;
@@ -152,11 +155,13 @@ static void mf_push( hb_mux_t * mux, int tk, hb_buffer_t *buf )
}
track->mf.fifo[in & mask] = buf;
track->mf.in = in + 1;
- track->buffered_size += buf->alloc;
+ track->buffered_size += buf->size;
+ mux->buffered_size += buf->size;
}
-static hb_buffer_t *mf_pull( hb_track_t *track )
+static hb_buffer_t *mf_pull( hb_mux_t * mux, int tk )
{
+ hb_track_t *track =mux->track[tk];
hb_buffer_t *b = NULL;
if ( track->mf.out != track->mf.in )
{
@@ -164,7 +169,8 @@ static hb_buffer_t *mf_pull( hb_track_t *track )
b = track->mf.fifo[track->mf.out & (track->mf.flen - 1)];
++track->mf.out;
- track->buffered_size -= b->alloc;
+ track->buffered_size -= b->size;
+ mux->buffered_size -= b->size;
}
return b;
}
@@ -190,13 +196,14 @@ static void MoveToInternalFifos( int tk, hb_mux_t *mux, hb_buffer_t * buf )
}
}
-static void OutputTrackChunk( hb_mux_t *mux, hb_track_t *track, hb_mux_object_t *m )
+static void OutputTrackChunk( hb_mux_t *mux, int tk, hb_mux_object_t *m )
{
+ hb_track_t *track = mux->track[tk];
hb_buffer_t *buf;
while ( ( buf = mf_peek( track ) ) != NULL && buf->start < mux->pts )
{
- buf = mf_pull( track );
+ buf = mf_pull( mux, tk );
track->frames += 1;
track->bytes += buf->size;
m->mux( m, track->mux_data, buf );
@@ -247,14 +254,15 @@ static int muxWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
int more = mux->rdy;
// all tracks have at least 'interleave' ticks of data. Output
// all that we can in 'interleave' size chunks.
- while ( (( mux->rdy & mux->allRdy ) == mux->allRdy && more) ||
+ while ( (( mux->rdy & mux->allRdy ) == mux->allRdy &&
+ more && mux->buffered_size > MIN_BUFFERING ) ||
( mux->eof == mux->allEof ) )
{
more = 0;
for ( i = 0; i < mux->ntracks; ++i )
{
track = mux->track[i];
- OutputTrackChunk( mux, track, mux->m );
+ OutputTrackChunk( mux, i, mux->m );
if ( mf_full( track ) )
{
// If the track's fifo is still full, advance
@@ -375,7 +383,7 @@ void muxClose( hb_work_object_t * w )
{
hb_buffer_t * b;
track = mux->track[i];
- while ( (b = mf_pull( track )) != NULL )
+ while ( (b = mf_pull( mux, i )) != NULL )
{
hb_buffer_close( &b );
}