1 /* puthdr.c, generation of headers                                          */
2 
3 /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
4 
5 /*
6  * Disclaimer of Warranty
7  *
8  * These software programs are available to the user without any license fee or
9  * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
10  * any and all warranties, whether express, implied, or statuary, including any
11  * implied warranties or merchantability or of fitness for a particular
12  * purpose.  In no event shall the copyright-holder be liable for any
13  * incidental, punitive, or consequential damages of any kind whatsoever
14  * arising from the use of these programs.
15  *
16  * This disclaimer of warranty extends to the user of these programs and user's
17  * customers, employees, agents, transferees, successors, and assigns.
18  *
19  * The MPEG Software Simulation Group does not represent or warrant that the
20  * programs furnished hereunder are free of infringement of any third-party
21  * patents.
22  *
23  * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
24  * are subject to royalty fees to patent holders.  Many of these patents are
25  * general enough such that they are unavoidable regardless of implementation
26  * design.
27  *
28  */
29 
30 #include <stdio.h>
31 #include <math.h>
32 #include "global.h"
33 
34 /* private prototypes */
35 static int frametotc(simpeg_encode_context * context, int frame);
36 
37 /* generate sequence header (6.2.2.1, 6.3.3)
38  *
39  * matrix download not implemented
40  */
41 void
simpeg_encode_putseqhdr(simpeg_encode_context * context)42 simpeg_encode_putseqhdr(simpeg_encode_context * context)
43 {
44   int i;
45 
46   simpeg_encode_alignbits(context);
47   simpeg_encode_putbits(context, SEQ_START_CODE,32); /* sequence_header_code */
48   simpeg_encode_putbits(context, context->horizontal_size,12); /* horizontal_size_value */
49   simpeg_encode_putbits(context, context->vertical_size,12); /* vertical_size_value */
50   simpeg_encode_putbits(context, context->aspectratio,4); /* aspect_ratio_information */
51   simpeg_encode_putbits(context, context->frame_rate_code,4); /* frame_rate_code */
52   simpeg_encode_putbits(context, (int)ceil(context->bit_rate/400.0),18); /* bit_rate_value */
53   simpeg_encode_putbits(context, 1,1); /* marker_bit */
54   simpeg_encode_putbits(context, context->vbv_buffer_size,10); /* vbv_buffer_size_value */
55   simpeg_encode_putbits(context, context->constrparms,1); /* constrained_parameters_flag */
56 
57   simpeg_encode_putbits(context, context->load_iquant,1); /* load_intra_quantizer_matrix */
58   if (context->load_iquant)
59     for (i=0; i<64; i++)  /* matrices are always downloaded in zig-zag order */
60       simpeg_encode_putbits(context, context->intra_q[context->zig_zag_scan[i]],8); /* intra_quantizer_matrix */
61 
62   simpeg_encode_putbits(context, context->load_niquant,1); /* load_non_intra_quantizer_matrix */
63   if (context->load_niquant)
64     for (i=0; i<64; i++)
65       simpeg_encode_putbits(context, context->inter_q[context->zig_zag_scan[i]],8); /* non_intra_quantizer_matrix */
66 }
67 
68 /* generate sequence extension (6.2.2.3, 6.3.5) header (MPEG-2 only) */
69 void
simpeg_encode_putseqext(simpeg_encode_context * context)70 simpeg_encode_putseqext(simpeg_encode_context * context)
71 {
72   simpeg_encode_alignbits(context);
73   simpeg_encode_putbits(context, EXT_START_CODE,32); /* extension_start_code */
74   simpeg_encode_putbits(context, SEQ_ID,4); /* extension_start_code_identifier */
75   simpeg_encode_putbits(context, (context->profile<<4)|context->level,8); /* profile_and_level_indication */
76   simpeg_encode_putbits(context, context->prog_seq,1); /* progressive sequence */
77   simpeg_encode_putbits(context, context->chroma_format,2); /* chroma_format */
78   simpeg_encode_putbits(context, context->horizontal_size>>12,2); /* horizontal_size_extension */
79   simpeg_encode_putbits(context, context->vertical_size>>12,2); /* vertical_size_extension */
80   simpeg_encode_putbits(context, ((int)ceil(context->bit_rate/400.0))>>18,12); /* bit_rate_extension */
81   simpeg_encode_putbits(context, 1,1); /* marker_bit */
82   simpeg_encode_putbits(context, context->vbv_buffer_size>>10,8); /* vbv_buffer_size_extension */
83   simpeg_encode_putbits(context, 0,1); /* low_delay  -- currently not implemented */
84   simpeg_encode_putbits(context, 0,2); /* frame_rate_extension_n */
85   simpeg_encode_putbits(context, 0,5); /* frame_rate_extension_d */
86 }
87 
88 /* generate sequence display extension (6.2.2.4, 6.3.6)
89  *
90  * content not yet user setable
91  */
92 void
simpeg_encode_putseqdispext(simpeg_encode_context * context)93 simpeg_encode_putseqdispext(simpeg_encode_context * context)
94 {
95   simpeg_encode_alignbits(context);
96   simpeg_encode_putbits(context, EXT_START_CODE,32); /* extension_start_code */
97   simpeg_encode_putbits(context, DISP_ID,4); /* extension_start_code_identifier */
98   simpeg_encode_putbits(context, context->video_format,3); /* video_format */
99   simpeg_encode_putbits(context, 1,1); /* colour_description */
100   simpeg_encode_putbits(context, context->color_primaries,8); /* colour_primaries */
101   simpeg_encode_putbits(context, context->transfer_characteristics,8); /* transfer_characteristics */
102   simpeg_encode_putbits(context, context->matrix_coefficients,8); /* matrix_coefficients */
103   simpeg_encode_putbits(context, context->display_horizontal_size,14); /* display_horizontal_size */
104   simpeg_encode_putbits(context, 1,1); /* marker_bit */
105   simpeg_encode_putbits(context, context->display_vertical_size,14); /* display_vertical_size */
106 }
107 
108 /* output a zero terminated string as user data (6.2.2.2.2, 6.3.4.1)
109  *
110  * string must not emulate start codes
111  */
112 void
simpeg_encode_putuserdata(simpeg_encode_context * context,char * userdata)113 simpeg_encode_putuserdata(simpeg_encode_context * context,
114                           char *userdata)
115 {
116   simpeg_encode_alignbits(context);
117   simpeg_encode_putbits(context, USER_START_CODE,32); /* user_data_start_code */
118   while (*userdata)
119     simpeg_encode_putbits(context, *userdata++,8);
120 }
121 
122 /* generate group of pictures header (6.2.2.6, 6.3.9)
123  *
124  * uses tc0 (timecode of first frame) and frame0 (number of first frame)
125  */
126 void
simpeg_encode_putgophdr(simpeg_encode_context * context,int frame,int closed_gop)127 simpeg_encode_putgophdr(simpeg_encode_context * context,
128                         int frame, int closed_gop)
129 {
130   int tc;
131 
132   simpeg_encode_alignbits(context);
133   simpeg_encode_putbits(context, GOP_START_CODE,32); /* group_start_code */
134   tc = frametotc(context, context->tc0+frame);
135   simpeg_encode_putbits(context, tc,25); /* time_code */
136   simpeg_encode_putbits(context, closed_gop,1); /* closed_gop */
137   simpeg_encode_putbits(context, 0,1); /* broken_link */
138 }
139 
140 /* convert frame number to time_code
141  *
142  * drop_frame not implemented
143  */
frametotc(simpeg_encode_context * context,int frame)144 static int frametotc(simpeg_encode_context * context, int frame)
145 {
146   int fps, pict, sec, minute, hour, tc;
147 
148   fps = (int)(context->frame_rate+0.5);
149   pict = frame%fps;
150   frame = (frame-pict)/fps;
151   sec = frame%60;
152   frame = (frame-sec)/60;
153   minute = frame%60;
154   frame = (frame-minute)/60;
155   hour = frame%24;
156   tc = (hour<<19) | (minute<<13) | (1<<12) | (sec<<6) | pict;
157 
158   return tc;
159 }
160 
161 /* generate picture header (6.2.3, 6.3.10) */
162 void
simpeg_encode_putpicthdr(simpeg_encode_context * context)163 simpeg_encode_putpicthdr(simpeg_encode_context * context)
164 {
165   simpeg_encode_alignbits(context);
166   simpeg_encode_putbits(context, PICTURE_START_CODE,32); /* picture_start_code */
167   simpeg_encode_calc_vbv_delay(context);
168   simpeg_encode_putbits(context, context->temp_ref,10); /* temporal_reference */
169   simpeg_encode_putbits(context, context->pict_type,3); /* picture_coding_type */
170   simpeg_encode_putbits(context, context->vbv_delay,16); /* vbv_delay */
171 
172   if (context->pict_type==P_TYPE || context->pict_type==B_TYPE)
173   {
174     simpeg_encode_putbits(context, 0,1); /* full_pel_forward_vector */
175     if (context->mpeg1)
176       simpeg_encode_putbits(context, context->forw_hor_f_code,3);
177     else
178       simpeg_encode_putbits(context, 7,3); /* forward_f_code */
179   }
180 
181   if (context->pict_type==B_TYPE)
182   {
183     simpeg_encode_putbits(context, 0,1); /* full_pel_backward_vector */
184     if (context->mpeg1)
185       simpeg_encode_putbits(context, context->back_hor_f_code,3);
186     else
187       simpeg_encode_putbits(context, 7,3); /* backward_f_code */
188   }
189 
190   simpeg_encode_putbits(context, 0,1); /* extra_bit_picture */
191 }
192 
193 /* generate picture coding extension (6.2.3.1, 6.3.11)
194  *
195  * composite display information (v_axis etc.) not implemented
196  */
197 void
simpeg_encode_putpictcodext(simpeg_encode_context * context)198 simpeg_encode_putpictcodext(simpeg_encode_context * context)
199 {
200   simpeg_encode_alignbits(context);
201   simpeg_encode_putbits(context, EXT_START_CODE,32); /* extension_start_code */
202   simpeg_encode_putbits(context, CODING_ID,4); /* extension_start_code_identifier */
203   simpeg_encode_putbits(context, context->forw_hor_f_code,4); /* forward_horizontal_f_code */
204   simpeg_encode_putbits(context, context->forw_vert_f_code,4); /* forward_vertical_f_code */
205   simpeg_encode_putbits(context, context->back_hor_f_code,4); /* backward_horizontal_f_code */
206   simpeg_encode_putbits(context, context->back_vert_f_code,4); /* backward_vertical_f_code */
207   simpeg_encode_putbits(context, context->dc_prec,2); /* intra_dc_precision */
208   simpeg_encode_putbits(context, context->pict_struct,2); /* picture_structure */
209   simpeg_encode_putbits(context, (context->pict_struct==FRAME_PICTURE)?context->topfirst:0,1); /* top_field_first */
210   simpeg_encode_putbits(context, context->frame_pred_dct,1); /* frame_pred_frame_dct */
211   simpeg_encode_putbits(context, 0,1); /* concealment_motion_vectors  -- currently not implemented */
212   simpeg_encode_putbits(context, context->q_scale_type,1); /* q_scale_type */
213   simpeg_encode_putbits(context, context->intravlc,1); /* intra_vlc_format */
214   simpeg_encode_putbits(context, context->altscan,1); /* alternate_scan */
215   simpeg_encode_putbits(context, context->repeatfirst,1); /* repeat_first_field */
216   simpeg_encode_putbits(context, context->prog_frame,1); /* chroma_420_type */
217   simpeg_encode_putbits(context, context->prog_frame,1); /* progressive_frame */
218   simpeg_encode_putbits(context, 0,1); /* composite_display_flag */
219 }
220 
221 /* generate sequence_end_code (6.2.2) */
222 void
simpeg_encode_putseqend(simpeg_encode_context * context)223 simpeg_encode_putseqend(simpeg_encode_context * context)
224 {
225   simpeg_encode_alignbits(context);
226   simpeg_encode_putbits(context, SEQ_END_CODE,32);
227 }
228