Bằng cách giới thiệu của Aegonis work 1 và work 2, tôi cũng có luồng H.264, nhưng màu sắc không chính xác. Tôi đang sử dụng HTC Butterfly để phát triển. Dưới đây là một phần của mã của tôi:Mediacodec và máy ảnh, không gian màu không chính xác
Camera:
parameters.setPreviewSize(width, height);
parameters.setPreviewFormat(ImageFormat.YV12);
parameters.setPreviewFrameRate(frameRate);
MediaCodec:
mediaCodec = MediaCodec.createEncoderByType("video/avc");
MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", 320, 240);
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 500000);
mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 15);
mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar);
mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
mediaCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
mediaCodec.start();
Khi sử dụng COLOR_FormatYUV420Planar các chương trình báo lỗi "[OMX.qcom.video.encoder.avc] làm không hỗ trợ định dạng màu 19, "vì vậy tôi chỉ có thể sử dụng" COLOR_FormatYUV420SemiPlanar ". Có ai biết lý do tại sao không hỗ trợ?
Got nó, bằng cách sử dụng:
int colorFormat = 0;
MediaCodecInfo.CodecCapabilities capabilities = codecInfo.getCapabilitiesForType(mimeType);
for (int i = 0; i < capabilities.colorFormats.length && colorFormat == 0; i++) {
int format = capabilities.colorFormats[i];
Log.e(TAG, "Using color format " + format);
}
chúng ta có thể định dạng màu (COLOR_FormatYUV420SemiPlanar) và (không có định dạng tương ứng), tôi nghĩ rằng định dạng sẽ thay đổi phụ thuộc vào thiết bị.
Sau đó, tôi đã thử màu biến đổi được cung cấp từ những gợi ý trong work 1 và work 2:
public static byte[] YV12toYUV420PackedSemiPlanar(final byte[] input, final byte[] output, final int width, final int height) {
/*
* COLOR_TI_FormatYUV420PackedSemiPlanar is NV12
* We convert by putting the corresponding U and V bytes together (interleaved).
*/
final int frameSize = width * height;
final int qFrameSize = frameSize/4;
System.arraycopy(input, 0, output, 0, frameSize); // Y
for (int i = 0; i < qFrameSize; i++) {
output[frameSize + i*2] = input[frameSize + i + qFrameSize]; // Cb (U)
output[frameSize + i*2 + 1] = input[frameSize + i]; // Cr (V)
}
return output;
}
public static byte[] YV12toYUV420Planar(byte[] input, byte[] output, int width, int height) {
/*
* COLOR_FormatYUV420Planar is I420 which is like YV12, but with U and V reversed.
* So we just have to reverse U and V.
*/
final int frameSize = width * height;
final int qFrameSize = frameSize/4;
System.arraycopy(input, 0, output, 0, frameSize); // Y
System.arraycopy(input, frameSize, output, frameSize + qFrameSize, qFrameSize); // Cr (V)
System.arraycopy(input, frameSize + qFrameSize, output, frameSize, qFrameSize); // Cb (U)
return output;
}
public static byte[] swapYV12toI420(byte[] yv12bytes, int width, int height) {
byte[] i420bytes = new byte[yv12bytes.length];
for (int i = 0; i < width*height; i++)
i420bytes[i] = yv12bytes[i];
for (int i = width*height; i < width*height + (width/2*height/2); i++)
i420bytes[i] = yv12bytes[i + (width/2*height/2)];
for (int i = width*height + (width/2*height/2); i < width*height + 2*(width/2*height/2); i++)
i420bytes[i] = yv12bytes[i - (width/2*height/2)];
return i420bytes;
}
Rõ ràng, màu sắc biến đổi của YV12toYUV420PackedSemiPlanar thực hiện tốt hơn so với hai người kia. Nó tương đối tốt hơn nhưng vẫn trông khác so với màu thực. Có gì sai với mã của tôi không? Mọi bình luận sẽ được đánh giá cao.
+1 để viết các câu hỏi theo cách như vậy. –
"khác" giống như các kênh chroma bị lạc hậu, hoặc "khác" giống như mọi thứ được tinh tế? (Nếu bạn sắp xếp lại 'YV12toYUV420PackedSemiPlanar' để hoán đổi các kênh Cb/Cr, có đúng không?) – fadden
Tôi đã cố gắng hoán đổi Cb/Cr và màu không chính xác. Tôi cũng thử chỉ hiển thị màu của Y và có vẻ như video được đặt trên mặt nạ màu xanh lá cây, đó không phải là những gì tôi mong đợi. Tôi thực sự không thể tìm ra những gì đang xảy ra. – Albert