技术专栏
关于DM368的H264视频编码过程(下)
接上篇
四、一些需要注意的问题和提示
色彩空间
在capture捕获线程中有一项设置叫色彩空间,colorspace 变量。色彩空间的定义在Dmai中的 ColorSpace.h 文件中:
/**
* @brief Color formats.
*/
typedef enum {
ColorSpace_NOTSET = -1,
/**
* @brief YUV 420 semi planar corresponding to V4L2_PIX_FMT_NV12 in v4l2.
* This format consists of two planes: one with the Y component
* and one with the CbCr components interleaved (hence semi).
* See the LSP documentation for a thorough description of this
* format.
*/
ColorSpace_YUV420PSEMI = 0,
/**
* @brief YUV 422 semi planar corresponding to V4L2_PIX_FMT_YUV422UVP. This
* format was added to v4l2 by TI because the dm6467 VDCE and VPSS
* peripherals use this format. The format consists of two planes:
* one with the Y component and one with the CbCr components
* interleaved (hence semi) See the LSP VDCE documentation for a
* thorough description of this format.
*/
ColorSpace_YUV422PSEMI,
/** @brief YUV 422 interleaved corresponding to V4L2_PIX_FMT_UYVY in v4l2 */
ColorSpace_UYVY,
/** @brief RGB 888 packed corresponding to V4L2_PIX_FMT_RGB24 in v4l2 */
ColorSpace_RGB888,
/** @brief RGB 565 packed corresponding to V4L2_PIX_FMT_RGB565 in v4l2 */
ColorSpace_RGB565,
/**
* @brief 2 bits per pixel. This is the format used by the VDCE for the
* bitmap while blending and is documented in the VDCE peripheral
* guide.
*/
ColorSpace_2BIT,
/**
* @brief YUV 420 planar. The format consists of three planes:
* one with the Y component, one Cb, and one Cr component.
*/
ColorSpace_YUV420P,
/**
* @brief YUV 422 planar. The format consists of three planes:
* one with the Y component, one Cb, and one Cr component.
*/
ColorSpace_YUV422P,
/**
* @brief YUV 444 planar. The format consists of three planes:
* one with the Y component, one Cb, and one Cr component.
*/
ColorSpace_YUV444P,
/**
* @brief Gray Scale. The format consist of single Luma plane
* ignoring the color plane components.
*
*/
ColorSpace_GRAY,
ColorSpace_COUNT
} ColorSpace_Type;
支持的视频编码格式
在视频编码线程中支持的视频编码格式枚举变量在 VideoStd.h 文件中定义:
/** @brief Video standards */
typedef enum {
VideoStd_AUTO = 0, /**< Automatically select standard (if supported) */
VideoStd_CIF, /**< CIF @ 30 frames per second */
VideoStd_SIF_NTSC, /**< SIF @ 30 frames per second */
VideoStd_SIF_PAL, /**< SIF @ 25 frames per second */
VideoStd_VGA, /**< VGA (640x480) @ 60 frames per second */
VideoStd_D1_NTSC, /**< D1 NTSC @ 30 frames per second */
VideoStd_D1_PAL, /**< D1 PAL @ 25 frames per second */
VideoStd_480P, /**< D1 Progressive NTSC @ 60 frames per second */
VideoStd_576P, /**< D1 Progressive PAL @ 50 frames per second */
VideoStd_720P_60, /**< 720P @ 60 frames per second */
VideoStd_720P_50, /**< 720P @ 50 frames per second */
VideoStd_720P_30, /**< 720P @ 30 frames per second */
VideoStd_1080I_30, /**< 1080I @ 30 frames per second */
VideoStd_1080I_25, /**< 1080I @ 25 frames per second */
VideoStd_1080P_30, /**< 1080P @ 30 frames per second */
VideoStd_1080P_25, /**< 1080P @ 25 frames per second */
VideoStd_1080P_24, /**< 1080P @ 24 frames per second */
VideoStd_QVGA, /**< QVGA @ 30 frames per second */
VideoStd_1080P_60, /**< 1080P @ 60 frames per second */
VideoStd_1080P_50, /**< 1080P @ 50 frames per second */
VideoStd_1080I_60, /**< 1080I @ 60 frames per second */
VideoStd_COUNT
} VideoStd_Type;
支持的视频输入源
支持的输入源枚举变量在 Capture.h 文件中定义:
/**
* @brief Video capture inputs.
*/
typedef enum {
/** @brief S-Video video input */
Capture_Input_SVIDEO = 0,
/** @brief Composite video input */
Capture_Input_COMPOSITE,
/** @brief Component video input */
Capture_Input_COMPONENT,
/** @brief Camera/Imager card video input
* @remarks only applicable on DM368
*/
Capture_Input_CAMERA,
Capture_Input_COUNT
} Capture_Input;
Camera的更换
Dmai(达芬奇多媒体应用程序接口)中是调用V4L2库从系统中的video设备获取图像的。这一步可以在 Capture.c 文件中的 Capture_detectVideoStd 函数中得到证实:
/******************************************************************************
* Capture_detectVideoStd
******************************************************************************/
Int Capture_detectVideoStd(Capture_Handle hCapture, VideoStd_Type *videoStdPtr,
Capture_Attrs *attrs)
{
Int failCount = 0;
Int firstInput;
Int queryInput;
struct v4l2_input v4l2Input;
v4l2_std_id std;
Int input;
Int fd;
Int ret;
assert(videoStdPtr);
assert(attrs);
/*
* Initialize variables outside of variable declarations to suppress
* "unused variable" warnings for platforms that don't use them.
*/
Dmai_clear(v4l2Input);
queryInput = 0;
firstInput = -1;
if (attrs->videoStd < 0 || attrs->videoStd > VideoStd_COUNT) {
Dmai_err1("Invalid capture standard given (%d)\n", attrs->videoStd);
return Dmai_EINVAL;
}
if (hCapture) {
fd = hCapture->fd;
}
else {
fd = open(attrs->captureDevice, O_RDWR, 0);
if (fd == -1) {
Dmai_err2("Cannot open %s (%s)\n", attrs->captureDevice,
strerror(errno));
return Dmai_EFAIL;
}
}
if (attrs->decoderIdx < 0) {
v4l2Input.type = V4L2_INPUT_TYPE_CAMERA;
v4l2Input.index = 0;
do {
if (ioctl(fd, VIDIOC_ENUMINPUT, &v4l2Input) != 0) {
Dmai_err2("%s input not found (%s)\n",
captureInputString[attrs->videoInput], strerror(errno));
return Dmai_EFAIL;
}
v4l2Input.index++;
} while (strcmp((Char *) v4l2Input.name,
captureInputString[attrs->videoInput]) != 0);
input = --v4l2Input.index;
Dmai_dbg1("%s input selected\n", v4l2Input.name);
} else {
input = attrs->decoderIdx;
}
if (ioctl(fd, VIDIOC_S_INPUT, &input) == -1) {
Dmai_err2("Failed to set video input to %d (%s)\n",
input, strerror(errno));
return Dmai_EFAIL;
}
if (ioctl(fd, VIDIOC_G_INPUT, &queryInput) == -1) {
Dmai_err0("Failed to retrieve video input setting\n");
return Dmai_EFAIL;
}
if (input != queryInput) {
Dmai_dbg2("Attempted to set video input to %d, but it still has a"
"setting of %d\n", input, queryInput);
return Dmai_EFAIL;
}
if (attrs->videoStd != VideoStd_AUTO) {
/* Force video standard */
std = stds[attrs->videoStd];
} else {
Dmai_dbg0("Checking video standard\n");
/* It might take a few tries to detect the signal */
do {
ret = ioctl(fd, VIDIOC_QUERYSTD, &std);
if (ret == -1 && errno == EAGAIN) {
usleep(1);
failCount++;
}
} while (ret == -1 && errno == EAGAIN && failCount < NUM_IOCTL_RETRIES);
if (ret == -1) {
Dmai_err1("VIDIOC_QUERYSTD failed on %s. Video input connected?\n",
attrs->captureDevice);
return Dmai_EFAIL;
}
}
if(ioctl(fd, VIDIOC_S_STD, &std) == -1) {
Dmai_err2("VIDIOC_S_STD failed on %s (%s)\n",
attrs->captureDevice, strerror(errno));
return Dmai_EFAIL;
}
if (!hCapture) {
close(fd);
}
if (std & V4L2_STD_NTSC) {
*videoStdPtr = VideoStd_D1_NTSC;
}
else if (std & V4L2_STD_PAL) {
*videoStdPtr = VideoStd_D1_PAL;
}
else if (std & V4L2_STD_525P_60) {
*videoStdPtr = VideoStd_480P;
}
else if (std & V4L2_STD_625P_50) {
*videoStdPtr = VideoStd_576P;
}
else if (std == V4L2_STD_720P_60) {
*videoStdPtr = VideoStd_720P_60;
}
else if (std == V4L2_STD_720P_50) {
*videoStdPtr = VideoStd_720P_50;
}
#if 0
else if (std == V4L2_STD_720P_30) {
*videoStdPtr = VideoStd_720P_30;
}
#endif
else if (std == V4L2_STD_1080I_60) {
*videoStdPtr = VideoStd_1080I_30;
}
else if (std == V4L2_STD_1080I_50) {
*videoStdPtr = VideoStd_1080I_25;
}
#if 0
else if (std == V4L2_STD_1080P_30) {
*videoStdPtr = VideoStd_1080P_30;
}
else if (std == V4L2_STD_1080P_25) {
*videoStdPtr = VideoStd_1080P_25;
}
else if (std == V4L2_STD_1080P_24) {
*videoStdPtr = VideoStd_1080P_24;
}
#endif
else if (std == V4L2_STD_1080P_60) {
*videoStdPtr = VideoStd_1080P_60;
}
else if (std == V4L2_STD_1080P_50) {
*videoStdPtr = VideoStd_1080P_50;
}
else {
Dmai_err1("Unknown video standard on capture device %s\n",
attrs->captureDevice);
return Dmai_EFAIL;
}
attrs->videoStd = *videoStdPtr;
Dmai_dbg2("Capture input set to %s:%d\n",
captureInputString[attrs->videoInput], *videoStdPtr);
return Dmai_EOK;
}
emmmm,函数有点长哈,总之,更换摄像头需要在linux内核中添加对新sensor的支持,且驱动要在V4L2框架下编写。不知道V4L2的请自行bing一下(因为我写累了)。
在DVSDK4_02_00_06中的Linux内核是2.6.32.17版本的,该内核支持的sensor非常有限,可以在 ./linux-2.6.32.17/drivers/media/video/ 中查看。
IDR帧
Dmai中,它比较皮,要是不设置,是不会产生IDR帧的。
在例程中,video线程处理部分,有这样的函数:
unsigned char idr_trigger = 0;//IDR帧触发变量
//IDR帧触发(这个判断在video的while中轮询)
if(idr_trigger)
{
ForceIDR(hVe1, &dynParams, 1);
idr_trigger=0;
}
//修改产生IDR的设置
void ForceIDR(Venc1_Handle hVe1, VIDENC1_DynamicParams *dynParams, unsigned int idr)
{
Int mystatus;
VIDENC1_Status tEncStatus;
VIDENC1_Handle enghandle = Venc1_getVisaHandle(hVe1);
tEncStatus.size = sizeof(VIDENC1_Status);
tEncStatus.data.buf = NULL;
if(0 == idr)
{
dynParams->forceFrame = IVIDEO_NA_FRAME;
}
else
{
dynParams->forceFrame = IVIDEO_IDR_FRAME;
}
mystatus = VIDENC1_control(enghandle, XDM_SETPARAMS, dynParams, &tEncStatus);
if(mystatus != VIDENC1_EOK)
{
VIDENC1_delete(enghandle);
return;
}
}
什么?没看到?那跟我没关系嗷。
五、后记
本人才疏学浅,千万别喷,谢谢,给你卖个萌嗷:
喵~!
声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
红包
点赞
收藏
评论
打赏
- 分享
- 举报
评论
0个
手气红包
暂无数据
相关专栏
-
浏览量:748次2023-06-30 09:18:17
-
浏览量:681次2023-06-12 14:34:57
-
浏览量:615次2023-06-12 14:35:02
-
浏览量:1178次2023-06-12 14:34:40
-
浏览量:668次2023-10-23 17:56:00
-
浏览量:1478次2023-11-01 10:56:09
-
浏览量:4948次2018-11-13 10:03:09
-
浏览量:1489次2023-06-12 14:35:30
-
浏览量:987次2023-11-01 11:26:42
-
浏览量:4566次2021-04-27 16:33:22
-
浏览量:2199次2020-05-22 19:32:20
-
浏览量:704次2023-10-30 15:15:38
-
浏览量:5461次2021-04-27 16:33:54
-
2023-06-12 14:35:32
-
浏览量:3090次2018-05-07 16:22:35
-
浏览量:5524次2020-08-20 14:18:11
-
浏览量:1396次2024-02-27 17:03:43
-
浏览量:1303次2024-05-16 12:25:25
-
浏览量:13183次2020-11-14 10:44:48
置顶时间设置
结束时间
删除原因
-
广告/SPAM
-
恶意灌水
-
违规内容
-
文不对题
-
重复发帖
打赏作者
Tony
您的支持将鼓励我继续创作!
打赏金额:
¥1
¥5
¥10
¥50
¥100
支付方式:
微信支付
打赏成功!
感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~
举报反馈
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明
审核成功
发布时间设置
发布时间:
请选择发布时间设置
是否关联周任务-专栏模块
审核失败
失败原因
请选择失败原因
备注
请输入备注