1492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com/* 2492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com * Copyright 2011 The LibYuv Project Authors. All rights reserved. 3492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com * 4492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com * Use of this source code is governed by a BSD-style license 5492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com * that can be found in the LICENSE file in the root of the source 6492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com * tree. An additional intellectual property rights grant can be found 7492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com * in the file PATENTS. All contributing project authors may 8492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com * be found in the AUTHORS file in the root of the source tree. 9492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com */ 10492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com 111f923e3ea6de7afd9380c73f60a2f3e7b0588811fbarchard@google.com#include <stdlib.h> 121f923e3ea6de7afd9380c73f60a2f3e7b0588811fbarchard@google.com 13492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com#include "libyuv/convert.h" 14492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com 15492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com#include "libyuv/format_conversion.h" 16492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com#include "libyuv/video_common.h" 17492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com 18492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com#ifdef __cplusplus 19492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.comnamespace libyuv { 20492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.comextern "C" { 21492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com#endif 22492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com 23492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com// Convert camera sample to I420 with cropping, rotation and vertical flip. 24492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com// src_width is used for source stride computation 25492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com// src_height is used to compute location of planes, and indicate inversion 26492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com// sample_size is measured in bytes and is the size of the frame. 27492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com// With MJPEG it is the compressed size of the frame. 28492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.comLIBYUV_API 29492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.comint ConvertToI420(const uint8* sample, 30492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com size_t sample_size, 31492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com uint8* y, int y_stride, 32492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com uint8* u, int u_stride, 33492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com uint8* v, int v_stride, 34492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com int crop_x, int crop_y, 35492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com int src_width, int src_height, 36f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com int crop_width, int crop_height, 37db73518b19f73a3975b4fd58e9d17c8215a39d98fbarchard@google.com enum RotationMode rotation, 38492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com uint32 fourcc) { 39492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com uint32 format = CanonicalFourCC(fourcc); 40492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com int aligned_src_width = (src_width + 1) & ~1; 41492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com const uint8* src; 42492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com const uint8* src_uv; 43492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com int abs_src_height = (src_height < 0) ? -src_height : src_height; 44f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com int inv_crop_height = (crop_height < 0) ? -crop_height : crop_height; 45492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com int r = 0; 46db73518b19f73a3975b4fd58e9d17c8215a39d98fbarchard@google.com LIBYUV_BOOL need_buf = (rotation && format != FOURCC_I420 && 47492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com format != FOURCC_NV12 && format != FOURCC_NV21 && 48492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com format != FOURCC_YU12 && format != FOURCC_YV12) || y == sample; 49492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com uint8* tmp_y = y; 50492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com uint8* tmp_u = u; 51492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com uint8* tmp_v = v; 52492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com int tmp_y_stride = y_stride; 53492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com int tmp_u_stride = u_stride; 54492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com int tmp_v_stride = v_stride; 552d8824079a1460b8b42faa93753f09ef8375a084fbarchard@google.com uint8* rotate_buffer = NULL; 56f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com int abs_crop_height = (crop_height < 0) ? -crop_height : crop_height; 576d82347dda1b90d7b2c4ee8c110089c78777c738fbarchard@google.com 586d82347dda1b90d7b2c4ee8c110089c78777c738fbarchard@google.com if (!y || !u || !v || !sample || 596d82347dda1b90d7b2c4ee8c110089c78777c738fbarchard@google.com src_width <= 0 || crop_width <= 0 || 606d82347dda1b90d7b2c4ee8c110089c78777c738fbarchard@google.com src_height == 0 || crop_height == 0) { 616d82347dda1b90d7b2c4ee8c110089c78777c738fbarchard@google.com return -1; 626d82347dda1b90d7b2c4ee8c110089c78777c738fbarchard@google.com } 636d82347dda1b90d7b2c4ee8c110089c78777c738fbarchard@google.com if (src_height < 0) { 646d82347dda1b90d7b2c4ee8c110089c78777c738fbarchard@google.com inv_crop_height = -inv_crop_height; 656d82347dda1b90d7b2c4ee8c110089c78777c738fbarchard@google.com } 666d82347dda1b90d7b2c4ee8c110089c78777c738fbarchard@google.com 676d82347dda1b90d7b2c4ee8c110089c78777c738fbarchard@google.com // One pass rotation is available for some formats. For the rest, convert 686d82347dda1b90d7b2c4ee8c110089c78777c738fbarchard@google.com // to I420 (with optional vertical flipping) into a temporary I420 buffer, 696d82347dda1b90d7b2c4ee8c110089c78777c738fbarchard@google.com // and then rotate the I420 to the final destination buffer. 706d82347dda1b90d7b2c4ee8c110089c78777c738fbarchard@google.com // For in-place conversion, if destination y is same as source sample, 716d82347dda1b90d7b2c4ee8c110089c78777c738fbarchard@google.com // also enable temporary buffer. 72492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com if (need_buf) { 73f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com int y_size = crop_width * abs_crop_height; 74f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com int uv_size = ((crop_width + 1) / 2) * ((abs_crop_height + 1) / 2); 7553a7923b159626a6a598a7856a9830df4bbb560cfbarchard@google.com rotate_buffer = (uint8*)malloc(y_size + uv_size * 2); 762d8824079a1460b8b42faa93753f09ef8375a084fbarchard@google.com if (!rotate_buffer) { 77492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com return 1; // Out of memory runtime error. 78492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com } 792d8824079a1460b8b42faa93753f09ef8375a084fbarchard@google.com y = rotate_buffer; 80492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u = y + y_size; 81492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v = u + uv_size; 82f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com y_stride = crop_width; 83f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com u_stride = v_stride = ((crop_width + 1) / 2); 84492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com } 85492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com 86492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com switch (format) { 87492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com // Single plane formats 88492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_YUY2: 89492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src = sample + (aligned_src_width * crop_y + crop_x) * 2; 90492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = YUY2ToI420(src, aligned_src_width * 2, 91492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com y, y_stride, 92492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u, u_stride, 93492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v, v_stride, 94f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com crop_width, inv_crop_height); 95492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com break; 96492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_UYVY: 97492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src = sample + (aligned_src_width * crop_y + crop_x) * 2; 98492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = UYVYToI420(src, aligned_src_width * 2, 99492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com y, y_stride, 100492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u, u_stride, 101492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v, v_stride, 102f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com crop_width, inv_crop_height); 103492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com break; 104492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_RGBP: 105492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src = sample + (src_width * crop_y + crop_x) * 2; 106492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = RGB565ToI420(src, src_width * 2, 107492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com y, y_stride, 108492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u, u_stride, 109492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v, v_stride, 110f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com crop_width, inv_crop_height); 111492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com break; 112492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_RGBO: 113492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src = sample + (src_width * crop_y + crop_x) * 2; 114492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = ARGB1555ToI420(src, src_width * 2, 115492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com y, y_stride, 116492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u, u_stride, 117492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v, v_stride, 118f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com crop_width, inv_crop_height); 119492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com break; 120492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_R444: 121492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src = sample + (src_width * crop_y + crop_x) * 2; 122492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = ARGB4444ToI420(src, src_width * 2, 123492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com y, y_stride, 124492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u, u_stride, 125492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v, v_stride, 126f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com crop_width, inv_crop_height); 127492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com break; 128492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_24BG: 129492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src = sample + (src_width * crop_y + crop_x) * 3; 130492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = RGB24ToI420(src, src_width * 3, 131492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com y, y_stride, 132492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u, u_stride, 133492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v, v_stride, 134f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com crop_width, inv_crop_height); 135492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com break; 136492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_RAW: 137492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src = sample + (src_width * crop_y + crop_x) * 3; 138492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = RAWToI420(src, src_width * 3, 139492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com y, y_stride, 140492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u, u_stride, 141492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v, v_stride, 142f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com crop_width, inv_crop_height); 143492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com break; 144492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_ARGB: 145492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src = sample + (src_width * crop_y + crop_x) * 4; 146492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = ARGBToI420(src, src_width * 4, 147492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com y, y_stride, 148492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u, u_stride, 149492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v, v_stride, 150f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com crop_width, inv_crop_height); 151492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com break; 152492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_BGRA: 153492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src = sample + (src_width * crop_y + crop_x) * 4; 154492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = BGRAToI420(src, src_width * 4, 155492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com y, y_stride, 156492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u, u_stride, 157492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v, v_stride, 158f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com crop_width, inv_crop_height); 159492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com break; 160492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_ABGR: 161492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src = sample + (src_width * crop_y + crop_x) * 4; 162492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = ABGRToI420(src, src_width * 4, 163492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com y, y_stride, 164492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u, u_stride, 165492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v, v_stride, 166f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com crop_width, inv_crop_height); 167492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com break; 168492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_RGBA: 169492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src = sample + (src_width * crop_y + crop_x) * 4; 170492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = RGBAToI420(src, src_width * 4, 171492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com y, y_stride, 172492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u, u_stride, 173492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v, v_stride, 174f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com crop_width, inv_crop_height); 175492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com break; 176492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com // TODO(fbarchard): Support cropping Bayer by odd numbers 177492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com // by adjusting fourcc. 178492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_BGGR: 179492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src = sample + (src_width * crop_y + crop_x); 180492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = BayerBGGRToI420(src, src_width, 181492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com y, y_stride, 182492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u, u_stride, 183492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v, v_stride, 184f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com crop_width, inv_crop_height); 185492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com break; 186492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_GBRG: 187492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src = sample + (src_width * crop_y + crop_x); 188492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = BayerGBRGToI420(src, src_width, 189492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com y, y_stride, 190492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u, u_stride, 191492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v, v_stride, 192f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com crop_width, inv_crop_height); 193492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com break; 194492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_GRBG: 195492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src = sample + (src_width * crop_y + crop_x); 196492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = BayerGRBGToI420(src, src_width, 197492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com y, y_stride, 198492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u, u_stride, 199492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v, v_stride, 200f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com crop_width, inv_crop_height); 201492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com break; 202492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_RGGB: 203492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src = sample + (src_width * crop_y + crop_x); 204492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = BayerRGGBToI420(src, src_width, 205492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com y, y_stride, 206492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u, u_stride, 207492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v, v_stride, 208f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com crop_width, inv_crop_height); 209492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com break; 210492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_I400: 211492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src = sample + src_width * crop_y + crop_x; 212492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = I400ToI420(src, src_width, 213492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com y, y_stride, 214492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u, u_stride, 215492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v, v_stride, 216f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com crop_width, inv_crop_height); 217492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com break; 218492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com // Biplanar formats 219492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_NV12: 220492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src = sample + (src_width * crop_y + crop_x); 221492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_uv = sample + aligned_src_width * (src_height + crop_y / 2) + crop_x; 222492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = NV12ToI420Rotate(src, src_width, 223492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_uv, aligned_src_width, 224492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com y, y_stride, 225492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u, u_stride, 226492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v, v_stride, 227f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com crop_width, inv_crop_height, rotation); 228492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com break; 229492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_NV21: 230492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src = sample + (src_width * crop_y + crop_x); 231492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_uv = sample + aligned_src_width * (src_height + crop_y / 2) + crop_x; 232492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com // Call NV12 but with u and v parameters swapped. 233492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = NV12ToI420Rotate(src, src_width, 234492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_uv, aligned_src_width, 235492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com y, y_stride, 236492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v, v_stride, 237492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u, u_stride, 238f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com crop_width, inv_crop_height, rotation); 239492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com break; 240492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_M420: 241492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src = sample + (src_width * crop_y) * 12 / 8 + crop_x; 242492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = M420ToI420(src, src_width, 243492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com y, y_stride, 244492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u, u_stride, 245492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v, v_stride, 246f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com crop_width, inv_crop_height); 247492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com break; 248492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_Q420: 249492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src = sample + (src_width + aligned_src_width * 2) * crop_y + crop_x; 250492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_uv = sample + (src_width + aligned_src_width * 2) * crop_y + 251492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_width + crop_x * 2; 252492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = Q420ToI420(src, src_width * 3, 253492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_uv, src_width * 3, 254492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com y, y_stride, 255492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u, u_stride, 256492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v, v_stride, 257f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com crop_width, inv_crop_height); 258492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com break; 259492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com // Triplanar formats 260492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_I420: 261492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_YU12: 262492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_YV12: { 263492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com const uint8* src_y = sample + (src_width * crop_y + crop_x); 264492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com const uint8* src_u; 265492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com const uint8* src_v; 266492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com int halfwidth = (src_width + 1) / 2; 267492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com int halfheight = (abs_src_height + 1) / 2; 268492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com if (format == FOURCC_YV12) { 269492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_v = sample + src_width * abs_src_height + 270492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com (halfwidth * crop_y + crop_x) / 2; 271492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_u = sample + src_width * abs_src_height + 272492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com halfwidth * (halfheight + crop_y / 2) + crop_x / 2; 273492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com } else { 274492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_u = sample + src_width * abs_src_height + 275492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com (halfwidth * crop_y + crop_x) / 2; 276492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_v = sample + src_width * abs_src_height + 277492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com halfwidth * (halfheight + crop_y / 2) + crop_x / 2; 278492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com } 279492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = I420Rotate(src_y, src_width, 280492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_u, halfwidth, 281492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_v, halfwidth, 282492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com y, y_stride, 283492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u, u_stride, 284492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v, v_stride, 285f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com crop_width, inv_crop_height, rotation); 286492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com break; 287492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com } 288492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_I422: 289492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_YV16: { 290492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com const uint8* src_y = sample + src_width * crop_y + crop_x; 291492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com const uint8* src_u; 292492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com const uint8* src_v; 293492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com int halfwidth = (src_width + 1) / 2; 294492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com if (format == FOURCC_YV16) { 295492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_v = sample + src_width * abs_src_height + 296492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com halfwidth * crop_y + crop_x / 2; 297492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_u = sample + src_width * abs_src_height + 298492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com halfwidth * (abs_src_height + crop_y) + crop_x / 2; 299492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com } else { 300492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_u = sample + src_width * abs_src_height + 301492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com halfwidth * crop_y + crop_x / 2; 302492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_v = sample + src_width * abs_src_height + 303492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com halfwidth * (abs_src_height + crop_y) + crop_x / 2; 304492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com } 305492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = I422ToI420(src_y, src_width, 306492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_u, halfwidth, 307492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_v, halfwidth, 308492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com y, y_stride, 309492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u, u_stride, 310492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v, v_stride, 311f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com crop_width, inv_crop_height); 312492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com break; 313492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com } 314492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_I444: 315492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_YV24: { 316492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com const uint8* src_y = sample + src_width * crop_y + crop_x; 317492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com const uint8* src_u; 318492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com const uint8* src_v; 319492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com if (format == FOURCC_YV24) { 320492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_v = sample + src_width * (abs_src_height + crop_y) + crop_x; 321492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_u = sample + src_width * (abs_src_height * 2 + crop_y) + crop_x; 322492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com } else { 323492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_u = sample + src_width * (abs_src_height + crop_y) + crop_x; 324492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_v = sample + src_width * (abs_src_height * 2 + crop_y) + crop_x; 325492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com } 326492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = I444ToI420(src_y, src_width, 327492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_u, src_width, 328492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_v, src_width, 329492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com y, y_stride, 330492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u, u_stride, 331492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v, v_stride, 332f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com crop_width, inv_crop_height); 333492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com break; 334492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com } 335492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_I411: { 336492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com int quarterwidth = (src_width + 3) / 4; 337492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com const uint8* src_y = sample + src_width * crop_y + crop_x; 338492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com const uint8* src_u = sample + src_width * abs_src_height + 339492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com quarterwidth * crop_y + crop_x / 4; 340492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com const uint8* src_v = sample + src_width * abs_src_height + 341492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com quarterwidth * (abs_src_height + crop_y) + crop_x / 4; 342492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = I411ToI420(src_y, src_width, 343492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_u, quarterwidth, 344492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com src_v, quarterwidth, 345492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com y, y_stride, 346492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u, u_stride, 347492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v, v_stride, 348f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com crop_width, inv_crop_height); 349492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com break; 350492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com } 351492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com#ifdef HAVE_JPEG 352492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com case FOURCC_MJPG: 353492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = MJPGToI420(sample, sample_size, 354492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com y, y_stride, 355492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u, u_stride, 356492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v, v_stride, 357f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com src_width, abs_src_height, crop_width, inv_crop_height); 358492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com break; 359492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com#endif 360492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com default: 361492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = -1; // unknown fourcc - return failure code. 362492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com } 363492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com 364492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com if (need_buf) { 365492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com if (!r) { 366492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com r = I420Rotate(y, y_stride, 367492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com u, u_stride, 368492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com v, v_stride, 369492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com tmp_y, tmp_y_stride, 370492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com tmp_u, tmp_u_stride, 371492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com tmp_v, tmp_v_stride, 372f2bd31538e43abaefc51d2a07b7a9f9e5f9911a0fbarchard@google.com crop_width, abs_crop_height, rotation); 373492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com } 3741f923e3ea6de7afd9380c73f60a2f3e7b0588811fbarchard@google.com free(rotate_buffer); 375492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com } 376492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com 377492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com return r; 378492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com} 379492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com 380492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com#ifdef __cplusplus 381492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com} // extern "C" 382492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com} // namespace libyuv 383492768cbca51a0ea8a00faaf572fa02b1d6b1934fbarchard@google.com#endif 384