📄 video.c
字号:
zoom.Zoom_V = ZOOM_1X;
if (ioctl(fd, FBIO_SETZOOM, &zoom)) {
ERR("Failed setting zoom parameters\n");
return FAILURE;
}
printf("Display set to %dx%d and no zoom\n",varInfo.xres, varInfo.yres);
}
return fd;
}
/******************************************************************************
* cleanupDisplayDevice
******************************************************************************/
static void cleanupDisplayDevice(int fd, char *displays[])
{
struct Zoom_Params zoom;
zoom.WindowID = VID1_INDEX;
zoom.Zoom_H = ZOOM_1X;
zoom.Zoom_V = ZOOM_1X;
if (ioctl(fd, FBIO_SETZOOM, &zoom)) {
ERR("Failed setting zoom parameters\n");
}
munmap(displays[0], D1_FRAME_SIZE * NUM_BUFS);
close(fd);
}
/******************************************************************************
* waitForFrame
******************************************************************************/
static inline int waitForFrame(int fd)
{
struct timeval tv;
fd_set fds;
int ret;
FD_ZERO(&fds);
FD_SET(fd, &fds);
/* Timeout. */
tv.tv_sec = 2;
tv.tv_usec = 0;
ret = select(fd + 1, &fds, NULL, NULL, &tv);
if (ret == -1) {
ERR("Select failed capture device (%s)\n", strerror(errno));
return FAILURE;
}
if (ret == 0) {
ERR("Select timed out\n");
return FAILURE;
}
return SUCCESS;
}
/******************************************************************************
* videoThrFxn
******************************************************************************/
void *videoThrFxn(void *arg)
{
enum InitLevels initLevel = 0;
DemoEnv *envp = (DemoEnv *) arg;
void *status = THREAD_SUCCESS;
char *cifBuf = NULL;
int displayIdx = 0;
int workingIdx = 1;
int framesDropped;
int encBufSize;
int captureFd;
int captureWidth;
int captureHeight;
char *displays[NUM_BUFS];
unsigned int numVidBufs;
VideoBuffer *vidBufs;
VIDDEC_Handle hDecode;
VIDENC_Handle hEncode;
Engine_Handle hEngine;
struct v4l2_buffer v4l2buf;
int frameSize;
int captureSize;
char *encBuf;
int fbFd;
char *dst;
char *src;
int y;
int fd;
fbFd = initDisplayDevice(envp->resolution, displays);
if (fbFd == FAILURE) {
CLEANUP(THREAD_FAILURE);
}
DBG("Framebuffer device initialized.\n");
initLevel = DISPLAYDEVICEINITIALIZED;
captureFd = initCaptureDevice(envp->resolution, &vidBufs, &numVidBufs,
&captureWidth, &captureHeight);
if (captureFd == FAILURE) {
CLEANUP(THREAD_FAILURE);
}
captureSize = captureWidth * captureHeight * SCREEN_BPP / 8;
DBG("Video capture initialized and started\n");
initLevel = CAPTUREDEVICEINITIALIZED;
/* Reset, load, and start DSP Engine */
if ((hEngine = Engine_open(ENGINE_NAME, NULL, NULL)) == NULL) {
ERR("Failed to open codec engine %s\n", ENGINE_NAME);
CLEANUP(THREAD_FAILURE);
}
initLevel = ENGINEOPENED;
/* Allocate and initialize video encoder on the engine */
if (videoEncodeAlgCreate(hEngine, &hEncode,
captureWidth, captureHeight) == FAILURE) {
CLEANUP(THREAD_FAILURE);
}
initLevel = VIDEOENCODERCREATED;
/* Allocate and initialize video decoder on the engine */
if (videoDecodeAlgCreate(hEngine, &hDecode, &encBufSize,
captureWidth, captureHeight) == FAILURE) {
CLEANUP(THREAD_FAILURE);
}
initLevel = VIDEODECODERCREATED;
DBG("encBufSize=%d\n",encBufSize);
/* Allocate intermediate buffer (for encoded data) */
encBuf = (char *) Memory_contigAlloc(encBufSize,
Memory_DEFAULTALIGNMENT);
if (encBuf == NULL) {
ERR("Failed to allocate contiguous memory block.\n");
CLEANUP(THREAD_FAILURE);
}
DBG("Contiguous buffer allocated at phyical address 0x%lx)\n",
Memory_getPhysicalAddress(encBuf));
initLevel = ENCODEDBUFFERALLOCATED;
if (envp->resolution != D1) {
/* Allocate cif buffer (until displayWidth is supported) */
cifBuf = (char *) Memory_contigAlloc(CIF_FRAME_SIZE,
Memory_DEFAULTALIGNMENT);
if (cifBuf == NULL) {
ERR("Failed to allocate contiguous memory block.\n");
CLEANUP(THREAD_FAILURE);
}
DBG("Contiguous buffer allocated at phyical address 0x%lx)\n",
Memory_getPhysicalAddress(cifBuf));
}
initLevel = CIFBUFFERALLOCATED;
if((fd = open("savebuf",O_RDWR|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR)) == -1)
{
fprintf(stderr,"Open %s Error:%s\n","recvbuf",strerror(errno));
exit(1);
}
/* Signal main thread that video initialization is done */
MET_CONDITION(videoMutex, videoInit);
/* Wait until all the other threads have done their initialization */
WAIT_CONDITION(allMutex, allInit);
DBG("Entering video main loop.\n");
while (!getQuit()) {
#if 1
if (waitForFrame(captureFd) == FAILURE) {
BREAK_LOOP(THREAD_FAILURE);
}
/* Don't play if the demo is paused */
if (!getPlay()) {
usleep(100);
continue;
}
CLEAR(v4l2buf);
v4l2buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
v4l2buf.memory = V4L2_MEMORY_MMAP;
/* Dequeue a frame buffer from the capture device driver */
if (ioctl(captureFd, VIDIOC_DQBUF, &v4l2buf) == -1) {
if (errno == EAGAIN) {
continue;
}
ERR("VIDIOC_DQBUF failed (%s)\n", strerror(errno));
BREAK_LOOP(THREAD_FAILURE);
}
frameSize = encBufSize;
/* Encode the buffer using H.264 */
if (encodeVideoBuffer(hEncode, vidBufs[v4l2buf.index].start,
captureSize, encBuf, &frameSize) == FAILURE) {
BREAK_LOOP(THREAD_FAILURE);
}
/* Issue capture buffer back to capture device driver */
if (ioctl(captureFd, VIDIOC_QBUF, &v4l2buf) == -1) {
ERR("VIDIOC_QBUF failed (%s)\n", strerror(errno));
BREAK_LOOP(THREAD_FAILURE);
}
#endif
#if 1
/* if((fd = open("savebuf",O_RDWR|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR)) == -1)
{
fprintf(stderr,"Open %s Error:%s\n","recvbuf",strerror(errno));
exit(1);
}
*/
write( fd, encBuf, frameSize );
// printf( "video:write file ok.frameSize=%d \n",frameSize );
// close(fd);
// memset(encBuf,0x0,encBufSize);
#endif
#if 0
static ii=1;
frameSize=1594;//0000;//frameSize;
if((fd = open("savebuf",O_RDONLY,S_IRUSR|S_IWUSR)) == -1)
{
fprintf(stderr,"Open %s Error:%s\n","recvbuf",strerror(errno));
exit(1);
}
if (lseek(fd, 0, SEEK_SET) == -1) {
ERR("Failed lseek on video file (%s)\n", strerror(errno));
return FAILURE;
}
int readSize=read(fd,encBuf,frameSize);
printf("video:read %d ok ii=%d\n",readSize,ii++);
close(fd);
//memcpy(encBuf,buf,readSize);
DBG("read %d bytes\n",readSize);
#endif
DBG("video:frameSize=%d\n",frameSize);
dst = envp->resolution == D1 ? displays[workingIdx] : cifBuf;
printf("workdingIdx=%d\n",workingIdx);
/* Decode the buffer using H.264 */
if (decodeVideoBuffer(hDecode, encBuf, frameSize, dst, captureSize,
&framesDropped) == FAILURE) {
BREAK_LOOP(THREAD_FAILURE);
}
/*
* Do an extra memcpy for resolutions smaller than D1. Will go away
* when we get 'displayWidth' support in the h.264 decoder.
*/
if (envp->resolution != D1) {
DBG("CIF_____________________________\n");
src = dst;
if (envp->resolution == ZOOM) {
dst = displays[workingIdx];
}
else {
dst = displays[workingIdx] + CIF_YPOS * D1_WIDTH + CIF_XPOS;
}
for (y = 0; y < captureHeight; y++) {
memcpy(dst, src, CIF_LINE_WIDTH);
dst += D1_LINE_WIDTH;
src += CIF_LINE_WIDTH;
}
}
/* Increment statistics for OSD display */
incFrames();
incVideoBytesEncoded(frameSize);
DBG("video:displayIdx=%d, workingIdx=%d\n", displayIdx, workingIdx);
/* Flip the display buffers */
displayIdx = (displayIdx + 1) % NUM_BUFS;
workingIdx = (workingIdx + 1) % NUM_BUFS;
flipDisplayBuffers(fbFd, displayIdx);
//sleep(100);
}
printf("Total number of video frames dropped: %d\n", framesDropped);
cleanup:
if (initLevel >= CIFBUFFERALLOCATED && envp->resolution != D1) {
Memory_contigFree(cifBuf, CIF_FRAME_SIZE);
}
if (initLevel >= ENCODEDBUFFERALLOCATED) {
Memory_contigFree(encBuf, encBufSize);
}
if (initLevel >= VIDEODECODERCREATED) {
VIDDEC_delete(hDecode);
}
if (initLevel >= VIDEOENCODERCREATED) {
VIDENC_delete(hEncode);
}
if (initLevel >= ENGINEOPENED) {
dspTraceDump(hEngine);
Engine_close(hEngine);
}
if (initLevel >= CAPTUREDEVICEINITIALIZED) {
cleanupCaptureDevice(captureFd, vidBufs, numVidBufs);
}
if (initLevel >= DISPLAYDEVICEINITIALIZED) {
cleanupDisplayDevice(fbFd, displays);
}
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -