diff options
author | John Stebbins <[email protected]> | 2016-05-17 11:51:25 -0600 |
---|---|---|
committer | John Stebbins <[email protected]> | 2016-05-17 11:51:25 -0600 |
commit | de858d1600ac61258dc895b2fc8756b7c5d1d3a8 (patch) | |
tree | cdbd82e3d9ee83cfb9a31ebbb034852aa36fb2cb /libhb/encx264.c | |
parent | 9dcce9df07f4db1fa61f25ffeb106aa00bd64190 (diff) |
libhb: send initial chapter through pipeline
Eliminate the need for everyone to assume that the first chapter starts
at the first frame.
Diffstat (limited to 'libhb/encx264.c')
-rw-r--r-- | libhb/encx264.c | 179 |
1 files changed, 59 insertions, 120 deletions
diff --git a/libhb/encx264.c b/libhb/encx264.c index 30cee1096..50f7fe197 100644 --- a/libhb/encx264.c +++ b/libhb/encx264.c @@ -48,34 +48,27 @@ hb_work_object_t hb_encx264 = struct hb_work_private_s { - hb_job_t * job; - x264_t * x264; - x264_picture_t pic_in; + hb_job_t * job; + x264_t * x264; + x264_picture_t pic_in; - int64_t last_stop; // Debugging - stop time of previous input frame + int64_t last_stop; // Debugging - stop time of previous input frame + + hb_chapter_queue_t * chapter_queue; - hb_list_t * delayed_chapters; - int64_t next_chapter_pts; struct { - int64_t duration; + int64_t duration; } frame_info[FRAME_INFO_SIZE]; - char filename[1024]; + char filename[1024]; // Multiple bit-depth - const x264_api_t * api; + const x264_api_t * api; }; #define HB_X264_API_COUNT 2 static x264_api_t x264_apis[HB_X264_API_COUNT]; -// used in delayed_chapters list -struct chapter_s -{ - int index; - int64_t start; -}; - const char *libx264_10bit_names[] = { "libx26410b", "libx264_main10", NULL }; @@ -313,12 +306,12 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job ) if (pv->api == NULL) { hb_error("encx264: hb_x264_api_get failed, bit-depth %d", bit_depth); + return 1; } pv->job = job; - pv->next_chapter_pts = AV_NOPTS_VALUE; pv->last_stop = AV_NOPTS_VALUE; - pv->delayed_chapters = hb_list_init(); + pv->chapter_queue = hb_chapter_queue_init(); if (pv->api->param_default_preset(¶m, job->encoder_preset, job->encoder_tune) < 0) @@ -613,22 +606,12 @@ void encx264Close( hb_work_object_t * w ) // Not initialized return; } - if (pv->delayed_chapters != NULL) - { - struct chapter_s *item; - while ((item = hb_list_item(pv->delayed_chapters, 0)) != NULL) - { - hb_list_rem(pv->delayed_chapters, item); - free(item); - } - hb_list_close(&pv->delayed_chapters); - } + + hb_chapter_queue_close(&pv->chapter_queue); pv->api->encoder_close( pv->x264 ); free( pv ); w->private_data = NULL; - - /* TODO */ } /* @@ -669,6 +652,50 @@ static hb_buffer_t *nal_encode( hb_work_object_t *w, x264_picture_t *pic_out, w->config->h264.init_delay = -pic_out->i_dts; } + /* Decide what type of frame we have. */ + switch( pic_out->i_type ) + { + case X264_TYPE_IDR: + // Handled in b_keyframe check below. + break; + + case X264_TYPE_I: + buf->s.frametype = HB_FRAME_I; + break; + + case X264_TYPE_P: + buf->s.frametype = HB_FRAME_P; + break; + + case X264_TYPE_B: + buf->s.frametype = HB_FRAME_B; + break; + + /* This is for b-pyramid, which has reference b-frames + However, it doesn't seem to ever be used... */ + case X264_TYPE_BREF: + buf->s.frametype = HB_FRAME_BREF; + break; + + // If it isn't the above, what type of frame is it?? + default: + buf->s.frametype = 0; + break; + } + + // PIR has no IDR frames, but x264 marks recovery points + // as keyframes. So fake an IDR at these points. This flag + // is also set for real IDR frames. + if (pic_out->b_keyframe) + { + buf->s.frametype = HB_FRAME_IDR; + /* if we have a chapter marker pending and this + frame's presentation time stamp is at or after + the marker's time stamp, use this as the + chapter start. */ + hb_chapter_dequeue(pv->chapter_queue, buf); + } + /* Encode all the NALs we were given into buf. NOTE: This code assumes one video frame per NAL (but there can be other stuff like SPS and/or PPS). If there are multiple @@ -701,37 +728,6 @@ static hb_buffer_t *nal_encode( hb_work_object_t *w, x264_picture_t *pic_out, break; } - /* Decide what type of frame we have. */ - switch( pic_out->i_type ) - { - case X264_TYPE_IDR: - // Handled in b_keyframe check below. - break; - - case X264_TYPE_I: - buf->s.frametype = HB_FRAME_I; - break; - - case X264_TYPE_P: - buf->s.frametype = HB_FRAME_P; - break; - - case X264_TYPE_B: - buf->s.frametype = HB_FRAME_B; - break; - - /* This is for b-pyramid, which has reference b-frames - However, it doesn't seem to ever be used... */ - case X264_TYPE_BREF: - buf->s.frametype = HB_FRAME_BREF; - break; - - // If it isn't the above, what type of frame is it?? - default: - buf->s.frametype = 0; - break; - } - /* Since libx264 doesn't tell us when b-frames are themselves reference frames, figure it out on our own. */ if( (buf->s.frametype == HB_FRAME_B) && @@ -744,43 +740,6 @@ static hb_buffer_t *nal_encode( hb_work_object_t *w, x264_picture_t *pic_out, else buf->s.flags |= HB_FRAME_REF; - // PIR has no IDR frames, but x264 marks recovery points - // as keyframes. So fake an IDR at these points. This flag - // is also set for real IDR frames. - if( pic_out->b_keyframe ) - { - buf->s.frametype = HB_FRAME_IDR; - /* if we have a chapter marker pending and this - frame's presentation time stamp is at or after - the marker's time stamp, use this as the - chapter start. */ - if (pv->next_chapter_pts != AV_NOPTS_VALUE && - pv->next_chapter_pts <= pic_out->i_pts) - { - // we're no longer looking for this chapter - pv->next_chapter_pts = AV_NOPTS_VALUE; - - // get the chapter index from the list - struct chapter_s *item = hb_list_item(pv->delayed_chapters, 0); - if (item != NULL) - { - // we're done with this chapter - buf->s.new_chap = item->index; - hb_list_rem(pv->delayed_chapters, item); - free(item); - - // we may still have another pending chapter - item = hb_list_item(pv->delayed_chapters, 0); - if (item != NULL) - { - // we're looking for this one now - // we still need it, don't remove it - pv->next_chapter_pts = item->start; - } - } - } - } - buf->size += size; } // make sure we found at least one video frame @@ -845,7 +804,7 @@ static hb_buffer_t *x264_encode( hb_work_object_t *w, hb_buffer_t *in ) pv->pic_in.img.plane[2] = in->plane[2].data; } - if( in->s.new_chap && job->chapter_markers ) + if( in->s.new_chap > 0 && job->chapter_markers ) { /* chapters have to start with an IDR frame so request that this frame be coded as IDR. Since there may be up to 16 frames @@ -853,27 +812,7 @@ static hb_buffer_t *x264_encode( hb_work_object_t *w, hb_buffer_t *in ) when this frame finally pops out of the encoder we'll mark its buffer as the start of a chapter. */ pv->pic_in.i_type = X264_TYPE_IDR; - if (pv->next_chapter_pts == AV_NOPTS_VALUE) - { - pv->next_chapter_pts = in->s.start; - } - /* - * Chapter markers are sometimes so close we can get a new one before the - * previous marker has been through the encoding queue. - * - * Dropping markers can cause weird side-effects downstream, including but - * not limited to missing chapters in the output, so we need to save it - * somehow. - */ - struct chapter_s *item = malloc(sizeof(struct chapter_s)); - if (item != NULL) - { - item->start = in->s.start; - item->index = in->s.new_chap; - hb_list_add(pv->delayed_chapters, item); - } - /* don't let 'work_loop' put a chapter mark on the wrong buffer */ - in->s.new_chap = 0; + hb_chapter_enqueue(pv->chapter_queue, in); } else { |