| @@ -298,17 +298,11 @@ static int sse16_c(void *v, uint8_t *pix1, uint8_t *pix2, int line_size, int h) | |||
| /* draw the edges of width 'w' of an image of size width, height */ | |||
| //FIXME check that this is ok for mpeg4 interlaced | |||
| static void draw_edges_c(uint8_t *buf, int wrap, int width, int height, int w) | |||
| static void draw_edges_c(uint8_t *buf, int wrap, int width, int height, int w, int sides) | |||
| { | |||
| uint8_t *ptr, *last_line; | |||
| int i; | |||
| last_line = buf + (height - 1) * wrap; | |||
| for(i=0;i<w;i++) { | |||
| /* top and bottom */ | |||
| memcpy(buf - (i + 1) * wrap, buf, width); | |||
| memcpy(last_line + (i + 1) * wrap, last_line, width); | |||
| } | |||
| /* left and right */ | |||
| ptr = buf; | |||
| for(i=0;i<height;i++) { | |||
| @@ -316,13 +310,16 @@ static void draw_edges_c(uint8_t *buf, int wrap, int width, int height, int w) | |||
| memset(ptr + width, ptr[width-1], w); | |||
| ptr += wrap; | |||
| } | |||
| /* corners */ | |||
| for(i=0;i<w;i++) { | |||
| memset(buf - (i + 1) * wrap - w, buf[0], w); /* top left */ | |||
| memset(buf - (i + 1) * wrap + width, buf[width-1], w); /* top right */ | |||
| memset(last_line + (i + 1) * wrap - w, last_line[0], w); /* top left */ | |||
| memset(last_line + (i + 1) * wrap + width, last_line[width-1], w); /* top right */ | |||
| } | |||
| /* top and bottom + corners */ | |||
| buf -= w; | |||
| last_line = buf + (height - 1) * wrap; | |||
| if (sides & EDGE_TOP) | |||
| for(i = 0; i < w; i++) | |||
| memcpy(buf - (i + 1) * wrap, buf, width + w + w); // top | |||
| if (sides & EDGE_BOTTOM) | |||
| for (i = 0; i < w; i++) | |||
| memcpy(last_line + (i + 1) * wrap, last_line, width + w + w); // bottom | |||
| } | |||
| /** | |||
| @@ -492,8 +492,10 @@ 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); | |||
| void (*draw_edges)(uint8_t *buf, int wrap, int width, int height, int w, int sides); | |||
| #define EDGE_WIDTH 16 | |||
| #define EDGE_TOP 1 | |||
| #define EDGE_BOTTOM 2 | |||
| void (*prefetch)(void *mem, int stride, int h); | |||
| @@ -1067,9 +1067,15 @@ void MPV_frame_end(MpegEncContext *s) | |||
| && s->current_picture.reference | |||
| && !s->intra_only | |||
| && !(s->flags&CODEC_FLAG_EMU_EDGE)) { | |||
| s->dsp.draw_edges(s->current_picture.data[0], s->linesize , s->h_edge_pos , s->v_edge_pos , EDGE_WIDTH ); | |||
| s->dsp.draw_edges(s->current_picture.data[1], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2); | |||
| s->dsp.draw_edges(s->current_picture.data[2], s->uvlinesize, s->h_edge_pos>>1, s->v_edge_pos>>1, EDGE_WIDTH/2); | |||
| 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->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->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); | |||
| } | |||
| emms_c(); | |||
| @@ -1976,9 +1976,15 @@ static int frame_start(SnowContext *s){ | |||
| int h= s->avctx->height; | |||
| if(s->current_picture.data[0]){ | |||
| s->dsp.draw_edges(s->current_picture.data[0], s->current_picture.linesize[0], w , h , EDGE_WIDTH ); | |||
| s->dsp.draw_edges(s->current_picture.data[1], s->current_picture.linesize[1], w>>1, h>>1, EDGE_WIDTH/2); | |||
| s->dsp.draw_edges(s->current_picture.data[2], s->current_picture.linesize[2], w>>1, h>>1, EDGE_WIDTH/2); | |||
| s->dsp.draw_edges(s->current_picture.data[0], | |||
| s->current_picture.linesize[0], w , h , | |||
| 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); | |||
| 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); | |||
| } | |||
| release_buffer(s->avctx); | |||
| @@ -783,7 +783,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) | |||
| static void draw_edges_mmx(uint8_t *buf, int wrap, int width, int height, int w, int sides) | |||
| { | |||
| uint8_t *ptr, *last_line; | |||
| int i; | |||
| @@ -836,36 +836,43 @@ static void draw_edges_mmx(uint8_t *buf, int wrap, int width, int height, int w) | |||
| ); | |||
| } | |||
| for(i=0;i<w;i+=4) { | |||
| /* top and bottom (and hopefully also the corners) */ | |||
| ptr= buf - (i + 1) * wrap - w; | |||
| __asm__ volatile( | |||
| "1: \n\t" | |||
| "movq (%1, %0), %%mm0 \n\t" | |||
| "movq %%mm0, (%0) \n\t" | |||
| "movq %%mm0, (%0, %2) \n\t" | |||
| "movq %%mm0, (%0, %2, 2) \n\t" | |||
| "movq %%mm0, (%0, %3) \n\t" | |||
| "add $8, %0 \n\t" | |||
| "cmp %4, %0 \n\t" | |||
| " jb 1b \n\t" | |||
| : "+r" (ptr) | |||
| : "r" ((x86_reg)buf - (x86_reg)ptr - w), "r" ((x86_reg)-wrap), "r" ((x86_reg)-wrap*3), "r" (ptr+width+2*w) | |||
| ); | |||
| ptr= last_line + (i + 1) * wrap - w; | |||
| __asm__ volatile( | |||
| "1: \n\t" | |||
| "movq (%1, %0), %%mm0 \n\t" | |||
| "movq %%mm0, (%0) \n\t" | |||
| "movq %%mm0, (%0, %2) \n\t" | |||
| "movq %%mm0, (%0, %2, 2) \n\t" | |||
| "movq %%mm0, (%0, %3) \n\t" | |||
| "add $8, %0 \n\t" | |||
| "cmp %4, %0 \n\t" | |||
| " jb 1b \n\t" | |||
| : "+r" (ptr) | |||
| : "r" ((x86_reg)last_line - (x86_reg)ptr - w), "r" ((x86_reg)wrap), "r" ((x86_reg)wrap*3), "r" (ptr+width+2*w) | |||
| ); | |||
| /* top and bottom (and hopefully also the corners) */ | |||
| if (sides&EDGE_TOP) { | |||
| for(i = 0; i < w; i += 4) { | |||
| ptr= buf - (i + 1) * wrap - w; | |||
| __asm__ volatile( | |||
| "1: \n\t" | |||
| "movq (%1, %0), %%mm0 \n\t" | |||
| "movq %%mm0, (%0) \n\t" | |||
| "movq %%mm0, (%0, %2) \n\t" | |||
| "movq %%mm0, (%0, %2, 2) \n\t" | |||
| "movq %%mm0, (%0, %3) \n\t" | |||
| "add $8, %0 \n\t" | |||
| "cmp %4, %0 \n\t" | |||
| " jb 1b \n\t" | |||
| : "+r" (ptr) | |||
| : "r" ((x86_reg)buf - (x86_reg)ptr - w), "r" ((x86_reg)-wrap), "r" ((x86_reg)-wrap*3), "r" (ptr+width+2*w) | |||
| ); | |||
| } | |||
| } | |||
| if (sides&EDGE_BOTTOM) { | |||
| for(i = 0; i < w; i += 4) { | |||
| ptr= last_line + (i + 1) * wrap - w; | |||
| __asm__ volatile( | |||
| "1: \n\t" | |||
| "movq (%1, %0), %%mm0 \n\t" | |||
| "movq %%mm0, (%0) \n\t" | |||
| "movq %%mm0, (%0, %2) \n\t" | |||
| "movq %%mm0, (%0, %2, 2) \n\t" | |||
| "movq %%mm0, (%0, %3) \n\t" | |||
| "add $8, %0 \n\t" | |||
| "cmp %4, %0 \n\t" | |||
| " jb 1b \n\t" | |||
| : "+r" (ptr) | |||
| : "r" ((x86_reg)last_line - (x86_reg)ptr - w), "r" ((x86_reg)wrap), "r" ((x86_reg)wrap*3), "r" (ptr+width+2*w) | |||
| ); | |||
| } | |||
| } | |||
| } | |||