wince下使用directdraw实现yuv视频的显示,屏幕出现绿条!

wuzhu266 2011-06-11 03:02:23
我使用6410开发板,wince6.0操作系统实现h.264的硬解码,解码后使用directdraw实现对YUV视频数据的直接显示,显示的时候发现视频图像的右下方有绿条出现,初步考虑是右下角的宏快区域写得慢,导致图像刷新不过来,而且改变不同的帧率和GOP绿条的出现几率还不一样,同样帧率下gop越大绿条出现的几率很小,当gop=1,即全为关键帧时,绿条一直存在,请问该怎么解决呢?
// TestCode.cpp : Defines the entry point for the console application.
//
#include <windows.h>
#include <stdio.h>
#include <ddraw.h>

#include "SsbSipH264Decode.h"
#include "FrameExtractor.h"
#include "H264Frames.h"

#include "mfc_decode.h"
#include "mfc_render.h"
#include "number_img.h"
#include "Record.h"
#include "icamprotocol.h"
#include "hw_lib.h"
//#define MAX_STREAM_BUFFER_NUM 5

static unsigned char delimiter_h264[4] = {0x00, 0x00, 0x00, 0x01};
int nLoop;
DWORD t1, t2, t_diff; // tick for performance measurement
int perf_disp_period = 100;
wchar_t str_performance[8];
float fps;
//decoder
unsigned char *pStrmBuf;
int nFrameLeng;
unsigned char *pYUVBuf;
int nYUVLeng;

FRAMEX_CTX *pFrameExCtx;

unsigned char *delimiter;
int delimiter_leng;

SSBSIP_H264_STREAM_INFO stream_info;
STREAM_BUFFER_INFO *streamBufferInfo;
SIZE_IMG_IDX size_img_idx;

void *decoderHandle;
void *hRender;
static int flag=0;
void *video_disp_handle;
extern queue<CAudioData> video_vData;
extern queue<CAudioData> first_vData;
//unsigned char firstvideo[1024*30];
extern CAudioData video_first;
extern int del_device_flg;
//extern FRAMEX_CTX *FrameExtractorInit(FRAMEX_IN_TYPE type, unsigned char delimiter[], int delim_leng, int delim_insert);

//static DWORD WINAPI mfcdec_demo(void)

int mfcdec_demo(void)
{
delimiter = delimiter_h264;
delimiter_leng = sizeof(delimiter_h264);
STREAM_BUFFER_INFO *streamBufferInfo;
int encoderFrameBufCounter=0;
CAudioData disp_data;
disp_data.data=(unsigned char*)malloc(1024*300*sizeof(unsigned char));
//init render

//int decoderBufCounter = 0;
//printf("896585868096086096\n");
///////////////////////////////////
// FrameExtractor Initialization //
///////////////////////////////////
pFrameExCtx = FrameExtractorInit(FRAMEX_IN_TYPE_MEM, delimiter, delimiter_leng, 1);
//////////////////////////////////////
/// 1. Create new instance ///
//////////////////////////////////////
//printf("front645646\n");
decoderHandle = SsbSipH264DecodeInit();
if (decoderHandle == NULL) {
RETAILMSG(1,(L"Decoder Init Failed.\n"));
return 0;
}
//printf("back45546\n");
/////////////////////////////////////////////
/// 2. Obtaining the Input Buffer ///
/// (SsbSipH264DecodeGetInBuf) ///
/////////////////////////////////////////////
pStrmBuf = (unsigned char *) SsbSipH264DecodeGetInBuf(decoderHandle, 204800);
if (pStrmBuf == NULL) {
RETAILMSG(1,(L"SsbSipH264DecodeGetInBuf Failed.\n"));
SsbSipH264DecodeDeInit(decoderHandle);
return 0;
}
/**********copy receive data***********/


memcpy(pStrmBuf,video_first.data,video_first.length);
nFrameLeng=video_first.length;
// for(int i=0;i<21;i++)
// {
// printf("pStrmBuf[%d]=%d\n",i,pStrmBuf[i]);
// }

// for(int i=0;i<5;i++)
// printf("video_vData.front().data[%d]=%d\n",i,video_vData.front().data[i]);
//printf("nFrameLeng=%d\n",nFrameLeng);

////////////////////////////////////////////////////////////////
/// 3. Configuring the instance with the config stream ///
/// (SsbSipH264DecodeExe) ///
////////////////////////////////////////////////////////////////
printf("nFrameLeng=%d\n",nFrameLeng);
if (SsbSipH264DecodeExe(decoderHandle, nFrameLeng) != SSBSIP_H264_DEC_RET_OK) {
// free(disp_data.data);
RETAILMSG(1,(L"H.264 Decoder Configuration Failed.\n"));
return 0;
}

/////////////////////////////////////
/// 4. Get stream information ///
/////////////////////////////////////
if((SsbSipH264DecodeGetConfig(decoderHandle, H264_DEC_GETCONF_STREAMINFO, &(stream_info)))==SSBSIP_H264_DEC_RET_OK)
printf("SsbSipH264DecodeGetConfig success!\n");
//RETAILMSG(1,(L"\n\t<STREAMINFO> width=%d height=%d.\n", stream_info[pip].width, stream_info[pip].height));

/*********************render for display************************/
// Performance display interval setting
hRender = mfc_render_create_overlay(MFC_RENDER_SURFACE_TYPE_YV12,
0, 0,
stream_info.width, stream_info.height,
256, 220);
// 320,240);
//352,208);
// 480,272);

if ((stream_info.width == 320) && (stream_info.height == 240)) {
size_img_idx = SIZE_IMG_QVGA;
perf_disp_period = 200;
}
else if ((stream_info.width == 640) && (stream_info.height == 480)) {
size_img_idx = SIZE_IMG_VGA;
perf_disp_period = 100;
}
else if ((stream_info.width == 720) && (stream_info.height == 480)) {
size_img_idx = SIZE_IMG_SD;
perf_disp_period = 60;
}
else if ((stream_info.width == 720) && (stream_info.height == 576)) {
size_img_idx = SIZE_IMG_SD;
perf_disp_period = 60;
}
else {
size_img_idx = SIZE_IMG_UNDEF;
perf_disp_period = 100;
}

t1 = GetTickCount();

for (nLoop=0; ; ) {

if(del_device_flg)
{
printf("release device@@@@@@@@@@@\n");
mfc_render_delete_overlay(hRender);
del_device_flg=0;
if(0==SsbSipH264DecodeDeInit(decoderHandle))
printf("close video device success!\n");
else
printf("close video device failed!\n");
break;
}

if(video_vData.size()!=0)
{

//直接copy到显示buffer //show camera yuv buffer to display
//memcpy(decoderOutBuf[decoderBufCounter],inYUVbuf[encoderFrameBufCounter],BUFF_SIZE);

//////////////////////////////////
/// 5. DECODE ///
/// (SsbSipH264DecodeExe) ///
//////////////////////////////////
if (SsbSipH264DecodeExe(decoderHandle, nFrameLeng) != SSBSIP_H264_DEC_RET_OK) {
// sprintf(msg, "\n\t Error in decoding -th video, %d-th frame\n", nLoop);
RETAILMSG(1,(L"DECODE ERROR\n"));
continue;
}
// printf("nFrameLeng=%d\n",nFrameLeng);
//////////////////////////////////////////////
/// 6. Obtaining the Output Buffer ///
/// (SsbSipH264DecodeGetOutBuf) ///
//////////////////////////////////////////////
pYUVBuf = (unsigned char *) SsbSipH264DecodeGetOutBuf(decoderHandle, (long *) &(nYUVLeng));
//printf("nYUVLeng=%ld\n",nYUVLeng);


mfc_render_do(hRender, pYUVBuf, stream_info.width, stream_info.height, MFC_RENDER_IMAGE_TYPE_YUV420);
mfc_render_flip(hRender);

// Next VIDEO stream //
//将解码流数据buffer送入解码器 //copy next stream frame to decoder
//printf("video_vData.size=%d\n",video_vData.size());

memcpy(pStrmBuf,video_vData.front().data,video_vData.front().length);
nFrameLeng=video_vData.front().length;
video_vData.pop();
nLoop++;
if (nLoop == perf_disp_period) {
t2 = GetTickCount();
t_diff = t2 - t1;
fps = (float)(1000 * nLoop) / t_diff;
wsprintf(str_performance, L"%3.1f", fps);
printf("Decoder =%s fps\n", str_performance);
nLoop = 0;
t1 = GetTickCount();
}
}
else
continue;

}

free(disp_data.data);
return 0;
}
,以上是我实现显示的代码,采用的是overlay的方式,请问该怎么解决这个问题呢?
...全文
419 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
wuzhu266 2011-06-21
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 arrowrain 的回复:]
存为文件,本地播放试试 或者 到Windows,Linux下面播放试试。
你的是底部一条线都是绿色还是只有很小的一段是绿色。
[/Quote]
只有一小段是绿条!
arrowrain 2011-06-20
  • 打赏
  • 举报
回复
存为文件,本地播放试试 或者 到Windows,Linux下面播放试试。
你的是底部一条线都是绿色还是只有很小的一段是绿色。
wuzhu266 2011-06-16
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 crystal28 的回复:]
网络传输是udp还是tcp?比较一下两边哪一步的结果不同不就行了?
yuv全为0就是绿色。
我觉得可能全为关键帧时,因为码率会比较大,导致网络传输时丢包
[/Quote]
网络传输是TCP,应该不存在丢包问题把?还有是不是因为显示的时候没有及时啊,就是解码完得这一包数据去送显示,但还没有显示完全,下一帧又来显示,会是这种情况吗?另外YUV数据我还没来及测,但感觉应该不是YUV数据的原因吧。其他地方没有绿条,就右下角存在绿条啊?
wuzhu266 2011-06-15
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 crystal28 的回复:]
把yuv数据保存成文件,打开看是不是有大片数据全为0,这样就可以确定是directdraw的问题还是其他的
[/Quote]
在进行本地测试时(即linux那端得边采边播,同时采集-编码-解码-显示),没有绿条的出现啊,通过网络传输到我这里进行解码后就出现了这种现象。这两端得开发板相同,就是系统不同?YUV数据都为0意味着什么呢?
「已注销」 2011-06-15
  • 打赏
  • 举报
回复
网络传输是udp还是tcp?比较一下两边哪一步的结果不同不就行了?
yuv全为0就是绿色。
我觉得可能全为关键帧时,因为码率会比较大,导致网络传输时丢包
「已注销」 2011-06-14
  • 打赏
  • 举报
回复
把yuv数据保存成文件,打开看是不是有大片数据全为0,这样就可以确定是directdraw的问题还是其他的
wuzhu266 2011-06-13
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 aaa_tnt 的回复:]
降低摄像头的输入CLK试试
[/Quote]
摄像头是另一端开发板(linux)通过网络传递到我这端的(wince),我进行解码和显示,想在已经将摄像头的时钟由24m改到了12m,没有什么效果啊!是我这边显示程序的原因还是其他的原因。
Ei 2011-06-11
  • 打赏
  • 举报
回复
降低摄像头的输入CLK试试
当我遇上-你 2011-06-11
  • 打赏
  • 举报
回复
帮顶,等高人

19,502

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 嵌入开发(WinCE)
社区管理员
  • 嵌入开发(WinCE)社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧