diff --git a/source/convert_to_argb.cc b/source/convert_to_argb.cc index 7f731197f..f9e0e808a 100644 --- a/source/convert_to_argb.cc +++ b/source/convert_to_argb.cc @@ -50,8 +50,8 @@ int ConvertToARGB(const uint8* sample, int r = 0; // One pass rotation is available for some formats. For the rest, convert - // to I420 (with optional vertical flipping) into a temporary I420 buffer, - // and then rotate the I420 to the final destination buffer. + // to ARGB (with optional vertical flipping) into a temporary ARGB buffer, + // and then rotate the ARGB to the final destination buffer. // For in-place conversion, if destination crop_argb is same as source sample, // also enable temporary buffer. LIBYUV_BOOL need_buf = @@ -102,9 +102,11 @@ int ConvertToARGB(const uint8* sample, inv_crop_height); break; case FOURCC_ARGB: - src = sample + (src_width * crop_y + crop_x) * 4; - r = ARGBToARGB(src, src_width * 4, crop_argb, argb_stride, crop_width, - inv_crop_height); + if (!need_buf && !rotation) { + src = sample + (src_width * crop_y + crop_x) * 4; + r = ARGBToARGB(src, src_width * 4, crop_argb, argb_stride, crop_width, + inv_crop_height); + } break; case FOURCC_BGRA: src = sample + (src_width * crop_y + crop_x) * 4; @@ -253,6 +255,11 @@ int ConvertToARGB(const uint8* sample, crop_width, abs_crop_height, rotation); } free(rotate_buffer); + } else if (rotation) { + src = sample + (src_width * crop_y + crop_x) * 4; + r = ARGBRotate(src, src_width * 4, + crop_argb, argb_stride, + crop_width, inv_crop_height, rotation); } return r; diff --git a/unit_test/convert_test.cc b/unit_test/convert_test.cc index cd0b93984..e471a8e32 100644 --- a/unit_test/convert_test.cc +++ b/unit_test/convert_test.cc @@ -1910,4 +1910,40 @@ TESTPLANARTOE(I422, 2, 1, UYVY, 2, 4, ARGB, 4) TESTQPLANARTOE(I420Alpha, 2, 2, ARGB, 1, 4, ABGR, 4) TESTQPLANARTOE(I420Alpha, 2, 2, ABGR, 1, 4, ARGB, 4) +TEST_F(LibYUVConvertTest, RotateWithARGBSource) { + // 2x2 frames + uint32_t src[4]; + uint32_t dst[4]; + // some random input + src[0] = 0x11000000; + src[1] = 0x00450000; + src[2] = 0x00009f00; + src[3] = 0x000000ff; + // zeros on destination + dst[0] = 0x00000000; + dst[1] = 0x00000000; + dst[2] = 0x00000000; + dst[3] = 0x00000000; + + int r = ConvertToARGB( + reinterpret_cast(src), + 16, // input size + reinterpret_cast(dst), + 8, // destination stride + 0, // crop_x + 0, // crop_y + 2, // width + 2, // height + 2, // crop width + 2, // crop height + kRotate90, FOURCC_ARGB); + + EXPECT_EQ(r, 0); + // 90 degrees rotation, no conversion + EXPECT_EQ(dst[0], src[2]); + EXPECT_EQ(dst[1], src[0]); + EXPECT_EQ(dst[2], src[3]); + EXPECT_EQ(dst[3], src[1]); +} + } // namespace libyuv