Remove unused code
[rtmpclient.git] / app / src / main / jni / libuvc / src / frame.c
diff --git a/app/src/main/jni/libuvc/src/frame.c b/app/src/main/jni/libuvc/src/frame.c
deleted file mode 100644 (file)
index 27e5ad7..0000000
+++ /dev/null
@@ -1,1395 +0,0 @@
-/*********************************************************************
- *********************************************************************/
-/*********************************************************************
- * added and modified some function for support and help for Android
- * Copyright (C) 2014 saki@serenegiant All rights reserved.
- * add:
- *     added some helper functions for supporting rgb565 and rgbx8888
- * modified:
- *     modified for optimization with gcc
- *     modified macros that convert pixel format to reduce cpu cycles
- *     added boundary check of pointer in the converting function to avoid crash
- *********************************************************************/
-
-/*********************************************************************
- * Software License Agreement (BSD License)
- *
- *  Copyright (C) 2010-2012 Ken Tossell
- *  All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions
- *  are met:
- *
- *   * Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   * Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the following
- *     disclaimer in the documentation and/or other materials provided
- *     with the distribution.
- *   * Neither the name of the author nor other contributors may be
- *     used to endorse or promote products derived from this software
- *     without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- *********************************************************************/
-/**
- * @defgroup frame Frame processing
- * @brief Tools for managing frame buffers and converting between image formats
- */
-#include "libuvc/libuvc.h"
-#include "libuvc/libuvc_internal.h"
-
-#define USE_STRIDE 1
-/** @internal */
-uvc_error_t uvc_ensure_frame_size(uvc_frame_t *frame, size_t need_bytes) {
-       if LIKELY(frame->library_owns_data) {
-               if UNLIKELY(!frame->data || frame->data_bytes != need_bytes) {
-                       frame->actual_bytes = frame->data_bytes = need_bytes;   // XXX
-                       frame->data = realloc(frame->data, frame->data_bytes);
-               }
-               if (UNLIKELY(!frame->data || !need_bytes))
-                       return UVC_ERROR_NO_MEM;
-               return UVC_SUCCESS;
-       } else {
-               if (UNLIKELY(!frame->data || frame->data_bytes < need_bytes))
-                       return UVC_ERROR_NO_MEM;
-               return UVC_SUCCESS;
-       }
-}
-
-/** @brief Allocate a frame structure
- * @ingroup frame
- *
- * @param data_bytes Number of bytes to allocate, or zero
- * @return New frame, or NULL on error
- */
-uvc_frame_t *uvc_allocate_frame(size_t data_bytes) {
-       uvc_frame_t *frame = malloc(sizeof(*frame));    // FIXME using buffer pool is better performance(5-30%) than directory use malloc everytime.
-
-       if (UNLIKELY(!frame))
-               return NULL;
-
-#ifndef __ANDROID__
-       // XXX in many case, it is not neccesary to clear because all fields are set before use
-       // therefore we remove this to improve performace, but be care not to forget to set fields before use
-       memset(frame, 0, sizeof(*frame));       // bzero(frame, sizeof(*frame)); // bzero is deprecated
-#endif
-//     frame->library_owns_data = 1;   // XXX moved to lower
-
-       if (LIKELY(data_bytes > 0)) {
-               frame->library_owns_data = 1;
-               frame->actual_bytes = frame->data_bytes = data_bytes;   // XXX
-               frame->data = malloc(data_bytes);
-
-               if (UNLIKELY(!frame->data)) {
-                       free(frame);
-                       return NULL ;
-               }
-       }
-
-       return frame;
-}
-
-/** @brief Free a frame structure
- * @ingroup frame
- *
- * @param frame Frame to destroy
- */
-void uvc_free_frame(uvc_frame_t *frame) {
-       if ((frame->data_bytes > 0) && frame->library_owns_data)
-               free(frame->data);
-
-       free(frame);
-}
-
-static inline unsigned char sat(int i) {
-       return (unsigned char) (i >= 255 ? 255 : (i < 0 ? 0 : i));
-}
-
-/** @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 (UNLIKELY(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;
-       if (out->library_owns_data)
-               out->step = in->step;
-       out->sequence = in->sequence;
-       out->capture_time = in->capture_time;
-       out->source = in->source;
-       out->actual_bytes = in->actual_bytes;   // XXX
-
-#if USE_STRIDE  // XXX
-       if (in->step && out->step) {
-               const int istep = in->step;
-               const int ostep = out->step;
-               const int hh = in->height < out->height ? in->height : out->height;
-               const int rowbytes = istep < ostep ? istep : ostep;
-               register void *ip = in->data;
-               register void *op = out->data;
-               int h;
-               for (h = 0; h < hh; h += 4) {
-                       memcpy(op, ip, rowbytes);
-                       ip += istep; op += ostep;
-                       memcpy(op, ip, rowbytes);
-                       ip += istep; op += ostep;
-                       memcpy(op, ip, rowbytes);
-                       ip += istep; op += ostep;
-                       memcpy(op, ip, rowbytes);
-                       ip += istep; op += ostep;
-               }
-       } else {
-               // compressed format? XXX if only one of the frame in / out has step, this may lead to crash...
-               memcpy(out->data, in->data, in->actual_bytes);
-       }
-#else
-       memcpy(out->data, in->data, in->actual_bytes); // XXX
-#endif
-       return UVC_SUCCESS;
-}
-
-#define PIXEL_RGB565           2
-#define PIXEL_UYVY                     2
-#define PIXEL_YUYV                     2
-#define PIXEL_RGB                      3
-#define PIXEL_BGR                      3
-#define PIXEL_RGBX                     4
-
-#define PIXEL2_RGB565          PIXEL_RGB565 * 2
-#define PIXEL2_UYVY                    PIXEL_UYVY * 2
-#define PIXEL2_YUYV                    PIXEL_YUYV * 2
-#define PIXEL2_RGB                     PIXEL_RGB * 2
-#define PIXEL2_BGR                     PIXEL_BGR * 2
-#define PIXEL2_RGBX                    PIXEL_RGBX * 2
-
-#define PIXEL4_RGB565          PIXEL_RGB565 * 4
-#define PIXEL4_UYVY                    PIXEL_UYVY * 4
-#define PIXEL4_YUYV                    PIXEL_YUYV * 4
-#define PIXEL4_RGB                     PIXEL_RGB * 4
-#define PIXEL4_BGR                     PIXEL_BGR * 4
-#define PIXEL4_RGBX                    PIXEL_RGBX * 4
-
-#define PIXEL8_RGB565          PIXEL_RGB565 * 8
-#define PIXEL8_UYVY                    PIXEL_UYVY * 8
-#define PIXEL8_YUYV                    PIXEL_YUYV * 8
-#define PIXEL8_RGB                     PIXEL_RGB * 8
-#define PIXEL8_BGR                     PIXEL_BGR * 8
-#define PIXEL8_RGBX                    PIXEL_RGBX * 8
-
-#define PIXEL16_RGB565         PIXEL_RGB565 * 16
-#define PIXEL16_UYVY           PIXEL_UYVY * 16
-#define PIXEL16_YUYV           PIXEL_YUYV * 16
-#define PIXEL16_RGB                    PIXEL_RGB * 16
-#define PIXEL16_BGR                    PIXEL_BGR * 16
-#define PIXEL16_RGBX           PIXEL_RGBX * 16
-
-#define RGB2RGBX_2(prgb, prgbx, ax, bx) { \
-               (prgbx)[bx+0] = (prgb)[ax+0]; \
-               (prgbx)[bx+1] = (prgb)[ax+1]; \
-               (prgbx)[bx+2] = (prgb)[ax+2]; \
-               (prgbx)[bx+3] = 0xff; \
-               (prgbx)[bx+4] = (prgb)[ax+3]; \
-               (prgbx)[bx+5] = (prgb)[ax+4]; \
-               (prgbx)[bx+6] = (prgb)[ax+5]; \
-               (prgbx)[bx+7] = 0xff; \
-       }
-#define RGB2RGBX_16(prgb, prgbx, ax, bx) \
-       RGB2RGBX_8(prgb, prgbx, ax, bx) \
-       RGB2RGBX_8(prgb, prgbx, ax + PIXEL8_RGB, bx +PIXEL8_RGBX);
-#define RGB2RGBX_8(prgb, prgbx, ax, bx) \
-       RGB2RGBX_4(prgb, prgbx, ax, bx) \
-       RGB2RGBX_4(prgb, prgbx, ax + PIXEL4_RGB, bx + PIXEL4_RGBX);
-#define RGB2RGBX_4(prgb, prgbx, ax, bx) \
-       RGB2RGBX_2(prgb, prgbx, ax, bx) \
-       RGB2RGBX_2(prgb, prgbx, ax + PIXEL2_RGB, bx + PIXEL2_RGBX);
-
-/** @brief Convert a frame from RGB888 to RGBX8888
- * @ingroup frame
- * @param ini RGB888 frame
- * @param out RGBX8888 frame
- */
-uvc_error_t uvc_rgb2rgbx(uvc_frame_t *in, uvc_frame_t *out) {
-       if (UNLIKELY(in->frame_format != UVC_FRAME_FORMAT_RGB))
-               return UVC_ERROR_INVALID_PARAM;
-
-       if (UNLIKELY(uvc_ensure_frame_size(out, in->width * in->height * PIXEL_RGBX) < 0))
-               return UVC_ERROR_NO_MEM;
-
-       out->width = in->width;
-       out->height = in->height;
-       out->frame_format = UVC_FRAME_FORMAT_RGBX;
-       if (out->library_owns_data)
-               out->step = in->width * PIXEL_RGBX;
-       out->sequence = in->sequence;
-       out->capture_time = in->capture_time;
-       out->source = in->source;
-
-       uint8_t *prgb = in->data;
-       const uint8_t *prgb_end = prgb + in->data_bytes - PIXEL8_RGB;
-       uint8_t *prgbx = out->data;
-       const uint8_t *prgbx_end = prgbx + out->data_bytes - PIXEL8_RGBX;
-
-       // RGB888 to RGBX8888
-#if USE_STRIDE
-       if (in->step && out->step && (in->step != out->step)) {
-               const int hh = in->height < out->height ? in->height : out->height;
-               const int ww = in->width < out->width ? in->width : out->width;
-               int h, w;
-               for (h = 0; h < hh; h++) {
-                       w = 0;
-                       prgb = in->data + in->step * h;
-                       prgbx = out->data + out->step * h;
-                       for (; (prgbx <= prgbx_end) && (prgb <= prgb_end) && (w < ww) ;) {
-                               RGB2RGBX_8(prgb, prgbx, 0, 0);
-
-                               prgb += PIXEL8_RGB;
-                               prgbx += PIXEL8_RGBX;
-                               w += 8;
-                       }
-               }
-       } else {
-               // compressed format? XXX if only one of the frame in / out has step, this may lead to crash...
-               for (; (prgbx <= prgbx_end) && (prgb <= prgb_end) ;) {
-                       RGB2RGBX_8(prgb, prgbx, 0, 0);
-
-                       prgb += PIXEL8_RGB;
-                       prgbx += PIXEL8_RGBX;
-               }
-       }
-#else
-       for (; (prgbx <= prgbx_end) && (prgb <= prgb_end) ;) {
-               RGB2RGBX_8(prgb, prgbx, 0, 0);
-
-               prgb += PIXEL8_RGB;
-               prgbx += PIXEL8_RGBX;
-       }
-#endif
-       return UVC_SUCCESS;
-}
-
-// prgb565[0] = ((g << 3) & 0b11100000) | ((b >> 3) & 0b00011111);     // low byte
-// prgb565[1] = ((r & 0b11111000) | ((g >> 5) & 0b00000111));          // high byte
-#define RGB2RGB565_2(prgb, prgb565, ax, bx) { \
-               (prgb565)[bx+0] = (((prgb)[ax+1] << 3) & 0b11100000) | (((prgb)[ax+2] >> 3) & 0b00011111); \
-               (prgb565)[bx+1] = (((prgb)[ax+0] & 0b11111000) | (((prgb)[ax+1] >> 5) & 0b00000111)); \
-               (prgb565)[bx+2] = (((prgb)[ax+4] << 3) & 0b11100000) | (((prgb)[ax+5] >> 3) & 0b00011111); \
-               (prgb565)[bx+3] = (((prgb)[ax+3] & 0b11111000) | (((prgb)[ax+4] >> 5) & 0b00000111)); \
-    }
-#define RGB2RGB565_16(prgb, prgb565, ax, bx) \
-       RGB2RGB565_8(prgb, prgb565, ax, bx) \
-       RGB2RGB565_8(prgb, prgb565, ax + PIXEL8_RGB, bx + PIXEL8_RGB565);
-#define RGB2RGB565_8(prgb, prgb565, ax, bx) \
-       RGB2RGB565_4(prgb, prgb565, ax, bx) \
-       RGB2RGB565_4(prgb, prgb565, ax + PIXEL4_RGB, bx + PIXEL4_RGB565);
-#define RGB2RGB565_4(prgb, prgb565, ax, bx) \
-       RGB2RGB565_2(prgb, prgb565, ax, bx) \
-       RGB2RGB565_2(prgb, prgb565, ax + PIXEL2_RGB, bx + PIXEL2_RGB565);
-
-/** @brief Convert a frame from RGB888 to RGB565
- * @ingroup frame
- * @param ini RGB888 frame
- * @param out RGB565 frame
- */
-uvc_error_t uvc_rgb2rgb565(uvc_frame_t *in, uvc_frame_t *out) {
-       if (UNLIKELY(in->frame_format != UVC_FRAME_FORMAT_RGB))
-               return UVC_ERROR_INVALID_PARAM;
-
-       if (UNLIKELY(uvc_ensure_frame_size(out, in->width * in->height * PIXEL_RGB565) < 0))
-               return UVC_ERROR_NO_MEM;
-
-       out->width = in->width;
-       out->height = in->height;
-       out->frame_format = UVC_FRAME_FORMAT_RGB565;
-       if (out->library_owns_data)
-               out->step = in->width * PIXEL_RGB565;
-       out->sequence = in->sequence;
-       out->capture_time = in->capture_time;
-       out->source = in->source;
-
-       uint8_t *prgb = in->data;
-       const uint8_t *prgb_end = prgb + in->data_bytes - PIXEL8_RGB;
-       uint8_t *prgb565 = out->data;
-       const uint8_t *prgb565_end = prgb565 + out->data_bytes - PIXEL8_RGB565;
-
-       // RGB888 to RGB565
-#if USE_STRIDE
-       if (in->step && out->step && (in->step != out->step)) {
-               const int hh = in->height < out->height ? in->height : out->height;
-               const int ww = in->width < out->width ? in->width : out->width;
-               int h, w;
-               for (h = 0; h < hh; h++) {
-                       w = 0;
-                       prgb = in->data + in->step * h;
-                       prgb565 = out->data + out->step * h;
-                       for (; (prgb565 <= prgb565_end) && (prgb <= prgb_end) && (w < ww) ;) {
-                               RGB2RGB565_8(prgb, prgb565, 0, 0);
-
-                               prgb += PIXEL8_RGB;
-                               prgb565 += PIXEL8_RGB565;
-                               w += 8;
-                       }
-               }
-       } else {
-               // compressed format? XXX if only one of the frame in / out has step, this may lead to crash...
-               for (; (prgb565 <= prgb565_end) && (prgb <= prgb_end) ;) {
-                       RGB2RGB565_8(prgb, prgb565, 0, 0);
-
-                       prgb += PIXEL8_RGB;
-                       prgb565 += PIXEL8_RGB565;
-               }
-       }
-#else
-       for (; (prgb565 <= prgb565_end) && (prgb <= prgb_end) ;) {
-               RGB2RGB565_8(prgb, prgb565, 0, 0);
-
-               prgb += PIXEL8_RGB;
-               prgb565 += PIXEL8_RGB565;
-       }
-#endif
-       return UVC_SUCCESS;
-}
-/*
- #define YUYV2RGB_2(pyuv, prgb) { \
-    float r = 1.402f * ((pyuv)[3]-128); \
-    float g = -0.34414f * ((pyuv)[1]-128) - 0.71414f * ((pyuv)[3]-128); \
-    float b = 1.772f * ((pyuv)[1]-128); \
-    (prgb)[0] = sat(pyuv[0] + r); \
-    (prgb)[1] = sat(pyuv[0] + g); \
-    (prgb)[2] = sat(pyuv[0] + b); \
-    (prgb)[3] = sat(pyuv[2] + r); \
-    (prgb)[4] = sat(pyuv[2] + g); \
-    (prgb)[5] = sat(pyuv[2] + b); \
-    }
-*/
-
-#define IYUYV2RGB_2(pyuv, prgb, ax, bx) { \
-               const int d1 = (pyuv)[ax+1]; \
-               const int d3 = (pyuv)[ax+3]; \
-               const int r = (22987 * (d3/*(pyuv)[ax+3]*/ - 128)) >> 14; \
-               const int g = (-5636 * (d1/*(pyuv)[ax+1]*/ - 128) - 11698 * (d3/*(pyuv)[ax+3]*/ - 128)) >> 14; \
-               const int b = (29049 * (d1/*(pyuv)[ax+1]*/ - 128)) >> 14; \
-               const int y0 = (pyuv)[ax+0]; \
-               (prgb)[bx+0] = sat(y0 + r); \
-               (prgb)[bx+1] = sat(y0 + g); \
-               (prgb)[bx+2] = sat(y0 + b); \
-               const int y2 = (pyuv)[ax+2]; \
-               (prgb)[bx+3] = sat(y2 + r); \
-               (prgb)[bx+4] = sat(y2 + g); \
-               (prgb)[bx+5] = sat(y2 + b); \
-    }
-#define IYUYV2RGB_16(pyuv, prgb, ax, bx) \
-       IYUYV2RGB_8(pyuv, prgb, ax, bx) \
-       IYUYV2RGB_8(pyuv, prgb, ax + PIXEL8_YUYV, bx + PIXEL8_RGB)
-#define IYUYV2RGB_8(pyuv, prgb, ax, bx) \
-       IYUYV2RGB_4(pyuv, prgb, ax, bx) \
-       IYUYV2RGB_4(pyuv, prgb, ax + PIXEL4_YUYV, bx + PIXEL4_RGB)
-#define IYUYV2RGB_4(pyuv, prgb, ax, bx) \
-       IYUYV2RGB_2(pyuv, prgb, ax, bx) \
-       IYUYV2RGB_2(pyuv, prgb, ax + PIXEL2_YUYV, bx + PIXEL2_RGB)
-
-/** @brief Convert a frame from YUYV to RGB888
- * @ingroup frame
- *
- * @param in YUYV frame
- * @param out RGB888 frame
- */
-uvc_error_t uvc_yuyv2rgb(uvc_frame_t *in, uvc_frame_t *out) {
-       if (UNLIKELY(in->frame_format != UVC_FRAME_FORMAT_YUYV))
-               return UVC_ERROR_INVALID_PARAM;
-
-       if (UNLIKELY(uvc_ensure_frame_size(out, in->width * in->height * PIXEL_RGB) < 0))
-               return UVC_ERROR_NO_MEM;
-
-       out->width = in->width;
-       out->height = in->height;
-       out->frame_format = UVC_FRAME_FORMAT_RGB;
-       if (out->library_owns_data)
-               out->step = in->width * PIXEL_RGB;
-       out->sequence = in->sequence;
-       out->capture_time = in->capture_time;
-       out->source = in->source;
-
-       uint8_t *pyuv = in->data;
-       const uint8_t *pyuv_end = pyuv + in->data_bytes - PIXEL8_YUYV;
-       uint8_t *prgb = out->data;
-       const uint8_t *prgb_end = prgb + out->data_bytes - PIXEL8_RGB;
-
-#if USE_STRIDE
-       if (in->step && out->step && (in->step != out->step)) {
-               const int hh = in->height < out->height ? in->height : out->height;
-               const int ww = in->width < out->width ? in->width : out->width;
-               int h, w;
-               for (h = 0; h < hh; h++) {
-                       w = 0;
-                       pyuv = in->data + in->step * h;
-                       prgb = out->data + out->step * h;
-                       for (; (prgb <= prgb_end) && (pyuv <= pyuv_end) && (w < ww) ;) {
-                               IYUYV2RGB_8(pyuv, prgb, 0, 0);
-
-                               prgb += PIXEL8_RGB;
-                               pyuv += PIXEL8_YUYV;
-                               w += 8;
-                       }
-               }
-       } else {
-               // compressed format? XXX if only one of the frame in / out has step, this may lead to crash...
-               for (; (prgb <= prgb_end) && (pyuv <= pyuv_end) ;) {
-                       IYUYV2RGB_8(pyuv, prgb, 0, 0);
-
-                       prgb += PIXEL8_RGB;
-                       pyuv += PIXEL8_YUYV;
-               }
-       }
-#else
-       // YUYV => RGB888
-       for (; (prgb <= prgb_end) && (pyuv <= pyuv_end) ;) {
-               IYUYV2RGB_8(pyuv, prgb, 0, 0);
-
-               prgb += PIXEL8_RGB;
-               pyuv += PIXEL8_YUYV;
-       }
-#endif
-       return UVC_SUCCESS;
-}
-
-/** @brief Convert a frame from YUYV to RGB565
- * @ingroup frame
- * @param ini YUYV frame
- * @param out RGB565 frame
- */
-uvc_error_t uvc_yuyv2rgb565(uvc_frame_t *in, uvc_frame_t *out) {
-       if (UNLIKELY(in->frame_format != UVC_FRAME_FORMAT_YUYV))
-               return UVC_ERROR_INVALID_PARAM;
-
-       if (UNLIKELY(uvc_ensure_frame_size(out, in->width * in->height * PIXEL_RGB565) < 0))
-               return UVC_ERROR_NO_MEM;
-
-       out->width = in->width;
-       out->height = in->height;
-       out->frame_format = UVC_FRAME_FORMAT_RGB565;
-       if (out->library_owns_data)
-               out->step = in->width * PIXEL_RGB565;
-       out->sequence = in->sequence;
-       out->capture_time = in->capture_time;
-       out->source = in->source;
-
-       uint8_t *pyuv = in->data;
-       const uint8_t *pyuv_end = pyuv + in->data_bytes - PIXEL8_YUYV;
-       uint8_t *prgb565 = out->data;
-       const uint8_t *prgb565_end = prgb565 + out->data_bytes - PIXEL8_RGB565;
-
-       uint8_t tmp[PIXEL8_RGB];        // for temporary rgb888 data(8pixel)
-
-#if USE_STRIDE
-       if (in->step && out->step && (in->step != out->step)) {
-               const int hh = in->height < out->height ? in->height : out->height;
-               const int ww = in->width < out->width ? in->width : out->width;
-               int h, w;
-               for (h = 0; h < hh; h++) {
-                       w = 0;
-                       pyuv = in->data + in->step * h;
-                       prgb565 = out->data + out->step * h;
-                       for (; (prgb565 <= prgb565_end) && (pyuv <= pyuv_end) && (w < ww) ;) {
-                               IYUYV2RGB_8(pyuv, tmp, 0, 0);
-                               RGB2RGB565_8(tmp, prgb565, 0, 0);
-
-                               prgb565 += PIXEL8_YUYV;
-                               pyuv += PIXEL8_RGB565;
-                               w += 8;
-                       }
-               }
-       } else {
-               // compressed format? XXX if only one of the frame in / out has step, this may lead to crash...
-               for (; (prgb565 <= prgb565_end) && (pyuv <= pyuv_end) ;) {
-                       IYUYV2RGB_8(pyuv, tmp, 0, 0);
-                       RGB2RGB565_8(tmp, prgb565, 0, 0);
-
-                       prgb565 += PIXEL8_YUYV;
-                       pyuv += PIXEL8_RGB565;
-               }
-       }
-#else
-       // YUYV => RGB565
-       for (; (prgb565 <= prgb565_end) && (pyuv <= pyuv_end) ;) {
-               IYUYV2RGB_8(pyuv, tmp, 0, 0);
-               RGB2RGB565_8(tmp, prgb565, 0, 0);
-
-               prgb565 += PIXEL8_YUYV;
-               pyuv += PIXEL8_RGB565;
-       }
-#endif
-       return UVC_SUCCESS;
-}
-
-#define IYUYV2RGBX_2(pyuv, prgbx, ax, bx) { \
-               const int d1 = (pyuv)[ax+1]; \
-               const int d3 = (pyuv)[ax+3]; \
-               const int r = (22987 * (d3/*(pyuv)[ax+3]*/ - 128)) >> 14; \
-               const int g = (-5636 * (d1/*(pyuv)[ax+1]*/ - 128) - 11698 * (d3/*(pyuv)[ax+3]*/ - 128)) >> 14; \
-               const int b = (29049 * (d1/*(pyuv)[ax+1]*/ - 128)) >> 14; \
-               const int y0 = (pyuv)[ax+0]; \
-               (prgbx)[bx+0] = sat(y0 + r); \
-               (prgbx)[bx+1] = sat(y0 + g); \
-               (prgbx)[bx+2] = sat(y0 + b); \
-               (prgbx)[bx+3] = 0xff; \
-               const int y2 = (pyuv)[ax+2]; \
-               (prgbx)[bx+4] = sat(y2 + r); \
-               (prgbx)[bx+5] = sat(y2 + g); \
-               (prgbx)[bx+6] = sat(y2 + b); \
-               (prgbx)[bx+7] = 0xff; \
-    }
-#define IYUYV2RGBX_16(pyuv, prgbx, ax, bx) \
-       IYUYV2RGBX_8(pyuv, prgbx, ax, bx) \
-       IYUYV2RGBX_8(pyuv, prgbx, ax + PIXEL8_YUYV, bx + PIXEL8_RGBX);
-#define IYUYV2RGBX_8(pyuv, prgbx, ax, bx) \
-       IYUYV2RGBX_4(pyuv, prgbx, ax, bx) \
-       IYUYV2RGBX_4(pyuv, prgbx, ax + PIXEL4_YUYV, bx + PIXEL4_RGBX);
-#define IYUYV2RGBX_4(pyuv, prgbx, ax, bx) \
-       IYUYV2RGBX_2(pyuv, prgbx, ax, bx) \
-       IYUYV2RGBX_2(pyuv, prgbx, ax + PIXEL2_YUYV, bx + PIXEL2_RGBX);
-
-/** @brief Convert a frame from YUYV to RGBX8888
- * @ingroup frame
- * @param ini YUYV frame
- * @param out RGBX8888 frame
- */
-uvc_error_t uvc_yuyv2rgbx(uvc_frame_t *in, uvc_frame_t *out) {
-       if (UNLIKELY(in->frame_format != UVC_FRAME_FORMAT_YUYV))
-               return UVC_ERROR_INVALID_PARAM;
-
-       if (UNLIKELY(uvc_ensure_frame_size(out, in->width * in->height * PIXEL_RGBX) < 0))
-               return UVC_ERROR_NO_MEM;
-
-       out->width = in->width;
-       out->height = in->height;
-       out->frame_format = UVC_FRAME_FORMAT_RGBX;
-       if (out->library_owns_data)
-               out->step = in->width * PIXEL_RGBX;
-       out->sequence = in->sequence;
-       out->capture_time = in->capture_time;
-       out->source = in->source;
-
-       uint8_t *pyuv = in->data;
-       const uint8_t *pyuv_end = pyuv + in->data_bytes - PIXEL8_YUYV;
-       uint8_t *prgbx = out->data;
-       const uint8_t *prgbx_end = prgbx + out->data_bytes - PIXEL8_RGBX;
-
-       // YUYV => RGBX8888
-#if USE_STRIDE
-       if (in->step && out->step && (in->step != out->step)) {
-               const int hh = in->height < out->height ? in->height : out->height;
-               const int ww = in->width < out->width ? in->width : out->width;
-               int h, w;
-               for (h = 0; h < hh; h++) {
-                       w = 0;
-                       pyuv = in->data + in->step * h;
-                       prgbx = out->data + out->step * h;
-                       for (; (prgbx <= prgbx_end) && (pyuv <= pyuv_end) && (w < ww) ;) {
-                               IYUYV2RGBX_8(pyuv, prgbx, 0, 0);
-
-                               prgbx += PIXEL8_RGBX;
-                               pyuv += PIXEL8_YUYV;
-                               w += 8;
-                       }
-               }
-       } else {
-               // compressed format? XXX if only one of the frame in / out has step, this may lead to crash...
-               for (; (prgbx <= prgbx_end) && (pyuv <= pyuv_end) ;) {
-                       IYUYV2RGBX_8(pyuv, prgbx, 0, 0);
-
-                       prgbx += PIXEL8_RGBX;
-                       pyuv += PIXEL8_YUYV;
-               }
-       }
-#else
-       for (; (prgbx <= prgbx_end) && (pyuv <= pyuv_end) ;) {
-               IYUYV2RGBX_8(pyuv, prgbx, 0, 0);
-
-               prgbx += PIXEL8_RGBX;
-               pyuv += PIXEL8_YUYV;
-       }
-#endif
-       return UVC_SUCCESS;
-}
-
-#define IYUYV2BGR_2(pyuv, pbgr, ax, bx) { \
-               const int d1 = (pyuv)[1]; \
-               const int d3 = (pyuv)[3]; \
-           const int r = (22987 * (d3/*(pyuv)[3]*/ - 128)) >> 14; \
-           const int g = (-5636 * (d1/*(pyuv)[1]*/ - 128) - 11698 * (d3/*(pyuv)[3]*/ - 128)) >> 14; \
-           const int b = (29049 * (d1/*(pyuv)[1]*/ - 128)) >> 14; \
-               const int y0 = (pyuv)[ax+0]; \
-               (pbgr)[bx+0] = sat(y0 + b); \
-               (pbgr)[bx+1] = sat(y0 + g); \
-               (pbgr)[bx+2] = sat(y0 + r); \
-               const int y2 = (pyuv)[ax+2]; \
-               (pbgr)[bx+3] = sat(y2 + b); \
-               (pbgr)[bx+4] = sat(y2 + g); \
-               (pbgr)[bx+5] = sat(y2 + r); \
-    }
-#define IYUYV2BGR_16(pyuv, pbgr, ax, bx) \
-       IYUYV2BGR_8(pyuv, pbgr, ax, bx) \
-       IYUYV2BGR_8(pyuv, pbgr, ax + PIXEL8_YUYV, bx + PIXEL8_BGR)
-#define IYUYV2BGR_8(pyuv, pbgr, ax, bx) \
-       IYUYV2BGR_4(pyuv, pbgr, ax, bx) \
-       IYUYV2BGR_4(pyuv, pbgr, ax + PIXEL4_YUYV, bx + PIXEL4_BGR)
-#define IYUYV2BGR_4(pyuv, pbgr, ax, bx) \
-       IYUYV2BGR_2(pyuv, pbgr, ax, bx) \
-       IYUYV2BGR_2(pyuv, pbgr, ax + PIXEL2_YUYV, bx + PIXEL2_BGR)
-
-/** @brief Convert a frame from YUYV to BGR888
- * @ingroup frame
- *
- * @param in YUYV frame
- * @param out BGR888 frame
- */
-uvc_error_t uvc_yuyv2bgr(uvc_frame_t *in, uvc_frame_t *out) {
-       if (UNLIKELY(in->frame_format != UVC_FRAME_FORMAT_YUYV))
-               return UVC_ERROR_INVALID_PARAM;
-
-       if (UNLIKELY(uvc_ensure_frame_size(out, in->width * in->height * PIXEL_BGR) < 0))
-               return UVC_ERROR_NO_MEM;
-
-       out->width = in->width;
-       out->height = in->height;
-       out->frame_format = UVC_FRAME_FORMAT_BGR;
-       if (out->library_owns_data)
-               out->step = in->width * PIXEL_BGR;
-       out->sequence = in->sequence;
-       out->capture_time = in->capture_time;
-       out->source = in->source;
-
-       uint8_t *pyuv = in->data;
-       uint8_t *pyuv_end = pyuv + in->data_bytes - PIXEL8_YUYV;
-       uint8_t *pbgr = out->data;
-       uint8_t *pbgr_end = pbgr + out->data_bytes - PIXEL8_BGR;
-
-       // YUYV => BGR888
-#if USE_STRIDE
-       if (in->step && out->step && (in->step != out->step)) {
-               const int hh = in->height < out->height ? in->height : out->height;
-               const int ww = in->width < out->width ? in->width : out->width;
-               int h, w;
-               for (h = 0; h < hh; h++) {
-                       w = 0;
-                       pyuv = in->data + in->step * h;
-                       pbgr = out->data + out->step * h;
-                       for (; (pbgr <= pbgr_end) && (pyuv <= pyuv_end) && (w < ww) ;) {
-                               IYUYV2BGR_8(pyuv, pbgr, 0, 0);
-
-                               pbgr += PIXEL8_BGR;
-                               pyuv += PIXEL8_YUYV;
-                               w += 8;
-                       }
-               }
-       } else {
-               // compressed format? XXX if only one of the frame in / out has step, this may lead to crash...
-               for (; (pbgr <= pbgr_end) && (pyuv <= pyuv_end) ;) {
-                       IYUYV2BGR_8(pyuv, pbgr, 0, 0);
-
-                       pbgr += PIXEL8_BGR;
-                       pyuv += PIXEL8_YUYV;
-               }
-       }
-#else
-       for (; (pbgr <= pbgr_end) && (pyuv <= pyuv_end) ;) {
-               IYUYV2BGR_8(pyuv, pbgr, 0, 0);
-
-               pbgr += PIXEL8_BGR;
-               pyuv += PIXEL8_YUYV;
-       }
-#endif
-       return UVC_SUCCESS;
-}
-
-#define IUYVY2RGB_2(pyuv, prgb, ax, bx) { \
-               const int d0 = (pyuv)[ax+0]; \
-               const int d2 = (pyuv)[ax+2]; \
-           const int r = (22987 * (d2/*(pyuv)[ax+2]*/ - 128)) >> 14; \
-           const int g = (-5636 * (d0/*(pyuv)[ax+0]*/ - 128) - 11698 * (d2/*(pyuv)[ax+2]*/ - 128)) >> 14; \
-           const int b = (29049 * (d0/*(pyuv)[ax+0]*/ - 128)) >> 14; \
-               const int y1 = (pyuv)[ax+1]; \
-               (prgb)[bx+0] = sat(y1 + r); \
-               (prgb)[bx+1] = sat(y1 + g); \
-               (prgb)[bx+2] = sat(y1 + b); \
-               const int y3 = (pyuv)[ax+3]; \
-               (prgb)[bx+3] = sat(y3 + r); \
-               (prgb)[bx+4] = sat(y3 + g); \
-               (prgb)[bx+5] = sat(y3 + b); \
-    }
-#define IUYVY2RGB_16(pyuv, prgb, ax, bx) \
-       IUYVY2RGB_8(pyuv, prgb, ax, bx) \
-       IUYVY2RGB_8(pyuv, prgb, ax + 16, bx + 24)
-#define IUYVY2RGB_8(pyuv, prgb, ax, bx) \
-       IUYVY2RGB_4(pyuv, prgb, ax, bx) \
-       IUYVY2RGB_4(pyuv, prgb, ax + 8, bx + 12)
-#define IUYVY2RGB_4(pyuv, prgb, ax, bx) \
-       IUYVY2RGB_2(pyuv, prgb, ax, bx) \
-       IUYVY2RGB_2(pyuv, prgb, ax + 4, bx + 6)
-
-/** @brief Convert a frame from UYVY to RGB888
- * @ingroup frame
- * @param ini UYVY frame
- * @param out RGB888 frame
- */
-uvc_error_t uvc_uyvy2rgb(uvc_frame_t *in, uvc_frame_t *out) {
-       if (UNLIKELY(in->frame_format != UVC_FRAME_FORMAT_UYVY))
-               return UVC_ERROR_INVALID_PARAM;
-
-       if (UNLIKELY(uvc_ensure_frame_size(out, in->width * in->height * PIXEL_RGB) < 0))
-               return UVC_ERROR_NO_MEM;
-
-       out->width = in->width;
-       out->height = in->height;
-       out->frame_format = UVC_FRAME_FORMAT_RGB;
-       if (out->library_owns_data)
-               out->step = in->width * PIXEL_RGB;
-       out->sequence = in->sequence;
-       out->capture_time = in->capture_time;
-       out->source = in->source;
-
-       uint8_t *pyuv = in->data;
-       const uint8_t *pyuv_end = pyuv + in->data_bytes - PIXEL8_UYVY;
-       uint8_t *prgb = out->data;
-       const uint8_t *prgb_end = prgb + out->data_bytes - PIXEL8_RGB;
-
-       // UYVY => RGB888
-#if USE_STRIDE
-       if (in->step && out->step && (in->step != out->step)) {
-               const int hh = in->height < out->height ? in->height : out->height;
-               const int ww = in->width < out->width ? in->width : out->width;
-               int h, w;
-               for (h = 0; h < hh; h++) {
-                       w = 0;
-                       pyuv = in->data + in->step * h;
-                       prgb = out->data + out->step * h;
-                       for (; (prgb <= prgb_end) && (pyuv <= pyuv_end) && (w < ww) ;) {
-                               IUYVY2RGB_8(pyuv, prgb, 0, 0);
-
-                               prgb += PIXEL8_RGB;
-                               pyuv += PIXEL8_UYVY;
-                               w += 8;
-                       }
-               }
-       } else {
-               // compressed format? XXX if only one of the frame in / out has step, this may lead to crash...
-               for (; (prgb <= prgb_end) && (pyuv <= pyuv_end) ;) {
-                       IUYVY2RGB_8(pyuv, prgb, 0, 0);
-
-                       prgb += PIXEL8_RGB;
-                       pyuv += PIXEL8_UYVY;
-               }
-       }
-#else
-       for (; ((prgb <= prgb_end) && (pyuv <= pyuv_end) ;) {
-               IUYVY2RGB_8(pyuv, prgb, 0, 0);
-
-               prgb += PIXEL8_RGB;
-               pyuv += PIXEL8_UYVY;
-       }
-#endif
-       return UVC_SUCCESS;
-}
-
-/** @brief Convert a frame from UYVY to RGB565
- * @ingroup frame
- * @param ini UYVY frame
- * @param out RGB565 frame
- */
-uvc_error_t uvc_uyvy2rgb565(uvc_frame_t *in, uvc_frame_t *out) {
-       if (UNLIKELY(in->frame_format != UVC_FRAME_FORMAT_UYVY))
-               return UVC_ERROR_INVALID_PARAM;
-
-       if (UNLIKELY(uvc_ensure_frame_size(out, in->width * in->height * PIXEL_RGB565) < 0))
-               return UVC_ERROR_NO_MEM;
-
-       out->width = in->width;
-       out->height = in->height;
-       out->frame_format = UVC_FRAME_FORMAT_RGB565;
-       if (out->library_owns_data)
-               out->step = in->width * PIXEL_RGB565;
-       out->sequence = in->sequence;
-       out->capture_time = in->capture_time;
-       out->source = in->source;
-
-       uint8_t *pyuv = in->data;
-       const uint8_t *pyuv_end = pyuv + in->data_bytes - PIXEL8_UYVY;
-       uint8_t *prgb565 = out->data;
-       const uint8_t *prgb565_end = prgb565 + out->data_bytes - PIXEL8_RGB565;
-
-       uint8_t tmp[PIXEL8_RGB];                // for temporary rgb888 data(8pixel)
-
-       // UYVY => RGB565
-#if USE_STRIDE
-       if (in->step && out->step && (in->step != out->step)) {
-               const int hh = in->height < out->height ? in->height : out->height;
-               const int ww = in->width < out->width ? in->width : out->width;
-               int h, w;
-               for (h = 0; h < hh; h++) {
-                       w = 0;
-                       pyuv = in->data + in->step * h;
-                       prgb565 = out->data + out->step * h;
-                       for (; (prgb565 <= prgb565_end) && (pyuv <= pyuv_end) && (w < ww) ;) {
-                               IUYVY2RGB_8(pyuv, tmp, 0, 0);
-                               RGB2RGB565_8(tmp, prgb565, 0, 0);
-
-                               prgb565 += PIXEL8_RGB565;
-                               pyuv += PIXEL8_UYVY;
-                               w += 8;
-                       }
-               }
-       } else {
-               // compressed format? XXX if only one of the frame in / out has step, this may lead to crash...
-               for (; (prgb565 <= prgb565_end) && (pyuv <= pyuv_end) ;) {
-                       IUYVY2RGB_8(pyuv, tmp, 0, 0);
-                       RGB2RGB565_8(tmp, prgb565, 0, 0);
-
-                       prgb565 += PIXEL8_RGB565;
-                       pyuv += PIXEL8_UYVY;
-               }
-       }
-#else
-       for (; (prgb565 <= prgb565_end) && (pyuv <= pyuv_end) ;) {
-               IUYVY2RGB_8(pyuv, tmp, 0, 0);
-               RGB2RGB565_8(tmp, prgb565, 0, 0);
-
-               prgb565 += PIXEL8_RGB565;
-               pyuv += PIXEL8_UYVY;
-       }
-#endif
-       return UVC_SUCCESS;
-}
-
-#define IUYVY2RGBX_2(pyuv, prgbx, ax, bx) { \
-               const int d0 = (pyuv)[ax+0]; \
-               const int d2 = (pyuv)[ax+2]; \
-           const int r = (22987 * (d2/*(pyuv)[ax+2]*/ - 128)) >> 14; \
-           const int g = (-5636 * (d0/*(pyuv)[ax+0]*/ - 128) - 11698 * (d2/*(pyuv)[ax+2]*/ - 128)) >> 14; \
-           const int b = (29049 * (d0/*(pyuv)[ax+0]*/ - 128)) >> 14; \
-               const int y1 = (pyuv)[ax+1]; \
-               (prgbx)[bx+0] = sat(y1 + r); \
-               (prgbx)[bx+1] = sat(y1 + g); \
-               (prgbx)[bx+2] = sat(y1 + b); \
-               (prgbx)[bx+3] = 0xff; \
-               const int y3 = (pyuv)[ax+3]; \
-               (prgbx)[bx+4] = sat(y3 + r); \
-               (prgbx)[bx+5] = sat(y3 + g); \
-               (prgbx)[bx+6] = sat(y3 + b); \
-               (prgbx)[bx+7] = 0xff; \
-    }
-#define IUYVY2RGBX_16(pyuv, prgbx, ax, bx) \
-       IUYVY2RGBX_8(pyuv, prgbx, ax, bx) \
-       IUYVY2RGBX_8(pyuv, prgbx, ax + PIXEL8_UYVY, bx + PIXEL8_RGBX)
-#define IUYVY2RGBX_8(pyuv, prgbx, ax, bx) \
-       IUYVY2RGBX_4(pyuv, prgbx, ax, bx) \
-       IUYVY2RGBX_4(pyuv, prgbx, ax + PIXEL4_UYVY, bx + PIXEL4_RGBX)
-#define IUYVY2RGBX_4(pyuv, prgbx, ax, bx) \
-       IUYVY2RGBX_2(pyuv, prgbx, ax, bx) \
-       IUYVY2RGBX_2(pyuv, prgbx, ax + PIXEL2_UYVY, bx + PIXEL2_RGBX)
-
-/** @brief Convert a frame from UYVY to RGBX8888
- * @ingroup frame
- * @param ini UYVY frame
- * @param out RGBX8888 frame
- */
-uvc_error_t uvc_uyvy2rgbx(uvc_frame_t *in, uvc_frame_t *out) {
-       if (UNLIKELY(in->frame_format != UVC_FRAME_FORMAT_UYVY))
-               return UVC_ERROR_INVALID_PARAM;
-
-       if (UNLIKELY(uvc_ensure_frame_size(out, in->width * in->height * PIXEL_RGBX) < 0))
-               return UVC_ERROR_NO_MEM;
-
-       out->width = in->width;
-       out->height = in->height;
-       out->frame_format = UVC_FRAME_FORMAT_RGBX;
-       if (out->library_owns_data)
-               out->step = in->width * PIXEL_RGBX;
-       out->sequence = in->sequence;
-       out->capture_time = in->capture_time;
-       out->source = in->source;
-
-       uint8_t *pyuv = in->data;
-       const uint8_t *pyuv_end = pyuv + in->data_bytes - PIXEL8_UYVY;
-       uint8_t *prgbx = out->data;
-       const uint8_t *prgbx_end = prgbx + out->data_bytes - PIXEL8_RGBX;
-
-       // UYVY => RGBX8888
-#if USE_STRIDE
-       if (in->step && out->step && (in->step != out->step)) {
-               const int hh = in->height < out->height ? in->height : out->height;
-               const int ww = in->width < out->width ? in->width : out->width;
-               int h, w;
-               for (h = 0; h < hh; h++) {
-                       w = 0;
-                       pyuv = in->data + in->step * h;
-                       prgbx = out->data + out->step * h;
-                       for (; (prgbx <= prgbx_end) && (pyuv <= pyuv_end) && (w < ww) ;) {
-                               IUYVY2RGBX_8(pyuv, prgbx, 0, 0);
-
-                               prgbx += PIXEL8_RGBX;
-                               pyuv += PIXEL8_UYVY;
-                               w += 8;
-                       }
-               }
-       } else {
-               // compressed format? XXX if only one of the frame in / out has step, this may lead to crash...
-               for (; (prgbx <= prgbx_end) && (pyuv <= pyuv_end) ;) {
-                       IUYVY2RGBX_8(pyuv, prgbx, 0, 0);
-
-                       prgbx += PIXEL8_RGBX;
-                       pyuv += PIXEL8_UYVY;
-               }
-       }
-#else
-       for (; (prgbx <= prgbx_end) && (pyuv <= pyuv_end) ;) {
-               IUYVY2RGBX_8(pyuv, prgbx, 0, 0);
-
-               prgbx += PIXEL8_RGBX;
-               pyuv += PIXEL8_UYVY;
-       }
-#endif
-       return UVC_SUCCESS;
-}
-
-#define IUYVY2BGR_2(pyuv, pbgr, ax, bx) { \
-               const int d0 = (pyuv)[ax+0]; \
-               const int d2 = (pyuv)[ax+2]; \
-           const int r = (22987 * (d2/*(pyuv)[ax+2]*/ - 128)) >> 14; \
-           const int g = (-5636 * (d0/*(pyuv)[ax+0]*/ - 128) - 11698 * (d2/*(pyuv)[ax+2]*/ - 128)) >> 14; \
-           const int b = (29049 * (d0/*(pyuv)[ax+0]*/ - 128)) >> 14; \
-               const int y1 = (pyuv)[ax+1]; \
-               (pbgr)[bx+0] = sat(y1 + b); \
-               (pbgr)[bx+1] = sat(y1 + g); \
-               (pbgr)[bx+2] = sat(y1 + r); \
-               const int y3 = (pyuv)[ax+3]; \
-               (pbgr)[bx+3] = sat(y3 + b); \
-               (pbgr)[bx+4] = sat(y3 + g); \
-               (pbgr)[bx+5] = sat(y3 + r); \
-    }
-#define IUYVY2BGR_16(pyuv, pbgr, ax, bx) \
-       IUYVY2BGR_8(pyuv, pbgr, ax, bx) \
-       IUYVY2BGR_8(pyuv, pbgr, ax + PIXEL8_UYVY, bx + PIXEL8_BGR)
-#define IUYVY2BGR_8(pyuv, pbgr, ax, bx) \
-       IUYVY2BGR_4(pyuv, pbgr, ax, bx) \
-       IUYVY2BGR_4(pyuv, pbgr, ax + PIXEL4_UYVY, bx + PIXEL4_BGR)
-#define IUYVY2BGR_4(pyuv, pbgr, ax, bx) \
-       IUYVY2BGR_2(pyuv, pbgr, ax, bx) \
-       IUYVY2BGR_2(pyuv, pbgr, ax + PIXEL2_UYVY, bx + PIXEL2_BGR)
-
-/** @brief Convert a frame from UYVY to BGR888
- * @ingroup frame
- * @param ini UYVY frame
- * @param out BGR888 frame
- */
-uvc_error_t uvc_uyvy2bgr(uvc_frame_t *in, uvc_frame_t *out) {
-       if (UNLIKELY(in->frame_format != UVC_FRAME_FORMAT_UYVY))
-               return UVC_ERROR_INVALID_PARAM;
-
-       if (UNLIKELY(uvc_ensure_frame_size(out, in->width * in->height * PIXEL_BGR) < 0))
-               return UVC_ERROR_NO_MEM;
-
-       out->width = in->width;
-       out->height = in->height;
-       out->frame_format = UVC_FRAME_FORMAT_BGR;
-       if (out->library_owns_data)
-               out->step = in->width * PIXEL_BGR;
-       out->sequence = in->sequence;
-       out->capture_time = in->capture_time;
-       out->source = in->source;
-
-       uint8_t *pyuv = in->data;
-       const uint8_t *pyuv_end = pyuv + in->data_bytes - PIXEL8_UYVY;
-       uint8_t *pbgr = out->data;
-       const uint8_t *pbgr_end = pbgr + out->data_bytes - PIXEL8_BGR;
-
-       // UYVY => BGR888
-#if USE_STRIDE
-       if (in->step && out->step && (in->step != out->step)) {
-               const int hh = in->height < out->height ? in->height : out->height;
-               const int ww = in->width < out->width ? in->width : out->width;
-               int h, w;
-               for (h = 0; h < hh; h++) {
-                       w = 0;
-                       pyuv = in->data + in->step * h;
-                       pbgr = out->data + out->step * h;
-                       for (; (pbgr <= pbgr_end) && (pyuv <= pyuv_end) && (w < ww) ;) {
-                               IUYVY2BGR_8(pyuv, pbgr, 0, 0);
-
-                               pbgr += PIXEL8_BGR;
-                               pyuv += PIXEL8_UYVY;
-                               w += 8;
-                       }
-               }
-       } else {
-               // compressed format? XXX if only one of the frame in / out has step, this may lead to crash...
-               for (; (pbgr <= pbgr_end) && (pyuv <= pyuv_end) ;) {
-                       IUYVY2BGR_8(pyuv, pbgr, 0, 0);
-
-                       pbgr += PIXEL8_BGR;
-                       pyuv += PIXEL8_UYVY;
-               }
-       }
-#else
-       for (; (pbgr <= pbgr_end) && (pyuv <= pyuv_end) ;) {
-               IUYVY2BGR_8(pyuv, pbgr, 0, 0);
-
-               pbgr += PIXEL8_BGR;
-               pyuv += PIXEL8_UYVY;
-       }
-#endif
-       return UVC_SUCCESS;
-}
-
-int uvc_yuyv2yuv420P(uvc_frame_t *in, uvc_frame_t *out) {
-
-       ENTER();
-       
-       if (UNLIKELY(in->frame_format != UVC_FRAME_FORMAT_YUYV))
-               RETURN(UVC_ERROR_INVALID_PARAM, uvc_error_t);
-
-       if (UNLIKELY(uvc_ensure_frame_size(out, (in->width * in->height * 3) / 2) < 0))
-               RETURN(UVC_ERROR_NO_MEM, uvc_error_t);
-
-       const uint8_t *src = in->data;
-       uint8_t *dest = out->data;
-       const int32_t width = in->width;
-       const int32_t height = in->height;
-       const int32_t src_width = in->step;
-       const int32_t src_height = in->height;
-       const int32_t dest_width = out->width = out->step = in->width;
-       const int32_t dest_height = out->height = in->height;
-       const uint32_t hh = src_height < dest_height ? src_height : dest_height;
-       uint8_t *y = dest;
-       uint8_t *v = dest + dest_width * dest_height;
-       uint8_t *u = dest + dest_width * dest_height * 5 / 4;
-       int h, w;
-       for (h = 0; h < hh; h++) {
-               const uint8_t *yuv = src + src_width * h;
-               for (w = 0; w < width; w += 4) {
-                       *(y++) = yuv[0];        // y
-                       *(y++) = yuv[2];        // y'
-                       *(y++) = yuv[4];        // y''
-                       *(y++) = yuv[6];        // y'''
-                       if ((h & 1) == 1) {
-                               *(u++) = yuv[3];        // u
-                               *(u++) = yuv[7];        // u
-                       } else {
-                               *(v++) = yuv[1];        // v
-                               *(v++) = yuv[5];        // v
-                       }
-                       yuv += 8;       // (1pixel=2bytes)x4pixel=8bytes
-               }
-       }
-       RETURN(0, int);
-}
-
-//--------------------------------------------------------------------------------
-int uvc_yuyv2iyuv420P(uvc_frame_t *in, uvc_frame_t *out) {
-
-       ENTER();
-       
-       if (UNLIKELY(in->frame_format != UVC_FRAME_FORMAT_YUYV))
-               RETURN(UVC_ERROR_INVALID_PARAM, uvc_error_t);
-
-       if (UNLIKELY(uvc_ensure_frame_size(out, (in->width * in->height * 3) / 2) < 0))
-               RETURN(UVC_ERROR_NO_MEM, uvc_error_t);
-
-       const uint8_t *src = in->data;
-       uint8_t *dest = out->data;
-       const int32_t width = in->width;
-       const int32_t height = in->height;
-       const int32_t src_width = in->step;
-       const int32_t src_height = in->height;
-       const int32_t dest_width = out->width = out->step = in->width;
-       const int32_t dest_height = out->height = in->height;
-       const uint32_t hh = src_height < dest_height ? src_height : dest_height;
-       uint8_t *y = dest;
-       uint8_t *u = dest + dest_width * dest_height * 5 / 4;
-       uint8_t *v = dest + dest_width * dest_height * 5 / 4;
-       int h, w;
-       for (h = 0; h < hh; h++) {
-               const uint8_t *yuv = src + src_width * h;
-               for (w = 0; w < width; w += 4) {
-                       *(y++) = yuv[0];        // y
-                       *(y++) = yuv[2];        // y'
-                       *(y++) = yuv[4];        // y''
-                       *(y++) = yuv[6];        // y'''
-                       if ((h & 1) == 1) {
-                               *(u++) = yuv[3];        // u
-                               *(u++) = yuv[7];        // u
-                       } else {
-                               *(v++) = yuv[1];        // v
-                               *(v++) = yuv[5];        // v
-                       }
-                       yuv += 8;       // (1pixel=2bytes)x4pixel=8bytes
-               }
-       }
-       RETURN(0, int);
-}
-
-uvc_error_t uvc_yuyv2yuv420SP(uvc_frame_t *in, uvc_frame_t *out) {
-       ENTER();
-       
-       if (UNLIKELY(in->frame_format != UVC_FRAME_FORMAT_YUYV))
-               RETURN(UVC_ERROR_INVALID_PARAM, uvc_error_t);
-
-       if (UNLIKELY(uvc_ensure_frame_size(out, (in->width * in->height * 3) / 2) < 0))
-               RETURN(UVC_ERROR_NO_MEM, uvc_error_t);
-
-       const uint8_t *src = in->data;
-       uint8_t *dest = out->data;
-       const int32_t width = in->width;
-       const int32_t height = in->height;
-       const int32_t src_width = in->step;
-       const int32_t src_height = in->height;
-       const int32_t dest_width = out->width = out->step = in->width;
-       const int32_t dest_height = out->height = in->height;
-
-       const uint32_t hh = src_height < dest_height ? src_height : dest_height;
-       uint8_t *uv = dest + dest_width * dest_height;
-       int h, w;
-       for (h = 0; h < hh - 1; h += 2) {
-               uint8_t *y0 = dest + width * h;
-               uint8_t *y1 = y0 + width;
-               const uint8_t *yuv = src + src_width * h;
-               for (w = 0; w < width; w += 4) {
-                       *(y0++) = yuv[0];       // y
-                       *(y0++) = yuv[2];       // y'
-                       *(y0++) = yuv[4];       // y''
-                       *(y0++) = yuv[6];       // y'''
-                       *(uv++) = yuv[1];       // u
-                       *(uv++) = yuv[3];       // v
-                       *(uv++) = yuv[5];       // u
-                       *(uv++) = yuv[7];       // v
-                       *(y1++) = yuv[src_width+0];     // y on next low
-                       *(y1++) = yuv[src_width+2];     // y' on next low
-                       *(y1++) = yuv[src_width+4];     // y''  on next low
-                       *(y1++) = yuv[src_width+6];     // y'''  on next low
-                       yuv += 8;       // (1pixel=2bytes)x4pixels=8bytes
-               }
-       }
-       
-       RETURN(UVC_SUCCESS, uvc_error_t);
-}
-
-uvc_error_t uvc_yuyv2iyuv420SP(uvc_frame_t *in, uvc_frame_t *out) {
-       ENTER();
-       
-       if (UNLIKELY(in->frame_format != UVC_FRAME_FORMAT_YUYV))
-               RETURN(UVC_ERROR_INVALID_PARAM, uvc_error_t);
-
-       if (UNLIKELY(uvc_ensure_frame_size(out, (in->width * in->height * 3) / 2) < 0))
-               return UVC_ERROR_NO_MEM;
-
-       const uint8_t *src = in->data;
-       uint8_t *dest =out->data;
-       const int32_t width = in->width;
-       const int32_t height = in->height;
-       const int32_t src_width = in->step;
-       const int32_t src_height = in->height;
-       const int32_t dest_width = out->width = out->step = in->width;
-       const int32_t dest_height = out->height = in->height;
-
-       const uint32_t hh = src_height < dest_height ? src_height : dest_height;
-       uint8_t *uv = dest + dest_width * dest_height;
-       int h, w;
-       for (h = 0; h < hh - 1; h += 2) {
-               uint8_t *y0 = dest + width * h;
-               uint8_t *y1 = y0 + width;
-               const uint8_t *yuv = src + src_width * h;
-               for (w = 0; w < width; w += 4) {
-                       *(y0++) = yuv[0];       // y
-                       *(y0++) = yuv[2];       // y'
-                       *(y0++) = yuv[4];       // y''
-                       *(y0++) = yuv[6];       // y'''
-                       *(uv++) = yuv[3];       // v
-                       *(uv++) = yuv[1];       // u
-                       *(uv++) = yuv[7];       // v
-                       *(uv++) = yuv[5];       // u
-                       *(y1++) = yuv[src_width+0];     // y on next low
-                       *(y1++) = yuv[src_width+2];     // y' on next low
-                       *(y1++) = yuv[src_width+4];     // y''  on next low
-                       *(y1++) = yuv[src_width+6];     // y'''  on next low
-                       yuv += 8;       // (1pixel=2bytes)x4pixels=8bytes
-               }
-       }
-       
-       RETURN(UVC_SUCCESS, uvc_error_t);
-}
-
-/** @brief Convert a frame to RGB565
- * @ingroup frame
- *
- * @param in non-RGB565 frame
- * @param out RGB565 frame
- */
-uvc_error_t uvc_any2rgb565(uvc_frame_t *in, uvc_frame_t *out) {
-
-       switch (in->frame_format) {
-#ifdef LIBUVC_HAS_JPEG
-       case UVC_FRAME_FORMAT_MJPEG:
-               return uvc_mjpeg2rgb565(in, out);
-#endif
-       case UVC_FRAME_FORMAT_YUYV:
-               return uvc_yuyv2rgb565(in, out);
-       case UVC_FRAME_FORMAT_UYVY:
-               return uvc_uyvy2rgb565(in, out);
-       case UVC_FRAME_FORMAT_RGB565:
-               return uvc_duplicate_frame(in, out);
-       case UVC_FRAME_FORMAT_RGB:
-               return uvc_rgb2rgb565(in, out);
-       default:
-               return UVC_ERROR_NOT_SUPPORTED;
-       }
-}
-
-/** @brief Convert a frame to RGB888
- * @ingroup frame
- *
- * @param in non-RGB888 frame
- * @param out RGB888 frame
- */
-uvc_error_t uvc_any2rgb(uvc_frame_t *in, uvc_frame_t *out) {
-
-       switch (in->frame_format) {
-#ifdef LIBUVC_HAS_JPEG
-       case UVC_FRAME_FORMAT_MJPEG:
-               return uvc_mjpeg2rgb(in, out);
-#endif
-       case UVC_FRAME_FORMAT_YUYV:
-               return uvc_yuyv2rgb(in, out);
-       case UVC_FRAME_FORMAT_UYVY:
-               return uvc_uyvy2rgb(in, out);
-       case UVC_FRAME_FORMAT_RGB:
-               return uvc_duplicate_frame(in, out);
-       default:
-               return UVC_ERROR_NOT_SUPPORTED;
-       }
-}
-
-/** @brief Convert a frame to BGR888
- * @ingroup frame
- *
- * @param in non-BGR888 frame
- * @param out BGR888 frame
- */
-uvc_error_t uvc_any2bgr(uvc_frame_t *in, uvc_frame_t *out) {
-
-       switch (in->frame_format) {
-#ifdef LIBUVC_HAS_JPEG
-       case UVC_FRAME_FORMAT_MJPEG:
-               return uvc_mjpeg2bgr(in, out);
-#endif
-       case UVC_FRAME_FORMAT_YUYV:
-               return uvc_yuyv2bgr(in, out);
-       case UVC_FRAME_FORMAT_UYVY:
-               return uvc_uyvy2bgr(in, out);
-       case UVC_FRAME_FORMAT_BGR:
-               return uvc_duplicate_frame(in, out);
-       default:
-               return UVC_ERROR_NOT_SUPPORTED;
-       }
-}
-
-/** @brief Convert a frame to RGBX8888
- * @ingroup frame
- *
- * @param in non-rgbx frame
- * @param out rgbx frame
- */
-uvc_error_t uvc_any2rgbx(uvc_frame_t *in, uvc_frame_t *out) {
-
-       switch (in->frame_format) {
-#ifdef LIBUVC_HAS_JPEG
-       case UVC_FRAME_FORMAT_MJPEG:
-               return uvc_mjpeg2rgbx(in, out);
-#endif
-       case UVC_FRAME_FORMAT_YUYV:
-               return uvc_yuyv2rgbx(in, out);
-       case UVC_FRAME_FORMAT_UYVY:
-               return uvc_uyvy2rgbx(in, out);
-       case UVC_FRAME_FORMAT_RGBX:
-               return uvc_duplicate_frame(in, out);
-       case UVC_FRAME_FORMAT_RGB:
-               return uvc_rgb2rgbx(in, out);
-       default:
-               return UVC_ERROR_NOT_SUPPORTED;
-       }
-}
-
-/** @brief Convert a frame to yuyv
- * @ingroup frame
- *
- * @param in non-yuyv frame
- * @param out yuyv frame
- */
-uvc_error_t uvc_any2yuyv(uvc_frame_t *in, uvc_frame_t *out) {
-
-       switch (in->frame_format) {
-#ifdef LIBUVC_HAS_JPEG
-       case UVC_FRAME_FORMAT_MJPEG:
-               return uvc_mjpeg2yuyv(in, out);
-#endif
-       case UVC_FRAME_FORMAT_YUYV:
-               return uvc_duplicate_frame(in, out);
-       default:
-               return UVC_ERROR_NOT_SUPPORTED;
-       }
-}
-
-/** @brief Convert a frame to yuv420sp
- * @ingroup frame
- *
- * @param in non-yuv420sp frame
- * @param out yuv420sp frame
- */
-uvc_error_t uvc_any2yuv420SP(uvc_frame_t *in, uvc_frame_t *out) {
-       uvc_error_t result = UVC_ERROR_NO_MEM;
-       uvc_frame_t *yuv = uvc_allocate_frame((in->width * in->height * 3) / 2);
-       if (yuv) {
-               result = uvc_any2yuyv(in, yuv);
-               if (LIKELY(!result)) {
-                       result = uvc_yuyv2yuv420SP(yuv, out);
-               }
-               uvc_free_frame(yuv);
-       }
-       return result;
-}
-
-/** @brief Convert a frame to iyuv420sp(NV21)
- * @ingroup frame
- *
- * @param in non-iyuv420SP(NV21) frame
- * @param out iyuv420SP(NV21) frame
- */
-uvc_error_t uvc_any2iyuv420SP(uvc_frame_t *in, uvc_frame_t *out) {
-       uvc_error_t result = UVC_ERROR_NO_MEM;
-       uvc_frame_t *yuv = uvc_allocate_frame((in->width * in->height * 3) / 2);
-       if (yuv) {
-               result = uvc_any2yuyv(in, yuv);
-               if (LIKELY(!result)) {
-                       result = uvc_yuyv2iyuv420SP(yuv, out);
-               }
-               uvc_free_frame(yuv);
-       }
-       return result;
-}