Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

mheaders.c

Go to the documentation of this file.
00001 /*===========================================================================*
00002  * mheaders.c                                                                *
00003  *                                                                           *
00004  *      Procedures to generate MPEG headers                                  *
00005  *                                                                           *
00006  * EXPORTED PROCEDURES:                                                      *
00007  *      Mhead_GenPictureHeader                                               *
00008  *      Mhead_GenSequenceHeader                                              *
00009  *      Mhead_GenSequenceEnder                                               *
00010  *      Mhead_GenGOPHeader                                                   *
00011  *      Mhead_GenSliceHeader                                                 *
00012  *      Mhead_GenSliceEnder                                                  *
00013  *      Mhead_GenMBHeader                                                    *
00014  *                                                                           *
00015  *===========================================================================*/
00016 
00017 /*
00018  * Copyright (c) 1995 The Regents of the University of California.
00019  * All rights reserved.
00020  *
00021  * Permission to use, copy, modify, and distribute this software and its
00022  * documentation for any purpose, without fee, and without written agreement is
00023  * hereby granted, provided that the above copyright notice and the following
00024  * two paragraphs appear in all copies of this software.
00025  *
00026  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
00027  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
00028  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
00029  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030  *
00031  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
00032  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
00033  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
00034  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
00035  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
00036  */
00037 
00038 /*
00039  *  $Header: /misc/elrond0/share/cvs/AFNI/src/mpeg_encodedir/mheaders.c,v 1.4 2004/04/02 15:12:40 rwcox Exp $
00040  *  $Log: mheaders.c,v $
00041  *  Revision 1.4  2004/04/02 15:12:40  rwcox
00042  *  Cput
00043  *
00044  *  Revision 1.3  2003/12/23 13:50:08  rwcox
00045  *  Cput
00046  *
00047  *  Revision 1.2  2003/12/03 14:46:14  rwcox
00048  *  Cput
00049  *
00050  *  Revision 1.1  2001/12/17 16:11:54  rwcox
00051  *  Cadd
00052  *
00053  *  Revision 1.15  1995/08/07 21:45:19  smoot
00054  *  check for illegal MVs (shouldnt ever be called, but....)
00055  *  fix bug which made us not weite Iframe Qscale changes
00056  *  warns if writing a size=0 mpeg
00057  *
00058  *  Revision 1.14  1995/05/22 20:53:35  smoot
00059  *  corrected bit_rate value in constrained params flag
00060  *
00061  * Revision 1.13  1995/05/02  01:50:38  eyhung
00062  * made VidRateNum un-static
00063  *
00064  * Revision 1.12  1995/03/27  19:28:23  smoot
00065  * auto-determines Qscale changes (was mb_quant)
00066  *
00067  * Revision 1.11  1995/02/16  09:12:39  eyhung
00068  * fixed compile bug with HP7xx
00069  *
00070  * Revision 1.10  1995/01/25  22:53:50  smoot
00071  * Better buf_size checking, and actually check constrained params
00072  *
00073  * Revision 1.9  1995/01/19  23:08:47  eyhung
00074  * Changed copyrights
00075  *
00076  * Revision 1.8  1995/01/16  08:45:10  eyhung
00077  * BLEAH'ed hsize and vsize
00078  *
00079  * Revision 1.7  1994/12/09  22:27:17  smoot
00080  * Fixed buffer size in stream
00081  *
00082  * Revision 1.6  1994/11/12  02:11:54  keving
00083  * nothing
00084  *
00085  * Revision 1.5  1994/03/15  00:27:11  keving
00086  * nothing
00087  *
00088  * Revision 1.4  1993/12/22  19:19:01  keving
00089  * nothing
00090  *
00091  * Revision 1.3  1993/07/22  22:23:43  keving
00092  * nothing
00093  *
00094  * Revision 1.2  1993/06/30  20:06:09  keving
00095  * nothing
00096  *
00097  * Revision 1.1  1993/06/03  21:08:08  keving
00098  * nothing
00099  *
00100  * Revision 1.6  1993/03/01  23:03:40  keving
00101  * nothing
00102  *
00103  * Revision 1.5  1993/02/17  23:18:20  dwallach
00104  * checkin prior to keving's joining the project
00105  *
00106  * Revision 1.4  1993/01/18  10:20:02  dwallach
00107  * *** empty log message ***
00108  *
00109  * Revision 1.3  1993/01/18  10:17:29  dwallach
00110  * RCS headers installed, code indented uniformly
00111  *
00112  * Revision 1.3  1993/01/18  10:17:29  dwallach
00113  * RCS headers installed, code indented uniformly
00114  *
00115  */
00116 
00117 
00118 /*==============*
00119  * HEADER FILES *
00120  *==============*/
00121 
00122 #include "all.h"
00123 #include "bitio.h"
00124 #include "frames.h"
00125 #include "mheaders.h"
00126 
00127 
00128 /*==================*
00129  * STATIC VARIABLES *
00130  *==================*/
00131 
00132 static int gopStartFrame = 0;
00133 static int lastGOPStart = 0;
00134 static int lastQSSet;
00135 
00136 static uint32 mbAddrIncrTable[][2] = {
00137     {0x0, 0},
00138     {0x1, 1},
00139     {0x3, 3},
00140     {0x2, 3},
00141     {0x3, 4},
00142     {0x2, 4},
00143     {0x3, 5},
00144     {0x2, 5},
00145     {0x7, 7},
00146     {0x6, 7},
00147     {0xb, 8},
00148     {0xa, 8},
00149     {0x9, 8},
00150     {0x8, 8},
00151     {0x7, 8},
00152     {0x6, 8},
00153     {0x17, 10},
00154     {0x16, 10},
00155     {0x15, 10},
00156     {0x14, 10},
00157     {0x13, 10},
00158     {0x12, 10},
00159     {0x23, 11},
00160     {0x22, 11},
00161     {0x21, 11},
00162     {0x20, 11},
00163     {0x1f, 11},
00164     {0x1e, 11},
00165     {0x1d, 11},
00166     {0x1c, 11},
00167     {0x1b, 11},
00168     {0x1a, 11},
00169     {0x19, 11},
00170     {0x18, 11}};
00171 
00172 static uint32 mbMotionVectorTable[][2] = {
00173     {0x19, 11},
00174     {0x1b, 11},
00175     {0x1d, 11},
00176     {0x1f, 11},
00177     {0x21, 11},
00178     {0x23, 11},
00179     {0x13, 10},
00180     {0x15, 10},
00181     {0x17, 10},
00182     {0x7, 8},
00183     {0x9, 8},
00184     {0xb, 8},
00185     {0x7, 7},
00186     {0x3, 5},
00187     {0x3, 4},
00188     {0x3, 3},
00189     {0x1, 1},
00190     {0x2, 3},
00191     {0x2, 4},
00192     {0x2, 5},
00193     {0x6, 7},
00194     {0xa, 8},
00195     {0x8, 8},
00196     {0x6, 8},
00197     {0x16, 10},
00198     {0x14, 10},
00199     {0x12, 10},
00200     {0x22, 11},
00201     {0x20, 11},
00202     {0x1e, 11},
00203     {0x1c, 11},
00204     {0x1a, 11},
00205     {0x18, 11}};
00206 
00207 static uint32 mbPatTable[][2] = {
00208     {0x0, 0},
00209     {0xb, 5},
00210     {0x9, 5},
00211     {0xd, 6},
00212     {0xd, 4},
00213     {0x17, 7},
00214     {0x13, 7},
00215     {0x1f, 8},
00216     {0xc, 4},
00217     {0x16, 7},
00218     {0x12, 7},
00219     {0x1e, 8},
00220     {0x13, 5},
00221     {0x1b, 8},
00222     {0x17, 8},
00223     {0x13, 8},
00224     {0xb, 4},
00225     {0x15, 7},
00226     {0x11, 7},
00227     {0x1d, 8},
00228     {0x11, 5},
00229     {0x19, 8},
00230     {0x15, 8},
00231     {0x11, 8},
00232     {0xf, 6},
00233     {0xf, 8},
00234     {0xd, 8},
00235     {0x3, 9},
00236     {0xf, 5},
00237     {0xb, 8},
00238     {0x7, 8},
00239     {0x7, 9},
00240     {0xa, 4},
00241     {0x14, 7},
00242     {0x10, 7},
00243     {0x1c, 8},
00244     {0xe, 6},
00245     {0xe, 8},
00246     {0xc, 8},
00247     {0x2, 9},
00248     {0x10, 5},
00249     {0x18, 8},
00250     {0x14, 8},
00251     {0x10, 8},
00252     {0xe, 5},
00253     {0xa, 8},
00254     {0x6, 8},
00255     {0x6, 9},
00256     {0x12, 5},
00257     {0x1a, 8},
00258     {0x16, 8},
00259     {0x12, 8},
00260     {0xd, 5},
00261     {0x9, 8},
00262     {0x5, 8},
00263     {0x5, 9},
00264     {0xc, 5},
00265     {0x8, 8},
00266     {0x4, 8},
00267     {0x4, 9},
00268     {0x7, 3},
00269     {0xa, 5},   /* grrr... 61, 62, 63 added - Kevin */
00270     {0x8, 5},
00271     {0xc, 6}
00272 };
00273 
00274 /*===========*
00275  * CONSTANTS *
00276  *===========*/
00277 
00278 #define SEQ_HEAD_CODE 0x000001b3
00279 #define EXT_START_CODE 0x000001b5
00280 #define USER_START_CODE 0x000001b2
00281 #define GOP_START_CODE 0x000001b8
00282 #define PICT_START_CODE 0x00000100
00283 #define SLICE_BASE_CODE 0x00000100
00284 
00285 #define SEQ_END_CODE    0x000001b7
00286 
00287 /* not static anymore because information is used for computing frame rate 
00288  * and for statistics */
00289 const double VidRateNum[9]={1.0, 23.976, 24.0, 25.0, 29.97, 30.0,
00290                              50.0 ,59.94, 60.0};
00291 
00292 
00293 /*===============================*
00294  * INTERNAL PROCEDURE prototypes *
00295  *===============================*/
00296 
00297 static void     GenMBAddrIncr _ANSI_ARGS_((BitBucket *bb, uint32 addr_incr));
00298 static void     GenPictHead _ANSI_ARGS_((BitBucket *bb, uint32 temp_ref,
00299                     uint32 code_type, uint32 vbv_delay,
00300                     int32 full_pel_forw_flag, uint32 forw_f_code,
00301                     int32 full_pel_back_flag, uint32 back_f_code,
00302                     uint8 *extra_info, uint32 extra_info_size,
00303                     uint8 *ext_data, uint32 ext_data_size,
00304                     uint8 *user_data, uint32 user_data_size));
00305 static void     GenMBType _ANSI_ARGS_((BitBucket *bb, uint32 pict_code_type,
00306                   uint32 mb_quant, uint32 motion_forw, uint32 motion_back,
00307                   uint32 mb_pattern, uint32 mb_intra));
00308 static void     GenMotionCode _ANSI_ARGS_((BitBucket *bb, int32 vector));
00309 static void     GenBlockPattern _ANSI_ARGS_((BitBucket *bb,
00310                                              uint32 mb_pattern));
00311 
00312 
00313 /*=====================*
00314  * EXPORTED PROCEDURES *
00315  *=====================*/
00316 
00317 
00318 /*===========================================================================*
00319  *
00320  * SetGOPStartTime
00321  *
00322  *      sets the start frame of the GOP; to be used with GenPictureHeader
00323  *
00324  * RETURNS:     nothing
00325  *
00326  * SIDE EFFECTS:    none
00327  *
00328  *===========================================================================*/
00329 void
00330 SetGOPStartTime(index)
00331     int index;
00332 {
00333     lastGOPStart = gopStartFrame;
00334     gopStartFrame = index;
00335 }
00336 
00337 
00338 /*===========================================================================*
00339  *
00340  * Mhead_GenPictureHeader
00341  *
00342  *      generate picture header with given frame type and picture count
00343  *      append result to the specified bitstream
00344  *
00345  * RETURNS:     nothing
00346  *
00347  * SIDE EFFECTS:    none
00348  *
00349  *===========================================================================*/
00350 void
00351 Mhead_GenPictureHeader(bbPtr, frameType, pictCount, f_code)
00352     BitBucket *bbPtr;
00353     int frameType;
00354     int pictCount;
00355     int f_code;
00356 {
00357     int     temporalRef;
00358 
00359     if ( pictCount >= gopStartFrame ) {
00360         temporalRef = (pictCount-gopStartFrame);
00361     } else {
00362         temporalRef = (pictCount-lastGOPStart);
00363     }
00364     temporalRef = (temporalRef % 1024);
00365         
00366     DBG_PRINT(("Picture Header\n"));
00367     GenPictHead(bbPtr, temporalRef, frameType,
00368                 0 /* vbv_delay */,
00369                 pixelFullSearch /* full_pel_forw_flag */,
00370                 f_code /* forw_f_code */,
00371                 pixelFullSearch /* full_pel_back_flag */,
00372                 f_code /* back_f_code */,
00373                 NULL, 0, NULL, 0, NULL, 0);
00374 }
00375 
00376 
00377 /*===========================================================================*
00378  *
00379  * Mhead_GenSequenceHeader
00380  *
00381  *      generate sequence header with given attributes
00382  *      append result to the specified bitstream
00383  *
00384  * RETURNS:     nothing
00385  *
00386  * SIDE EFFECTS:    none
00387  *
00388  *===========================================================================*/
00389 void
00390 Mhead_GenSequenceHeader(bbPtr, hsize, vsize, pratio, pict_rate, bit_rate,
00391                         buf_size, c_param_flag, iq_matrix, niq_matrix,
00392                         ext_data, ext_data_size, user_data, user_data_size)
00393     BitBucket *bbPtr;
00394     uint32 hsize;
00395     uint32 vsize;
00396     int32 pratio;
00397     int32 pict_rate;
00398     int32 bit_rate;
00399     int32 buf_size;
00400     int32 c_param_flag;
00401     int32 *iq_matrix;
00402     int32 *niq_matrix;
00403     uint8 *ext_data;
00404     int32 ext_data_size;
00405     uint8 *user_data;
00406     int32 user_data_size;
00407 {
00408     extern int ZAG[];
00409     int i;
00410 
00411     /* Write seq start code. */
00412 
00413     Bitio_Write(bbPtr, SEQ_HEAD_CODE, 32);
00414 
00415     /* Write horiz. and vert. sizes. */
00416 
00417 #ifdef BLEAH
00418 fprintf(stdout, "hsize, vsize = %d, %d\n", hsize, vsize);
00419 #endif
00420 
00421     if (hsize==0 || vsize==0) {
00422       fprintf(stderr, "Writing zero size to stream!\n");
00423     }
00424     Bitio_Write(bbPtr, hsize, 12);
00425     Bitio_Write(bbPtr, vsize, 12);
00426 
00427     /* Write pixel aspect ratio, negative values default to 1. */
00428 
00429     if (pratio < 0) {
00430         fprintf(stderr, "PROGRAMMER ERROR:  pratio = %d\n", pratio);
00431         exit(1);
00432     }
00433     Bitio_Write(bbPtr, pratio, 4);
00434 
00435     /* Wrtie picture rate, negative values default to 30 fps. */
00436 
00437     if (pict_rate < 0) {
00438         fprintf(stderr, "PROGRAMMER ERROR:  pict_rate = %d\n", pict_rate);
00439         exit(1);
00440     }
00441     Bitio_Write(bbPtr, pict_rate, 4);
00442 
00443     /* Write bit rate, negative values default to variable. */
00444 
00445     if (bit_rate < 0) {
00446         bit_rate = -1;
00447     } else {
00448         bit_rate = bit_rate / 400;
00449     }
00450 
00451     Bitio_Write(bbPtr, bit_rate, 18);
00452 
00453     /* Marker bit. */
00454     Bitio_Write(bbPtr, 0x1, 1);
00455 
00456     /* Write VBV buffer size. Negative values default to zero. */
00457     if (buf_size < 0) {
00458         buf_size = 0;
00459     }
00460 
00461     buf_size = (buf_size + (16*1024 - 1)) / (16*1024);
00462     if (buf_size>=0x400) buf_size=0x3ff;
00463     Bitio_Write(bbPtr, buf_size, 10);
00464 
00465     /* Write constrained parameter flag. */
00466     {
00467       int num_mb = ((hsize+15)/16) * ((vsize+15)/16);
00468       /* At present we cheat on buffer size */
00469       c_param_flag = ((bit_rate <= 4640) &&
00470                     (bit_rate >0) &&
00471                     (buf_size <= 20) &&
00472                     (pict_rate >= 1) &&
00473                     (pict_rate <= 5) &&
00474                     (hsize <= 768) &&
00475                     (vsize <= 576) &&
00476                     (num_mb <= 396) &&
00477                     (num_mb*VidRateNum[pict_rate] <= 9900) &&
00478                     (fCodeP<=4) &&
00479                     (fCodeB<=4));
00480     }
00481 
00482     if (c_param_flag) {
00483         Bitio_Write(bbPtr, 0x01, 1);
00484     } else {
00485         Bitio_Write(bbPtr, 0x00, 1);
00486     }
00487 
00488     /* Write intra quant matrix if present. */
00489 
00490     if (iq_matrix != NULL) {
00491         Bitio_Write(bbPtr, 0x01, 1);
00492         for (i = 0; i < 64; i++) {
00493             Bitio_Write(bbPtr, iq_matrix[ZAG[i]], 8);
00494         }
00495     } else {
00496         Bitio_Write(bbPtr, 0x00, 1);
00497     }
00498 
00499     /* Write non intra quant matrix if present. */
00500 
00501     if (niq_matrix != NULL) {
00502         Bitio_Write(bbPtr, 0x01, 1);
00503         for (i = 0; i < 64; i++) {
00504             Bitio_Write(bbPtr, niq_matrix[ZAG[i]], 8);
00505         }
00506     } else {
00507         Bitio_Write(bbPtr, 0x00, 1);
00508     }
00509 
00510     /* next start code */
00511     Bitio_BytePad(bbPtr);
00512 
00513 
00514     /* Write ext data if present. */
00515 
00516     if (ext_data != NULL) {
00517         Bitio_Write(bbPtr, EXT_START_CODE, 32);
00518 
00519         for (i = 0; i < ext_data_size; i++) {
00520             Bitio_Write(bbPtr, ext_data[i], 8);
00521         }
00522         Bitio_BytePad(bbPtr);
00523     }
00524     /* Write user data if present. */
00525     if ((user_data != NULL) && (user_data_size != 0)) {
00526         Bitio_Write(bbPtr, USER_START_CODE, 32);
00527 
00528         for (i = 0; i < user_data_size; i++) {
00529             Bitio_Write(bbPtr, user_data[i], 8);
00530         }
00531         Bitio_BytePad(bbPtr);
00532     }
00533 }
00534 
00535 
00536 /*===========================================================================*
00537  *
00538  * Mhead_GenSequenceEnder
00539  *
00540  *      generate sequence ender
00541  *      append result to the specified bitstream
00542  *
00543  * RETURNS:     nothing
00544  *
00545  * SIDE EFFECTS:    none
00546  *
00547  *===========================================================================*/
00548 void
00549 Mhead_GenSequenceEnder(bbPtr)
00550     BitBucket *bbPtr;
00551 {
00552     Bitio_Write(bbPtr, SEQ_END_CODE, 32);
00553 }
00554 
00555 
00556 /*===========================================================================*
00557  *
00558  * Mhead_GenGOPHeader
00559  *
00560  *      generate GOP header with specified attributes
00561  *      append result to the specified bitstream
00562  *
00563  * RETURNS:     nothing
00564  *
00565  * SIDE EFFECTS:    none
00566  *
00567  *===========================================================================*/
00568 void
00569 Mhead_GenGOPHeader(bbPtr, drop_frame_flag, tc_hrs, tc_min, tc_sec, tc_pict,
00570                    closed_gop, broken_link, ext_data, ext_data_size,
00571                    user_data, user_data_size)
00572     BitBucket *bbPtr;
00573     int32 drop_frame_flag;
00574     int32 tc_hrs;
00575     int32 tc_min;
00576     int32 tc_sec;
00577     int32 tc_pict;
00578     int32 closed_gop;
00579     int32 broken_link;
00580     uint8 *ext_data;
00581     int32 ext_data_size;
00582     uint8 *user_data;
00583     int32 user_data_size;
00584 {
00585     int i;
00586 
00587     /* Write gop start code. */
00588     Bitio_Write(bbPtr, GOP_START_CODE, 32);
00589 
00590                 /* Construct and write timecode. */
00591 
00592     /* Drop frame flag. */
00593     if (drop_frame_flag) {
00594         Bitio_Write(bbPtr, 0x01, 1);
00595     } else {
00596         Bitio_Write(bbPtr, 0x00, 1);
00597     }
00598 
00599     /* Time code hours. */
00600     Bitio_Write(bbPtr, tc_hrs, 5);
00601 
00602     /* Time code minutes. */
00603     Bitio_Write(bbPtr, tc_min, 6);
00604 
00605     /* Marker bit. */
00606     Bitio_Write(bbPtr, 0x01, 1);
00607 
00608     /* Time code seconds. */
00609     Bitio_Write(bbPtr, tc_sec, 6);
00610 
00611     /* Time code pictures. */
00612     Bitio_Write(bbPtr, tc_pict, 6);
00613 
00614 
00615     /* Closed gop flag. */
00616     if (closed_gop) {
00617         Bitio_Write(bbPtr, 0x01, 1);
00618     } else {
00619         Bitio_Write(bbPtr, 0x00, 1);
00620     }
00621 
00622     /* Broken link flag. */
00623     if (broken_link) {
00624         Bitio_Write(bbPtr, 0x01, 1);
00625     } else {
00626         Bitio_Write(bbPtr, 0x00, 1);
00627     }
00628 
00629     /* next start code */
00630     Bitio_BytePad(bbPtr);
00631 
00632     /* Write ext data if present. */
00633 
00634     if (ext_data != NULL) {
00635         Bitio_Write(bbPtr, EXT_START_CODE, 32);
00636 
00637         for (i = 0; i < ext_data_size; i++) {
00638             Bitio_Write(bbPtr, ext_data[i], 8);
00639         }
00640         Bitio_BytePad(bbPtr);
00641     }
00642     /* Write user data if present. */
00643     if (user_data != NULL) {
00644         Bitio_Write(bbPtr, USER_START_CODE, 32);
00645 
00646         for (i = 0; i < user_data_size; i++) {
00647             Bitio_Write(bbPtr, user_data[i], 8);
00648         }
00649         Bitio_BytePad(bbPtr);
00650     }
00651 }
00652 
00653 
00654 /*===========================================================================*
00655  *
00656  * Mhead_GenSliceHeader
00657  *
00658  *      generate slice header with specified attributes
00659  *      append result to the specified bitstream
00660  *
00661  * RETURNS:     nothing
00662  *
00663  * SIDE EFFECTS:    none
00664  *
00665  *===========================================================================*/
00666 void
00667 Mhead_GenSliceHeader(bbPtr, verticalPos, qscale, extra_info, extra_info_size)
00668     BitBucket *bbPtr;
00669     uint32 verticalPos;
00670     uint32 qscale;
00671     uint8 *extra_info;
00672     uint32 extra_info_size;
00673 {
00674     int i;
00675 
00676     /* Write slice start code. */
00677     Bitio_Write(bbPtr, (SLICE_BASE_CODE + verticalPos), 32);
00678 
00679     /* Quant. scale. */
00680     Bitio_Write(bbPtr, qscale, 5);
00681     lastQSSet = qscale;
00682 
00683     /* Extra bit slice info. */
00684 
00685     if (extra_info != NULL) {
00686         for (i = 0; i < extra_info_size; i++) {
00687             Bitio_Write(bbPtr, 0x01, 1);
00688             Bitio_Write(bbPtr, extra_info[i], 8);
00689         }
00690     }
00691 
00692     /* extra_bit_slice */
00693     Bitio_Write(bbPtr, 0x00, 1);
00694 }
00695 
00696 
00697 /*===========================================================================*
00698  *
00699  * Mhead_GenSliceEnder
00700  *
00701  *      generate slice ender
00702  *      append result to the specified bitstream
00703  *
00704  * RETURNS:     nothing
00705  *
00706  * SIDE EFFECTS:    none
00707  *
00708  *===========================================================================*/
00709 void
00710 Mhead_GenSliceEnder(bbPtr)
00711     BitBucket *bbPtr;
00712 {
00713     Bitio_BytePad(bbPtr);
00714 }
00715 
00716 
00717 /*===========================================================================*
00718  *
00719  * Mhead_GenMBHeader
00720  *
00721  *      generate macroblock header with given attributes
00722  *      append result to the specified bitstream
00723  *
00724  * RETURNS:     nothing
00725  *
00726  * SIDE EFFECTS:    none
00727  *
00728  *===========================================================================*/
00729 void
00730 Mhead_GenMBHeader(bbPtr, pict_code_type, addr_incr, q_scale,
00731                   forw_f_code, back_f_code, horiz_forw_r, vert_forw_r,
00732                   horiz_back_r, vert_back_r, motion_forw, m_horiz_forw,
00733                   m_vert_forw, motion_back, m_horiz_back, m_vert_back,
00734                   mb_pattern, mb_intra)
00735     BitBucket *bbPtr;
00736     uint32 pict_code_type;
00737     uint32 addr_incr;
00738     uint32 q_scale;
00739     uint32 forw_f_code;
00740     uint32 back_f_code;
00741     uint32 horiz_forw_r;
00742     uint32 vert_forw_r;
00743     uint32 horiz_back_r;
00744     uint32 vert_back_r;
00745     int32 motion_forw;
00746     int32 m_horiz_forw;
00747     int32 m_vert_forw;
00748     int32 motion_back;
00749     int32 m_horiz_back;
00750     int32 m_vert_back;
00751     uint32 mb_pattern;
00752     uint32 mb_intra;
00753 {
00754     uint32 mb_quant;
00755 
00756     /* MB escape sequences if necessary. */
00757 
00758 #ifdef BLEAH
00759 if ( addr_incr != 1 )
00760     fprintf(stdout, "Creating MB_INCR:  %d\n", addr_incr);
00761 #endif
00762 
00763     while (addr_incr > 33) {
00764         Bitio_Write(bbPtr, 0x008, 11);
00765         addr_incr -= 33;
00766     }
00767 
00768     /* Generate addr incr code. */
00769     GenMBAddrIncr(bbPtr, addr_incr);
00770 
00771     /* Determine mb_quant  (true if change in q scale) */
00772     if ((q_scale != lastQSSet) && ((mb_pattern != 0) || (mb_intra == TRUE))) {
00773       mb_quant = TRUE;
00774       lastQSSet = q_scale;
00775     } else {
00776       mb_quant = FALSE;
00777     }
00778 
00779     /* Generate mb type code. */
00780     GenMBType(bbPtr, pict_code_type, mb_quant, motion_forw, motion_back, mb_pattern, mb_intra);
00781 
00782     /* MB quant. */
00783     if (mb_quant) {
00784         Bitio_Write(bbPtr, q_scale, 5);
00785     }
00786     /* Forward predictive vector stuff. */
00787 
00788     if (motion_forw) {
00789         int forw_f, forw_r_size;
00790 
00791         forw_r_size = forw_f_code - 1;
00792         forw_f = 1 << forw_r_size;      /* 1 > 0 */
00793         if ((m_horiz_forw > 16*forw_f-1) || (m_horiz_forw < -16*forw_f)) {
00794           fprintf(stderr, "Illegal motion? %d %d\n", m_horiz_forw, 16*forw_f);
00795         }
00796         if ((m_vert_forw > 16*forw_f-1) || (m_vert_forw < -16*forw_f)) {
00797           fprintf(stderr, "Illegal motion? %d %d\n", m_vert_forw, 16*forw_f);
00798         }
00799         GenMotionCode(bbPtr, m_horiz_forw);
00800 
00801         if ((forw_f != 1) && (m_horiz_forw != 0)) {
00802             Bitio_Write(bbPtr, horiz_forw_r, forw_r_size);
00803         }
00804         GenMotionCode(bbPtr, m_vert_forw);
00805 
00806         if ((forw_f != 1) && (m_vert_forw != 0)) {
00807             Bitio_Write(bbPtr, vert_forw_r, forw_r_size);
00808         }
00809     }
00810     /* Back predicted vector stuff. */
00811 
00812     if (motion_back) {
00813         int back_f, back_r_size;
00814 
00815         back_r_size = back_f_code - 1;
00816         back_f = 1 << back_r_size;      /* 1 > 0 */
00817 
00818         if ((m_horiz_back > 16*back_f-1) || (m_horiz_back < -16*back_f)) {
00819           fprintf(stderr, "Illegal motion? %d %d\n", m_horiz_back, 16*back_f);
00820         }
00821         if ((m_vert_back > 16*back_f-1) || (m_vert_back < -16*back_f)) {
00822           fprintf(stderr, "Illegal motion? %d %d\n", m_vert_back, 16*back_f);
00823         }
00824 
00825         GenMotionCode(bbPtr, m_horiz_back);
00826 
00827         if ((back_f != 1) && (m_horiz_back != 0)) {
00828             Bitio_Write(bbPtr, horiz_back_r, back_r_size);
00829         }
00830         GenMotionCode(bbPtr, m_vert_back);
00831 
00832         if ((back_f != 1) && (m_vert_back != 0)) {
00833             Bitio_Write(bbPtr, vert_back_r, back_r_size);
00834         }
00835     }
00836     /* MB pattern. */
00837 
00838     if (mb_pattern) {
00839         GenBlockPattern(bbPtr, mb_pattern);
00840     }
00841 }
00842 
00843 
00844 /*=====================*
00845  * INTERNAL PROCEDURES *
00846  *=====================*/
00847 
00848 /*===========================================================================*
00849  *
00850  * GenMBType
00851  *
00852  *      generate macroblock type with given attributes
00853  *      append result to the specified bitstream
00854  *
00855  * RETURNS:     nothing
00856  *
00857  * SIDE EFFECTS:    none
00858  *
00859  *===========================================================================*/
00860 static void
00861 GenMBType(bbPtr, pict_code_type, mb_quant, motion_forw, motion_back,
00862           mb_pattern, mb_intra)
00863     BitBucket *bbPtr;
00864     uint32 pict_code_type;
00865     uint32 mb_quant;
00866     uint32 motion_forw;
00867     uint32 motion_back;
00868     uint32 mb_pattern;
00869     uint32 mb_intra;
00870 {
00871     int code;
00872 
00873     switch (pict_code_type) {
00874     case 1:
00875         if ((motion_forw != 0) || (motion_back != 0) || (mb_pattern != 0) || (mb_intra != 1)) {
00876             perror("Illegal parameters for macroblock type.");
00877             exit(-1);
00878         }
00879         if (mb_quant) {
00880             Bitio_Write(bbPtr, 0x1, 2);
00881         } else {
00882             Bitio_Write(bbPtr, 0x1, 1);
00883         }
00884         break;
00885 
00886     case 2:
00887         code = 0;
00888         if (mb_quant) {
00889             code += 16;
00890         }
00891         if (motion_forw) {
00892             code += 8;
00893         }
00894         if (motion_back) {
00895             code += 4;
00896         }
00897         if (mb_pattern) {
00898             code += 2;
00899         }
00900         if (mb_intra) {
00901             code += 1;
00902         }
00903 
00904         switch (code) {
00905         case 1:
00906             Bitio_Write(bbPtr, 0x3, 5);
00907             break;
00908         case 2:
00909             Bitio_Write(bbPtr, 0x1, 2);
00910             break;
00911         case 8:
00912             Bitio_Write(bbPtr, 0x1, 3);
00913             break;
00914         case 10:
00915             Bitio_Write(bbPtr, 0x1, 1);
00916             break;
00917         case 17:
00918             Bitio_Write(bbPtr, 0x1, 6);
00919             break;
00920         case 18:
00921             Bitio_Write(bbPtr, 0x1, 5);
00922             break;
00923         case 26:
00924             Bitio_Write(bbPtr, 0x2, 5);
00925             break;
00926         default:
00927             perror("Illegal parameters for macroblock type.");
00928             exit(-1);
00929             break;
00930         }
00931         break;
00932 
00933     case 3:
00934         code = 0;
00935         if (mb_quant) {
00936             code += 16;
00937         }
00938         if (motion_forw) {
00939             code += 8;
00940         }
00941         if (motion_back) {
00942             code += 4;
00943         }
00944         if (mb_pattern) {
00945             code += 2;
00946         }
00947         if (mb_intra) {
00948             code += 1;
00949         }
00950 
00951         switch (code) {
00952         case 12:
00953             Bitio_Write(bbPtr, 0x2, 2);
00954             break;
00955         case 14:
00956             Bitio_Write(bbPtr, 0x3, 2);
00957             break;
00958         case 4:
00959             Bitio_Write(bbPtr, 0x2, 3);
00960             break;
00961         case 6:
00962             Bitio_Write(bbPtr, 0x3, 3);
00963             break;
00964         case 8:
00965             Bitio_Write(bbPtr, 0x2, 4);
00966             break;
00967         case 10:
00968             Bitio_Write(bbPtr, 0x3, 4);
00969             break;
00970         case 1:
00971             Bitio_Write(bbPtr, 0x3, 5);
00972             break;
00973         case 30:
00974             Bitio_Write(bbPtr, 0x2, 5);
00975             break;
00976         case 26:
00977             Bitio_Write(bbPtr, 0x3, 6);
00978             break;
00979         case 22:
00980             Bitio_Write(bbPtr, 0x2, 6);
00981             break;
00982         case 17:
00983             Bitio_Write(bbPtr, 0x1, 6);
00984             break;
00985         default:
00986             perror("Illegal parameters for macroblock type.");
00987             exit(-1);
00988             break;
00989         }
00990         break;
00991     }
00992 }
00993 
00994 
00995 /*===========================================================================*
00996  *
00997  * GenMotionCode
00998  *
00999  *      generate motion vector output with given value
01000  *      append result to the specified bitstream
01001  *
01002  * RETURNS:     nothing
01003  *
01004  * SIDE EFFECTS:    none
01005  *
01006  *===========================================================================*/
01007 static void
01008 GenMotionCode(bbPtr, vector)
01009     BitBucket *bbPtr;
01010     int32 vector;
01011 {
01012     uint32 code, num;
01013 
01014     if ((vector < -16) || (vector > 16)) {
01015         perror("Motion vector out of range.");
01016         fprintf(stderr, "Motion vector out of range:  vector = %d\n", vector);
01017         exit(-1);
01018     }
01019     code = mbMotionVectorTable[vector + 16][0];
01020     num = mbMotionVectorTable[vector + 16][1];
01021 
01022     Bitio_Write(bbPtr, code, num);
01023 }
01024 
01025 
01026 /*===========================================================================*
01027  *
01028  * GenBlockPattern
01029  *
01030  *      generate macroblock pattern output
01031  *      append result to the specified bitstream
01032  *
01033  * RETURNS:     nothing
01034  *
01035  * SIDE EFFECTS:    none
01036  *
01037  *===========================================================================*/
01038 static void
01039 GenBlockPattern(bbPtr, mb_pattern)
01040     BitBucket *bbPtr;
01041     uint32 mb_pattern;
01042 {
01043     uint32 code, num;
01044 
01045     code = mbPatTable[mb_pattern][0];
01046     num = mbPatTable[mb_pattern][1];
01047 
01048     Bitio_Write(bbPtr, code, num);
01049 }
01050 
01051 
01052 /*===========================================================================*
01053  *
01054  * GenMBAddrIncr
01055  *
01056  *      generate macroblock address increment output
01057  *      append result to the specified bitstream
01058  *
01059  * RETURNS:     nothing
01060  *
01061  * SIDE EFFECTS:    none
01062  *
01063  *===========================================================================*/
01064 static void
01065 GenMBAddrIncr(bbPtr, addr_incr)
01066     BitBucket *bbPtr;
01067     uint32 addr_incr;
01068 {
01069     uint32 code;
01070     uint32 num;
01071 
01072     code = mbAddrIncrTable[addr_incr][0];
01073     num = mbAddrIncrTable[addr_incr][1];
01074 
01075     Bitio_Write(bbPtr, code, num);
01076 }
01077 
01078 
01079 /*===========================================================================*
01080  *
01081  * GenPictHead
01082  *
01083  *      generate picture header with given attributes
01084  *      append result to the specified bitstream
01085  *
01086  * RETURNS:     nothing
01087  *
01088  * SIDE EFFECTS:    none
01089  *
01090  *===========================================================================*/
01091 static void
01092 GenPictHead(bbPtr, temp_ref, code_type, vbv_delay, full_pel_forw_flag,
01093             forw_f_code, full_pel_back_flag, back_f_code, extra_info,
01094             extra_info_size, ext_data, ext_data_size, user_data,
01095             user_data_size)
01096     BitBucket *bbPtr;
01097     uint32 temp_ref;
01098     uint32 code_type;
01099     uint32 vbv_delay;
01100     int32 full_pel_forw_flag;
01101     uint32 forw_f_code;
01102     int32 full_pel_back_flag;
01103     uint32 back_f_code;
01104     uint8 *extra_info;
01105     uint32 extra_info_size;
01106     uint8 *ext_data;
01107     uint32 ext_data_size;
01108     uint8 *user_data;
01109     uint32 user_data_size;
01110 {
01111     int i;
01112 
01113     /* Write picture start code. */
01114     Bitio_Write(bbPtr, PICT_START_CODE, 32);
01115 
01116     /* Temp reference. */
01117     Bitio_Write(bbPtr, temp_ref, 10);
01118 
01119     /* Code_type. */
01120     if (code_type == 0) {
01121         code_type = 1;
01122     }
01123     Bitio_Write(bbPtr, code_type, 3);
01124 
01125     /* vbv_delay. */
01126     vbv_delay = 0xffff;             /* see page 36 (section 2.4.3.4) */
01127     Bitio_Write(bbPtr, vbv_delay, 16);
01128 
01129     if ((code_type == 2) || (code_type == 3)) {
01130 
01131         /* Full pel forw flag. */
01132 
01133         if (full_pel_forw_flag) {
01134             Bitio_Write(bbPtr, 0x01, 1);
01135         } else {
01136             Bitio_Write(bbPtr, 0x00, 1);
01137         }
01138 
01139         /* Forw f code. */
01140 
01141         Bitio_Write(bbPtr, forw_f_code, 3);
01142     }
01143     if (code_type == 3) {
01144 
01145         /* Full pel back flag. */
01146 
01147         if (full_pel_back_flag) {
01148             Bitio_Write(bbPtr, 0x01, 1);
01149         } else {
01150             Bitio_Write(bbPtr, 0x00, 1);
01151         }
01152 
01153         /* Back f code. */
01154 
01155         Bitio_Write(bbPtr, back_f_code, 3);
01156     }
01157     /* Extra bit picture info. */
01158 
01159     if (extra_info != NULL) {
01160         for (i = 0; i < extra_info_size; i++) {
01161             Bitio_Write(bbPtr, 0x01, 1);
01162             Bitio_Write(bbPtr, extra_info[i], 8);
01163         }
01164     }
01165     Bitio_Write(bbPtr, 0x00, 1);
01166 
01167     /* next start code */
01168     Bitio_BytePad(bbPtr);
01169 
01170     /* Write ext data if present. */
01171 
01172     if (ext_data != NULL) {
01173         Bitio_Write(bbPtr, EXT_START_CODE, 32);
01174 
01175         for (i = 0; i < ext_data_size; i++) {
01176             Bitio_Write(bbPtr, ext_data[i], 8);
01177         }
01178         Bitio_BytePad(bbPtr);
01179     }
01180     /* Write user data if present. */
01181     if (user_data != NULL) {
01182         Bitio_Write(bbPtr, USER_START_CODE, 32);
01183 
01184         for (i = 0; i < user_data_size; i++) {
01185             Bitio_Write(bbPtr, user_data[i], 8);
01186         }
01187         Bitio_BytePad(bbPtr);
01188     }
01189 }
01190 
01191 
01192 #ifdef UNUSED_PROCEDURES
01193 
01194 /* GenMBEnd only used for `D` pictures. Shouldn't really ever be called. */
01195 /* - dwallach */
01196 void
01197 GenMBEnd(bbPtr)
01198     BitBucket *bbPtr;
01199 {
01200     Bitio_Write(bbPtr, 0x01, 1);
01201 }
01202 
01203 #endif /* UNUSED_PROCEDURES */
 

Powered by Plone

This site conforms to the following standards: