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

📄 decoder.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    decoder_t *p_dec;    p_dec = vlc_object_create( p_input, i_object_type );    if( p_dec == NULL )    {        msg_Err( p_input, "out of memory" );        return NULL;    }    p_dec->pf_decode_audio = 0;    p_dec->pf_decode_video = 0;    p_dec->pf_decode_sub = 0;    p_dec->pf_packetize = 0;   /* Initialize the decoder fifo */    p_dec->p_module = NULL;    es_format_Copy( &p_dec->fmt_in, fmt );    es_format_Copy( &p_dec->fmt_out, &null_es_format );    /* Allocate our private structure for the decoder */    p_dec->p_owner = malloc( sizeof( decoder_owner_sys_t ) );    if( p_dec->p_owner == NULL )    {        msg_Err( p_dec, "out of memory" );        return NULL;    }    p_dec->p_owner->b_own_thread = VLC_TRUE;    p_dec->p_owner->i_preroll_end = -1;    p_dec->p_owner->p_input = p_input;    p_dec->p_owner->p_aout = NULL;    p_dec->p_owner->p_aout_input = NULL;    p_dec->p_owner->p_vout = NULL;    p_dec->p_owner->p_spu_vout = NULL;    p_dec->p_owner->i_spu_channel = 0;    p_dec->p_owner->p_sout = p_input->p_sout;    p_dec->p_owner->p_sout_input = NULL;    p_dec->p_owner->p_packetizer = NULL;    /* decoder fifo */    if( ( p_dec->p_owner->p_fifo = block_FifoNew( p_dec ) ) == NULL )    {        msg_Err( p_dec, "out of memory" );        return NULL;    }    /* Set buffers allocation callbacks for the decoders */    p_dec->pf_aout_buffer_new = aout_new_buffer;    p_dec->pf_aout_buffer_del = aout_del_buffer;    p_dec->pf_vout_buffer_new = vout_new_buffer;    p_dec->pf_vout_buffer_del = vout_del_buffer;    p_dec->pf_picture_link    = vout_link_picture;    p_dec->pf_picture_unlink  = vout_unlink_picture;    p_dec->pf_spu_buffer_new  = spu_new_buffer;    p_dec->pf_spu_buffer_del  = spu_del_buffer;    vlc_object_attach( p_dec, p_input );    stats_Create( p_dec->p_parent, "decoded_audio", STATS_DECODED_AUDIO,                  VLC_VAR_INTEGER, STATS_COUNTER );    stats_Create( p_dec->p_parent, "decoded_video", STATS_DECODED_VIDEO,                  VLC_VAR_INTEGER, STATS_COUNTER );    stats_Create( p_dec->p_parent, "decoded_sub", STATS_DECODED_SUB,                  VLC_VAR_INTEGER, STATS_COUNTER );    /* Find a suitable decoder/packetizer module */    if( i_object_type == VLC_OBJECT_DECODER )        p_dec->p_module = module_Need( p_dec, "decoder", "$codec", 0 );    else        p_dec->p_module = module_Need( p_dec, "packetizer", "$packetizer", 0 );    /* Check if decoder requires already packetized data */    if( i_object_type == VLC_OBJECT_DECODER &&        p_dec->b_need_packetized && !p_dec->fmt_in.b_packetized )    {        p_dec->p_owner->p_packetizer =            vlc_object_create( p_input, VLC_OBJECT_PACKETIZER );        if( p_dec->p_owner->p_packetizer )        {            es_format_Copy( &p_dec->p_owner->p_packetizer->fmt_in,                            &p_dec->fmt_in );            es_format_Copy( &p_dec->p_owner->p_packetizer->fmt_out,                            &null_es_format );            vlc_object_attach( p_dec->p_owner->p_packetizer, p_input );            p_dec->p_owner->p_packetizer->p_module =                module_Need( p_dec->p_owner->p_packetizer,                             "packetizer", "$packetizer", 0 );            if( !p_dec->p_owner->p_packetizer->p_module )            {                es_format_Clean( &p_dec->p_owner->p_packetizer->fmt_in );                vlc_object_detach( p_dec->p_owner->p_packetizer );                vlc_object_destroy( p_dec->p_owner->p_packetizer );            }        }    }    return p_dec;}/** * The decoding main loop * * \param p_dec the decoder * \return 0 */static int DecoderThread( decoder_t * p_dec ){    block_t *p_block;    /* The decoder's main loop */    while( !p_dec->b_die && !p_dec->b_error )    {        if( ( p_block = block_FifoGet( p_dec->p_owner->p_fifo ) ) == NULL )        {            p_dec->b_error = 1;            break;        }        if( DecoderDecode( p_dec, p_block ) != VLC_SUCCESS )        {            break;        }    }    while( !p_dec->b_die )    {        /* Trash all received PES packets */        p_block = block_FifoGet( p_dec->p_owner->p_fifo );        if( p_block ) block_Release( p_block );    }    /* We do it here because of the dll loader that wants close() in the     * same thread than open()/decode() */    module_Unneed( p_dec, p_dec->p_module );    return 0;}/** * Decode a block * * \param p_dec the decoder object * \param p_block the block to decode * \return VLC_SUCCESS or an error code */static int DecoderDecode( decoder_t *p_dec, block_t *p_block ){    int i_rate = p_block ? p_block->i_rate : 1000;    if( p_block && p_block->i_buffer <= 0 )    {        block_Release( p_block );        return VLC_SUCCESS;    }    if( p_dec->i_object_type == VLC_OBJECT_PACKETIZER )    {        block_t *p_sout_block;        while( ( p_sout_block =                     p_dec->pf_packetize( p_dec, p_block ? &p_block : 0 ) ) )        {            if( !p_dec->p_owner->p_sout_input )            {                es_format_Copy( &p_dec->p_owner->sout, &p_dec->fmt_out );                p_dec->p_owner->sout.i_group = p_dec->fmt_in.i_group;                p_dec->p_owner->sout.i_id = p_dec->fmt_in.i_id;                if( p_dec->fmt_in.psz_language )                {                    if( p_dec->p_owner->sout.psz_language )                        free( p_dec->p_owner->sout.psz_language );                    p_dec->p_owner->sout.psz_language =                        strdup( p_dec->fmt_in.psz_language );                }                p_dec->p_owner->p_sout_input =                    sout_InputNew( p_dec->p_owner->p_sout,                                   &p_dec->p_owner->sout );                if( p_dec->p_owner->p_sout_input == NULL )                {                    msg_Err( p_dec, "cannot create packetizer output (%4.4s)",                             (char *)&p_dec->p_owner->sout.i_codec );                    p_dec->b_error = VLC_TRUE;                    while( p_sout_block )                    {                        block_t *p_next = p_sout_block->p_next;                        block_Release( p_sout_block );                        p_sout_block = p_next;                    }                    break;                }            }            while( p_sout_block )            {                block_t *p_next = p_sout_block->p_next;                p_sout_block->p_next = NULL;                p_sout_block->i_rate = i_rate;                sout_InputSendBuffer( p_dec->p_owner->p_sout_input,                                      p_sout_block );                p_sout_block = p_next;            }            /* For now it's enough, as only sout inpact on this flag */            if( p_dec->p_owner->p_sout->i_out_pace_nocontrol > 0 &&                p_dec->p_owner->p_input->b_out_pace_control )            {                msg_Dbg( p_dec, "switching to sync mode" );                p_dec->p_owner->p_input->b_out_pace_control = VLC_FALSE;            }            else if( p_dec->p_owner->p_sout->i_out_pace_nocontrol <= 0 &&                     !p_dec->p_owner->p_input->b_out_pace_control )            {                msg_Dbg( p_dec, "switching to async mode" );                p_dec->p_owner->p_input->b_out_pace_control = VLC_TRUE;            }        }    }    else if( p_dec->fmt_in.i_cat == AUDIO_ES )    {        aout_buffer_t *p_aout_buf;        if( p_dec->p_owner->p_packetizer )        {            block_t *p_packetized_block;            decoder_t *p_packetizer = p_dec->p_owner->p_packetizer;            while( (p_packetized_block =                    p_packetizer->pf_packetize( p_packetizer, &p_block )) )            {                if( p_packetizer->fmt_out.i_extra && !p_dec->fmt_in.i_extra )                {                    es_format_Clean( &p_dec->fmt_in );                    es_format_Copy( &p_dec->fmt_in, &p_packetizer->fmt_out );                }                while( p_packetized_block )                {                    block_t *p_next = p_packetized_block->p_next;                    p_packetized_block->p_next = NULL;                    p_packetized_block->i_rate = i_rate;                    while( (p_aout_buf = p_dec->pf_decode_audio( p_dec,                                                       &p_packetized_block )) )                    {                        stats_UpdateInteger( p_dec->p_parent,                                             STATS_DECODED_AUDIO, 1, NULL );                        /* FIXME the best would be to handle the case start_date < preroll < end_date                         * but that's not easy with non raw audio stream */                        if( p_dec->p_owner->i_preroll_end > 0 &&                            p_aout_buf->start_date < p_dec->p_owner->i_preroll_end )                        {                            aout_DecDeleteBuffer( p_dec->p_owner->p_aout,                                                  p_dec->p_owner->p_aout_input, p_aout_buf );                        }                        else                        {                            p_dec->p_owner->i_preroll_end = -1;                            aout_DecPlay( p_dec->p_owner->p_aout,                                          p_dec->p_owner->p_aout_input,                                          p_aout_buf );                        }                    }                    p_packetized_block = p_next;                }            }        }        else while( (p_aout_buf = p_dec->pf_decode_audio( p_dec, &p_block )) )        {            stats_UpdateInteger( p_dec->p_parent, STATS_DECODED_AUDIO, 1, NULL );            if( p_dec->p_owner->i_preroll_end > 0 &&                p_aout_buf->start_date < p_dec->p_owner->i_preroll_end )            {                aout_DecDeleteBuffer( p_dec->p_owner->p_aout,                                      p_dec->p_owner->p_aout_input, p_aout_buf );            }            else            {                p_dec->p_owner->i_preroll_end = -1;                aout_DecPlay( p_dec->p_owner->p_aout,                              p_dec->p_owner->p_aout_input,                              p_aout_buf );            }        }    }    else if( p_dec->fmt_in.i_cat == VIDEO_ES )    {        picture_t *p_pic;        if( p_dec->p_owner->p_packetizer )        {            block_t *p_packetized_block;            decoder_t *p_packetizer = p_dec->p_owner->p_packetizer;            while( (p_packetized_block =                    p_packetizer->pf_packetize( p_packetizer, &p_block )) )            {                if( p_packetizer->fmt_out.i_extra && !p_dec->fmt_in.i_extra )                {                    es_format_Clean( &p_dec->fmt_in );                    es_format_Copy( &p_dec->fmt_in, &p_packetizer->fmt_out );                }                while( p_packetized_block )                {                    block_t *p_next = p_packetized_block->p_next;                    p_packetized_block->p_next = NULL;                    p_packetized_block->i_rate = i_rate;                    while( (p_pic = p_dec->pf_decode_video( p_dec,                                                       &p_packetized_block )) )                    {                        stats_UpdateInteger( p_dec->p_parent, STATS_DECODED_VIDEO,                                                             1, NULL );                        if( p_dec->p_owner->i_preroll_end > 0 &&                            p_pic->date < p_dec->p_owner->i_preroll_end )                        {                            vout_DestroyPicture( p_dec->p_owner->p_vout, p_pic );                        }                        else                        {                            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 );                        }                    }                    p_packetized_block = p_next;                }            }        }        else while( (p_pic = p_dec->pf_decode_video( p_dec, &p_block )) )        {            stats_UpdateInteger( p_dec->p_parent, STATS_DECODED_VIDEO, 1 , NULL);            if( p_dec->p_owner->i_preroll_end > 0 &&                p_pic->date < p_dec->p_owner->i_preroll_end )            {                vout_DestroyPicture( p_dec->p_owner->p_vout, p_pic );            }            else            {                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 ) ) )        {            stats_UpdateInteger( p_dec->p_parent, STATS_DECODED_SUB, 1 , NULL);            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;            }

⌨️ 快捷键说明

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