⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 video.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    p_sys->p_pp = E_(OpenPostproc)( p_dec, &p_sys->b_pp_async );#endif    /* ffmpeg doesn't properly release old pictures when frames are skipped */    //if( p_sys->b_hurry_up ) p_sys->b_direct_rendering = 0;    if( p_sys->b_direct_rendering )    {        msg_Dbg( p_dec, "using direct rendering" );        p_sys->p_context->flags |= CODEC_FLAG_EMU_EDGE;    }    /* Always use our get_buffer wrapper so we can calculate the     * PTS correctly */    p_sys->p_context->get_buffer = ffmpeg_GetFrameBuf;    p_sys->p_context->release_buffer = ffmpeg_ReleaseFrameBuf;    p_sys->p_context->opaque = p_dec;    /* ***** init this codec with special data ***** */    ffmpeg_InitCodec( p_dec );    /* ***** misc init ***** */    p_sys->input_pts = p_sys->input_dts = 0;    p_sys->i_pts = 0;    p_sys->b_has_b_frames = VLC_FALSE;    p_sys->b_first_frame = VLC_TRUE;    p_sys->i_late_frames = 0;    p_sys->i_buffer = 0;    p_sys->i_buffer_orig = 1;    p_sys->p_buffer_orig = p_sys->p_buffer = malloc( p_sys->i_buffer_orig );    /* Set output properties */    p_dec->fmt_out.i_cat = VIDEO_ES;    p_dec->fmt_out.i_codec = ffmpeg_PixFmtToChroma( p_context->pix_fmt );    /* Setup palette */#if LIBAVCODEC_BUILD >= 4688    if( p_dec->fmt_in.video.p_palette )        p_sys->p_context->palctrl =            (AVPaletteControl *)p_dec->fmt_in.video.p_palette;    else        p_sys->p_context->palctrl = &palette_control;#endif    /* ***** Open the codec ***** */    vlc_mutex_lock( lockval.p_address );    if( avcodec_open( p_sys->p_context, p_sys->p_codec ) < 0 )    {        vlc_mutex_unlock( lockval.p_address );        msg_Err( p_dec, "cannot open codec (%s)", p_sys->psz_namecodec );        free( p_sys );        return VLC_EGENERIC;    }    vlc_mutex_unlock( lockval.p_address );    msg_Dbg( p_dec, "ffmpeg codec (%s) started", p_sys->psz_namecodec );    return VLC_SUCCESS;}/***************************************************************************** * DecodeVideo: Called to decode one or more frames *****************************************************************************/picture_t *E_(DecodeVideo)( decoder_t *p_dec, block_t **pp_block ){    decoder_sys_t *p_sys = p_dec->p_sys;    int b_drawpicture;    int b_null_size = VLC_FALSE;    block_t *p_block;    if( !pp_block || !*pp_block ) return NULL;    if( !p_sys->p_context->extradata_size && p_dec->fmt_in.i_extra )        ffmpeg_InitCodec( p_dec );    p_block = *pp_block;    if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )    {        p_sys->i_buffer = 0;        p_sys->i_pts = 0; /* To make sure we recover properly */        p_sys->input_pts = p_sys->input_dts = 0;        p_sys->i_late_frames = 0;        block_Release( p_block );        return NULL;    }    if( p_block->i_flags & BLOCK_FLAG_PREROLL )    {        /* Do not care about late frames when prerolling         * TODO avoid decoding of non reference frame         * (ie all B except for H264 where it depends only on nal_ref_idc) */        p_sys->i_late_frames = 0;    }    if( !p_dec->b_pace_control && p_sys->i_late_frames > 0 &&        mdate() - p_sys->i_late_frames_start > I64C(5000000) )    {        if( p_sys->i_pts )        {            msg_Err( p_dec, "more than 5 seconds of late video -> "                     "dropping frame (computer too slow ?)" );            p_sys->i_pts = 0; /* To make sure we recover properly */        }        block_Release( p_block );        p_sys->i_late_frames--;        return NULL;    }    if( p_block->i_pts > 0 || p_block->i_dts > 0 )    {        p_sys->input_pts = p_block->i_pts;        p_sys->input_dts = p_block->i_dts;        /* Make sure we don't reuse the same timestamps twice */        p_block->i_pts = p_block->i_dts = 0;    }    /* TODO implement it in a better way */    /* A good idea could be to decode all I pictures and see for the other */    if( !p_dec->b_pace_control &&        p_sys->b_hurry_up && p_sys->i_late_frames > 4 )    {        b_drawpicture = 0;        if( p_sys->i_late_frames < 8 )        {            p_sys->p_context->hurry_up = 2;        }        else        {            /* picture too late, won't decode             * but break picture until a new I, and for mpeg4 ...*/            p_sys->i_late_frames--; /* needed else it will never be decrease */            block_Release( p_block );            p_sys->i_buffer = 0;            return NULL;        }    }    else    {        if (!(p_block->i_flags & BLOCK_FLAG_PREROLL))        {            b_drawpicture = 1;            p_sys->p_context->hurry_up = 0;        }        else        {            b_drawpicture = 0;            p_sys->p_context->hurry_up = 1;        }    }    if( p_sys->p_context->width <= 0 || p_sys->p_context->height <= 0 )    {        p_sys->p_context->hurry_up = 5;        b_null_size = VLC_TRUE;    }    /*     * Do the actual decoding now     */    /* Check if post-processing was enabled */    p_sys->b_pp = p_sys->b_pp_async;    /* Don't forget that ffmpeg requires a little more bytes     * that the real frame size */    if( p_block->i_buffer > 0 )    {        p_sys->i_buffer = p_block->i_buffer;        if( p_sys->i_buffer + FF_INPUT_BUFFER_PADDING_SIZE >            p_sys->i_buffer_orig )        {            free( p_sys->p_buffer_orig );            p_sys->i_buffer_orig =                p_block->i_buffer + FF_INPUT_BUFFER_PADDING_SIZE;            p_sys->p_buffer_orig = malloc( p_sys->i_buffer_orig );        }        p_sys->p_buffer = p_sys->p_buffer_orig;        p_sys->i_buffer = p_block->i_buffer;        p_dec->p_vlc->pf_memcpy( p_sys->p_buffer, p_block->p_buffer,                                 p_block->i_buffer );        memset( p_sys->p_buffer + p_block->i_buffer, 0,                FF_INPUT_BUFFER_PADDING_SIZE );        p_block->i_buffer = 0;    }    while( p_sys->i_buffer > 0 )    {        int i_used, b_gotpicture;        picture_t *p_pic;        i_used = avcodec_decode_video( p_sys->p_context, p_sys->p_ff_pic,                                       &b_gotpicture,                                       (uint8_t*)p_sys->p_buffer, p_sys->i_buffer );        if( b_null_size && p_sys->p_context->width > 0 &&            p_sys->p_context->height > 0 )        {            /* Reparse it to not drop the I frame */            b_null_size = VLC_FALSE;            p_sys->p_context->hurry_up = 0;            i_used = avcodec_decode_video( p_sys->p_context, p_sys->p_ff_pic,                                           &b_gotpicture,                                           (uint8_t*)p_sys->p_buffer, p_sys->i_buffer );        }        if( i_used < 0 )        {            msg_Warn( p_dec, "cannot decode one frame (%d bytes)",                      p_sys->i_buffer );            block_Release( p_block );            return NULL;        }        else if( i_used > p_sys->i_buffer )        {            i_used = p_sys->i_buffer;        }        /* Consumed bytes */        p_sys->i_buffer -= i_used;        p_sys->p_buffer += i_used;        /* Nothing to display */        if( !b_gotpicture )        {            if( i_used == 0 ) break;            continue;        }        /* Update frame late count (except when doing preroll) */        if( p_sys->i_pts && p_sys->i_pts <= mdate() &&            !(p_block->i_flags & BLOCK_FLAG_PREROLL) )        {            p_sys->i_late_frames++;            if( p_sys->i_late_frames == 1 )                p_sys->i_late_frames_start = mdate();        }        else        {            p_sys->i_late_frames = 0;        }        if( !b_drawpicture || !p_sys->p_ff_pic->linesize[0] )        {            /* Do not display the picture */            continue;        }        if( !p_sys->p_ff_pic->opaque )        {            /* Get a new picture */            p_pic = ffmpeg_NewPictBuf( p_dec, p_sys->p_context );            if( !p_pic )            {                block_Release( p_block );                return NULL;            }            /* Fill p_picture_t from AVVideoFrame and do chroma conversion             * if needed */            ffmpeg_CopyPicture( p_dec, p_pic, p_sys->p_ff_pic );        }        else        {            p_pic = (picture_t *)p_sys->p_ff_pic->opaque;        }        /* Set the PTS */        if( p_sys->p_ff_pic->pts ) p_sys->i_pts = p_sys->p_ff_pic->pts;        /* Sanity check (seems to be needed for some streams) */        if( p_sys->p_ff_pic->pict_type == FF_B_TYPE )        {            p_sys->b_has_b_frames = VLC_TRUE;        }        if( !p_dec->fmt_in.video.i_aspect )        {            /* Fetch again the aspect ratio in case it changed */#if LIBAVCODEC_BUILD >= 4687            p_dec->fmt_out.video.i_aspect =                VOUT_ASPECT_FACTOR                    * ( av_q2d(p_sys->p_context->sample_aspect_ratio)                    * p_sys->p_context->width / p_sys->p_context->height );            p_dec->fmt_out.video.i_sar_num                = p_sys->p_context->sample_aspect_ratio.num;            p_dec->fmt_out.video.i_sar_den                = p_sys->p_context->sample_aspect_ratio.den;#else            p_dec->fmt_out.video.i_aspect =                VOUT_ASPECT_FACTOR * p_sys->p_context->aspect_ratio;#endif            if( p_dec->fmt_out.video.i_aspect == 0 )            {                p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR                    * p_sys->p_context->width / p_sys->p_context->height;            }        }        /* Send decoded frame to vout */        if( p_sys->i_pts )        {            p_pic->date = p_sys->i_pts;            /* interpolate the next PTS */#if LIBAVCODEC_BUILD >= 4754            if( p_dec->fmt_in.video.i_frame_rate > 0 &&                p_dec->fmt_in.video.i_frame_rate_base > 0 )            {                p_sys->i_pts += I64C(1000000) *                    (2 + p_sys->p_ff_pic->repeat_pict) *                    p_dec->fmt_in.video.i_frame_rate_base *                    p_block->i_rate / INPUT_RATE_DEFAULT /                    (2 * p_dec->fmt_in.video.i_frame_rate);            }            else if( p_sys->p_context->time_base.den > 0 )            {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -