mirror of
https://github.com/mpv-player/mpv
synced 2024-11-18 21:16:10 +01:00
mencoder lavc audio encoding support
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@11376 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
0287286214
commit
834c6ad746
@ -3251,6 +3251,8 @@ no encoding, just streamcopy
|
||||
encode to uncompressed PCM
|
||||
.IPs "\-oac mp3lame"
|
||||
encode to MP3 (using Lame)
|
||||
.IPs "\-oac lavc"
|
||||
encode with a libavcodec codecs
|
||||
.RE
|
||||
.PD 1
|
||||
.
|
||||
@ -3529,9 +3531,30 @@ For full details read the source.
|
||||
.RE
|
||||
.PD 1
|
||||
|
||||
.TP
|
||||
.B acodec=<value>
|
||||
Audio codec (default: mp2):
|
||||
.PD 0
|
||||
.RSs
|
||||
.IPs mp2
|
||||
MPEG Layer 2
|
||||
.IPs mp3
|
||||
MPEG Layer 3
|
||||
.IPs ac3
|
||||
AC3
|
||||
.IPs adpcm_ima_wav
|
||||
IMA Adaptive PCM (4bits per sample, 4:1 compression)
|
||||
.RE
|
||||
.PD 1
|
||||
.TP
|
||||
.B abitrate=<value>
|
||||
Audio bitrate in kBit (default 224).
|
||||
.TP
|
||||
.B atag=<value>
|
||||
Use the specified windows audio format tag (e.g. atag=0x55).
|
||||
.TP
|
||||
.B vcodec=<value>
|
||||
use the specified codec (there is no default, you must specify it):
|
||||
use the specified codec (default: mpeg4):
|
||||
.PD 0
|
||||
.RSs
|
||||
.IPs mjpeg
|
||||
|
@ -107,12 +107,20 @@ m_option_t oac_conf[]={
|
||||
{"mp3lame", &out_audio_codec, CONF_TYPE_FLAG, 0, 0, ACODEC_VBRMP3, NULL},
|
||||
#else
|
||||
{"mp3lame", "MPlayer was compiled without libmp3lame support!\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
|
||||
#endif
|
||||
#ifdef USE_LIBAVCODEC
|
||||
{"lavc", &out_audio_codec, CONF_TYPE_FLAG, 0, 0, ACODEC_LAVC, NULL},
|
||||
#else
|
||||
{"lavc", "MPlayer was compiled without libavcodec! See README or DOCS!\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
|
||||
#endif
|
||||
{"help", "\nAvailable codecs:\n"
|
||||
" copy - frame copy, without re-encoding (useful for AC3)\n"
|
||||
" pcm - uncompressed PCM audio\n"
|
||||
#ifdef HAVE_MP3LAME
|
||||
" mp3lame - cbr/abr/vbr MP3 using libmp3lame\n"
|
||||
#endif
|
||||
#ifdef USE_LIBAVCODEC
|
||||
" lavc - ffmpeg audio encoder (mp2, ac3, ...)\n"
|
||||
#endif
|
||||
"\n", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0, NULL},
|
||||
{NULL, NULL, 0, 0, 0, 0, NULL}
|
||||
|
4
configure
vendored
4
configure
vendored
@ -5725,6 +5725,7 @@ VIDIX = $_vidix
|
||||
SHARED_PP = $_shared_pp
|
||||
CONFIG_PP = yes
|
||||
CONFIG_RISKY = yes
|
||||
CONFIG_MP3LAME = $_mp3lame
|
||||
LIBMENU = $_menu
|
||||
I18NLIBS = $_i18n_libs
|
||||
MATROSKA = $_matroska
|
||||
@ -5802,7 +5803,7 @@ MP1E_LIB = $_ld_mp1e
|
||||
ARCH_LIB = $_ld_arch $_ld_iconv
|
||||
XVID = $_xvid
|
||||
XVID_LIB = $_ld_xvid
|
||||
DECORE_LIB = $_ld_decore
|
||||
DECORE_LIB = $_ld_decore $_ld_mp3lame
|
||||
MENCODER = $_mencoder
|
||||
ENCORE_LIB = $_ld_encore $_ld_mp3lame
|
||||
DIRECTFB_INC = $_inc_directfb
|
||||
@ -5944,6 +5945,7 @@ $_def_encore
|
||||
/* Indicates if libmp3lame is available
|
||||
Note: for mencoder */
|
||||
$_def_mp3lame
|
||||
#define CONFIG_MP3LAME HAVE_MP3LAME
|
||||
|
||||
/* Define libmp1e for realtime mpeg encoding (for DXR3 and DVB cards) */
|
||||
$_def_mp1e
|
||||
|
@ -135,10 +135,17 @@ static int lavc_param_cbp= 0;
|
||||
static int lavc_param_mv0= 0;
|
||||
static int lavc_param_noise_reduction= 0;
|
||||
|
||||
char *lavc_param_acodec = "mp2";
|
||||
int lavc_param_atag = 0;
|
||||
int lavc_param_abitrate = 224;
|
||||
|
||||
#include "m_option.h"
|
||||
|
||||
#ifdef USE_LIBAVCODEC
|
||||
m_option_t lavcopts_conf[]={
|
||||
{"acodec", &lavc_param_acodec, CONF_TYPE_STRING, 0, 0, 0, NULL},
|
||||
{"abitrate", &lavc_param_abitrate, CONF_TYPE_INT, CONF_RANGE, 1, 1000, NULL},
|
||||
{"atag", &lavc_param_atag, CONF_TYPE_INT, CONF_RANGE, 0, 0xffff, NULL},
|
||||
{"vcodec", &lavc_param_vcodec, CONF_TYPE_STRING, 0, 0, 0, NULL},
|
||||
{"vbitrate", &lavc_param_vbitrate, CONF_TYPE_INT, CONF_RANGE, 4, 24000000, NULL},
|
||||
{"vratetol", &lavc_param_vrate_tolerance, CONF_TYPE_INT, CONF_RANGE, 4, 24000000, NULL},
|
||||
|
210
mencoder.c
210
mencoder.c
@ -14,6 +14,7 @@
|
||||
#define ACODEC_PCM 1
|
||||
#define ACODEC_VBRMP3 2
|
||||
#define ACODEC_NULL 3
|
||||
#define ACODEC_LAVC 4
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -71,6 +72,21 @@
|
||||
|
||||
#include "osdep/timer.h"
|
||||
|
||||
#ifdef USE_LIBAVCODEC
|
||||
// for lavc audio encoding
|
||||
#include "libavcodec/avcodec.h"
|
||||
static AVCodec *lavc_acodec;
|
||||
static AVCodecContext *lavc_actx = NULL;
|
||||
extern char *lavc_param_acodec;
|
||||
extern int lavc_param_abitrate;
|
||||
extern int lavc_param_atag;
|
||||
// tmp buffer for lavc audio encoding (to free!!!!!)
|
||||
static void *lavc_abuf = NULL;
|
||||
extern int avcodec_inited;
|
||||
|
||||
static uint32_t lavc_find_atag(char *codec);
|
||||
#endif
|
||||
|
||||
int vo_doublebuffering=0;
|
||||
int vo_directrendering=0;
|
||||
int vo_config_count=0;
|
||||
@ -792,6 +808,145 @@ case ACODEC_VBRMP3:
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef USE_LIBAVCODEC
|
||||
case ACODEC_LAVC:
|
||||
if(!lavc_param_acodec)
|
||||
{
|
||||
mp_msg(MSGT_MENCODER, MSGL_FATAL, "Audio LAVC, Missing codec name!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(!avcodec_inited){
|
||||
avcodec_init();
|
||||
avcodec_register_all();
|
||||
avcodec_inited=1;
|
||||
}
|
||||
|
||||
lavc_acodec = avcodec_find_encoder_by_name(lavc_param_acodec);
|
||||
if (!lavc_acodec)
|
||||
{
|
||||
mp_msg(MSGT_MENCODER, MSGL_FATAL, "Audio LAVC, couldn't find encoder for codec %s\n", lavc_param_acodec);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
lavc_actx = avcodec_alloc_context();
|
||||
if(lavc_actx == NULL)
|
||||
{
|
||||
mp_msg(MSGT_MENCODER, MSGL_FATAL, "Audio LAVC, couldn't allocate context!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(lavc_param_atag == 0)
|
||||
lavc_param_atag = lavc_find_atag(lavc_param_acodec);
|
||||
|
||||
// put sample parameters
|
||||
lavc_actx->channels = audio_output_channels ? audio_output_channels : sh_audio->channels;
|
||||
lavc_actx->sample_rate = force_srate ? force_srate : sh_audio->samplerate;
|
||||
lavc_actx->bit_rate = lavc_param_abitrate * 1000;
|
||||
|
||||
/*
|
||||
* Special case for imaadpcm.
|
||||
* The bitrate is only dependant on samplerate.
|
||||
* We have to known frame_size and block_align in advance,
|
||||
* so I just copied the code from libavcodec/adpcm.c
|
||||
*
|
||||
* However, ms imaadpcm uses a block_align of 2048,
|
||||
* lavc defaults to 1024
|
||||
*/
|
||||
if(lavc_param_atag == 0x11) {
|
||||
int blkalign = 2048;
|
||||
int framesize = (blkalign - 4 * lavc_actx->channels) * 8 / (4 * lavc_actx->channels) + 1;
|
||||
lavc_actx->bit_rate = lavc_actx->sample_rate*8*blkalign/framesize;
|
||||
}
|
||||
|
||||
if(avcodec_open(lavc_actx, lavc_acodec) < 0)
|
||||
{
|
||||
mp_msg(MSGT_MENCODER, MSGL_FATAL, "Couldn't open codec %s, br=%d\n", lavc_param_acodec, lavc_param_abitrate);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(lavc_param_atag == 0x11) {
|
||||
lavc_actx->block_align = 2048;
|
||||
lavc_actx->frame_size = (lavc_actx->block_align - 4 * lavc_actx->channels) * 8 / (4 * lavc_actx->channels) + 1;
|
||||
}
|
||||
|
||||
lavc_abuf = malloc(lavc_actx->frame_size * 2 * lavc_actx->channels);
|
||||
if(lavc_abuf == NULL)
|
||||
{
|
||||
fprintf(stderr, "Couldn't allocate %d bytes\n", lavc_actx->frame_size * 2 * lavc_actx->channels);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (sizeof(MPEGLAYER3WAVEFORMAT) != 30) // should be 30
|
||||
broken_c_compiler___size_of_MPEGLAYER3WAVEFORMAT_not_30();
|
||||
|
||||
mux_a->wf = malloc(sizeof(MPEGLAYER3WAVEFORMAT));
|
||||
mux_a->wf->wFormatTag = lavc_param_atag;
|
||||
mux_a->wf->nChannels = lavc_actx->channels;
|
||||
mux_a->wf->nSamplesPerSec = lavc_actx->sample_rate;
|
||||
mux_a->wf->nAvgBytesPerSec = (lavc_actx->bit_rate / 8);
|
||||
mux_a->h.dwRate = mux_a->wf->nAvgBytesPerSec;
|
||||
if (lavc_actx->block_align) {
|
||||
mux_a->h.dwSampleSize = mux_a->h.dwScale = lavc_actx->block_align;
|
||||
} else {
|
||||
mux_a->h.dwScale = (mux_a->wf->nAvgBytesPerSec * lavc_actx->frame_size)/ mux_a->wf->nSamplesPerSec; /* for cbr */
|
||||
|
||||
if ((mux_a->wf->nAvgBytesPerSec *
|
||||
lavc_actx->frame_size) % mux_a->wf->nSamplesPerSec) {
|
||||
mux_a->h.dwScale = lavc_actx->frame_size;
|
||||
mux_a->h.dwRate = lavc_actx->sample_rate;
|
||||
mux_a->h.dwSampleSize = 0; // Blocksize not constant
|
||||
} else {
|
||||
mux_a->h.dwSampleSize = mux_a->h.dwScale;
|
||||
}
|
||||
}
|
||||
mux_a->wf->nBlockAlign = mux_a->h.dwScale;
|
||||
mux_a->h.dwSuggestedBufferSize = audio_preload*mux_a->wf->nAvgBytesPerSec;
|
||||
mux_a->h.dwSuggestedBufferSize -= mux_a->h.dwSuggestedBufferSize % mux_a->wf->nBlockAlign;
|
||||
|
||||
switch (lavc_param_atag) {
|
||||
case 0x11: /* imaadpcm */
|
||||
mux_a->wf->wBitsPerSample = 4;
|
||||
mux_a->wf->cbSize = 2;
|
||||
/*
|
||||
* Magic imaadpcm values, currently probably only valid
|
||||
* for 48KHz Stereo
|
||||
*/
|
||||
((unsigned char*)mux_a->wf)[sizeof(WAVEFORMATEX)] = 0xf9;
|
||||
((unsigned char*)mux_a->wf)[sizeof(WAVEFORMATEX)+1] = 0x07;
|
||||
break;
|
||||
case 0x55: /* mp3 */
|
||||
mux_a->wf->cbSize = 12;
|
||||
mux_a->wf->wBitsPerSample = 0; /* does not apply */
|
||||
((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->wID = 1;
|
||||
((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->fdwFlags = 2;
|
||||
((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nBlockSize = mux_a->wf->nBlockAlign;
|
||||
((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nFramesPerBlock = 1;
|
||||
((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nCodecDelay = 0;
|
||||
break;
|
||||
default:
|
||||
mux_a->wf->cbSize = 0;
|
||||
mux_a->wf->wBitsPerSample = 0; /* Unknown */
|
||||
break;
|
||||
}
|
||||
|
||||
// setup filter:
|
||||
if (!init_audio_filters(
|
||||
sh_audio,
|
||||
sh_audio->samplerate, sh_audio->channels,
|
||||
sh_audio->sample_format, sh_audio->samplesize,
|
||||
mux_a->wf->nSamplesPerSec, mux_a->wf->nChannels,
|
||||
AFMT_S16_NE, 2,
|
||||
mux_a->h.dwSuggestedBufferSize,
|
||||
mux_a->h.dwSuggestedBufferSize*2)) {
|
||||
mp_msg(MSGT_CPLAYER, MSGL_ERR, "Couldn't find matching filter / ao format!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
mp_msg(MSGT_MENCODER, MSGL_V, "FRAME_SIZE: %d, BUFFER_SIZE: %d, TAG: 0x%x\n", lavc_actx->frame_size, lavc_actx->frame_size * 2 * lavc_actx->channels, mux_a->wf->wFormatTag);
|
||||
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (verbose>1) print_wave_header(mux_a->wf);
|
||||
@ -919,6 +1074,33 @@ if(sh_audio){
|
||||
|
||||
ptimer_start = GetTimerMS();
|
||||
|
||||
#ifdef USE_LIBAVCODEC
|
||||
if(mux_a->codec == ACODEC_LAVC){
|
||||
int size, rd_len;
|
||||
|
||||
size = lavc_actx->frame_size * 2 * mux_a->wf->nChannels;
|
||||
|
||||
rd_len = dec_audio(sh_audio, lavc_abuf, size);
|
||||
if(rd_len != size)
|
||||
break;
|
||||
|
||||
// Encode one frame
|
||||
mux_a->buffer_len += avcodec_encode_audio(lavc_actx, mux_a->buffer + mux_a->buffer_len, size, lavc_abuf);
|
||||
if (mux_a->h.dwSampleSize) { /* CBR */
|
||||
/*
|
||||
* work around peculiar lame behaviour
|
||||
*/
|
||||
if (mux_a->buffer_len < mux_a->wf->nBlockAlign) {
|
||||
len = 0;
|
||||
} else {
|
||||
len = mux_a->wf->nBlockAlign*(mux_a->buffer_len/mux_a->wf->nBlockAlign);
|
||||
}
|
||||
} else { /* VBR */
|
||||
len = mux_a->buffer_len;
|
||||
}
|
||||
if (mux_v->timer == 0) mux_a->h.dwInitialFrames++;
|
||||
}
|
||||
#endif
|
||||
if(mux_a->h.dwSampleSize){
|
||||
// CBR - copy 0.5 sec of audio
|
||||
switch(mux_a->codec){
|
||||
@ -1294,6 +1476,11 @@ if(sh_video){ uninit_video(sh_video);sh_video=NULL; }
|
||||
if(demuxer) free_demuxer(demuxer);
|
||||
if(stream) free_stream(stream); // kill cache thread
|
||||
|
||||
#ifdef USE_LIBAVCODEC
|
||||
if(lavc_abuf != NULL)
|
||||
free(lavc_abuf);
|
||||
#endif
|
||||
|
||||
return interrupted;
|
||||
}
|
||||
|
||||
@ -1600,3 +1787,26 @@ static void lame_presets_longinfo_dm ( FILE* msgfp )
|
||||
mencoder_exit(0, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIBAVCODEC
|
||||
static uint32_t lavc_find_atag(char *codec)
|
||||
{
|
||||
if(codec == NULL)
|
||||
return 0;
|
||||
|
||||
if(! strcasecmp(codec, "mp2"))
|
||||
return 0x50;
|
||||
|
||||
if(! strcasecmp(codec, "mp3"))
|
||||
return 0x55;
|
||||
|
||||
if(! strcasecmp(codec, "ac3"))
|
||||
return 0x2000;
|
||||
|
||||
if(! strcasecmp(codec, "adpcm_ima_wav"))
|
||||
return 0x11;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user