Hi, Im new to C. I am trying to encode a series of BMP into JPEG, fragment it(becuz of MTU) and send to a UDP server. The server just echoes everything back to me(client). Then I construct a complete JPEG with enough fragments received from server.
Program structure:
socket send() is done in main thread when a timer goes off. and in WM_CREATE, I start a thread to listen on the socket and receive in an infinite loop, which is recvThread shown below.
Problem:
In debugging mode, I can see that each JPEG frame is received correctly when (recvNum == totalNum, set break point here). However, in run-time(or when I set break point in "jpeg_decode(jpegBuf, bmpBuf, pr->bmpFrameSize);"), each JPEG frame has some wrong data and the image is either incomplete or with some wrong part.
The following is some related code. I will paste more if necessary. New here, thanks in advance.
Code:typedef struct { int* len; long* fn; long* pn; SOCKET fd; unsigned char *encBuf; unsigned char *frameBuf; unsigned char *outFrameBuf; struct JpegPacketStruct jpacket; struct sockaddr_in saddr; FIFO *fifo; HWND hwnd; HANDLE hEvent; BOOL bContinue; DWORD bmpFrameSize; } FrameInfo; void * StartThread(int(*func)(void *arg), void *arg, int size) { DWORD id; int *argp; if(size > 0) { if((argp = malloc(size)) == 0) return 0; memcpy(argp, arg, size); } return CreateThread(0, STK_SIZE, (LPTHREAD_START_ROUTINE)func, argp, 0, &id); } void *recvThread(void *arg) { BYTE recvBuf[2048]; BYTE bmpBuf[512*1024]; BYTE jpegBuf[64*1024]; BYTE *pjpegbuf = jpegBuf; BYTE *pbmpBuf = bmpBuf; int retval; int recvNum = 0; long pktNum, totalNum, frameNum; static long currentNum = 0; //save serial number for current frame volatile FrameInfo *pr = (FrameInfo *)arg; JpegPacket jpacket; BYTE *pbuf; BYTE *prframebuf = pr->frameBuf; int saddr_len = sizeof(pr->saddr); while(1) { fd_set fds; struct timeval tv; int msec = 5000; FD_ZERO(&fds); FD_SET(pr->fd, &fds); tv.tv_sec = msec/1000; tv.tv_usec = msec%1000*1000; if(select((pr->fd)+1, &fds, NULL, NULL, &tv) <= 0) return -2; memset(recvBuf, 0, sizeof(recvBuf)); //retval = recv(pr->fd, recvBuf, sizeof(jpacket), 0); retval = recvfrom(pr->fd, recvBuf, sizeof(jpacket), 0, (struct sockaddr *)(&pr->saddr), &saddr_len); if (retval == SOCKET_ERROR) { continue; } //frame serial number pbuf = recvBuf; pbuf += sizeof(jpacket.header.info); frameNum = getlong(pbuf); pbuf += sizeof(jpacket.header.frameNum); //fragment serial number pktNum = getlong(pbuf); pbuf += sizeof(jpacket.header.pktNum); //number of fragments totalNum = getlong(pbuf); pbuf += sizeof(jpacket.header.totalNum); pbuf += sizeof(jpacket.header.len); //now pbuf points to the beginning of img data //move ptr to correct location according to pktNum and copy data pjpegbuf = jpegBuf; pjpegbuf += (pktNum)*sizeof(jpacket.payload); memcpy(pjpegbuf, pbuf, sizeof(jpacket.payload)); //number of fragments received recvNum += 1; if((recvNum == totalNum) || (pktNum == totalNum - 1)) { jpeg_decode(jpegBuf, bmpBuf, pr->bmpFrameSize); memcpy(pr->outFrameBuf, bmpBuf, pr->bmpFrameSize); //write to FIFO pbmpBuf = bmpBuf; pbmpBuf += sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); write_fifo(pr->fifo, pbmpBuf); PostMessage(pr->hwnd, WM_FRAME_RECEIVED, 0, 0); recvNum = 0; currentNum ++; } } }



LinkBack URL
About LinkBacks


