Commit c9c49387 authored by Jason Garrett-Glaser's avatar Jason Garrett-Glaser

4:4:4 H.264 decoding support

Note: this is 4:4:4 from the 2007 spec revision, not the previous (now deprecated) 4:4:4 mode in H.264.
parent 25f05ddb
......@@ -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
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment