// // Vertical resizing // Resized one plane also //_______________________________ void AVDMVideoStreamResize::ResizeV(Image * iin, Image * iout, INT *pattern) { INT *cur = pattern; int fir_filter_width = *cur++; int row_size = iin->width; unsigned char *out = iout->data; unsigned char *srcbuffer = iin->data; unsigned char *base ,*base2; int total; for (uint32_t y = 0; y < iout->height; ++y) { base = srcbuffer + row_size * (*cur++); for (int x = 0; x < row_size; ++x) { total = 0; base2 = base + x; for (int b = 0; b < fir_filter_width; ++b) { total += *base2 * cur[b]; base2 += row_size; } *out++ = ScaledPixelClip(total); } cur += fir_filter_width; } }
//____________________________________ // Perform horizontal resizing // On one plane // Must be called 3 times for RGB or 3 times for YV12 //____________________________________ void AVDMVideoStreamResize::ResizeH(Image * iin, Image * iout, INT *pattern) { unsigned char *base = iin->data; unsigned char *out = iout->data; int src_row_size = iin->width; int dst_row_size = iout->width; uint8_t *ptr; INT *cur; int32_t total; INT ofs; for (uint32_t y = iin->height; y>0; y--) { cur = pattern + 1; for (int x = 0; x < dst_row_size ; x++) { total=0; ofs = *cur++; ptr= &(base[(ofs )]); for (int a = pattern[0];a>0; a--) { total += (*ptr++) * (*cur++); } out[x] = ScaledPixelClip(total); } // next line... base += src_row_size; out += dst_row_size; } }
PVideoFrame __stdcall ConvertToYUY2::GetFrame(int n, IScriptEnvironment* env) { PVideoFrame src = child->GetFrame(n, env); if (((src_cs&VideoInfo::CS_YV12)==VideoInfo::CS_YV12)||((src_cs&VideoInfo::CS_I420)==VideoInfo::CS_I420)) { PVideoFrame dst = env->NewVideoFrame(vi,32); // We need a bit more pitch here. BYTE* yuv = dst->GetWritePtr(); if (interlaced) { //if ((env->GetCPUFlags() & CPUF_INTEGER_SSE)) { isse_yv12_i_to_yuy2(src->GetReadPtr(PLANAR_Y), src->GetReadPtr(PLANAR_U), src->GetReadPtr(PLANAR_V), src->GetRowSize(PLANAR_Y_ALIGNED), src->GetPitch(PLANAR_Y), src->GetPitch(PLANAR_U), yuv, dst->GetPitch() ,src->GetHeight()); /*} else { mmx_yv12_i_to_yuy2(src->GetReadPtr(PLANAR_Y), src->GetReadPtr(PLANAR_U), src->GetReadPtr(PLANAR_V), src->GetRowSize(PLANAR_Y_ALIGNED), src->GetPitch(PLANAR_Y), src->GetPitch(PLANAR_U), yuv, dst->GetPitch() ,src->GetHeight()); }*/ } else { //if ((env->GetCPUFlags() & CPUF_INTEGER_SSE)) { isse_yv12_to_yuy2(src->GetReadPtr(PLANAR_Y), src->GetReadPtr(PLANAR_U), src->GetReadPtr(PLANAR_V), src->GetRowSize(PLANAR_Y_ALIGNED), src->GetPitch(PLANAR_Y), src->GetPitch(PLANAR_U), yuv, dst->GetPitch() ,src->GetHeight()); /*} else { mmx_yv12_to_yuy2(src->GetReadPtr(PLANAR_Y), src->GetReadPtr(PLANAR_U), src->GetReadPtr(PLANAR_V), src->GetRowSize(PLANAR_Y_ALIGNED), src->GetPitch(PLANAR_Y), src->GetPitch(PLANAR_U), yuv, dst->GetPitch() ,src->GetHeight()); }*/ } return dst; } //josh: x64 machines aren't getting anywhere near softwire . . . #ifndef _AMD64_ if (env->GetCPUFlags() & CPUF_MMX) { PVideoFrame dst = env->NewVideoFrame(vi); BYTE* yuv = dst->GetWritePtr(); mmx_ConvertRGBtoYUY2(src->GetReadPtr(), yuv ,src->GetPitch(), dst->GetPitch(), vi.height); return dst; } #else /*if (env->GetCPUFlags() & CPUF_MMX) { PVideoFrame dst = env->NewVideoFrame(vi); BYTE* yuv = dst->GetWritePtr(); convert_rgb_asm(src->GetReadPtr(),yuv,src->GetPitch(), dst->GetPitch(),vi.width, vi.height, theMatrix); return dst; }*/ #endif // non MMX machines. PVideoFrame dst = env->NewVideoFrame(vi); BYTE* yuv = dst->GetWritePtr(); const BYTE* rgb = src->GetReadPtr() + (vi.height-1) * src->GetPitch(); const int yuv_offset = dst->GetPitch() - dst->GetRowSize(); const int rgb_offset = -src->GetPitch() - src->GetRowSize(); const int rgb_inc = ((src_cs&VideoInfo::CS_BGR32)==VideoInfo::CS_BGR32) ? 4 : 3; /* Prototype 1-2-1 Kernel version if (theMatrix == PC_601) { const int cyb = int(0.114*65536+0.5); const int cyg = int(0.587*65536+0.5); const int cyr = int(0.299*65536+0.5); const int ku = int(127./(255.*(1.0-0.114))*16384+0.5); const int kv = int(127./(255.*(1.0-0.299))*16384+0.5); for (int y=vi.height; y>0; --y) { const BYTE* rgb_prev = rgb; int y0 = (cyb*rgb_prev[0] + cyg*rgb_prev[1] + cyr*rgb_prev[2] + 0x8000) >> 16; for (int x = 0; x < vi.width; x += 2) { const BYTE* const rgb_next = rgb + rgb_inc; // y1 and y2 can't overflow const int y1 = (cyb*rgb[0] + cyg*rgb[1] + cyr*rgb[2] + 0x8000) >> 16; yuv[0] = y1; const int y2 = (cyb*rgb_next[0] + cyg*rgb_next[1] + cyr*rgb_next[2] + 0x8000) >> 16; yuv[2] = y2; const int scaled_y = y0+y1*2+y2; y0 = y2; const int b_y = (rgb_prev[0]+rgb[0]*2+rgb_next[0]) - scaled_y; yuv[1] = ScaledPixelClip(b_y * ku + 0x800000); // u const int r_y = (rgb_prev[2]+rgb[2]*2+rgb_next[2]) - scaled_y; yuv[3] = ScaledPixelClip(r_y * kv + 0x800000); // v rgb_prev = rgb_next; rgb = rgb_next + rgb_inc; yuv += 4; } rgb += rgb_offset; yuv += yuv_offset; } } */ /* Existing 0-1-1 Kernel version */ if (theMatrix == PC_601) { const int cyb = int(0.114*65536+0.5); const int cyg = int(0.587*65536+0.5); const int cyr = int(0.299*65536+0.5); const int ku = int(127./(255.*(1.0-0.114))*32768+0.5); const int kv = int(127./(255.*(1.0-0.299))*32768+0.5); for (int y=vi.height; y>0; --y) { for (int x = 0; x < vi.width; x += 2) { const BYTE* const rgb_next = rgb + rgb_inc; // y1 and y2 can't overflow const int y1 = (cyb*rgb[0] + cyg*rgb[1] + cyr*rgb[2] + 0x8000) >> 16; yuv[0] = y1; const int y2 = (cyb*rgb_next[0] + cyg*rgb_next[1] + cyr*rgb_next[2] + 0x8000) >> 16; yuv[2] = y2; const int scaled_y = y1+y2; const int b_y = (rgb[0]+rgb_next[0]) - scaled_y; yuv[1] = ScaledPixelClip(b_y * ku + 0x800000); // u const int r_y = (rgb[2]+rgb_next[2]) - scaled_y; yuv[3] = ScaledPixelClip(r_y * kv + 0x800000); // v rgb = rgb_next + rgb_inc; yuv += 4; } rgb += rgb_offset; yuv += yuv_offset; } } else if (theMatrix == PC_709) {