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