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 BASIS_SHIFT 16 | ||||
#define RECON_SHIFT 6 | #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_WIDTH 16 | ||||
#define EDGE_TOP 1 | #define EDGE_TOP 1 | ||||
#define EDGE_BOTTOM 2 | #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 */ | /* draw the edges of width 'w' of an image of size width, height */ | ||||
//FIXME check that this is ok for mpeg4 interlaced | //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; | pixel *buf = (pixel*)_buf; | ||||
int wrap = _wrap / sizeof(pixel); | 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; | buf -= w; | ||||
last_line = buf + (height - 1) * wrap; | last_line = buf + (height - 1) * wrap; | ||||
if (sides & EDGE_TOP) | 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 | memcpy(buf - (i + 1) * wrap, buf, (width + w + w) * sizeof(pixel)); // top | ||||
if (sides & EDGE_BOTTOM) | 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 | 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 interlaced_dct interlaced_dct_is_a_bad_name | ||||
#define mb_intra mb_intra_is_not_initialized_see_mb_type | #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 CHROMA_DC_COEFF_TOKEN_VLC_BITS 8 | ||||
#define COEFF_TOKEN_VLC_BITS 8 | #define COEFF_TOKEN_VLC_BITS 8 | ||||
#define TOTAL_ZEROS_VLC_BITS 9 | #define TOTAL_ZEROS_VLC_BITS 9 | ||||
@@ -60,8 +57,6 @@ | |||||
* of progressive decoding by about 2%. */ | * of progressive decoding by about 2%. */ | ||||
#define ALLOW_INTERLACE | #define ALLOW_INTERLACE | ||||
#define ALLOW_NOCHROMA | |||||
#define FMO 0 | #define FMO 0 | ||||
/** | /** | ||||
@@ -85,16 +80,12 @@ | |||||
#endif | #endif | ||||
#define FIELD_OR_MBAFF_PICTURE (FRAME_MBAFF || FIELD_PICTURE) | #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 | #ifndef CABAC | ||||
#define CABAC h->pps.cabac | #define CABAC h->pps.cabac | ||||
#endif | #endif | ||||
#define CHROMA444 (h->sps.chroma_format_idc == 3) | |||||
#define EXTENDED_SAR 255 | #define EXTENDED_SAR 255 | ||||
#define MB_TYPE_REF0 MB_TYPE_ACPRED //dirty but it fits in 16 bit | #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 num_reorder_frames; | ||||
int scaling_matrix_present; | int scaling_matrix_present; | ||||
uint8_t scaling_matrix4[6][16]; | 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 nal_hrd_parameters_present_flag; | ||||
int vcl_hrd_parameters_present_flag; | int vcl_hrd_parameters_present_flag; | ||||
int pic_struct_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 redundant_pic_cnt_present; ///< redundant_pic_cnt_present_flag | ||||
int transform_8x8_mode; ///< transform_8x8_mode_flag | int transform_8x8_mode; ///< transform_8x8_mode_flag | ||||
uint8_t scaling_matrix4[6][16]; | 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 | uint8_t chroma_qp_table[2][64]; ///< pre-scaled (with chroma_qp_index_offset) version of qp_table | ||||
int chroma_qp_diff; | int chroma_qp_diff; | ||||
}PPS; | }PPS; | ||||
@@ -298,21 +289,15 @@ typedef struct H264Context{ | |||||
unsigned int top_samples_available; | unsigned int top_samples_available; | ||||
unsigned int topright_samples_available; | unsigned int topright_samples_available; | ||||
unsigned int left_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. | * non zero coeff count cache. | ||||
* is 64 if not available. | * 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. | * Motion vector cache. | ||||
@@ -336,7 +321,7 @@ typedef struct H264Context{ | |||||
* block_offset[ 0..23] for frame macroblocks | * block_offset[ 0..23] for frame macroblocks | ||||
* block_offset[24..47] for field 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 *mb2b_xy; //FIXME are these 4 a good idea? | ||||
uint32_t *mb2br_xy; | uint32_t *mb2br_xy; | ||||
@@ -356,9 +341,9 @@ typedef struct H264Context{ | |||||
PPS pps; //FIXME move to Picture perhaps? (->no) do we need that? | 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 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 (*dequant4_coeff[6])[16]; | ||||
uint32_t (*dequant8_coeff[2])[64]; | |||||
uint32_t (*dequant8_coeff[6])[64]; | |||||
int slice_num; | int slice_num; | ||||
uint16_t *slice_table; ///< slice_table_base + 2*mb_stride + 1 | uint16_t *slice_table; ///< slice_table_base + 2*mb_stride + 1 | ||||
@@ -408,15 +393,15 @@ typedef struct H264Context{ | |||||
GetBitContext *intra_gb_ptr; | GetBitContext *intra_gb_ptr; | ||||
GetBitContext *inter_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 | 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 | * Cabac | ||||
*/ | */ | ||||
CABACContext 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 */ | /* 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; | uint16_t *cbp_table; | ||||
@@ -721,27 +706,43 @@ o-o o-o | |||||
*/ | */ | ||||
/* Scan8 organization: | /* 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. | * 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 | //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){ | 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; | MpegEncContext * const s = &h->s; | ||||
const int mb_xy= h->mb_xy; | const int mb_xy= h->mb_xy; | ||||
int topleft_xy, top_xy, topright_xy, left_xy[2]; | 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; | 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) | //FIXME constraint_intra_pred & partitioning & nnz (let us hope this is just a typo in the spec) | ||||
if(top_type){ | 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++) { | for (i=0; i<2; i++) { | ||||
if(left_type[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{ | }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) { | if(top_type) { | ||||
h->top_cbp = h->cbp_table[top_xy]; | h->top_cbp = h->cbp_table[top_xy]; | ||||
} else { | } else { | ||||
h->top_cbp = IS_INTRA(mb_type) ? 0x1CF : 0x00F; | |||||
h->top_cbp = IS_INTRA(mb_type) ? 0x7CF : 0x00F; | |||||
} | } | ||||
// left_cbp | // left_cbp | ||||
if (left_type[0]) { | 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[0]]>>(left_block[0]&(~1)))&2) | ||||
| (((h->cbp_table[left_xy[1]]>>(left_block[2]&(~1)))&2) << 2); | | (((h->cbp_table[left_xy[1]]>>(left_block[2]&(~1)))&2) << 2); | ||||
} else { | } 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){ | static inline void write_back_non_zero_count(H264Context *h){ | ||||
const int mb_xy= h->mb_xy; | 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){ | 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; | const int mb_xy= h->mb_xy; | ||||
int mb_type=0; | 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) | if(MB_FIELD) | ||||
mb_type|= MB_TYPE_INTERLACED; | 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 | //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); | coeff_token= get_vlc2(gb, chroma_dc_coeff_token_vlc.table, CHROMA_DC_COEFF_TOKEN_VLC_BITS, 1); | ||||
total_coeff= coeff_token>>2; | total_coeff= coeff_token>>2; | ||||
}else{ | }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); | 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; | total_coeff= coeff_token>>2; | ||||
}else{ | }else{ | ||||
@@ -482,7 +482,8 @@ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, in | |||||
if(total_coeff == max_coeff) | if(total_coeff == max_coeff) | ||||
zeros_left=0; | zeros_left=0; | ||||
else{ | 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); | zeros_left= get_vlc2(gb, (chroma_dc_total_zeros_vlc-1)[ total_coeff ].table, CHROMA_DC_TOTAL_ZEROS_VLC_BITS, 1); | ||||
else | else | ||||
zeros_left= get_vlc2(gb, (total_zeros_vlc-1)[ total_coeff ].table, TOTAL_ZEROS_VLC_BITS, 1); | 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; | 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){ | int ff_h264_decode_mb_cavlc(H264Context *h){ | ||||
MpegEncContext * const s = &h->s; | MpegEncContext * const s = &h->s; | ||||
int mb_xy; | int mb_xy; | ||||
int partition_count; | int partition_count; | ||||
unsigned int mb_type, cbp; | unsigned int mb_type, cbp; | ||||
int dct8x8_allowed= h->pps.transform_8x8_mode; | 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; | const int pixel_shift = h->pixel_shift; | ||||
mb_xy = h->mb_xy = s->mb_x + s->mb_y*s->mb_stride; | 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)){ | if(IS_INTRA_PCM(mb_type)){ | ||||
unsigned int x; | 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. | // We assume these blocks are very rare so we do not optimize it. | ||||
align_get_bits(&s->gb); | align_get_bits(&s->gb); | ||||
// The pixels are stored in the same order as levels in h->mb array. | // 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); | ((uint8_t*)h->mb)[x]= get_bits(&s->gb, 8); | ||||
} | } | ||||
// In deblocking, the quantizer is 0 | // In deblocking, the quantizer is 0 | ||||
s->current_picture.qscale_table[mb_xy]= 0; | s->current_picture.qscale_table[mb_xy]= 0; | ||||
// All coeffs are present | // 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; | s->current_picture.mb_type[mb_xy]= mb_type; | ||||
return 0; | return 0; | ||||
@@ -668,7 +739,7 @@ decode_intra_mb: | |||||
if(h->intra16x16_pred_mode < 0) | if(h->intra16x16_pred_mode < 0) | ||||
return -1; | return -1; | ||||
} | } | ||||
if(CHROMA){ | |||||
if(decode_chroma){ | |||||
pred_mode= ff_h264_check_intra_pred_mode(h, get_ue_golomb_31(&s->gb)); | pred_mode= ff_h264_check_intra_pred_mode(h, get_ue_golomb_31(&s->gb)); | ||||
if(pred_mode < 0) | if(pred_mode < 0) | ||||
return -1; | return -1; | ||||
@@ -896,15 +967,19 @@ decode_intra_mb: | |||||
if(!IS_INTRA16x16(mb_type)){ | if(!IS_INTRA16x16(mb_type)){ | ||||
cbp= get_ue_golomb(&s->gb); | 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]; | if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp[cbp]; | ||||
else cbp= golomb_to_inter_cbp [cbp]; | else cbp= golomb_to_inter_cbp [cbp]; | ||||
}else{ | }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]; | if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp_gray[cbp]; | ||||
else cbp= golomb_to_inter_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; | s->current_picture.mb_type[mb_xy]= mb_type; | ||||
if(cbp || IS_INTRA16x16(mb_type)){ | if(cbp || IS_INTRA16x16(mb_type)){ | ||||
int i8x8, i4x4, chroma_idx; | |||||
int i4x4, chroma_idx; | |||||
int dquant; | int dquant; | ||||
int ret; | |||||
GetBitContext *gb= IS_INTRA(mb_type) ? h->intra_gb_ptr : h->inter_gb_ptr; | GetBitContext *gb= IS_INTRA(mb_type) ? h->intra_gb_ptr : h->inter_gb_ptr; | ||||
const uint8_t *scan, *scan8x8; | const uint8_t *scan, *scan8x8; | ||||
const int max_qp = 51 + 6*(h->sps.bit_depth_luma-8); | 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[0]= get_chroma_qp(h, 0, s->qscale); | ||||
h->chroma_qp[1]= get_chroma_qp(h, 1, 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++){ | 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; | return -1; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
}else{ | }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{ | }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; | s->current_picture.qscale_table[mb_xy]= s->qscale; | ||||
write_back_non_zero_count(h); | 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; | 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); | ff_h264_filter_mb(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize); | ||||
return; | return; | ||||
} | } | ||||
@@ -353,9 +353,10 @@ static int check_mv(H264Context *h, long b_idx, long bn_idx, int mvy_limit){ | |||||
return v; | 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; | MpegEncContext * const s = &h->s; | ||||
int edge; | int edge; | ||||
int chroma_qp_avg[2]; | |||||
const int mbm_xy = dir == 0 ? mb_xy -1 : h->top_mb_xy; | 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; | 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[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]); | bS[3]= 1+((h->cbp_table[mbn_xy] & 8)||h->non_zero_count_cache[scan8[0]+3]); | ||||
}else{ | }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; | int i; | ||||
for( i = 0; i < 4; i++ ) { | for( i = 0; i < 4; i++ ) { | ||||
bS[i] = 1 + !!(h->non_zero_count_cache[scan8[0]+i] | mbn_nnz[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); | 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"); } | { 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_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{ | }else{ | ||||
DECLARE_ALIGNED(8, int16_t, bS)[4]; | 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, 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); | 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"); } | //{ 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 ) { | if( dir == 0 ) { | ||||
filter_mb_edgev( &img_y[0], linesize, bS, qp, h ); | 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 { | } else { | ||||
filter_mb_edgeh( &img_y[0], linesize, bS, qp, h ); | 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"); } | //{ int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); } | ||||
if( dir == 0 ) { | if( dir == 0 ) { | ||||
filter_mb_edgev( &img_y[4*edge << h->pixel_shift], linesize, bS, qp, h ); | 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_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); | filter_mb_edgecv( &img_cr[2*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[1], h); | ||||
} | } | ||||
} else { | } else { | ||||
filter_mb_edgeh( &img_y[4*edge*linesize], linesize, bS, qp, h ); | 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_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); | 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 { | } else { | ||||
static const uint8_t offset[2][2][8]={ | 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]; | 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 | #if CONFIG_SMALL | ||||
for( dir = 0; dir < 2; dir++ ) | 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 | #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 | #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[0] : default_scaling4[0], | ||||
fallback_sps ? sps->scaling_matrix4[3] : default_scaling4[1], | fallback_sps ? sps->scaling_matrix4[3] : default_scaling4[1], | ||||
fallback_sps ? sps->scaling_matrix8[0] : default_scaling8[0], | 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)){ | if(get_bits1(&s->gb)){ | ||||
sps->scaling_matrix_present |= is_sps; | 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 | decode_scaling_list(h,scaling_matrix4[5],16,default_scaling4[1],scaling_matrix4[4]); // Inter, Cb | ||||
if(is_sps || pps->transform_8x8_mode){ | 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[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){ | 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"); | 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"); | av_log(h->s.avctx, AV_LOG_ERROR, "brainfart cropping not supported, this could look slightly wrong ...\n"); | ||||
} | } | ||||
}else{ | }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_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_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_luma_dc_dequant_idct)(DCTELEM *output, DCTELEM *input/*align 16*/, int qmul); | ||||
void (*h264_chroma_dc_dequant_idct)(DCTELEM *block, int qmul); | void (*h264_chroma_dc_dequant_idct)(DCTELEM *block, int qmul); | ||||
}H264DSPContext; | }H264DSPContext; | ||||
@@ -30,15 +30,19 @@ | |||||
#ifndef AVCODEC_H264IDCT_INTERNAL_H | #ifndef AVCODEC_H264IDCT_INTERNAL_H | ||||
#define 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 | //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 | #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; | int i; | ||||
for(i=0; i<16; i++){ | for(i=0; i<16; i++){ | ||||
int nnz = nnzc[ scan8[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; | int i; | ||||
for(i=0; i<16; 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); | 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; | int i; | ||||
for(i=0; i<16; i+=4){ | for(i=0; i<16; i+=4){ | ||||
int nnz = nnzc[ scan8[i] ]; | 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->current_picture.reference | ||||
&& !s->intra_only | && !s->intra_only | ||||
&& !(s->flags&CODEC_FLAG_EMU_EDGE)) { | && !(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->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->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->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(); | emms_c(); | ||||
@@ -2284,14 +2286,19 @@ void ff_draw_horiz_band(MpegEncContext *s, int y, int h){ | |||||
&& !s->intra_only | && !s->intra_only | ||||
&& !(s->flags&CODEC_FLAG_EMU_EDGE)) { | && !(s->flags&CODEC_FLAG_EMU_EDGE)) { | ||||
int sides = 0, edge_h; | 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==0) sides |= EDGE_TOP; | ||||
if (y + h >= s->v_edge_pos) sides |= EDGE_BOTTOM; | if (y + h >= s->v_edge_pos) sides |= EDGE_BOTTOM; | ||||
edge_h= FFMIN(h, s->v_edge_pos - y); | 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); | h= FFMIN(h, s->avctx->height - y); | ||||
@@ -1978,13 +1978,13 @@ static int frame_start(SnowContext *s){ | |||||
if(s->current_picture.data[0]){ | if(s->current_picture.data[0]){ | ||||
s->dsp.draw_edges(s->current_picture.data[0], | s->dsp.draw_edges(s->current_picture.data[0], | ||||
s->current_picture.linesize[0], w , h , | 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->dsp.draw_edges(s->current_picture.data[1], | ||||
s->current_picture.linesize[1], w>>1, h>>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->dsp.draw_edges(s->current_picture.data[2], | ||||
s->current_picture.linesize[2], w>>1, h>>1, | 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); | 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 | /* draw the edges of width 'w' of an image of size width, height | ||||
this mmx version can only handle w==8 || w==16 */ | 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; | uint8_t *ptr, *last_line; | ||||
int i; | 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) */ | /* top and bottom (and hopefully also the corners) */ | ||||
if (sides&EDGE_TOP) { | if (sides&EDGE_TOP) { | ||||
for(i = 0; i < w; i += 4) { | |||||
for(i = 0; i < h; i += 4) { | |||||
ptr= buf - (i + 1) * wrap - w; | ptr= buf - (i + 1) * wrap - w; | ||||
__asm__ volatile( | __asm__ volatile( | ||||
"1: \n\t" | "1: \n\t" | ||||
@@ -36,7 +36,7 @@ | |||||
#if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) | #if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) | ||||
static int decode_significance_x86(CABACContext *c, int max_coeff, | static int decode_significance_x86(CABACContext *c, int max_coeff, | ||||
uint8_t *significant_coeff_ctx_base, | uint8_t *significant_coeff_ctx_base, | ||||
int *index){ | |||||
int *index, int last_off){ | |||||
void *end= significant_coeff_ctx_base + max_coeff - 1; | void *end= significant_coeff_ctx_base + max_coeff - 1; | ||||
int minusstart= -(int)significant_coeff_ctx_base; | int minusstart= -(int)significant_coeff_ctx_base; | ||||
int minusindex= 4-(int)index; | int minusindex= 4-(int)index; | ||||
@@ -52,10 +52,12 @@ static int decode_significance_x86(CABACContext *c, int max_coeff, | |||||
"test $1, %%edx \n\t" | "test $1, %%edx \n\t" | ||||
" jz 3f \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") | "%%bx", "%%esi", "%%eax", "%%al") | ||||
"sub %7, %1 \n\t" | |||||
"mov %2, %%"REG_a" \n\t" | "mov %2, %%"REG_a" \n\t" | ||||
"movl %4, %%ecx \n\t" | "movl %4, %%ecx \n\t" | ||||
"add %1, %%"REG_c" \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 %%esi, "RANGE "(%3) \n\t" | ||||
"movl %%ebx, "LOW "(%3) \n\t" | "movl %%ebx, "LOW "(%3) \n\t" | ||||
:"=&a"(coeff_count), "+r"(significant_coeff_ctx_base), "+m"(index) | :"=&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" | : "%"REG_c, "%ebx", "%edx", "%esi", "memory" | ||||
); | ); | ||||
return coeff_count; | 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, | static int decode_significance_8x8_x86(CABACContext *c, | ||||
uint8_t *significant_coeff_ctx_base, | 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 minusindex= 4-(int)index; | ||||
int coeff_count; | int coeff_count; | ||||
x86_reg last=0; | 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" | "movzbl "MANGLE(last_coeff_flag_offset_8x8)"(%%edi), %%edi\n\t" | ||||
"add %5, %%"REG_D" \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") | "%%bx", "%%esi", "%%eax", "%%al") | ||||
"mov %2, %%"REG_a" \n\t" | "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 %%esi, "RANGE "(%3) \n\t" | ||||
"movl %%ebx, "LOW "(%3) \n\t" | "movl %%ebx, "LOW "(%3) \n\t" | ||||
:"=&a"(coeff_count),"+m"(last), "+m"(index) | :"=&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" | : "%"REG_c, "%ebx", "%edx", "%esi", "%"REG_D, "memory" | ||||
); | ); | ||||
return coeff_count; | return coeff_count; | ||||
@@ -32,14 +32,18 @@ | |||||
SECTION_RODATA | SECTION_RODATA | ||||
; FIXME this table is a duplicate from h264data.h, and will be removed once the tables from, h264 have been split | ; 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 | %ifdef PIC | ||||
%define scan8 r11 | %define scan8 r11 | ||||
%else | %else | ||||
@@ -617,6 +621,8 @@ cglobal h264_idct_add8_8_mmx, 5, 7, 0 | |||||
mov r10, r0 | mov r10, r0 | ||||
%endif | %endif | ||||
call h264_idct_add8_mmx_plane | call h264_idct_add8_mmx_plane | ||||
mov r5, 32 | |||||
add r2, 384 | |||||
%ifdef ARCH_X86_64 | %ifdef ARCH_X86_64 | ||||
add r10, gprsize | add r10, gprsize | ||||
%else | %else | ||||
@@ -678,6 +684,8 @@ cglobal h264_idct_add8_8_mmx2, 5, 7, 0 | |||||
lea r11, [scan8_mem] | lea r11, [scan8_mem] | ||||
%endif | %endif | ||||
call h264_idct_add8_mmx2_plane | call h264_idct_add8_mmx2_plane | ||||
mov r5, 32 | |||||
add r2, 384 | |||||
%ifdef ARCH_X86_64 | %ifdef ARCH_X86_64 | ||||
add r10, gprsize | add r10, gprsize | ||||
%else | %else | ||||
@@ -810,12 +818,12 @@ cglobal h264_idct_add16intra_8_sse2, 5, 7, 8 | |||||
test r0, r0 | test r0, r0 | ||||
jz .try%1dc | jz .try%1dc | ||||
%ifdef ARCH_X86_64 | %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] | add r0, [r10] | ||||
%else | %else | ||||
mov r0, r0m | mov r0, r0m | ||||
mov r0, [r0] | mov r0, [r0] | ||||
add r0, dword [r1+%1*8+64] | |||||
add r0, dword [r1+(%1&1)*8+64*(1+(%1>>1))] | |||||
%endif | %endif | ||||
call x264_add8x4_idct_sse2 | call x264_add8x4_idct_sse2 | ||||
jmp .cycle%1end | jmp .cycle%1end | ||||
@@ -824,16 +832,18 @@ cglobal h264_idct_add16intra_8_sse2, 5, 7, 8 | |||||
or r0w, word [r2+32] | or r0w, word [r2+32] | ||||
jz .cycle%1end | jz .cycle%1end | ||||
%ifdef ARCH_X86_64 | %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] | add r0, [r10] | ||||
%else | %else | ||||
mov r0, r0m | mov r0, r0m | ||||
mov r0, [r0] | mov r0, [r0] | ||||
add r0, dword [r1+%1*8+64] | |||||
add r0, dword [r1+(%1&1)*8+64*(1+(%1>>1))] | |||||
%endif | %endif | ||||
call h264_idct_dc_add8_mmx2 | call h264_idct_dc_add8_mmx2 | ||||
.cycle%1end | .cycle%1end | ||||
%if %1 < 3 | |||||
%if %1 == 1 | |||||
add r2, 384+64 | |||||
%elif %1 < 3 | |||||
add r2, 64 | add r2, 64 | ||||
%endif | %endif | ||||
%endmacro | %endmacro | ||||
@@ -845,15 +855,15 @@ cglobal h264_idct_add8_8_sse2, 5, 7, 8 | |||||
%ifdef ARCH_X86_64 | %ifdef ARCH_X86_64 | ||||
mov r10, r0 | mov r10, r0 | ||||
%endif | %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 | %ifdef ARCH_X86_64 | ||||
add r10, gprsize | add r10, gprsize | ||||
%else | %else | ||||
add r0mp, gprsize | add r0mp, gprsize | ||||
%endif | %endif | ||||
add8_sse2_cycle 2, 0x21 | |||||
add8_sse2_cycle 3, 0x29 | |||||
add8_sse2_cycle 2, 0x5c | |||||
add8_sse2_cycle 3, 0x64 | |||||
RET | RET | ||||
;void ff_h264_luma_dc_dequant_idct_mmx(DCTELEM *output, DCTELEM *input, int qmul) | ;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) | pw_pixel_max: times 8 dw ((1 << 10)-1) | ||||
pd_32: times 4 dd 32 | 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 | %ifdef PIC | ||||
%define scan8 r11 | %define scan8 r11 | ||||
@@ -306,7 +310,7 @@ INIT_AVX | |||||
IDCT_ADD16INTRA_10 avx | IDCT_ADD16INTRA_10 avx | ||||
%endif | %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]) | ; 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 | %endif | ||||
add r2, 1024 | add r2, 1024 | ||||
mov r0, [r0] | 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 | %ifdef ARCH_X86_64 | ||||
mov r0, [r10+gprsize] | mov r0, [r10+gprsize] | ||||
%else | %else | ||||
mov r0, r0m | mov r0, r0m | ||||
mov r0, [r0+gprsize] | mov r0, [r0+gprsize] | ||||
%endif | %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 | REP_RET | ||||
AC %1, 16 | AC %1, 16 | ||||
AC %1, 18 | AC %1, 18 | ||||
AC %1, 20 | |||||
AC %1, 22 | |||||
AC %1, 32 | |||||
AC %1, 34 | |||||
%endmacro ; IDCT_ADD8 | %endmacro ; IDCT_ADD8 | ||||