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

📄 decoder.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 3 页
字号:
                input_NullPacket( p_input, p_es );            }        }    }#endif}#endif/** * Create a decoder object * * \param p_input the input thread * \param p_es the es descriptor * \param i_object_type Object type as define in include/vlc_objects.h * \return the decoder object */static decoder_t * CreateDecoder( input_thread_t *p_input,                                  es_format_t *fmt, int i_object_type ){    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 );    /* 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 )                {                    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" );                    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 synch 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 asynch 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 )                {                    p_dec->fmt_in.i_extra = p_packetizer->fmt_out.i_extra;                    p_dec->fmt_in.p_extra = malloc( p_dec->fmt_in.i_extra );                    memcpy( p_dec->fmt_in.p_extra,                            p_packetizer->fmt_out.p_extra,                            p_dec->fmt_in.i_extra );                }                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 )) )                    {                        /* 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 )) )        {            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 )) )            {                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 )) )                    {                        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 )) )        {            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            {

⌨️ 快捷键说明

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