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

📄 rawvid.c

📁 VLC Player Source Code
💻 C
字号:
/***************************************************************************** * rawvid.c : raw video input module for vlc ***************************************************************************** * Copyright (C) 2007 the VideoLAN team * $Id$ * * Authors: Gildas Bazin <gbazin@videolan.org> *          Antoine Cellerier <dionoea at videolan d.t org> * * 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_demux.h>#include <vlc_vout.h>                                     /* vout_InitFormat *//***************************************************************************** * Module descriptor *****************************************************************************/static int  Open ( vlc_object_t * );static void Close( vlc_object_t * );#define FPS_TEXT N_("Frames per Second")#define FPS_LONGTEXT N_("This is the desired frame rate when " \    "playing raw video streams.")#define WIDTH_TEXT N_("Width")#define WIDTH_LONGTEXT N_("This specifies the width in pixels of the raw " \    "video stream.")#define HEIGHT_TEXT N_("Height")#define HEIGHT_LONGTEXT N_("This specifies the height in pixels of the raw " \    "video stream.")#define CHROMA_TEXT N_("Force chroma (Use carefully)")#define CHROMA_LONGTEXT N_("Force chroma. This is a four character string.")#define ASPECT_RATIO_TEXT N_("Aspect ratio")#define ASPECT_RATIO_LONGTEXT N_( \    "Aspect ratio (4:3, 16:9). Default is square pixels." )vlc_module_begin();    set_shortname( "Raw Video" );    set_description( N_("Raw video demuxer") );    set_capability( "demux", 10 );    set_category( CAT_INPUT );    set_subcategory( SUBCAT_INPUT_DEMUX );    set_callbacks( Open, Close );    add_shortcut( "rawvideo" );    add_float( "rawvid-fps", 0, 0, FPS_TEXT, FPS_LONGTEXT, false );    add_integer( "rawvid-width", 0, 0, WIDTH_TEXT, WIDTH_LONGTEXT, 0 );    add_integer( "rawvid-height", 0, 0, HEIGHT_TEXT, HEIGHT_LONGTEXT, 0 );    add_string( "rawvid-chroma", NULL, NULL, CHROMA_TEXT, CHROMA_LONGTEXT,                true );    add_string( "rawvid-aspect-ratio", NULL, NULL,                ASPECT_RATIO_TEXT, ASPECT_RATIO_LONGTEXT, true );vlc_module_end();/***************************************************************************** * Definitions of structures used by this plugin *****************************************************************************/struct demux_sys_t{    int    frame_size;    float  f_fps;    es_out_id_t *p_es_video;    es_format_t  fmt_video;    mtime_t i_pcr;    bool b_y4m;};/***************************************************************************** * Local prototypes *****************************************************************************/static int Demux( demux_t * );static int Control( demux_t *, int i_query, va_list args );struct preset_t{    const char *psz_ext;    int i_width;    int i_height;    double f_fps;    const char *psz_aspect_ratio;    const char *psz_chroma;};static const struct preset_t p_presets[] ={    { "sqcif", 128, 96, 29.97, "4:3", "YV12" },    { "qcif", 176, 144, 29.97, "4:3", "YV12" },    { "cif", 352, 288, 29.97, "4:3", "YV12" },    { "4cif", 704, 576, 29.97, "4:3", "YV12" },    { "16cif", 1408, 1152, 29.97, "4:3", "YV12" },    { "yuv", 176, 144, 25, "4:3", "YV12" },    { "", 0, 0, 0., "", "" }};/***************************************************************************** * Open: initializes raw DV demux structures *****************************************************************************/static int Open( vlc_object_t * p_this ){    demux_t     *p_demux = (demux_t*)p_this;    demux_sys_t *p_sys;    int i_width, i_height;    char *psz_ext;    char *psz_chroma;    uint32_t i_chroma;    char *psz_aspect_ratio;    unsigned int i_aspect = 0;    const struct preset_t *p_preset = NULL;    const uint8_t *p_peek;    bool b_valid = false;    bool b_y4m = false;    if( stream_Peek( p_demux->s, &p_peek, 9 ) == 9 )    {        /* http://wiki.multimedia.cx/index.php?title=YUV4MPEG2 */        if( !strncmp( (char *)p_peek, "YUV4MPEG2", 9 ) )        {            b_valid = true;            b_y4m = true;        }    }    psz_ext = strrchr( p_demux->psz_path, '.' );    if( psz_ext )    {        psz_ext++;        for( p_preset = p_presets; *p_preset->psz_ext; p_preset++ )            if( !strcasecmp( psz_ext, p_preset->psz_ext ) )            {                b_valid = true;                break;            }    }    if( !b_valid && !p_demux->b_force )        return VLC_EGENERIC;    /* Set p_input field */    p_demux->pf_demux   = Demux;    p_demux->pf_control = Control;    p_demux->p_sys      = p_sys = malloc( sizeof( demux_sys_t ) );    if( !p_sys )        return VLC_ENOMEM;    p_sys->i_pcr = 1;    p_sys->b_y4m = b_y4m;    p_sys->f_fps = var_CreateGetFloat( p_demux, "rawvid-fps" );    i_width = var_CreateGetInteger( p_demux, "rawvid-width" );    i_height = var_CreateGetInteger( p_demux, "rawvid-height" );    psz_chroma = var_CreateGetString( p_demux, "rawvid-chroma" );    psz_aspect_ratio = var_CreateGetString( p_demux, "rawvid-aspect-ratio" );    if( b_y4m )    {        char *psz;        char *buf;        int a = 1;        int b = 1;        psz = stream_ReadLine( p_demux->s );        /* TODO: handle interlacing */#define READ_FRAC( key, num, den ) \        buf = strstr( psz+9, key );\        if( buf )\        {\            char *end = strchr( buf+1, ' ' );\            char *sep;\            if( end ) *end = '\0';\            sep = strchr( buf+1, ':' );\            if( sep )\            {\                *sep = '\0';\                den = atoi( sep+1 );\            }\            else\            {\                den = 1;\            }\            num = atoi( buf+2 );\            if( sep ) *sep = ':';\            if( end ) *end = ' ';\        }        READ_FRAC( " W", i_width, a )        READ_FRAC( " H", i_height, a )        READ_FRAC( " F", a, b )        p_sys->f_fps = (double)a/(double)b;        READ_FRAC( " A", a, b )        if( b != 0 ) i_aspect = a * VOUT_ASPECT_FACTOR / b;        buf = strstr( psz+9, " C" );        if( buf )        {            char *end = strchr( buf+1, ' ' );            if( end ) *end = '\0';            buf+=2;            if( !strncmp( buf, "420jpeg", 7 ) )            {                psz_chroma = strdup( "I420" );            }            else if( !strncmp( buf, "420paldv", 8 ) )            {                psz_chroma = strdup( "I420" );            }            else if( !strncmp( buf, "420", 3 ) )            {                psz_chroma = strdup( "I420" );            }            else if( !strncmp( buf, "422", 3 ) )            {                psz_chroma = strdup( "I422" );            }            else if( !strncmp( buf, "444", 3 ) )            {                psz_chroma = strdup( "I444" );            }            else if( !strncmp( buf, "mono", 4 ) )            {                psz_chroma = strdup( "GREY" );            }            else            {                msg_Warn( p_demux, "Unknown YUV4MPEG2 chroma type \"%s\"",                          buf );            }            if( end ) *end = ' ';        }        free( psz );    }    if( p_preset && *p_preset->psz_ext )    {        if( !i_width ) i_width = p_preset->i_width;        if( !i_height ) i_height = p_preset->i_height;        if( !p_sys->f_fps ) p_sys->f_fps = p_preset->f_fps;        if( !*psz_aspect_ratio )        {            free( psz_aspect_ratio );            psz_aspect_ratio = strdup( psz_aspect_ratio );        }        if( !*psz_chroma )        {            free( psz_chroma );            psz_chroma = strdup( psz_chroma );        }    }    if( i_width <= 0 || i_height <= 0 )    {        msg_Err( p_demux, "width and height must be strictly positive." );        free( psz_aspect_ratio );        free( psz_chroma );        free( p_sys );        return VLC_EGENERIC;    }    if( !i_aspect )    {        if( psz_aspect_ratio && *psz_aspect_ratio )        {            char *psz_parser = strchr( psz_aspect_ratio, ':' );            if( psz_parser )            {                *psz_parser++ = '\0';                i_aspect = atoi( psz_aspect_ratio ) * VOUT_ASPECT_FACTOR                           / atoi( psz_parser );            }            else            {                i_aspect = atof( psz_aspect_ratio ) * VOUT_ASPECT_FACTOR;            }        }        else        {            i_aspect = i_width * VOUT_ASPECT_FACTOR / i_height;        }    }    free( psz_aspect_ratio );    if( psz_chroma && strlen( psz_chroma ) >= 4 )    {        memcpy( &i_chroma, psz_chroma, 4 );        msg_Dbg( p_demux, "Forcing chroma to 0x%.8x (%4.4s)", i_chroma,                 (char*)&i_chroma );    }    else    {        i_chroma = VLC_FOURCC('Y','V','1','2');        msg_Dbg( p_demux, "Using default chroma 0x%.8x (%4.4s)", i_chroma,                 (char*)&i_chroma );    }    free( psz_chroma );    es_format_Init( &p_sys->fmt_video, VIDEO_ES, i_chroma );    vout_InitFormat( &p_sys->fmt_video.video, i_chroma, i_width, i_height,                     i_aspect );    if( !p_sys->fmt_video.video.i_bits_per_pixel )    {        msg_Err( p_demux, "Unsupported chroma 0x%.8x (%4.4s)", i_chroma,                 (char*)&i_chroma );        free( p_sys );        return VLC_EGENERIC;    }    p_sys->frame_size = i_width * i_height                        * p_sys->fmt_video.video.i_bits_per_pixel / 8;    p_sys->p_es_video = es_out_Add( p_demux->out, &p_sys->fmt_video );    return VLC_SUCCESS;}/***************************************************************************** * 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;    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;    block_t     *p_block;    /* Call the pace control */    es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pcr );    if( p_sys->b_y4m )    {        /* Skip the frame header */        unsigned char psz_buf[10];        psz_buf[9] = '\0';        stream_Read( p_demux->s, psz_buf, strlen( "FRAME" ) );        while( psz_buf[0] != 0x0a )        {            if( stream_Read( p_demux->s, psz_buf, 1 ) < 1 )                return 0;        }    }    if( ( p_block = stream_Block( p_demux->s, p_sys->frame_size ) ) == NULL )    {        /* EOF */        return 0;    }    p_block->i_dts = p_block->i_pts = p_sys->i_pcr;    es_out_Send( p_demux->out, p_sys->p_es_video, p_block );    p_sys->i_pcr += ( INT64_C(1000000) / p_sys->f_fps );    return 1;}/***************************************************************************** * Control: *****************************************************************************/static int Control( demux_t *p_demux, int i_query, va_list args ){    demux_sys_t *p_sys  = p_demux->p_sys;    /* XXX: DEMUX_SET_TIME is precise here */    return demux_vaControlHelper( p_demux->s, 0, -1,                                   p_sys->frame_size * p_sys->f_fps * 8,                                   p_sys->frame_size, i_query, args );}

⌨️ 快捷键说明

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