Merge "[gl] Increase the color precision in TextureResize" into emu-master-dev
diff --git a/android/avd/info.c b/android/avd/info.c
index 484aaa9..de69351 100644
--- a/android/avd/info.c
+++ b/android/avd/info.c
@@ -1432,9 +1432,9 @@
int avdInfo_getAdbdCommunicationMode( const AvdInfo* i )
{
- if (i->apiLevel < 16) {
+ if (i->apiLevel < 16 || i->apiLevel > 99) {
// QEMU pipe for ADB communication was added in android-4.1.1_r1 API 16
- D("API < 16, forcing ro.adb.qemud==0");
+ D("API < 16 or unknown, forcing ro.adb.qemud==0");
return 0;
}
diff --git a/android/camera/camera-format-converters.c b/android/camera/camera-format-converters.c
index ada82ae..c6b8c75 100644
--- a/android/camera/camera-format-converters.c
+++ b/android/camera/camera-format-converters.c
@@ -15,6 +15,7 @@
*/
#include "android/camera/camera-format-converters.h"
+#include "android/utils/misc.h"
#ifdef __linux__
#include <linux/videodev2.h>
@@ -453,29 +454,17 @@
*/
typedef void* (*save_rgb_func)(void* rgb, uint8_t r, uint8_t g, uint8_t b);
-/* Prototype for a routine that calculates an offset of the first U value for the
- * given line in a YUV framebuffer.
+/* Prototype for a routine that calculates an offset of the first Y, U or V
+ * value for the given line in a YUV framebuffer.
* Param:
* desc - Descriptor for the YUV frame for which the offset is being calculated.
* line - Zero-based line number for which to calculate the offset.
* width, height - Frame dimensions.
* Return:
- * Offset of the first U value for the given frame line. The offset returned
- * here is relative to the beginning of the YUV framebuffer.
+ * Offset of the first Y, U or V value for the given frame line. The offset
+ * returned here is relative to the beginning of the YUV framebuffer.
*/
-typedef int (*u_offset_func)(const YUVDesc* desc, int line, int width, int height);
-
-/* Prototype for a routine that calculates an offset of the first V value for the
- * given line in a YUV framebuffer.
- * Param:
- * desc - Descriptor for the YUV frame for which the offset is being calculated.
- * line - Zero-based line number for which to calculate the offset.
- * width, height - Frame dimensions.
- * Return:
- * Offset of the first V value for the given frame line. The offset returned
- * here is relative to the beginning of the YUV framebuffer.
- */
-typedef int (*v_offset_func)(const YUVDesc* desc, int line, int width, int height);
+typedef int (*yuv_offset_func)(const YUVDesc* desc, int line, int width, int height);
/* RGB/BRG format descriptor. */
struct RGBDesc {
@@ -513,12 +502,15 @@
/* Controls location of the first V value in YUV framebuffer.
* See comments to U_offset for more info. */
int V_offset;
+ /* Routine that calculates an offset of the first Y value for the given line
+ * in a YUV framebuffer. */
+ yuv_offset_func y_offset;
/* Routine that calculates an offset of the first U value for the given line
* in a YUV framebuffer. */
- u_offset_func u_offset;
+ yuv_offset_func u_offset;
/* Routine that calculates an offset of the first V value for the given line
* in a YUV framebuffer. */
- v_offset_func v_offset;
+ yuv_offset_func v_offset;
};
/* Bayer format descriptor. */
@@ -659,9 +651,26 @@
#endif
/********************************************************************************
- * YUV's U/V offset calculation routines.
+ * YUV's Y/U/V offset calculation routines.
*******************************************************************************/
+/* Y offset in an aligned format such as YV12 */
+static int YOffAlignedYUV(const YUVDesc* desc, int line, int width, int height)
+{
+ int stride = align(width, 16);
+ // As the name implies the Y_next_pair value skips a pair of values. Since
+ // this is counting values, not pairs, per line we divide by two.
+ return line * stride * (desc->Y_next_pair / 2) + desc->Y_offset;
+}
+
+/* Y offset in a packed format with no padding or alignment requirements */
+static int YOffPackedYUV(const YUVDesc* desc, int line, int width, int height)
+{
+ // As the name implies the Y_next_pair value skips a pair of values. Since
+ // this is counting values, not pairs, per line we divide by two.
+ return line * width * (desc->Y_next_pair / 2) + desc->Y_offset;
+}
+
/* U offset in a fully interleaved YUV 4:2:2 */
static int
_UOffIntrlYUV(const YUVDesc* desc, int line, int width, int height)
@@ -704,9 +713,9 @@
return (height + line / 2) * width + desc->V_offset;
}
-/* U offset in a 3-pane YUV 4:2:0 */
+/* U offset in a 3-pane aligned YUV 4:2:0 */
static int
-_UOffSepYUV(const YUVDesc* desc, int line, int width, int height)
+_UOffSepAlignedYUV(const YUVDesc* desc, int line, int width, int height)
{
/* U, or V pane starts right after the Y pane, that occupies 'height * width'
* bytes. Eacht line in each of U and V panes contains width / 2 elements.
@@ -721,28 +730,32 @@
*
* for the second pane.
*/
- const int y_pane_size = height * width;
+ const int y_stride = align(width, 16);
+ const int uv_stride = align(y_stride / 2, 16);
+ const int y_pane_size = height * y_stride;
if (desc->U_offset) {
/* U pane comes right after the Y pane. */
- return y_pane_size + (line / 2) * width / 2;
+ return y_pane_size + (line / 2) * uv_stride;
} else {
/* U pane follows V pane. */
- return y_pane_size + y_pane_size / 4 + (line / 2) * width / 2;
+ return y_pane_size + (height / 2 + line / 2) * uv_stride;
}
}
-/* V offset in a 3-pane YUV 4:2:0 */
+/* V offset in a 3-pane aligned YUV 4:2:0 */
static int
-_VOffSepYUV(const YUVDesc* desc, int line, int width, int height)
+_VOffSepAlignedYUV(const YUVDesc* desc, int line, int width, int height)
{
/* See comment for _UOffSepYUV. */
- const int y_pane_size = height * width;
+ const int y_stride = align(width, 16);
+ const int uv_stride = align(y_stride / 2, 16);
+ const int y_pane_size = height * y_stride;
if (desc->V_offset) {
/* V pane comes right after the Y pane. */
- return y_pane_size + (line / 2) * width / 2;
+ return y_pane_size + (line / 2) * uv_stride;
} else {
/* V pane follows U pane. */
- return y_pane_size + y_pane_size / 4 + (line / 2) * width / 2;
+ return y_pane_size + (height / 2 + line / 2) * uv_stride;
}
}
@@ -1018,8 +1031,9 @@
const int Y_Inc = yuv_fmt->Y_inc;
const int UV_inc = yuv_fmt->UV_inc;
const int Y_next_pair = yuv_fmt->Y_next_pair;
- uint8_t* pY = (uint8_t*)yuv + yuv_fmt->Y_offset;
for (y = 0; y < height; y++) {
+ uint8_t* pY =
+ (uint8_t*)yuv + yuv_fmt->y_offset(yuv_fmt, y, width, height);
uint8_t* pU =
(uint8_t*)yuv + yuv_fmt->u_offset(yuv_fmt, y, width, height);
uint8_t* pV =
@@ -1086,8 +1100,9 @@
const int Y_Inc = yuv_fmt->Y_inc;
const int UV_inc = yuv_fmt->UV_inc;
const int Y_next_pair = yuv_fmt->Y_next_pair;
- const uint8_t* pY = (const uint8_t*)yuv + yuv_fmt->Y_offset;
for (y = 0; y < height; y++) {
+ const uint8_t* pY =
+ (const uint8_t*)yuv + yuv_fmt->y_offset(yuv_fmt, y, width, height);
const uint8_t* pU =
(const uint8_t*)yuv + yuv_fmt->u_offset(yuv_fmt, y, width, height);
const uint8_t* pV =
@@ -1131,13 +1146,15 @@
const int Y_Inc_dst = dst_fmt->Y_inc;
const int UV_inc_dst = dst_fmt->UV_inc;
const int Y_next_pair_dst = dst_fmt->Y_next_pair;
- const uint8_t* pYsrc = (const uint8_t*)src + src_fmt->Y_offset;
- uint8_t* pYdst = (uint8_t*)dst + dst_fmt->Y_offset;
for (y = 0; y < height; y++) {
+ const uint8_t* pYsrc =
+ (const uint8_t*)src + src_fmt->y_offset(src_fmt, y, width, height);
const uint8_t* pUsrc =
(const uint8_t*)src + src_fmt->u_offset(src_fmt, y, width, height);
const uint8_t* pVsrc =
(const uint8_t*)src + src_fmt->v_offset(src_fmt, y, width, height);
+ uint8_t* pYdst =
+ (uint8_t*)dst + dst_fmt->y_offset(dst_fmt, y, width, height);
uint8_t* pUdst =
(uint8_t*)dst + dst_fmt->u_offset(dst_fmt, y, width, height);
uint8_t* pVdst =
@@ -1205,8 +1222,9 @@
const int Y_Inc = yuv_fmt->Y_inc;
const int UV_inc = yuv_fmt->UV_inc;
const int Y_next_pair = yuv_fmt->Y_next_pair;
- uint8_t* pY = (uint8_t*)yuv + yuv_fmt->Y_offset;
for (y = 0; y < height; y++) {
+ uint8_t* pY =
+ (uint8_t*)yuv + yuv_fmt->y_offset(yuv_fmt, y, width, height);
uint8_t* pU =
(uint8_t*)yuv + yuv_fmt->u_offset(yuv_fmt, y, width, height);
uint8_t* pV =
@@ -1293,6 +1311,7 @@
.UV_inc = 4,
.U_offset = 1,
.V_offset = 3,
+ .y_offset = &YOffPackedYUV,
.u_offset = &_UOffIntrlYUV,
.v_offset = &_VOffIntrlYUV
};
@@ -1306,6 +1325,7 @@
.UV_inc = 4,
.U_offset = 0,
.V_offset = 2,
+ .y_offset = &YOffPackedYUV,
.u_offset = &_UOffIntrlYUV,
.v_offset = &_VOffIntrlYUV
};
@@ -1319,6 +1339,7 @@
.UV_inc = 4,
.U_offset = 3,
.V_offset = 1,
+ .y_offset = &YOffPackedYUV,
.u_offset = &_UOffIntrlYUV,
.v_offset = &_VOffIntrlYUV
};
@@ -1332,6 +1353,7 @@
.UV_inc = 4,
.U_offset = 2,
.V_offset = 0,
+ .y_offset = &YOffPackedYUV,
.u_offset = &_UOffIntrlYUV,
.v_offset = &_VOffIntrlYUV
};
@@ -1345,6 +1367,7 @@
.UV_inc = 4,
.U_offset = 2,
.V_offset = 3,
+ .y_offset = &YOffPackedYUV,
.u_offset = &_UOffIntrlYUV,
.v_offset = &_VOffIntrlYUV
};
@@ -1358,6 +1381,7 @@
.UV_inc = 4,
.U_offset = 3,
.V_offset = 2,
+ .y_offset = &YOffPackedYUV,
.u_offset = &_UOffIntrlYUV,
.v_offset = &_VOffIntrlYUV
};
@@ -1375,8 +1399,9 @@
.UV_inc = 1,
.U_offset = 0,
.V_offset = 1,
- .u_offset = &_UOffSepYUV,
- .v_offset = &_VOffSepYUV
+ .y_offset = &YOffAlignedYUV,
+ .u_offset = &_UOffSepAlignedYUV,
+ .v_offset = &_VOffSepAlignedYUV
};
/* YU12: 4:2:0, YUV are fully separated, V pane follows U pane */
@@ -1388,8 +1413,9 @@
.UV_inc = 1,
.U_offset = 1,
.V_offset = 0,
- .u_offset = &_UOffSepYUV,
- .v_offset = &_VOffSepYUV
+ .y_offset = &YOffAlignedYUV,
+ .u_offset = &_UOffSepAlignedYUV,
+ .v_offset = &_VOffSepAlignedYUV
};
/* NV12: 4:2:0, UV are interleaved, V follows U in UV pane */
@@ -1401,6 +1427,7 @@
.UV_inc = 2,
.U_offset = 0,
.V_offset = 1,
+ .y_offset = &YOffPackedYUV,
.u_offset = &_UOffIntrlUV,
.v_offset = &_VOffIntrlUV
};
@@ -1414,6 +1441,7 @@
.UV_inc = 2,
.U_offset = 1,
.V_offset = 0,
+ .y_offset = &YOffPackedYUV,
.u_offset = &_UOffIntrlUV,
.v_offset = &_VOffIntrlUV
};
diff --git a/android/camera/camera-service.c b/android/camera/camera-service.c
index 1ab83f3..ab4a997 100644
--- a/android/camera/camera-service.c
+++ b/android/camera/camera-service.c
@@ -805,9 +805,6 @@
_qemu_client_reply_ok(qc, NULL);
}
-static int align(int value, int alignment) {
- return (value + alignment - 1) & (~(alignment - 1));
-}
static bool calculate_video_frame_size(uint32_t format,
int width,
diff --git a/android/utils/misc.h b/android/utils/misc.h
index 86f1a3a..fc3c6fd 100644
--- a/android/utils/misc.h
+++ b/android/utils/misc.h
@@ -132,4 +132,19 @@
*/
extern int get_token_value_int(const char* params, const char* name, int* value);
+/** ALIGNMENT
+ **/
+
+/* Align a value to the next larger value that is a multiple of alignment.
+ * This only works for alignments that are powers of 2.
+ * Param:
+ * value - The value that should be aligned
+ * alignment - The alignment that value should be a multiple of
+ * Return:
+ * The aligned value
+ */
+static inline int align(int value, int alignment) {
+ return (value + alignment - 1) & (~(alignment - 1));
+}
+
ANDROID_END_HEADER