示例#1
0
/** @brief Convert a frame from UYVY to BGR
 * @ingroup frame
 * @param ini UYVY frame
 * @param out BGR frame
 */
uvc_error_t uvc_uyvy2bgr(uvc_frame_t *in, uvc_frame_t *out) {
  if (in->frame_format != UVC_FRAME_FORMAT_UYVY)
    return UVC_ERROR_INVALID_PARAM;

  if (uvc_ensure_frame_size(out, in->width * in->height * 3) < 0)
    return UVC_ERROR_NO_MEM;

  out->width = in->width;
  out->height = in->height;
  out->frame_format = UVC_FRAME_FORMAT_BGR;
  out->step = in->width *3;
  out->sequence = in->sequence;
  out->capture_time = in->capture_time;
  out->source = in->source;

  uint8_t *pyuv = static_cast<uint8_t *>(in->data);
  uint8_t *pbgr = static_cast<uint8_t *>(out->data);
  uint8_t *pbgr_end = pbgr + out->data_bytes;

  while (pbgr < pbgr_end) {
    IUYVY2BGR_8(pyuv, pbgr);

    pbgr += 3 * 8;
    pyuv += 2 * 8;
  }

  return UVC_SUCCESS;
}
示例#2
0
/** @brief Convert a frame from YUYV to UV (GRAY8)
 * @ingroup frame
 *
 * @param in YUYV frame
 * @param out GRAY8 frame
 */
uvc_error_t uvc_yuyv2uv(uvc_frame_t *in, uvc_frame_t *out) {
  if (in->frame_format != UVC_FRAME_FORMAT_YUYV)
    return UVC_ERROR_INVALID_PARAM;

  if (uvc_ensure_frame_size(out, in->width * in->height) < 0)
    return UVC_ERROR_NO_MEM;

  out->width = in->width;
  out->height = in->height;
  out->frame_format = UVC_FRAME_FORMAT_GRAY8;
  out->step = in->width;
  out->sequence = in->sequence;
  out->capture_time = in->capture_time;
  out->source = in->source;

  uint8_t *pyuv = static_cast<uint8_t *>(in->data);
  uint8_t *puv = static_cast<uint8_t *>(out->data);
  uint8_t *puv_end = puv + out->data_bytes;

  while (puv < puv_end) {
    IYUYV2UV(pyuv, puv);

    puv += 1;
    pyuv += 2;
  }

  return UVC_SUCCESS;
}
示例#3
0
/** @brief Convert a frame from YUYV to RGB
 * @ingroup frame
 *
 * @param in YUYV frame
 * @param out RGB frame
 */
uvc_error_t uvc_yuyv2rgb(uvc_frame_t *in, uvc_frame_t *out) {
  if (in->frame_format != UVC_FRAME_FORMAT_YUYV)
    return UVC_ERROR_INVALID_PARAM;

  if (uvc_ensure_frame_size(out, in->width * in->height * 3) < 0)
    return UVC_ERROR_NO_MEM;

  out->width = in->width;
  out->height = in->height;
  out->frame_format = UVC_FRAME_FORMAT_RGB;
  out->step = in->width * 3;
  out->sequence = in->sequence;
  out->capture_time = in->capture_time;
  out->source = in->source;

  uint8_t *pyuv = static_cast<uint8_t *>(in->data);
  uint8_t *prgb = static_cast<uint8_t *>(out->data);
  uint8_t *prgb_end = prgb + out->data_bytes;

  while (prgb < prgb_end) {
    IYUYV2RGB_8(pyuv, prgb);

    prgb += 3 * 8;
    pyuv += 2 * 8;
  }

  return UVC_SUCCESS;
}
示例#4
0
/** @brief Duplicate a frame, preserving color format
 * @ingroup frame
 *
 * @param in Original frame
 * @param out Duplicate frame
 */
uvc_error_t uvc_duplicate_frame(uvc_frame_t *in, uvc_frame_t *out) {
  if (uvc_ensure_frame_size(out, in->data_bytes) < 0)
    return UVC_ERROR_NO_MEM;

  out->width = in->width;
  out->height = in->height;
  out->frame_format = in->frame_format;
  out->step = in->step;
  out->sequence = in->sequence;
  out->capture_time = in->capture_time;
  out->source = in->source;

  memcpy(out->data, in->data, in->data_bytes);

  return UVC_SUCCESS;
}
示例#5
0
void CallbackPipeline::do_capture(JNIEnv *env) {
	ENTER();

	uvc_frame_t *frame;
	uvc_frame_t *temp = get_frame(default_frame_size);
	uvc_frame_t *callback_frame;
	uint32_t width = 0, height = 0;
	size_t sz = default_frame_size;

	if (LIKELY(temp)) {
		for (; isRunning() && isCapturing();) {
			frame = waitCaptureFrame();
			if ((LIKELY(frame))) {
				if (UNLIKELY((width != frame->width) || (height != frame->height))) {
					width = frame->width;
					height = frame->height;
					callbackPixelFormatChanged(width, height);
					uvc_ensure_frame_size(temp, callbackPixelBytes);
					sz = callbackPixelBytes;
				}
				if (mFrameCallbackObj) {
					callback_frame = frame;
					sz = frame->actual_bytes;
					if (mFrameCallbackFunc) {
						callback_frame = temp;
						sz = callbackPixelBytes;
						int b = mFrameCallbackFunc(frame, temp);
						if (UNLIKELY(b)) {
							LOGW("failed to convert to callback frame");
							goto SKIP;
						}
					}
					jobject buf = env->NewDirectByteBuffer(callback_frame->data, callbackPixelBytes);
					env->CallVoidMethod(mFrameCallbackObj, iframecallback_fields.onFrame, buf);
					env->ExceptionClear();
					env->DeleteLocalRef(buf);
				}
SKIP:
				recycle_frame(frame);
			}
		}
		recycle_frame(temp);
	}

	EXIT();
}
示例#6
0
uvc_error_t uvc_mjpeg2yuyv(uvc_frame_t *in, uvc_frame_t *out) {

	out->actual_bytes = 0;	// XXX
	if (UNLIKELY(in->frame_format != UVC_FRAME_FORMAT_MJPEG))
		return UVC_ERROR_INVALID_PARAM;

	if (uvc_ensure_frame_size(out, in->width * in->height * 2) < 0)
		return UVC_ERROR_NO_MEM;

	size_t lines_read = 0;
	int i, j;
	int num_scanlines;
	register uint8_t *yuyv, *ycbcr;

	out->width = in->width;
	out->height = in->height;
	out->frame_format = UVC_FRAME_FORMAT_YUYV;
	out->step = in->width * 2;
	out->sequence = in->sequence;
	out->capture_time = in->capture_time;
	out->source = in->source;

	struct jpeg_decompress_struct dinfo;
	struct error_mgr jerr;
	dinfo.err = jpeg_std_error(&jerr.super);
	jerr.super.error_exit = _error_exit;

	if (setjmp(jerr.jmp)) {
		goto fail;
	}

	jpeg_create_decompress(&dinfo);
	jpeg_mem_src(&dinfo, in->data, in->actual_bytes/*in->data_bytes*/);	// XXX
	jpeg_read_header(&dinfo, TRUE);

	if (dinfo.dc_huff_tbl_ptrs[0] == NULL) {
		/* This frame is missing the Huffman tables: fill in the standard ones */
		insert_huff_tables(&dinfo);
	}

	dinfo.out_color_space = JCS_YCbCr;
	dinfo.dct_method = JDCT_IFAST;

	// start decompressor
	jpeg_start_decompress(&dinfo);

	// these dinfo.xxx valiables are only valid after jpeg_start_decompress
	const int row_stride = dinfo.output_width * dinfo.output_components;

	// allocate buffer
	register JSAMPARRAY buffer = (*dinfo.mem->alloc_sarray)
		((j_common_ptr) &dinfo, JPOOL_IMAGE, row_stride, MAX_READLINE);

	// local copy
	uint8_t *data = out->data;
	const int out_step = out->step;

	if (LIKELY(dinfo.output_height == out->height)) {
		for (; dinfo.output_scanline < dinfo.output_height ;) {
			// convert lines of mjpeg data to YCbCr
			num_scanlines = jpeg_read_scanlines(&dinfo, buffer, MAX_READLINE);
			// convert YCbCr to yuyv(YUV422)
			for (j = 0; j < num_scanlines; j++) {
				yuyv = data + (lines_read + j) * out_step;
				ycbcr = buffer[j];
				for (i = 0; i < row_stride; i += 24) {	// step by YCbCr x 8 pixels = 3 x 8 bytes
					YCbCr_YUYV_2(ycbcr + i, yuyv);
					YCbCr_YUYV_2(ycbcr + i + 6, yuyv);
					YCbCr_YUYV_2(ycbcr + i + 12, yuyv);
					YCbCr_YUYV_2(ycbcr + i + 18, yuyv);
				}
			}
			lines_read += num_scanlines;
		}
		out->actual_bytes = in->width * in->height * 2;	// XXX
	}

	jpeg_finish_decompress(&dinfo);
	jpeg_destroy_decompress(&dinfo);
	return lines_read == out->height ? UVC_SUCCESS : UVC_ERROR_OTHER;

fail:
	jpeg_destroy_decompress(&dinfo);
	return lines_read == out->height ? UVC_SUCCESS : UVC_ERROR_OTHER+1;
}
示例#7
0
/** @brief Convert an MJPEG frame to RGB
 * @ingroup frame
 *
 * @param in MJPEG frame
 * @param out RGB frame
 */
uvc_error_t uvc_mjpeg2rgb(uvc_frame_t *in, uvc_frame_t *out) {
	struct jpeg_decompress_struct dinfo;
	struct error_mgr jerr;
	size_t lines_read;
	// local copy
	uint8_t *data = out->data;
	const int out_step = out->step;

	int num_scanlines, i;
	lines_read = 0;
	unsigned char *buffer[MAX_READLINE];

	out->actual_bytes = 0;	// XXX
	if (UNLIKELY(in->frame_format != UVC_FRAME_FORMAT_MJPEG))
		return UVC_ERROR_INVALID_PARAM;

	if (uvc_ensure_frame_size(out, in->width * in->height * 3) < 0)
		return UVC_ERROR_NO_MEM;

	out->width = in->width;
	out->height = in->height;
	out->frame_format = UVC_FRAME_FORMAT_RGB;
	out->step = in->width * 3;
	out->sequence = in->sequence;
	out->capture_time = in->capture_time;
	out->source = in->source;

	dinfo.err = jpeg_std_error(&jerr.super);
	jerr.super.error_exit = _error_exit;

	if (setjmp(jerr.jmp)) {
		goto fail;
	}

	jpeg_create_decompress(&dinfo);
	jpeg_mem_src(&dinfo, in->data, in->actual_bytes/*in->data_bytes*/);
	jpeg_read_header(&dinfo, TRUE);

	if (dinfo.dc_huff_tbl_ptrs[0] == NULL) {
		/* This frame is missing the Huffman tables: fill in the standard ones */
		insert_huff_tables(&dinfo);
	}

	dinfo.out_color_space = JCS_RGB;
	dinfo.dct_method = JDCT_IFAST;

	jpeg_start_decompress(&dinfo);

	if (LIKELY(dinfo.output_height == out->height)) {
		for (; dinfo.output_scanline < dinfo.output_height ;) {
			buffer[0] = data + (lines_read) * out_step;
			for (i = 1; i < MAX_READLINE; i++)
				buffer[i] = buffer[i-1] + out_step;
			num_scanlines = jpeg_read_scanlines(&dinfo, buffer, MAX_READLINE);
			lines_read += num_scanlines;
		}
		out->actual_bytes = in->width * in->height * 3;	// XXX
	}
	jpeg_finish_decompress(&dinfo);
	jpeg_destroy_decompress(&dinfo);
	return lines_read == out->height ? UVC_SUCCESS : UVC_ERROR_OTHER;	// XXX

fail:
	jpeg_destroy_decompress(&dinfo);
	return UVC_ERROR_OTHER+1;
}