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

📄 decoder.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 3 页
字号:
                p_dec->p_owner->i_preroll_end = -1;                vout_DatePicture( p_dec->p_owner->p_vout, p_pic, p_pic->date );                vout_DisplayPicture( p_dec->p_owner->p_vout, p_pic );            }        }    }    else if( p_dec->fmt_in.i_cat == SPU_ES )    {        vout_thread_t *p_vout;        subpicture_t *p_spu;        while( (p_spu = p_dec->pf_decode_sub( p_dec, &p_block ) ) )        {            if( p_dec->p_owner->i_preroll_end > 0 &&                p_spu->i_start < p_dec->p_owner->i_preroll_end &&                ( p_spu->i_stop <= 0 || p_spu->i_stop <= p_dec->p_owner->i_preroll_end ) )            {                spu_DestroySubpicture( p_dec->p_owner->p_vout->p_spu, p_spu );                continue;            }            p_dec->p_owner->i_preroll_end = -1;            p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );            if( p_vout )            {                spu_DisplaySubpicture( p_vout->p_spu, p_spu );                vlc_object_release( p_vout );            }        }    }    else    {        msg_Err( p_dec, "unknown ES format" );        p_dec->b_error = 1;    }    return p_dec->b_error ? VLC_EGENERIC : VLC_SUCCESS;}/** * Destroys a decoder object * * \param p_dec the decoder object * \return nothing */static void DeleteDecoder( decoder_t * p_dec ){    msg_Dbg( p_dec, "killing decoder fourcc `%4.4s', %d PES in FIFO",             (char*)&p_dec->fmt_in.i_codec,             p_dec->p_owner->p_fifo->i_depth );    /* Free all packets still in the decoder fifo. */    block_FifoEmpty( p_dec->p_owner->p_fifo );    block_FifoRelease( p_dec->p_owner->p_fifo );    /* Cleanup */    if( p_dec->p_owner->p_aout_input )        aout_DecDelete( p_dec->p_owner->p_aout, p_dec->p_owner->p_aout_input );    if( p_dec->p_owner->p_vout )    {        int i_pic;#define p_pic p_dec->p_owner->p_vout->render.pp_picture[i_pic]        /* Hack to make sure all the the pictures are freed by the decoder */        for( i_pic = 0; i_pic < p_dec->p_owner->p_vout->render.i_pictures;             i_pic++ )        {            if( p_pic->i_status == RESERVED_PICTURE )                vout_DestroyPicture( p_dec->p_owner->p_vout, p_pic );            if( p_pic->i_refcount > 0 )                vout_UnlinkPicture( p_dec->p_owner->p_vout, p_pic );        }#undef p_pic        /* We are about to die. Reattach video output to p_vlc. */        vout_Request( p_dec, p_dec->p_owner->p_vout, 0 );    }    if( p_dec->p_owner->p_sout_input )    {        sout_InputDelete( p_dec->p_owner->p_sout_input );        es_format_Clean( &p_dec->p_owner->sout );    }    if( p_dec->fmt_in.i_cat == SPU_ES )    {        vout_thread_t *p_vout;        p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );        if( p_vout )        {            spu_Control( p_vout->p_spu, SPU_CHANNEL_CLEAR,                         p_dec->p_owner->i_spu_channel );            vlc_object_release( p_vout );        }    }    es_format_Clean( &p_dec->fmt_in );    es_format_Clean( &p_dec->fmt_out );    if( p_dec->p_owner->p_packetizer )    {        module_Unneed( p_dec->p_owner->p_packetizer,                       p_dec->p_owner->p_packetizer->p_module );        es_format_Clean( &p_dec->p_owner->p_packetizer->fmt_in );        es_format_Clean( &p_dec->p_owner->p_packetizer->fmt_out );        vlc_object_detach( p_dec->p_owner->p_packetizer );        vlc_object_destroy( p_dec->p_owner->p_packetizer );    }    vlc_object_detach( p_dec );    free( p_dec->p_owner );}/***************************************************************************** * Buffers allocation callbacks for the decoders *****************************************************************************/static aout_buffer_t *aout_new_buffer( decoder_t *p_dec, int i_samples ){    decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner;    aout_buffer_t *p_buffer;    if( p_sys->p_aout_input != NULL &&        ( p_dec->fmt_out.audio.i_rate != p_sys->audio.i_rate ||          p_dec->fmt_out.audio.i_original_channels !=              p_sys->audio.i_original_channels ||          p_dec->fmt_out.audio.i_bytes_per_frame !=              p_sys->audio.i_bytes_per_frame ) )    {        /* Parameters changed, restart the aout */        aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );        p_sys->p_aout_input = NULL;    }    if( p_sys->p_aout_input == NULL )    {        p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec;        p_sys->audio = p_dec->fmt_out.audio;        p_sys->p_aout_input =            aout_DecNew( p_dec, &p_sys->p_aout, &p_sys->audio );        if( p_sys->p_aout_input == NULL )        {            msg_Err( p_dec, "failed to create audio output" );            p_dec->b_error = VLC_TRUE;            return NULL;        }        p_dec->fmt_out.audio.i_bytes_per_frame =            p_sys->audio.i_bytes_per_frame;    }    p_buffer = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input,                                  i_samples );    return p_buffer;}static void aout_del_buffer( decoder_t *p_dec, aout_buffer_t *p_buffer ){    aout_DecDeleteBuffer( p_dec->p_owner->p_aout,                          p_dec->p_owner->p_aout_input, p_buffer );}static picture_t *vout_new_buffer( decoder_t *p_dec ){    decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner;    picture_t *p_pic;    if( p_sys->p_vout == NULL ||        p_dec->fmt_out.video.i_width != p_sys->video.i_width ||        p_dec->fmt_out.video.i_height != p_sys->video.i_height ||        p_dec->fmt_out.video.i_chroma != p_sys->video.i_chroma ||        p_dec->fmt_out.video.i_aspect != p_sys->video.i_aspect )    {        if( !p_dec->fmt_out.video.i_width ||            !p_dec->fmt_out.video.i_height )        {            /* Can't create a new vout without display size */            return NULL;        }        if( !p_dec->fmt_out.video.i_sar_num ||            !p_dec->fmt_out.video.i_sar_den )        {            p_dec->fmt_out.video.i_sar_num =              p_dec->fmt_out.video.i_aspect * p_dec->fmt_out.video.i_height;            p_dec->fmt_out.video.i_sar_den = VOUT_ASPECT_FACTOR *              p_dec->fmt_out.video.i_width;        }        vlc_reduce( &p_dec->fmt_out.video.i_sar_num,                    &p_dec->fmt_out.video.i_sar_den,		    p_dec->fmt_out.video.i_sar_num,		    p_dec->fmt_out.video.i_sar_den, 0 );	if( !p_dec->fmt_out.video.i_visible_width ||	    !p_dec->fmt_out.video.i_visible_height )	{	    p_dec->fmt_out.video.i_visible_width =	        p_dec->fmt_out.video.i_width;	    p_dec->fmt_out.video.i_visible_height =	        p_dec->fmt_out.video.i_height;	}        p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec;        p_sys->video = p_dec->fmt_out.video;        p_sys->p_vout = vout_Request( p_dec, p_sys->p_vout,                                      &p_dec->fmt_out.video );        if( p_sys->p_vout == NULL )        {            msg_Err( p_dec, "failed to create video output" );            p_dec->b_error = VLC_TRUE;            return NULL;        }        if( p_sys->video.i_rmask )            p_sys->p_vout->render.i_rmask = p_sys->video.i_rmask;        if( p_sys->video.i_gmask )            p_sys->p_vout->render.i_gmask = p_sys->video.i_gmask;        if( p_sys->video.i_bmask )            p_sys->p_vout->render.i_bmask = p_sys->video.i_bmask;    }    /* Get a new picture */    while( !(p_pic = vout_CreatePicture( p_sys->p_vout, 0, 0, 0 ) ) )    {        int i_pic, i_ready_pic = 0;        if( p_dec->b_die || p_dec->b_error )        {            return NULL;        }#define p_pic p_dec->p_owner->p_vout->render.pp_picture[i_pic]        /* Check the decoder doesn't leak pictures */        for( i_pic = 0; i_pic < p_dec->p_owner->p_vout->render.i_pictures;             i_pic++ )        {            if( p_pic->i_status == READY_PICTURE )            {                if( i_ready_pic++ > 0 ) break;                else continue;            }            if( p_pic->i_status != DISPLAYED_PICTURE &&                p_pic->i_status != RESERVED_PICTURE &&                p_pic->i_status != READY_PICTURE ) break;            if( !p_pic->i_refcount && p_pic->i_status != RESERVED_PICTURE )                break;        }        if( i_pic == p_dec->p_owner->p_vout->render.i_pictures )        {            msg_Err( p_dec, "decoder is leaking pictures, resetting the heap" );            /* Just free all the pictures */            for( i_pic = 0; i_pic < p_dec->p_owner->p_vout->render.i_pictures;                 i_pic++ )            {                if( p_pic->i_status == RESERVED_PICTURE )                    vout_DestroyPicture( p_dec->p_owner->p_vout, p_pic );                if( p_pic->i_refcount > 0 )                vout_UnlinkPicture( p_dec->p_owner->p_vout, p_pic );            }        }#undef p_pic        msleep( VOUT_OUTMEM_SLEEP );    }    return p_pic;}static void vout_del_buffer( decoder_t *p_dec, picture_t *p_pic ){    vout_DestroyPicture( p_dec->p_owner->p_vout, p_pic );}static void vout_link_picture( decoder_t *p_dec, picture_t *p_pic ){    vout_LinkPicture( p_dec->p_owner->p_vout, p_pic );}static void vout_unlink_picture( decoder_t *p_dec, picture_t *p_pic ){    vout_UnlinkPicture( p_dec->p_owner->p_vout, p_pic );}static subpicture_t *spu_new_buffer( decoder_t *p_dec ){    decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner;    vout_thread_t *p_vout = NULL;    subpicture_t *p_subpic;    int i_attempts = 30;    while( i_attempts-- )    {        if( p_dec->b_die || p_dec->b_error ) break;        p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );        if( p_vout ) break;        msleep( VOUT_DISPLAY_DELAY );    }    if( !p_vout )    {        msg_Warn( p_dec, "no vout found, dropping subpicture" );        return NULL;    }    if( p_sys->p_spu_vout != p_vout )    {        spu_Control( p_vout->p_spu, SPU_CHANNEL_REGISTER,                     &p_sys->i_spu_channel );        p_sys->p_spu_vout = p_vout;    }    p_subpic = spu_CreateSubpicture( p_vout->p_spu );    if( p_subpic )    {        p_subpic->i_channel = p_sys->i_spu_channel;    }    vlc_object_release( p_vout );    return p_subpic;}static void spu_del_buffer( decoder_t *p_dec, subpicture_t *p_subpic ){    decoder_owner_sys_t *p_sys = (decoder_owner_sys_t *)p_dec->p_owner;    vout_thread_t *p_vout = NULL;    p_vout = vlc_object_find( p_dec, VLC_OBJECT_VOUT, FIND_ANYWHERE );    if( !p_vout || p_sys->p_spu_vout != p_vout )    {        if( p_vout )            vlc_object_release( p_vout );        msg_Warn( p_dec, "no vout found, leaking subpicture" );        return;    }    spu_DestroySubpicture( p_vout->p_spu, p_subpic );    vlc_object_release( p_vout );}

⌨️ 快捷键说明

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