• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Aucun tag

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

frameworks/base


Commit MetaInfo

Révision74908804ca31b4392c3ccb5ccc284889b1e71e92 (tree)
l'heure2015-12-22 13:13:49
AuteurZhao Liang <leo.zhao@inte...>
CommiterChih-Wei Huang

Message de Log

import YuvToEncoder R3 patches, BZ 18528, 19092, 19696

BZ: 47824

Please refer http://umgbugzilla.sh.intel.com:41006/show_bug.cgi?id=19092 and
external/jpeg/libjpeg.doc

The MCU height is max_v_samp_factor = 2 DCT rows so you must pass at least 16
scanlines on each call to jpeg_write_raw_data(), which is to say 16 actual
sample rows of Y and 8 each of Cb and Cr.

The original implement of Yuv420SpToJpegEncoder::compress didn't add padding to the frame buffer
when height and width aren't aligned with 16 pixel. It will cause illegal memory violation and core dump.

Category: aosp improvement
Domain: Video.Media-jpeg
Origin: Internal
Upstream: Yes

Change-Id: Ibcf14230d616e2d440ace244bb420723b5c01dc2
Orig-Change-Id: Ic1b7494b98ee9c1997b226d58abd034b1dcb18f6
Signed-off-by: Tong, Bo <box.tong@intel.com>
Signed-off-by: Zhao Liang <leo.zhao@intel.com>

Change Summary

Modification

--- a/core/jni/android/graphics/YuvToJpegEncoder.cpp
+++ b/core/jni/android/graphics/YuvToJpegEncoder.cpp
@@ -43,6 +43,7 @@ bool YuvToJpegEncoder::encode(SkWStream* stream, void* inYuv, int width,
4343 compress(&cinfo, (uint8_t*) inYuv, offsets);
4444
4545 jpeg_finish_compress(&cinfo);
46+ jpeg_destroy_compress(&cinfo);
4647
4748 return true;
4849 }
@@ -83,9 +84,15 @@ void Yuv420SpToJpegEncoder::compress(jpeg_compress_struct* cinfo,
8384 int height = cinfo->image_height;
8485 uint8_t* yPlanar = yuv + offsets[0];
8586 uint8_t* vuPlanar = yuv + offsets[1]; //width * height;
86- uint8_t* uRows = new uint8_t [8 * (width >> 1)];
87- uint8_t* vRows = new uint8_t [8 * (width >> 1)];
88-
87+ uint8_t* uRows = new uint8_t [8 * (((width + 15) & ~15) >> 1)];
88+ uint8_t* vRows = new uint8_t [8 * (((width + 15) & ~15) >> 1)];
89+ uint8_t* yRows;
90+ int lastLines;
91+
92+ if ((height & 0xf) != 0) {
93+ lastLines = height & 0xf;
94+ yRows = new uint8_t [16 * ((width + 15) & ~15)];
95+ }
8996
9097 // process 16 lines of Y and 8 lines of U/V each time.
9198 while (cinfo->next_scanline < cinfo->image_height) {
@@ -94,8 +101,11 @@ void Yuv420SpToJpegEncoder::compress(jpeg_compress_struct* cinfo,
94101
95102 // Jpeg library ignores the rows whose indices are greater than height.
96103 for (int i = 0; i < 16; i++) {
97- // y row
98- y[i] = yPlanar + (cinfo->next_scanline + i) * fStrides[0];
104+ // y row. Add padding if height isn't aligned to 16 pixels.
105+ if ((height & 0xf) != 0 && (cinfo->next_scanline + i) > height)
106+ y[i] = &yRows[(i - lastLines) * ((width + 15) & ~15)];
107+ else
108+ y[i] = yPlanar + (cinfo->next_scanline + i) * fStrides[0];
99109
100110 // construct u row and v row
101111 if ((i & 1) == 0) {
@@ -107,6 +117,8 @@ void Yuv420SpToJpegEncoder::compress(jpeg_compress_struct* cinfo,
107117 }
108118 jpeg_write_raw_data(cinfo, planes, 16);
109119 }
120+ if ((height & 0xf) != 0)
121+ delete [] yRows;
110122 delete [] uRows;
111123 delete [] vRows;
112124
@@ -114,9 +126,12 @@ void Yuv420SpToJpegEncoder::compress(jpeg_compress_struct* cinfo,
114126
115127 void Yuv420SpToJpegEncoder::deinterleave(uint8_t* vuPlanar, uint8_t* uRows,
116128 uint8_t* vRows, int rowIndex, int width, int height) {
117- int numRows = (height - rowIndex) / 2;
118- if (numRows > 8) numRows = 8;
119- for (int row = 0; row < numRows; ++row) {
129+ int lines = 16;
130+ //In case there isn't enough lines to process
131+ if ((rowIndex + lines) > height)
132+ lines = (height - rowIndex);
133+
134+ for (int row = 0; row < (lines >> 1); ++row) {
120135 int offset = ((rowIndex >> 1) + row) * fStrides[1];
121136 uint8_t* vu = vuPlanar + offset;
122137 for (int i = 0; i < (width >> 1); ++i) {