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

📄 nsv.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * nsv.c: NullSoft Video demuxer. ***************************************************************************** * Copyright (C) 2004 VideoLAN * $Id: nsv.c 10547 2005-04-04 23:50:07Z hartman $ * * Authors: Laurent Aimar <fenrir@via.ecp.fr> * * 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., 59 Temple Place - Suite 330, Boston, MA  02111, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include <stdlib.h>                                      /* malloc(), free() */#include <vlc/vlc.h>#include <vlc/input.h>/* TODO: *  - implement NSVf parsing (to get meta data) *  - implement missing Control (and in the right way) *  - ... *//***************************************************************************** * Module descriptor *****************************************************************************/static int  Open    ( vlc_object_t * );static void Close  ( vlc_object_t * );vlc_module_begin();    set_description( _("NullSoft demuxer" ) );    set_capability( "demux2", 10 );    set_category( CAT_INPUT );    set_subcategory( SUBCAT_INPUT_DEMUX );    set_callbacks( Open, Close );    add_shortcut( "nsv" );vlc_module_end();/***************************************************************************** * Local prototypes *****************************************************************************/struct demux_sys_t{    es_format_t  fmt_audio;    es_out_id_t *p_audio;    es_format_t  fmt_video;    es_out_id_t *p_video;    es_format_t  fmt_sub;    es_out_id_t  *p_sub;    int64_t     i_pcr;    int64_t     i_time;    int64_t     i_pcr_inc;};static int Demux  ( demux_t *p_demux );static int Control( demux_t *p_demux, int i_query, va_list args );static int ReSynch( demux_t *p_demux );static int ReadNSVf( demux_t *p_demux );static int ReadNSVs( demux_t *p_demux );/***************************************************************************** * Open *****************************************************************************/static int Open( vlc_object_t *p_this ){    demux_t     *p_demux = (demux_t*)p_this;    demux_sys_t *p_sys;    uint8_t     *p_peek;    if( stream_Peek( p_demux->s, &p_peek, 8 ) < 8 ) return VLC_EGENERIC;    if( strncmp( p_peek, "NSVf", 4 ) && strncmp( p_peek, "NSVs", 4 ))    {       /* In case we had force this demuxer we try to resynch */        if( strcmp( p_demux->psz_demux, "nsv" ) || ReSynch( p_demux ) )        {            return VLC_EGENERIC;        }    }    /* Fill p_demux field */    p_demux->pf_demux = Demux;    p_demux->pf_control = Control;    p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );    es_format_Init( &p_sys->fmt_audio, AUDIO_ES, 0 );    p_sys->p_audio = NULL;    es_format_Init( &p_sys->fmt_video, VIDEO_ES, 0 );    p_sys->p_video = NULL;    es_format_Init( &p_sys->fmt_sub, SPU_ES, 0 );    p_sys->p_sub = NULL;    p_sys->i_pcr   = 1;    p_sys->i_time  = 0;    p_sys->i_pcr_inc = 0;    return VLC_SUCCESS;}/***************************************************************************** * Close *****************************************************************************/static void Close( vlc_object_t *p_this ){    demux_t     *p_demux = (demux_t*)p_this;    demux_sys_t *p_sys = p_demux->p_sys;    free( p_sys );}/***************************************************************************** * Demux: *****************************************************************************/static int Demux( demux_t *p_demux ){    demux_sys_t *p_sys = p_demux->p_sys;    uint8_t     header[5];    uint8_t     *p_peek;    int         i_size;    block_t     *p_frame;    for( ;; )    {        if( stream_Peek( p_demux->s, &p_peek, 8 ) < 8 )        {            msg_Warn( p_demux, "cannot peek" );            return 0;        }        if( !strncmp( p_peek, "NSVf", 4 ) )        {            if( ReadNSVf( p_demux ) )            {                return -1;            }        }        else if( !strncmp( p_peek, "NSVs", 4 ) )        {            if( ReadNSVs( p_demux ) )            {                return -1;            }            break;        }        else if( GetWLE( p_peek ) == 0xbeef )        {            /* Next frame of the current NSVs chunk */            if( stream_Read( p_demux->s, NULL, 2 ) < 2 )            {                msg_Warn( p_demux, "cannot read" );                return 0;            }            break;        }        else        {            msg_Err( p_demux, "invalid signature 0x%x (%4.4s)", *(uint32_t*)p_peek, (char*)p_peek );            if( ReSynch( p_demux ) )            {                return -1;            }        }    }    if( stream_Read( p_demux->s, header, 5 ) < 5 )    {        msg_Warn( p_demux, "cannot read" );        return 0;    }    /* Set PCR */    es_out_Control( p_demux->out, ES_OUT_SET_PCR, (int64_t)p_sys->i_pcr );    /* Read video */    i_size = ( header[0] >> 4 ) | ( header[1] << 4 ) | ( header[2] << 12 );    if( i_size > 0 )    {        /* extra data ? */        if( (header[0]&0x0f) != 0x0 )        {            uint8_t      aux[6];            int          i_aux;            vlc_fourcc_t fcc;            if( stream_Read( p_demux->s, aux, 6 ) < 6 )            {                msg_Warn( p_demux, "cannot read" );                return 0;            }            i_aux = GetWLE( aux );            fcc   = VLC_FOURCC( aux[2], aux[3], aux[4], aux[5] );            msg_Dbg( p_demux, "Belekas: %d - size=%d fcc=%4.4s",                     header[0]&0xf, i_aux, (char*)&fcc );            if( fcc == VLC_FOURCC( 'S', 'U', 'B', 'T' ) && i_aux > 2 )            {                if( p_sys->p_sub == NULL )                {                    p_sys->fmt_sub.i_codec = VLC_FOURCC( 's', 'u', 'b', 't' );                    p_sys->p_sub = es_out_Add( p_demux->out, &p_sys->fmt_sub );                    es_out_Control( p_demux->out, ES_OUT_SET_ES, p_sys->p_sub );                }                stream_Read( p_demux->s, NULL, 2 );                if( ( p_frame = stream_Block( p_demux->s, i_aux - 2 ) ) )                {                    uint8_t *p = p_frame->p_buffer;                    while( p < &p_frame->p_buffer[p_frame->i_buffer] && *p != 0 )                    {                        p++;                    }                    if( *p == 0 && p + 1 < &p_frame->p_buffer[p_frame->i_buffer] )                    {                        p_frame->i_buffer -= p + 1 - p_frame->p_buffer;                        p_frame->p_buffer = p + 1;                    }                    /* Skip the first part (it is the language name) */                    p_frame->i_pts = p_sys->i_pcr;                    p_frame->i_dts = p_sys->i_pcr + 4000000;    /* 4s */                    es_out_Send( p_demux->out, p_sys->p_sub, p_frame );                }            }            else            {                /* We skip this extra data */                if( stream_Read( p_demux->s, NULL, i_aux ) < i_aux )                {                    msg_Warn( p_demux, "cannot read" );                    return 0;                }            }            i_size -= 6 + i_aux;        }        /* msg_Dbg( p_demux, "frame video size=%d", i_size ); */        if( i_size > 0 && ( p_frame = stream_Block( p_demux->s, i_size ) ) )        {            p_frame->i_dts = p_sys->i_pcr;            es_out_Send( p_demux->out, p_sys->p_video, p_frame );        }    }    /* Read audio */    i_size = header[3] | ( header[4] << 8 );    if( i_size > 0 )    {        /* msg_Dbg( p_demux, "frame audio size=%d", i_size ); */

⌨️ 快捷键说明

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