summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2011-06-30 04:20:53 +0200
committerMichael Niedermayer <michaelni@gmx.at>2011-06-30 04:32:24 +0200
commit8c0cbb0848430e4de7182dc2fa2f70262d8c77c7 (patch)
treed08758ea987f08f1d5a8caf44f082adc5586e815 /libavcodec
parent623bf96678d2009d34e88ed7c2b73c00930cebae (diff)
parent812f2376eecc19c40a95ade1f7a43b762106e0f7 (diff)
Merge remote-tracking branch 'qatar/master'
* qatar/master: rational-test: Add proper main() declaration to fix gcc warnings. configure: Add vdpau and dxva2 to configure results output. Remove unused, never built libavutil/pca.[ch] matroskadec: forward parsing errors to caller. av_find_stream_info: simplify EAGAIN handling. aacenc: Fix determination of Mid/Side Mode. psymodel: Remove the single channel analysis function aacenc: Implement dummy channel group analysis that just calls the single channel analysis for each channel. psymodel: Add channels and channel groups to the psymodel. ARM: remove check for PLD instruction fate: move amr[nw]b test rules into separate files ogg: fix double free when finding length of small chained oggs. swscale: implement >8bit scaling support. build: fix creation of tools dir with make 3.81 build: Mark all-yes Makefile target as phony. pixfmt: fix YUV422/444 wrong endian comment build: create output directories as needed Add new yuv444 pixfmts to avcodec_align_dimensions2 Conflicts: Makefile configure libavutil/pca.c libavutil/pca.h libavutil/pixfmt.h libswscale/swscale.c libswscale/utils.c libswscale/x86/swscale_template.c tests/ref/lavfi/pixdesc tests/ref/lavfi/pixfmts_copy tests/ref/lavfi/pixfmts_null tests/ref/lavfi/pixfmts_scale tests/ref/lavfi/pixfmts_vflip Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/aaccoder.c14
-rw-r--r--libavcodec/aacenc.c13
-rw-r--r--libavcodec/aacpsy.c18
-rw-r--r--libavcodec/arm/dsputil_arm.S7
-rw-r--r--libavcodec/psymodel.c36
-rw-r--r--libavcodec/psymodel.h53
-rw-r--r--libavcodec/utils.c4
7 files changed, 107 insertions, 38 deletions
diff --git a/libavcodec/aaccoder.c b/libavcodec/aaccoder.c
index 4eba5dd83c..b61af18056 100644
--- a/libavcodec/aaccoder.c
+++ b/libavcodec/aaccoder.c
@@ -346,7 +346,7 @@ static void encode_window_bands_info(AACEncContext *s, SingleChannelElement *sce
float cost_stay_here, cost_get_here;
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];
+ FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(win+w)*16+swb];
rd += quantize_band_cost(s, sce->coeffs + start + w*128,
s->scoefs + start + w*128, size,
sce->sf_idx[(win+w)*16+swb], cb,
@@ -626,7 +626,7 @@ static void search_for_quantizers_anmr(AVCodecContext *avctx, AACEncContext *s,
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];
+ FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g];
if (band->energy <= band->threshold || band->threshold == 0.0f) {
sce->zeroes[(w+w2)*16+g] = 1;
continue;
@@ -655,7 +655,7 @@ static void search_for_quantizers_anmr(AVCodecContext *avctx, AACEncContext *s,
float dist = 0;
int cb = find_min_book(maxval, sce->sf_idx[w*16+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];
+ FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g];
dist += quantize_band_cost(s, coefs + w2*128, s->scoefs + start + w2*128, sce->ics.swb_sizes[g],
q + q0, cb, lambda / band->threshold, INFINITY, NULL);
}
@@ -728,7 +728,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
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];
+ FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g];
uplim += band->threshold;
if (band->energy <= band->threshold || band->threshold == 0.0f) {
sce->zeroes[(w+w2)*16+g] = 1;
@@ -1028,7 +1028,7 @@ static void search_for_quantizers_fast(AVCodecContext *avctx, AACEncContext *s,
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 = 0; w2 < sce->ics.group_len[w]; w2++) {
- FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(w+w2)*16+g];
+ FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_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;
@@ -1066,8 +1066,8 @@ static void search_for_ms(AACEncContext *s, ChannelElement *cpe,
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];
+ FFPsyBand *band0 = &s->psy.ch[s->cur_channel+0].psy_bands[(w+w2)*16+g];
+ FFPsyBand *band1 = &s->psy.ch[s->cur_channel+1].psy_bands[(w+w2)*16+g];
float minthr = FFMIN(band0->threshold, band1->threshold);
float maxthr = FFMAX(band0->threshold, band1->threshold);
for (i = 0; i < sce0->ics.swb_sizes[g]; i++) {
diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c
index 2a6dbc8ebd..b877e4eaef 100644
--- a/libavcodec/aacenc.c
+++ b/libavcodec/aacenc.c
@@ -219,7 +219,7 @@ static av_cold int aac_encode_init(AVCodecContext *avctx)
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);
+ ff_psy_init(&s->psy, avctx, 2, sizes, lengths, s->chan_map[0], &s->chan_map[1]);
s->psypp = ff_psy_preprocess_init(avctx);
s->coder = &ff_aac_coders[2];
@@ -373,7 +373,7 @@ static void adjust_frame_information(AACEncContext *apc, ChannelElement *cpe, in
if (msc == 0 || ics0->max_sfb == 0)
cpe->ms_mode = 0;
else
- cpe->ms_mode = msc < ics0->max_sfb ? 1 : 2;
+ cpe->ms_mode = msc < ics0->max_sfb * ics0->num_windows ? 1 : 2;
}
}
@@ -582,14 +582,17 @@ static int aac_encode_frame(AVCodecContext *avctx,
memset(chan_el_counter, 0, sizeof(chan_el_counter));
for (i = 0; i < s->chan_map[0]; i++) {
FFPsyWindowInfo* wi = windows + start_ch;
+ const float *coeffs[2];
tag = s->chan_map[i+1];
chans = tag == TYPE_CPE ? 2 : 1;
cpe = &s->cpe[i];
put_bits(&s->pb, 3, tag);
put_bits(&s->pb, 4, chan_el_counter[tag]++);
+ for (ch = 0; ch < chans; ch++)
+ coeffs[ch] = cpe->ch[ch].coeffs;
+ s->psy.model->analyze(&s->psy, start_ch, coeffs, wi);
for (ch = 0; ch < chans; ch++) {
- s->cur_channel = start_ch + ch;
- s->psy.model->analyze(&s->psy, s->cur_channel, cpe->ch[ch].coeffs, &wi[ch]);
+ s->cur_channel = start_ch * 2 + ch;
s->coder->search_for_quantizers(avctx, s, &cpe->ch[ch], s->lambda);
}
cpe->common_window = 0;
@@ -605,7 +608,7 @@ static int aac_encode_frame(AVCodecContext *avctx,
}
}
}
- s->cur_channel = start_ch;
+ s->cur_channel = start_ch * 2;
if (s->options.stereo_mode && cpe->common_window) {
if (s->options.stereo_mode > 0) {
IndividualChannelStream *ics = &cpe->ch[0].ics;
diff --git a/libavcodec/aacpsy.c b/libavcodec/aacpsy.c
index f2b525694b..4152b70bbf 100644
--- a/libavcodec/aacpsy.c
+++ b/libavcodec/aacpsy.c
@@ -557,8 +557,8 @@ static float calc_reduced_thr_3gpp(AacPsyBand *band, float min_snr,
/**
* Calculate band thresholds as suggested in 3GPP TS26.403
*/
-static void psy_3gpp_analyze(FFPsyContext *ctx, int channel,
- const float *coefs, const FFPsyWindowInfo *wi)
+static void psy_3gpp_analyze_channel(FFPsyContext *ctx, int channel,
+ const float *coefs, const FFPsyWindowInfo *wi)
{
AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data;
AacPsyChannel *pch = &pctx->ch[channel];
@@ -627,7 +627,7 @@ static void psy_3gpp_analyze(FFPsyContext *ctx, int channel,
}
/* 5.6.1.3.2 "Calculation of the desired perceptual entropy" */
- ctx->pe[channel] = pe;
+ ctx->ch[channel].entropy = pe;
desired_bits = calc_bit_demand(pctx, pe, ctx->bitres.bits, ctx->bitres.size, wi->num_windows == 8);
desired_pe = PSY_3GPP_BITS_TO_PE(desired_bits);
/* NOTE: PE correction is kept simple. During initial testing it had very
@@ -731,7 +731,7 @@ static void psy_3gpp_analyze(FFPsyContext *ctx, int channel,
for (w = 0; w < wi->num_windows*16; w += 16) {
for (g = 0; g < num_bands; g++) {
AacPsyBand *band = &pch->band[w+g];
- FFPsyBand *psy_band = &ctx->psy_bands[channel*PSY_MAX_BANDS+w+g];
+ FFPsyBand *psy_band = &ctx->ch[channel].psy_bands[w+g];
psy_band->threshold = band->thr;
psy_band->energy = band->energy;
@@ -741,6 +741,16 @@ static void psy_3gpp_analyze(FFPsyContext *ctx, int channel,
memcpy(pch->prev_band, pch->band, sizeof(pch->band));
}
+static void psy_3gpp_analyze(FFPsyContext *ctx, int channel,
+ const float **coeffs, const FFPsyWindowInfo *wi)
+{
+ int ch;
+ FFPsyChannelGroup *group = ff_psy_find_group(ctx, channel);
+
+ for (ch = 0; ch < group->num_ch; ch++)
+ psy_3gpp_analyze_channel(ctx, channel + ch, coeffs[ch], &wi[ch]);
+}
+
static av_cold void psy_3gpp_end(FFPsyContext *apc)
{
AacPsyContext *pctx = (AacPsyContext*) apc->model_priv_data;
diff --git a/libavcodec/arm/dsputil_arm.S b/libavcodec/arm/dsputil_arm.S
index c614206bac..1247b0fa84 100644
--- a/libavcodec/arm/dsputil_arm.S
+++ b/libavcodec/arm/dsputil_arm.S
@@ -24,11 +24,6 @@
preserve8
-#if !HAVE_PLD
-.macro pld reg
-.endm
-#endif
-
#if HAVE_ARMV5TE
function ff_prefetch_arm, export=1
subs r2, r2, #1
@@ -37,6 +32,8 @@ function ff_prefetch_arm, export=1
bne ff_prefetch_arm
bx lr
endfunc
+#else
+#define pld @
#endif
.macro ALIGN_QWORD_D shift, Rd0, Rd1, Rd2, Rd3, Rn0, Rn1, Rn2, Rn3, Rn4
diff --git a/libavcodec/psymodel.c b/libavcodec/psymodel.c
index 133a85f5c1..faadb1b870 100644
--- a/libavcodec/psymodel.c
+++ b/libavcodec/psymodel.c
@@ -25,16 +25,31 @@
extern const FFPsyModel ff_aac_psy_model;
-av_cold int ff_psy_init(FFPsyContext *ctx, AVCodecContext *avctx,
- int num_lens,
- const uint8_t **bands, const int* num_bands)
+av_cold int ff_psy_init(FFPsyContext *ctx, AVCodecContext *avctx, int num_lens,
+ const uint8_t **bands, const int* num_bands,
+ int num_groups, const uint8_t *group_map)
{
+ int i, j, k = 0;
+
ctx->avctx = avctx;
- ctx->psy_bands = av_mallocz(sizeof(FFPsyBand) * PSY_MAX_BANDS * avctx->channels);
+ ctx->ch = av_mallocz(sizeof(ctx->ch[0]) * avctx->channels * 2);
+ ctx->group = av_mallocz(sizeof(ctx->group[0]) * num_groups);
ctx->bands = av_malloc (sizeof(ctx->bands[0]) * num_lens);
ctx->num_bands = av_malloc (sizeof(ctx->num_bands[0]) * num_lens);
memcpy(ctx->bands, bands, sizeof(ctx->bands[0]) * num_lens);
memcpy(ctx->num_bands, num_bands, sizeof(ctx->num_bands[0]) * num_lens);
+
+ /* assign channels to groups (with virtual channels for coupling) */
+ for (i = 0; i < num_groups; i++) {
+ /* NOTE: Add 1 to handle the AAC chan_config without modification.
+ * This has the side effect of allowing an array of 0s to map
+ * to one channel per group.
+ */
+ ctx->group[i].num_ch = group_map[i] + 1;
+ for (j = 0; j < ctx->group[i].num_ch * 2; j++)
+ ctx->group[i].ch[j] = &ctx->ch[k++];
+ }
+
switch (ctx->avctx->codec_id) {
case CODEC_ID_AAC:
ctx->model = &ff_aac_psy_model;
@@ -45,13 +60,24 @@ av_cold int ff_psy_init(FFPsyContext *ctx, AVCodecContext *avctx,
return 0;
}
+FFPsyChannelGroup *ff_psy_find_group(FFPsyContext *ctx, int channel)
+{
+ int i = 0, ch = 0;
+
+ while (ch <= channel)
+ ch += ctx->group[i++].num_ch;
+
+ return &ctx->group[i-1];
+}
+
av_cold void ff_psy_end(FFPsyContext *ctx)
{
if (ctx->model->end)
ctx->model->end(ctx);
av_freep(&ctx->bands);
av_freep(&ctx->num_bands);
- av_freep(&ctx->psy_bands);
+ av_freep(&ctx->group);
+ av_freep(&ctx->ch);
}
typedef struct FFPsyPreprocessContext{
diff --git a/libavcodec/psymodel.h b/libavcodec/psymodel.h
index c65614a151..a7b7948cd2 100644
--- a/libavcodec/psymodel.h
+++ b/libavcodec/psymodel.h
@@ -41,6 +41,23 @@ typedef struct FFPsyBand {
} FFPsyBand;
/**
+ * single channel psychoacoustic information
+ */
+typedef struct FFPsyChannel {
+ FFPsyBand psy_bands[PSY_MAX_BANDS]; ///< channel bands information
+ float entropy; ///< total PE for this channel
+} FFPsyChannel;
+
+/**
+ * psychoacoustic information for an arbitrary group of channels
+ */
+typedef struct FFPsyChannelGroup {
+ FFPsyChannel *ch[PSY_MAX_CHANS]; ///< pointers to the individual channels in the group
+ uint8_t num_ch; ///< number of channels in this group
+ uint8_t coupling[PSY_MAX_BANDS]; ///< allow coupling for this band in the group
+} FFPsyChannelGroup;
+
+/**
* windowing related information
*/
typedef struct FFPsyWindowInfo {
@@ -58,14 +75,14 @@ typedef struct FFPsyContext {
AVCodecContext *avctx; ///< encoder context
const struct FFPsyModel *model; ///< encoder-specific model functions
- FFPsyBand *psy_bands; ///< frame bands information
+ FFPsyChannel *ch; ///< single channel information
+ FFPsyChannelGroup *group; ///< channel group information
+ int num_groups; ///< number of channel groups
uint8_t **bands; ///< scalefactor band sizes for possible frame sizes
int *num_bands; ///< number of scalefactor bands for possible frame sizes
int num_lens; ///< number of scalefactor band sets
- float pe[PSY_MAX_CHANS]; ///< total PE for each channel in the frame
-
struct {
int size; ///< size of the bitresevoir in bits
int bits; ///< number of bits used in the bitresevoir
@@ -95,14 +112,14 @@ typedef struct FFPsyModel {
FFPsyWindowInfo (*window)(FFPsyContext *ctx, const int16_t *audio, const int16_t *la, int channel, int prev_type);
/**
- * Perform psychoacoustic analysis and set band info (threshold, energy).
+ * Perform psychoacoustic analysis and set band info (threshold, energy) for a group of channels.
*
- * @param ctx model context
- * @param channel audio channel number
- * @param coeffs pointer to the transformed coefficients
- * @param wi window information
+ * @param ctx model context
+ * @param channel channel number of the first channel in the group to perform analysis on
+ * @param coeffs array of pointers to the transformed coefficients
+ * @param wi window information for the channels in the group
*/
- void (*analyze)(FFPsyContext *ctx, int channel, const float *coeffs, const FFPsyWindowInfo *wi);
+ void (*analyze)(FFPsyContext *ctx, int channel, const float **coeffs, const FFPsyWindowInfo *wi);
void (*end) (FFPsyContext *apc);
} FFPsyModel;
@@ -115,12 +132,24 @@ typedef struct FFPsyModel {
* @param num_lens number of possible frame lengths
* @param bands scalefactor band lengths for all frame lengths
* @param num_bands number of scalefactor bands for all frame lengths
+ * @param num_groups number of channel groups
+ * @param group_map array with # of channels in group - 1, for each group
*
* @return zero if successful, a negative value if not
*/
-av_cold int ff_psy_init(FFPsyContext *ctx, AVCodecContext *avctx,
- int num_lens,
- const uint8_t **bands, const int* num_bands);
+av_cold int ff_psy_init(FFPsyContext *ctx, AVCodecContext *avctx, int num_lens,
+ const uint8_t **bands, const int* num_bands,
+ int num_groups, const uint8_t *group_map);
+
+/**
+ * Determine what group a channel belongs to.
+ *
+ * @param ctx psymodel context
+ * @param channel channel to locate the group for
+ *
+ * @return pointer to the FFPsyChannelGroup this channel belongs to
+ */
+FFPsyChannelGroup *ff_psy_find_group(FFPsyContext *ctx, int channel);
/**
* Cleanup model context at the end.
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index fd011cfa19..bc08e350cf 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -141,6 +141,10 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, int l
case PIX_FMT_YUV420P10BE:
case PIX_FMT_YUV422P10LE:
case PIX_FMT_YUV422P10BE:
+ case PIX_FMT_YUV444P9LE:
+ case PIX_FMT_YUV444P9BE:
+ case PIX_FMT_YUV444P10LE:
+ case PIX_FMT_YUV444P10BE:
w_align= 16; //FIXME check for non mpeg style codecs and use less alignment
h_align= 16;
if(s->codec_id == CODEC_ID_MPEG2VIDEO || s->codec_id == CODEC_ID_MJPEG || s->codec_id == CODEC_ID_AMV || s->codec_id == CODEC_ID_THP || s->codec_id == CODEC_ID_H264)