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

📄 encoder.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************** * encoder.c: video and audio encoder using the ffmpeg library ***************************************************************************** * Copyright (C) 1999-2004 VideoLAN * $Id: encoder.c 11321 2005-06-06 17:11:25Z gbazin $ * * Authors: Laurent Aimar <fenrir@via.ecp.fr> *          Gildas Bazin <gbazin@videolan.org> *          Christophe Massiot <massiot@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/vout.h>#include <vlc/aout.h>#include <vlc/sout.h>#include <vlc/decoder.h>/* ffmpeg header */#define HAVE_MMX#ifdef HAVE_FFMPEG_AVCODEC_H#   include <ffmpeg/avcodec.h>#else#   include <avcodec.h>#endif#if LIBAVCODEC_BUILD < 4704#   define AV_NOPTS_VALUE 0#endif#if LIBAVCODEC_BUILD < 4684#    define FF_QP2LAMBDA 118#endif#include "ffmpeg.h"#define AVCODEC_MAX_VIDEO_FRAME_SIZE (3*1024*1024)#define HURRY_UP_GUARD1 (450000)#define HURRY_UP_GUARD2 (300000)#define HURRY_UP_GUARD3 (100000)#define MAX_FRAME_DELAY (FF_MAX_B_FRAMES + 2)/***************************************************************************** * Local prototypes *****************************************************************************/int  E_(OpenEncoder) ( vlc_object_t * );void E_(CloseEncoder)( vlc_object_t * );static block_t *EncodeVideo( encoder_t *, picture_t * );static block_t *EncodeAudio( encoder_t *, aout_buffer_t * );struct thread_context_t;static int FfmpegThread( struct thread_context_t *p_context );static int FfmpegExecute( AVCodecContext *s,                          int (*pf_func)(AVCodecContext *c2, void *arg2),                          void **arg, int *ret, int count );/***************************************************************************** * thread_context_t : for multithreaded encoding *****************************************************************************/#if LIBAVCODEC_BUILD >= 4702struct thread_context_t{    VLC_COMMON_MEMBERS    AVCodecContext  *p_context;    int             (* pf_func)(AVCodecContext *c, void *arg);    void            *arg;    int             i_ret;    vlc_mutex_t     lock;    vlc_cond_t      cond;    vlc_bool_t      b_work, b_done;};#endif/***************************************************************************** * encoder_sys_t : ffmpeg encoder descriptor *****************************************************************************/struct encoder_sys_t{    /*     * Ffmpeg properties     */    AVCodec         *p_codec;    AVCodecContext  *p_context;    /*     * Common properties     */    char *p_buffer;    char *p_buffer_out;    /*     * Video properties     */    mtime_t i_last_ref_pts;    mtime_t i_buggy_pts_detect;    mtime_t i_last_pts;    vlc_bool_t b_inited;    /*     * Audio properties     */    int i_frame_size;    int i_samples_delay;    mtime_t i_pts;    /* Encoding settings */    int        i_key_int;    int        i_b_frames;    int        i_vtolerance;    int        i_qmin;    int        i_qmax;    int        i_hq;    vlc_bool_t b_strict_rc;    int        i_rc_buffer_size;    float      f_rc_buffer_aggressivity;    vlc_bool_t b_pre_me;    vlc_bool_t b_hurry_up;    vlc_bool_t b_interlace;    float      f_i_quant_factor;    int        i_noise_reduction;    vlc_bool_t b_mpeg4_matrix;    vlc_bool_t b_trellis;    int        i_quality; /* for VBR */    /* Used to work around stupid timestamping behaviour in libavcodec */    uint64_t i_framenum;    mtime_t  pi_delay_pts[MAX_FRAME_DELAY];};static const char *ppsz_enc_options[] = {    "keyint", "bframes", "vt", "qmin", "qmax", "hq", "strict-rc",    "rc-buffer-size", "rc-buffer-aggressivity", "pre-me", "hurry-up",    "interlace", "i-quant-factor", "noise-reduction", "mpeg4-matrix",    "trellis", "qscale", "strict", NULL};/***************************************************************************** * OpenEncoder: probe the encoder *****************************************************************************/extern int16_t IMPORT_SYMBOL ff_mpeg4_default_intra_matrix[];extern int16_t IMPORT_SYMBOL ff_mpeg4_default_non_intra_matrix[];int E_(OpenEncoder)( vlc_object_t *p_this ){    encoder_t *p_enc = (encoder_t *)p_this;    encoder_sys_t *p_sys = p_enc->p_sys;    AVCodecContext *p_context;    AVCodec *p_codec;    int i_codec_id, i_cat;    char *psz_namecodec;    vlc_value_t val;    if( !E_(GetFfmpegCodec)( p_enc->fmt_out.i_codec, &i_cat, &i_codec_id,                             &psz_namecodec ) )    {        if( E_(GetFfmpegChroma)( p_enc->fmt_out.i_codec ) < 0 )        {            /* handed chroma output */            return VLC_EGENERIC;        }        i_cat      = VIDEO_ES;        i_codec_id = CODEC_ID_RAWVIDEO;        psz_namecodec = "Raw video";    }    if( p_enc->fmt_out.i_cat == VIDEO_ES && i_cat != VIDEO_ES )    {        msg_Err( p_enc, "\"%s\" is not a video encoder", psz_namecodec );        return VLC_EGENERIC;    }    if( p_enc->fmt_out.i_cat == AUDIO_ES && i_cat != AUDIO_ES )    {        msg_Err( p_enc, "\"%s\" is not an audio encoder", psz_namecodec );        return VLC_EGENERIC;    }    /* Initialization must be done before avcodec_find_decoder() */    E_(InitLibavcodec)(p_this);    p_codec = avcodec_find_encoder( i_codec_id );    if( !p_codec )    {        msg_Err( p_enc, "cannot find encoder %s", psz_namecodec );        return VLC_EGENERIC;    }    /* Allocate the memory needed to store the decoder's structure */    if( ( p_sys = (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )    {        msg_Err( p_enc, "out of memory" );        return VLC_EGENERIC;    }    memset( p_sys, 0, sizeof(encoder_sys_t) );    p_enc->p_sys = p_sys;    p_sys->p_codec = p_codec;    p_enc->pf_encode_video = EncodeVideo;    p_enc->pf_encode_audio = EncodeAudio;    p_sys->p_buffer_out = NULL;    p_sys->p_buffer = NULL;    p_sys->p_context = p_context = avcodec_alloc_context();    /* Set CPU capabilities */    p_context->dsp_mask = 0;    if( !(p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_MMX) )    {        p_context->dsp_mask |= FF_MM_MMX;    }    if( !(p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_MMXEXT) )    {        p_context->dsp_mask |= FF_MM_MMXEXT;    }    if( !(p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_3DNOW) )    {        p_context->dsp_mask |= FF_MM_3DNOW;    }    if( !(p_enc->p_libvlc->i_cpu & CPU_CAPABILITY_SSE) )    {        p_context->dsp_mask |= FF_MM_SSE;        p_context->dsp_mask |= FF_MM_SSE2;    }    sout_CfgParse( p_enc, ENC_CFG_PREFIX, ppsz_enc_options, p_enc->p_cfg );    var_Get( p_enc, ENC_CFG_PREFIX "keyint", &val );    p_sys->i_key_int = val.i_int;    var_Get( p_enc, ENC_CFG_PREFIX "bframes", &val );    p_sys->i_b_frames = val.i_int;    var_Get( p_enc, ENC_CFG_PREFIX "vt", &val );    p_sys->i_vtolerance = val.i_int;    var_Get( p_enc, ENC_CFG_PREFIX "interlace", &val );    p_sys->b_interlace = val.b_bool;    var_Get( p_enc, ENC_CFG_PREFIX "pre-me", &val );    p_sys->b_pre_me = val.b_bool;    var_Get( p_enc, ENC_CFG_PREFIX "hurry-up", &val );    p_sys->b_hurry_up = val.b_bool;    if( p_sys->b_hurry_up )    {        /* hurry up mode needs noise reduction, even small */        p_sys->i_noise_reduction = 1;    }    var_Get( p_enc, ENC_CFG_PREFIX "strict-rc", &val );    p_sys->b_strict_rc = val.b_bool;    var_Get( p_enc, ENC_CFG_PREFIX "rc-buffer-size", &val );    p_sys->i_rc_buffer_size = val.i_int;    var_Get( p_enc, ENC_CFG_PREFIX "rc-buffer-aggressivity", &val );    p_sys->f_rc_buffer_aggressivity = val.f_float;    var_Get( p_enc, ENC_CFG_PREFIX "i-quant-factor", &val );    p_sys->f_i_quant_factor = val.f_float;    var_Get( p_enc, ENC_CFG_PREFIX "noise-reduction", &val );    p_sys->i_noise_reduction = val.i_int;    var_Get( p_enc, ENC_CFG_PREFIX "mpeg4-matrix", &val );    p_sys->b_mpeg4_matrix = val.b_bool;    var_Get( p_enc, ENC_CFG_PREFIX "qscale", &val );    if( val.f_float < 0.01 || val.f_float > 255.0 ) val.f_float = 0;    p_sys->i_quality = (int)(FF_QP2LAMBDA * val.f_float + 0.5);    var_Get( p_enc, ENC_CFG_PREFIX "hq", &val );    if( val.psz_string && *val.psz_string )    {        if( !strcmp( val.psz_string, "rd" ) )            p_sys->i_hq = FF_MB_DECISION_RD;        else if( !strcmp( val.psz_string, "bits" ) )            p_sys->i_hq = FF_MB_DECISION_BITS;        else if( !strcmp( val.psz_string, "simple" ) )            p_sys->i_hq = FF_MB_DECISION_SIMPLE;        else            p_sys->i_hq = FF_MB_DECISION_RD;    }    if( val.psz_string ) free( val.psz_string );    var_Get( p_enc, ENC_CFG_PREFIX "qmin", &val );    p_sys->i_qmin = val.i_int;    var_Get( p_enc, ENC_CFG_PREFIX "qmax", &val );    p_sys->i_qmax = val.i_int;    var_Get( p_enc, ENC_CFG_PREFIX "trellis", &val );    p_sys->b_trellis = val.b_bool;    var_Get( p_enc, ENC_CFG_PREFIX "strict", &val );

⌨️ 快捷键说明

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