/***************************************************************************** * Open *****************************************************************************/ static int Open(vlc_object_t *p_this) { decoder_t *p_dec = (decoder_t*)p_this; decoder_sys_t *p_sys; if (p_dec->fmt_in.i_codec != VLC_CODEC_HEVC) return VLC_EGENERIC; p_dec->p_sys = p_sys = calloc(1, sizeof(decoder_sys_t)); if (!p_dec->p_sys) return VLC_ENOMEM; INITQ(pre); INITQ(frame); INITQ(post); packetizer_Init(&p_dec->p_sys->packetizer, p_hevc_startcode, sizeof(p_hevc_startcode), startcode_FindAnnexB, p_hevc_startcode, 1, 5, PacketizeReset, PacketizeParse, PacketizeValidate, p_dec); /* Copy properties */ es_format_Copy(&p_dec->fmt_out, &p_dec->fmt_in); p_dec->fmt_out.b_packetized = true; /* Set callbacks */ const uint8_t *p_extra = p_dec->fmt_in.p_extra; const size_t i_extra = p_dec->fmt_in.i_extra; /* Check if we have hvcC as extradata */ if(hevc_ishvcC(p_extra, i_extra)) { p_dec->pf_packetize = PacketizeHVC1; /* Clear hvcC/HVC1 extra, to be replaced with AnnexB */ free(p_dec->fmt_out.p_extra); p_dec->fmt_out.i_extra = 0; size_t i_new_extra = 0; p_dec->fmt_out.p_extra = hevc_hvcC_to_AnnexB_NAL(p_extra, i_extra, &i_new_extra, &p_sys->i_nal_length_size); if(p_dec->fmt_out.p_extra) p_dec->fmt_out.i_extra = i_new_extra; } else { p_dec->pf_packetize = PacketizeAnnexB; } p_dec->pf_flush = PacketizeFlush; if(p_dec->fmt_out.i_extra) { /* Feed with AnnexB VPS/SPS/PPS/SEI extradata */ packetizer_Header(&p_sys->packetizer, p_dec->fmt_out.p_extra, p_dec->fmt_out.i_extra); } return VLC_SUCCESS; }
static block_t * OutputQueues(decoder_sys_t *p_sys, bool b_valid) { block_t *p_output = NULL; block_t **pp_output_last = &p_output; uint32_t i_flags = 0; /* Because block_ChainGather does not merge flags or times */ if(p_sys->pre.p_chain) { i_flags |= p_sys->pre.p_chain->i_flags; block_ChainLastAppend(&pp_output_last, p_sys->pre.p_chain); INITQ(pre); } if(p_sys->frame.p_chain) { i_flags |= p_sys->frame.p_chain->i_flags; if(p_output && p_output->i_dts == 0) { p_output->i_dts = p_sys->frame.p_chain->i_dts; p_output->i_pts = p_sys->frame.p_chain->i_pts; } block_ChainLastAppend(&pp_output_last, p_sys->frame.p_chain); INITQ(frame); } if(p_sys->post.p_chain) { i_flags |= p_sys->post.p_chain->i_flags; block_ChainLastAppend(&pp_output_last, p_sys->post.p_chain); INITQ(post); } if(p_output) { p_output->i_flags |= i_flags; if(!b_valid) p_output->i_flags |= BLOCK_FLAG_CORRUPTED; } return p_output; }