代码基本仿照C:\dvsdk_1_11_00_00_DM648\examples\video_preview\evmDM648下面的video_preview.c来写,代码如下:
VOID DM648_VideoCapAndDisplay(VOID)
{
Int32 status = DRV_SUCCESS;
FVID_Frame *frameBuffPtr = NULL;
FVID_Handle disChan, capChan;
int i = 0;
/* Allocate both capture and display frame buffers
in external heap memory */
vCapParamsChan.segId = DDR_HEAP;
vDisParamsChan.segId = DDR_HEAP;
/* Assign EDMA3 driver handle to channel params */
vCapParamsChan.hEdma = hEdma;
vDisParamsChan.hEdma = hEdma;
/* Setting num frame buffers to zero signals the video drivers to allow
* the application to own the buffers.
*/
vCapParamsChan.numFrmBufs = 0;
vDisParamsChan.numFrmBufs = 0;
/* create video input channel */
if (DRV_SUCCESS == status) {
capChan = FVID_create("/VP1CAPTURE/A/2", /* VP1, Channel A, External Decoder 0 "/VP1CAPTURE/A/2 ??"*/
IOM_INPUT, &status, (Ptr)&vCapParamsChan, NULL);
}
/* create video output channel, plane 0 */
if (DRV_SUCCESS == status) {
disChan = FVID_create("/VP2DISPLAY/SAA7105", IOM_OUTPUT, /* VP2, External Encoder 0 */
&status, (Ptr)&vDisParamsChan, NULL);
}
/* allocate and prime frame buffers for the capture channel */
/*FVID_allocBuffer alloc three buffer for one frame video*/
if (DRV_SUCCESS == status) {
for (i=0; i < FRAME_BUFF_CNT && status == DRV_SUCCESS; i++) {
status = FVID_allocBuffer(capChan, &frameBuffPtr);
if (status == IOM_COMPLETED) {
status = FVID_queue(capChan, &frameBuffPtr);
}
}
}
/* allocate and prime frame buffers for the display channel */
if (DRV_SUCCESS == status) {
for (i=0; i < FRAME_BUFF_CNT && status == DRV_SUCCESS; i++) {
status = FVID_allocBuffer(disChan, &frameBuffPtr);
if (status == IOM_COMPLETED) {
status = FVID_queue(disChan, &frameBuffPtr);
}
}
}
/* Configure external video encoders (SAA7105) & decoders (TVP5154) */
if (DRV_SUCCESS == status)
{
/* Configure SAA7105 */
status |= FVID_control(disChan,
VPORT_CMD_EDC_BASE + EDC_CONFIG,
(Ptr)&vDisParamsEncoder);
/* Configure TVP5154 */
status |= FVID_control(capChan,
VPORT_CMD_EDC_BASE + EDC_CONFIG,
(Ptr)&vCapParamsDecoder);
}
/* start capture & display operation */
if(DRV_SUCCESS == status)
{
status |= FVID_control(disChan, VPORT_CMD_START, NULL);
if(DRV_SUCCESS == status)
{
status |= FVID_control(capChan, VPORT_CMD_START, NULL);
}
}
/* grab first buffer from input queue */
if (DRV_SUCCESS == status) {
status = FVID_dequeue(disChan, &frameBuffPtr);
}
/* loop forever performing video capture and display */
while (status == 0) {
/* grab a fresh video input frame */
FVID_exchange(capChan, &frameBuffPtr);
/* display the video frame */
FVID_exchange(disChan, &frameBuffPtr);
}
}
if ((viop = (FVID_Frame *)QUE_dequeue(&chan->qOut)) != (FVID_Frame *)& chan->qOut)进而返回retVal = packet->status = IOM_PENDING;
总感觉少了什么触发,没把qIn的buffer挂到qOut上,求指导
Chris Meng:
你好,
1.请问你使用的是TI官方的DM648 EVM还是你自己的板子?如果是自己的板子在采集和显示部分的硬件设计和EVM是否完全一样?
2. 请问你是否有检查过采集TVP5154的VP口的buffer,是否有数据采集进来?
YesDayLucky:
回复 Chris Meng:
请教你个问题:
8148的开发板用的是rdk
我的问题是H264解码后 通过process link进入dsp后,此时数据格式应该是YUV420SP
通过 System_getLinksFullFrames(pInQueParams->prevLinkId, pInQueParams->prevLinkQueId, &frameList);
pFrame = frameList.frames[frameId]; FRAMEPOI=pFrame.addr[0][0];读取到Y分量的首地址。接着我该如何处理?
我的视频是720*576 得到通道行宽896. 我打印的大部分数据。按照正常的理解。
for(i=0;i<height;i++)
for(j=0;j<widht;j++)
{
*(FRAMEPOI+j)=0;
FRAMEPOI=FRAMEPOI+896;
}
是不是就将整个y分量置零了。但是显示结果不是这样。
所以请教这是为什么。该如何解决这个问题
jun pu:
回复 Chris Meng:
是自己的板子,模仿EVM设计的,区别主要在于EVM是VP0采集,VP1显示,我们板子是VP1采集,VP2显示。
camera(分辨率PAL 752*582)——>TVP5154——>(VP1)DM648(VP2)——>SAA7105——>screen
时钟芯片供给TVP5154时钟为14.3M,供给SAA7105时钟为27M,TVP5154输出PORT_CLK给DM648的VP1采集口时钟为27M,时钟芯片供给VP2显示口时钟为27M。
刚才直接用C:\dvsdk_1_11_00_00_DM648\examples\video_preview\evmDM648里面的video_preview跑了下(除了VP口按照自己板子做了修改外),在TVP5154的VP口buffer中能看到数据采集进来了,但是还是在status = FVID_dequeue(disChan, &frameBuffPtr); 出现同样的问题。
Chris Meng:
回复 jun pu:
你好,
/* grab first buffer from input queue */ –》注释提示的是从采集序列里面拿到以一个buffer if (DRV_SUCCESS == status) { status = FVID_dequeue(disChan, &frameBuffPtr); –》这边是从显示通道在拿? }
jun pu:
回复 Chris Meng:
C:\dvsdk_1_11_00_00_DM648\examples\video_preview\evmDM648下面的video_preview.c里面就是写的,见下:
/* allocate and prime frame buffers for the capture channel */ if (status == 0) { for (i=0; i < FRAME_BUFF_CNT && status == 0; i++) { status = FVID_allocBuffer(capChan, &frameBuffPtr);
if (status == IOM_COMPLETED) { status = FVID_queue(capChan, &frameBuffPtr); } } }
/* allocate and prime frame buffers for the display channel */ if (status == 0) { for (i=0; i < FRAME_BUFF_CNT && status == 0; i++) { status = FVID_allocBuffer(disChan, &frameBuffPtr);
if (status == IOM_COMPLETED) { status = FVID_queue(disChan, &frameBuffPtr); } } }
分配出的buffer都是通过FVID_queue函数挂在capchan和dischan各自有个qIn的链上,最后frameBuffPtr指向的buffer是分给dischan的,所以在
/* grab first buffer from input queue */ if (status == 0) { FVID_dequeue(disChan, &frameBuffPtr); }它是从dischan取出一个空闲的buffer当做整个采集显示循环的起始buffer,但是就是不明白FVID_dequeue函数是从qOut链上取的,但是前面分配的buffer都是挂在qIn上面,所以qOut是空链。既然库文件这么写的应该不会有问题,所以不知道我这边到底是硬件还是哪里出错了。
Jizhou Zhang:
回复 jun pu:
您好,我自己画了一块DM648的板子,视频编解码部分与您的板子不同,但是在调试时遇到了和您非常类似的情况。也是在FVID_dequeue(disChan, &frameBuffPtr);运行的时候跑飞了,chan->qOut的几个指针一直指着同一个地址。请问您帖子里提到的问题解决了没有,还请指导一下。
jun pu:
回复 Jizhou Zhang:
DM648上的管脚CLKIN1,即DM648的输入时钟,我板子上是27M,代码中忘记倍频了,即PLLC
Jizhou Zhang:
回复 jun pu:
感谢您的回复!
我遇到的可能还不是这个情况。我是用官方的gel文件基础上修改的gel文件来初始化PLLC、DDR2什么的,也看了PLLM寄存器的值,是正常的。我只能再检查一下,看是什么原因了。再次表示感谢。
jun pu:
回复 Jizhou Zhang:
肯定还是跟配置有关,TI的用例一般不会出错的
Jizhou Zhang:
回复 jun pu:
恩恩 已经初步确定我的问题出现的原因了,是硬件有点问题,AEA20管脚没有做上拉,导致BOOTCFG错误,进而导致VPORT口不能正确配置。需要修改硬件才能修复,当时以为EVM板上的那个配置位没用就给删掉了,唉!
再次表示感谢!和有经验的人讨论确实十分有助于确定问题。