Note: this is 4:4:4 from the 2007 spec revision, not the previous (now deprecated) 4:4:4 mode in H.264.tags/n0.8
@@ -507,7 +507,7 @@ typedef struct DSPContext { | |||
#define BASIS_SHIFT 16 | |||
#define RECON_SHIFT 6 | |||
void (*draw_edges)(uint8_t *buf, int wrap, int width, int height, int w, int sides); | |||
void (*draw_edges)(uint8_t *buf, int wrap, int width, int height, int w, int h, int sides); | |||
#define EDGE_WIDTH 16 | |||
#define EDGE_TOP 1 | |||
#define EDGE_BOTTOM 2 | |||
@@ -79,7 +79,7 @@ static inline void FUNC(copy_block16)(uint8_t *dst, const uint8_t *src, int dstS | |||
/* draw the edges of width 'w' of an image of size width, height */ | |||
//FIXME check that this is ok for mpeg4 interlaced | |||
static void FUNCC(draw_edges)(uint8_t *_buf, int _wrap, int width, int height, int w, int sides) | |||
static void FUNCC(draw_edges)(uint8_t *_buf, int _wrap, int width, int height, int w, int h, int sides) | |||
{ | |||
pixel *buf = (pixel*)_buf; | |||
int wrap = _wrap / sizeof(pixel); | |||
@@ -106,10 +106,10 @@ static void FUNCC(draw_edges)(uint8_t *_buf, int _wrap, int width, int height, i | |||
buf -= w; | |||
last_line = buf + (height - 1) * wrap; | |||
if (sides & EDGE_TOP) | |||
for(i = 0; i < w; i++) | |||
for(i = 0; i < h; i++) | |||
memcpy(buf - (i + 1) * wrap, buf, (width + w + w) * sizeof(pixel)); // top | |||
if (sides & EDGE_BOTTOM) | |||
for (i = 0; i < w; i++) | |||
for (i = 0; i < h; i++) | |||
memcpy(last_line + (i + 1) * wrap, last_line, (width + w + w) * sizeof(pixel)); // bottom | |||
} | |||
@@ -39,9 +39,6 @@ | |||
#define interlaced_dct interlaced_dct_is_a_bad_name | |||
#define mb_intra mb_intra_is_not_initialized_see_mb_type | |||
#define LUMA_DC_BLOCK_INDEX 24 | |||
#define CHROMA_DC_BLOCK_INDEX 25 | |||
#define CHROMA_DC_COEFF_TOKEN_VLC_BITS 8 | |||
#define COEFF_TOKEN_VLC_BITS 8 | |||
#define TOTAL_ZEROS_VLC_BITS 9 | |||
@@ -60,8 +57,6 @@ | |||
* of progressive decoding by about 2%. */ | |||
#define ALLOW_INTERLACE | |||
#define ALLOW_NOCHROMA | |||
#define FMO 0 | |||
/** | |||
@@ -85,16 +80,12 @@ | |||
#endif | |||
#define FIELD_OR_MBAFF_PICTURE (FRAME_MBAFF || FIELD_PICTURE) | |||
#ifdef ALLOW_NOCHROMA | |||
#define CHROMA h->sps.chroma_format_idc | |||
#else | |||
#define CHROMA 1 | |||
#endif | |||
#ifndef CABAC | |||
#define CABAC h->pps.cabac | |||
#endif | |||
#define CHROMA444 (h->sps.chroma_format_idc == 3) | |||
#define EXTENDED_SAR 255 | |||
#define MB_TYPE_REF0 MB_TYPE_ACPRED //dirty but it fits in 16 bit | |||
@@ -198,7 +189,7 @@ typedef struct SPS{ | |||
int num_reorder_frames; | |||
int scaling_matrix_present; | |||
uint8_t scaling_matrix4[6][16]; | |||
uint8_t scaling_matrix8[2][64]; | |||
uint8_t scaling_matrix8[6][64]; | |||
int nal_hrd_parameters_present_flag; | |||
int vcl_hrd_parameters_present_flag; | |||
int pic_struct_present_flag; | |||
@@ -233,7 +224,7 @@ typedef struct PPS{ | |||
int redundant_pic_cnt_present; ///< redundant_pic_cnt_present_flag | |||
int transform_8x8_mode; ///< transform_8x8_mode_flag | |||
uint8_t scaling_matrix4[6][16]; | |||
uint8_t scaling_matrix8[2][64]; | |||
uint8_t scaling_matrix8[6][64]; | |||
uint8_t chroma_qp_table[2][64]; ///< pre-scaled (with chroma_qp_index_offset) version of qp_table | |||
int chroma_qp_diff; | |||
}PPS; | |||
@@ -298,21 +289,15 @@ typedef struct H264Context{ | |||
unsigned int top_samples_available; | |||
unsigned int topright_samples_available; | |||
unsigned int left_samples_available; | |||
uint8_t (*top_borders[2])[(16+2*8)*2]; | |||
uint8_t (*top_borders[2])[(16*3)*2]; | |||
/** | |||
* non zero coeff count cache. | |||
* is 64 if not available. | |||
*/ | |||
DECLARE_ALIGNED(8, uint8_t, non_zero_count_cache)[6*8]; | |||
DECLARE_ALIGNED(8, uint8_t, non_zero_count_cache)[15*8]; | |||
/* | |||
.UU.YYYY | |||
.UU.YYYY | |||
.vv.YYYY | |||
.VV.YYYY | |||
*/ | |||
uint8_t (*non_zero_count)[32]; | |||
uint8_t (*non_zero_count)[48]; | |||
/** | |||
* Motion vector cache. | |||
@@ -336,7 +321,7 @@ typedef struct H264Context{ | |||
* block_offset[ 0..23] for frame macroblocks | |||
* block_offset[24..47] for field macroblocks | |||
*/ | |||
int block_offset[2*(16+8)]; | |||
int block_offset[2*(16*3)]; | |||
uint32_t *mb2b_xy; //FIXME are these 4 a good idea? | |||
uint32_t *mb2br_xy; | |||
@@ -356,9 +341,9 @@ typedef struct H264Context{ | |||
PPS pps; //FIXME move to Picture perhaps? (->no) do we need that? | |||
uint32_t dequant4_buffer[6][QP_MAX_NUM+1][16]; //FIXME should these be moved down? | |||
uint32_t dequant8_buffer[2][QP_MAX_NUM+1][64]; | |||
uint32_t dequant8_buffer[6][QP_MAX_NUM+1][64]; | |||
uint32_t (*dequant4_coeff[6])[16]; | |||
uint32_t (*dequant8_coeff[2])[64]; | |||
uint32_t (*dequant8_coeff[6])[64]; | |||
int slice_num; | |||
uint16_t *slice_table; ///< slice_table_base + 2*mb_stride + 1 | |||
@@ -408,15 +393,15 @@ typedef struct H264Context{ | |||
GetBitContext *intra_gb_ptr; | |||
GetBitContext *inter_gb_ptr; | |||
DECLARE_ALIGNED(16, DCTELEM, mb)[16*24*2]; ///< as a dct coeffecient is int32_t in high depth, we need to reserve twice the space. | |||
DECLARE_ALIGNED(16, DCTELEM, mb_luma_dc)[16*2]; | |||
DECLARE_ALIGNED(16, DCTELEM, mb)[16*48*2]; ///< as a dct coeffecient is int32_t in high depth, we need to reserve twice the space. | |||
DECLARE_ALIGNED(16, DCTELEM, mb_luma_dc)[3][16*2]; | |||
DCTELEM mb_padding[256*2]; ///< as mb is addressed by scantable[i] and scantable is uint8_t we can either check that i is not too large or ensure that there is some unused stuff after mb | |||
/** | |||
* Cabac | |||
*/ | |||
CABACContext cabac; | |||
uint8_t cabac_state[460]; | |||
uint8_t cabac_state[1024]; | |||
/* 0x100 -> non null luma_dc, 0x80/0x40 -> non null chroma_dc (cb/cr), 0x?0 -> chroma_cbp(0,1,2), 0x0? luma_cbp */ | |||
uint16_t *cbp_table; | |||
@@ -721,27 +706,43 @@ o-o o-o | |||
*/ | |||
/* Scan8 organization: | |||
* 0 1 2 3 4 5 6 7 | |||
* 0 u u y y y y y | |||
* 1 u U U y Y Y Y Y | |||
* 2 u U U y Y Y Y Y | |||
* 3 v v y Y Y Y Y | |||
* 4 v V V y Y Y Y Y | |||
* 5 v V V DYDUDV | |||
* 0 1 2 3 4 5 6 7 | |||
* 0 DY y y y y y | |||
* 1 y Y Y Y Y | |||
* 2 y Y Y Y Y | |||
* 3 y Y Y Y Y | |||
* 4 y Y Y Y Y | |||
* 5 DU u u u u u | |||
* 6 u U U U U | |||
* 7 u U U U U | |||
* 8 u U U U U | |||
* 9 u U U U U | |||
* 10 DV v v v v v | |||
* 11 v V V V V | |||
* 12 v V V V V | |||
* 13 v V V V V | |||
* 14 v V V V V | |||
* DY/DU/DV are for luma/chroma DC. | |||
*/ | |||
#define LUMA_DC_BLOCK_INDEX 48 | |||
#define CHROMA_DC_BLOCK_INDEX 49 | |||
//This table must be here because scan8[constant] must be known at compiletime | |||
static const uint8_t scan8[16 + 2*4 + 3]={ | |||
4+1*8, 5+1*8, 4+2*8, 5+2*8, | |||
6+1*8, 7+1*8, 6+2*8, 7+2*8, | |||
4+3*8, 5+3*8, 4+4*8, 5+4*8, | |||
6+3*8, 7+3*8, 6+4*8, 7+4*8, | |||
1+1*8, 2+1*8, | |||
1+2*8, 2+2*8, | |||
1+4*8, 2+4*8, | |||
1+5*8, 2+5*8, | |||
4+5*8, 5+5*8, 6+5*8 | |||
static const uint8_t scan8[16*3 + 3]={ | |||
4+ 1*8, 5+ 1*8, 4+ 2*8, 5+ 2*8, | |||
6+ 1*8, 7+ 1*8, 6+ 2*8, 7+ 2*8, | |||
4+ 3*8, 5+ 3*8, 4+ 4*8, 5+ 4*8, | |||
6+ 3*8, 7+ 3*8, 6+ 4*8, 7+ 4*8, | |||
4+ 6*8, 5+ 6*8, 4+ 7*8, 5+ 7*8, | |||
6+ 6*8, 7+ 6*8, 6+ 7*8, 7+ 7*8, | |||
4+ 8*8, 5+ 8*8, 4+ 9*8, 5+ 9*8, | |||
6+ 8*8, 7+ 8*8, 6+ 9*8, 7+ 9*8, | |||
4+11*8, 5+11*8, 4+12*8, 5+12*8, | |||
6+11*8, 7+11*8, 6+12*8, 7+12*8, | |||
4+13*8, 5+13*8, 4+14*8, 5+14*8, | |||
6+13*8, 7+13*8, 6+14*8, 7+14*8, | |||
0+ 0*8, 0+ 5*8, 0+10*8 | |||
}; | |||
static av_always_inline uint32_t pack16to32(int a, int b){ | |||
@@ -773,11 +774,11 @@ static void fill_decode_neighbors(H264Context *h, int mb_type){ | |||
MpegEncContext * const s = &h->s; | |||
const int mb_xy= h->mb_xy; | |||
int topleft_xy, top_xy, topright_xy, left_xy[2]; | |||
static const uint8_t left_block_options[4][16]={ | |||
{0,1,2,3,7,10,8,11,7+0*8, 7+1*8, 7+2*8, 7+3*8, 2+0*8, 2+3*8, 2+1*8, 2+2*8}, | |||
{2,2,3,3,8,11,8,11,7+2*8, 7+2*8, 7+3*8, 7+3*8, 2+1*8, 2+2*8, 2+1*8, 2+2*8}, | |||
{0,0,1,1,7,10,7,10,7+0*8, 7+0*8, 7+1*8, 7+1*8, 2+0*8, 2+3*8, 2+0*8, 2+3*8}, | |||
{0,2,0,2,7,10,7,10,7+0*8, 7+2*8, 7+0*8, 7+2*8, 2+0*8, 2+3*8, 2+0*8, 2+3*8} | |||
static const uint8_t left_block_options[4][32]={ | |||
{0,1,2,3,7,10,8,11,3+0*4, 3+1*4, 3+2*4, 3+3*4, 1+4*4, 1+8*4, 1+5*4, 1+9*4}, | |||
{2,2,3,3,8,11,8,11,3+2*4, 3+2*4, 3+3*4, 3+3*4, 1+5*4, 1+9*4, 1+5*4, 1+9*4}, | |||
{0,0,1,1,7,10,7,10,3+0*4, 3+0*4, 3+1*4, 3+1*4, 1+4*4, 1+8*4, 1+4*4, 1+8*4}, | |||
{0,2,0,2,7,10,7,10,3+0*4, 3+2*4, 3+0*4, 3+2*4, 1+4*4, 1+8*4, 1+4*4, 1+8*4} | |||
}; | |||
h->topleft_partition= -1; | |||
@@ -947,32 +948,41 @@ static void fill_decode_caches(H264Context *h, int mb_type){ | |||
*/ | |||
//FIXME constraint_intra_pred & partitioning & nnz (let us hope this is just a typo in the spec) | |||
if(top_type){ | |||
AV_COPY32(&h->non_zero_count_cache[4+8*0], &h->non_zero_count[top_xy][4+3*8]); | |||
h->non_zero_count_cache[1+8*0]= h->non_zero_count[top_xy][1+1*8]; | |||
h->non_zero_count_cache[2+8*0]= h->non_zero_count[top_xy][2+1*8]; | |||
h->non_zero_count_cache[1+8*3]= h->non_zero_count[top_xy][1+2*8]; | |||
h->non_zero_count_cache[2+8*3]= h->non_zero_count[top_xy][2+2*8]; | |||
}else { | |||
h->non_zero_count_cache[1+8*0]= | |||
h->non_zero_count_cache[2+8*0]= | |||
h->non_zero_count_cache[1+8*3]= | |||
h->non_zero_count_cache[2+8*3]= | |||
AV_WN32A(&h->non_zero_count_cache[4+8*0], CABAC && !IS_INTRA(mb_type) ? 0 : 0x40404040); | |||
AV_COPY32(&h->non_zero_count_cache[4+8* 0], &h->non_zero_count[top_xy][4*3]); | |||
if(CHROMA444){ | |||
AV_COPY32(&h->non_zero_count_cache[4+8* 5], &h->non_zero_count[top_xy][4* 7]); | |||
AV_COPY32(&h->non_zero_count_cache[4+8*10], &h->non_zero_count[top_xy][4*11]); | |||
}else{ | |||
AV_COPY32(&h->non_zero_count_cache[4+8* 5], &h->non_zero_count[top_xy][4* 5]); | |||
AV_COPY32(&h->non_zero_count_cache[4+8*10], &h->non_zero_count[top_xy][4* 9]); | |||
} | |||
}else{ | |||
uint32_t top_empty = CABAC && !IS_INTRA(mb_type) ? 0 : 0x40404040; | |||
AV_WN32A(&h->non_zero_count_cache[4+8* 0], top_empty); | |||
AV_WN32A(&h->non_zero_count_cache[4+8* 5], top_empty); | |||
AV_WN32A(&h->non_zero_count_cache[4+8*10], top_empty); | |||
} | |||
for (i=0; i<2; i++) { | |||
if(left_type[i]){ | |||
h->non_zero_count_cache[3+8*1 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[8+0+2*i]]; | |||
h->non_zero_count_cache[3+8*2 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[8+1+2*i]]; | |||
h->non_zero_count_cache[0+8*1 + 8*i]= h->non_zero_count[left_xy[i]][left_block[8+4+2*i]]; | |||
h->non_zero_count_cache[0+8*4 + 8*i]= h->non_zero_count[left_xy[i]][left_block[8+5+2*i]]; | |||
h->non_zero_count_cache[3+8* 1 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[8+0+2*i]]; | |||
h->non_zero_count_cache[3+8* 2 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[8+1+2*i]]; | |||
if(CHROMA444){ | |||
h->non_zero_count_cache[3+8* 6 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[8+0+2*i]+4*4]; | |||
h->non_zero_count_cache[3+8* 7 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[8+1+2*i]+4*4]; | |||
h->non_zero_count_cache[3+8*11 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[8+0+2*i]+8*4]; | |||
h->non_zero_count_cache[3+8*12 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[8+1+2*i]+8*4]; | |||
}else{ | |||
h->non_zero_count_cache[3+8* 6 + 8*i]= h->non_zero_count[left_xy[i]][left_block[8+4+2*i]]; | |||
h->non_zero_count_cache[3+8*11 + 8*i]= h->non_zero_count[left_xy[i]][left_block[8+5+2*i]]; | |||
} | |||
}else{ | |||
h->non_zero_count_cache[3+8*1 + 2*8*i]= | |||
h->non_zero_count_cache[3+8*2 + 2*8*i]= | |||
h->non_zero_count_cache[0+8*1 + 8*i]= | |||
h->non_zero_count_cache[0+8*4 + 8*i]= CABAC && !IS_INTRA(mb_type) ? 0 : 64; | |||
h->non_zero_count_cache[3+8* 1 + 2*8*i]= | |||
h->non_zero_count_cache[3+8* 2 + 2*8*i]= | |||
h->non_zero_count_cache[3+8* 6 + 2*8*i]= | |||
h->non_zero_count_cache[3+8* 7 + 2*8*i]= | |||
h->non_zero_count_cache[3+8*11 + 2*8*i]= | |||
h->non_zero_count_cache[3+8*12 + 2*8*i]= CABAC && !IS_INTRA(mb_type) ? 0 : 64; | |||
} | |||
} | |||
@@ -981,15 +991,15 @@ static void fill_decode_caches(H264Context *h, int mb_type){ | |||
if(top_type) { | |||
h->top_cbp = h->cbp_table[top_xy]; | |||
} else { | |||
h->top_cbp = IS_INTRA(mb_type) ? 0x1CF : 0x00F; | |||
h->top_cbp = IS_INTRA(mb_type) ? 0x7CF : 0x00F; | |||
} | |||
// left_cbp | |||
if (left_type[0]) { | |||
h->left_cbp = (h->cbp_table[left_xy[0]] & 0x1f0) | |||
h->left_cbp = (h->cbp_table[left_xy[0]] & 0x7F0) | |||
| ((h->cbp_table[left_xy[0]]>>(left_block[0]&(~1)))&2) | |||
| (((h->cbp_table[left_xy[1]]>>(left_block[2]&(~1)))&2) << 2); | |||
} else { | |||
h->left_cbp = IS_INTRA(mb_type) ? 0x1CF : 0x00F; | |||
h->left_cbp = IS_INTRA(mb_type) ? 0x7CF : 0x00F; | |||
} | |||
} | |||
} | |||
@@ -1190,11 +1200,21 @@ static inline int pred_intra_mode(H264Context *h, int n){ | |||
static inline void write_back_non_zero_count(H264Context *h){ | |||
const int mb_xy= h->mb_xy; | |||
AV_COPY64(&h->non_zero_count[mb_xy][ 0], &h->non_zero_count_cache[0+8*1]); | |||
AV_COPY64(&h->non_zero_count[mb_xy][ 8], &h->non_zero_count_cache[0+8*2]); | |||
AV_COPY32(&h->non_zero_count[mb_xy][16], &h->non_zero_count_cache[0+8*5]); | |||
AV_COPY32(&h->non_zero_count[mb_xy][20], &h->non_zero_count_cache[4+8*3]); | |||
AV_COPY64(&h->non_zero_count[mb_xy][24], &h->non_zero_count_cache[0+8*4]); | |||
AV_COPY32(&h->non_zero_count[mb_xy][ 0], &h->non_zero_count_cache[4+8* 1]); | |||
AV_COPY32(&h->non_zero_count[mb_xy][ 4], &h->non_zero_count_cache[4+8* 2]); | |||
AV_COPY32(&h->non_zero_count[mb_xy][ 8], &h->non_zero_count_cache[4+8* 3]); | |||
AV_COPY32(&h->non_zero_count[mb_xy][12], &h->non_zero_count_cache[4+8* 4]); | |||
AV_COPY32(&h->non_zero_count[mb_xy][16], &h->non_zero_count_cache[4+8* 6]); | |||
AV_COPY32(&h->non_zero_count[mb_xy][20], &h->non_zero_count_cache[4+8* 7]); | |||
AV_COPY32(&h->non_zero_count[mb_xy][32], &h->non_zero_count_cache[4+8*11]); | |||
AV_COPY32(&h->non_zero_count[mb_xy][36], &h->non_zero_count_cache[4+8*12]); | |||
if(CHROMA444){ | |||
AV_COPY32(&h->non_zero_count[mb_xy][24], &h->non_zero_count_cache[4+8* 8]); | |||
AV_COPY32(&h->non_zero_count[mb_xy][28], &h->non_zero_count_cache[4+8* 9]); | |||
AV_COPY32(&h->non_zero_count[mb_xy][40], &h->non_zero_count_cache[4+8*13]); | |||
AV_COPY32(&h->non_zero_count[mb_xy][44], &h->non_zero_count_cache[4+8*14]); | |||
} | |||
} | |||
static inline void write_back_motion(H264Context *h, int mb_type){ | |||
@@ -1267,8 +1287,7 @@ static void av_unused decode_mb_skip(H264Context *h){ | |||
const int mb_xy= h->mb_xy; | |||
int mb_type=0; | |||
memset(h->non_zero_count[mb_xy], 0, 32); | |||
memset(h->non_zero_count_cache + 8, 0, 8*5); //FIXME ugly, remove pfui | |||
memset(h->non_zero_count[mb_xy], 0, 48); | |||
if(MB_FIELD) | |||
mb_type|= MB_TYPE_INTERLACED; | |||
@@ -371,12 +371,12 @@ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, in | |||
//FIXME put trailing_onex into the context | |||
if(n >= CHROMA_DC_BLOCK_INDEX){ | |||
if(max_coeff <= 8){ | |||
coeff_token= get_vlc2(gb, chroma_dc_coeff_token_vlc.table, CHROMA_DC_COEFF_TOKEN_VLC_BITS, 1); | |||
total_coeff= coeff_token>>2; | |||
}else{ | |||
if(n == LUMA_DC_BLOCK_INDEX){ | |||
total_coeff= pred_non_zero_count(h, 0); | |||
if(n >= LUMA_DC_BLOCK_INDEX){ | |||
total_coeff= pred_non_zero_count(h, (n - LUMA_DC_BLOCK_INDEX)*16); | |||
coeff_token= get_vlc2(gb, coeff_token_vlc[ coeff_token_table_index[total_coeff] ].table, COEFF_TOKEN_VLC_BITS, 2); | |||
total_coeff= coeff_token>>2; | |||
}else{ | |||
@@ -482,7 +482,8 @@ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, in | |||
if(total_coeff == max_coeff) | |||
zeros_left=0; | |||
else{ | |||
if(n >= CHROMA_DC_BLOCK_INDEX) | |||
/* FIXME: we don't actually support 4:2:2 yet. */ | |||
if(max_coeff <= 8) | |||
zeros_left= get_vlc2(gb, (chroma_dc_total_zeros_vlc-1)[ total_coeff ].table, CHROMA_DC_TOTAL_ZEROS_VLC_BITS, 1); | |||
else | |||
zeros_left= get_vlc2(gb, (total_zeros_vlc-1)[ total_coeff ].table, TOTAL_ZEROS_VLC_BITS, 1); | |||
@@ -536,12 +537,80 @@ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, in | |||
return 0; | |||
} | |||
static av_always_inline int decode_luma_residual(H264Context *h, GetBitContext *gb, const uint8_t *scan, const uint8_t *scan8x8, int pixel_shift, int mb_type, int cbp, int p){ | |||
int i4x4, i8x8; | |||
MpegEncContext * const s = &h->s; | |||
int qscale = p == 0 ? s->qscale : h->chroma_qp[p-1]; | |||
if(IS_INTRA16x16(mb_type)){ | |||
AV_ZERO128(h->mb_luma_dc[p]+0); | |||
AV_ZERO128(h->mb_luma_dc[p]+8); | |||
AV_ZERO128(h->mb_luma_dc[p]+16); | |||
AV_ZERO128(h->mb_luma_dc[p]+24); | |||
if( decode_residual(h, h->intra_gb_ptr, h->mb_luma_dc[p], LUMA_DC_BLOCK_INDEX+p, scan, NULL, 16) < 0){ | |||
return -1; //FIXME continue if partitioned and other return -1 too | |||
} | |||
assert((cbp&15) == 0 || (cbp&15) == 15); | |||
if(cbp&15){ | |||
for(i8x8=0; i8x8<4; i8x8++){ | |||
for(i4x4=0; i4x4<4; i4x4++){ | |||
const int index= i4x4 + 4*i8x8 + p*16; | |||
if( decode_residual(h, h->intra_gb_ptr, h->mb + (16*index << pixel_shift), | |||
index, scan + 1, h->dequant4_coeff[p][qscale], 15) < 0 ){ | |||
return -1; | |||
} | |||
} | |||
} | |||
return 0xf; | |||
}else{ | |||
fill_rectangle(&h->non_zero_count_cache[scan8[p*16]], 4, 4, 8, 0, 1); | |||
return 0; | |||
} | |||
}else{ | |||
int cqm = (IS_INTRA( mb_type ) ? 0:3)+p; | |||
/* For CAVLC 4:4:4, we need to keep track of the luma 8x8 CBP for deblocking nnz purposes. */ | |||
int new_cbp = 0; | |||
for(i8x8=0; i8x8<4; i8x8++){ | |||
if(cbp & (1<<i8x8)){ | |||
if(IS_8x8DCT(mb_type)){ | |||
DCTELEM *buf = &h->mb[64*i8x8+256*p << pixel_shift]; | |||
uint8_t *nnz; | |||
for(i4x4=0; i4x4<4; i4x4++){ | |||
const int index= i4x4 + 4*i8x8 + p*16; | |||
if( decode_residual(h, gb, buf, index, scan8x8+16*i4x4, | |||
h->dequant8_coeff[cqm][qscale], 16) < 0 ) | |||
return -1; | |||
} | |||
nnz= &h->non_zero_count_cache[ scan8[4*i8x8+p*16] ]; | |||
nnz[0] += nnz[1] + nnz[8] + nnz[9]; | |||
new_cbp |= !!nnz[0] << i8x8; | |||
}else{ | |||
for(i4x4=0; i4x4<4; i4x4++){ | |||
const int index= i4x4 + 4*i8x8 + p*16; | |||
if( decode_residual(h, gb, h->mb + (16*index << pixel_shift), index, | |||
scan, h->dequant4_coeff[cqm][qscale], 16) < 0 ){ | |||
return -1; | |||
} | |||
new_cbp |= h->non_zero_count_cache[ scan8[index] ] << i8x8; | |||
} | |||
} | |||
}else{ | |||
uint8_t * const nnz= &h->non_zero_count_cache[ scan8[4*i8x8+p*16] ]; | |||
nnz[0] = nnz[1] = nnz[8] = nnz[9] = 0; | |||
} | |||
} | |||
return new_cbp; | |||
} | |||
} | |||
int ff_h264_decode_mb_cavlc(H264Context *h){ | |||
MpegEncContext * const s = &h->s; | |||
int mb_xy; | |||
int partition_count; | |||
unsigned int mb_type, cbp; | |||
int dct8x8_allowed= h->pps.transform_8x8_mode; | |||
int decode_chroma = h->sps.chroma_format_idc == 1 || h->sps.chroma_format_idc == 2; | |||
const int pixel_shift = h->pixel_shift; | |||
mb_xy = h->mb_xy = s->mb_x + s->mb_y*s->mb_stride; | |||
@@ -608,19 +677,21 @@ decode_intra_mb: | |||
if(IS_INTRA_PCM(mb_type)){ | |||
unsigned int x; | |||
static const uint16_t mb_sizes[4] = {256,384,512,768}; | |||
const int mb_size = mb_sizes[h->sps.chroma_format_idc]*h->sps.bit_depth_luma >> 3; | |||
// We assume these blocks are very rare so we do not optimize it. | |||
align_get_bits(&s->gb); | |||
// The pixels are stored in the same order as levels in h->mb array. | |||
for(x=0; x < (CHROMA ? 384 : 256)*h->sps.bit_depth_luma/8; x++){ | |||
for(x=0; x < mb_size; x++){ | |||
((uint8_t*)h->mb)[x]= get_bits(&s->gb, 8); | |||
} | |||
// In deblocking, the quantizer is 0 | |||
s->current_picture.qscale_table[mb_xy]= 0; | |||
// All coeffs are present | |||
memset(h->non_zero_count[mb_xy], 16, 32); | |||
memset(h->non_zero_count[mb_xy], 16, 48); | |||
s->current_picture.mb_type[mb_xy]= mb_type; | |||
return 0; | |||
@@ -668,7 +739,7 @@ decode_intra_mb: | |||
if(h->intra16x16_pred_mode < 0) | |||
return -1; | |||
} | |||
if(CHROMA){ | |||
if(decode_chroma){ | |||
pred_mode= ff_h264_check_intra_pred_mode(h, get_ue_golomb_31(&s->gb)); | |||
if(pred_mode < 0) | |||
return -1; | |||
@@ -896,15 +967,19 @@ decode_intra_mb: | |||
if(!IS_INTRA16x16(mb_type)){ | |||
cbp= get_ue_golomb(&s->gb); | |||
if(cbp > 47){ | |||
av_log(h->s.avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, s->mb_x, s->mb_y); | |||
return -1; | |||
} | |||
if(CHROMA){ | |||
if(decode_chroma){ | |||
if(cbp > 47){ | |||
av_log(h->s.avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, s->mb_x, s->mb_y); | |||
return -1; | |||
} | |||
if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp[cbp]; | |||
else cbp= golomb_to_inter_cbp [cbp]; | |||
}else{ | |||
if(cbp > 15){ | |||
av_log(h->s.avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, s->mb_x, s->mb_y); | |||
return -1; | |||
} | |||
if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp_gray[cbp]; | |||
else cbp= golomb_to_inter_cbp_gray[cbp]; | |||
} | |||
@@ -918,8 +993,9 @@ decode_intra_mb: | |||
s->current_picture.mb_type[mb_xy]= mb_type; | |||
if(cbp || IS_INTRA16x16(mb_type)){ | |||
int i8x8, i4x4, chroma_idx; | |||
int i4x4, chroma_idx; | |||
int dquant; | |||
int ret; | |||
GetBitContext *gb= IS_INTRA(mb_type) ? h->intra_gb_ptr : h->inter_gb_ptr; | |||
const uint8_t *scan, *scan8x8; | |||
const int max_qp = 51 + 6*(h->sps.bit_depth_luma-8); | |||
@@ -947,85 +1023,45 @@ decode_intra_mb: | |||
h->chroma_qp[0]= get_chroma_qp(h, 0, s->qscale); | |||
h->chroma_qp[1]= get_chroma_qp(h, 1, s->qscale); | |||
if(IS_INTRA16x16(mb_type)){ | |||
AV_ZERO128(h->mb_luma_dc+0); | |||
AV_ZERO128(h->mb_luma_dc+8); | |||
AV_ZERO128(h->mb_luma_dc+16); | |||
AV_ZERO128(h->mb_luma_dc+24); | |||
if( decode_residual(h, h->intra_gb_ptr, h->mb_luma_dc, LUMA_DC_BLOCK_INDEX, scan, h->dequant4_coeff[0][s->qscale], 16) < 0){ | |||
return -1; //FIXME continue if partitioned and other return -1 too | |||
} | |||
assert((cbp&15) == 0 || (cbp&15) == 15); | |||
if( (ret = decode_luma_residual(h, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 0)) < 0 ){ | |||
return -1; | |||
} | |||
h->cbp_table[mb_xy] |= ret << 12; | |||
if(CHROMA444){ | |||
if( decode_luma_residual(h, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 1) < 0 ){ | |||
return -1; | |||
} | |||
if( decode_luma_residual(h, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 2) < 0 ){ | |||
return -1; | |||
} | |||
} else { | |||
if(cbp&0x30){ | |||
for(chroma_idx=0; chroma_idx<2; chroma_idx++) | |||
if( decode_residual(h, gb, h->mb + ((256 + 16*16*chroma_idx) << pixel_shift), CHROMA_DC_BLOCK_INDEX+chroma_idx, chroma_dc_scan, NULL, 4) < 0){ | |||
return -1; | |||
} | |||
} | |||
if(cbp&15){ | |||
for(i8x8=0; i8x8<4; i8x8++){ | |||
if(cbp&0x20){ | |||
for(chroma_idx=0; chroma_idx<2; chroma_idx++){ | |||
const uint32_t *qmul = h->dequant4_coeff[chroma_idx+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[chroma_idx]]; | |||
for(i4x4=0; i4x4<4; i4x4++){ | |||
const int index= i4x4 + 4*i8x8; | |||
if( decode_residual(h, h->intra_gb_ptr, h->mb + (16*index << pixel_shift), index, scan + 1, h->dequant4_coeff[0][s->qscale], 15) < 0 ){ | |||
const int index= 16 + 16*chroma_idx + i4x4; | |||
if( decode_residual(h, gb, h->mb + (16*index << pixel_shift), index, scan + 1, qmul, 15) < 0){ | |||
return -1; | |||
} | |||
} | |||
} | |||
}else{ | |||
fill_rectangle(&h->non_zero_count_cache[scan8[0]], 4, 4, 8, 0, 1); | |||
fill_rectangle(&h->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1); | |||
fill_rectangle(&h->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1); | |||
} | |||
}else{ | |||
for(i8x8=0; i8x8<4; i8x8++){ | |||
if(cbp & (1<<i8x8)){ | |||
if(IS_8x8DCT(mb_type)){ | |||
DCTELEM *buf = &h->mb[64*i8x8 << pixel_shift]; | |||
uint8_t *nnz; | |||
for(i4x4=0; i4x4<4; i4x4++){ | |||
if( decode_residual(h, gb, buf, i4x4+4*i8x8, scan8x8+16*i4x4, | |||
h->dequant8_coeff[IS_INTRA( mb_type ) ? 0:1][s->qscale], 16) <0 ) | |||
return -1; | |||
} | |||
nnz= &h->non_zero_count_cache[ scan8[4*i8x8] ]; | |||
nnz[0] += nnz[1] + nnz[8] + nnz[9]; | |||
}else{ | |||
for(i4x4=0; i4x4<4; i4x4++){ | |||
const int index= i4x4 + 4*i8x8; | |||
if( decode_residual(h, gb, h->mb + (16*index << pixel_shift), index, scan, h->dequant4_coeff[IS_INTRA( mb_type ) ? 0:3][s->qscale], 16) <0 ){ | |||
return -1; | |||
} | |||
} | |||
} | |||
}else{ | |||
uint8_t * const nnz= &h->non_zero_count_cache[ scan8[4*i8x8] ]; | |||
nnz[0] = nnz[1] = nnz[8] = nnz[9] = 0; | |||
} | |||
} | |||
} | |||
if(cbp&0x30){ | |||
for(chroma_idx=0; chroma_idx<2; chroma_idx++) | |||
if( decode_residual(h, gb, h->mb + ((256 + 16*4*chroma_idx) << pixel_shift), CHROMA_DC_BLOCK_INDEX+chroma_idx, chroma_dc_scan, NULL, 4) < 0){ | |||
return -1; | |||
} | |||
} | |||
if(cbp&0x20){ | |||
for(chroma_idx=0; chroma_idx<2; chroma_idx++){ | |||
const uint32_t *qmul = h->dequant4_coeff[chroma_idx+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[chroma_idx]]; | |||
for(i4x4=0; i4x4<4; i4x4++){ | |||
const int index= 16 + 4*chroma_idx + i4x4; | |||
if( decode_residual(h, gb, h->mb + (16*index << pixel_shift), index, scan + 1, qmul, 15) < 0){ | |||
return -1; | |||
} | |||
} | |||
} | |||
}else{ | |||
uint8_t * const nnz= &h->non_zero_count_cache[0]; | |||
nnz[ scan8[16]+0 ] = nnz[ scan8[16]+1 ] =nnz[ scan8[16]+8 ] =nnz[ scan8[16]+9 ] = | |||
nnz[ scan8[20]+0 ] = nnz[ scan8[20]+1 ] =nnz[ scan8[20]+8 ] =nnz[ scan8[20]+9 ] = 0; | |||
} | |||
}else{ | |||
uint8_t * const nnz= &h->non_zero_count_cache[0]; | |||
fill_rectangle(&nnz[scan8[0]], 4, 4, 8, 0, 1); | |||
nnz[ scan8[16]+0 ] = nnz[ scan8[16]+1 ] =nnz[ scan8[16]+8 ] =nnz[ scan8[16]+9 ] = | |||
nnz[ scan8[20]+0 ] = nnz[ scan8[20]+1 ] =nnz[ scan8[20]+8 ] =nnz[ scan8[20]+9 ] = 0; | |||
fill_rectangle(&h->non_zero_count_cache[scan8[ 0]], 4, 4, 8, 0, 1); | |||
fill_rectangle(&h->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1); | |||
fill_rectangle(&h->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1); | |||
} | |||
s->current_picture.qscale_table[mb_xy]= s->qscale; | |||
write_back_non_zero_count(h); | |||
@@ -220,7 +220,7 @@ void ff_h264_filter_mb_fast( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, | |||
mb_xy = h->mb_xy; | |||
if(!h->top_type || !h->h264dsp.h264_loop_filter_strength || h->pps.chroma_qp_diff) { | |||
if(!h->top_type || !h->h264dsp.h264_loop_filter_strength || h->pps.chroma_qp_diff || CHROMA444) { | |||
ff_h264_filter_mb(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize); | |||
return; | |||
} | |||
@@ -353,9 +353,10 @@ static int check_mv(H264Context *h, long b_idx, long bn_idx, int mvy_limit){ | |||
return v; | |||
} | |||
static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize, int mb_xy, int mb_type, int mvy_limit, int first_vertical_edge_done, int dir) { | |||
static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize, int mb_xy, int mb_type, int mvy_limit, int first_vertical_edge_done, int chroma444, int dir) { | |||
MpegEncContext * const s = &h->s; | |||
int edge; | |||
int chroma_qp_avg[2]; | |||
const int mbm_xy = dir == 0 ? mb_xy -1 : h->top_mb_xy; | |||
const int mbm_type = dir == 0 ? h->left_type[0] : h->top_type; | |||
@@ -394,7 +395,7 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u | |||
bS[2]= 1+((h->cbp_table[mbn_xy] & 8)||h->non_zero_count_cache[scan8[0]+2]); | |||
bS[3]= 1+((h->cbp_table[mbn_xy] & 8)||h->non_zero_count_cache[scan8[0]+3]); | |||
}else{ | |||
const uint8_t *mbn_nnz = h->non_zero_count[mbn_xy] + 4+3*8; | |||
const uint8_t *mbn_nnz = h->non_zero_count[mbn_xy] + 3*4; | |||
int i; | |||
for( i = 0; i < 4; i++ ) { | |||
bS[i] = 1 + !!(h->non_zero_count_cache[scan8[0]+i] | mbn_nnz[i]); | |||
@@ -407,10 +408,15 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u | |||
tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, tmp_linesize, tmp_uvlinesize); | |||
{ int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); } | |||
filter_mb_edgeh( &img_y[j*linesize], tmp_linesize, bS, qp, h ); | |||
filter_mb_edgech( &img_cb[j*uvlinesize], tmp_uvlinesize, bS, | |||
( h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1, h); | |||
filter_mb_edgech( &img_cr[j*uvlinesize], tmp_uvlinesize, bS, | |||
( h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1, h); | |||
chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1; | |||
chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1; | |||
if (chroma444) { | |||
filter_mb_edgeh (&img_cb[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[0], h); | |||
filter_mb_edgeh (&img_cr[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[1], h); | |||
} else { | |||
filter_mb_edgech(&img_cb[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[0], h); | |||
filter_mb_edgech(&img_cr[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[1], h); | |||
} | |||
} | |||
}else{ | |||
DECLARE_ALIGNED(8, int16_t, bS)[4]; | |||
@@ -465,23 +471,29 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u | |||
//tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d, QPc:%d, QPcn:%d\n", mb_x, mb_y, dir, edge, qp, h->chroma_qp[0], s->current_picture.qscale_table[mbn_xy]); | |||
tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize); | |||
//{ int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); } | |||
chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbm_xy] ) + 1 ) >> 1; | |||
chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbm_xy] ) + 1 ) >> 1; | |||
if( dir == 0 ) { | |||
filter_mb_edgev( &img_y[0], linesize, bS, qp, h ); | |||
{ | |||
int qp= ( h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbm_xy] ) + 1 ) >> 1; | |||
filter_mb_edgecv( &img_cb[0], uvlinesize, bS, qp, h); | |||
if(h->pps.chroma_qp_diff) | |||
qp= ( h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbm_xy] ) + 1 ) >> 1; | |||
filter_mb_edgecv( &img_cr[0], uvlinesize, bS, qp, h); | |||
if (chroma444) { | |||
filter_mb_edgev ( &img_cb[0], uvlinesize, bS, chroma_qp_avg[0], h); | |||
filter_mb_edgev ( &img_cr[0], uvlinesize, bS, chroma_qp_avg[1], h); | |||
} else { | |||
filter_mb_edgecv( &img_cb[0], uvlinesize, bS, chroma_qp_avg[0], h); | |||
filter_mb_edgecv( &img_cr[0], uvlinesize, bS, chroma_qp_avg[1], h); | |||
} | |||
} | |||
} else { | |||
filter_mb_edgeh( &img_y[0], linesize, bS, qp, h ); | |||
{ | |||
int qp= ( h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbm_xy] ) + 1 ) >> 1; | |||
filter_mb_edgech( &img_cb[0], uvlinesize, bS, qp, h); | |||
if(h->pps.chroma_qp_diff) | |||
qp= ( h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbm_xy] ) + 1 ) >> 1; | |||
filter_mb_edgech( &img_cr[0], uvlinesize, bS, qp, h); | |||
if (chroma444) { | |||
filter_mb_edgeh ( &img_cb[0], uvlinesize, bS, chroma_qp_avg[0], h); | |||
filter_mb_edgeh ( &img_cr[0], uvlinesize, bS, chroma_qp_avg[1], h); | |||
} else { | |||
filter_mb_edgech( &img_cb[0], uvlinesize, bS, chroma_qp_avg[0], h); | |||
filter_mb_edgech( &img_cr[0], uvlinesize, bS, chroma_qp_avg[1], h); | |||
} | |||
} | |||
} | |||
} | |||
@@ -545,13 +557,19 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u | |||
//{ int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); } | |||
if( dir == 0 ) { | |||
filter_mb_edgev( &img_y[4*edge << h->pixel_shift], linesize, bS, qp, h ); | |||
if( (edge&1) == 0 ) { | |||
if (chroma444) { | |||
filter_mb_edgev ( &img_cb[4*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[0], h); | |||
filter_mb_edgev ( &img_cr[4*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[1], h); | |||
} else if( (edge&1) == 0 ) { | |||
filter_mb_edgecv( &img_cb[2*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[0], h); | |||
filter_mb_edgecv( &img_cr[2*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[1], h); | |||
} | |||
} else { | |||
filter_mb_edgeh( &img_y[4*edge*linesize], linesize, bS, qp, h ); | |||
if( (edge&1) == 0 ) { | |||
if (chroma444) { | |||
filter_mb_edgeh ( &img_cb[4*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[0], h); | |||
filter_mb_edgeh ( &img_cr[4*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[1], h); | |||
} else if( (edge&1) == 0 ) { | |||
filter_mb_edgech( &img_cb[2*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[0], h); | |||
filter_mb_edgech( &img_cr[2*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[1], h); | |||
} | |||
@@ -589,11 +607,11 @@ void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint | |||
} else { | |||
static const uint8_t offset[2][2][8]={ | |||
{ | |||
{7+8*0, 7+8*0, 7+8*0, 7+8*0, 7+8*1, 7+8*1, 7+8*1, 7+8*1}, | |||
{7+8*2, 7+8*2, 7+8*2, 7+8*2, 7+8*3, 7+8*3, 7+8*3, 7+8*3}, | |||
{3+4*0, 3+4*0, 3+4*0, 3+4*0, 3+4*1, 3+4*1, 3+4*1, 3+4*1}, | |||
{3+4*2, 3+4*2, 3+4*2, 3+4*2, 3+4*3, 3+4*3, 3+4*3, 3+4*3}, | |||
},{ | |||
{7+8*0, 7+8*1, 7+8*2, 7+8*3, 7+8*0, 7+8*1, 7+8*2, 7+8*3}, | |||
{7+8*0, 7+8*1, 7+8*2, 7+8*3, 7+8*0, 7+8*1, 7+8*2, 7+8*3}, | |||
{3+4*0, 3+4*1, 3+4*2, 3+4*3, 3+4*0, 3+4*1, 3+4*2, 3+4*3}, | |||
{3+4*0, 3+4*1, 3+4*2, 3+4*3, 3+4*0, 3+4*1, 3+4*2, 3+4*3}, | |||
} | |||
}; | |||
const uint8_t *off= offset[MB_FIELD][mb_y&1]; | |||
@@ -650,9 +668,9 @@ void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint | |||
#if CONFIG_SMALL | |||
for( dir = 0; dir < 2; dir++ ) | |||
filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, dir ? 0 : first_vertical_edge_done, dir); | |||
filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, dir ? 0 : first_vertical_edge_done, CHROMA444, dir); | |||
#else | |||
filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, first_vertical_edge_done, 0); | |||
filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, 0, 1); | |||
filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, first_vertical_edge_done, CHROMA444, 0); | |||
filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, 0, CHROMA444, 1); | |||
#endif | |||
} |
@@ -269,7 +269,7 @@ static void decode_scaling_matrices(H264Context *h, SPS *sps, PPS *pps, int is_s | |||
fallback_sps ? sps->scaling_matrix4[0] : default_scaling4[0], | |||
fallback_sps ? sps->scaling_matrix4[3] : default_scaling4[1], | |||
fallback_sps ? sps->scaling_matrix8[0] : default_scaling8[0], | |||
fallback_sps ? sps->scaling_matrix8[1] : default_scaling8[1] | |||
fallback_sps ? sps->scaling_matrix8[3] : default_scaling8[1] | |||
}; | |||
if(get_bits1(&s->gb)){ | |||
sps->scaling_matrix_present |= is_sps; | |||
@@ -281,7 +281,15 @@ static void decode_scaling_matrices(H264Context *h, SPS *sps, PPS *pps, int is_s | |||
decode_scaling_list(h,scaling_matrix4[5],16,default_scaling4[1],scaling_matrix4[4]); // Inter, Cb | |||
if(is_sps || pps->transform_8x8_mode){ | |||
decode_scaling_list(h,scaling_matrix8[0],64,default_scaling8[0],fallback[2]); // Intra, Y | |||
decode_scaling_list(h,scaling_matrix8[1],64,default_scaling8[1],fallback[3]); // Inter, Y | |||
if(h->sps.chroma_format_idc == 3){ | |||
decode_scaling_list(h,scaling_matrix8[1],64,default_scaling8[0],scaling_matrix8[0]); // Intra, Cr | |||
decode_scaling_list(h,scaling_matrix8[2],64,default_scaling8[0],scaling_matrix8[1]); // Intra, Cb | |||
} | |||
decode_scaling_list(h,scaling_matrix8[3],64,default_scaling8[1],fallback[3]); // Inter, Y | |||
if(h->sps.chroma_format_idc == 3){ | |||
decode_scaling_list(h,scaling_matrix8[4],64,default_scaling8[1],scaling_matrix8[3]); // Inter, Cr | |||
decode_scaling_list(h,scaling_matrix8[5],64,default_scaling8[1],scaling_matrix8[4]); // Inter, Cb | |||
} | |||
} | |||
} | |||
} | |||
@@ -395,7 +403,7 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ | |||
if(sps->crop_left || sps->crop_top){ | |||
av_log(h->s.avctx, AV_LOG_ERROR, "insane cropping not completely supported, this could look slightly wrong ...\n"); | |||
} | |||
if(sps->crop_right >= 8 || sps->crop_bottom >= 8){ | |||
if(sps->crop_right >= (8<<CHROMA444) || sps->crop_bottom >= (8<<CHROMA444)){ | |||
av_log(h->s.avctx, AV_LOG_ERROR, "brainfart cropping not supported, this could look slightly wrong ...\n"); | |||
} | |||
}else{ | |||
@@ -66,10 +66,10 @@ typedef struct H264DSPContext{ | |||
void (*h264_idct_dc_add)(uint8_t *dst/*align 4*/, DCTELEM *block/*align 16*/, int stride); | |||
void (*h264_idct8_dc_add)(uint8_t *dst/*align 8*/, DCTELEM *block/*align 16*/, int stride); | |||
void (*h264_idct_add16)(uint8_t *dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[6*8]); | |||
void (*h264_idct8_add4)(uint8_t *dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[6*8]); | |||
void (*h264_idct_add8)(uint8_t **dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[6*8]); | |||
void (*h264_idct_add16intra)(uint8_t *dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[6*8]); | |||
void (*h264_idct_add16)(uint8_t *dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[15*8]); | |||
void (*h264_idct8_add4)(uint8_t *dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[15*8]); | |||
void (*h264_idct_add8)(uint8_t **dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[15*8]); | |||
void (*h264_idct_add16intra)(uint8_t *dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[15*8]); | |||
void (*h264_luma_dc_dequant_idct)(DCTELEM *output, DCTELEM *input/*align 16*/, int qmul); | |||
void (*h264_chroma_dc_dequant_idct)(DCTELEM *block, int qmul); | |||
}H264DSPContext; | |||
@@ -30,15 +30,19 @@ | |||
#ifndef AVCODEC_H264IDCT_INTERNAL_H | |||
#define AVCODEC_H264IDCT_INTERNAL_H | |||
//FIXME this table is a duplicate from h264data.h, and will be removed once the tables from, h264 have been split | |||
static const uint8_t scan8[16 + 2*4]={ | |||
4+1*8, 5+1*8, 4+2*8, 5+2*8, | |||
6+1*8, 7+1*8, 6+2*8, 7+2*8, | |||
4+3*8, 5+3*8, 4+4*8, 5+4*8, | |||
6+3*8, 7+3*8, 6+4*8, 7+4*8, | |||
1+1*8, 2+1*8, | |||
1+2*8, 2+2*8, | |||
1+4*8, 2+4*8, | |||
1+5*8, 2+5*8, | |||
static const uint8_t scan8[16*3]={ | |||
4+ 1*8, 5+ 1*8, 4+ 2*8, 5+ 2*8, | |||
6+ 1*8, 7+ 1*8, 6+ 2*8, 7+ 2*8, | |||
4+ 3*8, 5+ 3*8, 4+ 4*8, 5+ 4*8, | |||
6+ 3*8, 7+ 3*8, 6+ 4*8, 7+ 4*8, | |||
4+ 6*8, 5+ 6*8, 4+ 7*8, 5+ 7*8, | |||
6+ 6*8, 7+ 6*8, 6+ 7*8, 7+ 7*8, | |||
4+ 8*8, 5+ 8*8, 4+ 9*8, 5+ 9*8, | |||
6+ 8*8, 7+ 8*8, 6+ 9*8, 7+ 9*8, | |||
4+11*8, 5+11*8, 4+12*8, 5+12*8, | |||
6+11*8, 7+11*8, 6+12*8, 7+12*8, | |||
4+13*8, 5+13*8, 4+14*8, 5+14*8, | |||
6+13*8, 7+13*8, 6+14*8, 7+14*8 | |||
}; | |||
#endif | |||
@@ -190,7 +194,7 @@ void FUNCC(ff_h264_idct8_dc_add)(uint8_t *_dst, DCTELEM *block, int stride){ | |||
} | |||
} | |||
void FUNCC(ff_h264_idct_add16)(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){ | |||
void FUNCC(ff_h264_idct_add16)(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){ | |||
int i; | |||
for(i=0; i<16; i++){ | |||
int nnz = nnzc[ scan8[i] ]; | |||
@@ -201,7 +205,7 @@ void FUNCC(ff_h264_idct_add16)(uint8_t *dst, const int *block_offset, DCTELEM *b | |||
} | |||
} | |||
void FUNCC(ff_h264_idct_add16intra)(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){ | |||
void FUNCC(ff_h264_idct_add16intra)(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){ | |||
int i; | |||
for(i=0; i<16; i++){ | |||
if(nnzc[ scan8[i] ]) FUNCC(idct_internal )(dst + block_offset[i], block + i*16*sizeof(pixel), stride, 4, 6, 1); | |||
@@ -209,7 +213,7 @@ void FUNCC(ff_h264_idct_add16intra)(uint8_t *dst, const int *block_offset, DCTEL | |||
} | |||
} | |||
void FUNCC(ff_h264_idct8_add4)(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){ | |||
void FUNCC(ff_h264_idct8_add4)(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){ | |||
int i; | |||
for(i=0; i<16; i+=4){ | |||
int nnz = nnzc[ scan8[i] ]; | |||
@@ -220,13 +224,15 @@ void FUNCC(ff_h264_idct8_add4)(uint8_t *dst, const int *block_offset, DCTELEM *b | |||
} | |||
} | |||
void FUNCC(ff_h264_idct_add8)(uint8_t **dest, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){ | |||
int i; | |||
for(i=16; i<16+8; i++){ | |||
if(nnzc[ scan8[i] ]) | |||
FUNCC(ff_h264_idct_add )(dest[(i&4)>>2] + block_offset[i], block + i*16*sizeof(pixel), stride); | |||
else if(((dctcoef*)block)[i*16]) | |||
FUNCC(ff_h264_idct_dc_add)(dest[(i&4)>>2] + block_offset[i], block + i*16*sizeof(pixel), stride); | |||
void FUNCC(ff_h264_idct_add8)(uint8_t **dest, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){ | |||
int i, j; | |||
for(j=1; j<3; j++){ | |||
for(i=j*16; i<j*16+4; i++){ | |||
if(nnzc[ scan8[i] ]) | |||
FUNCC(ff_h264_idct_add )(dest[j-1] + block_offset[i], block + i*16*sizeof(pixel), stride); | |||
else if(((dctcoef*)block)[i*16]) | |||
FUNCC(ff_h264_idct_dc_add)(dest[j-1] + block_offset[i], block + i*16*sizeof(pixel), stride); | |||
} | |||
} | |||
} | |||
/** | |||
@@ -1185,15 +1185,17 @@ void MPV_frame_end(MpegEncContext *s) | |||
&& s->current_picture.reference | |||
&& !s->intra_only | |||
&& !(s->flags&CODEC_FLAG_EMU_EDGE)) { | |||
int hshift = av_pix_fmt_descriptors[s->avctx->pix_fmt].log2_chroma_w; | |||
int vshift = av_pix_fmt_descriptors[s->avctx->pix_fmt].log2_chroma_h; | |||
s->dsp.draw_edges(s->current_picture.data[0], s->linesize , | |||
s->h_edge_pos , s->v_edge_pos , | |||
EDGE_WIDTH , EDGE_TOP | EDGE_BOTTOM); | |||
s->h_edge_pos , s->v_edge_pos, | |||
EDGE_WIDTH , EDGE_WIDTH , EDGE_TOP | EDGE_BOTTOM); | |||
s->dsp.draw_edges(s->current_picture.data[1], s->uvlinesize, | |||
s->h_edge_pos>>1, s->v_edge_pos>>1, | |||
EDGE_WIDTH/2, EDGE_TOP | EDGE_BOTTOM); | |||
s->h_edge_pos>>hshift, s->v_edge_pos>>vshift, | |||
EDGE_WIDTH>>hshift, EDGE_WIDTH>>vshift, EDGE_TOP | EDGE_BOTTOM); | |||
s->dsp.draw_edges(s->current_picture.data[2], s->uvlinesize, | |||
s->h_edge_pos>>1, s->v_edge_pos>>1, | |||
EDGE_WIDTH/2, EDGE_TOP | EDGE_BOTTOM); | |||
s->h_edge_pos>>hshift, s->v_edge_pos>>vshift, | |||
EDGE_WIDTH>>hshift, EDGE_WIDTH>>vshift, EDGE_TOP | EDGE_BOTTOM); | |||
} | |||
emms_c(); | |||
@@ -2284,14 +2286,19 @@ void ff_draw_horiz_band(MpegEncContext *s, int y, int h){ | |||
&& !s->intra_only | |||
&& !(s->flags&CODEC_FLAG_EMU_EDGE)) { | |||
int sides = 0, edge_h; | |||
int hshift = av_pix_fmt_descriptors[s->avctx->pix_fmt].log2_chroma_w; | |||
int vshift = av_pix_fmt_descriptors[s->avctx->pix_fmt].log2_chroma_h; | |||
if (y==0) sides |= EDGE_TOP; | |||
if (y + h >= s->v_edge_pos) sides |= EDGE_BOTTOM; | |||
edge_h= FFMIN(h, s->v_edge_pos - y); | |||
s->dsp.draw_edges(s->current_picture_ptr->data[0] + y *s->linesize , s->linesize , s->h_edge_pos , edge_h , EDGE_WIDTH , sides); | |||
s->dsp.draw_edges(s->current_picture_ptr->data[1] + (y>>1)*s->uvlinesize, s->uvlinesize, s->h_edge_pos>>1, edge_h>>1, EDGE_WIDTH/2, sides); | |||
s->dsp.draw_edges(s->current_picture_ptr->data[2] + (y>>1)*s->uvlinesize, s->uvlinesize, s->h_edge_pos>>1, edge_h>>1, EDGE_WIDTH/2, sides); | |||
s->dsp.draw_edges(s->current_picture_ptr->data[0] + y *s->linesize , s->linesize, | |||
s->h_edge_pos , edge_h , EDGE_WIDTH , EDGE_WIDTH , sides); | |||
s->dsp.draw_edges(s->current_picture_ptr->data[1] + (y>>vshift)*s->uvlinesize, s->uvlinesize, | |||
s->h_edge_pos>>hshift, edge_h>>hshift, EDGE_WIDTH>>hshift, EDGE_WIDTH>>vshift, sides); | |||
s->dsp.draw_edges(s->current_picture_ptr->data[2] + (y>>vshift)*s->uvlinesize, s->uvlinesize, | |||
s->h_edge_pos>>hshift, edge_h>>hshift, EDGE_WIDTH>>hshift, EDGE_WIDTH>>vshift, sides); | |||
} | |||
h= FFMIN(h, s->avctx->height - y); | |||
@@ -1978,13 +1978,13 @@ static int frame_start(SnowContext *s){ | |||
if(s->current_picture.data[0]){ | |||
s->dsp.draw_edges(s->current_picture.data[0], | |||
s->current_picture.linesize[0], w , h , | |||
EDGE_WIDTH , EDGE_TOP | EDGE_BOTTOM); | |||
EDGE_WIDTH , EDGE_WIDTH , EDGE_TOP | EDGE_BOTTOM); | |||
s->dsp.draw_edges(s->current_picture.data[1], | |||
s->current_picture.linesize[1], w>>1, h>>1, | |||
EDGE_WIDTH/2, EDGE_TOP | EDGE_BOTTOM); | |||
EDGE_WIDTH/2, EDGE_WIDTH/2, EDGE_TOP | EDGE_BOTTOM); | |||
s->dsp.draw_edges(s->current_picture.data[2], | |||
s->current_picture.linesize[2], w>>1, h>>1, | |||
EDGE_WIDTH/2, EDGE_TOP | EDGE_BOTTOM); | |||
EDGE_WIDTH/2, EDGE_WIDTH/2, EDGE_TOP | EDGE_BOTTOM); | |||
} | |||
release_buffer(s->avctx); | |||
@@ -784,7 +784,7 @@ static void h263_h_loop_filter_mmx(uint8_t *src, int stride, int qscale){ | |||
/* draw the edges of width 'w' of an image of size width, height | |||
this mmx version can only handle w==8 || w==16 */ | |||
static void draw_edges_mmx(uint8_t *buf, int wrap, int width, int height, int w, int sides) | |||
static void draw_edges_mmx(uint8_t *buf, int wrap, int width, int height, int w, int h, int sides) | |||
{ | |||
uint8_t *ptr, *last_line; | |||
int i; | |||
@@ -839,7 +839,7 @@ static void draw_edges_mmx(uint8_t *buf, int wrap, int width, int height, int w, | |||
/* top and bottom (and hopefully also the corners) */ | |||
if (sides&EDGE_TOP) { | |||
for(i = 0; i < w; i += 4) { | |||
for(i = 0; i < h; i += 4) { | |||
ptr= buf - (i + 1) * wrap - w; | |||
__asm__ volatile( | |||
"1: \n\t" | |||
@@ -36,7 +36,7 @@ | |||
#if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) | |||
static int decode_significance_x86(CABACContext *c, int max_coeff, | |||
uint8_t *significant_coeff_ctx_base, | |||
int *index){ | |||
int *index, int last_off){ | |||
void *end= significant_coeff_ctx_base + max_coeff - 1; | |||
int minusstart= -(int)significant_coeff_ctx_base; | |||
int minusindex= 4-(int)index; | |||
@@ -52,10 +52,12 @@ static int decode_significance_x86(CABACContext *c, int max_coeff, | |||
"test $1, %%edx \n\t" | |||
" jz 3f \n\t" | |||
"add %7, %1 \n\t" | |||
BRANCHLESS_GET_CABAC("%%edx", "%3", "61(%1)", "%%ebx", | |||
BRANCHLESS_GET_CABAC("%%edx", "%3", "(%1)", "%%ebx", | |||
"%%bx", "%%esi", "%%eax", "%%al") | |||
"sub %7, %1 \n\t" | |||
"mov %2, %%"REG_a" \n\t" | |||
"movl %4, %%ecx \n\t" | |||
"add %1, %%"REG_c" \n\t" | |||
@@ -82,7 +84,7 @@ static int decode_significance_x86(CABACContext *c, int max_coeff, | |||
"movl %%esi, "RANGE "(%3) \n\t" | |||
"movl %%ebx, "LOW "(%3) \n\t" | |||
:"=&a"(coeff_count), "+r"(significant_coeff_ctx_base), "+m"(index) | |||
:"r"(c), "m"(minusstart), "m"(end), "m"(minusindex) | |||
:"r"(c), "m"(minusstart), "m"(end), "m"(minusindex), "m"(last_off) | |||
: "%"REG_c, "%ebx", "%edx", "%esi", "memory" | |||
); | |||
return coeff_count; | |||
@@ -90,7 +92,7 @@ static int decode_significance_x86(CABACContext *c, int max_coeff, | |||
static int decode_significance_8x8_x86(CABACContext *c, | |||
uint8_t *significant_coeff_ctx_base, | |||
int *index, const uint8_t *sig_off){ | |||
int *index, int last_off, const uint8_t *sig_off){ | |||
int minusindex= 4-(int)index; | |||
int coeff_count; | |||
x86_reg last=0; | |||
@@ -114,8 +116,9 @@ static int decode_significance_8x8_x86(CABACContext *c, | |||
"movzbl "MANGLE(last_coeff_flag_offset_8x8)"(%%edi), %%edi\n\t" | |||
"add %5, %%"REG_D" \n\t" | |||
"add %7, %%"REG_D" \n\t" | |||
BRANCHLESS_GET_CABAC("%%edx", "%3", "15(%%"REG_D")", "%%ebx", | |||
BRANCHLESS_GET_CABAC("%%edx", "%3", "(%%"REG_D")", "%%ebx", | |||
"%%bx", "%%esi", "%%eax", "%%al") | |||
"mov %2, %%"REG_a" \n\t" | |||
@@ -142,7 +145,7 @@ static int decode_significance_8x8_x86(CABACContext *c, | |||
"movl %%esi, "RANGE "(%3) \n\t" | |||
"movl %%ebx, "LOW "(%3) \n\t" | |||
:"=&a"(coeff_count),"+m"(last), "+m"(index) | |||
:"r"(c), "m"(minusindex), "m"(significant_coeff_ctx_base), "m"(sig_off) | |||
:"r"(c), "m"(minusindex), "m"(significant_coeff_ctx_base), "m"(sig_off), "m"(last_off) | |||
: "%"REG_c, "%ebx", "%edx", "%esi", "%"REG_D, "memory" | |||
); | |||
return coeff_count; | |||
@@ -32,14 +32,18 @@ | |||
SECTION_RODATA | |||
; FIXME this table is a duplicate from h264data.h, and will be removed once the tables from, h264 have been split | |||
scan8_mem: db 4+1*8, 5+1*8, 4+2*8, 5+2*8 | |||
db 6+1*8, 7+1*8, 6+2*8, 7+2*8 | |||
db 4+3*8, 5+3*8, 4+4*8, 5+4*8 | |||
db 6+3*8, 7+3*8, 6+4*8, 7+4*8 | |||
db 1+1*8, 2+1*8 | |||
db 1+2*8, 2+2*8 | |||
db 1+4*8, 2+4*8 | |||
db 1+5*8, 2+5*8 | |||
scan8_mem: db 4+ 1*8, 5+ 1*8, 4+ 2*8, 5+ 2*8 | |||
db 6+ 1*8, 7+ 1*8, 6+ 2*8, 7+ 2*8 | |||
db 4+ 3*8, 5+ 3*8, 4+ 4*8, 5+ 4*8 | |||
db 6+ 3*8, 7+ 3*8, 6+ 4*8, 7+ 4*8 | |||
db 4+ 6*8, 5+ 6*8, 4+ 7*8, 5+ 7*8 | |||
db 6+ 6*8, 7+ 6*8, 6+ 7*8, 7+ 7*8 | |||
db 4+ 8*8, 5+ 8*8, 4+ 9*8, 5+ 9*8 | |||
db 6+ 8*8, 7+ 8*8, 6+ 9*8, 7+ 9*8 | |||
db 4+11*8, 5+11*8, 4+12*8, 5+12*8 | |||
db 6+11*8, 7+11*8, 6+12*8, 7+12*8 | |||
db 4+13*8, 5+13*8, 4+14*8, 5+14*8 | |||
db 6+13*8, 7+13*8, 6+14*8, 7+14*8 | |||
%ifdef PIC | |||
%define scan8 r11 | |||
%else | |||
@@ -617,6 +621,8 @@ cglobal h264_idct_add8_8_mmx, 5, 7, 0 | |||
mov r10, r0 | |||
%endif | |||
call h264_idct_add8_mmx_plane | |||
mov r5, 32 | |||
add r2, 384 | |||
%ifdef ARCH_X86_64 | |||
add r10, gprsize | |||
%else | |||
@@ -678,6 +684,8 @@ cglobal h264_idct_add8_8_mmx2, 5, 7, 0 | |||
lea r11, [scan8_mem] | |||
%endif | |||
call h264_idct_add8_mmx2_plane | |||
mov r5, 32 | |||
add r2, 384 | |||
%ifdef ARCH_X86_64 | |||
add r10, gprsize | |||
%else | |||
@@ -810,12 +818,12 @@ cglobal h264_idct_add16intra_8_sse2, 5, 7, 8 | |||
test r0, r0 | |||
jz .try%1dc | |||
%ifdef ARCH_X86_64 | |||
mov r0d, dword [r1+%1*8+64] | |||
mov r0d, dword [r1+(%1&1)*8+64*(1+(%1>>1))] | |||
add r0, [r10] | |||
%else | |||
mov r0, r0m | |||
mov r0, [r0] | |||
add r0, dword [r1+%1*8+64] | |||
add r0, dword [r1+(%1&1)*8+64*(1+(%1>>1))] | |||
%endif | |||
call x264_add8x4_idct_sse2 | |||
jmp .cycle%1end | |||
@@ -824,16 +832,18 @@ cglobal h264_idct_add16intra_8_sse2, 5, 7, 8 | |||
or r0w, word [r2+32] | |||
jz .cycle%1end | |||
%ifdef ARCH_X86_64 | |||
mov r0d, dword [r1+%1*8+64] | |||
mov r0d, dword [r1+(%1&1)*8+64*(1+(%1>>1))] | |||
add r0, [r10] | |||
%else | |||
mov r0, r0m | |||
mov r0, [r0] | |||
add r0, dword [r1+%1*8+64] | |||
add r0, dword [r1+(%1&1)*8+64*(1+(%1>>1))] | |||
%endif | |||
call h264_idct_dc_add8_mmx2 | |||
.cycle%1end | |||
%if %1 < 3 | |||
%if %1 == 1 | |||
add r2, 384+64 | |||
%elif %1 < 3 | |||
add r2, 64 | |||
%endif | |||
%endmacro | |||
@@ -845,15 +855,15 @@ cglobal h264_idct_add8_8_sse2, 5, 7, 8 | |||
%ifdef ARCH_X86_64 | |||
mov r10, r0 | |||
%endif | |||
add8_sse2_cycle 0, 0x09 | |||
add8_sse2_cycle 1, 0x11 | |||
add8_sse2_cycle 0, 0x34 | |||
add8_sse2_cycle 1, 0x3c | |||
%ifdef ARCH_X86_64 | |||
add r10, gprsize | |||
%else | |||
add r0mp, gprsize | |||
%endif | |||
add8_sse2_cycle 2, 0x21 | |||
add8_sse2_cycle 3, 0x29 | |||
add8_sse2_cycle 2, 0x5c | |||
add8_sse2_cycle 3, 0x64 | |||
RET | |||
;void ff_h264_luma_dc_dequant_idct_mmx(DCTELEM *output, DCTELEM *input, int qmul) | |||
@@ -29,14 +29,18 @@ SECTION_RODATA | |||
pw_pixel_max: times 8 dw ((1 << 10)-1) | |||
pd_32: times 4 dd 32 | |||
scan8_mem: db 4+1*8, 5+1*8, 4+2*8, 5+2*8 | |||
db 6+1*8, 7+1*8, 6+2*8, 7+2*8 | |||
db 4+3*8, 5+3*8, 4+4*8, 5+4*8 | |||
db 6+3*8, 7+3*8, 6+4*8, 7+4*8 | |||
db 1+1*8, 2+1*8 | |||
db 1+2*8, 2+2*8 | |||
db 1+4*8, 2+4*8 | |||
db 1+5*8, 2+5*8 | |||
scan8_mem: db 4+ 1*8, 5+ 1*8, 4+ 2*8, 5+ 2*8 | |||
db 6+ 1*8, 7+ 1*8, 6+ 2*8, 7+ 2*8 | |||
db 4+ 3*8, 5+ 3*8, 4+ 4*8, 5+ 4*8 | |||
db 6+ 3*8, 7+ 3*8, 6+ 4*8, 7+ 4*8 | |||
db 4+ 6*8, 5+ 6*8, 4+ 7*8, 5+ 7*8 | |||
db 6+ 6*8, 7+ 6*8, 6+ 7*8, 7+ 7*8 | |||
db 4+ 8*8, 5+ 8*8, 4+ 9*8, 5+ 9*8 | |||
db 6+ 8*8, 7+ 8*8, 6+ 9*8, 7+ 9*8 | |||
db 4+11*8, 5+11*8, 4+12*8, 5+12*8 | |||
db 6+11*8, 7+11*8, 6+12*8, 7+12*8 | |||
db 4+13*8, 5+13*8, 4+14*8, 5+14*8 | |||
db 6+13*8, 7+13*8, 6+14*8, 7+14*8 | |||
%ifdef PIC | |||
%define scan8 r11 | |||
@@ -306,7 +310,7 @@ INIT_AVX | |||
IDCT_ADD16INTRA_10 avx | |||
%endif | |||
%assign last_block 24 | |||
%assign last_block 36 | |||
;----------------------------------------------------------------------------- | |||
; h264_idct_add8(pixel **dst, const int *block_offset, dctcoef *block, int stride, const uint8_t nnzc[6*8]) | |||
;----------------------------------------------------------------------------- | |||
@@ -317,21 +321,22 @@ cglobal h264_idct_add8_10_%1,5,7 | |||
%endif | |||
add r2, 1024 | |||
mov r0, [r0] | |||
ADD16_OP_INTRA %1, 16, 1+1*8 | |||
ADD16_OP_INTRA %1, 18, 1+2*8 | |||
ADD16_OP_INTRA %1, 16, 4+ 6*8 | |||
ADD16_OP_INTRA %1, 18, 4+ 7*8 | |||
add r2, 1024-128*2 | |||
%ifdef ARCH_X86_64 | |||
mov r0, [r10+gprsize] | |||
%else | |||
mov r0, r0m | |||
mov r0, [r0+gprsize] | |||
%endif | |||
ADD16_OP_INTRA %1, 20, 1+4*8 | |||
ADD16_OP_INTRA %1, 22, 1+5*8 | |||
ADD16_OP_INTRA %1, 32, 4+11*8 | |||
ADD16_OP_INTRA %1, 34, 4+12*8 | |||
REP_RET | |||
AC %1, 16 | |||
AC %1, 18 | |||
AC %1, 20 | |||
AC %1, 22 | |||
AC %1, 32 | |||
AC %1, 34 | |||
%endmacro ; IDCT_ADD8 | |||