FFmpeg-soc
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
January 2009
- 12 participants
- 118 discussions
Author: faust3
Date: Sat Jan 31 19:08:18 2009
New Revision: 4014
Log:
use vector_fmul_window for the windowing
Modified:
wmapro/wma3dec.c
Modified: wmapro/wma3dec.c
==============================================================================
--- wmapro/wma3dec.c Tue Jan 27 21:57:50 2009 (r4013)
+++ wmapro/wma3dec.c Sat Jan 31 19:08:18 2009 (r4014)
@@ -1074,43 +1074,22 @@ static void wma_window(WMA3DecodeContext
for(i=0;i<s->channels_for_cur_subframe;i++){
int c = s->channel_indexes_for_cur_subframe[i];
int j = s->channel[c].cur_subframe;
- int x;
- // FIXME: use dsp.vector_fmul_window
float* start;
- float* end;
float* window;
int prev_block_len = s->channel[c].prev_block_len;
int block_len = s->channel[c].subframe_len[j];
- int len;
- int winlen;
+ int winlen = prev_block_len;
start = &s->channel[c].out[s->samples_per_frame/2 + s->channel[c].subframe_offset[j] - prev_block_len /2 ];
- end = &s->channel[c].out[s->samples_per_frame/2 + s->channel[c].subframe_offset[j] + block_len /2 - 1];
if(block_len <= prev_block_len){
start += (prev_block_len - block_len)/2;
- len = block_len/2;
winlen = block_len;
- }else{
- end -= (block_len - prev_block_len)/2;
- len = prev_block_len /2;
- winlen = prev_block_len;
}
-// float* rs = &s->channel[c].out[s->samples_per_frame/2 + s->channel[c].subframe_offset[i]];
-// printf("Dstart %i %i end %i win %i prev %i\n",s->frame_num+1, start - rs,end -rs,winlen,prev_block_len);
-
- // FIXME: untangle the windowing so DSP functions can be used
window = s->windows[av_log2(winlen)-BLOCK_MIN_BITS];
- for(x=0;x<len;x++){
- float ts = *start;
- float te = *end;
- float sin_v = window[x];
- float cos_v = window[winlen - x -1];
- *start = cos_v * ts - sin_v * te;
- *end = cos_v * te + sin_v * ts;
- ++start;
- --end;
- }
+
+ s->dsp.vector_fmul_window(start, start, start + winlen/2, window, 0, winlen/2);
+
s->channel[c].prev_block_len = block_len;
}
}
3
2
Author: vitor
Date: Tue Jan 27 21:57:50 2009
New Revision: 4013
Log:
Fix build when not using --enable-avfilter.
Patch by Cédric Schieli - cschieli <> gmail com
Modified:
libavfilter/diffs/02_ffmpeg_filters.diff
Modified: libavfilter/diffs/02_ffmpeg_filters.diff
==============================================================================
--- libavfilter/diffs/02_ffmpeg_filters.diff Tue Jan 27 06:34:33 2009 (r4012)
+++ libavfilter/diffs/02_ffmpeg_filters.diff Tue Jan 27 21:57:50 2009 (r4013)
@@ -250,15 +250,17 @@ Index: ffmpeg.c
if (ost->video_pad) {
av_picture_pad((AVPicture*)final_picture, (AVPicture *)padding_src,
-@@ -1190,6 +1383,7 @@
+@@ -1190,6 +1383,9 @@
static short *samples= NULL;
AVSubtitle subtitle, *subtitle_to_free;
int got_subtitle;
++#if CONFIG_AVFILTER
+ int loop;
++#endif
if(ist->next_pts == AV_NOPTS_VALUE)
ist->next_pts= ist->pts;
-@@ -1307,6 +1501,15 @@
+@@ -1307,6 +1503,15 @@
&buffer_to_free);
}
@@ -274,13 +276,15 @@ Index: ffmpeg.c
// preprocess audio (volume)
if (ist->st->codec->codec_type == CODEC_TYPE_AUDIO) {
if (audio_volume != 256) {
-@@ -1328,10 +1531,16 @@
+@@ -1328,10 +1533,18 @@
if (pts > now)
usleep(pts - now);
}
-
++#if CONFIG_AVFILTER
+ loop = ist->st->codec->codec_type != CODEC_TYPE_VIDEO ||
+ !ist->out_video_filter || avfilter_poll_frame(ist->out_video_filter->inputs[0]);
++#endif
/* if output time reached then transcode raw format,
encode packets and output them */
if (start_time == 0 || ist->pts >= start_time)
@@ -302,12 +306,14 @@ Index: ffmpeg.c
do_video_out(os, ost, ist, &picture, &frame_size);
if (vstats_filename && frame_size)
do_video_stats(os, ost, frame_size);
-@@ -1411,7 +1623,15 @@
+@@ -1411,7 +1627,17 @@
av_free_packet(&opkt);
}
}
++#if CONFIG_AVFILTER
+ loop = (ist->st->codec->codec_type == CODEC_TYPE_VIDEO) &&
+ ist->out_video_filter && avfilter_poll_frame(ist->out_video_filter->inputs[0]);
++#endif
}
+
+#if CONFIG_AVFILTER
1
0
27 Jan '09
Hi!
I just read about your efforts, including jpeg2000 in ffmpeg.
Sadly I could neither find a downloadable version, nor sth. like
'comming soon'..:-(
Would you tell me, how far things are?! Is the development going on?
Can I help in any way!?
All the best and keep on rokkin'!
Stefan Klein
--
Beste Grüße!
2
1
Author: kmalaussene
Date: Tue Jan 27 06:34:33 2009
New Revision: 4012
Log:
Fix decoding of pitch lag frac to match reference implementation.
Some of its value were widely out of bound.
Modified:
amr/amrnbfloatdec.c
Modified: amr/amrnbfloatdec.c
==============================================================================
--- amr/amrnbfloatdec.c Mon Jan 26 22:44:11 2009 (r4011)
+++ amr/amrnbfloatdec.c Tue Jan 27 06:34:33 2009 (r4012)
@@ -501,8 +501,9 @@ static void decode_pitch_lag_3(AMRContex
p->pitch_lag_frac = 0;
}else if(pitch_index < 12) {
// 1/3 fractional precision for [t1_temp-1 2/3, t1_temp+2/3]
- p->pitch_lag_int = ( ((pitch_index - 5)*10923)>>15 ) + t1_temp - 1;
+ p->pitch_lag_int = ( ((pitch_index - 5)*10923)>>15 ) - 1;
p->pitch_lag_frac = pitch_index - p->pitch_lag_int*3 - 9;
+ p->pitch_lag_int += t1_temp;
}else {
// integer only precision for [t1_temp+1, t1_temp+4]
p->pitch_lag_int = pitch_index + t1_temp - 11;
1
0
[soc]: r4011 - in libavfilter/diffs: 01_ffplay_filters.diff 02_ffmpeg_filters.diff
by stefano 26 Jan '09
by stefano 26 Jan '09
26 Jan '09
Author: stefano
Date: Mon Jan 26 22:44:11 2009
New Revision: 4011
Log:
Add checks for the validity of the parsed graph, fix crashes.
Modified:
libavfilter/diffs/01_ffplay_filters.diff
libavfilter/diffs/02_ffmpeg_filters.diff
Modified: libavfilter/diffs/01_ffplay_filters.diff
==============================================================================
--- libavfilter/diffs/01_ffplay_filters.diff Mon Jan 26 22:28:54 2009 (r4010)
+++ libavfilter/diffs/01_ffplay_filters.diff Mon Jan 26 22:44:11 2009 (r4011)
@@ -211,7 +211,7 @@ Index: ffplay.c
/* update the bitmap content */
SDL_UnlockYUVOverlay(vp->bmp);
-@@ -1335,54 +1406,264 @@
+@@ -1335,54 +1406,266 @@
return queue_picture(is, src_frame, pts);
}
@@ -435,6 +435,8 @@ Index: ffplay.c
+ }
+ avfilter_graph_add_filter(graph, filt_src);
+ avfilter_graph_add_filter(graph, filt_out);
++
++ if(avfilter_graph_check_validity(graph, NULL)) goto the_end;
+ if(avfilter_graph_config_formats(graph)) goto the_end;
+ if(avfilter_config_links(filt_out)) goto the_end;
+
@@ -507,7 +509,7 @@ Index: ffplay.c
av_free(frame);
return 0;
}
-@@ -2168,6 +2449,12 @@
+@@ -2168,6 +2451,12 @@
/* free all pictures */
for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
vp = &is->pictq[i];
@@ -520,7 +522,7 @@ Index: ffplay.c
if (vp->bmp) {
SDL_FreeYUVOverlay(vp->bmp);
vp->bmp = NULL;
-@@ -2505,6 +2792,9 @@
+@@ -2505,6 +2794,9 @@
{ "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options", "bit_mask" },
{ "sync", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
{ "threads", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
@@ -530,7 +532,7 @@ Index: ffplay.c
{ "default", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
{ NULL, },
};
-@@ -2553,7 +2843,9 @@
+@@ -2553,7 +2845,9 @@
avctx_opts[i]= avcodec_alloc_context2(i);
}
avformat_opts = av_alloc_format_context();
Modified: libavfilter/diffs/02_ffmpeg_filters.diff
==============================================================================
--- libavfilter/diffs/02_ffmpeg_filters.diff Mon Jan 26 22:28:54 2009 (r4010)
+++ libavfilter/diffs/02_ffmpeg_filters.diff Mon Jan 26 22:44:11 2009 (r4011)
@@ -40,7 +40,7 @@ Index: ffmpeg.c
} AVInputStream;
typedef struct AVInputFile {
-@@ -301,6 +318,174 @@
+@@ -301,6 +318,176 @@
static struct termios oldtty;
#endif
@@ -200,6 +200,8 @@ Index: ffmpeg.c
+ }
+
+ /* configure all the filter links */
++ if(avfilter_graph_check_validity(filt_graph_all, NULL))
++ return -1;
+ if(avfilter_graph_config_formats(filt_graph_all))
+ return -1;
+ if(avfilter_config_links(ist->out_video_filter))
@@ -215,7 +217,7 @@ Index: ffmpeg.c
static void term_exit(void)
{
#if HAVE_TERMIOS_H
-@@ -886,6 +1071,9 @@
+@@ -886,6 +1073,9 @@
if (nb_frames <= 0)
return;
@@ -225,7 +227,7 @@ Index: ffmpeg.c
if (ost->video_crop) {
if (av_picture_crop((AVPicture *)&picture_crop_temp, (AVPicture *)in_picture, dec->pix_fmt, ost->topBand, ost->leftBand) < 0) {
av_log(NULL, AV_LOG_ERROR, "error cropping picture\n");
-@@ -897,6 +1085,7 @@
+@@ -897,6 +1087,7 @@
} else {
formatted_picture = in_picture;
}
@@ -233,7 +235,7 @@ Index: ffmpeg.c
final_picture = formatted_picture;
padding_src = formatted_picture;
-@@ -914,12 +1103,14 @@
+@@ -914,12 +1105,14 @@
}
}
@@ -248,7 +250,7 @@ Index: ffmpeg.c
if (ost->video_pad) {
av_picture_pad((AVPicture*)final_picture, (AVPicture *)padding_src,
-@@ -1190,6 +1381,7 @@
+@@ -1190,6 +1383,7 @@
static short *samples= NULL;
AVSubtitle subtitle, *subtitle_to_free;
int got_subtitle;
@@ -256,7 +258,7 @@ Index: ffmpeg.c
if(ist->next_pts == AV_NOPTS_VALUE)
ist->next_pts= ist->pts;
-@@ -1307,6 +1499,15 @@
+@@ -1307,6 +1501,15 @@
&buffer_to_free);
}
@@ -272,7 +274,7 @@ Index: ffmpeg.c
// preprocess audio (volume)
if (ist->st->codec->codec_type == CODEC_TYPE_AUDIO) {
if (audio_volume != 256) {
-@@ -1328,10 +1529,16 @@
+@@ -1328,10 +1531,16 @@
if (pts > now)
usleep(pts - now);
}
@@ -290,7 +292,7 @@ Index: ffmpeg.c
for(i=0;i<nb_ostreams;i++) {
int frame_size;
-@@ -1354,6 +1561,9 @@
+@@ -1354,6 +1563,9 @@
do_audio_out(os, ost, ist, data_buf, data_size);
break;
case CODEC_TYPE_VIDEO:
@@ -300,7 +302,7 @@ Index: ffmpeg.c
do_video_out(os, ost, ist, &picture, &frame_size);
if (vstats_filename && frame_size)
do_video_stats(os, ost, frame_size);
-@@ -1411,7 +1621,15 @@
+@@ -1411,7 +1623,15 @@
av_free_packet(&opkt);
}
}
@@ -316,7 +318,7 @@ Index: ffmpeg.c
av_free(buffer_to_free);
/* XXX: allocate the subtitles in the codec ? */
if (subtitle_to_free) {
-@@ -1842,10 +2060,21 @@
+@@ -1842,10 +2062,21 @@
fprintf(stderr, "Cannot get resampling context\n");
av_exit(1);
}
@@ -338,7 +340,7 @@ Index: ffmpeg.c
break;
case CODEC_TYPE_SUBTITLE:
ost->encoding_needed = 1;
-@@ -3835,6 +4064,9 @@
+@@ -3835,6 +4066,9 @@
#if CONFIG_VHOOK
{ "vhook", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)add_frame_hooker}, "insert video processing module", "module" },
#endif
1
0
[soc]: r4010 - in libavfilter: allfilters.c checkout.sh diffs/01_ffplay_filters.diff diffs/02_ffmpeg_filters.diff
by stefano 26 Jan '09
by stefano 26 Jan '09
26 Jan '09
Author: stefano
Date: Mon Jan 26 22:28:54 2009
New Revision: 4010
Log:
Update to FFmpeg r16809.
Modified:
libavfilter/allfilters.c
libavfilter/checkout.sh
libavfilter/diffs/01_ffplay_filters.diff
libavfilter/diffs/02_ffmpeg_filters.diff
Modified: libavfilter/allfilters.c
==============================================================================
--- libavfilter/allfilters.c Mon Jan 26 20:20:40 2009 (r4009)
+++ libavfilter/allfilters.c Mon Jan 26 22:28:54 2009 (r4010)
@@ -24,7 +24,7 @@
#define REGISTER_FILTER(X,x,y) { \
extern AVFilter avfilter_##y##_##x ; \
- if(ENABLE_##X##_FILTER ) avfilter_register(&avfilter_##y##_##x ); }
+ if(CONFIG_##X##_FILTER ) avfilter_register(&avfilter_##y##_##x ); }
void avfilter_register_all(void)
{
Modified: libavfilter/checkout.sh
==============================================================================
--- libavfilter/checkout.sh Mon Jan 26 20:20:40 2009 (r4009)
+++ libavfilter/checkout.sh Mon Jan 26 22:28:54 2009 (r4010)
@@ -1,7 +1,7 @@
#! /bin/sh
echo "checking out pristine ffmpeg"
-svn checkout svn://svn.ffmpeg.org/ffmpeg/trunk/ ffmpeg -r16562
+svn checkout svn://svn.ffmpeg.org/ffmpeg/trunk/ ffmpeg -r16809
echo "patching ffmpeg"
for diff in $(ls $(pwd)/diffs/*.diff); do patch -d ffmpeg -p0 -i $diff; done
Modified: libavfilter/diffs/01_ffplay_filters.diff
==============================================================================
--- libavfilter/diffs/01_ffplay_filters.diff Mon Jan 26 20:20:40 2009 (r4009)
+++ libavfilter/diffs/01_ffplay_filters.diff Mon Jan 26 22:28:54 2009 (r4010)
@@ -1,12 +1,12 @@
Index: ffplay.c
===================================================================
---- ffplay.c (revision 16562)
+--- ffplay.c (revision 16809)
+++ ffplay.c (working copy)
@@ -29,6 +29,12 @@
#include "libavcodec/audioconvert.h"
#include "libavcodec/opt.h"
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+# include "libavfilter/avfilter.h"
+# include "libavfilter/avfiltergraph.h"
+# include "libavfilter/graphparser.h"
@@ -19,7 +19,7 @@ Index: ffplay.c
/* NOTE: the size must be big enough to compensate the hardware audio buffersize size */
#define SAMPLE_ARRAY_SIZE (2*65536)
-+#if !ENABLE_AVFILTER
++#if !CONFIG_AVFILTER
static int sws_flags = SWS_BICUBIC;
+#endif
@@ -32,7 +32,7 @@ Index: ffplay.c
+ enum PixelFormat pix_fmt;
int allocated;
+
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+ AVFilterPicRef *picref;
+#endif
} VideoPicture;
@@ -43,7 +43,7 @@ Index: ffplay.c
char filename[1024];
int width, height, xleft, ytop;
+
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+ AVFilterContext *out_video_filter; ///<the last filter in the video chain
+#endif
} VideoState;
@@ -53,7 +53,7 @@ Index: ffplay.c
static int error_recognition = FF_ER_CAREFUL;
static int error_concealment = 3;
static int decoder_reorder_pts= 0;
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+static char *vfilters = NULL;
+#endif
@@ -63,7 +63,7 @@ Index: ffplay.c
vp = &is->pictq[is->pictq_rindex];
if (vp->bmp) {
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+ if (vp->picref->pixel_aspect.num == 0)
+ aspect_ratio = 0;
+ else
@@ -89,7 +89,7 @@ Index: ffplay.c
} else if(!is_full_screen && screen_width){
w = screen_width;
h = screen_height;
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+ }else if (is->out_video_filter && is->out_video_filter->inputs[0]){
+ w = is->out_video_filter->inputs[0]->w;
+ h = is->out_video_filter->inputs[0]->h;
@@ -105,7 +105,7 @@ Index: ffplay.c
if (vp->bmp)
SDL_FreeYUVOverlay(vp->bmp);
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+ if (vp->picref)
+ avfilter_unref_pic(vp->picref);
+ vp->picref = NULL;
@@ -140,7 +140,7 @@ Index: ffplay.c
VideoPicture *vp;
int dst_pix_fmt;
AVPicture pict;
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+ AVPicture pict_src;
+#else
static struct SwsContext *img_convert_ctx;
@@ -153,7 +153,7 @@ Index: ffplay.c
/* alloc or resize hardware picture buffer */
if (!vp->bmp ||
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+ vp->width != is->out_video_filter->inputs[0]->w ||
+ vp->height != is->out_video_filter->inputs[0]->h) {
+#else
@@ -167,7 +167,7 @@ Index: ffplay.c
/* if the frame is not skipped, then display it */
if (vp->bmp) {
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+ if(vp->picref)
+ avfilter_unref_pic(vp->picref);
+ vp->picref = src_frame->opaque;
@@ -181,7 +181,7 @@ Index: ffplay.c
pict.linesize[1] = vp->bmp->pitches[2];
pict.linesize[2] = vp->bmp->pitches[1];
+
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+ pict_src.data[0] = src_frame->data[0];
+ pict_src.data[1] = src_frame->data[1];
+ pict_src.data[2] = src_frame->data[2];
@@ -253,7 +253,7 @@ Index: ffplay.c
+ return 0;
+}
+
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+typedef struct {
+ VideoState *is;
+ AVFrame *frame;
@@ -388,7 +388,7 @@ Index: ffplay.c
+ { .name = NULL }},
+ .outputs = (AVFilterPad[]) {{ .name = NULL }},
+};
-+#endif /* ENABLE_AVFILTER */
++#endif /* CONFIG_AVFILTER */
+
static int video_thread(void *arg)
{
@@ -401,7 +401,7 @@ Index: ffplay.c
+ int ret;
+
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+ AVFilterContext *filt_src = NULL, *filt_out = NULL;
+ AVFilterGraph *graph = av_mallocz(sizeof(AVFilterGraph));
+
@@ -443,7 +443,7 @@ Index: ffplay.c
+
for(;;) {
- while (is->paused && !is->videoq.abort_request) {
-+#if !ENABLE_AVFILTER
++#if !CONFIG_AVFILTER
+ AVPacket pkt;
+#endif
+ while (is->paused && !is->videoq.abort_request)
@@ -451,7 +451,7 @@ Index: ffplay.c
- }
- if (packet_queue_get(&is->videoq, pkt, 1) < 0)
- break;
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+ ret = get_filtered_video_frame(filt_out, frame, &pts_int);
+#else
+ ret = get_video_frame(is, frame, &pts_int, &pkt);
@@ -474,7 +474,7 @@ Index: ffplay.c
+ pts = pts_int;
+ pts /= AV_TIME_BASE;
+ ret = output_picture2(is, frame, pts);
-+#if !ENABLE_AVFILTER
++#if !CONFIG_AVFILTER
+ av_free_packet(&pkt);
+#endif
+ if (ret < 0)
@@ -501,17 +501,17 @@ Index: ffplay.c
stream_pause(cur_stream);
}
the_end:
-+ #if ENABLE_AVFILTER
++ #if CONFIG_AVFILTER
+ avfilter_destroy_graph(graph);
+ #endif
av_free(frame);
return 0;
}
-@@ -2170,6 +2451,12 @@
+@@ -2168,6 +2449,12 @@
/* free all pictures */
for(i=0;i<VIDEO_PICTURE_QUEUE_SIZE; i++) {
vp = &is->pictq[i];
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+ if (vp->picref) {
+ avfilter_unref_pic(vp->picref);
+ vp->picref = NULL;
@@ -520,21 +520,21 @@ Index: ffplay.c
if (vp->bmp) {
SDL_FreeYUVOverlay(vp->bmp);
vp->bmp = NULL;
-@@ -2507,6 +2794,9 @@
+@@ -2505,6 +2792,9 @@
{ "ec", OPT_INT | HAS_ARG | OPT_EXPERT, {(void*)&error_concealment}, "set error concealment options", "bit_mask" },
{ "sync", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
{ "threads", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+ { "vfilters", OPT_STRING | HAS_ARG, {(void*)&vfilters}, "video filters", "filter list" },
+#endif
{ "default", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
{ NULL, },
};
-@@ -2555,7 +2845,9 @@
+@@ -2553,7 +2843,9 @@
avctx_opts[i]= avcodec_alloc_context2(i);
}
avformat_opts = av_alloc_format_context();
-+#if !ENABLE_AVFILTER
++#if !CONFIG_AVFILTER
sws_opts = sws_getContext(16,16,0, 16,16,0, sws_flags, NULL,NULL,NULL);
+#endif
Modified: libavfilter/diffs/02_ffmpeg_filters.diff
==============================================================================
--- libavfilter/diffs/02_ffmpeg_filters.diff Mon Jan 26 20:20:40 2009 (r4009)
+++ libavfilter/diffs/02_ffmpeg_filters.diff Mon Jan 26 22:28:54 2009 (r4010)
@@ -1,26 +1,26 @@
Index: ffmpeg.c
===================================================================
---- ffmpeg.c (revision 16562)
+--- ffmpeg.c (revision 16809)
+++ ffmpeg.c (working copy)
@@ -41,6 +41,13 @@
#include "libavutil/avstring.h"
#include "libavformat/os_support.h"
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+# include "libavfilter/avfilter.h"
+# include "libavfilter/avfiltergraph.h"
+# include "libavfilter/graphparser.h"
+# include "libavfilter/vsrc_buffer.h"
+#endif
+
- #ifdef HAVE_SYS_RESOURCE_H
+ #if HAVE_SYS_RESOURCE_H
#include <sys/types.h>
#include <sys/resource.h>
@@ -148,6 +155,9 @@
static int loop_input = 0;
static int loop_output = AVFMT_NOOUTPUTLOOP;
static int qp_hist = 0;
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+static char *vfilters = NULL;
+#endif
@@ -30,7 +30,7 @@ Index: ffmpeg.c
is not defined */
int64_t pts; /* current pts */
int is_start; /* is 1 at the start and after a discontinuity */
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+ AVFilterContext *out_video_filter;
+ AVFilterContext *input_video_filter;
+ AVFrame *filter_frame;
@@ -44,7 +44,7 @@ Index: ffmpeg.c
static struct termios oldtty;
#endif
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+typedef struct {
+ int pix_fmt;
+} FilterOutPriv;
@@ -210,16 +210,16 @@ Index: ffmpeg.c
+
+ return 0;
+}
-+#endif /* ENABLE_AVFILTER */
++#endif /* CONFIG_AVFILTER */
+
static void term_exit(void)
{
- #ifdef HAVE_TERMIOS_H
+ #if HAVE_TERMIOS_H
@@ -886,6 +1071,9 @@
if (nb_frames <= 0)
return;
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+ formatted_picture = in_picture;
+#else
if (ost->video_crop) {
@@ -237,7 +237,7 @@ Index: ffmpeg.c
}
}
-+#if !ENABLE_AVFILTER
++#if !CONFIG_AVFILTER
if (ost->video_resample) {
padding_src = NULL;
final_picture = &ost->pict_tmp;
@@ -260,7 +260,7 @@ Index: ffmpeg.c
&buffer_to_free);
}
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+ if (ist->st->codec->codec_type == CODEC_TYPE_VIDEO && ist->input_video_filter) {
+ // add it to be filtered
+ av_vsrc_buffer_add_frame(ist->input_video_filter, &picture,
@@ -282,7 +282,7 @@ Index: ffmpeg.c
/* if output time reached then transcode raw format,
encode packets and output them */
if (start_time == 0 || ist->pts >= start_time)
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+ while(loop) {
+ if (ist->st->codec->codec_type == CODEC_TYPE_VIDEO && ist->out_video_filter)
+ get_filtered_video_pic(ist->out_video_filter, &ist->picref, &picture, &ist->pts);
@@ -294,7 +294,7 @@ Index: ffmpeg.c
do_audio_out(os, ost, ist, data_buf, data_size);
break;
case CODEC_TYPE_VIDEO:
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+ ost->st->codec->sample_aspect_ratio = ist->picref->pixel_aspect;
+#endif
do_video_out(os, ost, ist, &picture, &frame_size);
@@ -308,7 +308,7 @@ Index: ffmpeg.c
+ ist->out_video_filter && avfilter_poll_frame(ist->out_video_filter->inputs[0]);
}
+
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+ if(ist->picref)
+ avfilter_unref_pic(ist->picref);
+ }
@@ -316,11 +316,11 @@ Index: ffmpeg.c
av_free(buffer_to_free);
/* XXX: allocate the subtitles in the codec ? */
if (subtitle_to_free) {
-@@ -1840,10 +2058,21 @@
+@@ -1842,10 +2060,21 @@
fprintf(stderr, "Cannot get resampling context\n");
av_exit(1);
}
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+ ost->resample_height = icodec->height;
+#else
ost->resample_height = icodec->height - (frame_topBand + frame_bottomBand);
@@ -329,7 +329,7 @@ Index: ffmpeg.c
ost->encoding_needed = 1;
ist->decoding_needed = 1;
+
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+ if (configure_filters(ist, ost)) {
+ fprintf(stderr, "Error opening filters!\n");
+ exit(1);
@@ -338,11 +338,11 @@ Index: ffmpeg.c
break;
case CODEC_TYPE_SUBTITLE:
ost->encoding_needed = 1;
-@@ -3831,6 +4060,9 @@
- #ifdef CONFIG_VHOOK
+@@ -3835,6 +4064,9 @@
+ #if CONFIG_VHOOK
{ "vhook", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)add_frame_hooker}, "insert video processing module", "module" },
#endif
-+#if ENABLE_AVFILTER
++#if CONFIG_AVFILTER
+ { "vfilters", OPT_STRING | HAS_ARG, {(void*)&vfilters}, "video filters", "filter list" },
+#endif
{ "intra_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_intra_matrix}, "specify intra matrix coeffs", "matrix" },
1
0
Author: vitor
Date: Mon Jan 26 20:20:40 2009
New Revision: 4009
Log:
Fix "-vcodec copy" when using a libavfilter patched ffmpeg.
Patch by Cédric Schieli cschieli ! gmail ! com
Modified:
libavfilter/diffs/02_ffmpeg_filters.diff
Modified: libavfilter/diffs/02_ffmpeg_filters.diff
==============================================================================
--- libavfilter/diffs/02_ffmpeg_filters.diff Mon Jan 26 15:07:28 2009 (r4008)
+++ libavfilter/diffs/02_ffmpeg_filters.diff Mon Jan 26 20:20:40 2009 (r4009)
@@ -261,7 +261,7 @@ Index: ffmpeg.c
}
+#if ENABLE_AVFILTER
-+ if (ist->st->codec->codec_type == CODEC_TYPE_VIDEO) {
++ if (ist->st->codec->codec_type == CODEC_TYPE_VIDEO && ist->input_video_filter) {
+ // add it to be filtered
+ av_vsrc_buffer_add_frame(ist->input_video_filter, &picture,
+ ist->pts,
@@ -278,13 +278,13 @@ Index: ffmpeg.c
}
-
+ loop = ist->st->codec->codec_type != CODEC_TYPE_VIDEO ||
-+ avfilter_poll_frame(ist->out_video_filter->inputs[0]);
++ !ist->out_video_filter || avfilter_poll_frame(ist->out_video_filter->inputs[0]);
/* if output time reached then transcode raw format,
encode packets and output them */
if (start_time == 0 || ist->pts >= start_time)
+#if ENABLE_AVFILTER
+ while(loop) {
-+ if (ist->st->codec->codec_type == CODEC_TYPE_VIDEO)
++ if (ist->st->codec->codec_type == CODEC_TYPE_VIDEO && ist->out_video_filter)
+ get_filtered_video_pic(ist->out_video_filter, &ist->picref, &picture, &ist->pts);
+#endif
for(i=0;i<nb_ostreams;i++) {
@@ -305,7 +305,7 @@ Index: ffmpeg.c
}
}
+ loop = (ist->st->codec->codec_type == CODEC_TYPE_VIDEO) &&
-+ avfilter_poll_frame(ist->out_video_filter->inputs[0]);
++ ist->out_video_filter && avfilter_poll_frame(ist->out_video_filter->inputs[0]);
}
+
+#if ENABLE_AVFILTER
1
0
26 Jan '09
Author: kostya
Date: Mon Jan 26 15:07:28 2009
New Revision: 4008
Log:
Split out from AAC encoder core file all functions with heuristics for selecting
scalefactors, band codebooks, etc.
Added:
aacenc/aaccoder.c
- copied, changed from r4006, aacenc/aacenc.c
aacenc/aacenc.h
- copied, changed from r4006, aacenc/aacenc.c
Modified:
aacenc/aac_enc.patch
aacenc/aacenc.c
Modified: aacenc/aac_enc.patch
==============================================================================
--- aacenc/aac_enc.patch Mon Jan 26 15:00:57 2009 (r4007)
+++ aacenc/aac_enc.patch Mon Jan 26 15:07:28 2009 (r4008)
@@ -2,14 +2,14 @@ diff --git a/libavcodec/Makefile b/libav
index d4f6d1c..0ed9057 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
-@@ -25,6 +25,7 @@
-
- OBJS-$(CONFIG_ENCODERS) += faandct.o jfdctfst.o jfdctint.o
+@@ -33,6 +33,7 @@
-+OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o aacpsy.o aactab.o psymodel.o iirfilter.o mdct.o fft.o mpeg4audio.o
- OBJS-$(CONFIG_AAC_DECODER) += aac.o aactab.o mdct.o fft.o
- OBJS-$(CONFIG_AASC_DECODER) += aasc.o
- OBJS-$(CONFIG_AC3_DECODER) += ac3dec.o ac3tab.o ac3dec_data.o ac3.o mdct.o fft.o
+ # decoders/encoders
+ OBJS-$(CONFIG_AAC_DECODER) += aac.o aactab.o
++OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o aaccoder.o aacpsy.o aactab.o psymodel.o iirfilter.o mdct.o fft.o mpeg4audio.o
+ OBJS-$(CONFIG_AASC_DECODER) += aasc.o msrledec.o
+ OBJS-$(CONFIG_AC3_DECODER) += eac3dec.o ac3dec.o ac3tab.o ac3dec_data.o ac3.o
+ OBJS-$(CONFIG_AC3_ENCODER) += ac3enc.o ac3tab.o ac3.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 33a4242..6871496 100644
--- a/libavcodec/allcodecs.c
Copied and modified: aacenc/aaccoder.c (from r4006, aacenc/aacenc.c)
==============================================================================
--- aacenc/aacenc.c Mon Jan 26 14:37:36 2009 (r4006, copy source)
+++ aacenc/aaccoder.c Mon Jan 26 15:07:28 2009 (r4008)
@@ -1,6 +1,6 @@
/*
- * AAC encoder
- * Copyright (C) 2008 Konstantin Shishkov
+ * AAC coefficients encoder
+ * Copyright (C) 2008-2009 Konstantin Shishkov
*
* This file is part of FFmpeg.
*
@@ -20,106 +20,16 @@
*/
/**
- * @file aacenc.c
- * AAC encoder
+ * @file aaccoder.c
+ * AAC coefficients encoder
*/
-/***********************************
- * TODOs:
- * speedup quantizer selection
- * add sane pulse detection
- * add temporal noise shaping
- ***********************************/
-
#include "avcodec.h"
#include "bitstream.h"
-#include "dsputil.h"
-#include "mpeg4audio.h"
-
#include "aac.h"
+#include "aacenc.h"
#include "aactab.h"
-#include "psymodel.h"
-
-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
-};
-
-static const uint8_t *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
-};
-
-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_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_128[] = {
- /* the last entry on the following row is swb_size_128_64 but is a
- duplicate of swb_size_128_96 */
- swb_size_128_96, swb_size_128_96, swb_size_128_96,
- 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
-};
-
/** bits needed to code codebook run value for long windows */
static const uint8_t run_value_bits_long[64] = {
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
@@ -137,199 +47,6 @@ static const uint8_t* run_value_bits[2]
run_value_bits_long, run_value_bits_short
};
-/** default channel configurations */
-static const uint8_t aac_chan_configs[6][5] = {
- {1, TYPE_SCE}, // 1 channel - single channel element
- {1, TYPE_CPE}, // 2 channels - channel pair
- {2, TYPE_SCE, TYPE_CPE}, // 3 channels - center + stereo
- {3, TYPE_SCE, TYPE_CPE, TYPE_SCE}, // 4 channels - front center + stereo + back center
- {3, TYPE_SCE, TYPE_CPE, TYPE_CPE}, // 5 channels - front center + stereo + back stereo
- {4, TYPE_SCE, TYPE_CPE, TYPE_CPE, TYPE_LFE}, // 6 channels - front center + stereo + back stereo + LFE
-};
-
-/**
- * AAC encoder context
- */
-typedef struct {
- PutBitContext pb;
- MDCTContext mdct1024; ///< long (1024 samples) frame transform context
- MDCTContext mdct128; ///< short (128 samples) frame transform context
- DSPContext dsp;
- DECLARE_ALIGNED_16(FFTSample, output[2048]); ///< temporary buffer for MDCT input coefficients
- int16_t* samples; ///< saved preprocessed input
-
- int samplerate_index; ///< MPEG-4 samplerate index
-
- ChannelElement *cpe; ///< channel elements
- FFPsyContext psy;
- struct FFPsyPreprocessContext* psypp;
- int cur_channel;
- int last_frame;
- float lambda;
-} AACEncContext;
-
-/**
- * Make AAC audio config object.
- * @see 1.6.2.1 "Syntax - AudioSpecificConfig"
- */
-static void put_audio_specific_config(AVCodecContext *avctx)
-{
- PutBitContext pb;
- AACEncContext *s = avctx->priv_data;
-
- init_put_bits(&pb, avctx->extradata, avctx->extradata_size*8);
- put_bits(&pb, 5, 2); //object type - AAC-LC
- put_bits(&pb, 4, s->samplerate_index); //sample rate index
- put_bits(&pb, 4, avctx->channels);
- //GASpecificConfig
- put_bits(&pb, 1, 0); //frame length - 1024 samples
- put_bits(&pb, 1, 0); //does not depend on core coder
- put_bits(&pb, 1, 0); //is not extension
- flush_put_bits(&pb);
-}
-
-static av_cold int aac_encode_init(AVCodecContext *avctx)
-{
- AACEncContext *s = avctx->priv_data;
- int i;
- const uint8_t *sizes[2];
- int lengths[2];
-
- avctx->frame_size = 1024;
-
- for(i = 0; i < 16; i++)
- if(avctx->sample_rate == ff_mpeg4audio_sample_rates[i])
- break;
- if(i == 16){
- av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate %d\n", avctx->sample_rate);
- return -1;
- }
- if(avctx->channels > 6){
- av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %d\n", avctx->channels);
- return -1;
- }
- s->samplerate_index = i;
-
- dsputil_init(&s->dsp, avctx);
- ff_mdct_init(&s->mdct1024, 11, 0);
- ff_mdct_init(&s->mdct128, 8, 0);
- // window init
- ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024);
- ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128);
- ff_sine_window_init(ff_sine_1024, 1024);
- ff_sine_window_init(ff_sine_128, 128);
-
- s->samples = av_malloc(2 * 1024 * avctx->channels * sizeof(s->samples[0]));
- s->cpe = av_mallocz(sizeof(ChannelElement) * aac_chan_configs[avctx->channels-1][0]);
- avctx->extradata = av_malloc(2);
- avctx->extradata_size = 2;
- put_audio_specific_config(avctx);
-
- sizes[0] = swb_size_1024[i];
- sizes[1] = swb_size_128[i];
- lengths[0] = ff_aac_num_swb_1024[i];
- lengths[1] = ff_aac_num_swb_128[i];
- ff_psy_init(&s->psy, avctx, 2, sizes, lengths);
- s->psypp = ff_psy_preprocess_init(avctx);
-
-#if !CONFIG_HARDCODED_TABLES
- for (i = 0; i < 316; i++)
- ff_aac_pow2sf_tab[i] = pow(2, (i - 200)/4.);
-#endif /* CONFIG_HARDCODED_TABLES */
-
- return 0;
-}
-
-static void apply_window_and_mdct(AVCodecContext *avctx, AACEncContext *s,
- SingleChannelElement *sce, short *audio, int channel)
-{
- int i, j, k;
- const float * lwindow = sce->ics.use_kb_window[0] ? ff_aac_kbd_long_1024 : ff_sine_1024;
- const float * swindow = sce->ics.use_kb_window[0] ? ff_aac_kbd_short_128 : ff_sine_128;
- const float * pwindow = sce->ics.use_kb_window[1] ? ff_aac_kbd_short_128 : ff_sine_128;
-
- if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) {
- memcpy(s->output, sce->saved, sizeof(float)*1024);
- if(sce->ics.window_sequence[0] == LONG_STOP_SEQUENCE){
- memset(s->output, 0, sizeof(s->output[0]) * 448);
- for(i = 448; i < 576; i++)
- s->output[i] = sce->saved[i] * pwindow[i - 448];
- for(i = 576; i < 704; i++)
- s->output[i] = sce->saved[i];
- }
- if(sce->ics.window_sequence[0] != LONG_START_SEQUENCE){
- j = channel;
- for (i = 0; i < 1024; i++, j += avctx->channels){
- s->output[i+1024] = audio[j] * lwindow[1024 - i - 1];
- sce->saved[i] = audio[j] * lwindow[i];
- }
- }else{
- j = channel;
- for(i = 0; i < 448; i++, j += avctx->channels)
- s->output[i+1024] = audio[j];
- for(i = 448; i < 576; i++, j += avctx->channels)
- s->output[i+1024] = audio[j] * swindow[576 - i - 1];
- memset(s->output+1024+576, 0, sizeof(s->output[0]) * 448);
- j = channel;
- for(i = 0; i < 1024; i++, j += avctx->channels)
- sce->saved[i] = audio[j];
- }
- ff_mdct_calc(&s->mdct1024, sce->coeffs, s->output);
- }else{
- j = channel;
- for (k = 0; k < 1024; k += 128) {
- for(i = 448 + k; i < 448 + k + 256; i++)
- s->output[i - 448 - k] = (i < 1024)
- ? sce->saved[i]
- : audio[channel + (i-1024)*avctx->channels];
- s->dsp.vector_fmul (s->output, k ? swindow : pwindow, 128);
- s->dsp.vector_fmul_reverse(s->output+128, s->output+128, swindow, 128);
- ff_mdct_calc(&s->mdct128, sce->coeffs + k, s->output);
- }
- j = channel;
- for(i = 0; i < 1024; i++, j += avctx->channels)
- sce->saved[i] = audio[j];
- }
-}
-
-/**
- * Encode ics_info element.
- * @see Table 4.6 (syntax of ics_info)
- */
-static void put_ics_info(AACEncContext *s, IndividualChannelStream *info)
-{
- int w;
-
- put_bits(&s->pb, 1, 0); // ics_reserved bit
- put_bits(&s->pb, 2, info->window_sequence[0]);
- put_bits(&s->pb, 1, info->use_kb_window[0]);
- if(info->window_sequence[0] != EIGHT_SHORT_SEQUENCE){
- put_bits(&s->pb, 6, info->max_sfb);
- put_bits(&s->pb, 1, 0); // no prediction
- }else{
- put_bits(&s->pb, 4, info->max_sfb);
- for(w = 1; w < 8; w++){
- put_bits(&s->pb, 1, !info->group_len[w]);
- }
- }
-}
-
-/**
- * Encode MS data.
- * @see 4.6.8.1 "Joint Coding - M/S Stereo"
- */
-static void encode_ms_info(PutBitContext *pb, ChannelElement *cpe)
-{
- int i, w;
-
- put_bits(pb, 2, cpe->ms_mode);
- if(cpe->ms_mode == 1){
- for(w = 0; w < cpe->ch[0].ics.num_windows; w += cpe->ch[0].ics.group_len[w]){
- for(i = 0; i < cpe->ch[0].ics.max_sfb; i++)
- put_bits(pb, 1, cpe->ms_mask[w*16 + i]);
- }
- }
-}
/**
* Quantize one coefficient.
@@ -381,13 +98,13 @@ static float quantize_band_cost(const fl
float mincost;
int minidx = 0;
int minbits = 0;
- int quants[4][2], realquants[4][2];
+ int quants[4][2];
mincost = 0.0f;
for(j = 0; j < dim; j++){
- realquants[j][0] = quant2(in[i+j], Q);
- realquants[j][1] = quant (in[i+j], Q);
+ quants[j][0] = quant2(in[i+j], Q);
+ quants[j][1] = quant (in[i+j], Q);
for(k = 0; k < 2; k++){
- quants[j][k] = FFMIN(realquants[j][k], maxval);
+ quants[j][k] = FFMIN(quants[j][k], maxval);
if(!IS_CODEBOOK_UNSIGNED(cb) && in[i+j] < 0.0f)
quants[j][k] = -quants[j][k];
}
@@ -428,7 +145,7 @@ static float quantize_band_cost(const fl
di = t - 165140.0f;
curbits += 21;
}else{
- int c = realquants[k];
+ int c = quant(t, Q);
di = t - c*cbrt(c)*IQ;
curbits += av_log2(c)*2 - 4 + 1;
}
@@ -664,7 +381,7 @@ static void quantize_and_encode_band(Put
const float IQ = ff_aac_pow2sf_tab[200 - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];
int i, j, k;
const int dim = cb < FIRST_PAIR_BT ? 4 : 2;
-
+//START_TIMER
if(!cb)
return;
@@ -731,6 +448,7 @@ static void quantize_and_encode_band(Put
}
}
}
+//STOP_TIMER("quantize_and_encode")
}
#endif
@@ -844,65 +562,6 @@ static void encode_window_bands_info(AAC
}
}
-/**
- * Produce integer coefficients from scalefactors provided by the model.
- */
-static void adjust_frame_information(AACEncContext *apc, ChannelElement *cpe, int chans)
-{
- int i, w, w2, g, ch;
- int start, sum, maxsfb, cmaxsfb;
-
- for(ch = 0; ch < chans; ch++){
- IndividualChannelStream *ics = &cpe->ch[ch].ics;
- start = 0;
- maxsfb = 0;
- cpe->ch[ch].pulse.num_pulse = 0;
- for(w = 0; w < ics->num_windows*16; w += 16){
- for(g = 0; g < ics->num_swb; g++){
- sum = 0;
- //apply M/S
- if(!ch && cpe->ms_mask[w + g]){
- for(i = 0; i < ics->swb_sizes[g]; i++){
- cpe->ch[0].coeffs[start+i] = (cpe->ch[0].coeffs[start+i] + cpe->ch[1].coeffs[start+i]) / 2.0;
- cpe->ch[1].coeffs[start+i] = cpe->ch[0].coeffs[start+i] - cpe->ch[1].coeffs[start+i];
- }
- }
- start += ics->swb_sizes[g];
- }
- for(cmaxsfb = ics->num_swb; cmaxsfb > 0 && cpe->ch[ch].zeroes[w+cmaxsfb-1]; cmaxsfb--);
- maxsfb = FFMAX(maxsfb, cmaxsfb);
- }
- ics->max_sfb = maxsfb;
-
- //adjust zero bands for window groups
- for(w = 0; w < ics->num_windows; w += ics->group_len[w]){
- for(g = 0; g < ics->max_sfb; g++){
- i = 1;
- for(w2 = w; w2 < w + ics->group_len[w]; w2++){
- if(!cpe->ch[ch].zeroes[w2*16 + g]){
- i = 0;
- break;
- }
- }
- cpe->ch[ch].zeroes[w*16 + g] = i;
- }
- }
- }
-
- if(chans > 1 && cpe->common_window){
- IndividualChannelStream *ics0 = &cpe->ch[0].ics;
- IndividualChannelStream *ics1 = &cpe->ch[1].ics;
- int msc = 0;
- ics0->max_sfb = FFMAX(ics0->max_sfb, ics1->max_sfb);
- ics1->max_sfb = ics0->max_sfb;
- for(w = 0; w < ics0->num_windows*16; w += 16)
- for(i = 0; i < ics0->max_sfb; i++)
- if(cpe->ms_mask[w+i]) msc++;
- if(msc == 0 || ics0->max_sfb == 0) cpe->ms_mode = 0;
- else cpe->ms_mode = msc < ics0->max_sfb ? 1 : 2;
- }
-}
-
typedef struct TrellisPath {
float cost;
int prev;
@@ -910,7 +569,8 @@ typedef struct TrellisPath {
int max_val;
} TrellisPath;
-static void search_for_quantizers_anmr(AACEncContext *s, SingleChannelElement *sce, const float lambda)
+static void search_for_quantizers_anmr(AVCodecContext *avctx, AACEncContext *s,
+ SingleChannelElement *sce, const float lambda)
{
int q, w, w2, g, start = 0;
int i;
@@ -1186,7 +846,8 @@ static void search_for_quantizers_twoloo
}while(fflag && its < 10);
}
-static void search_for_quantizers_faac(AACEncContext *s, SingleChannelElement *sce, const float lambda)
+static void search_for_quantizers_faac(AVCodecContext *avctx, AACEncContext *s,
+ SingleChannelElement *sce, const float lambda)
{
int start = 0, i, w, w2, g;
float uplim[128], maxq[128];
@@ -1351,7 +1012,8 @@ static void search_for_quantizers_faac(A
}
}
-static void search_for_quantizers_fast(AACEncContext *s, SingleChannelElement *sce)
+static void search_for_quantizers_fast(AVCodecContext *avctx, AACEncContext *s,
+ SingleChannelElement *sce, const float lambda)
{
int start = 0, i, w, w2, g;
int minq = 255;
@@ -1374,7 +1036,7 @@ static void search_for_quantizers_fast(A
}
}
for(i = 0; i < 128; i++){
- sce->sf_idx[i] = av_clip(sce->sf_idx[i], minq, minq + SCALE_MAX_DIFF - 1);
+ sce->sf_idx[i] = 140;//av_clip(sce->sf_idx[i], minq, minq + SCALE_MAX_DIFF - 1);
}
//set the same quantizers inside window groups
for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w])
@@ -1383,15 +1045,6 @@ static void search_for_quantizers_fast(A
sce->sf_idx[(w+w2)*16+g] = sce->sf_idx[w*16+g];
}
-static void search_for_quantizers(AVCodecContext *avctx, AACEncContext *s,
- SingleChannelElement *sce)
-{
- search_for_quantizers_anmr(s, sce, s->lambda);
-// search_for_quantizers_twoloop(avctx, s, sce, s->lambda);
-// search_for_quantizers_faac(s, sce, av_clipf(s->lambda * 2e8, 50.0f, 300.0f));
-// search_for_quantizers_fast(s, sce);
-}
-
static void search_for_ms(AACEncContext *s, ChannelElement *cpe, const float lambda)
{
int start = 0, i, w, w2, g;
@@ -1443,246 +1096,29 @@ static void search_for_ms(AACEncContext
}
}
-/**
- * Encode scalefactor band coding type.
- */
-static void encode_band_info(AACEncContext *s, SingleChannelElement *sce)
-{
- int w;
-
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
- encode_window_bands_info(s, sce, w, sce->ics.group_len[w]);
- }
-}
-
-/**
- * Encode scalefactors.
- */
-static void encode_scale_factors(AVCodecContext *avctx, AACEncContext *s, SingleChannelElement *sce)
-{
- int off = sce->sf_idx[0], diff;
- int i, w;
-
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
- for(i = 0; i < sce->ics.max_sfb; i++){
- if(!sce->zeroes[w*16 + i]){
- diff = sce->sf_idx[w*16 + i] - off + SCALE_DIFF_ZERO;
- if(diff < 0 || diff > 120) av_log(avctx, AV_LOG_ERROR, "Scalefactor difference is too big to be coded\n");
- off = sce->sf_idx[w*16 + i];
- put_bits(&s->pb, ff_aac_scalefactor_bits[diff], ff_aac_scalefactor_code[diff]);
- }
- }
- }
-}
-
-/**
- * Encode pulse data.
- */
-static void encode_pulses(AACEncContext *s, Pulse *pulse)
-{
- int i;
-
- put_bits(&s->pb, 1, !!pulse->num_pulse);
- if(!pulse->num_pulse) return;
-
- put_bits(&s->pb, 2, pulse->num_pulse - 1);
- put_bits(&s->pb, 6, pulse->start);
- for(i = 0; i < pulse->num_pulse; i++){
- put_bits(&s->pb, 5, pulse->pos[i]);
- put_bits(&s->pb, 4, pulse->amp[i]);
- }
-}
-
-/**
- * Encode spectral coefficients processed by psychoacoustic model.
- */
-static void encode_spectral_coeffs(AACEncContext *s, SingleChannelElement *sce)
-{
- int start, i, w, w2;
-
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
- start = 0;
- for(i = 0; i < sce->ics.max_sfb; i++){
- if(sce->zeroes[w*16 + i]){
- start += sce->ics.swb_sizes[i];
- continue;
- }
- for(w2 = w; w2 < w + sce->ics.group_len[w]; w2++){
- quantize_and_encode_band(&s->pb, sce->coeffs + start + w2*128,
- sce->ics.swb_sizes[i],
- sce->sf_idx[w*16 + i],
- sce->band_type[w*16 + i],
- s->lambda);
- }
- start += sce->ics.swb_sizes[i];
- }
- }
-}
-
-/**
- * Encode one channel of audio data.
- */
-static int encode_individual_channel(AVCodecContext *avctx, AACEncContext *s, SingleChannelElement *sce, int common_window)
-{
- put_bits(&s->pb, 8, sce->sf_idx[0]);
- if(!common_window) put_ics_info(s, &sce->ics);
- encode_band_info(s, sce);
- encode_scale_factors(avctx, s, sce);
- encode_pulses(s, &sce->pulse);
- put_bits(&s->pb, 1, 0); //tns
- put_bits(&s->pb, 1, 0); //ssr
- encode_spectral_coeffs(s, sce);
- return 0;
-}
-
-/**
- * Write some auxiliary information about the created AAC file.
- */
-static void put_bitstream_info(AVCodecContext *avctx, AACEncContext *s, const char *name)
-{
- int i, namelen, padbits;
-
- namelen = strlen(name) + 2;
- put_bits(&s->pb, 3, TYPE_FIL);
- put_bits(&s->pb, 4, FFMIN(namelen, 15));
- if(namelen >= 15)
- put_bits(&s->pb, 8, namelen - 16);
- put_bits(&s->pb, 4, 0); //extension type - filler
- padbits = 8 - (put_bits_count(&s->pb) & 7);
- align_put_bits(&s->pb);
- for(i = 0; i < namelen - 2; i++)
- put_bits(&s->pb, 8, name[i]);
- put_bits(&s->pb, 12 - padbits, 0);
-}
-
-static int aac_encode_frame(AVCodecContext *avctx,
- uint8_t *frame, int buf_size, void *data)
-{
- AACEncContext *s = avctx->priv_data;
- int16_t *samples = s->samples, *samples2, *la;
- ChannelElement *cpe;
- int i, j, chans, tag, start_ch;
- const uint8_t *chan_map = aac_chan_configs[avctx->channels-1];
- int chan_el_counter[4];
-
- if(s->last_frame)
- return 0;
- if(data){
- if(!s->psypp){
- memcpy(s->samples + 1024 * avctx->channels, data, 1024 * avctx->channels * sizeof(s->samples[0]));
- }else{
- start_ch = 0;
- samples2 = s->samples + 1024 * avctx->channels;
- for(i = 0; i < chan_map[0]; i++){
- tag = chan_map[i+1];
- chans = tag == TYPE_CPE ? 2 : 1;
- ff_psy_preprocess(s->psypp, (uint16_t*)data + start_ch, samples2 + start_ch, start_ch + i, chans);
- start_ch += chans;
- }
- }
- }
- if(!avctx->frame_number){
- memcpy(s->samples, s->samples + 1024 * avctx->channels, 1024 * avctx->channels * sizeof(s->samples[0]));
- return 0;
- }
-
- init_put_bits(&s->pb, frame, buf_size*8);
- if((avctx->frame_number & 0xFF)==1 && !(avctx->flags & CODEC_FLAG_BITEXACT)){
- put_bitstream_info(avctx, s, LIBAVCODEC_IDENT);
- }
- start_ch = 0;
- memset(chan_el_counter, 0, sizeof(chan_el_counter));
- for(i = 0; i < chan_map[0]; i++){
- FFPsyWindowInfo wi[2];
- tag = chan_map[i+1];
- chans = tag == TYPE_CPE ? 2 : 1;
- cpe = &s->cpe[i];
- samples2 = samples + start_ch;
- la = samples2 + 1024 * avctx->channels + start_ch;
- if(!data) la = NULL;
- s->lambda = 5e-7f;
- for(j = 0; j < chans; j++){
- IndividualChannelStream *ics = &cpe->ch[j].ics;
- int k;
- wi[j] = ff_psy_suggest_window(&s->psy, samples2, la, start_ch + j, ics->window_sequence[0]);
- ics->window_sequence[1] = ics->window_sequence[0];
- ics->window_sequence[0] = wi[j].window_type[0];
- ics->use_kb_window[1] = ics->use_kb_window[0];
- ics->use_kb_window[0] = wi[j].window_shape;
- ics->num_windows = wi[j].num_windows;
- ics->swb_sizes = s->psy.bands [ics->num_windows == 8];
- ics->num_swb = s->psy.num_bands[ics->num_windows == 8];
- for(k = 0; k < ics->num_windows; k++)
- ics->group_len[k] = wi[j].grouping[k];
-
- s->cur_channel = start_ch + j;
- apply_window_and_mdct(avctx, s, &cpe->ch[j], samples2, j);
- search_for_quantizers(avctx, s, &cpe->ch[j]);
- }
- cpe->common_window = 0;
- if(chans > 1
- && wi[0].window_type[0] == wi[1].window_type[0]
- && wi[0].window_shape == wi[1].window_shape){
-
- cpe->common_window = 1;
- for(j = 0; j < wi[0].num_windows; j++){
- if(wi[0].grouping[j] != wi[1].grouping[j]){
- cpe->common_window = 0;
- break;
- }
- }
- }
-// search_for_ms(s, cpe, s->lambda);
- adjust_frame_information(s, cpe, chans);
- put_bits(&s->pb, 3, tag);
- put_bits(&s->pb, 4, chan_el_counter[tag]++);
- if(chans == 2){
- put_bits(&s->pb, 1, cpe->common_window);
- if(cpe->common_window){
- put_ics_info(s, &cpe->ch[0].ics);
- encode_ms_info(&s->pb, cpe);
- }
- }
- for(j = 0; j < chans; j++){
- s->cur_channel = start_ch + j;
- ff_psy_set_band_info(&s->psy, s->cur_channel, cpe->ch[j].coeffs, &wi[j]);
- encode_individual_channel(avctx, s, &cpe->ch[j], cpe->common_window);
- }
- start_ch += chans;
- }
-
- put_bits(&s->pb, 3, TYPE_END);
- flush_put_bits(&s->pb);
- avctx->frame_bits = put_bits_count(&s->pb);
-
- if(!data)
- s->last_frame = 1;
- memcpy(s->samples, s->samples + 1024 * avctx->channels, 1024 * avctx->channels * sizeof(s->samples[0]));
- return put_bits_count(&s->pb)>>3;
-}
-
-static av_cold int aac_encode_end(AVCodecContext *avctx)
-{
- AACEncContext *s = avctx->priv_data;
-
- ff_mdct_end(&s->mdct1024);
- ff_mdct_end(&s->mdct128);
- ff_psy_end(&s->psy);
- ff_psy_preprocess_end(s->psypp);
- av_freep(&s->samples);
- av_freep(&s->cpe);
- return 0;
-}
-
-AVCodec aac_encoder = {
- "aac",
- CODEC_TYPE_AUDIO,
- CODEC_ID_AAC,
- sizeof(AACEncContext),
- aac_encode_init,
- aac_encode_frame,
- aac_encode_end,
- .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY,
- .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE},
- .long_name = NULL_IF_CONFIG_SMALL("Advanced Audio Coding"),
+AACCoefficientsEncoder ff_aac_coders[] = {
+ {
+ search_for_quantizers_anmr,
+ encode_window_bands_info,
+ quantize_and_encode_band,
+// search_for_ms,
+ },
+ {
+ search_for_quantizers_faac,
+ encode_window_bands_info,
+ quantize_and_encode_band,
+// search_for_ms,
+ },
+ {
+ search_for_quantizers_twoloop,
+ encode_window_bands_info,
+ quantize_and_encode_band,
+// search_for_ms,
+ },
+ {
+ search_for_quantizers_fast,
+ encode_window_bands_info,
+ quantize_and_encode_band,
+// search_for_ms,
+ },
};
Modified: aacenc/aacenc.c
==============================================================================
--- aacenc/aacenc.c Mon Jan 26 15:00:57 2009 (r4007)
+++ aacenc/aacenc.c Mon Jan 26 15:07:28 2009 (r4008)
@@ -38,6 +38,7 @@
#include "aac.h"
#include "aactab.h"
+#include "aacenc.h"
#include "psymodel.h"
@@ -120,23 +121,6 @@ static const uint8_t *swb_size_128[] = {
swb_size_128_16, swb_size_128_16, swb_size_128_8
};
-/** bits needed to code codebook run value for long windows */
-static const uint8_t run_value_bits_long[64] = {
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 10,
- 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 15
-};
-
-/** bits needed to code codebook run value for short windows */
-static const uint8_t run_value_bits_short[16] = {
- 3, 3, 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 9
-};
-
-static const uint8_t* run_value_bits[2] = {
- run_value_bits_long, run_value_bits_short
-};
-
/** default channel configurations */
static const uint8_t aac_chan_configs[6][5] = {
{1, TYPE_SCE}, // 1 channel - single channel element
@@ -148,27 +132,6 @@ static const uint8_t aac_chan_configs[6]
};
/**
- * AAC encoder context
- */
-typedef struct {
- PutBitContext pb;
- MDCTContext mdct1024; ///< long (1024 samples) frame transform context
- MDCTContext mdct128; ///< short (128 samples) frame transform context
- DSPContext dsp;
- DECLARE_ALIGNED_16(FFTSample, output[2048]); ///< temporary buffer for MDCT input coefficients
- int16_t* samples; ///< saved preprocessed input
-
- int samplerate_index; ///< MPEG-4 samplerate index
-
- ChannelElement *cpe; ///< channel elements
- FFPsyContext psy;
- struct FFPsyPreprocessContext* psypp;
- int cur_channel;
- int last_frame;
- float lambda;
-} AACEncContext;
-
-/**
* Make AAC audio config object.
* @see 1.6.2.1 "Syntax - AudioSpecificConfig"
*/
@@ -231,6 +194,7 @@ static av_cold int aac_encode_init(AVCod
lengths[1] = ff_aac_num_swb_128[i];
ff_psy_init(&s->psy, avctx, 2, sizes, lengths);
s->psypp = ff_psy_preprocess_init(avctx);
+ s->coder = &ff_aac_coders[0];
#if !CONFIG_HARDCODED_TABLES
for (i = 0; i < 316; i++)
@@ -332,519 +296,6 @@ static void encode_ms_info(PutBitContext
}
/**
- * Quantize one coefficient.
- * @return absolute value of the quantized coefficient
- * @see 3GPP TS26.403 5.6.2 "Scalefactor determination"
- */
-static av_always_inline int quant(float coef, const float Q)
-{
- return av_clip((int)(pow(fabsf(coef) * Q, 0.75) + 0.4054), 0, 8191);
-}
-
-#if 1
-
-static av_always_inline int quant2(float coef, const float Q)
-{
- return av_clip((int)(pow(fabsf(coef) * Q, 0.75)), 0, 8191);
-}
-
-static const float aac_cb_range[12] = { 0, 3, 3, 3, 3, 9, 9, 8, 8, 13, 13, 17};
-static const float aac_cb_maxval[12] = {0, 1, 1, 2, 2, 4, 4, 7, 7, 12, 12, 16};
-
-/**
- * Calculate rate distortion cost for quantizing with given codebook
- *
- * @return quantization distortion
- */
-static float quantize_band_cost(const float *in, int size, int scale_idx, int cb,
- const float lambda, const float uplim, int *bits)
-{
- const float IQ = ff_aac_pow2sf_tab[200 + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
- const float Q = ff_aac_pow2sf_tab[200 - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];
- int i, j, k;
- float cost = 0;
- const int dim = cb < FIRST_PAIR_BT ? 4 : 2;
- int resbits = 0;
- const int range = aac_cb_range[cb];
- const int maxval = aac_cb_maxval[cb];
- int offs[4];
-
- if(!cb){
- for(i = 0; i < size; i++)
- cost += in[i]*in[i]*lambda;
- return cost;
- }
- offs[0] = 1;
- for(i = 1; i < dim; i++)
- offs[i] = offs[i-1]*range;
- for(i = 0; i < size; i += dim){
- float mincost;
- int minidx = 0;
- int minbits = 0;
- int quants[4][2], realquants[4][2];
- mincost = 0.0f;
- for(j = 0; j < dim; j++){
- realquants[j][0] = quant2(in[i+j], Q);
- realquants[j][1] = quant (in[i+j], Q);
- for(k = 0; k < 2; k++){
- quants[j][k] = FFMIN(realquants[j][k], maxval);
- if(!IS_CODEBOOK_UNSIGNED(cb) && in[i+j] < 0.0f)
- quants[j][k] = -quants[j][k];
- }
- mincost += in[i+j]*in[i+j]*lambda;
- }
- minidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40;
- minbits = ff_aac_spectral_bits[cb-1][minidx];
- mincost += minbits;
- for(j = 0; j < (1<<dim); j++){
- float rd = 0.0f;
- int curbits;
- int curidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40;
- const float *vec;
- int same = 0;
- for(k = 0; k < dim; k++){
- if((j & (1 << k)) && quants[k][0] == quants[k][1]){
- same = 1;
- break;
- }
- }
- if(same)
- continue;
- for(k = 0; k < dim; k++)
- curidx += quants[k][!!(j & (1 << k))] * offs[dim - 1 - k];
- curbits = ff_aac_spectral_bits[cb-1][curidx];
- vec = &ff_aac_codebook_vectors[cb-1][curidx*dim];
- if(IS_CODEBOOK_UNSIGNED(cb)){
- for(k = 0; k < dim; k++){
- float t = fabsf(in[i+k]);
- float di;
- //do not code with escape sequence small values
- if(vec[k] == 64.0f && t < 39.0f*IQ){
- rd = INFINITY;
- break;
- }
- if(vec[k] == 64.0f){//FIXME: slow
- if(t >= 165140.0f*IQ){ // clipped value
- di = t - 165140.0f;
- curbits += 21;
- }else{
- int c = realquants[k];
- di = t - c*cbrt(c)*IQ;
- curbits += av_log2(c)*2 - 4 + 1;
- }
- }else{
- di = t - vec[k]*IQ;
- }
- if(vec[k] != 0.0f)
- curbits++;
- rd += di*di*lambda;
- }
- }else{
- for(k = 0; k < dim; k++){
- float di = in[i+k] - vec[k]*IQ;
- rd += di*di*lambda;
- }
- }
- rd += curbits;
- if(rd < mincost){
- mincost = rd;
- minidx = j;
- minbits = curbits;
- }
- }
- cost += mincost;
- resbits += minbits;
- if(cost >= uplim)
- return uplim;
- }
-
- if(bits)
- *bits = resbits;
- return cost;
-}
-
-static void quantize_and_encode_band(PutBitContext *pb, const float *in, int size,
- int scale_idx, int cb, const float lambda)
-{
- const float IQ = ff_aac_pow2sf_tab[200 + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
- const float Q = ff_aac_pow2sf_tab[200 - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];
- const int range = aac_cb_range[cb];
- const int maxval = aac_cb_maxval[cb];
- const int dim = (cb < FIRST_PAIR_BT) ? 4 : 2;
- int i, j, k;
- int offs[4];
-
- if(!cb)
- return;
-
- offs[0] = 1;
- for(i = 1; i < dim; i++)
- offs[i] = offs[i-1]*range;
- for(i = 0; i < size; i += dim){
- float mincost;
- int minidx = 0;
- int minbits = 0;
- int quants[4][2];
- mincost = 0.0f;
- for(j = 0; j < dim; j++){
- quants[j][0] = av_clip(quant2(in[i+j], Q), -maxval, maxval);
- quants[j][1] = av_clip(quant (in[i+j], Q), -maxval, maxval);
- for(k = 0; k < 2; k++){
- quants[j][k] = FFMIN(quants[j][k], maxval);
- if(!IS_CODEBOOK_UNSIGNED(cb) && in[i+j] < 0.0f)
- quants[j][k] = -quants[j][k];
- }
- mincost += in[i+j]*in[i+j]*lambda;
- }
- minidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40;
- minbits = ff_aac_spectral_bits[cb-1][minidx];
- mincost += minbits;
- for(j = 0; j < (1<<dim); j++){
- float rd = 0.0f;
- int curbits;
- int curidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40;
- const float *vec;
- int same = 0;
- for(k = 0; k < dim; k++){
- if((j & (1 << k)) && quants[k][0] == quants[k][1]){
- same = 1;
- break;
- }
- }
- if(same)
- continue;
- for(k = 0; k < dim; k++)
- curidx += quants[k][!!(j & (1 << k))] * offs[dim - 1 - k];
- curbits = ff_aac_spectral_bits[cb-1][curidx];
- vec = &ff_aac_codebook_vectors[cb-1][curidx*dim];
- if(IS_CODEBOOK_UNSIGNED(cb)){
- for(k = 0; k < dim; k++){
- float t = fabsf(in[i+k]);
- float di;
- //do not code with escape sequence small values
- if(vec[k] == 64.0f && t < 39.0f*IQ){
- rd = INFINITY;
- break;
- }
- if(vec[k] == 64.0f){//FIXME: slow
- if(t >= 165140.0f*IQ){ // clipped value
- di = t - 165140.0f;
- curbits += 21;
- }else{
- int c = quant(t, Q);
- di = t - c*cbrt(c)*IQ;
- curbits += av_log2(c)*2 - 4 + 1;
- }
- }else{
- di = t - vec[k]*IQ;
- }
- if(vec[k] != 0.0f)
- curbits++;
- rd += di*di*lambda;
- }
- }else{
- for(k = 0; k < dim; k++){
- float di = in[i+k] - vec[k]*IQ;
- rd += di*di*lambda;
- }
- }
- rd += curbits;
- if(rd < mincost){
- mincost = rd;
- minidx = curidx;
- minbits = curbits;
- }
- }
- put_bits(pb, ff_aac_spectral_bits[cb-1][minidx], ff_aac_spectral_codes[cb-1][minidx]);
- if(IS_CODEBOOK_UNSIGNED(cb))
- for(j = 0; j < dim; j++)
- if(ff_aac_codebook_vectors[cb-1][minidx*dim+j] != 0.0f)
- put_bits(pb, 1, in[i+j] < 0.0f);
- if(cb == ESC_BT){
- for(j = 0; j < 2; j++){
- if(ff_aac_codebook_vectors[cb-1][minidx*2+j] == 64.0f){
- int coef = quant(in[i+j], Q);
- int len = av_log2(coef);
-
- put_bits(pb, len - 4 + 1, (1 << (len - 4 + 1)) - 2);
- put_bits(pb, len, coef & ((1 << len) - 1));
- }
- }
- }
- }
-}
-
-#else
-
-/**
- * Calculate rate distortion cost for quantizing with given codebook
- *
- * @return quantization distortion
- */
-static float quantize_band_cost(const float *in, int size, int scale_idx, int cb,
- const float lambda, const float uplim, int *bits)
-{
- const float Q = ff_aac_pow2sf_tab[200 + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
- int i, j, k;
- float cost = 0;
- const int dim = cb < FIRST_PAIR_BT ? 4 : 2;
- int resbits = 0;
-
- if(!cb){
- for(i = 0; i < size; i++)
- cost += in[i]*in[i]*lambda;
- return cost;
- }
- for(i = 0; i < size; i += dim){
- float mincost = INFINITY;
- int minidx = 0;
- int minbits = 0;
- const float *vec = ff_aac_codebook_vectors[cb-1];
- for(j = 0; j < ff_aac_spectral_sizes[cb-1]; j++, vec += dim){
- float rd = 0.0f;
- int curbits = ff_aac_spectral_bits[cb-1][j];
- if(IS_CODEBOOK_UNSIGNED(cb)){
- for(k = 0; k < dim; k++){
- float t = fabsf(in[i+k]);
- float di;
- //do not code with escape sequence small values
- if(vec[k] == 64.0f && t < 39.0f*Q){
- rd = INFINITY;
- break;
- }
- if(vec[k] == 64.0f){//FIXME: slow
- if(t >= 165140.0f*Q){ // clipped value
- di = t - 165140.0f;
- curbits += 21;
- }else{
- int c = quant(t, 1.0/Q);
- di = t - c*cbrt(c)*Q;
- curbits += av_log2(c)*2 - 4 + 1;
- }
- }else{
- di = t - vec[k]*Q;
- }
- if(vec[k] != 0.0f)
- curbits++;
- rd += di*di*lambda;
- }
- }else{
- for(k = 0; k < dim; k++){
- float di = in[i+k] - vec[k]*Q;
- rd += di*di*lambda;
- }
- }
- rd += curbits;
- if(rd < mincost){
- mincost = rd;
- minidx = j;
- minbits = curbits;
- }
- }
- cost += mincost;
- resbits += minbits;
- if(cost >= uplim)
- return uplim;
- }
-
- if(bits)
- *bits = resbits;
- return cost;
-}
-
-/**
- * Prepare coefficients for encoding.
- *
- * @return sum of coefficient absolute values
- */
-static void quantize_and_encode_band(PutBitContext *pb, const float *in, int size,
- int scale_idx, int cb, const float lambda)
-{
- const float Q = ff_aac_pow2sf_tab[200 + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
- const float IQ = ff_aac_pow2sf_tab[200 - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];
- int i, j, k;
- const int dim = cb < FIRST_PAIR_BT ? 4 : 2;
-
- if(!cb)
- return;
-
- for(i = 0; i < size; i += dim){
- float mincost = INFINITY;
- int minidx = 0;
- int minbits = 0;
- const float *vec = ff_aac_codebook_vectors[cb-1];
- for(j = 0; j < ff_aac_spectral_sizes[cb-1]; j++, vec += dim){
- float rd = 0.0f;
- int curbits = ff_aac_spectral_bits[cb-1][j];
- if(IS_CODEBOOK_UNSIGNED(cb)){
- for(k = 0; k < dim; k++){
- float t = fabsf(in[i+k]);
- float di;
- //do not code with escape sequence small values
- if(vec[k] == 64.0f && t < 39.0f*Q){
- rd = INFINITY;
- break;
- }
- if(vec[k] == 64.0f){//FIXME: slow
- if(t >= 165140.0f*Q){ // clipped value
- di = t - 165140.0f;
- curbits += 21;
- }else{
- int c = quant(t, IQ);
- di = t - c*cbrt(c)*Q;
- curbits += av_log2(c)*2 - 4 + 1;
- }
- }else{
- di = t - vec[k]*Q;
- }
- if(vec[k] != 0.0f)
- curbits++;
- rd += di*di*lambda;
- }
- }else{
- for(k = 0; k < dim; k++){
- float di = in[i+k] - vec[k]*Q;
- rd += di*di*lambda;
- }
- }
- rd += curbits;
- if(rd < mincost){
- mincost = rd;
- minidx = j;
- minbits = curbits;
- }
- }
- put_bits(pb, ff_aac_spectral_bits[cb-1][minidx], ff_aac_spectral_codes[cb-1][minidx]);
- if(IS_CODEBOOK_UNSIGNED(cb))
- for(j = 0; j < dim; j++)
- if(ff_aac_codebook_vectors[cb-1][minidx*dim+j] != 0.0f)
- put_bits(pb, 1, in[i+j] < 0.0f);
- if(cb == ESC_BT){
- for(j = 0; j < 2; j++){
- if(ff_aac_codebook_vectors[cb-1][minidx*2+j] == 64.0f){
- int coef = quant(in[i+j], IQ);
- int len = av_log2(coef);
-
- put_bits(pb, len - 4 + 1, (1 << (len - 4 + 1)) - 2);
- put_bits(pb, len, coef & ((1 << len) - 1));
- }
- }
- }
- }
-}
-
-#endif
-
-/**
- * structure used in optimal codebook search
- */
-typedef struct BandCodingPath {
- int prev_idx; ///< pointer to the previous path point
- int codebook; ///< codebook for coding band run
- float cost; ///< path cost
- int run;
-} BandCodingPath;
-
-/**
- * Encode band info for single window group bands.
- */
-static void encode_window_bands_info(AACEncContext *s, SingleChannelElement *sce,
- int win, int group_len)
-{
- BandCodingPath path[120][12];
- int w, swb, cb, start, start2, size;
- int i, j;
- const int max_sfb = sce->ics.max_sfb;
- const int run_bits = sce->ics.num_windows == 1 ? 5 : 3;
- const int run_esc = (1 << run_bits) - 1;
- int idx, ppos, count;
- int stackrun[120], stackcb[120], stack_len;
-
- start = win*128;
- for(cb = 0; cb < 12; cb++){
- path[0][cb].cost = 0.0f;
- path[0][cb].prev_idx = -1;
- path[0][cb].run = 0;
- }
- for(swb = 0; swb < max_sfb; swb++){
- start2 = start;
- size = sce->ics.swb_sizes[swb];
- if(sce->zeroes[win*16 + swb]){
- for(cb = 0; cb < 12; cb++){
- path[swb+1][cb].prev_idx = cb;
- path[swb+1][cb].cost = path[swb][cb].cost;
- path[swb+1][cb].run = path[swb][cb].run + 1;
- }
- }else{
- float minrd = INFINITY;
- int mincb = 0;
- for(cb = 0; cb < 12; cb++){
- float rd = 0.0f;
- for(w = 0; w < group_len; w++){
- FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(win+w)*16+swb];
- rd += quantize_band_cost(sce->coeffs + start + w*128, size,
- sce->sf_idx[(win+w)*16+swb], cb,
- s->lambda / band->threshold, INFINITY, NULL);
- }
- if( run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run]
- != run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run+1])
- rd += run_bits;
- path[swb+1][cb].prev_idx = cb;
- path[swb+1][cb].cost = path[swb][cb].cost + rd;
- path[swb+1][cb].run = path[swb][cb].run + 1;
- if(rd < minrd){
- minrd = rd;
- mincb = cb;
- }
- }
- for(cb = 0; cb < 12; cb++){
- float cost = path[swb][cb].cost + minrd + run_bits + 4;
- if(cost < path[swb+1][cb].cost){
- path[swb+1][cb].prev_idx = mincb;
- path[swb+1][cb].cost = cost;
- path[swb+1][cb].run = 1;
- }
- }
- }
- start += sce->ics.swb_sizes[swb];
- }
-
- //convert resulting path from backward-linked list
- stack_len = 0;
- idx = 0;
- for(cb = 1; cb < 12; cb++){
- if(path[max_sfb][cb].cost < path[max_sfb][idx].cost)
- idx = cb;
- }
- ppos = max_sfb;
- while(ppos > 0){
- cb = idx;
- stackrun[stack_len] = path[ppos][cb].run;
- stackcb [stack_len] = cb;
- idx = path[ppos][cb].prev_idx;
- ppos -= path[ppos][cb].run;
- stack_len++;
- }
- //perform actual band info encoding
- start = 0;
- for(i = stack_len - 1; i >= 0; i--){
- put_bits(&s->pb, 4, stackcb[i]);
- count = stackrun[i];
- memset(sce->zeroes + win*16 + start, !stackcb[i], count);
- //XXX: memset when band_type is also uint8_t
- for(j = 0; j < count; j++){
- sce->band_type[win*16 + start] = stackcb[i];
- start++;
- }
- while(count >= run_esc){
- put_bits(&s->pb, run_bits, run_esc);
- count -= run_esc;
- }
- put_bits(&s->pb, run_bits, count);
- }
-}
-
-/**
* Produce integer coefficients from scalefactors provided by the model.
*/
static void adjust_frame_information(AACEncContext *apc, ChannelElement *cpe, int chans)
@@ -903,546 +354,6 @@ static void adjust_frame_information(AAC
}
}
-typedef struct TrellisPath {
- float cost;
- int prev;
- int min_val;
- int max_val;
-} TrellisPath;
-
-static void search_for_quantizers_anmr(AACEncContext *s, SingleChannelElement *sce, const float lambda)
-{
- int q, w, w2, g, start = 0;
- int i;
- int idx;
- TrellisPath paths[256*121];
- int bandaddr[121];
- int minq;
- float mincost;
-
- for(i = 0; i < 256; i++){
- paths[i].cost = 0.0f;
- paths[i].prev = -1;
- paths[i].min_val = i;
- paths[i].max_val = i;
- }
- for(i = 256; i < 256*121; i++){
- paths[i].cost = INFINITY;
- paths[i].prev = -2;
- paths[i].min_val = INT_MAX;
- paths[i].max_val = 0;
- }
- idx = 256;
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
- start = w*128;
- for(g = 0; g < sce->ics.num_swb; g++){
- const float *coefs = sce->coeffs + start;
- float qmin, qmax;
- int nz = 0;
-
- bandaddr[idx >> 8] = w*16+g;
- qmin = INT_MAX;
- qmax = 0.0f;
- for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
- FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g];
- if(band->energy <= band->threshold || band->threshold == 0.0f){
- sce->zeroes[(w+w2)*16+g] = 1;
- continue;
- }
- sce->zeroes[(w+w2)*16+g] = 0;
- nz = 1;
- for(i = 0; i < sce->ics.swb_sizes[g]; i++){
- float t = fabsf(coefs[w2*128+i]);
- if(t > 0.0f) qmin = fminf(qmin, t);
- qmax = fmaxf(qmax, t);
- }
- }
- if(nz){
- int minscale, maxscale;
- float minrd = INFINITY;
- //minimum scalefactor index is when minimum nonzero coefficient after quantizing is not clipped
- minscale = av_clip_uint8(log2(qmin)*4 - 69 + SCALE_ONE_POS - SCALE_DIV_512);
- //maximum scalefactor index is when maximum coefficient after quantizing is still not zero
- maxscale = av_clip_uint8(log2(qmax)*4 + 6 + SCALE_ONE_POS - SCALE_DIV_512);
- for(q = minscale; q < maxscale; q++){
- float dists[12], dist;
- memset(dists, 0, sizeof(dists));
- for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
- FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g];
- int cb;
- for(cb = 0; cb <= ESC_BT; cb++){
- dists[cb] += quantize_band_cost(coefs + w2*128, sce->ics.swb_sizes[g],
- q, cb, s->lambda / band->threshold, INFINITY, NULL);
- }
- }
- dist = dists[0];
- for(i = 1; i <= ESC_BT; i++)
- dist = fminf(dist, dists[i]);
- minrd = fminf(minrd, dist);
-
- for(i = FFMAX(q - SCALE_MAX_DIFF, 0); i < FFMIN(q + SCALE_MAX_DIFF, 256); i++){
- float cost;
- int minv, maxv;
- if(isinf(paths[idx - 256 + i].cost))
- continue;
- cost = paths[idx - 256 + i].cost + dist
- + ff_aac_scalefactor_bits[q - i + SCALE_DIFF_ZERO];
- minv = FFMIN(paths[idx - 256 + i].min_val, q);
- maxv = FFMAX(paths[idx - 256 + i].max_val, q);
- if(cost < paths[idx + q].cost && maxv-minv < SCALE_MAX_DIFF){
- paths[idx + q].cost = cost;
- paths[idx + q].prev = idx - 256 + i;
- paths[idx + q].min_val = minv;
- paths[idx + q].max_val = maxv;
- }
- }
- }
- }else{
- for(q = 0; q < 256; q++){
- if(!isinf(paths[idx - 256 + q].cost)){
- paths[idx + q].cost = paths[idx - 256 + q].cost + 1;
- paths[idx + q].prev = idx - 256 + q;
- paths[idx + q].min_val = FFMIN(paths[idx - 256 + q].min_val, q);
- paths[idx + q].max_val = FFMAX(paths[idx - 256 + q].max_val, q);
- continue;
- }
- for(i = FFMAX(q - SCALE_MAX_DIFF, 0); i < FFMIN(q + SCALE_MAX_DIFF, 256); i++){
- float cost;
- int minv, maxv;
- if(isinf(paths[idx - 256 + i].cost))
- continue;
- cost = paths[idx - 256 + i].cost + ff_aac_scalefactor_bits[q - i + SCALE_DIFF_ZERO];
- minv = FFMIN(paths[idx - 256 + i].min_val, q);
- maxv = FFMAX(paths[idx - 256 + i].max_val, q);
- if(cost < paths[idx + q].cost && maxv-minv < SCALE_MAX_DIFF){
- paths[idx + q].cost = cost;
- paths[idx + q].prev = idx - 256 + i;
- paths[idx + q].min_val = minv;
- paths[idx + q].max_val = maxv;
- }
- }
- }
- }
- sce->zeroes[w*16+g] = !nz;
- start += sce->ics.swb_sizes[g];
- idx += 256;
- }
- }
- idx -= 256;
- mincost = paths[idx].cost;
- minq = idx;
- for(i = 1; i < 256; i++){
- if(paths[idx + i].cost < mincost){
- mincost = paths[idx + i].cost;
- minq = idx + i;
- }
- }
- while(minq >= 256){
- sce->sf_idx[bandaddr[minq>>8]] = minq & 0xFF;
- minq = paths[minq].prev;
- }
- //set the same quantizers inside window groups
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w])
- for(g = 0; g < sce->ics.num_swb; g++)
- for(w2 = 1; w2 < sce->ics.group_len[w]; w2++)
- sce->sf_idx[(w+w2)*16+g] = sce->sf_idx[w*16+g];
-}
-
-/**
- * two-loop quantizers search taken from ISO 13818-7 Appendix C
- */
-static void search_for_quantizers_twoloop(AVCodecContext *avctx, AACEncContext *s,
- SingleChannelElement *sce, const float lambda)
-{
- int start = 0, i, w, w2, g;
- int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / avctx->channels;
- float dists[128], uplims[128];
- int fflag, minscaler;
- int its = 0;
- int allz = 0;
- float minthr = INFINITY;
-
- //XXX: some heuristic to determine initial quantizers will reduce search time
- memset(dists, 0, sizeof(dists));
- //determine zero bands and upper limits
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
- for(g = 0; g < sce->ics.num_swb; g++){
- int nz = 0;
- float uplim = 0.0f;
- for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
- FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g];
- uplim += band->threshold;
- if(band->energy <= band->threshold || band->threshold == 0.0f){
- sce->zeroes[(w+w2)*16+g] = 1;
- continue;
- }
- nz = 1;
- }
- uplims[w*16+g] = uplim *512;
- sce->zeroes[w*16+g] = !nz;
- if(nz)
- minthr = fminf(minthr, uplim);
- allz = FFMAX(allz, nz);
- }
- }
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
- for(g = 0; g < sce->ics.num_swb; g++){
- if(sce->zeroes[w*16+g]){
- sce->sf_idx[w*16+g] = SCALE_ONE_POS;
- continue;
- }
- sce->sf_idx[w*16+g] = SCALE_ONE_POS + fminf(log2(uplims[w*16+g]/minthr)*4,59);
- }
- }
-
- if(!allz)
- return;
- //perform two-loop search
- //outer loop - improve quality
- do{
- int tbits, qstep;
- minscaler = sce->sf_idx[0];
- //inner loop - quantize spectrum to fit into given number of bits
- qstep = its ? 1 : 32;
- do{
- int prev = -1;
- tbits = 0;
- fflag = 0;
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
- start = w*128;
- for(g = 0; g < sce->ics.num_swb; g++){
- const float *coefs = sce->coeffs + start;
- int bits = 0;
- int cb;
- float mindist = INFINITY;
- int minbits = 0;
-
- if(sce->zeroes[w*16+g] || sce->sf_idx[w*16+g] >= 218)
- continue;
- minscaler = FFMIN(minscaler, sce->sf_idx[w*16+g]);
- for(cb = 0; cb <= ESC_BT; cb++){
- float dist = 0.0f;
- int bb = 0;
- for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
- int b;
- dist += quantize_band_cost(coefs + w2*128,
- sce->ics.swb_sizes[g],
- sce->sf_idx[w*16+g],
- ESC_BT,
- 1.0,
- INFINITY,
- &b);
- bb += b;
- }
- if(dist < mindist){
- mindist = dist;
- minbits = bb;
- }
- }
- dists[w*16+g] = mindist - minbits;
- bits = minbits;
- if(prev != -1){
- bits += ff_aac_scalefactor_bits[sce->sf_idx[w*16+g] - prev + SCALE_DIFF_ZERO];
- }
- tbits += bits;
- start += sce->ics.swb_sizes[g];
- prev = sce->sf_idx[w*16+g];
- }
- }
- if(tbits > destbits){
- for(i = 0; i < 128; i++){
- if(sce->sf_idx[i] < 218 - qstep){
- sce->sf_idx[i] += qstep;
- }
- }
- }else{
- for(i = 0; i < 128; i++){
- if(sce->sf_idx[i] > 60 - qstep){
- sce->sf_idx[i] -= qstep;
- }
- }
- }
- qstep >>= 1;
- if(!qstep && tbits > destbits*1.02)
- qstep = 1;
- if(sce->sf_idx[0] >= 217)break;
- }while(qstep);
-
- fflag = 0;
- minscaler = av_clip(minscaler, 60, 255 - SCALE_MAX_DIFF);
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
- start = w*128;
- for(g = 0; g < sce->ics.num_swb; g++){
- int prevsc = sce->sf_idx[w*16+g];
- if(dists[w*16+g] > uplims[w*16+g] && sce->sf_idx[w*16+g] > 60)
- sce->sf_idx[w*16+g]--;
- sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], minscaler, minscaler + SCALE_MAX_DIFF);
- sce->sf_idx[w*16+g] = FFMIN(sce->sf_idx[w*16+g], 219);
- if(sce->sf_idx[w*16+g] != prevsc)
- fflag = 1;
- }
- }
- its++;
- }while(fflag && its < 10);
-}
-
-static void search_for_quantizers_faac(AACEncContext *s, SingleChannelElement *sce, const float lambda)
-{
- int start = 0, i, w, w2, g;
- float uplim[128], maxq[128];
- int minq;
-#if 0
- float distfact = ((sce->ics.num_windows > 1) ? 85.80 : 147.84) / lambda;
- int last = 0, lastband = 0, curband = 0;
- float avg_energy = 0.0;
- if(sce->ics.num_windows == 1){
- start = 0;
- for(i = 0; i < 1024; i++){
- if(i - start >= sce->ics.swb_sizes[curband]){
- start += sce->ics.swb_sizes[curband];
- curband++;
- }
- if(sce->coeffs[i]){
- avg_energy += sce->coeffs[i] * sce->coeffs[i];
- last = i;
- lastband = curband;
- }
- }
- }else{
- for(w = 0; w < 8; w++){
- const float *coeffs = sce->coeffs + w*128;
- start = 0;
- for(i = 0; i < 128; i++){
- if(i - start >= sce->ics.swb_sizes[curband]){
- start += sce->ics.swb_sizes[curband];
- curband++;
- }
- if(coeffs[i]){
- avg_energy += coeffs[i] * coeffs[i];
- last = FFMAX(last, i);
- lastband = FFMAX(lastband, curband);
- }
- }
- }
- }
- last++;
- avg_energy /= last;
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
- start = w*128;
- for(g = 0; g < sce->ics.num_swb; g++){
- float *coefs = sce->coeffs + start;
- const int size = sce->ics.swb_sizes[g];
- int start2 = start, end2 = start + size, peakpos = start;
- float maxval = -1, thr = 0.0f, t;
- maxq[w*16+g] = 0.0f;
- if(g > lastband){
- maxq[w*16+g] = 0.0f;
- start += size;
- for(w2 = 0; w2 < sce->ics.group_len[w]; w2++)
- memset(coefs + w2*128, 0, sizeof(coefs[0])*size);
- continue;
- }
- for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
- for(i = 0; i < size; i++){
- float t = coefs[w2*128+i]*coefs[w2*128+i];
- maxq[w*16+g] = fmaxf(maxq[w*16+g], coefs[w2*128 + i]);
- thr += t;
- if(sce->ics.num_windows == 1 && maxval < t){
- maxval = t;
- peakpos = start+i;
- }
- }
- }
- if(sce->ics.num_windows == 1){
- start2 = FFMAX(peakpos - 2, start2);
- end2 = FFMIN(peakpos + 3, end2);
- }
- start += size;
- thr = pow(thr / (avg_energy * (end2 - start2)), 0.3 + 0.1*(lastband - g) / lastband);
- t = 1.0 - (1.0 * start2 / last);
- uplim[w*16+g] = distfact / (1.4 * thr + t*t*t + 0.075);
- }
- }
-#else
- memset(maxq, 0, sizeof(maxq));
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
- start = w*128;
- for(g = 0; g < sce->ics.num_swb; g++){
- float *coefs = sce->coeffs + start;
- const int size = sce->ics.swb_sizes[g];
- float thr = 0.0f;
- for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
- FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g];
- thr += band->threshold;
- for(i = 0; i < size; i++){
- maxq[w*16+g] = fmaxf(maxq[w*16+g], fabsf(coefs[w2*128 + i]));
- }
- }
- uplim[w*16+g] = thr / lambda;
- start += size;
- }
- }
-#endif
- memset(sce->sf_idx, 0, sizeof(sce->sf_idx));
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
- start = w*128;
- for(g = 0; g < sce->ics.num_swb; g++){
- const float *coefs = sce->coeffs + start;
- const int size = sce->ics.swb_sizes[g];
- int scf, prev_scf, step;
- if(maxq[w*16+g] < 21.544){
- sce->zeroes[w*16+g] = 1;
- continue;
- }
- sce->zeroes[w*16+g] = 0;
- scf = prev_scf = av_clip(SCALE_ONE_POS + log2(1/maxq[w*16+g])*16/3, 60, 218);
- step = 16;
- for(;;){
- float dist = 0.0f, t;
- int quant_max;
-
- for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
- int b;
- dist += quantize_band_cost(coefs + w2*128,
- sce->ics.swb_sizes[g],
- scf,
- ESC_BT,
- 1.0,
- INFINITY,
- &b);
- dist -= b;
- }
- quant_max = quant(maxq[w*16+g], ff_aac_pow2sf_tab[200 - scf + SCALE_ONE_POS]);
- if(quant_max >= 8191){ // too much, return to the previous quantizer
- sce->sf_idx[w*16+g] = prev_scf;
- break;
- }
- prev_scf = scf;
- t = pow(dist / size, -2.0/3.0);
- if(FFABS(step) > 4){
- int newstep = 4*log(t / maxq[w*16+g])/log(2) - 2;
- step = av_clip(-newstep, -4, 4);
- }
- if(FFABS(step) >= 4){
- step = 1 - step;
- scf += step;
- }else if(t >= uplim[w*16+g]){
- scf -= FFABS(step);
- }else{
- sce->sf_idx[w*16+g] = scf;
- break;
- }
- }
- start += size;
- }
- }
- minq = sce->sf_idx[0] ? sce->sf_idx[0] : INT_MAX;
- for(i = 1; i < 128; i++){
- if(!sce->sf_idx[i])
- sce->sf_idx[i] = sce->sf_idx[i-1];
- else
- minq = FFMIN(minq, sce->sf_idx[i]);
- }
- if(minq == INT_MAX) minq = 0;
- for(i = 126; i >= 0; i--){
- if(!sce->sf_idx[i])
- sce->sf_idx[i] = sce->sf_idx[i+1];
- sce->sf_idx[i] = av_clip(sce->sf_idx[i], minq, minq + SCALE_MAX_DIFF);
- }
-}
-
-static void search_for_quantizers_fast(AACEncContext *s, SingleChannelElement *sce)
-{
- int start = 0, i, w, w2, g;
- int minq = 255;
-
- memset(sce->sf_idx, 0, sizeof(sce->sf_idx));
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
- start = w*128;
- for(g = 0; g < sce->ics.num_swb; g++){
- for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
- FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g];
- if(band->energy <= band->threshold){
- sce->sf_idx[(w+w2)*16+g] = 218;
- sce->zeroes[(w+w2)*16+g] = 1;
- }else{
- sce->sf_idx[(w+w2)*16+g] = av_clip(SCALE_ONE_POS - SCALE_DIV_512 + log2(band->threshold), 80, 218);
- sce->zeroes[(w+w2)*16+g] = 0;
- }
- minq = FFMIN(minq, sce->sf_idx[(w+w2)*16+g]);
- }
- }
- }
- for(i = 0; i < 128; i++){
- sce->sf_idx[i] = av_clip(sce->sf_idx[i], minq, minq + SCALE_MAX_DIFF - 1);
- }
- //set the same quantizers inside window groups
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w])
- for(g = 0; g < sce->ics.num_swb; g++)
- for(w2 = 1; w2 < sce->ics.group_len[w]; w2++)
- sce->sf_idx[(w+w2)*16+g] = sce->sf_idx[w*16+g];
-}
-
-static void search_for_quantizers(AVCodecContext *avctx, AACEncContext *s,
- SingleChannelElement *sce)
-{
- search_for_quantizers_anmr(s, sce, s->lambda);
-// search_for_quantizers_twoloop(avctx, s, sce, s->lambda);
-// search_for_quantizers_faac(s, sce, av_clipf(s->lambda * 2e8, 50.0f, 300.0f));
-// search_for_quantizers_fast(s, sce);
-}
-
-static void search_for_ms(AACEncContext *s, ChannelElement *cpe, const float lambda)
-{
- int start = 0, i, w, w2, g;
- float M[128], S[128];
- SingleChannelElement *sce0 = &cpe->ch[0];
- SingleChannelElement *sce1 = &cpe->ch[1];
- if(!cpe->common_window)
- return;
- for(w = 0; w < sce0->ics.num_windows; w += sce0->ics.group_len[w]){
- for(g = 0; g < sce0->ics.num_swb; g++){
- if(!cpe->ch[0].zeroes[w*16+g] && !cpe->ch[1].zeroes[w*16+g]){
- float dist1 = 0.0f, dist2 = 0.0f;
- for(w2 = 0; w2 < sce0->ics.group_len[w]; w2++){
- FFPsyBand *band0 = &s->psy.psy_bands[(s->cur_channel+0)*PSY_MAX_BANDS+(w+w2)*16+g];
- FFPsyBand *band1 = &s->psy.psy_bands[(s->cur_channel+1)*PSY_MAX_BANDS+(w+w2)*16+g];
- float minthr = fminf(band0->threshold, band1->threshold);
- float maxthr = fmaxf(band0->threshold, band1->threshold);
- for(i = 0; i < sce0->ics.swb_sizes[g]; i++){
- M[i] = (sce0->coeffs[start+w2*128+i]
- + sce1->coeffs[start+w2*128+i])*0.5;
- S[i] = sce0->coeffs[start+w2*128+i]
- - sce1->coeffs[start+w2*128+i];
- }
- dist1 += quantize_band_cost(sce0->coeffs + start + w2*128,
- sce0->ics.swb_sizes[g],
- sce0->sf_idx[(w+w2)*16+g],
- sce0->band_type[(w+w2)*16+g],
- lambda / band0->threshold, INFINITY, NULL);
- dist1 += quantize_band_cost(sce1->coeffs + start + w2*128,
- sce1->ics.swb_sizes[g],
- sce1->sf_idx[(w+w2)*16+g],
- sce1->band_type[(w+w2)*16+g],
- lambda / band1->threshold, INFINITY, NULL);
- dist2 += quantize_band_cost(M,
- sce0->ics.swb_sizes[g],
- sce0->sf_idx[(w+w2)*16+g],
- sce0->band_type[(w+w2)*16+g],
- lambda / maxthr, INFINITY, NULL);
- dist2 += quantize_band_cost(S,
- sce1->ics.swb_sizes[g],
- sce1->sf_idx[(w+w2)*16+g],
- sce1->band_type[(w+w2)*16+g],
- lambda / minthr, INFINITY, NULL);
- }
- cpe->ms_mask[w*16+g] = dist2 < dist1;
- }
- start += sce0->ics.swb_sizes[g];
- }
- }
-}
-
/**
* Encode scalefactor band coding type.
*/
@@ -1451,7 +362,7 @@ static void encode_band_info(AACEncConte
int w;
for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
- encode_window_bands_info(s, sce, w, sce->ics.group_len[w]);
+ s->coder->encode_window_bands_info(s, sce, w, sce->ics.group_len[w]);
}
}
@@ -1508,7 +419,7 @@ static void encode_spectral_coeffs(AACEn
continue;
}
for(w2 = w; w2 < w + sce->ics.group_len[w]; w2++){
- quantize_and_encode_band(&s->pb, sce->coeffs + start + w2*128,
+ s->coder->quantize_and_encode_band(&s->pb, sce->coeffs + start + w2*128,
sce->ics.swb_sizes[i],
sce->sf_idx[w*16 + i],
sce->band_type[w*16 + i],
@@ -1617,7 +528,7 @@ static int aac_encode_frame(AVCodecConte
s->cur_channel = start_ch + j;
apply_window_and_mdct(avctx, s, &cpe->ch[j], samples2, j);
- search_for_quantizers(avctx, s, &cpe->ch[j]);
+ s->coder->search_for_quantizers(avctx, s, &cpe->ch[j], s->lambda);
}
cpe->common_window = 0;
if(chans > 1
@@ -1632,7 +543,8 @@ static int aac_encode_frame(AVCodecConte
}
}
}
-// search_for_ms(s, cpe, s->lambda);
+ if(cpe->common_window && s->coder->search_for_ms)
+ s->coder->search_for_ms(s, cpe, s->lambda);
adjust_frame_information(s, cpe, chans);
put_bits(&s->pb, 3, tag);
put_bits(&s->pb, 4, chan_el_counter[tag]++);
Copied and modified: aacenc/aacenc.h (from r4006, aacenc/aacenc.c)
==============================================================================
--- aacenc/aacenc.c Mon Jan 26 14:37:36 2009 (r4006, copy source)
+++ aacenc/aacenc.h Mon Jan 26 15:07:28 2009 (r4008)
@@ -19,138 +19,35 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-/**
- * @file aacenc.c
- * AAC encoder
- */
-
-/***********************************
- * TODOs:
- * speedup quantizer selection
- * add sane pulse detection
- * add temporal noise shaping
- ***********************************/
+#ifndef AVCODEC_AACENC_H
+#define AVCODEC_AACENC_H
#include "avcodec.h"
#include "bitstream.h"
#include "dsputil.h"
-#include "mpeg4audio.h"
#include "aac.h"
-#include "aactab.h"
#include "psymodel.h"
-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
-};
-
-static const uint8_t *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
-};
-
-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_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_128[] = {
- /* the last entry on the following row is swb_size_128_64 but is a
- duplicate of swb_size_128_96 */
- swb_size_128_96, swb_size_128_96, swb_size_128_96,
- 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
-};
-
-/** bits needed to code codebook run value for long windows */
-static const uint8_t run_value_bits_long[64] = {
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 10,
- 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
- 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 15
-};
-
-/** bits needed to code codebook run value for short windows */
-static const uint8_t run_value_bits_short[16] = {
- 3, 3, 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 9
-};
+struct AACEncContext;
-static const uint8_t* run_value_bits[2] = {
- run_value_bits_long, run_value_bits_short
-};
+typedef struct AACCoefficientsEncoder{
+ void (*search_for_quantizers)(AVCodecContext *avctx, struct AACEncContext *s,
+ SingleChannelElement *sce, const float lambda);
+ void (*encode_window_bands_info)(struct AACEncContext *s, SingleChannelElement *sce,
+ int win, int group_len);
+ void (*quantize_and_encode_band)(PutBitContext *pb, const float *in, int size,
+ int scale_idx, int cb, const float lambda);
+ void (*search_for_ms)(struct AACEncContext *s, ChannelElement *cpe, const float lambda);
+}AACCoefficientsEncoder;
-/** default channel configurations */
-static const uint8_t aac_chan_configs[6][5] = {
- {1, TYPE_SCE}, // 1 channel - single channel element
- {1, TYPE_CPE}, // 2 channels - channel pair
- {2, TYPE_SCE, TYPE_CPE}, // 3 channels - center + stereo
- {3, TYPE_SCE, TYPE_CPE, TYPE_SCE}, // 4 channels - front center + stereo + back center
- {3, TYPE_SCE, TYPE_CPE, TYPE_CPE}, // 5 channels - front center + stereo + back stereo
- {4, TYPE_SCE, TYPE_CPE, TYPE_CPE, TYPE_LFE}, // 6 channels - front center + stereo + back stereo + LFE
-};
+extern AACCoefficientsEncoder ff_aac_coders[];
/**
* AAC encoder context
*/
-typedef struct {
+typedef struct AACEncContext {
PutBitContext pb;
MDCTContext mdct1024; ///< long (1024 samples) frame transform context
MDCTContext mdct128; ///< short (128 samples) frame transform context
@@ -163,1526 +60,10 @@ typedef struct {
ChannelElement *cpe; ///< channel elements
FFPsyContext psy;
struct FFPsyPreprocessContext* psypp;
+ AACCoefficientsEncoder *coder;
int cur_channel;
int last_frame;
float lambda;
} AACEncContext;
-/**
- * Make AAC audio config object.
- * @see 1.6.2.1 "Syntax - AudioSpecificConfig"
- */
-static void put_audio_specific_config(AVCodecContext *avctx)
-{
- PutBitContext pb;
- AACEncContext *s = avctx->priv_data;
-
- init_put_bits(&pb, avctx->extradata, avctx->extradata_size*8);
- put_bits(&pb, 5, 2); //object type - AAC-LC
- put_bits(&pb, 4, s->samplerate_index); //sample rate index
- put_bits(&pb, 4, avctx->channels);
- //GASpecificConfig
- put_bits(&pb, 1, 0); //frame length - 1024 samples
- put_bits(&pb, 1, 0); //does not depend on core coder
- put_bits(&pb, 1, 0); //is not extension
- flush_put_bits(&pb);
-}
-
-static av_cold int aac_encode_init(AVCodecContext *avctx)
-{
- AACEncContext *s = avctx->priv_data;
- int i;
- const uint8_t *sizes[2];
- int lengths[2];
-
- avctx->frame_size = 1024;
-
- for(i = 0; i < 16; i++)
- if(avctx->sample_rate == ff_mpeg4audio_sample_rates[i])
- break;
- if(i == 16){
- av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate %d\n", avctx->sample_rate);
- return -1;
- }
- if(avctx->channels > 6){
- av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %d\n", avctx->channels);
- return -1;
- }
- s->samplerate_index = i;
-
- dsputil_init(&s->dsp, avctx);
- ff_mdct_init(&s->mdct1024, 11, 0);
- ff_mdct_init(&s->mdct128, 8, 0);
- // window init
- ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024);
- ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128);
- ff_sine_window_init(ff_sine_1024, 1024);
- ff_sine_window_init(ff_sine_128, 128);
-
- s->samples = av_malloc(2 * 1024 * avctx->channels * sizeof(s->samples[0]));
- s->cpe = av_mallocz(sizeof(ChannelElement) * aac_chan_configs[avctx->channels-1][0]);
- avctx->extradata = av_malloc(2);
- avctx->extradata_size = 2;
- put_audio_specific_config(avctx);
-
- sizes[0] = swb_size_1024[i];
- sizes[1] = swb_size_128[i];
- lengths[0] = ff_aac_num_swb_1024[i];
- lengths[1] = ff_aac_num_swb_128[i];
- ff_psy_init(&s->psy, avctx, 2, sizes, lengths);
- s->psypp = ff_psy_preprocess_init(avctx);
-
-#if !CONFIG_HARDCODED_TABLES
- for (i = 0; i < 316; i++)
- ff_aac_pow2sf_tab[i] = pow(2, (i - 200)/4.);
-#endif /* CONFIG_HARDCODED_TABLES */
-
- return 0;
-}
-
-static void apply_window_and_mdct(AVCodecContext *avctx, AACEncContext *s,
- SingleChannelElement *sce, short *audio, int channel)
-{
- int i, j, k;
- const float * lwindow = sce->ics.use_kb_window[0] ? ff_aac_kbd_long_1024 : ff_sine_1024;
- const float * swindow = sce->ics.use_kb_window[0] ? ff_aac_kbd_short_128 : ff_sine_128;
- const float * pwindow = sce->ics.use_kb_window[1] ? ff_aac_kbd_short_128 : ff_sine_128;
-
- if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) {
- memcpy(s->output, sce->saved, sizeof(float)*1024);
- if(sce->ics.window_sequence[0] == LONG_STOP_SEQUENCE){
- memset(s->output, 0, sizeof(s->output[0]) * 448);
- for(i = 448; i < 576; i++)
- s->output[i] = sce->saved[i] * pwindow[i - 448];
- for(i = 576; i < 704; i++)
- s->output[i] = sce->saved[i];
- }
- if(sce->ics.window_sequence[0] != LONG_START_SEQUENCE){
- j = channel;
- for (i = 0; i < 1024; i++, j += avctx->channels){
- s->output[i+1024] = audio[j] * lwindow[1024 - i - 1];
- sce->saved[i] = audio[j] * lwindow[i];
- }
- }else{
- j = channel;
- for(i = 0; i < 448; i++, j += avctx->channels)
- s->output[i+1024] = audio[j];
- for(i = 448; i < 576; i++, j += avctx->channels)
- s->output[i+1024] = audio[j] * swindow[576 - i - 1];
- memset(s->output+1024+576, 0, sizeof(s->output[0]) * 448);
- j = channel;
- for(i = 0; i < 1024; i++, j += avctx->channels)
- sce->saved[i] = audio[j];
- }
- ff_mdct_calc(&s->mdct1024, sce->coeffs, s->output);
- }else{
- j = channel;
- for (k = 0; k < 1024; k += 128) {
- for(i = 448 + k; i < 448 + k + 256; i++)
- s->output[i - 448 - k] = (i < 1024)
- ? sce->saved[i]
- : audio[channel + (i-1024)*avctx->channels];
- s->dsp.vector_fmul (s->output, k ? swindow : pwindow, 128);
- s->dsp.vector_fmul_reverse(s->output+128, s->output+128, swindow, 128);
- ff_mdct_calc(&s->mdct128, sce->coeffs + k, s->output);
- }
- j = channel;
- for(i = 0; i < 1024; i++, j += avctx->channels)
- sce->saved[i] = audio[j];
- }
-}
-
-/**
- * Encode ics_info element.
- * @see Table 4.6 (syntax of ics_info)
- */
-static void put_ics_info(AACEncContext *s, IndividualChannelStream *info)
-{
- int w;
-
- put_bits(&s->pb, 1, 0); // ics_reserved bit
- put_bits(&s->pb, 2, info->window_sequence[0]);
- put_bits(&s->pb, 1, info->use_kb_window[0]);
- if(info->window_sequence[0] != EIGHT_SHORT_SEQUENCE){
- put_bits(&s->pb, 6, info->max_sfb);
- put_bits(&s->pb, 1, 0); // no prediction
- }else{
- put_bits(&s->pb, 4, info->max_sfb);
- for(w = 1; w < 8; w++){
- put_bits(&s->pb, 1, !info->group_len[w]);
- }
- }
-}
-
-/**
- * Encode MS data.
- * @see 4.6.8.1 "Joint Coding - M/S Stereo"
- */
-static void encode_ms_info(PutBitContext *pb, ChannelElement *cpe)
-{
- int i, w;
-
- put_bits(pb, 2, cpe->ms_mode);
- if(cpe->ms_mode == 1){
- for(w = 0; w < cpe->ch[0].ics.num_windows; w += cpe->ch[0].ics.group_len[w]){
- for(i = 0; i < cpe->ch[0].ics.max_sfb; i++)
- put_bits(pb, 1, cpe->ms_mask[w*16 + i]);
- }
- }
-}
-
-/**
- * Quantize one coefficient.
- * @return absolute value of the quantized coefficient
- * @see 3GPP TS26.403 5.6.2 "Scalefactor determination"
- */
-static av_always_inline int quant(float coef, const float Q)
-{
- return av_clip((int)(pow(fabsf(coef) * Q, 0.75) + 0.4054), 0, 8191);
-}
-
-#if 1
-
-static av_always_inline int quant2(float coef, const float Q)
-{
- return av_clip((int)(pow(fabsf(coef) * Q, 0.75)), 0, 8191);
-}
-
-static const float aac_cb_range[12] = { 0, 3, 3, 3, 3, 9, 9, 8, 8, 13, 13, 17};
-static const float aac_cb_maxval[12] = {0, 1, 1, 2, 2, 4, 4, 7, 7, 12, 12, 16};
-
-/**
- * Calculate rate distortion cost for quantizing with given codebook
- *
- * @return quantization distortion
- */
-static float quantize_band_cost(const float *in, int size, int scale_idx, int cb,
- const float lambda, const float uplim, int *bits)
-{
- const float IQ = ff_aac_pow2sf_tab[200 + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
- const float Q = ff_aac_pow2sf_tab[200 - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];
- int i, j, k;
- float cost = 0;
- const int dim = cb < FIRST_PAIR_BT ? 4 : 2;
- int resbits = 0;
- const int range = aac_cb_range[cb];
- const int maxval = aac_cb_maxval[cb];
- int offs[4];
-
- if(!cb){
- for(i = 0; i < size; i++)
- cost += in[i]*in[i]*lambda;
- return cost;
- }
- offs[0] = 1;
- for(i = 1; i < dim; i++)
- offs[i] = offs[i-1]*range;
- for(i = 0; i < size; i += dim){
- float mincost;
- int minidx = 0;
- int minbits = 0;
- int quants[4][2], realquants[4][2];
- mincost = 0.0f;
- for(j = 0; j < dim; j++){
- realquants[j][0] = quant2(in[i+j], Q);
- realquants[j][1] = quant (in[i+j], Q);
- for(k = 0; k < 2; k++){
- quants[j][k] = FFMIN(realquants[j][k], maxval);
- if(!IS_CODEBOOK_UNSIGNED(cb) && in[i+j] < 0.0f)
- quants[j][k] = -quants[j][k];
- }
- mincost += in[i+j]*in[i+j]*lambda;
- }
- minidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40;
- minbits = ff_aac_spectral_bits[cb-1][minidx];
- mincost += minbits;
- for(j = 0; j < (1<<dim); j++){
- float rd = 0.0f;
- int curbits;
- int curidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40;
- const float *vec;
- int same = 0;
- for(k = 0; k < dim; k++){
- if((j & (1 << k)) && quants[k][0] == quants[k][1]){
- same = 1;
- break;
- }
- }
- if(same)
- continue;
- for(k = 0; k < dim; k++)
- curidx += quants[k][!!(j & (1 << k))] * offs[dim - 1 - k];
- curbits = ff_aac_spectral_bits[cb-1][curidx];
- vec = &ff_aac_codebook_vectors[cb-1][curidx*dim];
- if(IS_CODEBOOK_UNSIGNED(cb)){
- for(k = 0; k < dim; k++){
- float t = fabsf(in[i+k]);
- float di;
- //do not code with escape sequence small values
- if(vec[k] == 64.0f && t < 39.0f*IQ){
- rd = INFINITY;
- break;
- }
- if(vec[k] == 64.0f){//FIXME: slow
- if(t >= 165140.0f*IQ){ // clipped value
- di = t - 165140.0f;
- curbits += 21;
- }else{
- int c = realquants[k];
- di = t - c*cbrt(c)*IQ;
- curbits += av_log2(c)*2 - 4 + 1;
- }
- }else{
- di = t - vec[k]*IQ;
- }
- if(vec[k] != 0.0f)
- curbits++;
- rd += di*di*lambda;
- }
- }else{
- for(k = 0; k < dim; k++){
- float di = in[i+k] - vec[k]*IQ;
- rd += di*di*lambda;
- }
- }
- rd += curbits;
- if(rd < mincost){
- mincost = rd;
- minidx = j;
- minbits = curbits;
- }
- }
- cost += mincost;
- resbits += minbits;
- if(cost >= uplim)
- return uplim;
- }
-
- if(bits)
- *bits = resbits;
- return cost;
-}
-
-static void quantize_and_encode_band(PutBitContext *pb, const float *in, int size,
- int scale_idx, int cb, const float lambda)
-{
- const float IQ = ff_aac_pow2sf_tab[200 + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
- const float Q = ff_aac_pow2sf_tab[200 - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];
- const int range = aac_cb_range[cb];
- const int maxval = aac_cb_maxval[cb];
- const int dim = (cb < FIRST_PAIR_BT) ? 4 : 2;
- int i, j, k;
- int offs[4];
-
- if(!cb)
- return;
-
- offs[0] = 1;
- for(i = 1; i < dim; i++)
- offs[i] = offs[i-1]*range;
- for(i = 0; i < size; i += dim){
- float mincost;
- int minidx = 0;
- int minbits = 0;
- int quants[4][2];
- mincost = 0.0f;
- for(j = 0; j < dim; j++){
- quants[j][0] = av_clip(quant2(in[i+j], Q), -maxval, maxval);
- quants[j][1] = av_clip(quant (in[i+j], Q), -maxval, maxval);
- for(k = 0; k < 2; k++){
- quants[j][k] = FFMIN(quants[j][k], maxval);
- if(!IS_CODEBOOK_UNSIGNED(cb) && in[i+j] < 0.0f)
- quants[j][k] = -quants[j][k];
- }
- mincost += in[i+j]*in[i+j]*lambda;
- }
- minidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40;
- minbits = ff_aac_spectral_bits[cb-1][minidx];
- mincost += minbits;
- for(j = 0; j < (1<<dim); j++){
- float rd = 0.0f;
- int curbits;
- int curidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40;
- const float *vec;
- int same = 0;
- for(k = 0; k < dim; k++){
- if((j & (1 << k)) && quants[k][0] == quants[k][1]){
- same = 1;
- break;
- }
- }
- if(same)
- continue;
- for(k = 0; k < dim; k++)
- curidx += quants[k][!!(j & (1 << k))] * offs[dim - 1 - k];
- curbits = ff_aac_spectral_bits[cb-1][curidx];
- vec = &ff_aac_codebook_vectors[cb-1][curidx*dim];
- if(IS_CODEBOOK_UNSIGNED(cb)){
- for(k = 0; k < dim; k++){
- float t = fabsf(in[i+k]);
- float di;
- //do not code with escape sequence small values
- if(vec[k] == 64.0f && t < 39.0f*IQ){
- rd = INFINITY;
- break;
- }
- if(vec[k] == 64.0f){//FIXME: slow
- if(t >= 165140.0f*IQ){ // clipped value
- di = t - 165140.0f;
- curbits += 21;
- }else{
- int c = quant(t, Q);
- di = t - c*cbrt(c)*IQ;
- curbits += av_log2(c)*2 - 4 + 1;
- }
- }else{
- di = t - vec[k]*IQ;
- }
- if(vec[k] != 0.0f)
- curbits++;
- rd += di*di*lambda;
- }
- }else{
- for(k = 0; k < dim; k++){
- float di = in[i+k] - vec[k]*IQ;
- rd += di*di*lambda;
- }
- }
- rd += curbits;
- if(rd < mincost){
- mincost = rd;
- minidx = curidx;
- minbits = curbits;
- }
- }
- put_bits(pb, ff_aac_spectral_bits[cb-1][minidx], ff_aac_spectral_codes[cb-1][minidx]);
- if(IS_CODEBOOK_UNSIGNED(cb))
- for(j = 0; j < dim; j++)
- if(ff_aac_codebook_vectors[cb-1][minidx*dim+j] != 0.0f)
- put_bits(pb, 1, in[i+j] < 0.0f);
- if(cb == ESC_BT){
- for(j = 0; j < 2; j++){
- if(ff_aac_codebook_vectors[cb-1][minidx*2+j] == 64.0f){
- int coef = quant(in[i+j], Q);
- int len = av_log2(coef);
-
- put_bits(pb, len - 4 + 1, (1 << (len - 4 + 1)) - 2);
- put_bits(pb, len, coef & ((1 << len) - 1));
- }
- }
- }
- }
-}
-
-#else
-
-/**
- * Calculate rate distortion cost for quantizing with given codebook
- *
- * @return quantization distortion
- */
-static float quantize_band_cost(const float *in, int size, int scale_idx, int cb,
- const float lambda, const float uplim, int *bits)
-{
- const float Q = ff_aac_pow2sf_tab[200 + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
- int i, j, k;
- float cost = 0;
- const int dim = cb < FIRST_PAIR_BT ? 4 : 2;
- int resbits = 0;
-
- if(!cb){
- for(i = 0; i < size; i++)
- cost += in[i]*in[i]*lambda;
- return cost;
- }
- for(i = 0; i < size; i += dim){
- float mincost = INFINITY;
- int minidx = 0;
- int minbits = 0;
- const float *vec = ff_aac_codebook_vectors[cb-1];
- for(j = 0; j < ff_aac_spectral_sizes[cb-1]; j++, vec += dim){
- float rd = 0.0f;
- int curbits = ff_aac_spectral_bits[cb-1][j];
- if(IS_CODEBOOK_UNSIGNED(cb)){
- for(k = 0; k < dim; k++){
- float t = fabsf(in[i+k]);
- float di;
- //do not code with escape sequence small values
- if(vec[k] == 64.0f && t < 39.0f*Q){
- rd = INFINITY;
- break;
- }
- if(vec[k] == 64.0f){//FIXME: slow
- if(t >= 165140.0f*Q){ // clipped value
- di = t - 165140.0f;
- curbits += 21;
- }else{
- int c = quant(t, 1.0/Q);
- di = t - c*cbrt(c)*Q;
- curbits += av_log2(c)*2 - 4 + 1;
- }
- }else{
- di = t - vec[k]*Q;
- }
- if(vec[k] != 0.0f)
- curbits++;
- rd += di*di*lambda;
- }
- }else{
- for(k = 0; k < dim; k++){
- float di = in[i+k] - vec[k]*Q;
- rd += di*di*lambda;
- }
- }
- rd += curbits;
- if(rd < mincost){
- mincost = rd;
- minidx = j;
- minbits = curbits;
- }
- }
- cost += mincost;
- resbits += minbits;
- if(cost >= uplim)
- return uplim;
- }
-
- if(bits)
- *bits = resbits;
- return cost;
-}
-
-/**
- * Prepare coefficients for encoding.
- *
- * @return sum of coefficient absolute values
- */
-static void quantize_and_encode_band(PutBitContext *pb, const float *in, int size,
- int scale_idx, int cb, const float lambda)
-{
- const float Q = ff_aac_pow2sf_tab[200 + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];
- const float IQ = ff_aac_pow2sf_tab[200 - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];
- int i, j, k;
- const int dim = cb < FIRST_PAIR_BT ? 4 : 2;
-
- if(!cb)
- return;
-
- for(i = 0; i < size; i += dim){
- float mincost = INFINITY;
- int minidx = 0;
- int minbits = 0;
- const float *vec = ff_aac_codebook_vectors[cb-1];
- for(j = 0; j < ff_aac_spectral_sizes[cb-1]; j++, vec += dim){
- float rd = 0.0f;
- int curbits = ff_aac_spectral_bits[cb-1][j];
- if(IS_CODEBOOK_UNSIGNED(cb)){
- for(k = 0; k < dim; k++){
- float t = fabsf(in[i+k]);
- float di;
- //do not code with escape sequence small values
- if(vec[k] == 64.0f && t < 39.0f*Q){
- rd = INFINITY;
- break;
- }
- if(vec[k] == 64.0f){//FIXME: slow
- if(t >= 165140.0f*Q){ // clipped value
- di = t - 165140.0f;
- curbits += 21;
- }else{
- int c = quant(t, IQ);
- di = t - c*cbrt(c)*Q;
- curbits += av_log2(c)*2 - 4 + 1;
- }
- }else{
- di = t - vec[k]*Q;
- }
- if(vec[k] != 0.0f)
- curbits++;
- rd += di*di*lambda;
- }
- }else{
- for(k = 0; k < dim; k++){
- float di = in[i+k] - vec[k]*Q;
- rd += di*di*lambda;
- }
- }
- rd += curbits;
- if(rd < mincost){
- mincost = rd;
- minidx = j;
- minbits = curbits;
- }
- }
- put_bits(pb, ff_aac_spectral_bits[cb-1][minidx], ff_aac_spectral_codes[cb-1][minidx]);
- if(IS_CODEBOOK_UNSIGNED(cb))
- for(j = 0; j < dim; j++)
- if(ff_aac_codebook_vectors[cb-1][minidx*dim+j] != 0.0f)
- put_bits(pb, 1, in[i+j] < 0.0f);
- if(cb == ESC_BT){
- for(j = 0; j < 2; j++){
- if(ff_aac_codebook_vectors[cb-1][minidx*2+j] == 64.0f){
- int coef = quant(in[i+j], IQ);
- int len = av_log2(coef);
-
- put_bits(pb, len - 4 + 1, (1 << (len - 4 + 1)) - 2);
- put_bits(pb, len, coef & ((1 << len) - 1));
- }
- }
- }
- }
-}
-
-#endif
-
-/**
- * structure used in optimal codebook search
- */
-typedef struct BandCodingPath {
- int prev_idx; ///< pointer to the previous path point
- int codebook; ///< codebook for coding band run
- float cost; ///< path cost
- int run;
-} BandCodingPath;
-
-/**
- * Encode band info for single window group bands.
- */
-static void encode_window_bands_info(AACEncContext *s, SingleChannelElement *sce,
- int win, int group_len)
-{
- BandCodingPath path[120][12];
- int w, swb, cb, start, start2, size;
- int i, j;
- const int max_sfb = sce->ics.max_sfb;
- const int run_bits = sce->ics.num_windows == 1 ? 5 : 3;
- const int run_esc = (1 << run_bits) - 1;
- int idx, ppos, count;
- int stackrun[120], stackcb[120], stack_len;
-
- start = win*128;
- for(cb = 0; cb < 12; cb++){
- path[0][cb].cost = 0.0f;
- path[0][cb].prev_idx = -1;
- path[0][cb].run = 0;
- }
- for(swb = 0; swb < max_sfb; swb++){
- start2 = start;
- size = sce->ics.swb_sizes[swb];
- if(sce->zeroes[win*16 + swb]){
- for(cb = 0; cb < 12; cb++){
- path[swb+1][cb].prev_idx = cb;
- path[swb+1][cb].cost = path[swb][cb].cost;
- path[swb+1][cb].run = path[swb][cb].run + 1;
- }
- }else{
- float minrd = INFINITY;
- int mincb = 0;
- for(cb = 0; cb < 12; cb++){
- float rd = 0.0f;
- for(w = 0; w < group_len; w++){
- FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(win+w)*16+swb];
- rd += quantize_band_cost(sce->coeffs + start + w*128, size,
- sce->sf_idx[(win+w)*16+swb], cb,
- s->lambda / band->threshold, INFINITY, NULL);
- }
- if( run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run]
- != run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run+1])
- rd += run_bits;
- path[swb+1][cb].prev_idx = cb;
- path[swb+1][cb].cost = path[swb][cb].cost + rd;
- path[swb+1][cb].run = path[swb][cb].run + 1;
- if(rd < minrd){
- minrd = rd;
- mincb = cb;
- }
- }
- for(cb = 0; cb < 12; cb++){
- float cost = path[swb][cb].cost + minrd + run_bits + 4;
- if(cost < path[swb+1][cb].cost){
- path[swb+1][cb].prev_idx = mincb;
- path[swb+1][cb].cost = cost;
- path[swb+1][cb].run = 1;
- }
- }
- }
- start += sce->ics.swb_sizes[swb];
- }
-
- //convert resulting path from backward-linked list
- stack_len = 0;
- idx = 0;
- for(cb = 1; cb < 12; cb++){
- if(path[max_sfb][cb].cost < path[max_sfb][idx].cost)
- idx = cb;
- }
- ppos = max_sfb;
- while(ppos > 0){
- cb = idx;
- stackrun[stack_len] = path[ppos][cb].run;
- stackcb [stack_len] = cb;
- idx = path[ppos][cb].prev_idx;
- ppos -= path[ppos][cb].run;
- stack_len++;
- }
- //perform actual band info encoding
- start = 0;
- for(i = stack_len - 1; i >= 0; i--){
- put_bits(&s->pb, 4, stackcb[i]);
- count = stackrun[i];
- memset(sce->zeroes + win*16 + start, !stackcb[i], count);
- //XXX: memset when band_type is also uint8_t
- for(j = 0; j < count; j++){
- sce->band_type[win*16 + start] = stackcb[i];
- start++;
- }
- while(count >= run_esc){
- put_bits(&s->pb, run_bits, run_esc);
- count -= run_esc;
- }
- put_bits(&s->pb, run_bits, count);
- }
-}
-
-/**
- * Produce integer coefficients from scalefactors provided by the model.
- */
-static void adjust_frame_information(AACEncContext *apc, ChannelElement *cpe, int chans)
-{
- int i, w, w2, g, ch;
- int start, sum, maxsfb, cmaxsfb;
-
- for(ch = 0; ch < chans; ch++){
- IndividualChannelStream *ics = &cpe->ch[ch].ics;
- start = 0;
- maxsfb = 0;
- cpe->ch[ch].pulse.num_pulse = 0;
- for(w = 0; w < ics->num_windows*16; w += 16){
- for(g = 0; g < ics->num_swb; g++){
- sum = 0;
- //apply M/S
- if(!ch && cpe->ms_mask[w + g]){
- for(i = 0; i < ics->swb_sizes[g]; i++){
- cpe->ch[0].coeffs[start+i] = (cpe->ch[0].coeffs[start+i] + cpe->ch[1].coeffs[start+i]) / 2.0;
- cpe->ch[1].coeffs[start+i] = cpe->ch[0].coeffs[start+i] - cpe->ch[1].coeffs[start+i];
- }
- }
- start += ics->swb_sizes[g];
- }
- for(cmaxsfb = ics->num_swb; cmaxsfb > 0 && cpe->ch[ch].zeroes[w+cmaxsfb-1]; cmaxsfb--);
- maxsfb = FFMAX(maxsfb, cmaxsfb);
- }
- ics->max_sfb = maxsfb;
-
- //adjust zero bands for window groups
- for(w = 0; w < ics->num_windows; w += ics->group_len[w]){
- for(g = 0; g < ics->max_sfb; g++){
- i = 1;
- for(w2 = w; w2 < w + ics->group_len[w]; w2++){
- if(!cpe->ch[ch].zeroes[w2*16 + g]){
- i = 0;
- break;
- }
- }
- cpe->ch[ch].zeroes[w*16 + g] = i;
- }
- }
- }
-
- if(chans > 1 && cpe->common_window){
- IndividualChannelStream *ics0 = &cpe->ch[0].ics;
- IndividualChannelStream *ics1 = &cpe->ch[1].ics;
- int msc = 0;
- ics0->max_sfb = FFMAX(ics0->max_sfb, ics1->max_sfb);
- ics1->max_sfb = ics0->max_sfb;
- for(w = 0; w < ics0->num_windows*16; w += 16)
- for(i = 0; i < ics0->max_sfb; i++)
- if(cpe->ms_mask[w+i]) msc++;
- if(msc == 0 || ics0->max_sfb == 0) cpe->ms_mode = 0;
- else cpe->ms_mode = msc < ics0->max_sfb ? 1 : 2;
- }
-}
-
-typedef struct TrellisPath {
- float cost;
- int prev;
- int min_val;
- int max_val;
-} TrellisPath;
-
-static void search_for_quantizers_anmr(AACEncContext *s, SingleChannelElement *sce, const float lambda)
-{
- int q, w, w2, g, start = 0;
- int i;
- int idx;
- TrellisPath paths[256*121];
- int bandaddr[121];
- int minq;
- float mincost;
-
- for(i = 0; i < 256; i++){
- paths[i].cost = 0.0f;
- paths[i].prev = -1;
- paths[i].min_val = i;
- paths[i].max_val = i;
- }
- for(i = 256; i < 256*121; i++){
- paths[i].cost = INFINITY;
- paths[i].prev = -2;
- paths[i].min_val = INT_MAX;
- paths[i].max_val = 0;
- }
- idx = 256;
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
- start = w*128;
- for(g = 0; g < sce->ics.num_swb; g++){
- const float *coefs = sce->coeffs + start;
- float qmin, qmax;
- int nz = 0;
-
- bandaddr[idx >> 8] = w*16+g;
- qmin = INT_MAX;
- qmax = 0.0f;
- for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
- FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g];
- if(band->energy <= band->threshold || band->threshold == 0.0f){
- sce->zeroes[(w+w2)*16+g] = 1;
- continue;
- }
- sce->zeroes[(w+w2)*16+g] = 0;
- nz = 1;
- for(i = 0; i < sce->ics.swb_sizes[g]; i++){
- float t = fabsf(coefs[w2*128+i]);
- if(t > 0.0f) qmin = fminf(qmin, t);
- qmax = fmaxf(qmax, t);
- }
- }
- if(nz){
- int minscale, maxscale;
- float minrd = INFINITY;
- //minimum scalefactor index is when minimum nonzero coefficient after quantizing is not clipped
- minscale = av_clip_uint8(log2(qmin)*4 - 69 + SCALE_ONE_POS - SCALE_DIV_512);
- //maximum scalefactor index is when maximum coefficient after quantizing is still not zero
- maxscale = av_clip_uint8(log2(qmax)*4 + 6 + SCALE_ONE_POS - SCALE_DIV_512);
- for(q = minscale; q < maxscale; q++){
- float dists[12], dist;
- memset(dists, 0, sizeof(dists));
- for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
- FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g];
- int cb;
- for(cb = 0; cb <= ESC_BT; cb++){
- dists[cb] += quantize_band_cost(coefs + w2*128, sce->ics.swb_sizes[g],
- q, cb, s->lambda / band->threshold, INFINITY, NULL);
- }
- }
- dist = dists[0];
- for(i = 1; i <= ESC_BT; i++)
- dist = fminf(dist, dists[i]);
- minrd = fminf(minrd, dist);
-
- for(i = FFMAX(q - SCALE_MAX_DIFF, 0); i < FFMIN(q + SCALE_MAX_DIFF, 256); i++){
- float cost;
- int minv, maxv;
- if(isinf(paths[idx - 256 + i].cost))
- continue;
- cost = paths[idx - 256 + i].cost + dist
- + ff_aac_scalefactor_bits[q - i + SCALE_DIFF_ZERO];
- minv = FFMIN(paths[idx - 256 + i].min_val, q);
- maxv = FFMAX(paths[idx - 256 + i].max_val, q);
- if(cost < paths[idx + q].cost && maxv-minv < SCALE_MAX_DIFF){
- paths[idx + q].cost = cost;
- paths[idx + q].prev = idx - 256 + i;
- paths[idx + q].min_val = minv;
- paths[idx + q].max_val = maxv;
- }
- }
- }
- }else{
- for(q = 0; q < 256; q++){
- if(!isinf(paths[idx - 256 + q].cost)){
- paths[idx + q].cost = paths[idx - 256 + q].cost + 1;
- paths[idx + q].prev = idx - 256 + q;
- paths[idx + q].min_val = FFMIN(paths[idx - 256 + q].min_val, q);
- paths[idx + q].max_val = FFMAX(paths[idx - 256 + q].max_val, q);
- continue;
- }
- for(i = FFMAX(q - SCALE_MAX_DIFF, 0); i < FFMIN(q + SCALE_MAX_DIFF, 256); i++){
- float cost;
- int minv, maxv;
- if(isinf(paths[idx - 256 + i].cost))
- continue;
- cost = paths[idx - 256 + i].cost + ff_aac_scalefactor_bits[q - i + SCALE_DIFF_ZERO];
- minv = FFMIN(paths[idx - 256 + i].min_val, q);
- maxv = FFMAX(paths[idx - 256 + i].max_val, q);
- if(cost < paths[idx + q].cost && maxv-minv < SCALE_MAX_DIFF){
- paths[idx + q].cost = cost;
- paths[idx + q].prev = idx - 256 + i;
- paths[idx + q].min_val = minv;
- paths[idx + q].max_val = maxv;
- }
- }
- }
- }
- sce->zeroes[w*16+g] = !nz;
- start += sce->ics.swb_sizes[g];
- idx += 256;
- }
- }
- idx -= 256;
- mincost = paths[idx].cost;
- minq = idx;
- for(i = 1; i < 256; i++){
- if(paths[idx + i].cost < mincost){
- mincost = paths[idx + i].cost;
- minq = idx + i;
- }
- }
- while(minq >= 256){
- sce->sf_idx[bandaddr[minq>>8]] = minq & 0xFF;
- minq = paths[minq].prev;
- }
- //set the same quantizers inside window groups
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w])
- for(g = 0; g < sce->ics.num_swb; g++)
- for(w2 = 1; w2 < sce->ics.group_len[w]; w2++)
- sce->sf_idx[(w+w2)*16+g] = sce->sf_idx[w*16+g];
-}
-
-/**
- * two-loop quantizers search taken from ISO 13818-7 Appendix C
- */
-static void search_for_quantizers_twoloop(AVCodecContext *avctx, AACEncContext *s,
- SingleChannelElement *sce, const float lambda)
-{
- int start = 0, i, w, w2, g;
- int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / avctx->channels;
- float dists[128], uplims[128];
- int fflag, minscaler;
- int its = 0;
- int allz = 0;
- float minthr = INFINITY;
-
- //XXX: some heuristic to determine initial quantizers will reduce search time
- memset(dists, 0, sizeof(dists));
- //determine zero bands and upper limits
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
- for(g = 0; g < sce->ics.num_swb; g++){
- int nz = 0;
- float uplim = 0.0f;
- for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
- FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g];
- uplim += band->threshold;
- if(band->energy <= band->threshold || band->threshold == 0.0f){
- sce->zeroes[(w+w2)*16+g] = 1;
- continue;
- }
- nz = 1;
- }
- uplims[w*16+g] = uplim *512;
- sce->zeroes[w*16+g] = !nz;
- if(nz)
- minthr = fminf(minthr, uplim);
- allz = FFMAX(allz, nz);
- }
- }
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
- for(g = 0; g < sce->ics.num_swb; g++){
- if(sce->zeroes[w*16+g]){
- sce->sf_idx[w*16+g] = SCALE_ONE_POS;
- continue;
- }
- sce->sf_idx[w*16+g] = SCALE_ONE_POS + fminf(log2(uplims[w*16+g]/minthr)*4,59);
- }
- }
-
- if(!allz)
- return;
- //perform two-loop search
- //outer loop - improve quality
- do{
- int tbits, qstep;
- minscaler = sce->sf_idx[0];
- //inner loop - quantize spectrum to fit into given number of bits
- qstep = its ? 1 : 32;
- do{
- int prev = -1;
- tbits = 0;
- fflag = 0;
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
- start = w*128;
- for(g = 0; g < sce->ics.num_swb; g++){
- const float *coefs = sce->coeffs + start;
- int bits = 0;
- int cb;
- float mindist = INFINITY;
- int minbits = 0;
-
- if(sce->zeroes[w*16+g] || sce->sf_idx[w*16+g] >= 218)
- continue;
- minscaler = FFMIN(minscaler, sce->sf_idx[w*16+g]);
- for(cb = 0; cb <= ESC_BT; cb++){
- float dist = 0.0f;
- int bb = 0;
- for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
- int b;
- dist += quantize_band_cost(coefs + w2*128,
- sce->ics.swb_sizes[g],
- sce->sf_idx[w*16+g],
- ESC_BT,
- 1.0,
- INFINITY,
- &b);
- bb += b;
- }
- if(dist < mindist){
- mindist = dist;
- minbits = bb;
- }
- }
- dists[w*16+g] = mindist - minbits;
- bits = minbits;
- if(prev != -1){
- bits += ff_aac_scalefactor_bits[sce->sf_idx[w*16+g] - prev + SCALE_DIFF_ZERO];
- }
- tbits += bits;
- start += sce->ics.swb_sizes[g];
- prev = sce->sf_idx[w*16+g];
- }
- }
- if(tbits > destbits){
- for(i = 0; i < 128; i++){
- if(sce->sf_idx[i] < 218 - qstep){
- sce->sf_idx[i] += qstep;
- }
- }
- }else{
- for(i = 0; i < 128; i++){
- if(sce->sf_idx[i] > 60 - qstep){
- sce->sf_idx[i] -= qstep;
- }
- }
- }
- qstep >>= 1;
- if(!qstep && tbits > destbits*1.02)
- qstep = 1;
- if(sce->sf_idx[0] >= 217)break;
- }while(qstep);
-
- fflag = 0;
- minscaler = av_clip(minscaler, 60, 255 - SCALE_MAX_DIFF);
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
- start = w*128;
- for(g = 0; g < sce->ics.num_swb; g++){
- int prevsc = sce->sf_idx[w*16+g];
- if(dists[w*16+g] > uplims[w*16+g] && sce->sf_idx[w*16+g] > 60)
- sce->sf_idx[w*16+g]--;
- sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], minscaler, minscaler + SCALE_MAX_DIFF);
- sce->sf_idx[w*16+g] = FFMIN(sce->sf_idx[w*16+g], 219);
- if(sce->sf_idx[w*16+g] != prevsc)
- fflag = 1;
- }
- }
- its++;
- }while(fflag && its < 10);
-}
-
-static void search_for_quantizers_faac(AACEncContext *s, SingleChannelElement *sce, const float lambda)
-{
- int start = 0, i, w, w2, g;
- float uplim[128], maxq[128];
- int minq;
-#if 0
- float distfact = ((sce->ics.num_windows > 1) ? 85.80 : 147.84) / lambda;
- int last = 0, lastband = 0, curband = 0;
- float avg_energy = 0.0;
- if(sce->ics.num_windows == 1){
- start = 0;
- for(i = 0; i < 1024; i++){
- if(i - start >= sce->ics.swb_sizes[curband]){
- start += sce->ics.swb_sizes[curband];
- curband++;
- }
- if(sce->coeffs[i]){
- avg_energy += sce->coeffs[i] * sce->coeffs[i];
- last = i;
- lastband = curband;
- }
- }
- }else{
- for(w = 0; w < 8; w++){
- const float *coeffs = sce->coeffs + w*128;
- start = 0;
- for(i = 0; i < 128; i++){
- if(i - start >= sce->ics.swb_sizes[curband]){
- start += sce->ics.swb_sizes[curband];
- curband++;
- }
- if(coeffs[i]){
- avg_energy += coeffs[i] * coeffs[i];
- last = FFMAX(last, i);
- lastband = FFMAX(lastband, curband);
- }
- }
- }
- }
- last++;
- avg_energy /= last;
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
- start = w*128;
- for(g = 0; g < sce->ics.num_swb; g++){
- float *coefs = sce->coeffs + start;
- const int size = sce->ics.swb_sizes[g];
- int start2 = start, end2 = start + size, peakpos = start;
- float maxval = -1, thr = 0.0f, t;
- maxq[w*16+g] = 0.0f;
- if(g > lastband){
- maxq[w*16+g] = 0.0f;
- start += size;
- for(w2 = 0; w2 < sce->ics.group_len[w]; w2++)
- memset(coefs + w2*128, 0, sizeof(coefs[0])*size);
- continue;
- }
- for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
- for(i = 0; i < size; i++){
- float t = coefs[w2*128+i]*coefs[w2*128+i];
- maxq[w*16+g] = fmaxf(maxq[w*16+g], coefs[w2*128 + i]);
- thr += t;
- if(sce->ics.num_windows == 1 && maxval < t){
- maxval = t;
- peakpos = start+i;
- }
- }
- }
- if(sce->ics.num_windows == 1){
- start2 = FFMAX(peakpos - 2, start2);
- end2 = FFMIN(peakpos + 3, end2);
- }
- start += size;
- thr = pow(thr / (avg_energy * (end2 - start2)), 0.3 + 0.1*(lastband - g) / lastband);
- t = 1.0 - (1.0 * start2 / last);
- uplim[w*16+g] = distfact / (1.4 * thr + t*t*t + 0.075);
- }
- }
-#else
- memset(maxq, 0, sizeof(maxq));
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
- start = w*128;
- for(g = 0; g < sce->ics.num_swb; g++){
- float *coefs = sce->coeffs + start;
- const int size = sce->ics.swb_sizes[g];
- float thr = 0.0f;
- for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
- FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g];
- thr += band->threshold;
- for(i = 0; i < size; i++){
- maxq[w*16+g] = fmaxf(maxq[w*16+g], fabsf(coefs[w2*128 + i]));
- }
- }
- uplim[w*16+g] = thr / lambda;
- start += size;
- }
- }
-#endif
- memset(sce->sf_idx, 0, sizeof(sce->sf_idx));
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
- start = w*128;
- for(g = 0; g < sce->ics.num_swb; g++){
- const float *coefs = sce->coeffs + start;
- const int size = sce->ics.swb_sizes[g];
- int scf, prev_scf, step;
- if(maxq[w*16+g] < 21.544){
- sce->zeroes[w*16+g] = 1;
- continue;
- }
- sce->zeroes[w*16+g] = 0;
- scf = prev_scf = av_clip(SCALE_ONE_POS + log2(1/maxq[w*16+g])*16/3, 60, 218);
- step = 16;
- for(;;){
- float dist = 0.0f, t;
- int quant_max;
-
- for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
- int b;
- dist += quantize_band_cost(coefs + w2*128,
- sce->ics.swb_sizes[g],
- scf,
- ESC_BT,
- 1.0,
- INFINITY,
- &b);
- dist -= b;
- }
- quant_max = quant(maxq[w*16+g], ff_aac_pow2sf_tab[200 - scf + SCALE_ONE_POS]);
- if(quant_max >= 8191){ // too much, return to the previous quantizer
- sce->sf_idx[w*16+g] = prev_scf;
- break;
- }
- prev_scf = scf;
- t = pow(dist / size, -2.0/3.0);
- if(FFABS(step) > 4){
- int newstep = 4*log(t / maxq[w*16+g])/log(2) - 2;
- step = av_clip(-newstep, -4, 4);
- }
- if(FFABS(step) >= 4){
- step = 1 - step;
- scf += step;
- }else if(t >= uplim[w*16+g]){
- scf -= FFABS(step);
- }else{
- sce->sf_idx[w*16+g] = scf;
- break;
- }
- }
- start += size;
- }
- }
- minq = sce->sf_idx[0] ? sce->sf_idx[0] : INT_MAX;
- for(i = 1; i < 128; i++){
- if(!sce->sf_idx[i])
- sce->sf_idx[i] = sce->sf_idx[i-1];
- else
- minq = FFMIN(minq, sce->sf_idx[i]);
- }
- if(minq == INT_MAX) minq = 0;
- for(i = 126; i >= 0; i--){
- if(!sce->sf_idx[i])
- sce->sf_idx[i] = sce->sf_idx[i+1];
- sce->sf_idx[i] = av_clip(sce->sf_idx[i], minq, minq + SCALE_MAX_DIFF);
- }
-}
-
-static void search_for_quantizers_fast(AACEncContext *s, SingleChannelElement *sce)
-{
- int start = 0, i, w, w2, g;
- int minq = 255;
-
- memset(sce->sf_idx, 0, sizeof(sce->sf_idx));
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
- start = w*128;
- for(g = 0; g < sce->ics.num_swb; g++){
- for(w2 = 0; w2 < sce->ics.group_len[w]; w2++){
- FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g];
- if(band->energy <= band->threshold){
- sce->sf_idx[(w+w2)*16+g] = 218;
- sce->zeroes[(w+w2)*16+g] = 1;
- }else{
- sce->sf_idx[(w+w2)*16+g] = av_clip(SCALE_ONE_POS - SCALE_DIV_512 + log2(band->threshold), 80, 218);
- sce->zeroes[(w+w2)*16+g] = 0;
- }
- minq = FFMIN(minq, sce->sf_idx[(w+w2)*16+g]);
- }
- }
- }
- for(i = 0; i < 128; i++){
- sce->sf_idx[i] = av_clip(sce->sf_idx[i], minq, minq + SCALE_MAX_DIFF - 1);
- }
- //set the same quantizers inside window groups
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w])
- for(g = 0; g < sce->ics.num_swb; g++)
- for(w2 = 1; w2 < sce->ics.group_len[w]; w2++)
- sce->sf_idx[(w+w2)*16+g] = sce->sf_idx[w*16+g];
-}
-
-static void search_for_quantizers(AVCodecContext *avctx, AACEncContext *s,
- SingleChannelElement *sce)
-{
- search_for_quantizers_anmr(s, sce, s->lambda);
-// search_for_quantizers_twoloop(avctx, s, sce, s->lambda);
-// search_for_quantizers_faac(s, sce, av_clipf(s->lambda * 2e8, 50.0f, 300.0f));
-// search_for_quantizers_fast(s, sce);
-}
-
-static void search_for_ms(AACEncContext *s, ChannelElement *cpe, const float lambda)
-{
- int start = 0, i, w, w2, g;
- float M[128], S[128];
- SingleChannelElement *sce0 = &cpe->ch[0];
- SingleChannelElement *sce1 = &cpe->ch[1];
- if(!cpe->common_window)
- return;
- for(w = 0; w < sce0->ics.num_windows; w += sce0->ics.group_len[w]){
- for(g = 0; g < sce0->ics.num_swb; g++){
- if(!cpe->ch[0].zeroes[w*16+g] && !cpe->ch[1].zeroes[w*16+g]){
- float dist1 = 0.0f, dist2 = 0.0f;
- for(w2 = 0; w2 < sce0->ics.group_len[w]; w2++){
- FFPsyBand *band0 = &s->psy.psy_bands[(s->cur_channel+0)*PSY_MAX_BANDS+(w+w2)*16+g];
- FFPsyBand *band1 = &s->psy.psy_bands[(s->cur_channel+1)*PSY_MAX_BANDS+(w+w2)*16+g];
- float minthr = fminf(band0->threshold, band1->threshold);
- float maxthr = fmaxf(band0->threshold, band1->threshold);
- for(i = 0; i < sce0->ics.swb_sizes[g]; i++){
- M[i] = (sce0->coeffs[start+w2*128+i]
- + sce1->coeffs[start+w2*128+i])*0.5;
- S[i] = sce0->coeffs[start+w2*128+i]
- - sce1->coeffs[start+w2*128+i];
- }
- dist1 += quantize_band_cost(sce0->coeffs + start + w2*128,
- sce0->ics.swb_sizes[g],
- sce0->sf_idx[(w+w2)*16+g],
- sce0->band_type[(w+w2)*16+g],
- lambda / band0->threshold, INFINITY, NULL);
- dist1 += quantize_band_cost(sce1->coeffs + start + w2*128,
- sce1->ics.swb_sizes[g],
- sce1->sf_idx[(w+w2)*16+g],
- sce1->band_type[(w+w2)*16+g],
- lambda / band1->threshold, INFINITY, NULL);
- dist2 += quantize_band_cost(M,
- sce0->ics.swb_sizes[g],
- sce0->sf_idx[(w+w2)*16+g],
- sce0->band_type[(w+w2)*16+g],
- lambda / maxthr, INFINITY, NULL);
- dist2 += quantize_band_cost(S,
- sce1->ics.swb_sizes[g],
- sce1->sf_idx[(w+w2)*16+g],
- sce1->band_type[(w+w2)*16+g],
- lambda / minthr, INFINITY, NULL);
- }
- cpe->ms_mask[w*16+g] = dist2 < dist1;
- }
- start += sce0->ics.swb_sizes[g];
- }
- }
-}
-
-/**
- * Encode scalefactor band coding type.
- */
-static void encode_band_info(AACEncContext *s, SingleChannelElement *sce)
-{
- int w;
-
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
- encode_window_bands_info(s, sce, w, sce->ics.group_len[w]);
- }
-}
-
-/**
- * Encode scalefactors.
- */
-static void encode_scale_factors(AVCodecContext *avctx, AACEncContext *s, SingleChannelElement *sce)
-{
- int off = sce->sf_idx[0], diff;
- int i, w;
-
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
- for(i = 0; i < sce->ics.max_sfb; i++){
- if(!sce->zeroes[w*16 + i]){
- diff = sce->sf_idx[w*16 + i] - off + SCALE_DIFF_ZERO;
- if(diff < 0 || diff > 120) av_log(avctx, AV_LOG_ERROR, "Scalefactor difference is too big to be coded\n");
- off = sce->sf_idx[w*16 + i];
- put_bits(&s->pb, ff_aac_scalefactor_bits[diff], ff_aac_scalefactor_code[diff]);
- }
- }
- }
-}
-
-/**
- * Encode pulse data.
- */
-static void encode_pulses(AACEncContext *s, Pulse *pulse)
-{
- int i;
-
- put_bits(&s->pb, 1, !!pulse->num_pulse);
- if(!pulse->num_pulse) return;
-
- put_bits(&s->pb, 2, pulse->num_pulse - 1);
- put_bits(&s->pb, 6, pulse->start);
- for(i = 0; i < pulse->num_pulse; i++){
- put_bits(&s->pb, 5, pulse->pos[i]);
- put_bits(&s->pb, 4, pulse->amp[i]);
- }
-}
-
-/**
- * Encode spectral coefficients processed by psychoacoustic model.
- */
-static void encode_spectral_coeffs(AACEncContext *s, SingleChannelElement *sce)
-{
- int start, i, w, w2;
-
- for(w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]){
- start = 0;
- for(i = 0; i < sce->ics.max_sfb; i++){
- if(sce->zeroes[w*16 + i]){
- start += sce->ics.swb_sizes[i];
- continue;
- }
- for(w2 = w; w2 < w + sce->ics.group_len[w]; w2++){
- quantize_and_encode_band(&s->pb, sce->coeffs + start + w2*128,
- sce->ics.swb_sizes[i],
- sce->sf_idx[w*16 + i],
- sce->band_type[w*16 + i],
- s->lambda);
- }
- start += sce->ics.swb_sizes[i];
- }
- }
-}
-
-/**
- * Encode one channel of audio data.
- */
-static int encode_individual_channel(AVCodecContext *avctx, AACEncContext *s, SingleChannelElement *sce, int common_window)
-{
- put_bits(&s->pb, 8, sce->sf_idx[0]);
- if(!common_window) put_ics_info(s, &sce->ics);
- encode_band_info(s, sce);
- encode_scale_factors(avctx, s, sce);
- encode_pulses(s, &sce->pulse);
- put_bits(&s->pb, 1, 0); //tns
- put_bits(&s->pb, 1, 0); //ssr
- encode_spectral_coeffs(s, sce);
- return 0;
-}
-
-/**
- * Write some auxiliary information about the created AAC file.
- */
-static void put_bitstream_info(AVCodecContext *avctx, AACEncContext *s, const char *name)
-{
- int i, namelen, padbits;
-
- namelen = strlen(name) + 2;
- put_bits(&s->pb, 3, TYPE_FIL);
- put_bits(&s->pb, 4, FFMIN(namelen, 15));
- if(namelen >= 15)
- put_bits(&s->pb, 8, namelen - 16);
- put_bits(&s->pb, 4, 0); //extension type - filler
- padbits = 8 - (put_bits_count(&s->pb) & 7);
- align_put_bits(&s->pb);
- for(i = 0; i < namelen - 2; i++)
- put_bits(&s->pb, 8, name[i]);
- put_bits(&s->pb, 12 - padbits, 0);
-}
-
-static int aac_encode_frame(AVCodecContext *avctx,
- uint8_t *frame, int buf_size, void *data)
-{
- AACEncContext *s = avctx->priv_data;
- int16_t *samples = s->samples, *samples2, *la;
- ChannelElement *cpe;
- int i, j, chans, tag, start_ch;
- const uint8_t *chan_map = aac_chan_configs[avctx->channels-1];
- int chan_el_counter[4];
-
- if(s->last_frame)
- return 0;
- if(data){
- if(!s->psypp){
- memcpy(s->samples + 1024 * avctx->channels, data, 1024 * avctx->channels * sizeof(s->samples[0]));
- }else{
- start_ch = 0;
- samples2 = s->samples + 1024 * avctx->channels;
- for(i = 0; i < chan_map[0]; i++){
- tag = chan_map[i+1];
- chans = tag == TYPE_CPE ? 2 : 1;
- ff_psy_preprocess(s->psypp, (uint16_t*)data + start_ch, samples2 + start_ch, start_ch + i, chans);
- start_ch += chans;
- }
- }
- }
- if(!avctx->frame_number){
- memcpy(s->samples, s->samples + 1024 * avctx->channels, 1024 * avctx->channels * sizeof(s->samples[0]));
- return 0;
- }
-
- init_put_bits(&s->pb, frame, buf_size*8);
- if((avctx->frame_number & 0xFF)==1 && !(avctx->flags & CODEC_FLAG_BITEXACT)){
- put_bitstream_info(avctx, s, LIBAVCODEC_IDENT);
- }
- start_ch = 0;
- memset(chan_el_counter, 0, sizeof(chan_el_counter));
- for(i = 0; i < chan_map[0]; i++){
- FFPsyWindowInfo wi[2];
- tag = chan_map[i+1];
- chans = tag == TYPE_CPE ? 2 : 1;
- cpe = &s->cpe[i];
- samples2 = samples + start_ch;
- la = samples2 + 1024 * avctx->channels + start_ch;
- if(!data) la = NULL;
- s->lambda = 5e-7f;
- for(j = 0; j < chans; j++){
- IndividualChannelStream *ics = &cpe->ch[j].ics;
- int k;
- wi[j] = ff_psy_suggest_window(&s->psy, samples2, la, start_ch + j, ics->window_sequence[0]);
- ics->window_sequence[1] = ics->window_sequence[0];
- ics->window_sequence[0] = wi[j].window_type[0];
- ics->use_kb_window[1] = ics->use_kb_window[0];
- ics->use_kb_window[0] = wi[j].window_shape;
- ics->num_windows = wi[j].num_windows;
- ics->swb_sizes = s->psy.bands [ics->num_windows == 8];
- ics->num_swb = s->psy.num_bands[ics->num_windows == 8];
- for(k = 0; k < ics->num_windows; k++)
- ics->group_len[k] = wi[j].grouping[k];
-
- s->cur_channel = start_ch + j;
- apply_window_and_mdct(avctx, s, &cpe->ch[j], samples2, j);
- search_for_quantizers(avctx, s, &cpe->ch[j]);
- }
- cpe->common_window = 0;
- if(chans > 1
- && wi[0].window_type[0] == wi[1].window_type[0]
- && wi[0].window_shape == wi[1].window_shape){
-
- cpe->common_window = 1;
- for(j = 0; j < wi[0].num_windows; j++){
- if(wi[0].grouping[j] != wi[1].grouping[j]){
- cpe->common_window = 0;
- break;
- }
- }
- }
-// search_for_ms(s, cpe, s->lambda);
- adjust_frame_information(s, cpe, chans);
- put_bits(&s->pb, 3, tag);
- put_bits(&s->pb, 4, chan_el_counter[tag]++);
- if(chans == 2){
- put_bits(&s->pb, 1, cpe->common_window);
- if(cpe->common_window){
- put_ics_info(s, &cpe->ch[0].ics);
- encode_ms_info(&s->pb, cpe);
- }
- }
- for(j = 0; j < chans; j++){
- s->cur_channel = start_ch + j;
- ff_psy_set_band_info(&s->psy, s->cur_channel, cpe->ch[j].coeffs, &wi[j]);
- encode_individual_channel(avctx, s, &cpe->ch[j], cpe->common_window);
- }
- start_ch += chans;
- }
-
- put_bits(&s->pb, 3, TYPE_END);
- flush_put_bits(&s->pb);
- avctx->frame_bits = put_bits_count(&s->pb);
-
- if(!data)
- s->last_frame = 1;
- memcpy(s->samples, s->samples + 1024 * avctx->channels, 1024 * avctx->channels * sizeof(s->samples[0]));
- return put_bits_count(&s->pb)>>3;
-}
-
-static av_cold int aac_encode_end(AVCodecContext *avctx)
-{
- AACEncContext *s = avctx->priv_data;
-
- ff_mdct_end(&s->mdct1024);
- ff_mdct_end(&s->mdct128);
- ff_psy_end(&s->psy);
- ff_psy_preprocess_end(s->psypp);
- av_freep(&s->samples);
- av_freep(&s->cpe);
- return 0;
-}
-
-AVCodec aac_encoder = {
- "aac",
- CODEC_TYPE_AUDIO,
- CODEC_ID_AAC,
- sizeof(AACEncContext),
- aac_encode_init,
- aac_encode_frame,
- aac_encode_end,
- .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY,
- .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE},
- .long_name = NULL_IF_CONFIG_SMALL("Advanced Audio Coding"),
-};
+#endif /* AVCODEC_AACENC_H */
1
0
Author: kostya
Date: Mon Jan 26 15:00:57 2009
New Revision: 4007
Log:
Sync aac.h to the current FFmpeg SVN
Modified:
aacenc/aac.h
Modified: aacenc/aac.h
==============================================================================
--- aacenc/aac.h Mon Jan 26 14:37:36 2009 (r4006)
+++ aacenc/aac.h Mon Jan 26 15:00:57 2009 (r4007)
@@ -46,7 +46,6 @@
#define MAX_ELEM_ID 16
#define TNS_MAX_ORDER 20
-#define PNS_MEAN_ENERGY 3719550720.0f // sqrt(3.0) * 1<<31
enum AudioObjectType {
AOT_NULL,
@@ -133,6 +132,20 @@ enum CouplingPoint {
AFTER_IMDCT = 3,
};
+/**
+ * Predictor State
+ */
+typedef struct {
+ float cor0;
+ float cor1;
+ float var0;
+ float var1;
+ float r0;
+ float r1;
+} PredictorState;
+
+#define MAX_PREDICTORS 672
+
#define SCALE_DIV_512 36 ///< scalefactor difference that corresponds to scale difference in 512 times
#define SCALE_ONE_POS 140 ///< scalefactor index that corresponds to scale=1.0
#define SCALE_MAX_POS 255 ///< scalefactor index maximum value
@@ -153,6 +166,10 @@ typedef struct {
int num_swb; ///< number of scalefactor window bands
int num_windows;
int tns_max_bands;
+ int predictor_present;
+ int predictor_initialized;
+ int predictor_reset_group;
+ uint8_t prediction_used[41];
} IndividualChannelStream;
/**
@@ -198,8 +215,8 @@ typedef struct {
int num_coupled; ///< number of target elements
enum RawDataBlockType type[8]; ///< Type of channel element to be coupled - SCE or CPE.
int id_select[8]; ///< element id
- int ch_select[8]; /**< [0] shared list of gains; [1] list of gains for left channel;
- * [2] list of gains for right channel; [3] lists of gains for both channels
+ int ch_select[8]; /**< [0] shared list of gains; [1] list of gains for right channel;
+ * [2] list of gains for left channel; [3] lists of gains for both channels
*/
float gain[16][120];
} ChannelCoupling;
@@ -220,6 +237,7 @@ typedef struct {
DECLARE_ALIGNED_16(float, saved[1024]); ///< overlap
DECLARE_ALIGNED_16(float, ret[1024]); ///< PCM output
DECLARE_ALIGNED_16(int, icoefs[1024]); ///< integer coefficients for encoding
+ PredictorState predictor_state[MAX_PREDICTORS];
} SingleChannelElement;
/**
@@ -284,6 +302,7 @@ typedef struct {
int sf_offset; ///< offset into pow2sf_tab as appropriate for dsp.float_to_int16
/** @} */
+ DECLARE_ALIGNED(16, float, temp[128]);
} AACContext;
#endif /* AVCODEC_AAC_H */
1
0
Author: kostya
Date: Mon Jan 26 14:37:36 2009
New Revision: 4006
Log:
Sync AAC encoder to current FFmpeg CONFIG_ handling policy
Modified:
aacenc/aacenc.c
Modified: aacenc/aacenc.c
==============================================================================
--- aacenc/aacenc.c Sun Jan 25 16:56:43 2009 (r4005)
+++ aacenc/aacenc.c Mon Jan 26 14:37:36 2009 (r4006)
@@ -232,7 +232,7 @@ static av_cold int aac_encode_init(AVCod
ff_psy_init(&s->psy, avctx, 2, sizes, lengths);
s->psypp = ff_psy_preprocess_init(avctx);
-#ifndef CONFIG_HARDCODED_TABLES
+#if !CONFIG_HARDCODED_TABLES
for (i = 0; i < 316; i++)
ff_aac_pow2sf_tab[i] = pow(2, (i - 200)/4.);
#endif /* CONFIG_HARDCODED_TABLES */
1
0