예제 #1
0
파일: mediacodec.c 프로젝트: 9034725985/vlc
static int Video_OnNewBlock(decoder_t *p_dec, block_t *p_block, int *p_flags)
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    bool b_csd_changed = false, b_size_changed = false;

    if (p_block->i_flags & BLOCK_FLAG_INTERLACED_MASK
        && !p_sys->api->b_support_interlaced)
        return -1;

    if (p_dec->fmt_in.i_codec == VLC_CODEC_H264)
        H264ProcessBlock(p_dec, p_block, &b_csd_changed, &b_size_changed);
    else if (p_dec->fmt_in.i_codec == VLC_CODEC_HEVC)
        HEVCProcessBlock(p_dec, p_block, &b_csd_changed, &b_size_changed);

    if (b_csd_changed)
    {
        if (b_size_changed || !p_sys->api->b_started)
        {
            if (p_sys->api->b_started)
                msg_Err(p_dec, "SPS/PPS changed during playback and "
                        "video size are different. Restart it !");
            *p_flags |= NEWBLOCK_FLAG_RESTART;
        } else
        {
            msg_Err(p_dec, "SPS/PPS changed during playback. Flush it");
            *p_flags |= NEWBLOCK_FLAG_FLUSH;
        }
    }

    if (!p_sys->api->b_started)
    {
        *p_flags |= NEWBLOCK_FLAG_RESTART;

        /* Don't start if we don't have any csd */
        if ((p_sys->i_quirks & OMXCODEC_QUIRKS_NEED_CSD)
         && !p_dec->fmt_in.i_extra && !p_sys->pp_csd)
            *p_flags &= ~NEWBLOCK_FLAG_RESTART;

        /* Don't start if we don't have a valid video size */
        if ((p_sys->i_quirks & OMXCODEC_VIDEO_QUIRKS_NEED_SIZE)
         && (!p_sys->u.video.i_width || !p_sys->u.video.i_height))
            *p_flags &= ~NEWBLOCK_FLAG_RESTART;
    }

    timestamp_FifoPut(p_sys->u.video.timestamp_fifo,
                      p_block->i_pts ? VLC_TS_INVALID : p_block->i_dts);

    return 1;
}
예제 #2
0
static int Video_OnNewBlock(decoder_t *p_dec, block_t *p_block)
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    bool b_csd_changed = false, b_size_changed = false;
    bool b_delayed_start = false;

    if (p_block->i_flags & BLOCK_FLAG_INTERLACED_MASK
        && !p_sys->api->b_support_interlaced)
        return -1;

    if (p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED))
    {
        if (p_sys->decoded)
        {
            timestamp_FifoEmpty(p_sys->u.video.timestamp_fifo);
            /* Invalidate all pictures that are currently in flight
             * since flushing make all previous indices returned by
             * MediaCodec invalid. */
            if (p_sys->api->b_direct_rendering)
                InvalidateAllPictures(p_dec);
        }

        if (DecodeFlush(p_dec) != VLC_SUCCESS)
            return -1;
        return 0;
    }

    if (p_dec->fmt_in.i_codec == VLC_CODEC_H264)
        H264ProcessBlock(p_dec, p_block, &b_csd_changed, &b_size_changed);
    else if (p_dec->fmt_in.i_codec == VLC_CODEC_HEVC)
        HEVCProcessBlock(p_dec, p_block, &b_csd_changed, &b_size_changed);

    if (p_sys->api->b_started && b_csd_changed)
    {
        if (b_size_changed)
        {
            msg_Err(p_dec, "SPS/PPS changed during playback and "
                    "video size are different. Restart it !");
            StopMediaCodec(p_dec);
        } else
        {
            msg_Err(p_dec, "SPS/PPS changed during playback. Flush it");
            if (DecodeFlush(p_dec) != VLC_SUCCESS)
                return -1;
        }
    }

    if (b_csd_changed)
        b_delayed_start = true;

    /* try delayed opening if there is a new extra data */
    if (!p_sys->api->b_started)
    {
        switch (p_dec->fmt_in.i_codec)
        {
        case VLC_CODEC_VC1:
            if (p_dec->fmt_in.i_extra)
                b_delayed_start = true;
        default:
            break;
        }
        if (b_delayed_start && StartMediaCodec(p_dec) != VLC_SUCCESS)
            return -1;
        if (!p_sys->api->b_started)
            return 0;
    }

    timestamp_FifoPut(p_sys->u.video.timestamp_fifo,
                      p_block->i_pts ? VLC_TS_INVALID : p_block->i_dts);
    return 1;
}