r1007: Make configure detect and work on amd64.
[cinelerra_cv/mob.git] / mpeg2enc / putseq.c
blob30acf79e6850a9387fb395f7db05740d0cb7be1a
1 /* putseq.c, sequence level routines */
3 /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
5 /*
6 * Disclaimer of Warranty
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.
16 * This disclaimer of warranty extends to the user of these programs and user's
17 * customers, employees, agents, transferees, successors, and assigns.
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.
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.
30 #include "config.h"
31 #include <stdio.h>
32 #include <string.h>
33 #include "global.h"
38 void putseq()
40 /* this routine assumes (N % M) == 0 */
41 int i, j, k, f, f0, n, np, nb;
42 int ipflag;
43 int sxf = 0, sxb = 0, syf = 0, syb = 0;
44 motion_comp_s mc_data;
46 for(k = 0; k < processors; k++)
47 ratectl_init_seq(ratectl[k]); /* initialize rate control */
50 if(end_frame == 0x7fffffff)
51 frames_scaled = end_frame;
52 else
53 frames_scaled = (end_frame - start_frame) *
54 frame_rate /
55 input_frame_rate;
56 //frames_scaled = 100;
58 /* If we're not doing sequence header, sequence extension and
59 sequence display extension every GOP at least has to be one at the
60 start of the sequence.
63 if(!seq_header_every_gop) putseqhdr();
66 /* optionally output some text data (description, copyright or whatever) */
67 // if (strlen(id_string) > 1)
68 // putuserdata(id_string);
71 /* loop through all frames in encoding/decoding order */
72 for(i = 0;
73 i < frames_scaled;
74 i++)
76 //printf("putseq 1\n");
77 if(i != 0 && verbose)
79 if(end_frame == 0x7fffffff)
80 fprintf(stderr,"Encoding frame %d. bitrate achieved: %d \r",
81 frame0 + i + 1,
82 (int)((float)ftell(outfile) / ((float)i / frame_rate)) * 8);
83 else
84 fprintf(stderr,"%5d %13d%% %17d %23d \r",
85 frame0 + i + 1,
86 (int)((float)i / frames_scaled * 100),
87 (int)((float)ftell(outfile) / ((float)i / frame_rate)) * 8,
88 (int)((float)ftell(outfile) / ((float)i / frames_scaled)));
90 fflush(stderr);
92 /* f0: lowest frame number in current GOP
94 * first GOP contains N-(M-1) frames,
95 * all other GOPs contain N frames
97 f0 = N*((i+(M-1))/N) - (M-1);
99 if (f0<0)
100 f0=0;
102 if(i == 0 || (i - 1) % M == 0)
105 /* I or P frame: Somewhat complicated buffer handling.
106 The original reference frame data is actually held in
107 the frame input buffers. In input read-ahead buffer
108 management code worries about rotating them for use.
109 So to make the new old one the current new one we
110 simply move the pointers. However for the
111 reconstructed "ref" data we are managing our a seperate
112 pair of buffers. We need to swap these to avoid losing
113 one! */
115 for (j=0; j<3; j++)
117 unsigned char *tmp;
118 oldorgframe[j] = neworgframe[j];
119 tmp = oldrefframe[j];
120 oldrefframe[j] = newrefframe[j];
121 newrefframe[j] = tmp;
124 /* For an I or P frame the "current frame" is simply an alias
125 for the new new reference frame. Saves the need to copy
126 stuff around once the frame has been processed.
129 cur_picture.curorg = neworgframe;
130 cur_picture.curref = newrefframe;
131 //printf("putseq 1 %p %p %p\n", curorg[0], curorg[1], curorg[2]);
134 /* f: frame number in display order */
135 f = (i==0) ? 0 : i+M-1;
136 if (f>=end_frame)
137 f = end_frame - 1;
139 if (i==f0) /* first displayed frame in GOP is I */
141 /* I frame */
142 cur_picture.pict_type = I_TYPE;
144 cur_picture.forw_hor_f_code =
145 cur_picture.forw_vert_f_code = 15;
146 cur_picture.back_hor_f_code =
147 cur_picture.back_vert_f_code = 15;
149 /* n: number of frames in current GOP
151 * first GOP contains (M-1) less (B) frames
153 n = (i==0) ? N-(M-1) : N;
155 /* last GOP may contain less frames */
156 if (n > end_frame-f0)
157 n = end_frame-f0;
159 /* number of P frames */
160 if (i==0)
161 np = (n + 2*(M-1))/M - 1; /* first GOP */
162 else
163 np = (n + (M-1))/M - 1;
165 /* number of B frames */
166 nb = n - np - 1;
168 for(k = 0; k < processors; k++)
169 ratectl_init_GOP(ratectl[k], np, nb);
171 /* set closed_GOP in first GOP only
172 No need for per-GOP seqhdr in first GOP as one
173 has already been created.
175 // putgophdr(f0,i==0, i!=0 && seq_header_every_gop);
176 if(seq_header_every_gop) putseqhdr();
177 putgophdr(f0, i == 0);
179 else
181 /* P frame */
182 cur_picture.pict_type = P_TYPE;
183 cur_picture.forw_hor_f_code = motion_data[0].forw_hor_f_code;
184 cur_picture.forw_vert_f_code = motion_data[0].forw_vert_f_code;
185 cur_picture.back_hor_f_code =
186 cur_picture.back_vert_f_code = 15;
187 sxf = motion_data[0].sxf;
188 syf = motion_data[0].syf;
191 else
193 /* B frame: no need to change the reference frames.
194 The current frame data pointers are a 3rd set
195 seperate from the reference data pointers.
197 cur_picture.curorg = auxorgframe;
198 cur_picture.curref = auxframe;
200 /* f: frame number in display order */
201 f = i - 1;
202 cur_picture.pict_type = B_TYPE;
203 n = (i-2)%M + 1; /* first B: n=1, second B: n=2, ... */
204 cur_picture.forw_hor_f_code = motion_data[n].forw_hor_f_code;
205 cur_picture.forw_vert_f_code = motion_data[n].forw_vert_f_code;
206 cur_picture.back_hor_f_code = motion_data[n].back_hor_f_code;
207 cur_picture.back_vert_f_code = motion_data[n].back_vert_f_code;
208 sxf = motion_data[n].sxf;
209 syf = motion_data[n].syf;
210 sxb = motion_data[n].sxb;
211 syb = motion_data[n].syb;
214 cur_picture.temp_ref = f - f0;
215 cur_picture.frame_pred_dct = frame_pred_dct_tab[cur_picture.pict_type - 1];
216 cur_picture.q_scale_type = qscale_tab[cur_picture.pict_type - 1];
217 cur_picture.intravlc = intravlc_tab[cur_picture.pict_type - 1];
218 cur_picture.altscan = altscan_tab[cur_picture.pict_type - 1];
220 //printf("putseq 2 %d\n", cur_picture.frame_pred_dct);
221 readframe(f + frame0, cur_picture.curorg);
222 if(!frames_scaled) break;
223 //printf("putseq 3 %p %p %p\n", curorg[0], curorg[1], curorg[2]);
225 mc_data.oldorg = oldorgframe;
226 mc_data.neworg = neworgframe;
227 mc_data.oldref = oldrefframe;
228 mc_data.newref = newrefframe;
229 mc_data.cur = cur_picture.curorg;
230 mc_data.curref = cur_picture.curref;
231 mc_data.sxf = sxf;
232 mc_data.syf = syf;
233 mc_data.sxb = sxb;
234 mc_data.syb = syb;
236 if (fieldpic)
238 //printf("putseq 4\n");
239 cur_picture.topfirst = opt_topfirst;
240 if (!quiet)
242 fprintf(stderr,"\nfirst field (%s) ",
243 cur_picture.topfirst ? "top" : "bot");
244 fflush(stderr);
247 cur_picture.pict_struct = cur_picture.topfirst ? TOP_FIELD : BOTTOM_FIELD;
248 /* A.Stevens 2000: Append fast motion compensation data for new frame */
249 fast_motion_data(cur_picture.curorg[0], cur_picture.pict_struct);
250 motion_estimation(&cur_picture, &mc_data,0,0);
252 predict(&cur_picture,oldrefframe,newrefframe,predframe,0);
253 dct_type_estimation(&cur_picture,predframe[0],cur_picture.curorg[0]);
254 transform(&cur_picture,predframe,cur_picture.curorg);
256 putpict(&cur_picture); /* Quantisation: blocks -> qblocks */
257 #ifndef OUTPUT_STAT
258 if( cur_picture.pict_type!=B_TYPE)
260 #endif
261 iquantize( &cur_picture );
262 itransform(&cur_picture,predframe,cur_picture.curref);
264 * calcSNR(cur_picture.curorg,cur_picture.curref);
265 * stats();
267 #ifndef OUTPUT_STAT
269 #endif
270 if (!quiet)
272 fprintf(stderr,"second field (%s) ",cur_picture.topfirst ? "bot" : "top");
273 fflush(stderr);
276 cur_picture.pict_struct = cur_picture.topfirst ? BOTTOM_FIELD : TOP_FIELD;
278 ipflag = (cur_picture.pict_type==I_TYPE);
279 if (ipflag)
281 /* first field = I, second field = P */
282 cur_picture.pict_type = P_TYPE;
283 cur_picture.forw_hor_f_code = motion_data[0].forw_hor_f_code;
284 cur_picture.forw_vert_f_code = motion_data[0].forw_vert_f_code;
285 cur_picture.back_hor_f_code =
286 cur_picture.back_vert_f_code = 15;
287 sxf = motion_data[0].sxf;
288 syf = motion_data[0].syf;
291 motion_estimation(&cur_picture, &mc_data ,1,ipflag);
293 predict(&cur_picture,oldrefframe,newrefframe,predframe,1);
294 dct_type_estimation(&cur_picture,predframe[0],cur_picture.curorg[0]);
295 transform(&cur_picture,predframe,cur_picture.curorg);
297 putpict(&cur_picture); /* Quantisation: blocks -> qblocks */
299 #ifndef OUTPUT_STAT
300 if( cur_picture.pict_type!=B_TYPE)
302 #endif
303 iquantize( &cur_picture );
304 itransform(&cur_picture,predframe,cur_picture.curref);
306 * calcSNR(cur_picture.curorg,cur_picture.curref);
307 * stats();
309 #ifndef OUTPUT_STAT
311 #endif
314 else
316 //printf("putseq 5\n");
317 cur_picture.pict_struct = FRAME_PICTURE;
318 fast_motion_data(cur_picture.curorg[0], cur_picture.pict_struct);
319 //printf("putseq 5\n");
321 /* do motion_estimation
323 * uses source frames (...orgframe) for full pel search
324 * and reconstructed frames (...refframe) for half pel search
327 motion_estimation(&cur_picture,&mc_data,0,0);
329 //printf("putseq 5\n");
330 predict(&cur_picture, oldrefframe,newrefframe,predframe,0);
331 //printf("putseq 5\n");
332 dct_type_estimation(&cur_picture,predframe[0],cur_picture.curorg[0]);
333 //printf("putseq 5\n");
335 transform(&cur_picture,predframe,cur_picture.curorg);
336 //printf("putseq 5\n");
338 /* Side-effect: quantisation blocks -> qblocks */
339 putpict(&cur_picture);
340 //printf("putseq 6\n");
342 #ifndef OUTPUT_STAT
343 if( cur_picture.pict_type!=B_TYPE)
345 #endif
346 iquantize( &cur_picture );
347 //printf("putseq 5\n");
348 itransform(&cur_picture,predframe,cur_picture.curref);
349 //printf("putseq 6\n");
351 * calcSNR(cur_picture.curorg,cur_picture.curref);
352 * stats();
354 #ifndef OUTPUT_STAT
356 #endif
358 writeframe(f + frame0, cur_picture.curref);
360 //printf("putseq 7\n");
362 putseqend();
363 if(verbose) fprintf(stderr, "\nDone. Be sure to visit heroinewarrior.com for updates.\n");