inline int get_offset (int component_index, int pic_width, int pic_height) { switch (component_index) { case 0: return 0; case 1: return ROUND_UP_4 (pic_width) * ROUND_UP_2 (pic_height); case 2: return ROUND_UP_4 (pic_width) * ROUND_UP_2 (pic_height) + ROUND_UP_4 (ROUND_UP_2 (pic_width) / 2) * (ROUND_UP_2 (pic_height) / 2); default: /* error */ return 0; } }
int format_properties(const unsigned int format, const unsigned int width, const unsigned int height, size_t*linewidth, size_t*framewidth) { size_t lw, fw; switch(format) { case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YVU420: lw = width; /* ??? */ fw = ROUND_UP_4 (width) * ROUND_UP_2 (height); fw += 2 * ((ROUND_UP_8 (width) / 2) * (ROUND_UP_2 (height) / 2)); break; case V4L2_PIX_FMT_UYVY: case V4L2_PIX_FMT_Y41P: case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_YVYU: lw = (ROUND_UP_2 (width) * 2); fw = lw * height; break; default: return 0; } if(linewidth)*linewidth=lw; if(framewidth)*framewidth=fw; return 1; }
static void change_context (GstPostProc * postproc, gint width, gint height) { guint mmx_flags; guint altivec_flags; gint ppflags; GST_DEBUG_OBJECT (postproc, "change_context, width:%d, height:%d", width, height); if ((width != postproc->width) && (height != postproc->height)) { if (postproc->context) pp_free_context (postproc->context); #ifdef HAVE_ORC mmx_flags = orc_target_get_default_flags (orc_target_get_by_name ("mmx")); altivec_flags = orc_target_get_default_flags (orc_target_get_by_name ("altivec")); ppflags = (mmx_flags & ORC_TARGET_MMX_MMX ? PP_CPU_CAPS_MMX : 0) | (mmx_flags & ORC_TARGET_MMX_MMXEXT ? PP_CPU_CAPS_MMX2 : 0) | (mmx_flags & ORC_TARGET_MMX_3DNOW ? PP_CPU_CAPS_3DNOW : 0) | (altivec_flags & ORC_TARGET_ALTIVEC_ALTIVEC ? PP_CPU_CAPS_ALTIVEC : 0); #else mmx_flags = 0; altivec_flags = 0; ppflags = 0; #endif postproc->context = pp_get_context (width, height, PP_FORMAT_420 | ppflags); postproc->width = width; postproc->height = height; postproc->ystride = ROUND_UP_4 (width); postproc->ustride = ROUND_UP_8 (width) / 2; postproc->vstride = ROUND_UP_8 (postproc->ystride) / 2; postproc->ysize = postproc->ystride * ROUND_UP_2 (height); postproc->usize = postproc->ustride * ROUND_UP_2 (height) / 2; postproc->vsize = postproc->vstride * ROUND_UP_2 (height) / 2; GST_DEBUG_OBJECT (postproc, "new strides are (YUV) : %d %d %d", postproc->ystride, postproc->ustride, postproc->vstride); } }
int format_properties(const unsigned int Format, const unsigned int Width, const unsigned int Height, __u32* LineWidth, __u32* FrameSize) { __u32 lw = 0; __u32 fw = 0; switch(Format) { case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YVU420: lw = Width; /* ??? */ fw = ROUND_UP_4 (Width) * ROUND_UP_2 (Height); fw += 2 * ((ROUND_UP_8 (Width) / 2) * (ROUND_UP_2 (Height) / 2)); break; case V4L2_PIX_FMT_UYVY: case V4L2_PIX_FMT_Y41P: case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_YVYU: lw = (ROUND_UP_2 (Width) * 2); fw = lw * Height; // printf("lw : %d\n", lw); // printf("fw : %d\n", fw); break; case V4L2_PIX_FMT_RGB32: lw = (ROUND_UP_2 (Width) * 4); fw = lw * Height; break; case V4L2_PIX_FMT_MJPEG: case V4L2_PIX_FMT_GREY: lw = (ROUND_UP_2 (Width) * 2); // just for debugging purpose. Values could be wrong. fw = lw * Height; // Do NOT trust these values. Debugging purpose ONLY. break; default: printf("No proper format found. No Action\n"); return 0; } if(LineWidth) *LineWidth=lw; if(FrameSize) *FrameSize=fw; return 1; }
void vs_image_scale_linear_UYVY (const VSImage * dest, const VSImage * src, uint8_t * tmpbuf) { int acc; int y_increment; int x_increment; uint8_t *tmp1; uint8_t *tmp2; int y1; int y2; int i; int j; int x; int dest_size; int xacc; if (dest->height == 1) y_increment = 0; else y_increment = ((src->height - 1) << 16) / (dest->height - 1); if (dest->width == 1) x_increment = 0; else x_increment = ((src->width - 1) << 16) / (dest->width - 1); dest_size = ROUND_UP_4 (dest->width * 2); tmp1 = tmpbuf; tmp2 = tmpbuf + dest_size; acc = 0; xacc = 0; y2 = -1; vs_scanline_resample_linear_UYVY (tmp1, src->pixels, src->width, dest->width, &xacc, x_increment); y1 = 0; for (i = 0; i < dest->height; i++) { j = acc >> 16; x = acc & 0xffff; if (x == 0) { if (j == y1) { memcpy (dest->pixels + i * dest->stride, tmp1, dest_size); } else if (j == y2) { memcpy (dest->pixels + i * dest->stride, tmp2, dest_size); } else { xacc = 0; vs_scanline_resample_linear_UYVY (tmp1, src->pixels + j * src->stride, src->width, dest->width, &xacc, x_increment); y1 = j; memcpy (dest->pixels + i * dest->stride, tmp1, dest_size); } } else { if (j == y1) { if (j + 1 != y2) { xacc = 0; vs_scanline_resample_linear_UYVY (tmp2, src->pixels + (j + 1) * src->stride, src->width, dest->width, &xacc, x_increment); y2 = j + 1; } vs_scanline_merge_linear_UYVY (dest->pixels + i * dest->stride, tmp1, tmp2, dest->width, x); } else if (j == y2) { if (j + 1 != y1) { xacc = 0; vs_scanline_resample_linear_UYVY (tmp1, src->pixels + (j + 1) * src->stride, src->width, dest->width, &xacc, x_increment); y1 = j + 1; } vs_scanline_merge_linear_UYVY (dest->pixels + i * dest->stride, tmp2, tmp1, dest->width, x); } else { xacc = 0; vs_scanline_resample_linear_UYVY (tmp1, src->pixels + j * src->stride, src->width, dest->width, &xacc, x_increment); y1 = j; xacc = 0; vs_scanline_resample_linear_UYVY (tmp2, src->pixels + (j + 1) * src->stride, src->width, dest->width, &xacc, x_increment); y2 = (j + 1); vs_scanline_merge_linear_UYVY (dest->pixels + i * dest->stride, tmp1, tmp2, dest->width, x); } } acc += y_increment; } }
void Video_out::Run() { if(verbose) printf("Thread started: %s\n", this->devName.c_str()); int running = 1; pthread_mutex_lock(&this->lock); this->stopped = 0; pthread_mutex_unlock(&this->lock); this->fdwr = open(this->devName.c_str(), O_RDWR); assert(fdwr >= 0); struct v4l2_capability vid_caps; int ret_code = ioctl(this->fdwr, VIDIOC_QUERYCAP, &vid_caps); assert(ret_code != -1); struct v4l2_format vid_format; memset(&vid_format, 0, sizeof(vid_format)); ret_code = ioctl(this->fdwr, VIDIOC_G_FMT, &vid_format); if(verbose)print_format(&vid_format); int lw = 0; int fw = 0; if(strcmp(this->outputPxFmt.c_str(), "YVU420")==0) { lw = this->outputWidth; /* ??? */ fw = ROUND_UP_4 (this->outputWidth) * ROUND_UP_2 (this->outputHeight); fw += 2 * ((ROUND_UP_8 (this->outputWidth) / 2) * (ROUND_UP_2 (this->outputHeight) / 2)); } if(strcmp(this->outputPxFmt.c_str(), "YUYV")==0 || strcmp(this->outputPxFmt.c_str(), "UYVY")==0 ) { lw = (ROUND_UP_2 (this->outputWidth) * 2); fw = lw * this->outputHeight; } vid_format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; vid_format.fmt.pix.width = this->outputWidth; vid_format.fmt.pix.height = this->outputHeight; vid_format.fmt.pix.pixelformat = 0; if(strcmp(this->outputPxFmt.c_str(), "YUYV")==0) vid_format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; if(strcmp(this->outputPxFmt.c_str(), "UYVY")==0) vid_format.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY; if(strcmp(this->outputPxFmt.c_str(), "YVU420")==0) vid_format.fmt.pix.pixelformat = V4L2_PIX_FMT_YVU420; if(strcmp(this->outputPxFmt.c_str(), "RGB24")==0) vid_format.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24; vid_format.fmt.pix.sizeimage = lw; vid_format.fmt.pix.field = V4L2_FIELD_NONE; vid_format.fmt.pix.bytesperline = fw; vid_format.fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; if(verbose)print_format(&vid_format); ret_code = ioctl(this->fdwr, VIDIOC_S_FMT, &vid_format); assert(ret_code != -1); this->framesize = vid_format.fmt.pix.sizeimage; int linewidth = vid_format.fmt.pix.bytesperline; if(verbose)printf("frame: format=%s\tsize=%d\n", this->outputPxFmt.c_str(), framesize); try { while(running) { usleep(1000); this->SendFrameInternal(); pthread_mutex_lock(&this->lock); try { running = !this->stop; } catch(std::exception &err) { if(verbose) printf("An exception has occured: %s\n", err.what()); running = 0; } pthread_mutex_unlock(&this->lock); } } catch(std::exception &err) { if(verbose) printf("An exception has occured: %s\n", err.what()); } if(verbose) printf("Thread stopping\n"); pthread_mutex_lock(&this->lock); this->stopped = 1; pthread_mutex_unlock(&this->lock); }
/* this function pieced together from gstreamer ffmpegcolorspace component */ static void yuv422_to_yuv420p (unsigned char *dest, unsigned char *src, int width, int height) { const unsigned char *p, *p1; unsigned char *lum, *cr, *cb, *lum1, *cr1, *cb1; int w; int dest_stride[3] = { get_row_stride (0, width), get_row_stride (1, width), get_row_stride (2, width) }; /* this stuff specific to I420 and others in family */ int x_chroma_shift = 1; int y_chroma_shift = 1; int offset_cb = ROUND_UP_4 (width) * ROUND_UP_X (height, y_chroma_shift); int offset_cr = ROUND_UP_4 (DIV_ROUND_UP_X (width, x_chroma_shift)) * DIV_ROUND_UP_X (height, y_chroma_shift); /* src_stride calculation specific to YUV422 and others in family */ int src_stride = ROUND_UP_4 (width * 2); p1 = src; lum1 = dest; cb1 = dest + offset_cb; cr1 = cb1 + offset_cr; for (; height >= 1; height -= 2) { p = p1; lum = lum1; cb = cb1; cr = cr1; for (w = width; w >= 2; w -= 2) { lum[0] = p[0]; cb[0] = p[1]; lum[1] = p[2]; cr[0] = p[3]; p += 4; lum += 2; cb++; cr++; } if (w) { lum[0] = p[0]; cb[0] = p[1]; cr[0] = p[3]; } p1 += src_stride; lum1 += dest_stride[0]; if (height > 1) { p = p1; lum = lum1; for (w = width; w >= 2; w -= 2) { lum[0] = p[0]; lum[1] = p[2]; p += 4; lum += 2; } if (w) { lum[0] = p[0]; } p1 += src_stride; lum1 += dest_stride[0]; } cb1 += dest_stride[1]; cr1 += dest_stride[2]; } }
inline int get_row_stride (int component_index, int pic_width) { return (component_index == 0) ? ROUND_UP_4 (pic_width) : ROUND_UP_4 (ROUND_UP_2 (pic_width) / 2); }