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 | |||