📄 transcode.c
字号:
/***************************************************************************** * transcode.c: transcoding stream output module ***************************************************************************** * Copyright (C) 2003-2004 VideoLAN * $Id: transcode.c 11351 2005-06-08 12:07:14Z gbazin $ * * Authors: Laurent Aimar <fenrir@via.ecp.fr> * 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 *****************************************************************************/#include <stdlib.h>#include <string.h>#include <math.h>#include <vlc/vlc.h>#include <vlc/input.h>#include <vlc/sout.h>#include <vlc/vout.h>#include <vlc/decoder.h>#include "vlc_filter.h"#include "osd.h"/***************************************************************************** * Module descriptor *****************************************************************************/#define VENC_TEXT N_("Video encoder")#define VENC_LONGTEXT N_( \ "Allows you to specify the video encoder to use and its associated " \ "options." )#define VCODEC_TEXT N_("Destination video codec")#define VCODEC_LONGTEXT N_( \ "Allows you to specify the destination video codec used for the " \ "streaming output." )#define VB_TEXT N_("Video bitrate")#define VB_LONGTEXT N_( \ "Allows you to specify the video bitrate used for the streaming " \ "output." )#define SCALE_TEXT N_("Video scaling")#define SCALE_LONGTEXT N_( \ "Allows you to scale the video before encoding." )#define FPS_TEXT N_("Video frame-rate")#define FPS_LONGTEXT N_( \ "Allows you to specify an output frame rate for the video." )#define DEINTERLACE_TEXT N_("Deinterlace video")#define DEINTERLACE_LONGTEXT N_( \ "Allows you to deinterlace the video before encoding." )#define DEINTERLACE_MODULE_TEXT N_("Deinterlace module")#define DEINTERLACE_MODULE_LONGTEXT N_( \ "Specifies the deinterlace module to use (ffmpeg-deinterlace or " \ "deinterlace)." )#define WIDTH_TEXT N_("Video width")#define WIDTH_LONGTEXT N_( \ "Allows you to specify the output video width." )#define HEIGHT_TEXT N_("Video height")#define HEIGHT_LONGTEXT N_( \ "Allows you to specify the output video height." )#define CROPTOP_TEXT N_("Video crop top")#define CROPTOP_LONGTEXT N_( \ "Allows you to specify the top coordinate for the video cropping." )#define CROPLEFT_TEXT N_("Video crop left")#define CROPLEFT_LONGTEXT N_( \ "Allows you to specify the left coordinate for the video cropping." )#define CROPBOTTOM_TEXT N_("Video crop bottom")#define CROPBOTTOM_LONGTEXT N_( \ "Allows you to specify the bottom coordinate for the video cropping." )#define CROPRIGHT_TEXT N_("Video crop right")#define CROPRIGHT_LONGTEXT N_( \ "Allows you to specify the right coordinate for the video cropping." )#define AENC_TEXT N_("Audio encoder")#define AENC_LONGTEXT N_( \ "Allows you to specify the audio encoder to use and its associated " \ "options." )#define ACODEC_TEXT N_("Destination audio codec")#define ACODEC_LONGTEXT N_( \ "Allows you to specify the destination audio codec used for the " \ "streaming output." )#define AB_TEXT N_("Audio bitrate")#define AB_LONGTEXT N_( \ "Allows you to specify the audio bitrate used for the streaming " \ "output." )#define ARATE_TEXT N_("Audio sample rate")#define ARATE_LONGTEXT N_( \ "Allows you to specify the audio sample rate used for the streaming " \ "output." )#define ACHANS_TEXT N_("Audio channels")#define ACHANS_LONGTEXT N_( \ "Allows you to specify the number of audio channels used for the " \ "streaming output." )#define SENC_TEXT N_("Subtitles encoder")#define SENC_LONGTEXT N_( \ "Allows you to specify the subtitles encoder to use and its associated " \ "options." )#define SCODEC_TEXT N_("Destination subtitles codec")#define SCODEC_LONGTEXT N_( \ "Allows you to specify the destination subtitles codec used for the " \ "streaming output." )#define SFILTER_TEXT N_("Subpictures filter")#define SFILTER_LONGTEXT N_( \ "Allows you to specify subpictures filters used during the video " \ "transcoding. The subpictures produced by the filters will be overlayed " \ "directly onto the video." )#define THREADS_TEXT N_("Number of threads")#define THREADS_LONGTEXT N_( \ "Allows you to specify the number of threads used for the transcoding." )#define ASYNC_TEXT N_("Synchronise on audio track")#define ASYNC_LONGTEXT N_( \ "This option will drop/duplicate video frames to synchronise the video " \ "track on the audio track." )#define HURRYUP_TEXT N_( "Hurry up" )#define HURRYUP_LONGTEXT N_( "Allows you to specify if the transcoder " \ "should drop frames if your CPU can't keep up with the encoding rate." )static int Open ( vlc_object_t * );static void Close( vlc_object_t * );#define SOUT_CFG_PREFIX "sout-transcode-"vlc_module_begin(); set_shortname( _("Transcode")); set_description( _("Transcode stream output") ); set_capability( "sout stream", 50 ); add_shortcut( "transcode" ); set_callbacks( Open, Close ); set_category( CAT_SOUT ); set_subcategory( SUBCAT_SOUT_STREAM ); set_section( N_("Video"), NULL ); add_string( SOUT_CFG_PREFIX "venc", NULL, NULL, VENC_TEXT, VENC_LONGTEXT, VLC_FALSE ); add_string( SOUT_CFG_PREFIX "vcodec", NULL, NULL, VCODEC_TEXT, VCODEC_LONGTEXT, VLC_FALSE ); add_integer( SOUT_CFG_PREFIX "vb", 800 * 1000, NULL, VB_TEXT, VB_LONGTEXT, VLC_FALSE ); add_float( SOUT_CFG_PREFIX "scale", 1, NULL, SCALE_TEXT, SCALE_LONGTEXT, VLC_FALSE ); add_float( SOUT_CFG_PREFIX "fps", 0, NULL, FPS_TEXT, FPS_LONGTEXT, VLC_FALSE ); add_bool( SOUT_CFG_PREFIX "hurry-up", VLC_TRUE, NULL, HURRYUP_TEXT, HURRYUP_LONGTEXT, VLC_FALSE ); add_bool( SOUT_CFG_PREFIX "deinterlace", 0, NULL, DEINTERLACE_TEXT, DEINTERLACE_LONGTEXT, VLC_FALSE ); add_string( SOUT_CFG_PREFIX "deinterlace-module", "deinterlace", NULL, DEINTERLACE_MODULE_TEXT, DEINTERLACE_MODULE_LONGTEXT, VLC_FALSE ); add_integer( SOUT_CFG_PREFIX "width", 0, NULL, WIDTH_TEXT, WIDTH_LONGTEXT, VLC_TRUE ); add_integer( SOUT_CFG_PREFIX "height", 0, NULL, HEIGHT_TEXT, HEIGHT_LONGTEXT, VLC_TRUE ); add_integer( SOUT_CFG_PREFIX "croptop", 0, NULL, CROPTOP_TEXT, CROPTOP_LONGTEXT, VLC_TRUE ); add_integer( SOUT_CFG_PREFIX "cropleft", 0, NULL, CROPLEFT_TEXT, CROPLEFT_LONGTEXT, VLC_TRUE ); add_integer( SOUT_CFG_PREFIX "cropbottom", 0, NULL, CROPBOTTOM_TEXT, CROPBOTTOM_LONGTEXT, VLC_TRUE ); add_integer( SOUT_CFG_PREFIX "cropright", 0, NULL, CROPRIGHT_TEXT, CROPRIGHT_LONGTEXT, VLC_TRUE ); set_section( N_("Audio"), NULL ); add_string( SOUT_CFG_PREFIX "aenc", NULL, NULL, AENC_TEXT, AENC_LONGTEXT, VLC_FALSE ); add_string( SOUT_CFG_PREFIX "acodec", NULL, NULL, ACODEC_TEXT, ACODEC_LONGTEXT, VLC_FALSE ); add_integer( SOUT_CFG_PREFIX "ab", 64000, NULL, AB_TEXT, AB_LONGTEXT, VLC_FALSE ); add_integer( SOUT_CFG_PREFIX "channels", 0, NULL, ACHANS_TEXT, ACHANS_LONGTEXT, VLC_FALSE ); add_integer( SOUT_CFG_PREFIX "samplerate", 0, NULL, ARATE_TEXT, ARATE_LONGTEXT, VLC_TRUE ); add_bool( SOUT_CFG_PREFIX "audio-sync", 0, NULL, ASYNC_TEXT, ASYNC_LONGTEXT, VLC_FALSE ); set_section( N_("Overlays/Subtitles"), NULL ); add_string( SOUT_CFG_PREFIX "senc", NULL, NULL, SENC_TEXT, SENC_LONGTEXT, VLC_FALSE ); add_string( SOUT_CFG_PREFIX "scodec", NULL, NULL, SCODEC_TEXT, SCODEC_LONGTEXT, VLC_FALSE ); add_bool( SOUT_CFG_PREFIX "soverlay", 0, NULL, SCODEC_TEXT, SCODEC_LONGTEXT, VLC_FALSE ); add_module_list_cat( SOUT_CFG_PREFIX "sfilter", SUBCAT_VIDEO_SUBPIC, NULL, NULL, SFILTER_TEXT, SFILTER_LONGTEXT, VLC_FALSE ); set_section( N_("Miscellaneous"), NULL ); add_integer( SOUT_CFG_PREFIX "threads", 0, NULL, THREADS_TEXT, THREADS_LONGTEXT, VLC_TRUE );vlc_module_end();static const char *ppsz_sout_options[] = { "venc", "vcodec", "vb", "croptop", "cropbottom", "cropleft", "cropright", "scale", "fps", "width", "height", "deinterlace", "deinterlace-module", "threads", "hurry-up", "aenc", "acodec", "ab", "samplerate", "channels", "senc", "scodec", "soverlay", "sfilter", "audio-sync", NULL};/***************************************************************************** * Exported prototypes *****************************************************************************/static sout_stream_id_t *Add ( sout_stream_t *, es_format_t * );static int Del ( sout_stream_t *, sout_stream_id_t * );static int Send( sout_stream_t *, sout_stream_id_t *, block_t* );static int transcode_audio_new ( sout_stream_t *, sout_stream_id_t * );static void transcode_audio_close ( sout_stream_t *, sout_stream_id_t * );static int transcode_audio_process( sout_stream_t *, sout_stream_id_t *, block_t *, block_t ** );static aout_buffer_t *audio_new_buffer( decoder_t *, int );static void audio_del_buffer( decoder_t *, aout_buffer_t * );static int transcode_video_new ( sout_stream_t *, sout_stream_id_t * );static void transcode_video_close ( sout_stream_t *, sout_stream_id_t * );static int transcode_video_encoder_open( sout_stream_t *, sout_stream_id_t *);static int transcode_video_process( sout_stream_t *, sout_stream_id_t *, block_t *, block_t ** );static void video_del_buffer( vlc_object_t *, picture_t * );static picture_t *video_new_buffer_decoder( decoder_t * );static void video_del_buffer_decoder( decoder_t *, picture_t * );static void video_link_picture_decoder( decoder_t *, picture_t * );static void video_unlink_picture_decoder( decoder_t *, picture_t * );static picture_t *video_new_buffer_filter( filter_t * );static void video_del_buffer_filter( filter_t *, picture_t * );static int transcode_spu_new ( sout_stream_t *, sout_stream_id_t * );static void transcode_spu_close ( sout_stream_t *, sout_stream_id_t * );static int transcode_spu_process( sout_stream_t *, sout_stream_id_t *, block_t *, block_t ** );static int EncoderThread( struct sout_stream_sys_t * p_sys );static int pi_channels_maps[6] ={ 0, AOUT_CHAN_CENTER, AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT, AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT, AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT};#define PICTURE_RING_SIZE 64#define SUBPICTURE_RING_SIZE 20struct sout_stream_sys_t{ VLC_COMMON_MEMBERS sout_stream_t *p_out; sout_stream_id_t *id_video; block_t *p_buffers; vlc_mutex_t lock_out; vlc_cond_t cond; picture_t * pp_pics[PICTURE_RING_SIZE]; int i_first_pic, i_last_pic; /* Audio */ vlc_fourcc_t i_acodec; /* codec audio (0 if not transcode) */ char *psz_aenc; sout_cfg_t *p_audio_cfg; int i_sample_rate; int i_channels; int i_abitrate; /* Video */ vlc_fourcc_t i_vcodec; /* codec video (0 if not transcode) */ char *psz_venc; sout_cfg_t *p_video_cfg; int i_vbitrate; double f_scale; double f_fps; int i_width; int i_height; vlc_bool_t b_deinterlace; char *psz_deinterlace; sout_cfg_t *p_deinterlace_cfg; int i_threads; vlc_bool_t b_hurry_up; int i_crop_top; int i_crop_bottom; int i_crop_right; int i_crop_left; /* SPU */ vlc_fourcc_t i_scodec; /* codec spu (0 if not transcode) */ char *psz_senc; vlc_bool_t b_soverlay; sout_cfg_t *p_spu_cfg; spu_t *p_spu; /* Sync */ vlc_bool_t b_master_sync; mtime_t i_master_drift;};struct decoder_owner_sys_t{ picture_t *pp_pics[PICTURE_RING_SIZE]; sout_stream_sys_t *p_sys;};struct filter_owner_sys_t{ picture_t *pp_pics[PICTURE_RING_SIZE]; sout_stream_sys_t *p_sys;};/***************************************************************************** * Open: *****************************************************************************/static int Open( vlc_object_t *p_this ){ sout_stream_t *p_stream = (sout_stream_t*)p_this; sout_stream_sys_t *p_sys; vlc_value_t val; p_sys = vlc_object_create( p_this, sizeof( sout_stream_sys_t ) ); p_sys->p_out = sout_StreamNew( p_stream->p_sout, p_stream->psz_next ); if( !p_sys->p_out ) { msg_Err( p_stream, "cannot create chain" ); vlc_object_destroy( p_sys ); return VLC_EGENERIC; } p_sys->i_master_drift = 0; sout_CfgParse( p_stream, SOUT_CFG_PREFIX, ppsz_sout_options, p_stream->p_cfg ); /* Audio transcoding parameters */ var_Get( p_stream, SOUT_CFG_PREFIX "aenc", &val ); p_sys->psz_aenc = NULL; p_sys->p_audio_cfg = NULL; if( val.psz_string && *val.psz_string ) { char *psz_next; psz_next = sout_CfgCreate( &p_sys->psz_aenc, &p_sys->p_audio_cfg, val.psz_string ); if( psz_next ) free( psz_next ); } if( val.psz_string ) free( val.psz_string ); var_Get( p_stream, SOUT_CFG_PREFIX "acodec", &val ); p_sys->i_acodec = 0; if( val.psz_string && *val.psz_string ) { char fcc[4] = " "; memcpy( fcc, val.psz_string, __MIN( strlen( val.psz_string ), 4 ) ); p_sys->i_acodec = VLC_FOURCC( fcc[0], fcc[1], fcc[2], fcc[3] ); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -