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

📄 decoder.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:
        aout_DecDelete( p_dec->p_owner->p_aout, p_dec->p_owner->p_aout_input );    if( p_dec->p_owner->p_aout )    {        vlc_object_release( p_dec->p_owner->p_aout );        p_dec->p_owner->p_aout = NULL;    }    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, NULL );        var_SetBool( p_dec->p_owner->p_input, "intf-change-vout", true );    }#ifdef ENABLE_SOUT    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 );    }#endif    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_release( p_dec->p_owner->p_packetizer );    }    vlc_mutex_destroy( &p_dec->p_owner->lock_cc );    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 )    {        audio_sample_format_t format;        int i_force_dolby = config_GetInt( p_dec, "force-dolby-surround" );        p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec;        p_sys->audio = p_dec->fmt_out.audio;        memcpy( &format, &p_sys->audio, sizeof( audio_sample_format_t ) );        if ( i_force_dolby && (format.i_original_channels&AOUT_CHAN_PHYSMASK)                                    == (AOUT_CHAN_LEFT|AOUT_CHAN_RIGHT) )        {            if ( i_force_dolby == 1 )            {                format.i_original_channels = format.i_original_channels |                                             AOUT_CHAN_DOLBYSTEREO;            }            else /* i_force_dolby == 2 */            {                format.i_original_channels = format.i_original_channels &                                             ~AOUT_CHAN_DOLBYSTEREO;            }        }        p_sys->p_aout_input =            aout_DecNew( p_dec, &p_sys->p_aout, &format, &p_dec->fmt_out.audio_replay_gain );        if( p_sys->p_aout_input == NULL )        {            msg_Err( p_dec, "failed to create audio output" );            p_dec->b_error = 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_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 );}int vout_CountPictureAvailable( vout_thread_t *p_vout );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_visible_width ||            !p_dec->fmt_out.video.i_visible_height )        {            if( p_dec->fmt_in.video.i_visible_width &&                p_dec->fmt_in.video.i_visible_height )            {                p_dec->fmt_out.video.i_visible_width =                    p_dec->fmt_in.video.i_visible_width;                p_dec->fmt_out.video.i_visible_height =                    p_dec->fmt_in.video.i_visible_height;            }            else            {                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;            }        }        if( p_dec->fmt_out.video.i_visible_height == 1088 &&            var_CreateGetBool( p_dec, "hdtv-fix" ) )        {            p_dec->fmt_out.video.i_visible_height = 1080;            p_dec->fmt_out.video.i_sar_num *= 135;            p_dec->fmt_out.video.i_sar_den *= 136;            msg_Warn( p_dec, "Fixing broken HDTV stream (display_height=1088)");        }        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_visible_height;            p_dec->fmt_out.video.i_sar_den = VOUT_ASPECT_FACTOR *              p_dec->fmt_out.video.i_visible_width;        }        vlc_ureduce( &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, 50000 );        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 );        var_SetBool( p_sys->p_input, "intf-change-vout", true );        if( p_sys->p_vout == NULL )        {            msg_Err( p_dec, "failed to create video output" );            p_dec->b_error = 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     */    for( p_pic = NULL; ; )    {        int i_pic, i_ready_pic;        if( p_dec->b_die || p_dec->b_error )            return NULL;        /* The video filter chain required that there is always 1 free buffer         * that it will use as temporary one. It will release the temporary         * buffer once its work is done, so this check is safe even if we don't         * lock around both count() and create().         */        if( vout_CountPictureAvailable( p_sys->p_vout ) >= 2 )        {            p_pic = vout_CreatePicture( p_sys->p_vout, 0, 0, 0 );            if( p_pic )                break;        }#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_ready_pic = 0; i_pic < p_dec->p_owner->p_vout->render.i_pictures; i_pic++ )        {            if( p_pic->i_status == READY_PICTURE )            {                i_ready_pic++;                /* If we have at least 2 ready pictures, wait for the vout thread to                 * process one */                if( i_ready_pic >= 2 )                    break;                continue;            }            if( p_pic->i_status == DISPLAYED_PICTURE )            {                /* If at least one displayed picture is not referenced                 * let vout free it */                if( p_pic->i_refcount == 0 )                    break;            }        }        if( i_pic == p_dec->p_owner->p_vout->render.i_pictures )        {            /* Too many pictures are still referenced, there is probably a bug             * with the decoder */            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 ){    VoutDisplayedPicture( 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 + -