static void draw_slice_g400(uint8_t *image[], int stride[], int w,int h,int x,int y) { uint8_t *dest; uint8_t *dest2; uint32_t bespitch,bespitch2; bespitch = (mga_vid_config.src_width + 31) & ~31; bespitch2 = bespitch/2; dest = vid_data + bespitch * y + x; mem2agpcpy_pic(dest, image[0], w, h, bespitch, stride[0]); w/=2;h/=2;x/=2;y/=2; dest = vid_data + bespitch*mga_vid_config.src_height + bespitch2 * y + x; dest2= dest + bespitch2*mga_vid_config.src_height / 2; if(mga_vid_config.format==MGA_VID_FORMAT_YV12){ // mga_vid's YV12 assumes Y,U,V order (insteda of Y,V,U) :( mem2agpcpy_pic(dest, image[1], w, h, bespitch2, stride[1]); mem2agpcpy_pic(dest2,image[2], w, h, bespitch2, stride[2]); } else { mem2agpcpy_pic(dest, image[2], w, h, bespitch2, stride[2]); mem2agpcpy_pic(dest2,image[1], w, h, bespitch2, stride[1]); } }
static int draw_slice(uint8_t *i[], int s[], int w, int h, int x, int y) { /* We want to render to the YUV to the input page + the location * of the stripes we're doing */ reg_YUV->yuvBaseAddr = inpageoffset + in_width * in_depth * y + x; reg_YUV->yuvStride = in_width * in_depth; /* Put the YUV channels into the voodoos internal combiner unit * thingie */ mem2agpcpy_pic(YUV->Y, i[0], s[0], h , YUV_STRIDE, s[0]); mem2agpcpy_pic(YUV->U, i[1], s[1], h / 2, YUV_STRIDE, s[1]); mem2agpcpy_pic(YUV->V, i[2], s[2], h / 2, YUV_STRIDE, s[2]); return 0; }
static int draw_frame(uint8_t * src[]) { int numlines = vo_dga_lines; char *s, *d; s = *src; d = CURRENT_VIDEO_BUFFER.data + vo_dga_vp_offset; mem2agpcpy_pic(d, s, vo_dga_bytes_per_line, numlines, vo_dga_bytes_per_line + vo_dga_vp_skip, vo_dga_bytes_per_line); // DBG-COde #if 0 d = CURRENT_VIDEO_BUFFER.data + vo_dga_vp_offset; fillblock(d, 0, 10, 0x800000ff); fillblock(d, 10, 10, 0x8000ff00); fillblock(d, 20, 10, 0x80ff0000); fillblock(d, 30, 10, 0xff0000ff); fillblock(d, 40, 10, 0x800000ff); fillblock(d, 50, 10, 0x0f0000ff); #endif return 0; }
static int draw_slice(uint8_t *image[], int stride[], int w,int h,int x,int y) { uint8_t* ptr[3]; #ifdef VERBOSE printf("Draw slices %d\n",current_buffer); #endif switch(img_fmt) { case IMGFMT_YUY2: case IMGFMT_UYVY: case IMGFMT_BGR8: case IMGFMT_BGR16: case IMGFMT_BGR24: case IMGFMT_BGR32: // copy :( to agp_mem // still faster than tdfxfb wich directly copy to the video mem :) mem2agpcpy_pic(agp_mem + current_buffer * buffer_size + y*buffer_stride[0] + x * src_bpp, image[0], src_bpp*w,h,buffer_stride[0],stride[0]); return 0; case IMGFMT_YV12: case IMGFMT_I420: // Copy to agp mem ptr[0] = agp_mem + current_buffer * buffer_size; mem2agpcpy_pic(ptr[0] + y * buffer_stride[0] + x,image[0],w,h, buffer_stride[0],stride[0]); ptr[1] = ptr[0] + (src_height*src_width); mem2agpcpy_pic(ptr[1] + y/2 * buffer_stride[1] + x/2,image[1],w/2,h/2, buffer_stride[1],stride[1]); ptr[2] = ptr[1] + (src_height*src_width/4); mem2agpcpy_pic(ptr[2] + y/2 * buffer_stride[2] + x/2,image[2],w/2,h/2, buffer_stride[2],stride[2]); return 0; } return 1; }
static void draw_slice_g200(uint8_t *image[], int stride[], int width,int height,int x,int y) { uint8_t *dest; uint32_t bespitch = (mga_vid_config.src_width + 31) & ~31; dest = vid_data + bespitch*y + x; mem2agpcpy_pic(dest, image[0], width, height, bespitch, stride[0]); width/=2;height/=2;x/=2;y/=2; dest = vid_data + bespitch*mga_vid_config.src_height + bespitch*y + 2*x; interleaveBytes(image[1],image[2],dest, width, height, stride[1], stride[2], bespitch); }
static uint32_t draw_image(mp_image_t *mpi){ uint32_t bespitch = (mga_vid_config.src_width + 31) & ~31; // if -dr or -slices then do nothing: if(mpi->flags&(MP_IMGFLAG_DIRECT|MP_IMGFLAG_DRAW_CALLBACK)) return VO_TRUE; if(mpi->flags&MP_IMGFLAG_PLANAR){ // copy planar: draw_slice(mpi->planes,mpi->stride,mpi->w,mpi->h,mpi->x,mpi->y); } else { // copy packed: mem2agpcpy_pic(vid_data, mpi->planes[0], // dst,src mpi->w*(mpi->bpp/8), mpi->h, // w,h bespitch*2, mpi->stride[0]); // dstride,sstride } return VO_TRUE; }
static uint32_t draw_image(mp_image_t *mpi){ int buf = 0; tdfx_vid_agp_move_t mov; tdfx_vid_yuv_t yuv; int p; uint8_t* planes[3]; #ifdef VERBOSE printf("Draw image %d\n",buf); #endif if(mpi->flags & MP_IMGFLAG_DIRECT) buf = (int)mpi->priv; switch(mpi->imgfmt) { case IMGFMT_YUY2: case IMGFMT_UYVY: case IMGFMT_BGR8: case IMGFMT_BGR15: case IMGFMT_BGR16: case IMGFMT_BGR24: case IMGFMT_BGR32: if(!(mpi->flags&(MP_IMGFLAG_DIRECT|MP_IMGFLAG_DRAW_CALLBACK))) { // copy to agp_mem #ifdef VERBOSE printf("Memcpy\n"); #endif planes[0] = agp_mem + buf * buffer_size; mem2agpcpy_pic(planes[0],mpi->planes[0],src_bpp*mpi->width,mpi->height, buffer_stride[0],mpi->stride[0]); } else planes[0] = agp_mem + buf * buffer_size; mov.move2 = TDFX_VID_MOVE_2_PACKED; mov.width = mpi->width*((mpi->bpp+7)/8); mov.height = mpi->height; mov.src = planes[0] - agp_mem; mov.src_stride = buffer_stride[0]; mov.dst = back_buffer; mov.dst_stride = src_stride; if(ioctl(tdfx_fd,TDFX_VID_AGP_MOVE,&mov)) mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_AgpMoveFailed); break; case IMGFMT_YV12: case IMGFMT_I420: if(!(mpi->flags&(MP_IMGFLAG_DIRECT|MP_IMGFLAG_DRAW_CALLBACK))) { // Copy to agp mem #ifdef VERBOSE printf("Memcpy\n"); #endif planes[0] = agp_mem + buf * buffer_size; memcpy_pic(planes[0],mpi->planes[0],mpi->width,mpi->height, buffer_stride[0],mpi->stride[0]); planes[1] = planes[0] + (mpi->height*mpi->stride[0]); memcpy_pic(planes[1],mpi->planes[1],mpi->chroma_width,mpi->chroma_height, buffer_stride[1],mpi->stride[1]); planes[2] = planes[1] + (mpi->chroma_height*mpi->stride[1]); memcpy_pic(planes[2],mpi->planes[2],mpi->chroma_width,mpi->chroma_height, buffer_stride[2],mpi->stride[2]); } else { planes[0] = agp_mem + buf * buffer_size; planes[1] = planes[0] + buffer_stride[0] * src_height; planes[2] = planes[1] + buffer_stride[1] * src_height/2; } // Setup the yuv thing yuv.base = back_buffer; yuv.stride = src_stride; if(ioctl(tdfx_fd,TDFX_VID_SET_YUV,&yuv)) { mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_SetYuvFailed); break; } // Now agp move that // Y mov.move2 = TDFX_VID_MOVE_2_YUV; mov.width = mpi->width; mov.height = mpi->height; mov.src = planes[0] - agp_mem; mov.src_stride = buffer_stride[0]; mov.dst = 0x0; mov.dst_stride = TDFX_VID_YUV_STRIDE; if(ioctl(tdfx_fd,TDFX_VID_AGP_MOVE,&mov)) { mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_AgpMoveFailedOnYPlane); break; } //return 0; // U p = mpi->imgfmt == IMGFMT_YV12 ? 1 : 2; mov.width = mpi->chroma_width; mov.height = mpi->chroma_height; mov.src = planes[p] - agp_mem; mov.src_stride = buffer_stride[p]; mov.dst += TDFX_VID_YUV_PLANE_SIZE; if(ioctl(tdfx_fd,TDFX_VID_AGP_MOVE,&mov)) { mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_AgpMoveFailedOnUPlane); break; } // V p = mpi->imgfmt == IMGFMT_YV12 ? 2 : 1; mov.src = planes[p] - agp_mem; mov.src_stride = buffer_stride[p]; mov.dst += TDFX_VID_YUV_PLANE_SIZE; if(ioctl(tdfx_fd,TDFX_VID_AGP_MOVE,&mov)) { mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_AgpMoveFailedOnVPlane); break; } break; default: mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TDFXVID_UnknownFormat,mpi->imgfmt); return VO_TRUE; } return VO_TRUE; }