Commit 17106a7c authored by Michael Niedermayer's avatar Michael Niedermayer

Merge remote-tracking branch 'qatar/master'

* qatar/master:
  audio_frame_queue: Clean up ff_af_queue_log_state debug function
  dwt: Remove unused code.
  cavs: convert cavsdata.h to a .c file
  cavs: Move inline functions only used in one file out of the header
  cavs: Move data tables used in only one place to that file
  fate: Add a single symbol Ut Video decoder test
  vf_hqdn3d: x86 asm
  vf_hqdn3d: support 16bit colordepth
  avconv: prefer user-forced input framerate when choosing output framerate

Conflicts:
	ffmpeg.c
	libavcodec/audio_frame_queue.c
	libavcodec/dwt.c
Merged-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parents 3a621c9d d7f9786c
......@@ -2137,6 +2137,8 @@ static int transcode_init(void)
if (codec->codec_type == AVMEDIA_TYPE_VIDEO) {
if (ost->filter && !ost->frame_rate.num)
ost->frame_rate = av_buffersink_get_frame_rate(ost->filter->filter);
if (ist && !ost->frame_rate.num)
ost->frame_rate = ist->framerate;
if (ist && !ost->frame_rate.num)
ost->frame_rate = ist->st->r_frame_rate.num ? ist->st->r_frame_rate : (AVRational){25, 1};
// ost->frame_rate = ist->st->avg_frame_rate.num ? ist->st->avg_frame_rate : (AVRational){25, 1};
......
......@@ -133,7 +133,7 @@ OBJS-$(CONFIG_BMV_VIDEO_DECODER) += bmv.o
OBJS-$(CONFIG_BMV_AUDIO_DECODER) += bmv.o
OBJS-$(CONFIG_C93_DECODER) += c93.o
OBJS-$(CONFIG_CAVS_DECODER) += cavs.o cavsdec.o cavsdsp.o \
mpeg12data.o
cavsdata.o mpeg12data.o
OBJS-$(CONFIG_CDGRAPHICS_DECODER) += cdgraphics.o
OBJS-$(CONFIG_CDXL_DECODER) += cdxl.o
OBJS-$(CONFIG_CINEPAK_DECODER) += cinepak.o
......
......@@ -80,11 +80,4 @@ int ff_af_queue_add(AudioFrameQueue *afq, const AVFrame *f);
void ff_af_queue_remove(AudioFrameQueue *afq, int nb_samples, int64_t *pts,
int *duration);
/**
* Log the current state of the queue.
*
* @param afq queue context
*/
void ff_af_queue_log_state(AudioFrameQueue *afq);
#endif /* AVCODEC_AUDIO_FRAME_QUEUE_H */
......@@ -30,7 +30,36 @@
#include "golomb.h"
#include "mathops.h"
#include "cavs.h"
#include "cavsdata.h"
static const uint8_t alpha_tab[64] = {
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3,
4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 20,
22, 24, 26, 28, 30, 33, 33, 35, 35, 36, 37, 37, 39, 39, 42, 44,
46, 48, 50, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64
};
static const uint8_t beta_tab[64] = {
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6,
6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 27
};
static const uint8_t tc_tab[64] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9
};
/** mark block as unavailable, i.e. out of picture
or not yet decoded */
static const cavs_vector un_mv = { 0, 0, 1, NOT_AVAIL };
static const int8_t left_modifier_l[8] = { 0, -1, 6, -1, -1, 7, 6, 7 };
static const int8_t top_modifier_l[8] = { -1, 1, 5, -1, -1, 5, 7, 7 };
static const int8_t left_modifier_c[7] = { 5, -1, 2, -1, 6, 5, 6 };
static const int8_t top_modifier_c[7] = { 4, 1, -1, -1, 4, 6, 6 };
/*****************************************************************************
*
......@@ -298,6 +327,15 @@ static void intra_pred_lp_top(uint8_t *d,uint8_t *top,uint8_t *left,int stride)
#undef LOWPASS
static inline void modify_pred(const int8_t *mod_table, int *mode)
{
*mode = mod_table[*mode];
if(*mode < 0) {
av_log(NULL, AV_LOG_ERROR, "Illegal intra prediction mode\n");
*mode = 0;
}
}
void ff_cavs_modify_mb_i(AVSContext *h, int *pred_mode_uv) {
/* save pred modes before they get modified */
h->pred_mode_Y[3] = h->pred_mode_Y[5];
......@@ -307,14 +345,14 @@ void ff_cavs_modify_mb_i(AVSContext *h, int *pred_mode_uv) {
/* modify pred modes according to availability of neighbour samples */
if(!(h->flags & A_AVAIL)) {
modify_pred(ff_left_modifier_l, &h->pred_mode_Y[4] );
modify_pred(ff_left_modifier_l, &h->pred_mode_Y[7] );
modify_pred(ff_left_modifier_c, pred_mode_uv );
modify_pred(left_modifier_l, &h->pred_mode_Y[4]);
modify_pred(left_modifier_l, &h->pred_mode_Y[7]);
modify_pred(left_modifier_c, pred_mode_uv);
}
if(!(h->flags & B_AVAIL)) {
modify_pred(ff_top_modifier_l, &h->pred_mode_Y[4] );
modify_pred(ff_top_modifier_l, &h->pred_mode_Y[5] );
modify_pred(ff_top_modifier_c, pred_mode_uv );
modify_pred(top_modifier_l, &h->pred_mode_Y[4]);
modify_pred(top_modifier_l, &h->pred_mode_Y[5]);
modify_pred(top_modifier_c, pred_mode_uv);
}
}
......@@ -496,7 +534,7 @@ void ff_cavs_mv(AVSContext *h, enum cavs_mv_loc nP, enum cavs_mv_loc nC,
((mvA->ref == NOT_AVAIL) || (mvB->ref == NOT_AVAIL) ||
((mvA->x | mvA->y | mvA->ref) == 0) ||
((mvB->x | mvB->y | mvB->ref) == 0) )) {
mvP2 = &ff_cavs_un_mv;
mvP2 = &un_mv;
/* if there is only one suitable candidate, take it */
} else if((mvA->ref >= 0) && (mvB->ref < 0) && (mvC->ref < 0)) {
mvP2= mvA;
......@@ -545,10 +583,10 @@ void ff_cavs_init_mb(AVSContext *h) {
h->pred_mode_Y[2] = h->top_pred_Y[h->mbx*2+1];
/* clear top predictors if MB B is not available */
if(!(h->flags & B_AVAIL)) {
h->mv[MV_FWD_B2] = ff_cavs_un_mv;
h->mv[MV_FWD_B3] = ff_cavs_un_mv;
h->mv[MV_BWD_B2] = ff_cavs_un_mv;
h->mv[MV_BWD_B3] = ff_cavs_un_mv;
h->mv[MV_FWD_B2] = un_mv;
h->mv[MV_FWD_B3] = un_mv;
h->mv[MV_BWD_B2] = un_mv;
h->mv[MV_BWD_B3] = un_mv;
h->pred_mode_Y[1] = h->pred_mode_Y[2] = NOT_AVAIL;
h->flags &= ~(C_AVAIL|D_AVAIL);
} else if(h->mbx) {
......@@ -558,13 +596,13 @@ void ff_cavs_init_mb(AVSContext *h) {
h->flags &= ~C_AVAIL;
/* clear top-right predictors if MB C is not available */
if(!(h->flags & C_AVAIL)) {
h->mv[MV_FWD_C2] = ff_cavs_un_mv;
h->mv[MV_BWD_C2] = ff_cavs_un_mv;
h->mv[MV_FWD_C2] = un_mv;
h->mv[MV_BWD_C2] = un_mv;
}
/* clear top-left predictors if MB D is not available */
if(!(h->flags & D_AVAIL)) {
h->mv[MV_FWD_D3] = ff_cavs_un_mv;
h->mv[MV_BWD_D3] = ff_cavs_un_mv;
h->mv[MV_FWD_D3] = un_mv;
h->mv[MV_BWD_D3] = un_mv;
}
}
......@@ -597,7 +635,7 @@ int ff_cavs_next_mb(AVSContext *h) {
h->pred_mode_Y[3] = h->pred_mode_Y[6] = NOT_AVAIL;
/* clear left mv predictors */
for(i=0;i<=20;i+=4)
h->mv[i] = ff_cavs_un_mv;
h->mv[i] = un_mv;
h->mbx = 0;
h->mby++;
/* re-calculate sample pointers */
......@@ -622,7 +660,7 @@ void ff_cavs_init_pic(AVSContext *h) {
/* clear some predictors */
for(i=0;i<=20;i+=4)
h->mv[i] = ff_cavs_un_mv;
h->mv[i] = un_mv;
h->mv[MV_BWD_X0] = ff_cavs_dir_mv;
set_mvs(&h->mv[MV_BWD_X0], BLK_16X16);
h->mv[MV_FWD_X0] = ff_cavs_dir_mv;
......@@ -693,8 +731,8 @@ av_cold int ff_cavs_init(AVCodecContext *avctx) {
h->intra_pred_c[ INTRA_C_LP_LEFT] = intra_pred_lp_left;
h->intra_pred_c[ INTRA_C_LP_TOP] = intra_pred_lp_top;
h->intra_pred_c[ INTRA_C_DC_128] = intra_pred_dc_128;
h->mv[ 7] = ff_cavs_un_mv;
h->mv[19] = ff_cavs_un_mv;
h->mv[ 7] = un_mv;
h->mv[19] = un_mv;
return 0;
}
......
......@@ -225,41 +225,10 @@ typedef struct {
DCTELEM *block;
} AVSContext;
extern const uint8_t ff_cavs_dequant_shift[64];
extern const uint16_t ff_cavs_dequant_mul[64];
extern const struct dec_2dvlc ff_cavs_intra_dec[7];
extern const struct dec_2dvlc ff_cavs_inter_dec[7];
extern const struct dec_2dvlc ff_cavs_chroma_dec[5];
extern const uint8_t ff_cavs_chroma_qp[64];
extern const uint8_t ff_cavs_scan3x3[4];
extern const uint8_t ff_cavs_partition_flags[30];
extern const int8_t ff_left_modifier_l[8];
extern const int8_t ff_top_modifier_l[8];
extern const int8_t ff_left_modifier_c[7];
extern const int8_t ff_top_modifier_c[7];
extern const cavs_vector ff_cavs_intra_mv;
extern const cavs_vector ff_cavs_un_mv;
extern const cavs_vector ff_cavs_dir_mv;
static inline void modify_pred(const int8_t *mod_table, int *mode)
{
*mode = mod_table[*mode];
if(*mode < 0) {
av_log(NULL, AV_LOG_ERROR, "Illegal intra prediction mode\n");
*mode = 0;
}
}
static inline void set_intra_mode_default(AVSContext *h) {
if(h->stream_revision > 0) {
h->pred_mode_Y[3] = h->pred_mode_Y[6] = NOT_AVAIL;
h->top_pred_Y[h->mbx*2+0] = h->top_pred_Y[h->mbx*2+1] = NOT_AVAIL;
} else {
h->pred_mode_Y[3] = h->pred_mode_Y[6] = INTRA_L_LP;
h->top_pred_Y[h->mbx*2+0] = h->top_pred_Y[h->mbx*2+1] = INTRA_L_LP;
}
}
static inline void set_mvs(cavs_vector *mv, enum cavs_block size) {
switch(size) {
case BLK_16X16:
......@@ -274,35 +243,6 @@ static inline void set_mvs(cavs_vector *mv, enum cavs_block size) {
}
}
static inline void set_mv_intra(AVSContext *h) {
h->mv[MV_FWD_X0] = ff_cavs_intra_mv;
set_mvs(&h->mv[MV_FWD_X0], BLK_16X16);
h->mv[MV_BWD_X0] = ff_cavs_intra_mv;
set_mvs(&h->mv[MV_BWD_X0], BLK_16X16);
if(h->pic_type != AV_PICTURE_TYPE_B)
h->col_type_base[h->mbidx] = I_8X8;
}
static inline int dequant(AVSContext *h, DCTELEM *level_buf, uint8_t *run_buf,
DCTELEM *dst, int mul, int shift, int coeff_num) {
int round = 1 << (shift - 1);
int pos = -1;
const uint8_t *scantab = h->scantable.permutated;
/* inverse scan and dequantization */
while(--coeff_num >= 0){
pos += run_buf[coeff_num];
if(pos > 63) {
av_log(h->s.avctx, AV_LOG_ERROR,
"position out of block bounds at pic %d MB(%d,%d)\n",
h->picture.poc, h->mbx, h->mby);
return -1;
}
dst[scantab[pos]] = (level_buf[coeff_num]*mul + round) >> shift;
}
return 0;
}
void ff_cavs_filter(AVSContext *h, enum cavs_mb mb_type);
void ff_cavs_load_intra_pred_luma(AVSContext *h, uint8_t *top, uint8_t **left,
int block);
......
/*
* Chinese AVS video (AVS1-P2, JiZhun profile) decoder.
* Copyright (c) 2006 Stefan Gehrer <stefan.gehrer@gmx.de>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "cavs.h"
const uint8_t ff_cavs_partition_flags[30] = {
0, //I_8X8
0, //P_SKIP
0, //P_16X16
SPLITH, //P_16X8
SPLITV, //P_8X16
SPLITH|SPLITV, //P_8X8
SPLITH|SPLITV, //B_SKIP
SPLITH|SPLITV, //B_DIRECT
0, //B_FWD_16X16
0, //B_BWD_16X16
0, //B_SYM_16X16
FWD0|FWD1 |SPLITH,
FWD0|FWD1 |SPLITV,
BWD0|BWD1 |SPLITH,
BWD0|BWD1 |SPLITV,
FWD0|BWD1 |SPLITH,
FWD0|BWD1 |SPLITV,
BWD0|FWD1 |SPLITH,
BWD0|FWD1 |SPLITV,
FWD0|FWD1 |SYM1|SPLITH,
FWD0|FWD1 |SYM1 |SPLITV,
BWD0|FWD1 |SYM1|SPLITH,
BWD0|FWD1 |SYM1 |SPLITV,
FWD0|FWD1|SYM0 |SPLITH,
FWD0|FWD1|SYM0 |SPLITV,
FWD0|BWD1|SYM0 |SPLITH,
FWD0|BWD1|SYM0 |SPLITV,
FWD0|FWD1|SYM0|SYM1|SPLITH,
FWD0|FWD1|SYM0|SYM1 |SPLITV,
SPLITH|SPLITV, //B_8X8 = 29
};
/** mark block as "no prediction from this direction"
e.g. forward motion vector in BWD partition */
const cavs_vector ff_cavs_dir_mv = {0,0,1,REF_DIR};
/** mark block as using intra prediction */
const cavs_vector ff_cavs_intra_mv = {0,0,1,REF_INTRA};
This diff is collapsed.
This diff is collapsed.
......@@ -148,38 +148,6 @@ static av_always_inline void lift(DWTELEM *dst, DWTELEM *src, DWTELEM *ref,
inverse);
}
static av_always_inline void inv_lift(IDWTELEM *dst, IDWTELEM *src, IDWTELEM *ref,
int dst_step, int src_step, int ref_step,
int width, int mul, int add, int shift,
int highpass, int inverse)
{
const int mirror_left = !highpass;
const int mirror_right = (width & 1) ^ highpass;
const int w = (width >> 1) - 1 + (highpass & width);
int i;
#define LIFT(src, ref, inv) ((src) + ((inv) ? -(ref) : +(ref)))
if (mirror_left) {
dst[0] = LIFT(src[0], ((mul * 2 * ref[0] + add) >> shift), inverse);
dst += dst_step;
src += src_step;
}
for (i = 0; i < w; i++)
dst[i * dst_step] = LIFT(src[i * src_step],
((mul * (ref[i * ref_step] +
ref[(i + 1) * ref_step]) +
add) >> shift),
inverse);
if (mirror_right) {
dst[w * dst_step] = LIFT(src[w * src_step],
((mul * 2 * ref[w * ref_step] + add) >> shift),
inverse);
}
}
#ifndef liftS
static av_always_inline void liftS(DWTELEM *dst, DWTELEM *src, DWTELEM *ref,
int dst_step, int src_step, int ref_step,
int width, int mul, int add, int shift,
......@@ -213,40 +181,6 @@ static av_always_inline void liftS(DWTELEM *dst, DWTELEM *src, DWTELEM *ref,
inverse);
}
static av_always_inline void inv_liftS(IDWTELEM *dst, IDWTELEM *src,
IDWTELEM *ref, int dst_step,
int src_step, int ref_step,
int width, int mul, int add, int shift,
int highpass, int inverse)
{
const int mirror_left = !highpass;
const int mirror_right = (width & 1) ^ highpass;
const int w = (width >> 1) - 1 + (highpass & width);
int i;
av_assert1(shift == 4);
#define LIFTS(src, ref, inv) \
((inv) ? (src) + (((ref) + 4 * (src)) >> shift) \
: -((-16 * (src) + (ref) + add / \
4 + 1 + (5 << 25)) / (5 * 4) - (1 << 23)))
if (mirror_left) {
dst[0] = LIFTS(src[0], mul * 2 * ref[0] + add, inverse);
dst += dst_step;
src += src_step;
}
for (i = 0; i < w; i++)
dst[i * dst_step] = LIFTS(src[i * src_step],
mul * (ref[i * ref_step] +
ref[(i + 1) * ref_step]) + add,
inverse);
if (mirror_right)
dst[w * dst_step] = LIFTS(src[w * src_step],
mul * 2 * ref[w * ref_step] + add, inverse);
}
#endif /* ! liftS */
static void horizontal_decompose53i(DWTELEM *b, DWTELEM *temp, int width)
{
const int width2 = width >> 1;
......@@ -259,41 +193,8 @@ static void horizontal_decompose53i(DWTELEM *b, DWTELEM *temp, int width)
}
if (width & 1)
temp[x] = b[2 * x];
#if 0
{
int A1, A2, A3, A4;
A2 = temp[1];
A4 = temp[0];
A1 = temp[0 + width2];
A1 -= (A2 + A4) >> 1;
A4 += (A1 + 1) >> 1;
b[0 + width2] = A1;
b[0] = A4;
for (x = 1; x + 1 < width2; x += 2) {
A3 = temp[x + width2];
A4 = temp[x + 1];
A3 -= (A2 + A4) >> 1;
A2 += (A1 + A3 + 2) >> 2;
b[x + width2] = A3;
b[x] = A2;
A1 = temp[x + 1 + width2];
A2 = temp[x + 2];
A1 -= (A2 + A4) >> 1;
A4 += (A1 + A3 + 2) >> 2;
b[x + 1 + width2] = A1;
b[x + 1] = A4;
}
A3 = temp[width - 1];
A3 -= A2;
A2 += (A1 + A3 + 2) >> 2;
b[width - 1] = A3;
b[width2 - 1] = A2;
}
#else
lift(b + w2, temp + w2, temp, 1, 1, 1, width, -1, 0, 1, 1, 0);
lift(b, temp, b + w2, 1, 1, 1, width, 1, 2, 2, 0, 0);
#endif /* 0 */
}
static void vertical_decompose53iH0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
......@@ -374,12 +275,8 @@ static void vertical_decompose97iL0(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
int i;
for (i = 0; i < width; i++)
#ifdef liftS
b1[i] -= (W_BM * (b0[i] + b2[i]) + W_BO) >> W_BS;
#else
b1[i] = (16 * 4 * b1[i] - 4 * (b0[i] + b2[i]) + W_BO * 5 + (5 << 27)) /
(5 * 16) - (1 << 23);
#endif
}
static void vertical_decompose97iL1(DWTELEM *b0, DWTELEM *b1, DWTELEM *b2,
......@@ -583,15 +480,8 @@ static void av_unused spatial_compose53i(IDWTELEM *buffer, IDWTELEM *temp,
void ff_snow_horizontal_compose97i(IDWTELEM *b, IDWTELEM *temp, int width)
{
const int w2 = (width + 1) >> 1;
#if 0 //maybe more understadable but slower
inv_lift(temp, b, b + w2, 2, 1, 1, width, W_DM, W_DO, W_DS, 0, 1);
inv_lift(temp + 1, b + w2, temp, 2, 1, 2, width, W_CM, W_CO, W_CS, 1, 1);
inv_liftS(b, temp, temp + 1, 2, 2, 2, width, W_BM, W_BO, W_BS, 0, 1);
inv_lift(b + 1, temp + 1, b, 2, 2, 2, width, W_AM, W_AO, W_AS, 1, 0);
#else
int x;
temp[0] = b[0] - ((3 * b[w2] + 2) >> 2);
for (x = 1; x < (width >> 1); x++) {
temp[2 * x] = b[x] - ((3 * (b[x + w2 - 1] + b[x + w2]) + 4) >> 3);
......@@ -613,7 +503,6 @@ void ff_snow_horizontal_compose97i(IDWTELEM *b, IDWTELEM *temp, int width)
b[x - 1] = temp[x - 1] + ((3 * (b[x - 2] + b[x])) >> 1);
} else
b[x - 1] = temp[x - 1] + 3 * b[x - 2];
#endif
}
static void vertical_compose97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
......@@ -640,11 +529,7 @@ static void vertical_compose97iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
int i;
for (i = 0; i < width; i++)
#ifdef liftS
b1[i] += (W_BM * (b0[i] + b2[i]) + W_BO) >> W_BS;
#else
b1[i] += (W_BM * (b0[i] + b2[i]) + 4 * b1[i] + W_BO) >> W_BS;
#endif
}
static void vertical_compose97iL1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
......@@ -665,11 +550,7 @@ void ff_snow_vertical_compose97i(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
for (i = 0; i < width; i++) {
b4[i] -= (W_DM * (b3[i] + b5[i]) + W_DO) >> W_DS;
b3[i] -= (W_CM * (b2[i] + b4[i]) + W_CO) >> W_CS;
#ifdef liftS
b2[i] += (W_BM * (b1[i] + b3[i]) + W_BO) >> W_BS;
#else
b2[i] += (W_BM * (b1[i] + b3[i]) + 4 * b2[i] + W_BO) >> W_BS;
#endif
b1[i] += (W_AM * (b0[i] + b2[i]) + W_AO) >> W_AS;
}
}
......
......@@ -154,7 +154,6 @@ void ff_spatial_idwt_slice2(DWTContext *d, int y);
#define DWT_53 1
#define liftS lift
#if 1
#define W_AM 3
#define W_AO 0
#define W_AS 1
......@@ -171,57 +170,6 @@ void ff_spatial_idwt_slice2(DWTContext *d, int y);
#define W_DM 3
#define W_DO 4
#define W_DS 3
#elif 0
#define W_AM 55
#define W_AO 16
#define W_AS 5
#define W_BM 3
#define W_BO 32
#define W_BS 6
#define W_CM 127
#define W_CO 64
#define W_CS 7
#define W_DM 7
#define W_DO 8
#define W_DS 4
#elif 0
#define W_AM 97
#define W_AO 32
#define W_AS 6
#define W_BM 63
#define W_BO 512
#define W_BS 10
#define W_CM 13
#define W_CO 8
#define W_CS 4
#define W_DM 15
#define W_DO 16
#define W_DS 5
#else
#define W_AM 203
#define W_AO 64
#define W_AS 7
#define W_BM 217
#define W_BO 2048
#define W_BS 12
#define W_CM 113
#define W_CO 64
#define W_CS 7
#define W_DM 227
#define W_DO 128
#define W_DS 9
#endif
#define slice_buffer_get_line(slice_buf, line_num) \
((slice_buf)->line[line_num] ? (slice_buf)->line[line_num] \
......
......@@ -35,21 +35,30 @@
#include "video.h"
typedef struct {
int16_t coefs[4][512*16];
int16_t *coefs[4];
uint16_t *line;
uint16_t *frame_prev[3];
double strength[4];
int hsub, vsub;
int depth;
void (*denoise_row[17])(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal);
} HQDN3DContext;
void ff_hqdn3d_row_8_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal);
void ff_hqdn3d_row_9_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal);
void ff_hqdn3d_row_10_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal);
void ff_hqdn3d_row_16_x86(uint8_t *src, uint8_t *dst, uint16_t *line_ant, uint16_t *frame_ant, ptrdiff_t w, int16_t *spatial, int16_t *temporal);
#define LUT_BITS (depth==16 ? 8 : 4)
#define RIGHTSHIFT(a,b) (((a)+(((1<<(b))-1)>>1))>>(b))
#define LOAD(x) ((depth==8 ? src[x] : AV_RN16A(src+(x)*2)) << (16-depth))
#define STORE(x,val) (depth==8 ? dst[x] = RIGHTSHIFT(val, 16-depth)\
: AV_WN16A(dst+(x)*2, RIGHTSHIFT(val, 16-depth)))
static inline uint32_t lowpass(int prev, int cur, int16_t *coef)
av_always_inline
static inline uint32_t lowpass(int prev, int cur, int16_t *coef, int depth)
{
int d = (prev-cur)>>4;
int d = (prev - cur) >> (8 - LUT_BITS);
return cur + coef[d];
}
......@@ -62,11 +71,11 @@ static void denoise_temporal(uint8_t *src, uint8_t *dst,
long x, y;
uint32_t tmp;
temporal += 0x1000;
temporal += 256 << LUT_BITS;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
frame_ant[x] = tmp = lowpass(frame_ant[x], LOAD(x), temporal);
frame_ant[x] = tmp = lowpass(frame_ant[x], LOAD(x), temporal, depth);
STORE(x, tmp);
}
src += sstride;
......@@ -76,7 +85,8 @@ static void denoise_temporal(uint8_t *src, uint8_t *dst,
}
av_always_inline
static void denoise_spatial(uint8_t *src, uint8_t *dst,
static void denoise_spatial(HQDN3DContext *hqdn3d,
uint8_t *src, uint8_t *dst,
uint16_t *line_ant, uint16_t *frame_ant,
int w, int h, int sstride, int dstride,
int16_t *spatial, int16_t *temporal, int depth)
......@@ -85,15 +95,15 @@ static void denoise_spatial(uint8_t *src, uint8_t *dst,
uint32_t pixel_ant;
uint32_t tmp;
spatial += 0x1000;
temporal += 0x1000;
spatial += 256 << LUT_BITS;
temporal += 256 << LUT_BITS;
/* First line has no top neighbor. Only left one for each tmp and
* last frame */
pixel_ant = LOAD(0);
for (x = 0; x < w; x++) {
line_ant[x] = tmp = pixel_ant = lowpass(pixel_ant, LOAD(x), spatial);
frame_ant[x] = tmp = lowpass(frame_ant[x], tmp, temporal);
line_ant[x] = tmp = pixel_ant = lowpass(pixel_ant, LOAD(x), spatial, depth);
frame_ant[x] = tmp = lowpass(frame_ant[x], tmp, temporal, depth);
STORE(x, tmp);
}
......@@ -101,25 +111,32 @@ static void denoise_spatial(uint8_t *src, uint8_t *dst,
src += sstride;
dst += dstride;
frame_ant += w;
if (hqdn3d->denoise_row[depth]) {
hqdn3d->denoise_row[depth](src, dst, line_ant, frame_ant, w, spatial, temporal);
continue;
}
pixel_ant = LOAD(0);
for (x = 0; x < w-1; x++) {
line_ant[x] = tmp = lowpass(line_ant[x], pixel_ant, spatial);
pixel_ant = lowpass(pixel_ant, LOAD(x+1), spatial);
frame_ant[x] = tmp = lowpass(frame_ant[x], tmp, temporal);
line_ant[x] = tmp = lowpass(line_ant[x], pixel_ant, spatial, depth);
pixel_ant = lowpass(pixel_ant, LOAD(x+1), spatial, depth);
frame_ant[x] = tmp = lowpass(frame_ant[x], tmp, temporal, depth);
STORE(x, tmp);
}
line_ant[x] = tmp = lowpass(line_ant[x], pixel_ant, spatial);
frame_ant[x] = tmp = lowpass(frame_ant[x], tmp, temporal);
line_ant[x] = tmp = lowpass(line_ant[x], pixel_ant, spatial, depth);
frame_ant[x] = tmp = lowpass(frame_ant[x], tmp, temporal, depth);
STORE(x, tmp);
}
}
av_always_inline
static void denoise_depth(uint8_t *src, uint8_t *dst,
static void denoise_depth(HQDN3DContext *hqdn3d,
uint8_t *src, uint8_t *dst,
uint16_t *line_ant, uint16_t **frame_ant_ptr,
int w, int h, int sstride, int dstride,
int16_t *spatial, int16_t *temporal, int depth)
{
// FIXME: For 16bit depth, frame_ant could be a pointer to the previous
// filtered frame rather than a separate buffer.
long x, y;
uint16_t *frame_ant = *frame_ant_ptr;
if (!frame_ant) {
......@@ -133,7 +150,7 @@ static void denoise_depth(uint8_t *src, uint8_t *dst,
}
if (spatial[0])
denoise_spatial(src, dst, line_ant, frame_ant,
denoise_spatial(hqdn3d, src, dst, line_ant, frame_ant,
w, h, sstride, dstride, spatial, temporal, depth);
else
denoise_temporal(src, dst, frame_ant,
......@@ -145,24 +162,28 @@ static void denoise_depth(uint8_t *src, uint8_t *dst,
case 8: denoise_depth(__VA_ARGS__, 8); break;\
case 9: denoise_depth(__VA_ARGS__, 9); break;\
case 10: denoise_depth(__VA_ARGS__, 10); break;\
case 16: denoise_depth(__VA_ARGS__, 16); break;\
}
static void precalc_coefs(int16_t *ct, double dist25)
static int16_t *precalc_coefs(double dist25, int depth)
{
int i;
double gamma, simil, C;
int16_t *ct = av_malloc((512<<LUT_BITS)*sizeof(int16_t));
if (!ct)
return NULL;
gamma = log(0.25) / log(1.0 - FFMIN(dist25,252.0)/255.0 - 0.00001);
for (i = -255*16; i <= 255*16; i++) {
// lowpass() truncates (not rounds) the diff, so +15/32 for the midpoint of the bin.
double f = (i + 15.0/32.0) / 16.0;
for (i = -255<<LUT_BITS; i <= 255<<LUT_BITS; i++) {
double f = ((i<<(9-LUT_BITS)) + (1<<(8-LUT_BITS)) - 1) / 512.0; // midpoint of the bin
simil = 1.0 - FFABS(f) / 255.0;
C = pow(simil, gamma) * 256.0 * f;
ct[16*256+i] = lrint(C);
ct[(256<<LUT_BITS)+i] = lrint(C);
}
ct[0] = !!dist25;
return ct;
}
#define PARAM1_DEFAULT 4.0
......@@ -210,6 +231,11 @@ static int init(AVFilterContext *ctx, const char *args)
}
}
hqdn3d->strength[0] = lum_spac;
hqdn3d->strength[1] = lum_tmp;
hqdn3d->strength[2] = chrom_spac;
hqdn3d->strength[3] = chrom_tmp;
av_log(ctx, AV_LOG_VERBOSE, "ls:%lf cs:%lf lt:%lf ct:%lf\n",
lum_spac, chrom_spac, lum_tmp, chrom_tmp);
if (lum_spac < 0 || chrom_spac < 0 || isnan(chrom_tmp)) {
......@@ -219,11 +245,6 @@ static int init(AVFilterContext *ctx, const char *args)
return AVERROR(EINVAL);
}
precalc_coefs(hqdn3d->coefs[0], lum_spac);
precalc_coefs(hqdn3d->coefs[1], lum_tmp);
precalc_coefs(hqdn3d->coefs[2], chrom_spac);
precalc_coefs(hqdn3d->coefs[3], chrom_tmp);
return 0;
}
......@@ -231,6 +252,10 @@ static void uninit(AVFilterContext *ctx)
{
HQDN3DContext *hqdn3d = ctx->priv;
av_freep(&hqdn3d->coefs[0]);
av_freep(&hqdn3d->coefs[1]);
av_freep(&hqdn3d->coefs[2]);
av_freep(&hqdn3d->coefs[3]);
av_freep(&hqdn3d->line);
av_freep(&hqdn3d->frame_prev[0]);
av_freep(&hqdn3d->frame_prev[1]);
......@@ -256,6 +281,9 @@ static int query_formats(AVFilterContext *ctx)
AV_NE( PIX_FMT_YUV420P10BE, PIX_FMT_YUV420P10LE ),
AV_NE( PIX_FMT_YUV422P10BE, PIX_FMT_YUV422P10LE ),
AV_NE( PIX_FMT_YUV444P10BE, PIX_FMT_YUV444P10LE ),
AV_NE( PIX_FMT_YUV420P16BE, PIX_FMT_YUV420P16LE ),
AV_NE( PIX_FMT_YUV422P16BE, PIX_FMT_YUV422P16LE ),
AV_NE( PIX_FMT_YUV444P16BE, PIX_FMT_YUV444P16LE ),
PIX_FMT_NONE
};
......@@ -276,6 +304,19 @@ static int config_input(AVFilterLink *inlink)
if (!hqdn3d->line)
return AVERROR(ENOMEM);
for (int i=0; i<4; i++) {
hqdn3d->coefs[i] = precalc_coefs(hqdn3d->strength[i], hqdn3d->depth);
if (!hqdn3d->coefs[i])
return AVERROR(ENOMEM);
}
#if HAVE_YASM
hqdn3d->denoise_row[ 8] = ff_hqdn3d_row_8_x86;
hqdn3d->denoise_row[ 9] = ff_hqdn3d_row_9_x86;
hqdn3d->denoise_row[10] = ff_hqdn3d_row_10_x86;
hqdn3d->denoise_row[16] = ff_hqdn3d_row_16_x86;
#endif
return 0;
}
......@@ -293,7 +334,7 @@ static int end_frame(AVFilterLink *inlink)
int ret, c;
for (c = 0; c < 3; c++) {
denoise(inpic->data[c], outpic->data[c],
denoise(hqdn3d, inpic->data[c], outpic->data[c],
hqdn3d->line, &hqdn3d->frame_prev[c],
inpic->video->w >> (!!c * hqdn3d->hsub),
inpic->video->h >> (!!c * hqdn3d->vsub),
......
MMX-OBJS-$(CONFIG_YADIF_FILTER) += x86/yadif.o
MMX-OBJS-$(CONFIG_GRADFUN_FILTER) += x86/gradfun.o
YASM-OBJS-$(CONFIG_HQDN3D_FILTER) += x86/hqdn3d.o
;******************************************************************************
;* Copyright (c) 2012 Loren Merritt
;*
;* This file is part of FFmpeg.
;*
;* FFmpeg is free software; you can redistribute it and/or
;* modify it under the terms of the GNU Lesser General Public
;* License as published by the Free Software Foundation; either
;* version 2.1 of the License, or (at your option) any later version.
;*
;* FFmpeg is distributed in the hope that it will be useful,
;* but WITHOUT ANY WARRANTY; without even the implied warranty of
;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;* Lesser General Public License for more details.
;*
;* You should have received a copy of the GNU Lesser General Public
;* License along with FFmpeg; if not, write to the Free Software
;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
;******************************************************************************
%include "x86inc.asm"
SECTION .text
%macro LOWPASS 3 ; prevsample, cursample, lut
sub %1q, %2q
%if lut_bits != 8
sar %1q, 8-lut_bits
%endif
movsx %1d, word [%3q+%1q*2]
add %1d, %2d
%endmacro
%macro LOAD 3 ; dstreg, x, bitdepth
%if %3 == 8
movzx %1, byte [srcq+%2]
%else
movzx %1, word [srcq+(%2)*2]
%endif
%if %3 != 16
shl %1, 16-%3
%endif
%endmacro
%macro HQDN3D_ROW 1 ; bitdepth
%if ARCH_X86_64
cglobal hqdn3d_row_%1_x86, 7,10,0, src, dst, lineant, frameant, width, spatial, temporal, pixelant, t0, t1
%else
cglobal hqdn3d_row_%1_x86, 7,7,0, src, dst, lineant, frameant, width, spatial, temporal
%endif
%assign bytedepth (%1+7)>>3
%assign lut_bits 4+4*(%1/16)
dec widthq
lea srcq, [srcq+widthq*bytedepth]
lea dstq, [dstq+widthq*bytedepth]
lea frameantq, [frameantq+widthq*2]
lea lineantq, [lineantq+widthq*2]
neg widthq
%define xq widthq
%if ARCH_X86_32
mov dstmp, dstq
mov srcmp, srcq
mov frameantmp, frameantq
mov lineantmp, lineantq
%define dstq r0
%define frameantq r0
%define lineantq r0
%define pixelantq r1
%define pixelantd r1d
DECLARE_REG_TMP 2,3
%endif
LOAD pixelantd, xq, %1
ALIGN 16
.loop:
movifnidn srcq, srcmp
LOAD t0d, xq+1, %1 ; skip on the last iteration to avoid overread
.loop2:
movifnidn lineantq, lineantmp
movzx t1d, word [lineantq+xq*2]
LOWPASS t1, pixelant, spatial
mov [lineantq+xq*2], t1w
LOWPASS pixelant, t0, spatial
movifnidn frameantq, frameantmp
movzx t0d, word [frameantq+xq*2]
LOWPASS t0, t1, temporal
mov [frameantq+xq*2], t0w
movifnidn dstq, dstmp
%if %1 != 16
add t0d, (1<<(15-%1))-1
shr t0d, 16-%1 ; could eliminate this by storing from t0h, but only with some contraints on register allocation
%endif
%if %1 == 8
mov [dstq+xq], t0b
%else
mov [dstq+xq*2], t0w
%endif
inc xq
jl .loop
je .loop2
REP_RET
%endmacro ; HQDN3D_ROW
HQDN3D_ROW 8
HQDN3D_ROW 9
HQDN3D_ROW 10
HQDN3D_ROW 16
......@@ -159,6 +159,7 @@ CPUNOP amdnop
%define r%1w %2w
%define r%1b %2b
%define r%1h %2h
%define %2q %2
%if %0 == 2
%define r%1m %2d
%define r%1mp %2
......
......@@ -4,6 +4,9 @@ fate-utvideo_rgba_left: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_rgba_left.a
FATE_UTVIDEO += fate-utvideo_rgba_median
fate-utvideo_rgba_median: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_rgba_median.avi
FATE_UTVIDEO += fate-utvideo_rgba_single_symbol
fate-utvideo_rgba_single_symbol: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_rgba_single_symbol.avi
FATE_UTVIDEO += fate-utvideo_rgb_left
fate-utvideo_rgb_left: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_rgb_left.avi
......
#tb 0: 1/24
0, 0, 0, 1, 3145728, 0xac95c593
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment