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

📄 nuv.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * nuv.c: ***************************************************************************** * Copyright (C) 2005 VideoLAN * $Id: $ * * 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 <vlc/vlc.h>#include <vlc/input.h>/* TODO: *  - complete support (add support for rtjpeg and raw) *  - better seek support (to key frame) *  - control GET_LENGTH (harder, unless we have an extended header+index) *  - test *//***************************************************************************** * Module descriptor *****************************************************************************/static int  Open  ( vlc_object_t * );static void Close ( vlc_object_t * );vlc_module_begin();    set_category( CAT_INPUT );    set_subcategory( SUBCAT_INPUT_DEMUX );    set_description( _("Nuv demuxer") );    set_capability( "demux2", 145 );    set_callbacks( Open, Close );    add_shortcut( "nuv" );vlc_module_end();/***************************************************************************** * Local prototypes *****************************************************************************/static int Demux  ( demux_t * );static int Control( demux_t *, int, va_list );/* */typedef struct{    int64_t i_time;    int64_t i_offset;} demux_index_entry_t;typedef struct{    int i_idx;    int i_idx_max;    demux_index_entry_t *idx;} demux_index_t;static void demux_IndexInit( demux_index_t * );static void demux_IndexClean( demux_index_t * );static void demux_IndexAppend( demux_index_t *,                               int64_t i_time, int64_t i_offset );/* Convert a time into offset */static int64_t demux_IndexConvertTime( demux_index_t *, int64_t i_time );/* Find the nearest offset in the index */static int64_t demux_IndexFindOffset( demux_index_t *, int64_t i_offset );/* */typedef struct{    char id[12];       /* "NuppelVideo\0" or "MythTVVideo\0" */    char version[5];    /* "x.xx\0" */    int  i_width;    int  i_height;    int  i_width_desired;    int  i_height_desired;    char i_mode;            /* P progressive, I interlaced */    double  d_aspect;       /* 1.0 squared pixel */    double  d_fps;    int     i_video_blocks; /* 0 no video, -1 unknown */    int     i_audio_blocks;    int     i_text_blocks;    int     i_keyframe_distance;} header_t;typedef struct{    char i_type;        /* A: audio, V: video, S: sync; T: test                           R: Seekpoint (string:RTjjjjjjjj)                           D: Extra data for codec */    char i_compression; /* V: 0 uncompressed                              1 RTJpeg                              2 RTJpeg+lzo                              N black frame                              L copy last                           A: 0 uncompressed (44100 1-bits, 2ch)                              1 lzo                              2 layer 2                              3 layer 3                              F flac                              S shorten                              N null frame loudless                              L copy last                            S: B audio and vdeo sync point                               A audio sync info (timecode == effective                                    dsp frequency*100)                               V next video sync (timecode == next video                                    frame num)                               S audio,video,text correlation */    char i_keyframe;    /* 0 keyframe, else no no key frame */    uint8_t i_filters;  /* 0x01: gauss 5 pixel (8,2,2,2,2)/16                           0x02: gauss 5 pixel (8,1,1,1,1)/12                           0x04: cartoon filter */    int i_timecode;     /* ms */    int i_length;       /* V,A,T: length of following data                           S: length of packet correl */} frame_header_t;/* FIXME Not sure of this one */typedef struct{    int             i_version;    vlc_fourcc_t    i_video_fcc;    vlc_fourcc_t    i_audio_fcc;    int             i_audio_sample_rate;    int             i_audio_bits_per_sample;    int             i_audio_channels;    int             i_audio_compression_ratio;    int             i_audio_quality;    int             i_rtjpeg_quality;    int             i_rtjpeg_luma_filter;    int             i_rtjpeg_chroma_filter;    int             i_lavc_bitrate;    int             i_lavc_qmin;    int             i_lavc_qmax;    int             i_lavc_maxqdiff;    int64_t         i_seekable_offset;    int64_t         i_keyframe_adjust_offset;} extended_header_t;struct demux_sys_t{    header_t          hdr;    extended_header_t exh;    int64_t     i_pcr;    es_out_id_t *p_es_video;    int         i_extra_f;    uint8_t     *p_extra_f;    es_out_id_t *p_es_audio;    /* index */    demux_index_t idx;};static int HeaderLoad( demux_t *, header_t *h );static int FrameHeaderLoad( demux_t *, frame_header_t *h );static int ExtendedHeaderLoad( demux_t *, extended_header_t *h );/***************************************************************************** * Open: initializes ES structures *****************************************************************************/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;    frame_header_t fh;    vlc_bool_t  b_extended;    /* Check id */    if( stream_Peek( p_demux->s, &p_peek, 12 ) != 12 ||        ( strncmp( p_peek, "MythTVVideo", 11 ) &&          strncmp( p_peek, "NuppelVideo", 11 ) ) )        return VLC_EGENERIC;    p_sys = malloc( sizeof( demux_sys_t ) );    memset( p_sys, 0, sizeof( demux_sys_t ) );    p_sys->p_es_video = NULL;    p_sys->p_es_audio = NULL;    p_sys->p_extra_f = NULL;    p_sys->i_pcr = -1;    demux_IndexInit( &p_sys->idx );    if( HeaderLoad( p_demux, &p_sys->hdr ) )        goto error;    /* Load 'D' */    if( FrameHeaderLoad( p_demux, &fh ) || fh.i_type != 'D' )        goto error;    if( fh.i_length > 0 )    {        if( fh.i_compression == 'F' )        {            /* ffmpeg extra data */            p_sys->i_extra_f = fh.i_length;            p_sys->p_extra_f = malloc( fh.i_length );            if( stream_Read( p_demux->s,                             p_sys->p_extra_f, fh.i_length ) != fh.i_length )                goto error;        }        else        {            /* TODO handle rtjpeg */            msg_Warn( p_demux, "unsuported 'D' frame (c=%c)", fh.i_compression );            if( stream_Read( p_demux->s, NULL, fh.i_length ) != fh.i_length )                goto error;        }    }    /* Check and load extented */    if( stream_Peek( p_demux->s, &p_peek, 1 ) != 1 )        goto error;    if( p_peek[0] == 'X' )    {        b_extended = VLC_TRUE;        if( FrameHeaderLoad( p_demux, &fh ) )            goto error;        if( fh.i_length != 512 )            goto error;        if( ExtendedHeaderLoad( p_demux, &p_sys->exh ) )            goto error;    }    else    {        b_extended = VLC_FALSE;        /* XXX: for now only file with extended chunk are supported         * why: because else we need to have support for rtjpeg+stupid nuv shit */        msg_Err( p_demux, "incomplete NUV support (upload samples)" );        goto error;    }    /* Create audio/video (will work only with extended header and audio=mp3 */    if( p_sys->hdr.i_video_blocks != 0 )    {        es_format_t fmt;        es_format_Init( &fmt, VIDEO_ES, p_sys->exh.i_video_fcc );        fmt.video.i_width = p_sys->hdr.i_width;        fmt.video.i_height = p_sys->hdr.i_height;        fmt.i_extra = p_sys->i_extra_f;        fmt.p_extra = p_sys->p_extra_f;        p_sys->p_es_video = es_out_Add( p_demux->out, &fmt );    }    if( p_sys->hdr.i_audio_blocks != 0 )    {        es_format_t fmt;        es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC('m','p','g','a') );        fmt.audio.i_rate = p_sys->exh.i_audio_sample_rate;        fmt.audio.i_bitspersample = p_sys->exh.i_audio_bits_per_sample;        p_sys->p_es_audio = es_out_Add( p_demux->out, &fmt );    }    if( p_sys->hdr.i_text_blocks != 0 )    {        msg_Warn( p_demux, "text not yet supported (upload samples)" );    }    /* Fill p_demux fields */    p_demux->pf_demux = Demux;    p_demux->pf_control = Control;    p_demux->p_sys = p_sys;    return VLC_SUCCESS;error:    msg_Warn( p_demux, "cannot load Nuv file" );    free( p_sys );    return VLC_EGENERIC;}/***************************************************************************** * Close: frees unused data *****************************************************************************/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;    if( p_sys->p_extra_f )        free( p_sys->p_extra_f );    demux_IndexClean( &p_sys->idx );    free( p_sys );}/***************************************************************************** * Demux: reads and demuxes data packets ***************************************************************************** * Returns -1 in case of error, 0 in case of EOF, 1 otherwise *****************************************************************************/static int Demux( demux_t *p_demux ){    demux_sys_t *p_sys = p_demux->p_sys;    frame_header_t fh;    block_t *p_data;    for( ;; )    {        if( p_demux->b_die )            return -1;        if( FrameHeaderLoad( p_demux, &fh ) )            return 0;        if( fh.i_type == 'A' || fh.i_type == 'V' )            break;        /* TODO add support for some block type */        if( fh.i_type != 'R' )        {            stream_Read( p_demux->s, NULL, fh.i_length );        }    }    /* */    p_data = stream_Block( p_demux->s, fh.i_length );    p_data->i_dts = (int64_t)fh.i_timecode * 1000;    p_data->i_pts = (fh.i_type == 'V') ? 0 : p_data->i_dts;    /* */    demux_IndexAppend( &p_sys->idx, p_data->i_dts, stream_Tell(p_demux->s) );    /* */    if( p_data->i_dts > p_sys->i_pcr )    {        p_sys->i_pcr = p_data->i_dts;        es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pcr );    }    if( fh.i_type == 'A' && p_sys->p_es_audio )    {        if( fh.i_compression == '3' )            es_out_Send( p_demux->out, p_sys->p_es_audio, p_data );        else        {            msg_Dbg( p_demux, "unsupported compression %c for audio (upload samples)", fh.i_compression );            block_Release( p_data );        }    }    else if( fh.i_type == 'V' && p_sys->p_es_video )    {        if( fh.i_compression >= '4' )            es_out_Send( p_demux->out, p_sys->p_es_video, p_data );        else        {            msg_Dbg( p_demux, "unsupported compression %c for video (upload samples)", fh.i_compression );            block_Release( p_data );        }    }    else    {        block_Release( p_data );    }

⌨️ 快捷键说明

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