package com.twilight.h264.player; import java.awt.image.BufferedImage; import com.twilight.h264.decoder.AVFrame; public class FrameUtils { public static BufferedImage imageFromFrame(AVFrame f) { BufferedImage bi = new BufferedImage(f.imageWidth, f.imageHeight, BufferedImage.TYPE_INT_ARGB); int[] rgb = new int[f.imageWidth * f.imageHeight]; YUV2RGB(f, rgb); for (int j = 0; j < f.imageHeight; j++) { int off = j * f.imageWidth; for (int i = 0; i < f.imageWidth; i++) { bi.setRGB(i, j, rgb[off + i]); } } return bi; } public static void YUV2RGB(AVFrame f, int[] rgb) { int[] luma = f.data_base[0]; int[] cb = f.data_base[1]; int[] cr = f.data_base[2]; int stride = f.linesize[0]; int strideChroma = f.linesize[1]; for (int y = 0; y < f.imageHeight; y++) { int lineOffLuma = y * stride; int lineOffChroma = (y >> 1) * strideChroma; for (int x = 0; x < f.imageWidth; x++) { int c = luma[lineOffLuma + x] - 16; int d = cb[lineOffChroma + (x >> 1)] - 128; int e = cr[lineOffChroma + (x >> 1)] - 128; int red = (298 * c + 409 * e + 128) >> 8; red = red < 0 ? 0 : (red > 255 ? 255 : red); int green = (298 * c - 100 * d - 208 * e + 128) >> 8; green = green < 0 ? 0 : (green > 255 ? 255 : green); int blue = (298 * c + 516 * d + 128) >> 8; blue = blue < 0 ? 0 : (blue > 255 ? 255 : blue); int alpha = 255; rgb[lineOffLuma + x] = (alpha << 24) | ((red & 0x0ff) << 16) | ((green & 0x0ff) << 8) | (blue & 0x0ff); } } } }