From 822d1ec3fcdae7a453463d58cf0a1ceb70bb028f Mon Sep 17 00:00:00 2001 From: jp9000 Date: Thu, 16 Apr 2015 22:51:31 -0700 Subject: [PATCH] libobs: Add packed yuv to planar 4:4:4 conversion --- libobs/media-io/format-conversion.c | 50 +++++++++++++++++++++++++++++ libobs/media-io/format-conversion.h | 5 +++ 2 files changed, 55 insertions(+) diff --git a/libobs/media-io/format-conversion.c b/libobs/media-io/format-conversion.c index 656a6c8d5..99f366c6c 100644 --- a/libobs/media-io/format-conversion.c +++ b/libobs/media-io/format-conversion.c @@ -36,6 +36,17 @@ do { \ *(uint32_t*)(lum_plane+lum_pos1) = get_m128_32_1(pack_val); \ } while (false) +#define pack_val(lum_plane, lum_pos0, lum_pos1, line1, line2, mask) \ +do { \ + __m128i pack_val = _mm_packs_epi32( \ + _mm_and_si128(line1, mask), \ + _mm_and_si128(line2, mask)); \ + pack_val = _mm_packus_epi16(pack_val, pack_val); \ + \ + *(uint32_t*)(lum_plane+lum_pos0) = get_m128_32_0(pack_val); \ + *(uint32_t*)(lum_plane+lum_pos1) = get_m128_32_1(pack_val); \ +} while (false) + #define pack_ch_1plane(uv_plane, chroma_pos, line1, line2, uv_mask) \ do { \ __m128i add_val = _mm_add_epi64( \ @@ -152,6 +163,45 @@ void compress_uyvx_to_nv12( } } +void convert_uyvx_to_i444( + const uint8_t *input, uint32_t in_linesize, + uint32_t start_y, uint32_t end_y, + uint8_t *output[], const uint32_t out_linesize[]) +{ + uint8_t *lum_plane = output[0]; + uint8_t *u_plane = output[1]; + uint8_t *v_plane = output[2]; + uint32_t width = min_uint32(in_linesize, out_linesize[0]); + uint32_t y; + + __m128i lum_mask = _mm_set1_epi32(0x0000FF00); + __m128i u_mask = _mm_set1_epi32(0x000000FF); + __m128i v_mask = _mm_set1_epi32(0x00FF0000); + + for (y = start_y; y < end_y; y += 2) { + uint32_t y_pos = y * in_linesize; + uint32_t lum_y_pos = y * out_linesize[0]; + uint32_t x; + + for (x = 0; x < width; x += 4) { + const uint8_t *img = input + y_pos + x*4; + uint32_t lum_pos0 = lum_y_pos + x; + uint32_t lum_pos1 = lum_pos0 + out_linesize[0]; + + __m128i line1 = _mm_load_si128((const __m128i*)img); + __m128i line2 = _mm_load_si128( + (const __m128i*)(img + in_linesize)); + + pack_shift(lum_plane, lum_pos0, lum_pos1, + line1, line2, lum_mask, 1); + pack_val(u_plane, lum_pos0, lum_pos1, + line1, line2, u_mask); + pack_shift(v_plane, lum_pos0, lum_pos1, + line1, line2, v_mask, 2); + } + } +} + void decompress_420( const uint8_t *const input[], const uint32_t in_linesize[], uint32_t start_y, uint32_t end_y, diff --git a/libobs/media-io/format-conversion.h b/libobs/media-io/format-conversion.h index c91f3ec5b..ea88005fd 100644 --- a/libobs/media-io/format-conversion.h +++ b/libobs/media-io/format-conversion.h @@ -37,6 +37,11 @@ EXPORT void compress_uyvx_to_nv12( uint32_t start_y, uint32_t end_y, uint8_t *output[], const uint32_t out_linesize[]); +EXPORT void convert_uyvx_to_i444( + const uint8_t *input, uint32_t in_linesize, + uint32_t start_y, uint32_t end_y, + uint8_t *output[], const uint32_t out_linesize[]); + EXPORT void decompress_nv12( const uint8_t *const input[], const uint32_t in_linesize[], uint32_t start_y, uint32_t end_y,