📄 decode.c
字号:
* 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;
}
/******************************************************************************
* decodeThrFxn
******************************************************************************/
void *decodeThrFxn(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;
struct one_block block;
int addr_len;
int sockfd, new_fd; // lislen on sock-fd! n6r connection on nes-Id
struct sockaddr_in my_addr; // ry addiess i;fornation, : :., ii
struct sockaddr_in their_addr; //'-corin6cfotl,s dddres$lnforultion :
char buf[100];
int sin_size;
struct sigaction sa;
int yes = 1, numbytes;
if(envp->resolution == D1)
{
captureWidth=720;
captureHeight=480;
}
else
{
captureWidth=CIF_WIDTH;
captureHeight=CIF_HEIGHT;
}
fbFd = initDisplayDevice(envp->resolution, displays);
if (fbFd == FAILURE) {
CLEANUP(THREAD_FAILURE);
}
DBG("Framebuffer device initialized.\n\n");
initLevel = DISPLAYDEVICEINITIALIZED;
#if 0
captureFd = initCaptureDevice(envp->resolution, &vidBufs, &numVidBufs,
&captureWidth, &captureHeight);
if (captureFd == FAILURE) {
CLEANUP(THREAD_FAILURE);
}
#endif
captureSize = captureWidth * captureHeight * SCREEN_BPP / 8;
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;
#if 0
/* Allocate and initialize video encoder on the engine */
if (videoEncodeAlgCreate(hEngine, &hEncode,
captureWidth, captureHeight) == FAILURE) {
CLEANUP(THREAD_FAILURE);
}
#endif
initLevel = VIDEOENCODERCREATED;
DBG("$$$$$$$$$$$$$$$$$$decode:captureWidth=%d,captureHeight=%d\n",captureWidth,captureHeight);
/* Allocate and initialize video decoder on the engine */
if (videoDecodeAlgCreate(hEngine, &hDecode, &encBufSize,
captureWidth, captureHeight) == FAILURE) {
CLEANUP(THREAD_FAILURE);
}
initLevel = VIDEODECODERCREATED;
if(envp->resolution==D1)
encBufSize=150000;
else
encBufSize=10000;
DBG("decode: encBufSize=%d%%%%%%%%%%%%%%%%%%%%%\n",encBufSize);
/* Allocate intermediate buffer (for encoded data) */
encBuf = (char *) Memory_contigAlloc(encBufSize,
Memory_DEFAULTALIGNMENT);
if (encBuf == NULL) {
ERR("DECODE:Failed to allocate contiguous memory block.\n");
CLEANUP(THREAD_FAILURE);
}
DBG("decode:Contiguous buffer allocated at phyical address 0x%lx encBufSize=%d)\n\n",
Memory_getPhysicalAddress(encBuf),encBufSize);
initLevel = ENCODEDBUFFERALLOCATED;
DBG("CIF_FRAME_SIZE=%d\n",CIF_FRAME_SIZE);
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_RDONLY/*O_WRONLY | O_CREAT | O_TRUNC*/)) == -1)
{
fprintf(stderr,"Open %s Error:%s\n","recvbuf",strerror(errno));
exit(1);
}
/* Signal main thread that video initialization is done */
MET_CONDITION(encodeMutex, encodeInit);
DBG("decode: metcondition\n\n");
// WAIT_CONDITION(networkMutex, networkInit);
DBG("decode: met network condition\n");
/* Wait until all the other threads have done their initialization */
WAIT_CONDITION(allMutex, allInit);
DBG("Entering decode main loop.\n\n");
block.buf=encBuf;
block.len=0;
while (!getQuit()) {
#if 0
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);
}
printf("encode frameSize=%d\n",frameSize);
/* 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);
}
if((fd = open("recvbuf",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. \n" );
close( fd );
#endif
#if 0
// memset(encBuf, 0x0, encBufSize);
if((frameSize=recv(new_fd, encBuf, encBufSize, 0/*MSG_WAITALL*/)) == -1)
{
perror("recv");
exit(1);
}
printf("RECV: frameSize=%d\n", frameSize);
#endif
if(dequeue(recv_queue, &block))
{
DBG("decode:dequeue, datalen=%d\n",block.len);
#if 0
write( fd, encBuf, frameSize );
printf( "video:write file ok. \n" );
#endif
#if 0
frameSize=6220;
memset(encBuf, 0x0, encBufSize);
/* if((fd = open("encbuf",O_RDWR,S_IRUSR|S_IWUSR)) == -1)
{
fprintf(stderr,"Open %s Error:%s\n","savebuf",strerror(errno));
exit(1);
}
*/
read(fd,encBuf,frameSize);
printf("video:read file ok.\n");
close(fd);
#endif
dst = envp->resolution == D1 ? displays[workingIdx] : cifBuf;
DBG("decode:: captureSize=%d\n",captureSize);
/* Decode the buffer using H.264 */
if (decodeVideoBuffer(hDecode, encBuf, block.len, dst, captureSize, &framesDropped) == FAILURE) {
BREAK_LOOP(THREAD_FAILURE);
}
DBG("decode %d bytes+++++++++++++++++++++++++++++\n\n", frameSize);
#if 1
/*
* 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) {
src = dst;
if (envp->resolution == ZOOM) {
DBG("zoom\n");
dst = displays[workingIdx];
}
else {
DBG("cif\n");
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;
}
}
#endif
/* Increment statistics for OSD display */
incFrames();
incVideoBytesEncoded(frameSize);
DBG("decode: workingIdx=%d displayIdx=%d\n",workingIdx,displayIdx);
/* Flip the display buffers */
displayIdx = (displayIdx + 1) % NUM_BUFS;
workingIdx = (workingIdx + 1) % NUM_BUFS;
flipDisplayBuffers(fbFd, displayIdx);
}
}
printf("Total number of video frames dropped: %d\n", framesDropped);
cleanup:
close(fd);
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 + -