void hb_buffer_list_append(hb_buffer_list_t *list, hb_buffer_t *buf)
{
int count = 1;
+ int size = 0;
hb_buffer_t *end = buf;
if (buf == NULL)
}
// Input buffer may be a list of buffers, find the end.
+ size += buf->size;
while (end != NULL && end->next != NULL)
{
+ size += end->size;
end = end->next;
count++;
}
list->tail = end;
}
list->count += count;
+ list->size += size;
}
void hb_buffer_list_prepend(hb_buffer_list_t *list, hb_buffer_t *buf)
{
int count = 1;
+ int size = 0;
hb_buffer_t *end = buf;
if (buf == NULL)
}
// Input buffer may be a list of buffers, find the end.
+ size += buf->size;
while (end != NULL && end->next != NULL)
{
+ size += end->size;
end = end->next;
count++;
}
list->head = buf;
}
list->count += count;
+ list->size += size;
}
hb_buffer_t* hb_buffer_list_rem_head(hb_buffer_list_t *list)
}
list->head = list->head->next;
list->count--;
+ list->size -= head->size;
}
if (head != NULL)
{
{
list->head = list->tail = NULL;
list->count = 0;
+ list->size = 0;
}
else if (list->tail != NULL)
{
end->next = NULL;
list->tail = end;
list->count--;
+ list->size -= tail->size;
}
if (tail != NULL)
{
hb_buffer_t* hb_buffer_list_set(hb_buffer_list_t *list, hb_buffer_t *buf)
{
int count = 0;
+ int size = 0;
if (list == NULL)
{
if (end != NULL)
{
count++;
+ size += end->size;
while (end->next != NULL)
{
end = end->next;
count++;
+ size += end->size;
}
}
list->head = buf;
list->tail = end;
list->count = count;
+ list->size = size;
return head;
}
hb_buffer_t *head = list->head;
list->head = list->tail = NULL;
list->count = 0;
+ list->size = 0;
return head;
}
return list->count;
}
+int hb_buffer_list_size(hb_buffer_list_t *list)
+{
+ return list->size;
+}
+
/**********************************************************************
* hb_list implementation
**********************************************************************
int valid; // Stream timing is not valid until next scr.
} stream_timing_t;
+typedef struct
+{
+ int id;
+ hb_buffer_list_t list;
+} buffer_splice_list_t;
+
struct hb_work_private_s
{
hb_handle_t * h;
uint64_t st_first;
uint64_t duration;
hb_fifo_t * fifos[100];
+
+ buffer_splice_list_t * splice_list;
+ int splice_list_size;
};
/***********************************************************************
**********************************************************************/
static hb_fifo_t ** GetFifoForId( hb_work_private_t * r, int id );
static void UpdateState( hb_work_private_t * r, int64_t start);
+static hb_buffer_list_t * get_splice_list(hb_work_private_t * r, int id);
/***********************************************************************
* reader_init
}
}
+ // Count number of splice lists needed for merging buffers
+ // that have been split
+ int count = 1; // 1 for video
+ count += hb_list_count( job->list_subtitle );
+ count += hb_list_count( job->list_audio );
+ r->splice_list_size = count;
+ r->splice_list = calloc(count, sizeof(buffer_splice_list_t));
+
+ // Initialize stream id's of splice lists
+ int ii, jj = 0;
+ r->splice_list[jj++].id = r->title->video_id;
+ for (ii = 0; ii < hb_list_count(job->list_subtitle); ii++)
+ {
+ hb_subtitle_t * subtitle = hb_list_item(job->list_subtitle, ii);
+ r->splice_list[jj++].id = subtitle->id;
+ }
+ for (ii = 0; ii < hb_list_count(job->list_audio); ii++)
+ {
+ hb_audio_t * audio = hb_list_item(job->list_audio, ii);
+ r->splice_list[jj++].id = audio->id;
+ }
+
// The stream needs to be open before starting the reader thead
// to prevent a race with decoders that may share information
// with the reader. Specifically avcodec needs this.
free( r );
}
-static void push_buf( const hb_work_private_t *r, hb_fifo_t *fifo, hb_buffer_t *buf )
+static void push_buf( hb_work_private_t *r, hb_fifo_t *fifo, hb_buffer_t *buf )
{
+ // Handle buffers that were split across a PCR discontinuity.
+ // Rejoin them into a single buffer.
+ hb_buffer_list_t * list = get_splice_list(r, buf->s.id);
+ if (list != NULL)
+ {
+ hb_buffer_list_append(list, buf);
+ if (buf->s.split)
+ {
+ return;
+ }
+
+ int count = hb_buffer_list_count(list);
+ if (count > 1)
+ {
+ int size = hb_buffer_list_size(list);
+ hb_buffer_t * b = hb_buffer_init(size);
+ buf = hb_buffer_list_head(list);
+ b->s = buf->s;
+
+ int pos = 0;
+ while ((buf = hb_buffer_list_rem_head(list)) != NULL)
+ {
+ memcpy(b->data + pos, buf->data, buf->size);
+ pos += buf->size;
+ hb_buffer_close(&buf);
+ }
+ buf = b;
+ }
+ else
+ {
+ buf = hb_buffer_list_clear(list);
+ }
+ }
while ( !*r->die && !r->job->done )
{
if ( hb_fifo_full_wait( fifo ) )
return NULL;
}
+static hb_buffer_list_t * get_splice_list(hb_work_private_t * r, int id)
+{
+ int ii;
+
+ for (ii = 0; ii < r->splice_list_size; ii++)
+ {
+ if (r->splice_list[ii].id == id)
+ {
+ return &r->splice_list[ii].list;
+ }
+ }
+ return NULL;
+}