我试图将原始视频帧提供给libyuv以将UYVY视频转换为I420,但是当我使用libyuv转换帧时,我只得到视频的左上角我试图从我的decklink卡捕获。
这是使用
的函数的代码int vpx_img_read(vpx_image_t *img, void *raw) {
int plane;
unsigned char *buf0 = img->planes[0];
unsigned char *buf1 = img->planes[1];
unsigned char *buf2 = img->planes[2];
const int stride0 = img->stride[0];
const int stride1 = img->stride[1];
const int stride2 = img->stride[2];
UYVYToI420(raw , stride0,
buf0, stride0,
buf1, stride1,
buf2, stride2,
1920, 1080);
return 1;
}
我怎样才能让它显示整个画面? 谢谢!!!
答案 0 :(得分:0)
我必须为我需要的格式重写转换器,这是我的解决方案
// Copy row of UYVY Y's (422) into Y (420/422).
void UYVYToYRow_CD(const uint8* src_uyvy, uint8* dst_y, int width) {
// Output a row of Y values.
int x;
for (x = 0; x < width - 1; x += 2) {
dst_y[x] = src_uyvy[1];
dst_y[x + 1] = src_uyvy[3];
//if (x%4==0){
src_uyvy += 4;
//}
}
if (width & 1) {
dst_y[width - 1] = src_uyvy[1];
}
}
// Filter 2 rows of UYVY UV's (422) into U and V (420).
void UYVYToUVRow_CD(const uint8* src_uyvy, int src_stride_uyvy,
uint8* dst_u, uint8* dst_v, int width) {
// Output a row of UV values.
int x;
for (x = 0; x < width; x += 2) {
dst_u[0] = (src_uyvy[0] + src_uyvy[src_stride_uyvy + 0+1920] + 1) >> 1;
dst_v[0] = (src_uyvy[2] + src_uyvy[src_stride_uyvy + 2+1920] + 1) >> 1;
// if (x%4==0){
src_uyvy += 4;
//}
dst_u += 1;
dst_v += 1;
}
}
// Convert UYVY to I420.
LIBYUV_API
int UYVYToI420(const uint8* src_uyvy, int src_stride_uyvy,
uint8* dst_y, int dst_stride_y,
uint8* dst_u, int dst_stride_u,
uint8* dst_v, int dst_stride_v,
int width, int height) {
int y;
void (*UYVYToUVRow)(const uint8* src_uyvy, int src_stride_uyvy,
uint8* dst_u, uint8* dst_v, int width) = UYVYToUVRow_C;
void (*UYVYToYRow)(const uint8* src_uyvy,
uint8* dst_y, int width) = UYVYToYRow_C;
// Negative height means invert the image.
if (height < 0) {
height = -height;
src_uyvy = src_uyvy + (height - 1) * src_stride_uyvy;
src_stride_uyvy = -src_stride_uyvy;
}
#if defined(HAS_UYVYTOYROW_SSE2)
if (TestCpuFlag(kCpuHasSSE2)) {
UYVYToUVRow = UYVYToUVRow_Any_SSE2;
UYVYToYRow = UYVYToYRow_Any_SSE2;
if (IS_ALIGNED(width, 16)) {
UYVYToUVRow = UYVYToUVRow_SSE2;
UYVYToYRow = UYVYToYRow_SSE2;
}
}
#endif
#if defined(HAS_UYVYTOYROW_AVX2)
if (TestCpuFlag(kCpuHasAVX2)) {
UYVYToUVRow = UYVYToUVRow_Any_AVX2;
UYVYToYRow = UYVYToYRow_Any_AVX2;
if (IS_ALIGNED(width, 32)) {
UYVYToUVRow = UYVYToUVRow_AVX2;
UYVYToYRow = UYVYToYRow_AVX2;
}
}
#endif
#if defined(HAS_UYVYTOYROW_NEON)
if (TestCpuFlag(kCpuHasNEON)) {
UYVYToYRow = UYVYToYRow_Any_NEON;
UYVYToUVRow = UYVYToUVRow_Any_NEON;
if (IS_ALIGNED(width, 16)) {
UYVYToYRow = UYVYToYRow_NEON;
UYVYToUVRow = UYVYToUVRow_NEON;
}
}
#endif
for (y = 0; y < height - 1; y += 1) {
UYVYToUVRow_CD(src_uyvy, src_stride_uyvy, dst_u, dst_v, width);
UYVYToYRow_CD(src_uyvy, dst_y+ dst_stride_y + 960, width);
UYVYToYRow_CD(src_uyvy + src_stride_uyvy, dst_y + dst_stride_y + 960, width);
src_uyvy += src_stride_uyvy * 2;
dst_y += dst_stride_y * 1;
if (y%2==0)
{
dst_u += dst_stride_u;
dst_v += dst_stride_v;
}
}
if (height & 1) {
UYVYToUVRow_CD(src_uyvy, 0, dst_u, dst_v , width);
UYVYToYRow_CD(src_uyvy, dst_y, width);
}
return 0;
}