这几天做一个音视频采集与传输的项目,用v4l2来采集视频数据,公司给的USB摄像头只支持packed yuyv422数据,需要将其转换为planar yuv420,折腾了一下,将代码贴出来,说不定有同学可以用到。
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <stdint.h>
-
#include <stdbool.h>
-
#include <string.h>
-
#include <sys/time.h>
-
-
uint32_t width = 1280;
-
uint32_t height = 720;
-
-
uint32_t getcurrenttime()
-
{
-
struct timeval t;
-
gettimeofday(&t, NULL);
-
return (uint32_t)(t.tv_sec * 1000 + t.tv_usec / 1000);
-
}
-
-
int convert(uint8_t *inbuf, const uint32_t buflen, uint8_t *outbuf)
-
{
-
uint8_t *y = NULL;
-
uint8_t *u = NULL;
-
uint8_t *v = NULL;
-
y = outbuf;
-
u = y + 1280 * 720;
-
v = u + 1280 * 720 / 2;
-
-
uint32_t i = 0;
-
uint8_t swith = 0;
-
while (i < buflen) {
-
if (swith == 0 || swith == 2) {
-
*y++ = inbuf[i];
-
swith++;
-
} else if (swith == 1) {
-
*u++ = inbuf[i];
-
swith++;
-
} else if (swith == 3) {
-
*v++ = inbuf[i];
-
swith = 0;
-
}
-
i++;
-
}
-
return 0;
-
}
-
-
void yuyv2yuv420(uint8_t *inbuf, const uint32_t buflen, uint8_t *outbuf)
-
{
-
uint8_t *y = NULL;
-
uint8_t *u = NULL;
-
uint8_t *v = NULL;
-
int u_c = 0;
-
int v_c = 0;
-
y = outbuf;
-
u = y + 1280 * 720;
-
v = u + 1280 * 720 / 4;
-
bool swith = true;
-
uint32_t i = 0, j = 0;
-
-
for (i = 0; i < buflen; i += 2) {
-
*y++ = inbuf[i];
-
}
-
-
for (i = 0; i < height; i += 2) {
-
for (j = 1; j < width << 1; j += 2) {
-
if (swith) {
-
*u++ = ((uint8_t *)(inbuf + (i * width << 1)))[j];
-
swith = false;
-
u_c++;
-
} else {
-
*v++ = ((uint8_t *)(inbuf + (i * width << 1)))[j];
-
swith = true;
-
v_c++;
-
}
-
}
-
}
-
}
-
-
int main()
-
{
-
int ret = 0;
-
uint32_t inframesize = width * height * 2;
-
uint32_t outframesize = width * height * 3 / 2;
-
printf("inframesize: %u\n", inframesize);
-
printf("outframesize: %u\n", outframesize);
-
printf("size: %u\n", width * height / 4);
-
FILE *infb = NULL;
-
FILE *outfb = NULL;
-
uint8_t *inbuf = NULL;
-
uint8_t *outbuf = NULL;
-
-
inbuf = (uint8_t *)malloc(sizeof(uint8_t) * inframesize);
-
if (inbuf == NULL) {
-
printf("malloc inbuf failed\n");
-
ret = -1;
-
goto Error;
-
}
-
outbuf = (uint8_t *)malloc(sizeof(uint8_t) * outframesize);
-
if (outbuf == NULL) {
-
printf("malloc outbuf failed\n");
-
ret = -1;
-
goto Error;
-
}
-
-
infb = fopen("./test.yuv", "rb");
-
if (infb == NULL) {
-
printf("open ./test.yuv failed\n");
-
ret = -1;
-
goto Error;
-
}
-
outfb = fopen("./test.yuv420", "wb");
-
if (outfb == NULL) {
-
printf("open ./test.yuv422 failed\n");
-
ret = -1;
-
goto Error;
-
}
-
-
uint32_t start;
-
uint32_t end;
-
while (fread(inbuf, 1, inframesize, infb) == inframesize) {
-
//convert(inbuf, inframesize, outbuf);
-
start = getcurrenttime();
-
yuyv2yuv420(inbuf, inframesize, outbuf);
-
end = getcurrenttime();
-
printf("%d\n", end - start);
-
fwrite(outbuf, 1, outframesize, outfb);
-
}
-
-
Error:
-
if (inbuf != NULL) free(inbuf);
-
if (outbuf != NULL) free(outbuf);
-
if (infb != NULL) fclose(infb);
-
if (outfb != NULL) fclose(outfb);
-
return ret;
-
}
代码中的convert函数,只是将packed yuyv422转换成planar。
阅读(2497) | 评论(0) | 转发(0) |