Merge commit '718907cd881a0b593264aed059c0e00da13f9e15'
* commit '718907cd881a0b593264aed059c0e00da13f9e15': libtwolame MP2 encoding support Conflicts: Changelog configure doc/general.texi libavcodec/Makefile libavcodec/libtwolame.c libavcodec/version.h Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
@@ -920,7 +920,7 @@ following image formats are supported:
|
|||||||
@item Monkey's Audio @tab @tab X
|
@item Monkey's Audio @tab @tab X
|
||||||
@item MP1 (MPEG audio layer 1) @tab @tab IX
|
@item MP1 (MPEG audio layer 1) @tab @tab IX
|
||||||
@item MP2 (MPEG audio layer 2) @tab IX @tab IX
|
@item MP2 (MPEG audio layer 2) @tab IX @tab IX
|
||||||
@tab libtwolame can be used alternatively for encoding.
|
@tab encoding supported also through external library TwoLAME
|
||||||
@item MP3 (MPEG audio layer 3) @tab E @tab IX
|
@item MP3 (MPEG audio layer 3) @tab E @tab IX
|
||||||
@tab encoding supported through external library LAME, ADU MP3 and MP3onMP4 also supported
|
@tab encoding supported through external library LAME, ADU MP3 and MP3onMP4 also supported
|
||||||
@item MPEG-4 Audio Lossless Coding (ALS) @tab @tab X
|
@item MPEG-4 Audio Lossless Coding (ALS) @tab @tab X
|
||||||
|
@@ -26,7 +26,9 @@
|
|||||||
|
|
||||||
#include <twolame.h>
|
#include <twolame.h>
|
||||||
|
|
||||||
|
#include "libavutil/common.h"
|
||||||
#include "libavutil/opt.h"
|
#include "libavutil/opt.h"
|
||||||
|
|
||||||
#include "avcodec.h"
|
#include "avcodec.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "mpegaudio.h"
|
#include "mpegaudio.h"
|
||||||
@@ -39,6 +41,7 @@ typedef struct TWOLAMEContext {
|
|||||||
int error_protection;
|
int error_protection;
|
||||||
int copyright;
|
int copyright;
|
||||||
int original;
|
int original;
|
||||||
|
int verbosity;
|
||||||
|
|
||||||
twolame_options *glopts;
|
twolame_options *glopts;
|
||||||
int64_t next_pts;
|
int64_t next_pts;
|
||||||
@@ -57,12 +60,13 @@ static av_cold int twolame_encode_init(AVCodecContext *avctx)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
avctx->frame_size = TWOLAME_SAMPLES_PER_FRAME;
|
avctx->frame_size = TWOLAME_SAMPLES_PER_FRAME;
|
||||||
|
avctx->delay = 512 - 32 + 1;
|
||||||
|
|
||||||
s->glopts = twolame_init();
|
s->glopts = twolame_init();
|
||||||
if (!s->glopts)
|
if (!s->glopts)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
twolame_set_verbosity(s->glopts, 0);
|
twolame_set_verbosity(s->glopts, s->verbosity);
|
||||||
twolame_set_mode(s->glopts, s->mode);
|
twolame_set_mode(s->glopts, s->mode);
|
||||||
twolame_set_psymodel(s->glopts, s->psymodel);
|
twolame_set_psymodel(s->glopts, s->psymodel);
|
||||||
twolame_set_energy_levels(s->glopts, s->energy);
|
twolame_set_energy_levels(s->glopts, s->energy);
|
||||||
@@ -75,19 +79,21 @@ static av_cold int twolame_encode_init(AVCodecContext *avctx)
|
|||||||
twolame_set_out_samplerate(s->glopts, avctx->sample_rate);
|
twolame_set_out_samplerate(s->glopts, avctx->sample_rate);
|
||||||
if (avctx->flags & CODEC_FLAG_QSCALE || !avctx->bit_rate) {
|
if (avctx->flags & CODEC_FLAG_QSCALE || !avctx->bit_rate) {
|
||||||
twolame_set_VBR(s->glopts, TRUE);
|
twolame_set_VBR(s->glopts, TRUE);
|
||||||
twolame_set_VBR_level(s->glopts, avctx->global_quality);
|
twolame_set_VBR_level(s->glopts,
|
||||||
av_log(avctx, AV_LOG_WARNING, "VBR mode is experimental!\n");
|
avctx->global_quality / (float) FF_QP2LAMBDA);
|
||||||
|
av_log(avctx, AV_LOG_WARNING,
|
||||||
|
"VBR in MP2 is a hack, use another codec that supports it.\n");
|
||||||
} else {
|
} else {
|
||||||
twolame_set_bitrate(s->glopts, avctx->bit_rate / 1000);
|
twolame_set_bitrate(s->glopts, avctx->bit_rate / 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret = twolame_init_params(s->glopts)))
|
ret = twolame_init_params(s->glopts);
|
||||||
goto error;
|
if (ret) {
|
||||||
|
twolame_encode_close(avctx);
|
||||||
|
return AVERROR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
error:
|
|
||||||
twolame_encode_close(avctx);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int twolame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
|
static int twolame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
|
||||||
@@ -103,54 +109,61 @@ static int twolame_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
|
|||||||
switch (avctx->sample_fmt) {
|
switch (avctx->sample_fmt) {
|
||||||
case AV_SAMPLE_FMT_FLT:
|
case AV_SAMPLE_FMT_FLT:
|
||||||
ret = twolame_encode_buffer_float32_interleaved(s->glopts,
|
ret = twolame_encode_buffer_float32_interleaved(s->glopts,
|
||||||
frame->data[0],
|
(const float *)frame->data[0],
|
||||||
frame->nb_samples,
|
frame->nb_samples,
|
||||||
avpkt->data, avpkt->size);
|
avpkt->data,
|
||||||
|
avpkt->size);
|
||||||
break;
|
break;
|
||||||
case AV_SAMPLE_FMT_FLTP:
|
case AV_SAMPLE_FMT_FLTP:
|
||||||
ret = twolame_encode_buffer_float32(s->glopts,
|
ret = twolame_encode_buffer_float32(s->glopts,
|
||||||
frame->data[0], frame->data[1],
|
(const float *)frame->data[0],
|
||||||
|
(const float *)frame->data[1],
|
||||||
frame->nb_samples,
|
frame->nb_samples,
|
||||||
avpkt->data, avpkt->size);
|
avpkt->data, avpkt->size);
|
||||||
break;
|
break;
|
||||||
case AV_SAMPLE_FMT_S16:
|
case AV_SAMPLE_FMT_S16:
|
||||||
ret = twolame_encode_buffer_interleaved(s->glopts,
|
ret = twolame_encode_buffer_interleaved(s->glopts,
|
||||||
frame->data[0],
|
(const short int *)frame->data[0],
|
||||||
frame->nb_samples,
|
frame->nb_samples,
|
||||||
avpkt->data, avpkt->size);
|
avpkt->data, avpkt->size);
|
||||||
break;
|
break;
|
||||||
case AV_SAMPLE_FMT_S16P:
|
case AV_SAMPLE_FMT_S16P:
|
||||||
ret = twolame_encode_buffer(s->glopts,
|
ret = twolame_encode_buffer(s->glopts,
|
||||||
frame->data[0], frame->data[1],
|
(const short int *)frame->data[0],
|
||||||
|
(const short int *)frame->data[1],
|
||||||
frame->nb_samples,
|
frame->nb_samples,
|
||||||
avpkt->data, avpkt->size);
|
avpkt->data, avpkt->size);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
av_log(avctx, AV_LOG_ERROR,
|
||||||
|
"Unsupported sample format %d.\n", avctx->sample_fmt);
|
||||||
return AVERROR_BUG;
|
return AVERROR_BUG;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = twolame_encode_flush(s->glopts, avpkt->data, avpkt->size);
|
ret = twolame_encode_flush(s->glopts, avpkt->data, avpkt->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret > 0) {
|
if (!ret) // no bytes written
|
||||||
avpkt->duration = ff_samples_to_time_base(avctx, avctx->frame_size);
|
return 0;
|
||||||
|
if (ret < 0) // twolame error
|
||||||
|
return AVERROR_UNKNOWN;
|
||||||
|
|
||||||
|
avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples);
|
||||||
if (frame) {
|
if (frame) {
|
||||||
if (frame->pts != AV_NOPTS_VALUE)
|
if (frame->pts != AV_NOPTS_VALUE)
|
||||||
avpkt->pts = frame->pts;
|
avpkt->pts = frame->pts - ff_samples_to_time_base(avctx, avctx->delay);
|
||||||
} else {
|
} else {
|
||||||
avpkt->pts = s->next_pts;
|
avpkt->pts = s->next_pts;
|
||||||
}
|
}
|
||||||
|
// this is for setting pts for flushed packet(s).
|
||||||
if (avpkt->pts != AV_NOPTS_VALUE)
|
if (avpkt->pts != AV_NOPTS_VALUE)
|
||||||
s->next_pts = avpkt->pts + avpkt->duration;
|
s->next_pts = avpkt->pts + avpkt->duration;
|
||||||
|
|
||||||
avpkt->size = ret;
|
av_shrink_packet(avpkt, ret);
|
||||||
*got_packet_ptr = 1;
|
*got_packet_ptr = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define OFFSET(x) offsetof(TWOLAMEContext, x)
|
#define OFFSET(x) offsetof(TWOLAMEContext, x)
|
||||||
#define AE AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
|
#define AE AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
|
||||||
static const AVOption options[] = {
|
static const AVOption options[] = {
|
||||||
@@ -165,16 +178,27 @@ static const AVOption options[] = {
|
|||||||
{ "error_protection","enable CRC error protection", OFFSET(error_protection), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AE},
|
{ "error_protection","enable CRC error protection", OFFSET(error_protection), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AE},
|
||||||
{ "copyright", "set MPEG Audio Copyright flag", OFFSET(copyright), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AE},
|
{ "copyright", "set MPEG Audio Copyright flag", OFFSET(copyright), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AE},
|
||||||
{ "original", "set MPEG Audio Original flag", OFFSET(original), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AE},
|
{ "original", "set MPEG Audio Original flag", OFFSET(original), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AE},
|
||||||
|
{ "verbosity", "set library optput level (0-10)", OFFSET(verbosity), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 10, AE},
|
||||||
{ NULL },
|
{ NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const AVClass libtwolame_class = {
|
static const AVClass twolame_class = {
|
||||||
.class_name = "libtwolame encoder",
|
.class_name = "libtwolame encoder",
|
||||||
.item_name = av_default_item_name,
|
.item_name = av_default_item_name,
|
||||||
.option = options,
|
.option = options,
|
||||||
.version = LIBAVUTIL_VERSION_INT,
|
.version = LIBAVUTIL_VERSION_INT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const AVCodecDefault twolame_defaults[] = {
|
||||||
|
{ "b", "384000" },
|
||||||
|
{ "ar", "48000" },
|
||||||
|
{ NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int twolame_samplerates[] = {
|
||||||
|
16000, 22050, 24000, 32000, 44100, 48000, 0
|
||||||
|
};
|
||||||
|
|
||||||
AVCodec ff_libtwolame_encoder = {
|
AVCodec ff_libtwolame_encoder = {
|
||||||
.name = "libtwolame",
|
.name = "libtwolame",
|
||||||
.long_name = NULL_IF_CONFIG_SMALL("libtwolame MP2 (MPEG audio layer 2)"),
|
.long_name = NULL_IF_CONFIG_SMALL("libtwolame MP2 (MPEG audio layer 2)"),
|
||||||
@@ -185,14 +209,18 @@ AVCodec ff_libtwolame_encoder = {
|
|||||||
.encode2 = twolame_encode_frame,
|
.encode2 = twolame_encode_frame,
|
||||||
.close = twolame_encode_close,
|
.close = twolame_encode_close,
|
||||||
.capabilities = CODEC_CAP_DELAY,
|
.capabilities = CODEC_CAP_DELAY,
|
||||||
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLT,
|
.defaults = twolame_defaults,
|
||||||
|
.priv_class = &twolame_class,
|
||||||
|
.sample_fmts = (const enum AVSampleFormat[]) {
|
||||||
|
AV_SAMPLE_FMT_FLT,
|
||||||
AV_SAMPLE_FMT_FLTP,
|
AV_SAMPLE_FMT_FLTP,
|
||||||
AV_SAMPLE_FMT_S16,
|
AV_SAMPLE_FMT_S16,
|
||||||
AV_SAMPLE_FMT_S16P,
|
AV_SAMPLE_FMT_S16P,
|
||||||
AV_SAMPLE_FMT_NONE },
|
AV_SAMPLE_FMT_NONE
|
||||||
.channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO,
|
},
|
||||||
|
.channel_layouts = (const uint64_t[]) {
|
||||||
|
AV_CH_LAYOUT_MONO,
|
||||||
AV_CH_LAYOUT_STEREO,
|
AV_CH_LAYOUT_STEREO,
|
||||||
0 },
|
0 },
|
||||||
.supported_samplerates = (const int[]){ 16000, 22050, 24000, 32000, 44100, 48000, 0 },
|
.supported_samplerates = twolame_samplerates,
|
||||||
.priv_class = &libtwolame_class,
|
|
||||||
};
|
};
|
||||||
|
@@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
#define LIBAVCODEC_VERSION_MAJOR 55
|
#define LIBAVCODEC_VERSION_MAJOR 55
|
||||||
#define LIBAVCODEC_VERSION_MINOR 58
|
#define LIBAVCODEC_VERSION_MINOR 58
|
||||||
#define LIBAVCODEC_VERSION_MICRO 102
|
#define LIBAVCODEC_VERSION_MICRO 103
|
||||||
|
|
||||||
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
||||||
LIBAVCODEC_VERSION_MINOR, \
|
LIBAVCODEC_VERSION_MINOR, \
|
||||||
|
Reference in New Issue
Block a user