Main Page | File List

DecodingThread.cpp

00001 // DecodingThread.cpp : implementation file
00002 //
00003 
00004 #include "stdafx.h"
00005 #include "TransClient.h"
00006 #include "DecodingThread.h"
00007 #include "GlobalCon.h"
00008 #include "globalvar.h"
00009 
00010 #ifdef _DEBUG
00011 #define new DEBUG_NEW
00012 #undef THIS_FILE
00013 static char THIS_FILE[] = __FILE__;
00014 #endif
00015 
00016 
00017 extern int finished;
00018 extern HWND pPlayer;
00019 unsigned char *bufRGB;
00020 extern char ServerAddress[20];
00021 
00022 
00023 extern "C" 
00024 {
00025         #include "./h263/global.h"
00026 }
00027 
00028 /* Data for ConvertYUVtoRGB */
00029 
00030 long int crv_tab[256];
00031 long int cbu_tab[256];
00032 long int cgu_tab[256];
00033 
00034 long int cgv_tab[256];
00035 long int tab_76309[256];
00036 
00037 void ConvertYUVtoRGB (unsigned char *src0, unsigned char *src1, unsigned char *src2, 
00038                                           unsigned char *dst_ori, int width, int height);
00039 void init_dither_tab();
00040 
00042 // CDecodingThread
00043 
00044 IMPLEMENT_DYNCREATE(CDecodingThread, CWinThread)
00045 
00046 CDecodingThread::CDecodingThread()
00047 {
00048 }
00049 
00050 CDecodingThread::CDecodingThread(CClient* pClient)
00051 {
00052         m_pClient = pClient;
00053 }
00054 
00055 CDecodingThread::~CDecodingThread()
00056 {
00057 }
00058 
00059 BOOL CDecodingThread::InitInstance()
00060 {
00061         // TODO:  perform and per-thread initialization here
00062         // Initialize the decoder
00063 //      init_decoder();
00064         return TRUE;
00065 }
00066 
00067 int CDecodingThread::ExitInstance()
00068 {
00069         // TODO:  perform any per-thread cleanup here
00070 //      fclose(video);
00071         closesocket(m_ClientSock);
00072         return CWinThread::ExitInstance();
00073 }
00074 
00075 BEGIN_MESSAGE_MAP(CDecodingThread, CWinThread)
00076         //{{AFX_MSG_MAP(CDecodingThread)
00077                 // NOTE - the ClassWizard will add and remove mapping macros here.
00078         //}}AFX_MSG_MAP
00079 END_MESSAGE_MAP()
00080 
00082 // CDecodingThread message handlers
00083 
00084 int CDecodingThread::Run() 
00085 {
00086         // TODO: Add your specialized code here and/or call the base class
00087         recv_buf_size = 2*1024;
00088         bits_recv_buf = 0;
00089         int leng;
00090         int gob;
00091         int cc;
00092 
00093         if((recv_buf = (unsigned char*)malloc(recv_buf_size))==NULL)
00094         {
00095                 MessageBox(NULL, TEXT("cann't allocate recv_buf!"),TEXT("Client"),MB_ICONERROR | MB_OK);
00096                 return FALSE;
00097         }
00098 
00099         leng=sizeof(recv_buf_size);
00100 
00101         struct sockaddr_in servaddr;
00102 
00103         if((m_ClientSock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) 
00104         {
00105                 MessageBox(NULL, TEXT("cann't create data socket!"),TEXT("Client"),MB_ICONERROR | MB_OK);
00106                 return FALSE;
00107         }
00108 
00109         servaddr.sin_family = AF_INET;
00110         servaddr.sin_port = htons(m_pClient->m_DataPort);
00111         servaddr.sin_addr.s_addr = inet_addr(ServerAddress);
00112 
00113         if((connect(m_ClientSock, (struct sockaddr *)&servaddr, sizeof(servaddr)))==SOCKET_ERROR)
00114         {
00115                 MessageBox(NULL, TEXT("cann't connect to server!"),TEXT("Client"),MB_ICONERROR | MB_OK);
00116                 return FALSE;
00117         }
00118 
00119         setsockopt(m_ClientSock, SOL_SOCKET, SO_RCVBUF, (char *) &recv_buf_size, leng);
00120         
00121         m_framenum = 0;
00122         m_first = 1;
00123         
00124         base.pDataSock = m_ClientSock;
00125         ld=&base;
00126         initbits();
00127 
00128         while(gob=getheader())
00129         {       
00130                 if (m_first)
00131                 {
00132                         init_decoder();
00133                         init_display();
00134                         m_first = 0;
00135                 }
00136                 getpicture (&m_framenum, gob);
00137                 ConvertYUVtoRGB (current_frame[0],current_frame[1],current_frame[2],bufRGB,coded_picture_width,coded_picture_height);
00138                 ::SendMessage(pPlayer, USER_MSG_DISPLAY, m_framenum, (long)bufRGB);
00139                 m_framenum ++;
00140         }
00141         
00142         ::SendMessage(pPlayer, USER_MSG_DISPLAY, m_framenum, NULL);
00143 
00144         free(recv_buf);
00145         closesocket(m_ClientSock);
00146         free(bufRGB);
00147         
00148 
00149         for(cc=0; cc<3; cc++)
00150         {
00151                 free(next_I_P_frame[cc]);
00152                 free(prev_I_P_frame[cc]);
00153                 free(bframe[cc]);
00154                 free(tmp_f[cc]);
00155                 free(tmp_b[cc]);
00156                 free(edgeframeorig[cc]);
00157                 free(nextedgeframeorig[cc]);
00158         }
00159         VideoIsRequested = false;
00160         return true;
00161         //return CWinThread::Run();
00162 
00163 }
00164 
00165 
00166 void CDecodingThread::init_decoder()
00167 {
00168   int cc, size;
00169 
00170   /* MPEG-1 = TMN parameters */
00171   matrix_coefficients = 5;
00172 
00173   if (source_format == SF_CIF) {  // Input stream is CIF
00174     MBC = 22;
00175     MBR = 18;
00176   }
00177   else if (source_format == SF_QCIF) {   // Input stream is QCIF
00178     MBC = 11;
00179     MBR = 9;
00180   }
00181   else if (source_format == SF_SQCIF) {  // Input stream is SQCIF
00182         MBC = 8;
00183     MBR = 6;
00184   }
00185   else
00186     exit(1);
00187 
00188   horizontal_size = MBC*16;
00189   vertical_size = MBR*16;
00190 
00191   mb_width = horizontal_size/16;
00192   mb_height = vertical_size/16;
00193   coded_picture_width = 16*mb_width;
00194   coded_picture_height = 16*mb_height;
00195   chrom_width =  coded_picture_width>>1;
00196   chrom_height = coded_picture_height>>1;
00197   blk_cnt = 6;
00198 
00199   for (cc = 0; cc < 3; cc++)
00200   {
00201     if (cc == 0)
00202       size = coded_picture_width * coded_picture_height;
00203     else
00204       size = chrom_width * chrom_height;
00205 
00206     /* Used for bidirectional and direct prediction mode for true B
00207      * pictures, one for forward and one for backward. */
00208     next_I_P_frame[cc] = (unsigned char *) malloc (size);
00209 
00210     //prev_I_P_frame[cc] = (unsigned char *) malloc (size);
00211     
00212     current_frame[cc] = (unsigned char *) malloc (size);
00213 
00214     bframe[cc] = (unsigned char *) malloc (size);
00215     
00216     prev_frame[cc] = current_frame[cc];
00217     
00218     tmp_f[cc] = (unsigned char *) malloc (size);
00219 
00220     tmp_b[cc] = (unsigned char *) malloc (size);
00221   }
00222 
00223 
00224   for (cc = 0; cc < 3; cc++)
00225   {
00226     if (cc == 0)
00227     {
00228       size = (coded_picture_width + 64) * (coded_picture_height + 64);
00229 
00230       /* Stores framed version of previous inter-picture, luminance. */
00231       edgeframeorig[cc] = (unsigned char *) malloc (size);
00232 
00233       edgeframe[cc] = edgeframeorig[cc] + (coded_picture_width + 64) * 32 + 32;
00234 
00235       /* Required for true B frames backward, bidir, and direct
00236        * prediction. Stores future inter-picture, luminance */
00237       nextedgeframeorig[cc] = (unsigned char *) malloc (size);
00238 
00239       nextedgeframe[cc] = nextedgeframeorig[cc] + (coded_picture_width + 64) * 32 + 32;
00240     } 
00241     else
00242     {
00243       size = (chrom_width + 32) * (chrom_height + 32);
00244 
00245       /* Stores framed version of previous inter-picture, chrominance. */
00246       edgeframeorig[cc] = (unsigned char *) malloc (size);
00247 
00248       edgeframe[cc] = edgeframeorig[cc] + (chrom_width + 32) * 16 + 16;
00249 
00250       /* Required for true B frames backward, bidir, and direct
00251        * prediction. Stores future inter-picture, chrominance. */
00252       nextedgeframeorig[cc] = (unsigned char *) malloc (size);
00253 
00254       nextedgeframe[cc] = nextedgeframeorig[cc] + (chrom_width + 32) * 16 + 16;
00255     }
00256   }
00257 
00258   /* IDCT */
00259   if (refidct)
00260     init_idctref ();
00261   else
00262     init_idct ();
00263 
00264   prev_mv_outside_frame = prev_sac = prev_adv_pred = prev_aic = prev_df = 0;
00265   prev_slice_struct = prev_rps = prev_isd = prev_aivlc = prev_mq = 0;
00266   prev_4mv = prev_long_vectors = prev_obmc = 0;
00267 }
00268 
00269 
00270 void CDecodingThread::init_display()
00271 {
00272         int i;
00273         if (!(clp = (unsigned char *) malloc (1024))) {
00274                 AfxMessageBox ("malloc for clp failed");
00275                 return;
00276         }
00277         clp += 384;
00278         for (i = -384; i < 640; i++)
00279                 clp[i] = (i < 0) ? 0 : ((i > 255) ? 255 : i);
00280 
00281         init_dither_tab();
00282 
00283         /* now modify the couple that need it */
00284         /* allocate the memory needed to hold the RGB and visualization
00285          * information */
00286         bufRGB = (unsigned char *) malloc (3 * coded_picture_width * coded_picture_height);
00287 }
00288 
00289 
00290 void init_dither_tab ()
00291 {
00292   long int crv, cbu, cgu, cgv;
00293   int i;
00294 
00295   crv = 104597;
00296   cbu = 132201;                 /* fra matrise i global.h */
00297   cgu = 25675;
00298   cgv = 53279;
00299 
00300   for (i = 0; i < 256; i++)
00301   {
00302     crv_tab[i] = (i - 128) * crv;
00303     cbu_tab[i] = (i - 128) * cbu;
00304     cgu_tab[i] = (i - 128) * cgu;
00305     cgv_tab[i] = (i - 128) * cgv;
00306     tab_76309[i] = 76309 * (i - 16);
00307   }
00308 }
00309 
00310 
00311 
00312 
00313 /**********************************************************************
00314  *
00315  *      Name:            ConvertYUVtoRGB
00316  *      Description:     Converts YUV image to RGB (packed mode)
00317  *
00318  *      Input:           pointer to source luma, Cr, Cb, destination,
00319  *                       image width and height
00320  *      Returns:
00321  *      Side effects:
00322  *
00323  *      Date: 951208    Author: Karl.Lillevold@nta.no
00324  *
00325  ***********************************************************************/
00326 
00327 
00328 
00329 void ConvertYUVtoRGB (unsigned char *src0, unsigned char *src1, unsigned char *src2, 
00330                                           unsigned char *dst_ori, int width, int height)
00331 {
00332   extern long int crv_tab[];
00333   extern long int cbu_tab[];
00334   extern long int cgu_tab[];
00335 
00336   extern long int cgv_tab[];
00337   extern long int tab_76309[];
00338 
00339   int y11, y21;
00340   int y12, y22;
00341   int y13, y23;
00342   int y14, y24;
00343   int u, v;
00344   int i, j;
00345   int c11, c21, c31, c41;
00346   int c12, c22, c32, c42;
00347   unsigned int DW;
00348   unsigned int *id1, *id2;
00349   unsigned char *py1, *py2, *pu, *pv;
00350   unsigned char *d1, *d2;
00351 
00352   d1 = dst_ori;
00353   d1 += width * height * 3 - width * 3;
00354   d2 = d1 - width * 3;
00355 
00356   py1 = src0;
00357   pu = src1;
00358   pv = src2;
00359   py2 = py1 + width;
00360 
00361   id1 = (unsigned int *) d1;
00362   id2 = (unsigned int *) d2;
00363 
00364   for (j = 0; j < height; j += 2)
00365   {
00366     /* line j + 0 */
00367     for (i = 0; i < width; i += 4)
00368     {
00369       u = *pu++;
00370       v = *pv++;
00371       c11 = crv_tab[v];
00372       c21 = cgu_tab[u];
00373       c31 = cgv_tab[v];
00374       c41 = cbu_tab[u];
00375       u = *pu++;
00376       v = *pv++;
00377       c12 = crv_tab[v];
00378       c22 = cgu_tab[u];
00379       c32 = cgv_tab[v];
00380       c42 = cbu_tab[u];
00381 
00382       y11 = tab_76309[*py1++];  /* (255/219)*65536 */
00383       y12 = tab_76309[*py1++];
00384       y13 = tab_76309[*py1++];  /* (255/219)*65536 */
00385       y14 = tab_76309[*py1++];
00386 
00387       y21 = tab_76309[*py2++];
00388       y22 = tab_76309[*py2++];
00389       y23 = tab_76309[*py2++];
00390       y24 = tab_76309[*py2++];
00391 
00392       /* RGBR */
00393       DW = ((clp[(y11 + c41) >> 16])) |
00394         ((clp[(y11 - c21 - c31) >> 16]) << 8) |
00395         ((clp[(y11 + c11) >> 16]) << 16) |
00396         ((clp[(y12 + c41) >> 16]) << 24);
00397       *id1++ = DW;
00398 
00399       /* GBRG */
00400       DW = ((clp[(y12 - c21 - c31) >> 16])) |
00401         ((clp[(y12 + c11) >> 16]) << 8) |
00402         ((clp[(y13 + c42) >> 16]) << 16) |
00403         ((clp[(y13 - c22 - c32) >> 16]) << 24);
00404       *id1++ = DW;
00405 
00406       /* BRGB */
00407       DW = ((clp[(y13 + c12) >> 16])) |
00408         ((clp[(y14 + c42) >> 16]) << 8) |
00409         ((clp[(y14 - c22 - c32) >> 16]) << 16) |
00410         ((clp[(y14 + c12) >> 16]) << 24);
00411       *id1++ = DW;
00412 
00413       /* RGBR */
00414       DW = ((clp[(y21 + c41) >> 16])) |
00415         ((clp[(y21 - c21 - c31) >> 16]) << 8) |
00416         ((clp[(y21 + c11) >> 16]) << 16) |
00417         ((clp[(y22 + c41) >> 16]) << 24);
00418       *id2++ = DW;
00419 
00420       /* GBRG */
00421       DW = ((clp[(y22 - c21 - c31) >> 16])) |
00422         ((clp[(y22 + c11) >> 16]) << 8) |
00423         ((clp[(y23 + c42) >> 16]) << 16) |
00424         ((clp[(y23 - c22 - c32) >> 16]) << 24);
00425       *id2++ = DW;
00426 
00427       /* BRGB */
00428       DW = ((clp[(y23 + c12) >> 16])) |
00429         ((clp[(y24 + c42) >> 16]) << 8) |
00430         ((clp[(y24 - c22 - c32) >> 16]) << 16) |
00431         ((clp[(y24 + c12) >> 16]) << 24);
00432       *id2++ = DW;
00433     }
00434     id1 -= (9 * width) >> 2;
00435     id2 -= (9 * width) >> 2;
00436     py1 += width;
00437     py2 += width;
00438   }
00439 }

Generated on Mon May 8 22:27:08 2006 by  doxygen 1.3.9.1