home *** CD-ROM | disk | FTP | other *** search
/ MPEG Toolkit / MPEG Toolkit.iso / dos / secmpeg3 / decode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-01  |  12.3 KB  |  643 lines

  1.  
  2. /* --- C ---
  3. ************************************************************************
  4. *
  5. *    Filename    : decode.c
  6. *    Description : Decoding of MPEG-Frames
  7. *    Part of     : SECMPEG
  8. *
  9. *    Version     : 1.0
  10. *    Language    : C
  11. *    For machine : SunOS 4.1.x, INTERACTIVE Unix 2.2.1, Linux, MS-DOS
  12. *    Compile as  : see Makefile
  13. *
  14. *    Authors     : Juergen Meyer, Frank Gadegast
  15. *    Contact     : jm@cs.tu-berlin.de, phade@cs.tu-berlin.de
  16. *
  17. ************************************************************************
  18. */
  19.  
  20. #include "defs.h"
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <sys/types.h>
  24. #ifdef DOS
  25. #include <time.h>
  26. #else
  27. #include <sys/time.h>
  28. #endif
  29. #include "decode.h"
  30.  
  31. /* ------ PUBLIC ------ */
  32.  
  33. int    DecodeFrame(int);
  34. int    GetnBit(int);
  35. int    GetBit();
  36. void   bytealign();
  37.  
  38. /* ------ PRIVAT ------ */
  39.  
  40. static void SetCTableEntry();
  41. static void DecompressMDU(int);
  42. static void DecodeDFrame();
  43. static void DecodeAC(INT,INT *);
  44. static void CBPDecodeAC(INT,INT *);
  45. static INT  DecodeDC(DHUFF *);
  46.  
  47. /* ------ IMPORT ------ */
  48.  
  49. extern void ReadHeaderTrailer();         /* header.c */
  50. extern void ReadSliceHeader();
  51. extern int  ReadMakroblockHeader();
  52.  
  53. extern INT  Decode(DHUFF *);             /* huff.c */
  54.  
  55. /* ------ VARS   ------ */
  56.  
  57. static unsigned long frame_buffer_pos = 0;
  58.  
  59. static INT        current_read_byte   = 0;
  60. static INT        read_position       = 0;
  61. static int        c_table_entries     = 0;
  62. static short      last_makroblock     = 0;
  63.  
  64. /* ------ IMPORT ------ */
  65.  
  66. extern INT  bit_set_mask[];        /* stream.c */
  67. extern BYTE *frame_buffer;
  68.  
  69. extern SECURETABLE   c_table[];    /* main.c */
  70.  
  71. extern DHUFF *DCLumDHuff;          /* huff.c */
  72. extern DHUFF *DCChromDHuff;
  73. extern DHUFF *T1DHuff;
  74. extern DHUFF *T2DHuff;
  75.  
  76. extern int current_makroblock;           /* header */
  77. extern int PType;                /* group of pictures */
  78. extern int SQuant;
  79.  
  80. extern int MType;                /* makroblock layer */
  81. extern int LastMType;
  82. extern int MQuant;
  83. extern int SVP;
  84. extern int MVD1H;
  85. extern int MVD1V;
  86. extern int MVD2H;
  87. extern int MVD2V;
  88. extern int LastMVD1H;
  89. extern int LastMVD1V;
  90. extern int LastMVD2H;
  91. extern int LastMVD2V;
  92. extern int CBP;
  93. extern int MBSRead;
  94. extern int MBAIncrement;
  95. extern int LastMBA;
  96. extern int CurrentMBA;
  97.  
  98. extern int DCQuantMType[];
  99. extern int IntraQuantMType[];
  100. extern int PredQuantMType[];
  101. extern int InterQuantMType[];
  102. extern int *QuantPMType[];
  103.  
  104. extern int IntraMFMType[];
  105. extern int PredMFMType[];
  106. extern int InterMFMType[];
  107. extern int DCMFMType[];
  108. extern int *MFPMType[];
  109.  
  110. extern int IntraMBMType[];
  111. extern int PredMBMType[];
  112. extern int InterMBMType[];
  113. extern int DCMBMType[];
  114. extern int *MBPMType[];
  115.  
  116.  
  117. extern int IntraCBPMType[];
  118. extern int PredCBPMType[];
  119. extern int InterCBPMType[];
  120. extern int DCCBPMType[];
  121. extern int *CBPPMType[];
  122.  
  123. extern int IntraIMType[];
  124. extern int PredIMType[];
  125. extern int InterIMType[];
  126. extern int DCIMType[];
  127. extern int *IPMType[];
  128.  
  129.  
  130. int  DecodeFrame(int mode)
  131. {
  132.   INT x;
  133.   INT OldType,OldMVD1V,OldMVD1H,OldMVD2V,OldMVD2H;
  134.   INT NextType,NextMVD1V,NextMVD1H,NextMVD2V,NextMVD2H,NextCBP;
  135.   INT NextMBA,NextVPos;
  136.   INT StartSlice,LastPass=0;
  137.   int temp;
  138.   unsigned long offset = 0;
  139.  
  140. #ifdef DEBUG
  141.        fprintf(stderr,"%s : %d\n","DecodeFrame",frame_count++);
  142. #endif
  143.  
  144.    /* offset = lΣnge des PictureHeaders */
  145.      offset  = 4;
  146.    /* LΣnge des Markers                 */
  147.  
  148.       do
  149.       {  
  150.   
  151.      temp = frame_buffer[offset] + frame_buffer[offset+1] + frame_buffer[offset+2] + frame_buffer[offset+3];
  152.   
  153.          offset++;
  154.       }
  155.       while(temp != 0x02);
  156.       offset += 3;  /* 4 */
  157.   
  158.  
  159.    c_table_entries  = 0;
  160.    frame_buffer_pos = 0;
  161.    c_table[0].Offset = 0;
  162.    c_table[0].Len    = 8;
  163.  
  164.    MBSRead = 0;
  165.    SVP     = 1;
  166.    CBP     = 0x3f;
  167.    current_read_byte = 0;
  168.    read_position    = -1;
  169.  
  170.    frame_buffer_pos = offset;
  171.    current_makroblock = 0;
  172.    last_makroblock    = 0;
  173.  
  174.    
  175.    /* end initialisation */
  176.  
  177.   
  178.   if (PType==P_DCINTRA)
  179.       DecodeDFrame();
  180.  
  181.   CurrentMBS=0;
  182.   CurrentMBA=LastMBA= -1;
  183.   HPos=LastMType= -1;
  184.   VPos=0;
  185.   while(TRUE)
  186.     {
  187.       if (MBSRead >= 0)
  188.     {
  189.  
  190.       ReadSliceHeader();
  191.       CurrentMBS++;
  192.       NextVPos = SVP-1;
  193.     }
  194.       else
  195.     {
  196.       NextMBA = MBHeight*MBWidth-1;
  197.       if (CurrentMBA >= NextMBA) break;
  198.       LastPass=1;
  199.       NextMBA++;
  200.     }
  201.  
  202.       MVD1H=MVD1V=MVD2H=MVD2V=0;
  203.       UseQuant=SQuant;
  204.       if (VPos > MBHeight)
  205.     {
  206. #ifdef DEBUG
  207.          fprintf(stderr,"VPos: %d  MBHeight: %d. Buffer Overflow\n",VPos,MBHeight);
  208. #endif
  209.       return(0);
  210.     }
  211.       for(x=0;x<3;x++) LastDC[x]=128;
  212.       StartSlice=1;
  213.       while(TRUE)
  214.       {
  215.       OldType=MType;
  216.       OldMVD1V=MVD1V; OldMVD1H=MVD1H;
  217.       OldMVD2V=MVD2V; OldMVD2H=MVD2H;
  218.       if (StartSlice) MVD1H=MVD1V=MVD2H=MVD2V=0;
  219.       if (!LastPass)
  220.         {
  221.           if (ReadMakroBlockHeader()) break;
  222.           if (StartSlice)
  223.         {
  224.           StartSlice=0;
  225.           NextMBA = NextVPos*MBWidth+MBAIncrement-1;
  226.         }
  227.           else
  228.         NextMBA = LastMBA + MBAIncrement;
  229.         }
  230.       else
  231.         {
  232. #ifdef DEBUG
  233.          fprintf(stderr,"Entering Last Pass: %d of %d\n",
  234.              CurrentMBA,NextMBA);
  235. #endif
  236.           if (LastPass++>1) break;
  237.         }
  238.       NextType=MType; NextCBP = CBP;
  239.       NextMVD1V=MVD1V; NextMVD1H=MVD1H;
  240.       NextMVD2V=MVD2V; NextMVD2H=MVD2H;
  241.       while(CurrentMBA < NextMBA)
  242.         {
  243.           CurrentMBA++;
  244.           if (++HPos >= MBWidth)
  245.         {HPos=0; VPos++;}
  246.           if (CurrentMBA < NextMBA)
  247.         {
  248.           switch(PType)
  249.             {
  250.             case P_INTRA:
  251. #ifdef DEBUG
  252.              fprintf(stderr,"Bad skipped macroblock.\n");
  253. #endif
  254.               MType=OldType; CBP=0;
  255.               break;
  256.             case P_PREDICTED:
  257.               if (QuantPMType[PType][OldType])
  258.             MType=5;
  259.               else MType=1;
  260.               CBP=0; MVD1V=0;MVD1H=0;
  261.               break;
  262.             case P_INTERPOLATED:
  263.               MType = OldType;
  264.               CBP = 0;
  265.               MVD1V = OldMVD1V; MVD1H = OldMVD1H;
  266.               MVD2V = OldMVD2V; MVD2H = OldMVD2H;
  267.               if (IPMType[PType][MType])
  268.             {
  269. #ifdef DEBUG
  270.                  fprintf(stderr,"Interpolated skipped INTRA macroblock\n");
  271. #endif
  272.             }
  273.               break;
  274.             }
  275.         }
  276.           else if (LastPass) break;
  277.           else
  278.         {
  279.           MType=NextType;CBP=NextCBP;
  280.           MVD1V=NextMVD1V;MVD1H=NextMVD1H;
  281.           MVD2V=NextMVD2V;MVD2H=NextMVD2H;
  282.         }
  283.  
  284.           DecompressMDU(mode);
  285.         }
  286.       LastMType = MType;
  287.       LastMBA = CurrentMBA;
  288.     }
  289.       if (MBSRead<0) break;
  290.       else ReadHeaderTrailer();
  291.     }
  292.      
  293.     return(c_table_entries);
  294. }
  295.  
  296.  
  297. static void SetCTableEntry()
  298. {
  299.  
  300.        switch(MType)
  301.        {
  302.        case 0 :/* P_INTRA */  /* break; */
  303.        case 3 :/* P_PREDICTED */
  304.            if(last_makroblock != current_makroblock)
  305.            {
  306.  
  307.               last_makroblock = current_makroblock;
  308.               if((c_table[c_table_entries].Offset + c_table[c_table_entries].Len + 7) >=  (short)frame_buffer_pos)
  309.               {
  310.               c_table[c_table_entries].Len = (short)frame_buffer_pos - c_table[c_table_entries].Offset;
  311.               }
  312.               else
  313.               {
  314.              c_table_entries++;
  315.              c_table[c_table_entries].Offset = (short)frame_buffer_pos;
  316.              c_table[c_table_entries].Len    = 0;
  317.               }
  318.            }
  319.            else
  320.            {
  321.               c_table[c_table_entries].Len = (short)frame_buffer_pos - c_table[c_table_entries].Offset;
  322.            }
  323.  
  324.        case 6 :break;
  325.        default:break;
  326.        }
  327.       
  328. }
  329.  
  330.  
  331. static void DecompressMDU(int mode)
  332. {
  333.  
  334.   INT c,j,x;
  335.   INT *input;
  336.  
  337. #ifdef CODEC_DEBUG
  338.   fprintf(stderr,"%s : %d\n","DecompressMDU",decode_mdu_count++);
  339. #endif
  340. #ifdef MB_DEBUG
  341.   fprintf(stderr,"CMBS: %d CMDU: %d  LastDC: %d\n",
  342.          VPos, HPos, LastDC[0]);
  343. #endif
  344.  
  345.   if (PType==P_PREDICTED)
  346.     {
  347.       if (!MFPMType[PType][MType]) MVD1H=MVD1V=0;
  348.     }
  349.   else if (PType==P_INTERPOLATED)
  350.     {
  351.       if (IPMType[PType][MType]) MVD1H=MVD1V=MVD2H=MVD2V=0;
  352.     }
  353.   if (QuantPMType[PType][MType])
  354.     {
  355.       UseQuant=MQuant; /* Macroblock overrides */
  356.       SQuant=MQuant;   /* Overrides for future */
  357.     }
  358.   else UseQuant=SQuant;
  359.   if (IPMType[PType][MType])
  360.     {
  361.       if ((LastMType<0)||!(IPMType[PType][LastMType]))
  362.     for(x=0;x<3;x++) LastDC[x]=128;  /* Reset DC prediction */
  363.     }                                    /* if last one wasn't Intra */
  364.  
  365.  
  366.   for(c=0;c<6;c++)
  367.     {
  368.  
  369.       j=BlockJ[c];
  370.       input = mb_buffer;
  371.       if (CBP & bit_set_mask[5-c])
  372.     {
  373.       if (CBPPMType[PType][MType])
  374.         CBPDecodeAC(0,input);
  375.       else
  376.         {
  377.           /* Intra kodierte Makrobl÷cke */
  378.           /* Intra     MType 0          */
  379.           /* Predicted       3          */
  380.           /* Interpolated    6          */
  381.  
  382.           SetCTableEntry();
  383.           if (j)
  384.         *input = DecodeDC(DCChromDHuff) + LastDC[j];
  385.           else
  386.         *input = DecodeDC(DCLumDHuff) + LastDC[j];
  387.           LastDC[j] = *input;
  388.           DecodeAC(1,input);
  389.         }
  390.  
  391.     }
  392.       else for(x=0;x<64;x++) input[x]=0;
  393.  
  394.     }
  395. }
  396.  
  397.  
  398. static void DecodeDFrame()
  399. {
  400.       fprintf(stderr," not yet implemented \n");
  401.       error_exit(0);
  402. }
  403.  
  404.  
  405.  
  406.  
  407. void DecodeAC(INT index,INT *matrix)
  408. {
  409.  
  410.   INT k,r,l;
  411.   INT *mptr;
  412.  
  413. #ifdef CODEC_DEBUG
  414.   fprintf(stderr,"DecodeAC\n");
  415. #endif
  416.  
  417.   for(mptr=matrix+index;mptr<matrix+BLOCKSIZE;mptr++) {*mptr = 0;}
  418.   for(k=index;k<BLOCKSIZE;)  
  419.     {
  420.       r = Decode(T1DHuff);
  421.       {
  422. #ifdef CC_DEBUG
  423.       fprintf(stderr," r (T1D) %d\n",(int)r);
  424. #endif
  425.       }
  426.       if (!r)
  427.     {
  428. #ifdef CODEC_DEBUG
  429.       fprintf(stderr,"Return:%d\n",k);
  430. #endif
  431.       return;
  432.     } /*Eof*/
  433.       if (r == HUFFMAN_ESCAPE)
  434.     {
  435.       r = GetnBit(6);
  436.       l = GetnBit(8);
  437.       if (l==0x00)
  438.         l = GetnBit(8); /* extended precision */
  439.       else if (l==0x80)
  440.         l = GetnBit(8) | extend_mask[8]; /* extended sign */
  441.       else if (l & bit_set_mask[7]) 
  442.         l |= extend_mask[7];
  443.     }
  444.       else
  445.     {
  446.       l = r & 0xff;
  447.       r = r >> 8;
  448.       if (GetBit()) {l = -l;}
  449.     }
  450. #ifdef CC_DEBUG
  451.       fprintf(stderr,"DecodeAC: k:%d r:%d l:%d\n",(int)k,(int)r,(int)l);
  452. #endif
  453.       k += r;
  454.       if (k>=BLOCKSIZE)
  455.     {
  456. #ifdef DEBUG
  457.       fprintf(stderr,"k greater than blocksize:\n",k);
  458. #endif
  459.       fprintf(stderr,"k greater than blocksize:\n",k);
  460.       break;
  461.     }
  462.       matrix[k++] = l;
  463.       NumberNZ++;
  464.     }
  465.   if (r = Decode(T1DHuff))
  466.     {
  467. #ifdef DEBUG
  468.       fprintf(stderr,"EOB expected, found 0x%x.\n",r);
  469. #endif
  470.       fprintf(stderr,"EOB expected, found 0x%x.\n",r);
  471.     }
  472. }
  473.  
  474. void CBPDecodeAC(INT index,INT *matrix)
  475. {
  476.  
  477.   INT k,r,l;
  478.   INT *mptr;
  479.  
  480. #ifdef CODEC_DEBUG
  481.   fprintf(stderr,"CBPDecodeAC\n");
  482. #endif
  483.  
  484.   for(mptr=matrix+index;mptr<matrix+BLOCKSIZE;mptr++) {*mptr = 0;}
  485.   k = index;
  486.   r = Decode(T2DHuff);
  487.   if (!r)
  488.   {
  489. #ifdef DEBUG
  490.       fprintf(stderr,"Bad EOF in CBP block.\n");
  491. #endif
  492.       fprintf(stderr,"Bad EOF in CBP block.\n");
  493.       return;
  494.   }
  495.   if (r==HUFFMAN_ESCAPE)
  496.   {
  497.       r = (INT)GetnBit(6);
  498.       l = (INT)GetnBit(8);
  499.       if (l==0x00)
  500.       {
  501.       l = (INT)GetnBit(8); /* extended precision */
  502.       }
  503.       else if (l==0x80)
  504.       {
  505.       l = (INT)GetnBit(8) | extend_mask[8]; /* extended sign */
  506.       }
  507.       else if (l & bit_set_mask[7])
  508.       {
  509.       l |= extend_mask[7];
  510.       }
  511.   }
  512.   else
  513.   {
  514.       l = r & 0xff;
  515.       r = r >> 8;
  516.       if (GetBit()) {l = -l;}
  517.   }
  518.   k += r;
  519.   matrix[k++] = l;
  520.   NumberNZ++;
  521.   while(k<BLOCKSIZE)
  522.   {
  523.       r = Decode(T1DHuff);
  524.       if (!r) {return;} /*Eof*/
  525.       if (r == HUFFMAN_ESCAPE)
  526.       {
  527.       r = GetnBit(6);
  528.       l = GetnBit(8);
  529.       if (l==0x00)
  530.       {
  531.           l = (INT)GetnBit(8); /* extended precision */
  532.       }
  533.       else if (l==0x80)
  534.       {
  535.           l = (INT)GetnBit(8) | extend_mask[8]; /* extended sign */
  536.       }
  537.       else if (l & bit_set_mask[7])
  538.       {
  539.           l |= extend_mask[7];
  540.       }
  541.       }
  542.       else
  543.       {
  544.       l = r & 0xff;
  545.       r = r >> 8;
  546.       if (GetBit())  {l = -l;}
  547.       }
  548.  
  549. #ifdef CC_DEBUG
  550.       fprintf(stderr,"CBPDecodeAC: k:%d r:%d l:%d\n",r,l);
  551. #endif
  552.  
  553.       if (l & bit_set_mask[7])
  554.     l |= extend_mask[7];
  555.       k += r;
  556.       if (k>=BLOCKSIZE)
  557.       {
  558. #ifdef CODEC_DEBUG
  559.       fprintf(stderr,"k greater than blocksize:\n",k);
  560. #endif
  561.       break;
  562.       }
  563.       matrix[k++] = l;
  564.       NumberNZ++;
  565.   }
  566.   if (r = Decode(T1DHuff))
  567.   {
  568. #ifdef DEBUG
  569.       fprintf(stderr,"EOB expected, found 0x%x.\n",r);
  570. #endif
  571.   }
  572. }
  573.  
  574. INT DecodeDC(DHUFF *LocalDHuff)
  575. {
  576.  
  577.   INT s,diff;
  578.  
  579.   s = Decode(LocalDHuff);
  580.  
  581. #ifdef CODEC_DEBUG
  582.   fprintf(stderr,"DecodeDC\n");
  583. #endif
  584. #ifdef CC_DEBUG
  585.   fprintf(stderr,"DC Decode sig. %d\n",s);
  586. #endif
  587.  
  588.   if (s)
  589.   {
  590.       diff = GetnBit(s);
  591.       s--;
  592.  
  593. #ifdef CC_DEBUG
  594.       fprintf(stderr,"Raw DC Decode %d\n",diff);
  595. #endif
  596.       if ((diff & bit_set_mask[s]) == 0)
  597.       {
  598.       diff |= extend_mask[s];
  599.       diff++;
  600.       }
  601.   }
  602.   else
  603.     diff=0;
  604.  
  605.   return(diff);
  606. }
  607.  
  608. void bytealign()
  609. {
  610.   current_read_byte = 0;
  611.   read_position     = -1;
  612.   frame_buffer_pos  = 0;
  613. }
  614.  
  615. int    GetBit()
  616. {
  617.   if (read_position<0)
  618.     {
  619.       current_read_byte= (INT)frame_buffer[frame_buffer_pos++];
  620.       read_position = 7;
  621.     }
  622.   if (current_read_byte&bit_set_mask[read_position--]) {return(1);}
  623.   return(0);
  624. }
  625.  
  626.  
  627. int     GetnBit(int nbits)
  628. {
  629.   int b=0;
  630.  
  631.   while(nbits--)
  632.     {
  633.       b <<= 1;
  634.       if (GetBit()) {b |= 1;}
  635.     }
  636.   return(b);
  637. }
  638.  
  639.  
  640.  
  641.  
  642.  
  643.