static hb_buffer_t* nal_encode(hb_work_object_t *w, x265_picture *pic_out, x265_nal *nal, uint32_t nnal) { hb_work_private_t *pv = w->private_data; hb_job_t *job = pv->job; hb_buffer_t *buf = NULL; int i; if (nnal <= 0) { return NULL; } buf = hb_video_buffer_init(job->width, job->height); if (buf == NULL) { return NULL; } buf->size = 0; // copy the bitstream data for (i = 0; i < nnal; i++) { memcpy(buf->data + buf->size, nal[i].payload, nal[i].sizeBytes); buf->size += nal[i].sizeBytes; } // use the pts to get the original frame's duration. buf->s.duration = get_frame_duration(pv, pic_out->pts); buf->s.stop = pic_out->pts + buf->s.duration; buf->s.start = pic_out->pts; buf->s.renderOffset = pic_out->dts; if (w->config->h264.init_delay == 0 && pic_out->dts < 0) { w->config->h264.init_delay -= pic_out->dts; } switch (pic_out->sliceType) { case X265_TYPE_IDR: buf->s.frametype = HB_FRAME_IDR; break; case X265_TYPE_I: buf->s.frametype = HB_FRAME_I; break; case X265_TYPE_P: buf->s.frametype = HB_FRAME_P; break; case X265_TYPE_B: buf->s.frametype = HB_FRAME_B; break; case X265_TYPE_BREF: buf->s.frametype = HB_FRAME_BREF; break; default: buf->s.frametype = 0; break; } if (pv->next_chapter_pts != AV_NOPTS_VALUE && pv->next_chapter_pts <= pic_out->pts && pic_out->sliceType == X265_TYPE_IDR) { // 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 hb_list_rem(pv->delayed_chapters, item); buf->s.new_chap = item->index; 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; } } } // discard empty buffers (no video) if (buf->size <= 0) { hb_buffer_close(&buf); } return buf; }
static hb_buffer_t* nal_encode(hb_work_object_t *w, x265_picture *pic_out, x265_nal *nal, uint32_t nnal) { hb_work_private_t *pv = w->private_data; hb_job_t *job = pv->job; hb_buffer_t *buf = NULL; int i; if (nnal <= 0) { return NULL; } buf = hb_video_buffer_init(job->width, job->height); if (buf == NULL) { return NULL; } buf->s.flags = 0; buf->size = 0; // copy the bitstream data for (i = 0; i < nnal; i++) { if (HB_HEVC_NALU_KEYFRAME(nal[i].type)) { buf->s.flags |= HB_FLAG_FRAMETYPE_REF; buf->s.flags |= HB_FLAG_FRAMETYPE_KEY; } memcpy(buf->data + buf->size, nal[i].payload, nal[i].sizeBytes); buf->size += nal[i].sizeBytes; } // use the pts to get the original frame's duration. buf->s.duration = get_frame_duration(pv, pic_out->pts); buf->s.stop = pic_out->pts + buf->s.duration; buf->s.start = pic_out->pts; buf->s.renderOffset = pic_out->dts; if (w->config->init_delay == 0 && pic_out->dts < 0) { w->config->init_delay -= pic_out->dts; } switch (pic_out->sliceType) { case X265_TYPE_IDR: buf->s.flags |= HB_FLAG_FRAMETYPE_REF; buf->s.flags |= HB_FLAG_FRAMETYPE_KEY; buf->s.frametype = HB_FRAME_IDR; break; case X265_TYPE_P: buf->s.flags |= HB_FLAG_FRAMETYPE_REF; buf->s.frametype = HB_FRAME_P; break; case X265_TYPE_B: buf->s.frametype = HB_FRAME_B; break; case X265_TYPE_BREF: buf->s.flags |= HB_FLAG_FRAMETYPE_REF; buf->s.frametype = HB_FRAME_BREF; break; case X265_TYPE_I: default: buf->s.flags |= HB_FLAG_FRAMETYPE_REF; buf->s.frametype = HB_FRAME_I; break; } if (buf->s.flags & HB_FLAG_FRAMETYPE_KEY) { hb_chapter_dequeue(pv->chapter_queue, buf); } // discard empty buffers (no video) if (buf->size <= 0) { hb_buffer_close(&buf); } return buf; }