@@ -62,6 +62,7 @@ av_cold int ff_psy_init(FFPsyContext *ctx, AVCodecContext *avctx, int num_lens,
switch (ctx->avctx->codec_id) {
case AV_CODEC_ID_AAC:
+ case AV_CODEC_ID_VORBIS:
ctx->model = &ff_aac_psy_model;
break;
}
@@ -501,4 +501,115 @@ static const struct {
{ 3, 2, 3, { -1, 12, 13, 14 } },
};
+
+static const uint8_t swb_size_128_96[] = {
+ 4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36
+};
+
+static const uint8_t swb_size_128_64[] = {
+ 4, 4, 4, 4, 4, 4, 8, 8, 8, 16, 28, 36
+};
+
+static const uint8_t swb_size_128_48[] = {
+ 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16
+};
+
+static const uint8_t swb_size_128_24[] = {
+ 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 12, 12, 16, 16, 20
+};
+
+static const uint8_t swb_size_128_16[] = {
+ 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 12, 12, 16, 20, 20
+};
+
+static const uint8_t swb_size_128_8[] = {
+ 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 12, 16, 20, 20
+};
+
+static const uint8_t swb_size_1024_96[] = {
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8,
+ 12, 12, 12, 12, 12, 16, 16, 24, 28, 36, 44,
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
+};
+
+static const uint8_t swb_size_1024_64[] = {
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8,
+ 12, 12, 12, 16, 16, 16, 20, 24, 24, 28, 36,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40
+};
+
+static const uint8_t swb_size_1024_48[] = {
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8,
+ 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+ 96
+};
+
+static const uint8_t swb_size_1024_32[] = {
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8,
+ 12, 12, 12, 12, 16, 16, 20, 20, 24, 24, 28, 28,
+ 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
+};
+
+static const uint8_t swb_size_1024_24[] = {
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 12, 12, 12, 12, 16, 16, 16, 20, 20, 24, 24, 28, 28,
+ 32, 36, 36, 40, 44, 48, 52, 52, 64, 64, 64, 64, 64
+};
+
+static const uint8_t swb_size_1024_16[] = {
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 16, 16, 16, 16, 20, 20, 20, 24, 24, 28, 28,
+ 32, 36, 40, 40, 44, 48, 52, 56, 60, 64, 64, 64
+};
+
+static const uint8_t swb_size_1024_8[] = {
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 16, 16, 16, 16, 16, 16, 16, 20, 20, 20, 20, 24, 24, 24, 28, 28,
+ 32, 36, 36, 40, 44, 48, 52, 56, 60, 64, 80
+};
+
+const uint8_t *ff_vorbis_swb_size_128[] = {
+ swb_size_128_96, swb_size_128_96, swb_size_128_64,
+ swb_size_128_48, swb_size_128_48, swb_size_128_48,
+ swb_size_128_24, swb_size_128_24, swb_size_128_16,
+ swb_size_128_16, swb_size_128_16, swb_size_128_8,
+ swb_size_128_8
+};
+
+const uint8_t *ff_vorbis_swb_size_1024[] = {
+ swb_size_1024_96, swb_size_1024_96, swb_size_1024_64,
+ swb_size_1024_48, swb_size_1024_48, swb_size_1024_32,
+ swb_size_1024_24, swb_size_1024_24, swb_size_1024_16,
+ swb_size_1024_16, swb_size_1024_16, swb_size_1024_8,
+ swb_size_1024_8
+};
+
+const int ff_vorbis_swb_size_128_len = FF_ARRAY_ELEMS(ff_vorbis_swb_size_128);
+const int ff_vorbis_swb_size_1024_len = FF_ARRAY_ELEMS(ff_vorbis_swb_size_1024);
+
+/* duplicated from avpriv_mpeg4audio_sample_rates to avoid shared build
+ * failures */
+static const int mpeg4audio_sample_rates[16] = {
+ 96000, 88200, 64000, 48000, 44100, 32000,
+ 24000, 22050, 16000, 12000, 11025, 8000, 7350
+};
+
+enum WindowSequence {
+ ONLY_LONG_SEQUENCE,
+ LONG_START_SEQUENCE,
+ EIGHT_SHORT_SEQUENCE,
+ LONG_STOP_SEQUENCE,
+};
+
+const uint8_t ff_vorbis_num_swb_1024[] = {
+ 41, 41, 47, 49, 49, 51, 47, 47, 43, 43, 43, 40, 40
+};
+
+const uint8_t ff_vorbis_num_swb_128[] = {
+ 12, 12, 12, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15
+};
+
+
+
#endif /* AVCODEC_VORBIS_ENC_DATA_H */
@@ -32,6 +32,7 @@
#include "mathops.h"
#include "vorbis.h"
#include "vorbis_enc_data.h"
+#include "psymodel.h"
#define BITSTREAM_WRITER_LE
#include "put_bits.h"
@@ -97,6 +98,8 @@ typedef struct vorbis_enc_mode {
int mapping;
} vorbis_enc_mode;
+
+#define MAX_CHANNELS 2
typedef struct vorbis_enc_context {
int channels;
int sample_rate;
@@ -126,9 +129,12 @@ typedef struct vorbis_enc_context {
vorbis_enc_mode *modes;
int64_t next_pts;
+ //stuff concerned with psymodel
+ FFPsyContext psy;
+ struct FFPsyPreprocessContext *psypp;
+ enum WindowSequence window_sequence[MAX_CHANNELS];
} vorbis_enc_context;
-#define MAX_CHANNELS 2
#define MAX_CODEBOOK_DIM 8
#define MAX_FLOOR_CLASS_DIM 4
@@ -1029,6 +1035,40 @@ static int vorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
PutBitContext pb;
int i, ret;
+ float *samples2, *la, *overlap;
+ int start_ch, ch, chans, cur_channel;
+ FFPsyWindowInfo windows[MAX_CHANNELS];
+
+ if (!avctx->frame_number)
+ return 0;
+
+ if (venc->psypp)
+ ff_psy_preprocess(venc->psypp, audio, venc->channels);
+
+ start_ch = 0;
+ cur_channel = 0;
+ for (i = 0; i < venc->channels - 1; i++) {
+ FFPsyWindowInfo *wi = windows + start_ch;
+ chans = 2;
+ for (ch = 0; ch < 2; ch ++) {
+ cur_channel = start_ch + ch;
+ overlap = &audio[cur_channel][0];
+ samples2 = overlap + 1024;
+ la = samples2 + (448 + 64);
+ if (!frame)
+ la = NULL;
+ wi[ch] = venc->psy.model->window(&venc->psy, samples2, la, cur_channel, venc->window_sequence[0]);
+ venc->window_sequence[1] = venc->window_sequence[0];
+ venc->window_sequence[0] = wi[ch].window_type[0];
+ av_log(avctx, AV_LOG_INFO, "The venc->window_sequence[0] is %d\n", venc->window_sequence[0]);
+ if (venc->window_sequence[0] == EIGHT_SHORT_SEQUENCE)
+ venc->log2_blocksize[0] = 8;
+ }
+ start_ch += chans;
+ }
+
+
+
if (!apply_window_and_mdct(venc, audio, samples))
return 0;
samples = 1 << (venc->log2_blocksize[0] - 1);
@@ -1159,6 +1199,11 @@ static av_cold int vorbis_encode_close(AVCodecContext *avctx)
ff_mdct_end(&venc->mdct[0]);
ff_mdct_end(&venc->mdct[1]);
+ ff_psy_end(&venc->psy);
+
+ if (venc->psypp)
+ ff_psy_preprocess_end(venc->psypp);
+
av_freep(&avctx->extradata);
return 0 ;
@@ -1169,6 +1214,11 @@ static av_cold int vorbis_encode_init(AVCodecContext *avctx)
vorbis_enc_context *venc = avctx->priv_data;
int ret;
+ const uint8_t *sizes[MAX_CHANNELS];
+ uint8_t grouping[MAX_CHANNELS];
+ int lengths[MAX_CHANNELS];
+ int samplerate_index;
+
if (avctx->channels != 2) {
av_log(avctx, AV_LOG_ERROR, "Current FFmpeg Vorbis encoder only supports 2 channels.\n");
return -1;
@@ -1189,6 +1239,22 @@ static av_cold int vorbis_encode_init(AVCodecContext *avctx)
avctx->extradata_size = ret;
avctx->frame_size = 1 << (venc->log2_blocksize[0] - 1);
+
+ for (samplerate_index = 0; samplerate_index < 16; samplerate_index ++)
+ if (avctx->sample_rate == mpeg4audio_sample_rates[samplerate_index])
+ break;
+ if (samplerate_index == 16 || samplerate_index >= ff_vorbis_swb_size_1024_len || samplerate_index >= ff_vorbis_swb_size_128_len)
+ av_log(avctx, AV_LOG_ERROR, "Unsupperted sample rate %d\n", avctx->sample_rate);
+
+ sizes[0] = ff_vorbis_swb_size_1024[samplerate_index];
+ sizes[1] = ff_vorbis_swb_size_128[samplerate_index];
+ lengths[0] = ff_vorbis_num_swb_1024[samplerate_index];
+ lengths[1] = ff_vorbis_num_swb_128[samplerate_index];
+ grouping[0] = 1;
+
+ if ((ret = ff_psy_init(&venc->psy, avctx, 2, sizes, lengths, 1, grouping)) < 0)
+ goto error;
+ venc->psypp = ff_psy_preprocess_init(avctx);
return 0;
error:
Signed-off-by: Ruyi Ji <jiruyi1@gmail.com> --- libavcodec/psymodel.c | 1 + libavcodec/vorbis_enc_data.h | 111 +++++++++++++++++++++++++++++++++++++++++++ libavcodec/vorbisenc.c | 68 +++++++++++++++++++++++++- 3 files changed, 179 insertions(+), 1 deletion(-)