Exemplo n.º 1
0
Arquivo: hevc.c Projeto: etix/vlc
static block_t * ParseAUTail(decoder_t *p_dec, uint8_t i_nal_type, block_t *p_nalb)
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    block_t *p_ret = NULL;

    block_ChainLastAppend(&p_sys->post.pp_chain_last, p_nalb);

    switch(i_nal_type)
    {
        case HEVC_NAL_EOS:
        case HEVC_NAL_EOB:
            p_ret = OutputQueues(p_sys, true);
            break;

        case HEVC_NAL_SUFF_SEI:
            HxxxParse_AnnexB_SEI( p_nalb->p_buffer, p_nalb->i_buffer,
                                  2 /* nal header */, ParseSEICallback, p_dec );
            break;
    }

    if(!p_ret && p_sys->frame.p_chain == NULL)
        p_ret = OutputQueues(p_sys, false);

    return p_ret;
}
Exemplo n.º 2
0
Arquivo: hevc.c Projeto: BossKing/vlc
static block_t * ParseAUTail(decoder_t *p_dec, uint8_t i_nal_type, block_t *p_nalb)
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    block_t *p_ret = NULL;

    block_ChainLastAppend(&p_sys->post.pp_chain_last, p_nalb);

    switch(i_nal_type)
    {
        case HEVC_NAL_EOS:
        case HEVC_NAL_EOB:
            p_ret = OutputQueues(p_sys, true);
            break;
    }

    if(!p_ret && p_sys->frame.p_chain == NULL)
        p_ret = OutputQueues(p_sys, false);

    return p_ret;
}
Exemplo n.º 3
0
Arquivo: hevc.c Projeto: etix/vlc
/****************************************************************************
 * Packetizer Helpers
 ****************************************************************************/
static void PacketizeReset(void *p_private, bool b_broken)
{
    VLC_UNUSED(b_broken);

    decoder_t *p_dec = p_private;
    decoder_sys_t *p_sys = p_dec->p_sys;

    block_t *p_out = OutputQueues(p_sys, false);
    if(p_out)
        block_ChainRelease(p_out);

    p_sys->b_init_sequence_complete = false;
}
Exemplo n.º 4
0
Arquivo: hevc.c Projeto: etix/vlc
/*****************************************************************************
 * ParseNALBlock: parses annexB type NALs
 * All p_frag blocks are required to start with 0 0 0 1 4-byte startcode
 *****************************************************************************/
static block_t *ParseNALBlock(decoder_t *p_dec, bool *pb_ts_used, block_t *p_frag)
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    if(unlikely(p_frag->i_buffer < 5))
    {
        msg_Warn(p_dec,"NAL too small");
        block_Release(p_frag);
        *pb_ts_used = false;
        return NULL;
    }

    if(p_frag->p_buffer[4] & 0x80)
    {
        msg_Warn(p_dec,"Forbidden zero bit not null, corrupted NAL");
        block_Release(p_frag);
        *pb_ts_used = false;
        return GatherAndValidateChain(OutputQueues(p_sys, false)); /* will drop */
    }

    /* Get NALU type */
    block_t * p_output = NULL;
    uint8_t i_nal_type = hevc_getNALType(&p_frag->p_buffer[4]);
    if (i_nal_type < HEVC_NAL_VPS)
    {
        /* NAL is a VCL NAL */
        p_output = ParseVCL(p_dec, i_nal_type, p_frag);
        if (p_output && (p_output->i_flags & BLOCK_FLAG_CORRUPTED))
            msg_Info(p_dec, "Waiting for VPS/SPS/PPS");
    }
    else
    {
        p_output = ParseNonVCL(p_dec, i_nal_type, p_frag);
    }

    p_output = GatherAndValidateChain(p_output);
    *pb_ts_used = (p_output != NULL);
    return p_output;
}
Exemplo n.º 5
0
Arquivo: hevc.c Projeto: etix/vlc
static block_t * ParseAUHead(decoder_t *p_dec, uint8_t i_nal_type, block_t *p_nalb)
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    block_t *p_ret = NULL;

    if(p_sys->post.p_chain || p_sys->frame.p_chain)
        p_ret = OutputQueues(p_sys, true);

    switch(i_nal_type)
    {
        case HEVC_NAL_AUD:
            if(!p_ret && p_sys->pre.p_chain)
                p_ret = OutputQueues(p_sys, true);
            break;

        case HEVC_NAL_VPS:
        case HEVC_NAL_SPS:
        case HEVC_NAL_PPS:
        {
            uint8_t i_id;
            if( hevc_get_xps_id(p_nalb->p_buffer, p_nalb->i_buffer, &i_id) &&
                InsertXPS(p_dec, i_nal_type, i_id, p_nalb) )
            {
                const hevc_sequence_parameter_set_t *p_sps;
                if( i_nal_type == HEVC_NAL_SPS &&
                   (p_sps = p_dec->p_sys->rgi_p_decsps[i_id]) )
                {
                    if(!p_dec->fmt_out.video.i_frame_rate)
                    {
                        (void) hevc_get_frame_rate( p_sps, p_dec->p_sys->rgi_p_decvps,
                                                    &p_dec->fmt_out.video.i_frame_rate,
                                                    &p_dec->fmt_out.video.i_frame_rate_base );
                    }

                    if(p_dec->fmt_out.video.primaries == COLOR_PRIMARIES_UNDEF)
                    {
                        (void) hevc_get_colorimetry( p_sps,
                                                     &p_dec->fmt_out.video.primaries,
                                                     &p_dec->fmt_out.video.transfer,
                                                     &p_dec->fmt_out.video.space,
                                                     &p_dec->fmt_out.video.b_color_range_full);
                    }

                    unsigned sizes[4];
                    if( hevc_get_picture_size( p_sps, &sizes[0], &sizes[1],
                                                      &sizes[2], &sizes[3] ) )
                    {
                        if( p_dec->fmt_out.video.i_width != sizes[0] ||
                            p_dec->fmt_out.video.i_height != sizes[1] )
                        {
                            p_dec->fmt_out.video.i_width = sizes[0];
                            p_dec->fmt_out.video.i_height = sizes[1];
                        }
                    }

                    if(p_dec->fmt_out.i_profile == -1)
                    {
                        uint8_t i_profile, i_level;
                        if( hevc_get_sps_profile_tier_level( p_sps, &i_profile, &i_level ) )
                        {
                            p_dec->fmt_out.i_profile = i_profile;
                            p_dec->fmt_out.i_level = i_level;
                        }
                    }
                }
            }
            break;
        }

        case HEVC_NAL_PREF_SEI:
            HxxxParse_AnnexB_SEI( p_nalb->p_buffer, p_nalb->i_buffer,
                                  2 /* nal header */, ParseSEICallback, p_dec );
            break;

        default:
            break;
    }

    block_ChainLastAppend(&p_sys->pre.pp_chain_last, p_nalb);

    return p_ret;
}
Exemplo n.º 6
0
Arquivo: hevc.c Projeto: etix/vlc
static block_t *ParseVCL(decoder_t *p_dec, uint8_t i_nal_type, block_t *p_frag)
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    block_t *p_outputchain = NULL;

    const uint8_t *p_buffer = p_frag->p_buffer;
    size_t i_buffer = p_frag->i_buffer;

    if(unlikely(!hxxx_strip_AnnexB_startcode(&p_buffer, &i_buffer) || i_buffer < 3))
    {
        block_ChainLastAppend(&p_sys->frame.pp_chain_last, p_frag); /* might be corrupted */
        return NULL;
    }

    const uint8_t i_layer = hevc_getNALLayer( p_buffer );
    bool b_first_slice_in_pic = p_buffer[2] & 0x80;
    if (b_first_slice_in_pic)
    {
        if(p_sys->frame.p_chain)
        {
            /* Starting new frame: return previous frame data for output */
            p_outputchain = OutputQueues(p_sys, p_sys->b_init_sequence_complete);
        }

        switch(i_nal_type)
        {
            case HEVC_NAL_BLA_W_LP:
            case HEVC_NAL_BLA_W_RADL:
            case HEVC_NAL_BLA_N_LP:
            case HEVC_NAL_IDR_W_RADL:
            case HEVC_NAL_IDR_N_LP:
            case HEVC_NAL_CRA:
                p_frag->i_flags |= BLOCK_FLAG_TYPE_I;
                break;

            default:
            {
                hevc_slice_segment_header_t *p_sli = hevc_decode_slice_header( p_buffer, i_buffer, true,
                                                                               p_sys->rgi_p_decsps, p_sys->rgi_p_decpps );
                if( p_sli )
                {
                    enum hevc_slice_type_e type;
                    if( hevc_get_slice_type( p_sli, &type ) )
                    {
                        if( type == HEVC_SLICE_TYPE_P )
                            p_frag->i_flags |= BLOCK_FLAG_TYPE_P;
                        else
                            p_frag->i_flags |= BLOCK_FLAG_TYPE_B;
                    }
                    hevc_rbsp_release_slice_header( p_sli );
                }
                else p_frag->i_flags |= BLOCK_FLAG_TYPE_B;
            }
            break;
        }
    }

    if(!p_sys->b_init_sequence_complete && i_layer == 0 &&
       (p_frag->i_flags & BLOCK_FLAG_TYPE_I) && XPSReady(p_sys))
    {
        p_sys->b_init_sequence_complete = true;
    }

    if( !p_sys->b_init_sequence_complete )
        cc_storage_reset( p_sys->p_ccs );

    block_ChainLastAppend(&p_sys->frame.pp_chain_last, p_frag);

    return p_outputchain;
}