📄 decoder.c
字号:
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 + -