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