📄 schroedinger.c
字号:
/***************************************************************************** * schroedinger.c: Dirac decoder module making use of libschroedinger. * (http://www.bbc.co.uk/rd/projects/dirac/index.shtml) * (http://diracvideo.org) ***************************************************************************** * Copyright (C) 2008 the VideoLAN team * $Id$ * * Authors: Jonathan Rosser <jonathan.rosser@gmail.com> * David Flynn <davidf at rd dot bbc.co.uk> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include <vlc_plugin.h>#include <vlc_codec.h>#include <vlc_sout.h>#include <vlc_vout.h>#include <schroedinger/schro.h>/***************************************************************************** * Module descriptor *****************************************************************************/static int OpenDecoder ( vlc_object_t * );static void CloseDecoder ( vlc_object_t * );vlc_module_begin(); set_category( CAT_INPUT ); set_subcategory( SUBCAT_INPUT_VCODEC ); set_description( N_("Schroedinger video decoder") ); set_capability( "decoder", 200 ); set_callbacks( OpenDecoder, CloseDecoder ); add_shortcut( "schroedinger" );vlc_module_end();/***************************************************************************** * Local prototypes *****************************************************************************/static picture_t *DecodeBlock ( decoder_t *p_dec, block_t **pp_block );/***************************************************************************** * picture_pts_t : store pts alongside picture number, not carried through * decoder *****************************************************************************/struct picture_pts_t{ int i_empty; //not in use uint32_t u_pnum; //picture number from dirac header mtime_t i_pts; //pts for this picture};struct picture_free_t{ picture_t *p_pic; decoder_t *p_dec;};/***************************************************************************** * decoder_sys_t : Schroedinger decoder descriptor *****************************************************************************/#define PTS_TLB_SIZE 16struct decoder_sys_t{ /* * Dirac properties */ mtime_t i_lastpts; mtime_t i_frame_pts_delta; SchroDecoder *p_schro; SchroVideoFormat *p_format; struct picture_pts_t pts_tlb[PTS_TLB_SIZE]; int i_ts_resync_hack;};//#define TRACE/***************************************************************************** * ResetPTStlb: Purge all entries in @p_dec@'s PTS-tlb *****************************************************************************/static void ResetPTStlb( decoder_t *p_dec ){ decoder_sys_t *p_sys = p_dec->p_sys; for( int i=0; i<PTS_TLB_SIZE; i++) { p_sys->pts_tlb[i].i_empty = 1; }}/***************************************************************************** * OpenDecoder: probe the decoder and return score *****************************************************************************/static int OpenDecoder( vlc_object_t *p_this ){ decoder_t *p_dec = (decoder_t*)p_this; decoder_sys_t *p_sys; SchroDecoder *p_schro; if( p_dec->fmt_in.i_codec != VLC_FOURCC('d','r','a','c') ) { return VLC_EGENERIC; } /* Allocate the memory needed to store the decoder's structure */ p_sys = malloc(sizeof(decoder_sys_t)); if( p_sys == NULL ) return VLC_ENOMEM; /* Initialise the schroedinger (and hence liboil libraries */ /* This does no allocation and is safe to call */ schro_init(); /* Initialise the schroedinger decoder */ if( !(p_schro = schro_decoder_new()) ) { free( p_sys ); return VLC_EGENERIC; } p_dec->p_sys = p_sys; p_sys->p_schro = p_schro; p_sys->p_format = NULL; p_sys->i_lastpts = -1; p_sys->i_frame_pts_delta = 0; p_sys->i_ts_resync_hack = 0; ResetPTStlb(p_dec); /* Set output properties */ p_dec->fmt_out.i_cat = VIDEO_ES; p_dec->fmt_out.i_codec = VLC_FOURCC('I','4','2','0'); /* Set callbacks */ p_dec->pf_decode_video = DecodeBlock; return VLC_SUCCESS;}/***************************************************************************** * SetPictureFormat: Set the decoded picture params to the ones from the stream *****************************************************************************/static void SetVideoFormat( decoder_t *p_dec ){ decoder_sys_t *p_sys = p_dec->p_sys; double f_aspect; p_sys->p_format = schro_decoder_get_video_format(p_sys->p_schro); if( p_sys->p_format == NULL ) return; p_sys->i_frame_pts_delta = INT64_C(1000000) * p_sys->p_format->frame_rate_denominator / p_sys->p_format->frame_rate_numerator; switch( p_sys->p_format->chroma_format ) { case SCHRO_CHROMA_420: p_dec->fmt_out.i_codec = VLC_FOURCC('I','4','2','0'); break; case SCHRO_CHROMA_422: p_dec->fmt_out.i_codec = VLC_FOURCC('I','4','2','2'); break; case SCHRO_CHROMA_444: p_dec->fmt_out.i_codec = VLC_FOURCC('I','4','4','4'); break; default: p_dec->fmt_out.i_codec = 0; break; } p_dec->fmt_out.video.i_visible_width = p_dec->fmt_out.video.i_width = p_sys->p_format->width; p_dec->fmt_out.video.i_visible_height = p_dec->fmt_out.video.i_height = p_sys->p_format->height; /* aspect_ratio_[numerator|denominator] describes the pixel aspect ratio */ f_aspect = (double) ( p_sys->p_format->aspect_ratio_numerator * p_sys->p_format->width ) / ( p_sys->p_format->aspect_ratio_denominator * p_sys->p_format->height); p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR * f_aspect; p_dec->fmt_out.video.i_frame_rate = p_sys->p_format->frame_rate_numerator; p_dec->fmt_out.video.i_frame_rate_base = p_sys->p_format->frame_rate_denominator;}/***************************************************************************** * StorePicturePTS: Store the PTS value for a particular picture number *****************************************************************************/static void StorePicturePTS( decoder_t *p_dec, block_t *p_block, int i_pupos ){ decoder_sys_t *p_sys = p_dec->p_sys; uint32_t u_pnum; u_pnum = GetDWBE( p_block->p_buffer + i_pupos + 13 ); for( int i=0; i<PTS_TLB_SIZE; i++ ) { if( p_sys->pts_tlb[i].i_empty ) { p_sys->pts_tlb[i].u_pnum = u_pnum; p_sys->pts_tlb[i].i_pts = p_block->i_pts; p_sys->pts_tlb[i].i_empty = 0; return; } } msg_Err( p_dec, "Could not store PTS %"PRId64" for picture %u", p_block->i_pts, u_pnum );}/***************************************************************************** * GetPicturePTS: Retrieve the PTS value for a particular picture number *****************************************************************************/static mtime_t GetPicturePTS( decoder_t *p_dec, uint32_t u_pnum ){ decoder_sys_t *p_sys = p_dec->p_sys; for( int i=0; i<PTS_TLB_SIZE; i++ ) { if( (!p_sys->pts_tlb[i].i_empty) && (p_sys->pts_tlb[i].u_pnum == u_pnum)) { p_sys->pts_tlb[i].i_empty = 1; return p_sys->pts_tlb[i].i_pts; } } msg_Err( p_dec, "Could not retrieve PTS for picture %u", u_pnum ); return 0;}/***************************************************************************** * SchroFrameFree: schro_frame callback to release the associated picture_t * When schro_decoder_reset() is called there will be pictures in the * decoding pipeline that need to be released rather than displayed. *****************************************************************************/static void SchroFrameFree( SchroFrame *frame, void *priv){ struct picture_free_t *p_free = priv; if( !p_free ) return; p_free->p_dec->pf_vout_buffer_del( p_free->p_dec, p_free->p_pic ); free(p_free); (void)frame;}/***************************************************************************** * CreateSchroFrameFromPic: wrap a picture_t in a SchroFrame *****************************************************************************/static SchroFrame *CreateSchroFrameFromPic( decoder_t *p_dec ){ decoder_sys_t *p_sys = p_dec->p_sys; SchroFrame *p_schroframe = schro_frame_new(); picture_t *p_pic = NULL; struct picture_free_t *p_free; if( !p_schroframe ) return NULL; p_pic = p_dec->pf_vout_buffer_new( p_dec ); if( !p_pic ) return NULL; p_schroframe->format = SCHRO_FRAME_FORMAT_U8_420; if( p_sys->p_format->chroma_format == SCHRO_CHROMA_422 ) { p_schroframe->format = SCHRO_FRAME_FORMAT_U8_422;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -