dsputil: allow to skip drawing of top/bottom edges.

oldabi
Alexander Strange 14 years ago committed by Ronald S. Bultje
parent c56e618b4b
commit 1500be13f2
  1. 25
      libavcodec/dsputil.c
  2. 4
      libavcodec/dsputil.h
  3. 12
      libavcodec/mpegvideo.c
  4. 12
      libavcodec/snow.c
  5. 69
      libavcodec/x86/dsputil_mmx.c

@ -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 */ /* 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 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; uint8_t *ptr, *last_line;
int i; 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 */ /* left and right */
ptr = buf; ptr = buf;
for(i=0;i<height;i++) { 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); memset(ptr + width, ptr[width-1], w);
ptr += wrap; ptr += wrap;
} }
/* corners */
for(i=0;i<w;i++) { /* top and bottom + corners */
memset(buf - (i + 1) * wrap - w, buf[0], w); /* top left */ buf -= w;
memset(buf - (i + 1) * wrap + width, buf[width-1], w); /* top right */ last_line = buf + (height - 1) * wrap;
memset(last_line + (i + 1) * wrap - w, last_line[0], w); /* top left */ if (sides & EDGE_TOP)
memset(last_line + (i + 1) * wrap + width, last_line[width-1], w); /* top right */ 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 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); void (*draw_edges)(uint8_t *buf, int wrap, int width, int height, int w, int sides);
#define EDGE_WIDTH 16 #define EDGE_WIDTH 16
#define EDGE_TOP 1
#define EDGE_BOTTOM 2
void (*prefetch)(void *mem, int stride, int h); void (*prefetch)(void *mem, int stride, int h);

@ -1067,9 +1067,15 @@ 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)) {
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[0], s->linesize ,
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->h_edge_pos , s->v_edge_pos ,
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_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(); emms_c();

@ -1976,9 +1976,15 @@ static int frame_start(SnowContext *s){
int h= s->avctx->height; int h= s->avctx->height;
if(s->current_picture.data[0]){ 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[0],
s->dsp.draw_edges(s->current_picture.data[1], s->current_picture.linesize[1], w>>1, h>>1, EDGE_WIDTH/2); s->current_picture.linesize[0], w , h ,
s->dsp.draw_edges(s->current_picture.data[2], s->current_picture.linesize[2], w>>1, h>>1, EDGE_WIDTH/2); 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); 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 /* 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) static void draw_edges_mmx(uint8_t *buf, int wrap, int width, int height, int w, int sides)
{ {
uint8_t *ptr, *last_line; uint8_t *ptr, *last_line;
int i; 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) */
/* top and bottom (and hopefully also the corners) */ if (sides&EDGE_TOP) {
ptr= buf - (i + 1) * wrap - w; for(i = 0; i < w; i += 4) {
__asm__ volatile( ptr= buf - (i + 1) * wrap - w;
"1: \n\t" __asm__ volatile(
"movq (%1, %0), %%mm0 \n\t" "1: \n\t"
"movq %%mm0, (%0) \n\t" "movq (%1, %0), %%mm0 \n\t"
"movq %%mm0, (%0, %2) \n\t" "movq %%mm0, (%0) \n\t"
"movq %%mm0, (%0, %2, 2) \n\t" "movq %%mm0, (%0, %2) \n\t"
"movq %%mm0, (%0, %3) \n\t" "movq %%mm0, (%0, %2, 2) \n\t"
"add $8, %0 \n\t" "movq %%mm0, (%0, %3) \n\t"
"cmp %4, %0 \n\t" "add $8, %0 \n\t"
" jb 1b \n\t" "cmp %4, %0 \n\t"
: "+r" (ptr) " jb 1b \n\t"
: "r" ((x86_reg)buf - (x86_reg)ptr - w), "r" ((x86_reg)-wrap), "r" ((x86_reg)-wrap*3), "r" (ptr+width+2*w) : "+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" if (sides&EDGE_BOTTOM) {
"movq %%mm0, (%0, %2) \n\t" for(i = 0; i < w; i += 4) {
"movq %%mm0, (%0, %2, 2) \n\t" ptr= last_line + (i + 1) * wrap - w;
"movq %%mm0, (%0, %3) \n\t" __asm__ volatile(
"add $8, %0 \n\t" "1: \n\t"
"cmp %4, %0 \n\t" "movq (%1, %0), %%mm0 \n\t"
" jb 1b \n\t" "movq %%mm0, (%0) \n\t"
: "+r" (ptr) "movq %%mm0, (%0, %2) \n\t"
: "r" ((x86_reg)last_line - (x86_reg)ptr - w), "r" ((x86_reg)wrap), "r" ((x86_reg)wrap*3), "r" (ptr+width+2*w) "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)
);
}
} }
} }

Loading…
Cancel
Save