home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 9 / CD_ASCQ_09_1193.iso / news / 4441 / mpegcode / src / mheaders.c < prev    next >
C/C++ Source or Header  |  1993-09-27  |  24KB  |  1,061 lines

  1. /*===========================================================================*
  2.  * mheaders.c                                     *
  3.  *                                         *
  4.  *    Procedures to generate MPEG headers                     *
  5.  *                                         *
  6.  * EXPORTED PROCEDURES:                                 *
  7.  *    Mhead_GenPictureHeader                             *
  8.  *    Mhead_GenSequenceHeader                             *
  9.  *    Mhead_GenSequenceEnder                             *
  10.  *    Mhead_GenGOPHeader                             *
  11.  *    Mhead_GenSliceHeader                             *
  12.  *    Mhead_GenSliceEnder                             *
  13.  *    Mhead_GenMBHeader                             *
  14.  *                                         *
  15.  *===========================================================================*/
  16.  
  17. /*
  18.  * Copyright (c) 1993 The Regents of the University of California.
  19.  * All rights reserved.
  20.  *
  21.  * Permission to use, copy, modify, and distribute this software and its
  22.  * documentation for any purpose, without fee, and without written agreement is
  23.  * hereby granted, provided that the above copyright notice and the following
  24.  * two paragraphs appear in all copies of this software.
  25.  *
  26.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  27.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  28.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  29.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30.  *
  31.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  32.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  33.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  34.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  35.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  36.  */
  37.  
  38. /*
  39.  *  $Header: /n/picasso/users/keving/encode/src/RCS/mheaders.c,v 1.3 1993/07/22 22:23:43 keving Exp keving $
  40.  *  $Log: mheaders.c,v $
  41.  * Revision 1.3  1993/07/22  22:23:43  keving
  42.  * nothing
  43.  *
  44.  * Revision 1.2  1993/06/30  20:06:09  keving
  45.  * nothing
  46.  *
  47.  * Revision 1.1  1993/06/03  21:08:08  keving
  48.  * nothing
  49.  *
  50.  * Revision 1.6  1993/03/01  23:03:40  keving
  51.  * nothing
  52.  *
  53.  * Revision 1.5  1993/02/17  23:18:20  dwallach
  54.  * checkin prior to keving's joining the project
  55.  *
  56.  * Revision 1.4  1993/01/18  10:20:02  dwallach
  57.  * *** empty log message ***
  58.  *
  59.  * Revision 1.3  1993/01/18  10:17:29  dwallach
  60.  * RCS headers installed, code indented uniformly
  61.  *
  62.  * Revision 1.3  1993/01/18  10:17:29  dwallach
  63.  * RCS headers installed, code indented uniformly
  64.  *
  65.  */
  66.  
  67.  
  68. /*==============*
  69.  * HEADER FILES *
  70.  *==============*/
  71.  
  72. #include "all.h"
  73. #include "bitio.h"
  74. #include "frames.h"
  75. #include "mheaders.h"
  76.  
  77.  
  78. /*==================*
  79.  * STATIC VARIABLES *
  80.  *==================*/
  81.  
  82. static uint32 mbAddrIncrTable[][2] = {
  83.     {0x0, 0},
  84.     {0x1, 1},
  85.     {0x3, 3},
  86.     {0x2, 3},
  87.     {0x3, 4},
  88.     {0x2, 4},
  89.     {0x3, 5},
  90.     {0x2, 5},
  91.     {0x7, 7},
  92.     {0x6, 7},
  93.     {0xb, 8},
  94.     {0xa, 8},
  95.     {0x9, 8},
  96.     {0x8, 8},
  97.     {0x7, 8},
  98.     {0x6, 8},
  99.     {0x17, 10},
  100.     {0x16, 10},
  101.     {0x15, 10},
  102.     {0x14, 10},
  103.     {0x13, 10},
  104.     {0x12, 10},
  105.     {0x23, 11},
  106.     {0x22, 11},
  107.     {0x21, 11},
  108.     {0x20, 11},
  109.     {0x1f, 11},
  110.     {0x1e, 11},
  111.     {0x1d, 11},
  112.     {0x1c, 11},
  113.     {0x1b, 11},
  114.     {0x1a, 11},
  115.     {0x19, 11},
  116.     {0x18, 11}};
  117.  
  118. static uint32 mbMotionVectorTable[][2] = {
  119.     {0x19, 11},
  120.     {0x1b, 11},
  121.     {0x1d, 11},
  122.     {0x1f, 11},
  123.     {0x21, 11},
  124.     {0x23, 11},
  125.     {0x13, 10},
  126.     {0x15, 10},
  127.     {0x17, 10},
  128.     {0x7, 8},
  129.     {0x9, 8},
  130.     {0xb, 8},
  131.     {0x7, 7},
  132.     {0x3, 5},
  133.     {0x3, 4},
  134.     {0x3, 3},
  135.     {0x1, 1},
  136.     {0x2, 3},
  137.     {0x2, 4},
  138.     {0x2, 5},
  139.     {0x6, 7},
  140.     {0xa, 8},
  141.     {0x8, 8},
  142.     {0x6, 8},
  143.     {0x16, 10},
  144.     {0x14, 10},
  145.     {0x12, 10},
  146.     {0x22, 11},
  147.     {0x20, 11},
  148.     {0x1e, 11},
  149.     {0x1c, 11},
  150.     {0x1a, 11},
  151.     {0x18, 11}};
  152.  
  153. static uint32 mbPatTable[][2] = {
  154.     {0x0, 0},
  155.     {0xb, 5},
  156.     {0x9, 5},
  157.     {0xd, 6},
  158.     {0xd, 4},
  159.     {0x17, 7},
  160.     {0x13, 7},
  161.     {0x1f, 8},
  162.     {0xc, 4},
  163.     {0x16, 7},
  164.     {0x12, 7},
  165.     {0x1e, 8},
  166.     {0x13, 5},
  167.     {0x1b, 8},
  168.     {0x17, 8},
  169.     {0x13, 8},
  170.     {0xb, 4},
  171.     {0x15, 7},
  172.     {0x11, 7},
  173.     {0x1d, 8},
  174.     {0x11, 5},
  175.     {0x19, 8},
  176.     {0x15, 8},
  177.     {0x11, 8},
  178.     {0xf, 6},
  179.     {0xf, 8},
  180.     {0xd, 8},
  181.     {0x3, 9},
  182.     {0xf, 5},
  183.     {0xb, 8},
  184.     {0x7, 8},
  185.     {0x7, 9},
  186.     {0xa, 4},
  187.     {0x14, 7},
  188.     {0x10, 7},
  189.     {0x1c, 8},
  190.     {0xe, 6},
  191.     {0xe, 8},
  192.     {0xc, 8},
  193.     {0x2, 9},
  194.     {0x10, 5},
  195.     {0x18, 8},
  196.     {0x14, 8},
  197.     {0x10, 8},
  198.     {0xe, 5},
  199.     {0xa, 8},
  200.     {0x6, 8},
  201.     {0x6, 9},
  202.     {0x12, 5},
  203.     {0x1a, 8},
  204.     {0x16, 8},
  205.     {0x12, 8},
  206.     {0xd, 5},
  207.     {0x9, 8},
  208.     {0x5, 8},
  209.     {0x5, 9},
  210.     {0xc, 5},
  211.     {0x8, 8},
  212.     {0x4, 8},
  213.     {0x4, 9},
  214.     {0x7, 3},
  215.     {0xa, 5},    /* grrr... 61, 62, 63 added - Kevin */
  216.     {0x8, 5},
  217.     {0xc, 6}
  218. };
  219.  
  220.  
  221. /*===========*
  222.  * CONSTANTS *
  223.  *===========*/
  224.  
  225. #define SEQ_HEAD_CODE 0x000001b3
  226. #define EXT_START_CODE 0x000001b5
  227. #define USER_START_CODE 0x000001b2
  228. #define GOP_START_CODE 0x000001b8
  229. #define PICT_START_CODE 0x00000100
  230. #define SLICE_BASE_CODE 0x00000100
  231.  
  232. #define SEQ_END_CODE    0x000001b7
  233.  
  234.  
  235. /*===============================*
  236.  * INTERNAL PROCEDURE prototypes *
  237.  *===============================*/
  238.  
  239. static void    GenMBAddrIncr _ANSI_ARGS_((BitBucket *bb, uint32 addr_incr));
  240. static void    GenPictHead _ANSI_ARGS_((BitBucket *bb, uint32 temp_ref,
  241.             uint32 code_type, uint32 vbv_delay,
  242.             int32 full_pel_forw_flag, uint32 forw_f_code,
  243.             int32 full_pel_back_flag, uint32 back_f_code,
  244.             uint8 *extra_info, uint32 extra_info_size,
  245.             uint8 *ext_data, uint32 ext_data_size,
  246.             uint8 *user_data, uint32 user_data_size));
  247. static void    GenMBType _ANSI_ARGS_((BitBucket *bb, uint32 pict_code_type,
  248.           uint32 mb_quant, uint32 motion_forw, uint32 motion_back,
  249.           uint32 mb_pattern, uint32 mb_intra));
  250. static void    GenMotionCode _ANSI_ARGS_((BitBucket *bb, int32 vector));
  251. static void    GenBlockPattern _ANSI_ARGS_((BitBucket *bb,
  252.                          uint32 mb_pattern));
  253.  
  254.  
  255. /*=====================*
  256.  * EXPORTED PROCEDURES *
  257.  *=====================*/
  258.  
  259.  
  260. /*===========================================================================*
  261.  *
  262.  * Mhead_GenPictureHeader
  263.  *
  264.  *    generate picture header with given frame type and picture count
  265.  *    append result to the specified bitstream
  266.  *
  267.  * RETURNS:    nothing
  268.  *
  269.  * SIDE EFFECTS:    none
  270.  *
  271.  *===========================================================================*/
  272. void
  273. Mhead_GenPictureHeader(bbPtr, frameType, pictCount, f_code)
  274.     BitBucket *bbPtr;
  275.     int frameType;
  276.     int pictCount;
  277.     int f_code;
  278. {
  279.     DBG_PRINT(("Picture Header\n"));
  280.     GenPictHead(bbPtr, pictCount % 1024, frameType, 0 /* vbv_delay */,
  281.         pixelFullSearch /* full_pel_forw_flag */, f_code /* forw_f_code */,
  282.         pixelFullSearch /* full_pel_back_flag */, f_code /* back_f_code */,
  283.         NULL, 0, NULL, 0, NULL, 0);
  284. }
  285.  
  286.  
  287. /*===========================================================================*
  288.  *
  289.  * Mhead_GenSequenceHeader
  290.  *
  291.  *    generate sequence header with given attributes
  292.  *    append result to the specified bitstream
  293.  *
  294.  * RETURNS:    nothing
  295.  *
  296.  * SIDE EFFECTS:    none
  297.  *
  298.  *===========================================================================*/
  299. void
  300. Mhead_GenSequenceHeader(bbPtr, hsize, vsize, pratio, pict_rate, bit_rate,
  301.             buf_size, c_param_flag, iq_matrix, niq_matrix,
  302.             ext_data, ext_data_size, user_data, user_data_size)
  303.     BitBucket *bbPtr;
  304.     uint32 hsize;
  305.     uint32 vsize;
  306.     int32 pratio;
  307.     int32 pict_rate;
  308.     int32 bit_rate;
  309.     int32 buf_size;
  310.     int8 c_param_flag;
  311.     uint8 *iq_matrix;
  312.     uint8 *niq_matrix;
  313.     uint8 *ext_data;
  314.     int32 ext_data_size;
  315.     uint8 *user_data;
  316.     int32 user_data_size;
  317. {
  318.     int i;
  319.  
  320.     /* Write seq start code. */
  321.  
  322.     Bitio_Write(bbPtr, SEQ_HEAD_CODE, 32);
  323.  
  324.     /* Write horiz. and vert. sizes. */
  325.  
  326.     Bitio_Write(bbPtr, hsize, 12);
  327.     Bitio_Write(bbPtr, vsize, 12);
  328.  
  329.     /* Write pixel aspect ratio, negative values default to 1. */
  330.  
  331.     if (pratio < 0) {
  332.     pratio = 1;
  333.     }
  334.     Bitio_Write(bbPtr, pratio, 4);        /* 0001 */
  335.  
  336.     /* Wrtie picture rate, negative values default to 30 fps. */
  337.  
  338.     if (pict_rate < 0) {
  339.     pict_rate = 5;            /* 30 fps */
  340.     }
  341.     Bitio_Write(bbPtr, pict_rate, 4);
  342.  
  343.     /* Write bit rate, negative values default to variable. */
  344.  
  345.     if (bit_rate < 0) {
  346.     bit_rate = -1;
  347.     } else {
  348.     bit_rate = bit_rate / 400;
  349.     }
  350.  
  351.     Bitio_Write(bbPtr, bit_rate, 18);
  352.  
  353.     /* Marker bit. */
  354.     Bitio_Write(bbPtr, 0x1, 1);
  355.  
  356.     /* Write VBV buffer size. Negative values default to zero. */
  357.     if (buf_size < 0) {
  358.     buf_size = 0;
  359.     }
  360.     /* buf_size < 327680 */
  361.     buf_size = 16;
  362.     Bitio_Write(bbPtr, buf_size, 10);    /* ??? */
  363.  
  364.     /* Write constrained parameter flag. */
  365.     c_param_flag = 0;
  366.  
  367.     if (c_param_flag) {
  368.     Bitio_Write(bbPtr, 0x01, 1);
  369.     } else {
  370.     Bitio_Write(bbPtr, 0x00, 1);
  371.     }
  372.  
  373.     /* Write intra quant matrix if present. */
  374.  
  375.     if (iq_matrix != NULL) {
  376.     Bitio_Write(bbPtr, 0x01, 1);
  377.     for (i = 0; i < 64; i++) {
  378.         Bitio_Write(bbPtr, iq_matrix[i], 8);
  379.     }
  380.     } else {
  381.     Bitio_Write(bbPtr, 0x00, 1);
  382.     }
  383.  
  384.     /* Write non intra quant matrix if present. */
  385.  
  386.     if (niq_matrix != NULL) {
  387.     Bitio_Write(bbPtr, 0x01, 1);
  388.     for (i = 0; i < 64; i++) {
  389.         Bitio_Write(bbPtr, niq_matrix[i], 8);
  390.     }
  391.     } else {
  392.     Bitio_Write(bbPtr, 0x00, 1);
  393.     }
  394.  
  395.     /* next start code */
  396.     Bitio_BytePad(bbPtr);
  397.  
  398.  
  399.     /* Write ext data if present. */
  400.  
  401.     if (ext_data != NULL) {
  402.     Bitio_Write(bbPtr, EXT_START_CODE, 32);
  403.  
  404.     for (i = 0; i < ext_data_size; i++) {
  405.         Bitio_Write(bbPtr, ext_data[i], 8);
  406.     }
  407.     Bitio_BytePad(bbPtr);
  408.     }
  409.     /* Write user data if present. */
  410.     if (user_data != NULL) {
  411.     Bitio_Write(bbPtr, USER_START_CODE, 32);
  412.  
  413.     for (i = 0; i < user_data_size; i++) {
  414.         Bitio_Write(bbPtr, user_data[i], 8);
  415.     }
  416.     Bitio_BytePad(bbPtr);
  417.     }
  418. }
  419.  
  420.  
  421. /*===========================================================================*
  422.  *
  423.  * Mhead_GenSequenceEnder
  424.  *
  425.  *    generate sequence ender
  426.  *    append result to the specified bitstream
  427.  *
  428.  * RETURNS:    nothing
  429.  *
  430.  * SIDE EFFECTS:    none
  431.  *
  432.  *===========================================================================*/
  433. void
  434. Mhead_GenSequenceEnder(bbPtr)
  435.     BitBucket *bbPtr;
  436. {
  437.     Bitio_Write(bbPtr, SEQ_END_CODE, 32);
  438. }
  439.  
  440.  
  441. /*===========================================================================*
  442.  *
  443.  * Mhead_GenGOPHeader
  444.  *
  445.  *    generate GOP header with specified attributes
  446.  *    append result to the specified bitstream
  447.  *
  448.  * RETURNS:    nothing
  449.  *
  450.  * SIDE EFFECTS:    none
  451.  *
  452.  *===========================================================================*/
  453. void
  454. Mhead_GenGOPHeader(bbPtr, drop_frame_flag, tc_hrs, tc_min, tc_sec, tc_pict,
  455.            closed_gop, broken_link, ext_data, ext_data_size,
  456.            user_data, user_data_size)
  457.     BitBucket *bbPtr;
  458.     int32 drop_frame_flag;
  459.     int32 tc_hrs;
  460.     int32 tc_min;
  461.     int32 tc_sec;
  462.     int32 tc_pict;
  463.     int32 closed_gop;
  464.     int32 broken_link;
  465.     uint8 *ext_data;
  466.     int32 ext_data_size;
  467.     uint8 *user_data;
  468.     int32 user_data_size;
  469. {
  470.     int i;
  471.  
  472.     /* Write gop start code. */
  473.     Bitio_Write(bbPtr, GOP_START_CODE, 32);
  474.  
  475.         /* Construct and write timecode. */
  476.  
  477.     /* Drop frame flag. */
  478.     if (drop_frame_flag) {
  479.     Bitio_Write(bbPtr, 0x01, 1);
  480.     } else {
  481.     Bitio_Write(bbPtr, 0x00, 1);
  482.     }
  483.  
  484.     /* Time code hours. */
  485.     Bitio_Write(bbPtr, tc_hrs, 5);
  486.  
  487.     /* Time code minutes. */
  488.     Bitio_Write(bbPtr, tc_min, 6);
  489.  
  490.     /* Marker bit. */
  491.     Bitio_Write(bbPtr, 0x01, 1);
  492.  
  493.     /* Time code seconds. */
  494.     Bitio_Write(bbPtr, tc_sec, 6);
  495.  
  496.     /* Time code pictures. */
  497.     Bitio_Write(bbPtr, tc_pict, 6);
  498.  
  499.  
  500.     /* Closed gop flag. */
  501.     if (closed_gop) {
  502.     Bitio_Write(bbPtr, 0x01, 1);
  503.     } else {
  504.     Bitio_Write(bbPtr, 0x00, 1);
  505.     }
  506.  
  507.     /* Broken link flag. */
  508.     if (broken_link) {
  509.     Bitio_Write(bbPtr, 0x01, 1);
  510.     } else {
  511.     Bitio_Write(bbPtr, 0x00, 1);
  512.     }
  513.  
  514.     /* next start code */
  515.     Bitio_BytePad(bbPtr);
  516.  
  517.     /* Write ext data if present. */
  518.  
  519.     if (ext_data != NULL) {
  520.     Bitio_Write(bbPtr, EXT_START_CODE, 32);
  521.  
  522.     for (i = 0; i < ext_data_size; i++) {
  523.         Bitio_Write(bbPtr, ext_data[i], 8);
  524.     }
  525.     Bitio_BytePad(bbPtr);
  526.     }
  527.     /* Write user data if present. */
  528.     if (user_data != NULL) {
  529.     Bitio_Write(bbPtr, USER_START_CODE, 32);
  530.  
  531.     for (i = 0; i < user_data_size; i++) {
  532.         Bitio_Write(bbPtr, user_data[i], 8);
  533.     }
  534.     Bitio_BytePad(bbPtr);
  535.     }
  536. }
  537.  
  538.  
  539. /*===========================================================================*
  540.  *
  541.  * Mhead_GenSliceHeader
  542.  *
  543.  *    generate slice header with specified attributes
  544.  *    append result to the specified bitstream
  545.  *
  546.  * RETURNS:    nothing
  547.  *
  548.  * SIDE EFFECTS:    none
  549.  *
  550.  *===========================================================================*/
  551. void
  552. Mhead_GenSliceHeader(bbPtr, verticalPos, qscale, extra_info, extra_info_size)
  553.     BitBucket *bbPtr;
  554.     uint32 verticalPos;
  555.     uint32 qscale;
  556.     uint8 *extra_info;
  557.     uint32 extra_info_size;
  558. {
  559.     int i;
  560.  
  561.     /* Write slice start code. */
  562.     Bitio_Write(bbPtr, (SLICE_BASE_CODE + verticalPos), 32);
  563.  
  564.     /* Quant. scale. */
  565.     Bitio_Write(bbPtr, qscale, 5);
  566.  
  567.     /* Extra bit slice info. */
  568.  
  569.     if (extra_info != NULL) {
  570.     for (i = 0; i < extra_info_size; i++) {
  571.         Bitio_Write(bbPtr, 0x01, 1);
  572.         Bitio_Write(bbPtr, extra_info[i], 8);
  573.     }
  574.     }
  575.  
  576.     /* extra_bit_slice */
  577.     Bitio_Write(bbPtr, 0x00, 1);
  578. }
  579.  
  580.  
  581. /*===========================================================================*
  582.  *
  583.  * Mhead_GenSliceEnder
  584.  *
  585.  *    generate slice ender
  586.  *    append result to the specified bitstream
  587.  *
  588.  * RETURNS:    nothing
  589.  *
  590.  * SIDE EFFECTS:    none
  591.  *
  592.  *===========================================================================*/
  593. void
  594. Mhead_GenSliceEnder(bbPtr)
  595.     BitBucket *bbPtr;
  596. {
  597.     Bitio_BytePad(bbPtr);
  598. }
  599.  
  600.  
  601. /*===========================================================================*
  602.  *
  603.  * Mhead_GenMBHeader
  604.  *
  605.  *    generate macroblock header with given attributes
  606.  *    append result to the specified bitstream
  607.  *
  608.  * RETURNS:    nothing
  609.  *
  610.  * SIDE EFFECTS:    none
  611.  *
  612.  *===========================================================================*/
  613. void
  614. Mhead_GenMBHeader(bbPtr, pict_code_type, addr_incr, mb_quant, q_scale,
  615.           forw_f_code, back_f_code, horiz_forw_r, vert_forw_r,
  616.           horiz_back_r, vert_back_r, motion_forw, m_horiz_forw,
  617.           m_vert_forw, motion_back, m_horiz_back, m_vert_back,
  618.           mb_pattern, mb_intra)
  619.     BitBucket *bbPtr;
  620.     uint32 pict_code_type;
  621.     uint32 addr_incr;
  622.     uint32 mb_quant;
  623.     uint32 q_scale;
  624.     uint32 forw_f_code;
  625.     uint32 back_f_code;
  626.     uint32 horiz_forw_r;
  627.     uint32 vert_forw_r;
  628.     uint32 horiz_back_r;
  629.     uint32 vert_back_r;
  630.     int32 motion_forw;
  631.     int32 m_horiz_forw;
  632.     int32 m_vert_forw;
  633.     int32 motion_back;
  634.     int32 m_horiz_back;
  635.     int32 m_vert_back;
  636.     uint32 mb_pattern;
  637.     uint32 mb_intra;
  638. {
  639.     /* MB escape sequences if necessary. */
  640.  
  641.     while (addr_incr > 33) {
  642.     Bitio_Write(bbPtr, 0x008, 11);
  643.     addr_incr -= 33;
  644.     }
  645.  
  646.     /* Generate addr incr code. */
  647.     GenMBAddrIncr(bbPtr, addr_incr);
  648.  
  649.     /* Generate mb type code. */
  650.     GenMBType(bbPtr, pict_code_type, mb_quant, motion_forw, motion_back, mb_pattern, mb_intra);
  651.  
  652.     /* MB quant. */
  653.     if (mb_quant) {
  654.     Bitio_Write(bbPtr, q_scale, 5);
  655.     }
  656.     /* Forward predictive vector stuff. */
  657.  
  658.     if (motion_forw) {
  659.     int forw_f, forw_r_size;
  660.  
  661.     forw_r_size = forw_f_code - 1;
  662.     forw_f = 1 << forw_r_size;
  663.  
  664.     GenMotionCode(bbPtr, m_horiz_forw);
  665.  
  666.     if ((forw_f != 1) && (m_horiz_forw != 0)) {
  667.         Bitio_Write(bbPtr, horiz_forw_r, forw_r_size);
  668.     }
  669.     GenMotionCode(bbPtr, m_vert_forw);
  670.  
  671.     if ((forw_f != 1) && (m_vert_forw != 0)) {
  672.         Bitio_Write(bbPtr, vert_forw_r, forw_r_size);
  673.     }
  674.     }
  675.     /* Back predicted vector stuff. */
  676.  
  677.     if (motion_back) {
  678.     int back_f, back_r_size;
  679.  
  680.     back_r_size = back_f_code - 1;
  681.     back_f = 1 << back_r_size;
  682.  
  683.     GenMotionCode(bbPtr, m_horiz_back);
  684.  
  685.     if ((back_f != 1) && (m_horiz_back != 0)) {
  686.         Bitio_Write(bbPtr, horiz_back_r, back_r_size);
  687.     }
  688.     GenMotionCode(bbPtr, m_vert_back);
  689.  
  690.     if ((back_f != 1) && (m_vert_back != 0)) {
  691.         Bitio_Write(bbPtr, vert_back_r, back_r_size);
  692.     }
  693.     }
  694.     /* MB pattern. */
  695.  
  696.     if (mb_pattern) {
  697.     GenBlockPattern(bbPtr, mb_pattern);
  698.     }
  699. }
  700.  
  701.  
  702. /*=====================*
  703.  * INTERNAL PROCEDURES *
  704.  *=====================*/
  705.  
  706. /*===========================================================================*
  707.  *
  708.  * GenMBType
  709.  *
  710.  *    generate macroblock type with given attributes
  711.  *    append result to the specified bitstream
  712.  *
  713.  * RETURNS:    nothing
  714.  *
  715.  * SIDE EFFECTS:    none
  716.  *
  717.  *===========================================================================*/
  718. static void
  719. GenMBType(bbPtr, pict_code_type, mb_quant, motion_forw, motion_back,
  720.       mb_pattern, mb_intra)
  721.     BitBucket *bbPtr;
  722.     uint32 pict_code_type;
  723.     uint32 mb_quant;
  724.     uint32 motion_forw;
  725.     uint32 motion_back;
  726.     uint32 mb_pattern;
  727.     uint32 mb_intra;
  728. {
  729.     int code;
  730.  
  731.     switch (pict_code_type) {
  732.     case 1:
  733.     if ((motion_forw != 0) || (motion_back != 0) || (mb_pattern != 0) || (mb_intra != 1)) {
  734.         perror("Illegal parameters for macroblock type.");
  735.         exit(-1);
  736.     }
  737.     if (mb_quant) {
  738.         Bitio_Write(bbPtr, 0x1, 2);
  739.     } else {
  740.         Bitio_Write(bbPtr, 0x1, 1);
  741.     }
  742.     break;
  743.  
  744.     case 2:
  745.     code = 0;
  746.     if (mb_quant) {
  747.         code += 16;
  748.     }
  749.     if (motion_forw) {
  750.         code += 8;
  751.     }
  752.     if (motion_back) {
  753.         code += 4;
  754.     }
  755.     if (mb_pattern) {
  756.         code += 2;
  757.     }
  758.     if (mb_intra) {
  759.         code += 1;
  760.     }
  761.  
  762.     switch (code) {
  763.     case 1:
  764.         Bitio_Write(bbPtr, 0x3, 5);
  765.         break;
  766.     case 2:
  767.         Bitio_Write(bbPtr, 0x1, 2);
  768.         break;
  769.     case 8:
  770.         Bitio_Write(bbPtr, 0x1, 3);
  771.         break;
  772.     case 10:
  773.         Bitio_Write(bbPtr, 0x1, 1);
  774.         break;
  775.     case 17:
  776.         Bitio_Write(bbPtr, 0x1, 6);
  777.         break;
  778.     case 18:
  779.         Bitio_Write(bbPtr, 0x1, 5);
  780.         break;
  781.     case 26:
  782.         Bitio_Write(bbPtr, 0x2, 5);
  783.         break;
  784.     default:
  785.         perror("Illegal parameters for macroblock type.");
  786.         exit(-1);
  787.         break;
  788.     }
  789.     break;
  790.  
  791.     case 3:
  792.     code = 0;
  793.     if (mb_quant) {
  794.         code += 16;
  795.     }
  796.     if (motion_forw) {
  797.         code += 8;
  798.     }
  799.     if (motion_back) {
  800.         code += 4;
  801.     }
  802.     if (mb_pattern) {
  803.         code += 2;
  804.     }
  805.     if (mb_intra) {
  806.         code += 1;
  807.     }
  808.  
  809.     switch (code) {
  810.     case 12:
  811.         Bitio_Write(bbPtr, 0x2, 2);
  812.         break;
  813.     case 14:
  814.         Bitio_Write(bbPtr, 0x3, 2);
  815.         break;
  816.     case 4:
  817.         Bitio_Write(bbPtr, 0x2, 3);
  818.         break;
  819.     case 6:
  820.         Bitio_Write(bbPtr, 0x3, 3);
  821.         break;
  822.     case 8:
  823.         Bitio_Write(bbPtr, 0x2, 4);
  824.         break;
  825.     case 10:
  826.         Bitio_Write(bbPtr, 0x3, 4);
  827.         break;
  828.     case 1:
  829.         Bitio_Write(bbPtr, 0x3, 5);
  830.         break;
  831.     case 30:
  832.         Bitio_Write(bbPtr, 0x2, 5);
  833.         break;
  834.     case 26:
  835.         Bitio_Write(bbPtr, 0x3, 6);
  836.         break;
  837.     case 22:
  838.         Bitio_Write(bbPtr, 0x2, 6);
  839.         break;
  840.     case 17:
  841.         Bitio_Write(bbPtr, 0x1, 6);
  842.         break;
  843.     default:
  844.         perror("Illegal parameters for macroblock type.");
  845.         exit(-1);
  846.         break;
  847.     }
  848.     break;
  849.     }
  850. }
  851.  
  852.  
  853. /*===========================================================================*
  854.  *
  855.  * GenMotionCode
  856.  *
  857.  *    generate motion vector output with given value
  858.  *    append result to the specified bitstream
  859.  *
  860.  * RETURNS:    nothing
  861.  *
  862.  * SIDE EFFECTS:    none
  863.  *
  864.  *===========================================================================*/
  865. static void
  866. GenMotionCode(bbPtr, vector)
  867.     BitBucket *bbPtr;
  868.     int32 vector;
  869. {
  870.     uint32 code, num;
  871.  
  872.     if ((vector < -16) || (vector > 16)) {
  873.     perror("Motion vector out of range.");
  874.     exit(-1);
  875.     }
  876.     code = mbMotionVectorTable[vector + 16][0];
  877.     num = mbMotionVectorTable[vector + 16][1];
  878.  
  879.     Bitio_Write(bbPtr, code, num);
  880. }
  881.  
  882.  
  883. /*===========================================================================*
  884.  *
  885.  * GenBlockPattern
  886.  *
  887.  *    generate macroblock pattern output
  888.  *    append result to the specified bitstream
  889.  *
  890.  * RETURNS:    nothing
  891.  *
  892.  * SIDE EFFECTS:    none
  893.  *
  894.  *===========================================================================*/
  895. static void
  896. GenBlockPattern(bbPtr, mb_pattern)
  897.     BitBucket *bbPtr;
  898.     uint32 mb_pattern;
  899. {
  900.     uint32 code, num;
  901.  
  902.     code = mbPatTable[mb_pattern][0];
  903.     num = mbPatTable[mb_pattern][1];
  904.  
  905.     Bitio_Write(bbPtr, code, num);
  906. }
  907.  
  908.  
  909. /*===========================================================================*
  910.  *
  911.  * GenMBAddrIncr
  912.  *
  913.  *    generate macroblock address increment output
  914.  *    append result to the specified bitstream
  915.  *
  916.  * RETURNS:    nothing
  917.  *
  918.  * SIDE EFFECTS:    none
  919.  *
  920.  *===========================================================================*/
  921. static void
  922. GenMBAddrIncr(bbPtr, addr_incr)
  923.     BitBucket *bbPtr;
  924.     uint32 addr_incr;
  925. {
  926.     uint32 code;
  927.     uint32 num;
  928.  
  929.     code = mbAddrIncrTable[addr_incr][0];
  930.     num = mbAddrIncrTable[addr_incr][1];
  931.  
  932.     Bitio_Write(bbPtr, code, num);
  933. }
  934.  
  935.  
  936. /*===========================================================================*
  937.  *
  938.  * GenPictHead
  939.  *
  940.  *    generate picture header with given attributes
  941.  *    append result to the specified bitstream
  942.  *
  943.  * RETURNS:    nothing
  944.  *
  945.  * SIDE EFFECTS:    none
  946.  *
  947.  *===========================================================================*/
  948. static void
  949. GenPictHead(bbPtr, temp_ref, code_type, vbv_delay, full_pel_forw_flag,
  950.         forw_f_code, full_pel_back_flag, back_f_code, extra_info,
  951.         extra_info_size, ext_data, ext_data_size, user_data,
  952.         user_data_size)
  953.     BitBucket *bbPtr;
  954.     uint32 temp_ref;
  955.     uint32 code_type;
  956.     uint32 vbv_delay;
  957.     int32 full_pel_forw_flag;
  958.     uint32 forw_f_code;
  959.     int32 full_pel_back_flag;
  960.     uint32 back_f_code;
  961.     uint8 *extra_info;
  962.     uint32 extra_info_size;
  963.     uint8 *ext_data;
  964.     uint32 ext_data_size;
  965.     uint8 *user_data;
  966.     uint32 user_data_size;
  967. {
  968.     int i;
  969.  
  970.     /* Write picture start code. */
  971.     Bitio_Write(bbPtr, PICT_START_CODE, 32);
  972.  
  973.     /* Temp reference. */
  974.     Bitio_Write(bbPtr, temp_ref, 10);
  975.  
  976.     /* Code_type. */
  977.     if (code_type == 0) {
  978.     code_type = 1;
  979.     }
  980.     Bitio_Write(bbPtr, code_type, 3);
  981.  
  982.     /* vbv_delay. */
  983.     vbv_delay = 0xffff;            /* see page 36 (section 2.4.3.4) */
  984.     Bitio_Write(bbPtr, vbv_delay, 16);
  985.  
  986.     if ((code_type == 2) || (code_type == 3)) {
  987.  
  988.     /* Full pel forw flag. */
  989.  
  990.     if (full_pel_forw_flag) {
  991.         Bitio_Write(bbPtr, 0x01, 1);
  992.     } else {
  993.         Bitio_Write(bbPtr, 0x00, 1);
  994.     }
  995.  
  996.     /* Forw f code. */
  997.  
  998.     Bitio_Write(bbPtr, forw_f_code, 3);
  999.     }
  1000.     if (code_type == 3) {
  1001.  
  1002.     /* Full pel back flag. */
  1003.  
  1004.     if (full_pel_back_flag) {
  1005.         Bitio_Write(bbPtr, 0x01, 1);
  1006.     } else {
  1007.         Bitio_Write(bbPtr, 0x00, 1);
  1008.     }
  1009.  
  1010.     /* Back f code. */
  1011.  
  1012.     Bitio_Write(bbPtr, back_f_code, 3);
  1013.     }
  1014.     /* Extra bit picture info. */
  1015.  
  1016.     if (extra_info != NULL) {
  1017.     for (i = 0; i < extra_info_size; i++) {
  1018.         Bitio_Write(bbPtr, 0x01, 1);
  1019.         Bitio_Write(bbPtr, extra_info[i], 8);
  1020.     }
  1021.     }
  1022.     Bitio_Write(bbPtr, 0x00, 1);
  1023.  
  1024.     /* next start code */
  1025.     Bitio_BytePad(bbPtr);
  1026.  
  1027.     /* Write ext data if present. */
  1028.  
  1029.     if (ext_data != NULL) {
  1030.     Bitio_Write(bbPtr, EXT_START_CODE, 32);
  1031.  
  1032.     for (i = 0; i < ext_data_size; i++) {
  1033.         Bitio_Write(bbPtr, ext_data[i], 8);
  1034.     }
  1035.     Bitio_BytePad(bbPtr);
  1036.     }
  1037.     /* Write user data if present. */
  1038.     if (user_data != NULL) {
  1039.     Bitio_Write(bbPtr, USER_START_CODE, 32);
  1040.  
  1041.     for (i = 0; i < user_data_size; i++) {
  1042.         Bitio_Write(bbPtr, user_data[i], 8);
  1043.     }
  1044.     Bitio_BytePad(bbPtr);
  1045.     }
  1046. }
  1047.  
  1048.  
  1049. #ifdef UNUSED_PROCEDURES
  1050.  
  1051. /* GenMBEnd only used for `D` pictures. Shouldn't really ever be called. */
  1052. /* - dwallach */
  1053. void
  1054. GenMBEnd(bbPtr)
  1055.     BitBucket *bbPtr;
  1056. {
  1057.     Bitio_Write(bbPtr, 0x01, 1);
  1058. }
  1059.  
  1060. #endif UNUSED_PROCEDURES
  1061.