[FFmpeg-devel] This patch I add the check for venc->window_sequence[0], and set venc->log2_blocksize[0]=8 when venc->window_sequence[0] is the EIGHT_SHORT_SEQUENCE.

Submitted by Ruyi Ji on April 23, 2017, 7:27 a.m.

Details

Message ID 1492932450-6720-1-git-send-email-jiruyi1@gmail.com
State New
Headers show

Commit Message

Ruyi Ji April 23, 2017, 7:27 a.m.
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(-)

Comments

Michael Niedermayer April 23, 2017, 1:48 p.m.
On Sun, Apr 23, 2017 at 03:27:30AM -0400, Ruyi Ji wrote:
> 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(-)

Breaks
make fate-vorbis-encode

==25091== Invalid read of size 4
==25091==    at 0x103AA8A: psy_lame_window (in ffmpeg/ffmpeg_g)
==25091==    by 0xBA5757: vorbis_encode_frame (in ffmpeg/ffmpeg_g)
==25091==    by 0x81282F: avcodec_encode_audio2 (in ffmpeg/ffmpeg_g)
==25091==    by 0x813234: do_encode (in ffmpeg/ffmpeg_g)
==25091==    by 0x813357: avcodec_send_frame (in ffmpeg/ffmpeg_g)
==25091==    by 0x4BDC1B: reap_filters (in ffmpeg/ffmpeg_g)
==25091==    by 0x4C3DEA: transcode (in ffmpeg/ffmpeg_g)
==25091==    by 0x4A4227: main (in ffmpeg/ffmpeg_g)
==25091==  Address 0x19bb1618 is 8 bytes after a block of size 496 free'd
==25091==    at 0x4C2B5D9: free (vg_replace_malloc.c:446)
==25091==    by 0x5DAA51: filter_frame (in ffmpeg/ffmpeg_g)
==25091==    by 0x4E3CD6: ff_filter_activate (in ffmpeg/ffmpeg_g)
==25091==    by 0x4E7FC7: av_buffersrc_add_frame_internal (in ffmpeg/ffmpeg_g)
==25091==    by 0x4E833D: av_buffersrc_add_frame_flags (in ffmpeg/ffmpeg_g)
==25091==    by 0x4BE394: send_frame_to_filters (in ffmpeg/ffmpeg_g)
==25091==    by 0x4BFD29: process_input_packet (in ffmpeg/ffmpeg_g)
==25091==    by 0x4C1820: process_input (in ffmpeg/ffmpeg_g)
==25091==    by 0x4C3DD0: transcode (in ffmpeg/ffmpeg_g)
==25091==    by 0x4A4227: main (in ffmpeg/ffmpeg_g)


[...]

Patch hide | download patch | download mbox

diff --git a/libavcodec/psymodel.c b/libavcodec/psymodel.c
index 2b5f111..2e11c48 100644
--- a/libavcodec/psymodel.c
+++ b/libavcodec/psymodel.c
@@ -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;
     }
diff --git a/libavcodec/vorbis_enc_data.h b/libavcodec/vorbis_enc_data.h
index a51aaec..5102d30 100644
--- a/libavcodec/vorbis_enc_data.h
+++ b/libavcodec/vorbis_enc_data.h
@@ -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 */
diff --git a/libavcodec/vorbisenc.c b/libavcodec/vorbisenc.c
index 2974ca2..7dac45a 100644
--- a/libavcodec/vorbisenc.c
+++ b/libavcodec/vorbisenc.c
@@ -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: