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

📄 mux.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * mux.c: muxer using ffmpeg (libavformat). ***************************************************************************** * Copyright (C) 2006 the VideoLAN team * $Id$ * * Authors: Gildas Bazin <gbazin@videolan.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., 59 Temple Place - Suite 330, Boston, MA  02111, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include <vlc_block.h>#include <vlc_sout.h>/* ffmpeg header */#ifdef HAVE_LIBAVFORMAT_AVFORMAT_H#   include <libavformat/avformat.h>#elif defined(HAVE_FFMPEG_AVFORMAT_H)#   include <ffmpeg/avformat.h>#endif#include "avformat.h"#include "../../codec/avcodec/fourcc.h"#include "../../codec/avcodec/avutil.h"//#define AVFORMAT_DEBUG 1static const char *const ppsz_mux_options[] = {    "mux", NULL};/***************************************************************************** * mux_sys_t: mux descriptor *****************************************************************************/struct sout_mux_sys_t{    ByteIOContext   io;    int             io_buffer_size;    uint8_t        *io_buffer;    AVFormatContext *oc;    URLContext     url;    URLProtocol    prot;    bool     b_write_header;    bool     b_error;    int64_t        i_initial_dts;};/***************************************************************************** * Local prototypes *****************************************************************************/static int Control  ( sout_mux_t *, int, va_list );static int AddStream( sout_mux_t *, sout_input_t * );static int DelStream( sout_mux_t *, sout_input_t * );static int Mux      ( sout_mux_t * );static int IOWrite( void *opaque, uint8_t *buf, int buf_size );static offset_t IOSeek( void *opaque, offset_t offset, int whence );/***************************************************************************** * Open *****************************************************************************/int OpenMux( vlc_object_t *p_this ){    AVOutputFormat *file_oformat;    sout_mux_t *p_mux = (sout_mux_t*)p_this;    sout_mux_sys_t *p_sys;    AVFormatParameters params, *ap = &params;    char *psz_mux;    /* Should we call it only once ? */    av_register_all();    av_log_set_callback( LibavutilCallback );    config_ChainParse( p_mux, "ffmpeg-", ppsz_mux_options, p_mux->p_cfg );    /* Find the requested muxer */    psz_mux = var_GetNonEmptyString( p_mux, "ffmpeg-mux" );    if( psz_mux )    {        file_oformat = guess_format( psz_mux, NULL, NULL );    }    else    {        file_oformat =            guess_format(NULL, p_mux->p_access->psz_path, NULL);    }    if (!file_oformat)    {      msg_Err( p_mux, "unable for find a suitable output format" );      return VLC_EGENERIC;    }    /* Fill p_mux fields */    p_mux->pf_control   = Control;    p_mux->pf_addstream = AddStream;    p_mux->pf_delstream = DelStream;    p_mux->pf_mux       = Mux;    p_mux->p_sys = p_sys = malloc( sizeof( sout_mux_sys_t ) );    p_sys->oc = av_alloc_format_context();    p_sys->oc->oformat = file_oformat;    /* Create I/O wrapper */    p_sys->io_buffer_size = 32768;  /* FIXME */    p_sys->io_buffer = malloc( p_sys->io_buffer_size );    p_sys->url.priv_data = p_mux;    p_sys->url.prot = &p_sys->prot;    p_sys->url.prot->name = "VLC I/O wrapper";    p_sys->url.prot->url_open = 0;    p_sys->url.prot->url_read = 0;    p_sys->url.prot->url_write =                    (int (*) (URLContext *, unsigned char *, int))IOWrite;    p_sys->url.prot->url_seek =                    (offset_t (*) (URLContext *, offset_t, int))IOSeek;    p_sys->url.prot->url_close = 0;    p_sys->url.prot->next = 0;    init_put_byte( &p_sys->io, p_sys->io_buffer, p_sys->io_buffer_size,                   1, &p_sys->url, NULL, IOWrite, IOSeek );    memset( ap, 0, sizeof(*ap) );    if( av_set_parameters( p_sys->oc, ap ) < 0 )    {        msg_Err( p_mux, "invalid encoding parameters" );        av_free( p_sys->oc );        free( p_sys->io_buffer );        free( p_sys );        return VLC_EGENERIC;    }#if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(0<<8)+0)    p_sys->oc->pb = &p_sys->io;#else    p_sys->oc->pb = p_sys->io;#endif    p_sys->oc->nb_streams = 0;    p_sys->b_write_header = true;    p_sys->b_error = false;    p_sys->i_initial_dts = 0;    return VLC_SUCCESS;}/***************************************************************************** * Close *****************************************************************************/void CloseMux( vlc_object_t *p_this ){    sout_mux_t *p_mux = (sout_mux_t*)p_this;    sout_mux_sys_t *p_sys = p_mux->p_sys;    unsigned int i;    if( av_write_trailer( p_sys->oc ) < 0 )    {        msg_Err( p_mux, "could not write trailer" );    }    for( i = 0 ; i < p_sys->oc->nb_streams; i++ )    {        if( p_sys->oc->streams[i]->codec->extradata )            av_free( p_sys->oc->streams[i]->codec->extradata );        av_free( p_sys->oc->streams[i]->codec );        av_free( p_sys->oc->streams[i] );    }    av_free( p_sys->oc );    free( p_sys->io_buffer );    free( p_sys );}/***************************************************************************** * AddStream *****************************************************************************/static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input ){    sout_mux_sys_t *p_sys = p_mux->p_sys;    AVCodecContext *codec;    AVStream *stream;    int i_codec_id, i_aspect_num, i_aspect_den;    msg_Dbg( p_mux, "adding input" );    if( !GetFfmpegCodec( p_input->p_fmt->i_codec, 0, &i_codec_id, 0 ) )    {        msg_Dbg( p_mux, "couldn't find codec for fourcc '%4.4s'",                 (char *)&p_input->p_fmt->i_codec );        return VLC_EGENERIC;    }    p_input->p_sys = malloc( sizeof( int ) );    *((int *)p_input->p_sys) = p_sys->oc->nb_streams;    stream = av_new_stream( p_sys->oc, p_sys->oc->nb_streams);    if( !stream )    {        free( p_input->p_sys );        return VLC_EGENERIC;    }    codec = stream->codec;    /* This is used by LibavutilCallback (avutil.h) to print messages */    codec->opaque = (void*)p_mux;    switch( p_input->p_fmt->i_cat )    {    case AUDIO_ES:        codec->codec_type = CODEC_TYPE_AUDIO;        codec->channels = p_input->p_fmt->audio.i_channels;        codec->sample_rate = p_input->p_fmt->audio.i_rate;        codec->time_base = (AVRational){1, codec->sample_rate};        break;    case VIDEO_ES:        if( !p_input->p_fmt->video.i_frame_rate ||            !p_input->p_fmt->video.i_frame_rate_base )        {            msg_Warn( p_mux, "Missing frame rate, assuming 25fps" );            p_input->p_fmt->video.i_frame_rate = 25;            p_input->p_fmt->video.i_frame_rate_base = 1;        }        codec->codec_type = CODEC_TYPE_VIDEO;        codec->width = p_input->p_fmt->video.i_width;        codec->height = p_input->p_fmt->video.i_height;        av_reduce( &i_aspect_num, &i_aspect_den,                   p_input->p_fmt->video.i_aspect,                   VOUT_ASPECT_FACTOR, 1 << 30 /* something big */ );        av_reduce( &codec->sample_aspect_ratio.num,                   &codec->sample_aspect_ratio.den,                   i_aspect_num * (int64_t)codec->height,

⌨️ 快捷键说明

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