How to convert YUV420SP to RGB and display it?

邮差的信 提交于 2019-12-11 19:28:23

问题


Im trying to render a video frame using android NDK.

Im using this sample of google Native-Codec NDK sample code and modified it so I can manually display each video frame (non-tunneled).

so I added this code to get the output buffer which is in YUV.

  ANativeWindow_setBuffersGeometry(mWindow, bufferWidth, bufferHeight,
                                     WINDOW_FORMAT_RGBA_8888
  uint8_t *decodedBuff = AMediaCodec_getOutputBuffer(d->codec, status, &bufSize);
  auto format = AMediaCodec_getOutputFormat(d->codec);
  LOGV("VOUT: format %s", AMediaFormat_toString(format));
  AMediaFormat *myFormat = format;
  int32_t w,h;
  AMediaFormat_getInt32(myFormat, AMEDIAFORMAT_KEY_HEIGHT, &h);
  AMediaFormat_getInt32(myFormat, AMEDIAFORMAT_KEY_WIDTH, &w);
  err = ANativeWindow_lock(mWindow, &buffer, nullptr);

and these codes to convert the YUV to RGB and display it using native window.

  if (err == 0) {
            LOGV("ANativeWindow_lock()");
            int width =w;
            int height=h;
            int const frameSize = width * height;
            int *line = reinterpret_cast<int *>(buffer.bits);
            for (int y= 0; y < height; y++) {
                for (int x = 0; x < width; x++) {
                /*accessing YUV420SP elements*/
                int indexY = y * width + x;
                int indexU = (size + (y / 2) * (width ) + (x / 2) *2);
                int indexV = (int) (size + (y / 2) * (width) + (x / 2) * 2 + 1);

                /*todo; this conversion to int and then later back to int really isn't required.
                There's room for better work here.*/
                int Y = 0xFF & decodedBuff[indexY];
                int U = 0xFF & decodedBuff[indexU];
                int V = 0xFF & decodedBuff[indexV];

                /*constants picked up from http://www.fourcc.org/fccyvrgb.php*/
                    int R = (int) (Y + 1.402f * (V - 128));
                    int G = (int) (Y - 0.344f * (U - 128) - 0.714f * (V - 128));
                    int B = (int) (Y + 1.772f * (U - 128));

                /*clamping values*/
                R = R < 0 ? 0 : R;
                G = G < 0 ? 0 : G;
                B = B < 0 ? 0 : B;
                R = R > 255 ? 255 : R;
                G = G > 255 ? 255 : G;
                B = B > 255 ? 255 : B;

                line[buffer.stride * y + x] = 0xff000000 + (B << 16) + (G << 8) + R;
            }
        }
ANativeWindow_unlockAndPost(mWindow);

Finally I was able to display a video on my device. Now my problem is the video does not scale to fit the surface view :(

Your thoughts are very much appreciated.

来源:https://stackoverflow.com/questions/57724925/how-to-convert-yuv420sp-to-rgb-and-display-it

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!