Commit 412d64b1 authored by Laurent Aimar's avatar Laurent Aimar
Browse files

* added file needed for video transcoding with vlc.

parent 6ea48839
/*****************************************************************************
* encoder.h :
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: encoder.h,v 1.1 2003/01/22 10:41:57 fenrir Exp $
*
* 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.
*****************************************************************************/
#ifndef _ENCODER_H
#define _ENCODER_H
typedef struct encoder_sys_t encoder_sys_t;
typedef struct video_encoder_s
{
VLC_COMMON_MEMBERS
module_t * p_module;
vlc_fourcc_t i_codec; /* in */
vlc_fourcc_t i_chroma; /* in/out */
int i_width; /* in/out */
int i_height; /* in/out */
int i_aspect; /* in/out */
size_t i_buffer_size; /* in/out */
encoder_sys_t *p_sys;
int (*pf_init) ( struct video_encoder_s *p_enc );
int (*pf_encode) ( struct video_encoder_s *p_enc, picture_t *p_pic, void *p_data, size_t *pi_data );
void (*pf_end) ( struct video_encoder_s *p_enc );
} video_encoder_t;
/*
* Video decoder:
*
* = at loading a video decoder must
* * see if i_codec is supporte, if not => failling
* * modify i_width/i_height/i_chroma/i_aspect if required (for example,
* if a video codec required %8 size)
* * init/check the library
* * set pf_init, pf_encode and pf_end
* * set i_buffer_size to the max buffer size required to output a single frame
*
* = pf_init must
* * start encoding processing
* * doesn't change any parameters (i_chroma/i_width/i_height/i_aspect)
* * check for passed parameters (no one for the moment)
*
* = pf_encode must
* * encode a single frame
* * doesn't change any parameters (...)
* * doesn't look for passed paramters
*
* = pf_end must
* * end the encoding process
* * revert all that pf_init (and pf_encode) has done (memory...)
*
* = at unloading, a video decoder must revert all that was done while loading
*
* XXX: pf_init/pf_end could be called multiple time without the plugin unloaded.
* XXX: all memory allocated by video encoder MUST be unallocated by video encoder
*
*/
#endif
SOURCES_encoder_xvid = modules/encoder/xvid.c
SOURCES_encoder_ffmpeg = \
modules/encoder/ffmpeg/encoder.c \
modules/encoder/ffmpeg/video.c \
modules/encoder/ffmpeg/audio.c \
$(NULL)
/*****************************************************************************
* audio.c : audio encoder using ffmpeg library
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: audio.c,v 1.1 2003/01/22 10:41:57 fenrir Exp $
*
* Authors: Laurent Aimar
*
* 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/input.h>
#include <vlc/decoder.h>
#include <stdlib.h>
#include "codecs.h"
#include <avcodec.h>
/*****************************************************************************
* Local prototypes
*****************************************************************************/
int E_( OpenEncoderAudio ) ( vlc_object_t * );
void E_( CloseEncoderAudio )( vlc_object_t * );
struct encoder_sys_t
{
void *audio_handle;
};
int E_( OpenEncoderAudio ) ( vlc_object_t *p_this )
{
return VLC_EGENERIC;
}
void E_( CloseEncoderAudio )( vlc_object_t *p_this )
{
;
}
/*****************************************************************************
* encoder.c : audio/video encoder using ffmpeg library
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: encoder.c,v 1.1 2003/01/22 10:41:57 fenrir Exp $
*
* Authors: Laurent Aimar
*
* 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/input.h>
#include <vlc/decoder.h>
#include <stdlib.h>
#include "codecs.h"
#include "encoder.h"
/*****************************************************************************
* Local prototypes
*****************************************************************************/
int E_( OpenEncoderVideo )( vlc_object_t * );
void E_( CloseEncoderVideo )( vlc_object_t * );
int E_( OpenEncoderAudio ) ( vlc_object_t * );
void E_( CloseEncoderAudio )( vlc_object_t * );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
set_description( _("ffmpeg encoder") );
add_shortcut( "ffmpeg" );
add_submodule();
set_capability( "video encoder", 100 );
set_callbacks( E_( OpenEncoderVideo ), E_( CloseEncoderVideo ) );
add_category_hint( "video setting", NULL );
add_integer( "encoder-ffmpeg-video-bitrate", 1000, NULL, "bitrate (kb/s)", "bitrate (kb/s)" );
add_integer( "encoder-ffmpeg-video-max-key-interval", 10, NULL, "max key interval", "maximum value of frames between two keyframes" );
add_integer( "encoder-ffmpeg-min-quantizer", 2, NULL, "min quantizer", "range 1-31" );
add_integer( "encoder-ffmpeg-max-quantizer", 31, NULL, "max quantizer", "range 1-31" );
add_submodule();
set_capability( "audio encoder", 50 );
set_callbacks( E_( OpenEncoderAudio ), E_( CloseEncoderAudio ) );
add_category_hint( "audio setting", NULL );
add_integer( "encoder-ffmpeg-audio-bitrate", 64, NULL, "bitrate (kb/s)", "bitrate (kb/s)" );
vlc_module_end();
#if 0
add_category_hint( "general setting", NULL );
add_integer( "encoder-xvid-bitrate", 1000, NULL, "bitrate (kb/s)", "bitrate (kb/s)" );
add_integer( "encoder-xvid-min-quantizer", 2, NULL, "min quantizer", "range 1-31" );
add_integer( "encoder-xvid-max-quantizer", 31, NULL, "max quantizer", "1-31" );
add_category_hint( "advanced setting", NULL );
add_integer( "encoder-xvid-reaction-delay-factor", -1, NULL, "rc reaction delay factor", "rate controler parameters");
add_integer( "encoder-xvid-averaging-period", -1, NULL, "rc averaging period", "rate controler parameters" );
add_integer( "encoder-xvid-buffer", -1, NULL, "rc buffer", "rate controler parameters" );
add_category_hint( "advanced frame setting", NULL );
add_string_from_list( "encoder-xvid-quantization", "MPEG", ppsz_xvid_quant_algo, NULL, "quantization algorithm", "" );
add_bool( "encoder-xvid-halfpel", 1, NULL, "half pixel motion estimation.", "" );
add_bool( "encoder-xvid-4mv", 0, NULL, "fourc vector per macroblock(need halfpel)", "" );
add_bool( "encoder-xvid-lumi-mask", 0, NULL, "use a lumimasking algorithm", "" );
add_bool( "encoder-xvid-adaptive-quant", 0, NULL, "perform an adaptative quantization", "" );
add_bool( "encoder-xvid-interlacing", 0, NULL, "use MPEG4 interlaced mode", "" );
add_string_from_list( "encoder-xvid-me", "", ppsz_xvid_me, NULL, "motion estimation", "" );
add_bool( "encoder-xvid-motion-advanceddiamond", 1, NULL, "motion advanceddiamond", "" );
add_bool( "encoder-xvid-motion-halfpeldiamond", 1, NULL, "motion halfpel diamond", "" );
add_bool( "encoder-xvid-motion-halfpelrefine", 1, NULL, "motion halfpelrefine", "" );
add_bool( "encoder-xvid-motion-extsearch", 1, NULL, "motion extsearch", "" );
add_bool( "encoder-xvid-motion-earlystop", 1, NULL, "motion earlystop", "" );
add_bool( "encoder-xvid-motion-quickstop", 1, NULL, "motion quickstop", "" );
add_bool( "encoder-xvid-motion-usesquares", 0, NULL, "use a square search", "" );
vlc_module_end();
#endif
/*****************************************************************************
* video.c : video encoder using ffmpeg library
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: video.c,v 1.1 2003/01/22 10:41:57 fenrir Exp $
*
* Authors: Laurent Aimar
*
* 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/input.h>
#include <vlc/decoder.h>
#include <stdlib.h>
#include "codecs.h"
#include "encoder.h"
#include <avcodec.h>
int E_( OpenEncoderVideo ) ( vlc_object_t * );
void E_( CloseEncoderVideo )( vlc_object_t * );
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int Init ( video_encoder_t *p_encoder );
static int Encode ( video_encoder_t *p_encoder,
picture_t *p_pic, void *p_data, size_t *pi_data );
static void End ( video_encoder_t *p_encoder );
/*****************************************************************************
* Local definitions
*****************************************************************************/
struct encoder_sys_t
{
char *psz_codec;
AVCodecContext *p_context;
AVCodec *p_codec;
AVFrame *p_frame;
};
/*****************************************************************************
* OpenEncoderVideo:
*****************************************************************************
*
*****************************************************************************/
int E_( OpenEncoderVideo ) ( vlc_object_t *p_this )
{
video_encoder_t *p_encoder = (video_encoder_t*)p_this;
/* *** check supported codec *** */
switch( p_encoder->i_codec )
{
case VLC_FOURCC( 'm', 'p', '1', 'v' ):
case VLC_FOURCC( 'm', 'p', 'g', 'v' ):
case VLC_FOURCC( 'm', 'p', '4', 'v' ):
break;
default:
return VLC_EGENERIC;
}
/* *** init library */
avcodec_init();
avcodec_register_all();
/* *** fix parameters *** */
/* FIXME be clever, some codec support additional chroma */
if( p_encoder->i_chroma != VLC_FOURCC( 'I', '4', '2', '0' ) )
{
p_encoder->i_chroma = VLC_FOURCC( 'I', '4', '2', '0' );
}
#if 0
p_encoder->i_width = ( p_encoder->i_width + 15 )&0xfffff8;
p_encoder->i_height = ( p_encoder->i_height + 15 )&0xfffff8;
#endif
/* *** set exported functions *** */
p_encoder->pf_init = Init;
p_encoder->pf_encode = Encode;
p_encoder->pf_end = End;
return VLC_SUCCESS;
}
/*****************************************************************************
* CloseEncoderVideo:
*****************************************************************************
*
*****************************************************************************/
void E_( CloseEncoderVideo )( vlc_object_t *p_this )
{
;
}
/*****************************************************************************
* Init:
*****************************************************************************
*
*****************************************************************************/
static int Init ( video_encoder_t *p_encoder )
{
encoder_sys_t *p_sys;
char *psz_codec;
int i_codec;
/* *** allocate memory *** */
if( !( p_encoder->p_sys = p_sys = malloc( sizeof( encoder_sys_t ) ) ) )
{
msg_Err( p_encoder, "out of memory" );
return VLC_EGENERIC;
}
memset( p_sys, 0, sizeof( encoder_sys_t ) );
/* *** ask for the codec *** */
switch( p_encoder->i_codec )
{
case VLC_FOURCC( 'm', 'p', '1', 'v' ):
case VLC_FOURCC( 'm', 'p', 'g', 'v' ):
psz_codec = "MPEG I";
i_codec = CODEC_ID_MPEG1VIDEO;
break;
case VLC_FOURCC( 'm', 'p', '4', 'v' ):
psz_codec = "MPEG-4";
i_codec = CODEC_ID_MPEG4;
break;
default:
return VLC_EGENERIC;
}
if( ( p_sys->p_codec = avcodec_find_encoder( i_codec ) ) == NULL )
{
msg_Err( p_encoder, "cannot find encoder for %s", p_encoder->p_sys->psz_codec );
return VLC_EGENERIC;
}
msg_Dbg( p_encoder, "encoding with %s", p_encoder->p_sys->psz_codec );
#define p_frame p_sys->p_frame
#define p_context p_sys->p_context
/* *** set context properties *** */
p_context = avcodec_alloc_context();
p_context->bit_rate = config_GetInt( p_encoder, "encoder-ffmpeg-video-bitrate" ) * 1000;
p_context->width = p_encoder->i_width;
p_context->height= p_encoder->i_height;
p_context->frame_rate = 25 * FRAME_RATE_BASE;
p_context->gop_size = config_GetInt( p_encoder, "encoder-ffmpeg-video-max-key-interval" );
p_context->qmin = __MAX( __MIN( config_GetInt( p_encoder, "encoder-ffmpeg-video-min-quant" ), 31 ), 1 );
p_context->qmax = __MAX( __MIN( config_GetInt( p_encoder, "encoder-ffmpeg-video-max-quant" ), 31 ), 1 );
if( avcodec_open( p_context, p_encoder->p_sys->p_codec ) < 0 )
{
msg_Err( p_encoder, "failed to open %s codec", p_encoder->p_sys->psz_codec );
return VLC_EGENERIC;
}
p_frame = avcodec_alloc_frame();
switch( p_encoder->i_chroma )
{
case VLC_FOURCC( 'I', '4', '2', '0' ):
p_frame->pict_type = PIX_FMT_YUV420P;
break;
default:
return VLC_EGENERIC;
}
return VLC_SUCCESS;
#undef p_context
#undef p_frame
}
/*****************************************************************************
* Encode:
*****************************************************************************
*
*****************************************************************************/
static int Encode ( video_encoder_t *p_encoder,
picture_t *p_pic, void *p_data, size_t *pi_data )
{
#define p_frame p_encoder->p_sys->p_frame
#define p_context p_encoder->p_sys->p_context
int i;
for( i = 0; i < 3; i++ )
{
p_frame->linesize[i] = p_pic->p[i].i_pitch;
p_frame->data[i] = p_pic->p[i].p_pixels;
}
*pi_data = avcodec_encode_video( p_context, p_data, *pi_data, p_frame );
return VLC_SUCCESS;
#undef p_context
#undef p_frame
}
/*****************************************************************************
* End:
*****************************************************************************
*
*****************************************************************************/
static void End ( video_encoder_t *p_encoder )
{
avcodec_close( p_encoder->p_sys->p_context );
free( p_encoder->p_sys->p_context );
p_encoder->p_sys->p_context = NULL;
p_encoder->p_sys->p_codec = NULL;
}
/*****************************************************************************
* xvid.c: an encoder for libxvidcore, the Xvid video codec
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: xvid.c,v 1.1 2003/01/22 10:41:57 fenrir Exp $
*
* Authors: Laurent Aimar
*
* 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/input.h>
#include <vlc/decoder.h>
#include <stdlib.h>
#include "codecs.h"
#include "encoder.h"
#include <xvid.h>
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int OpenEncoder ( vlc_object_t * );
static void CloseEncoder ( vlc_object_t * );
static int Init ( video_encoder_t *p_encoder );
static int Encode ( video_encoder_t *p_encoder,
picture_t *p_pic, void *p_data, size_t *pi_data );
static void End ( video_encoder_t *p_encoder );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
static char * ppsz_xvid_quant_algo[] = { "MPEG", "H263",NULL };
static char * ppsz_xvid_me[] = { "", "zero", "logarithmic", "fullsearch", "pmvfast", "epzs", NULL };
vlc_module_begin();
set_description( _("XviD video encoder (MPEG-4)") );
set_capability( "video encoder", 50 );
set_callbacks( OpenEncoder, CloseEncoder );
add_shortcut( "xvid" );
add_category_hint( "general setting", NULL );
add_integer( "encoder-xvid-bitrate", 1000, NULL, "bitrate (kb/s)", "bitrate (kb/s)" );
add_integer( "encoder-xvid-min-quantizer", 2, NULL, "min quantizer", "range 1-31" );
add_integer( "encoder-xvid-max-quantizer", 31, NULL, "max quantizer", "1-31" );
add_integer( "encoder-xvid-max-key-interval", -1, NULL, "max key interval", "maximum value of frames between two keyframes" );
add_category_hint( "advanced setting", NULL );
add_integer( "encoder-xvid-reaction-delay-factor", -1, NULL, "rc reaction delay factor", "rate controler parameters");
add_integer( "encoder-xvid-averaging-period", -1, NULL, "rc averaging period", "rate controler parameters" );
add_integer( "encoder-xvid-buffer", -1, NULL, "rc buffer", "rate controler parameters" );
add_category_hint( "advanced frame setting", NULL );
add_string_from_list( "encoder-xvid-quantization", "MPEG", ppsz_xvid_quant_algo, NULL, "quantization algorithm", "" );
add_bool( "encoder-xvid-halfpel", 1, NULL, "half pixel motion estimation.", "" );
add_bool( "encoder-xvid-4mv", 0, NULL, "fourc vector per macroblock(need halfpel)", "" );
add_bool( "encoder-xvid-lumi-mask", 0, NULL, "use a lumimasking algorithm", "" );
add_bool( "encoder-xvid-adaptive-quant", 0, NULL, "perform an adaptative quantization", "" );
add_bool( "encoder-xvid-interlacing", 0, NULL, "use MPEG4 interlaced mode", "" );
add_string_from_list( "encoder-xvid-me", "", ppsz_xvid_me, NULL, "motion estimation", "" );
add_bool( "encoder-xvid-motion-advanceddiamond", 1, NULL, "motion advanceddiamond", "" );
add_bool( "encoder-xvid-motion-halfpeldiamond", 1, NULL, "motion halfpel diamond", "" );
add_bool( "encoder-xvid-motion-halfpelrefine", 1, NULL, "motion halfpelrefine", "" );
add_bool( "encoder-xvid-motion-extsearch", 1, NULL, "motion extsearch", "" );
add_bool( "encoder-xvid-motion-earlystop", 1, NULL, "motion earlystop", "" );
add_bool( "encoder-xvid-motion-quickstop", 1, NULL, "motion quickstop", "" );
add_bool( "encoder-xvid-motion-usesquares", 0, NULL, "use a square search", "" );
vlc_module_end();
struct encoder_sys_t
{
void *handle;
XVID_ENC_FRAME xframe;
};
/*****************************************************************************
* OpenEncoder:
*****************************************************************************
* Check the library and init it
* see if it can encode to the requested codec
*****************************************************************************/
static int OpenEncoder ( vlc_object_t *p_this )
{
video_encoder_t *p_encoder = (video_encoder_t*)p_this;
XVID_INIT_PARAM xinit;
int i_err;
if( p_encoder->i_codec != VLC_FOURCC( 'm', 'p', '4', 'v' ) )
{
/* unsupported codec */
return VLC_EGENERIC;
}
msg_Dbg( p_encoder, "XviD encoder compiled for API_VERSION:0x%x", API_VERSION );
/* init the library */
xinit.cpu_flags = 0;
if( ( i_err = xvid_init( NULL, 0, &xinit, NULL ) ) != XVID_ERR_OK )
{
msg_Err( p_encoder, "cannot init xvid library (err:0x%x)", i_err );
return VLC_EGENERIC;
}
/* check API_VERSION */
if( xinit.api_version != API_VERSION )
{
msg_Err( p_encoder, "API_VERSION version mismatch (library:0x%x)", xinit.api_version );
return VLC_EGENERIC;
}
msg_Dbg( p_encoder, "XviD api_version:0x%x core_build:0x%x cpu_flags:0x%x",
xinit.api_version,
xinit.core_build,
xinit.cpu_flags );