version update
[goodguy/cinelerra.git] / cinelerra-5.1 / mpeg2enc / putseq.c
1 /* putseq.c, sequence level routines                                        */
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 "config.h"
31 #include <stdio.h>
32 #include <string.h>
33 #include "global.h"
34
35
36
37
38 void putseq()
39 {
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;
45
46         for(k = 0; k < processors; k++)
47                 ratectl_init_seq(ratectl[k]); /* initialize rate control */
48
49
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;
57
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.
61         */
62         
63         if(!seq_header_every_gop) putseqhdr();
64
65
66         /* optionally output some text data (description, copyright or whatever) */
67 //      if (strlen(id_string) > 1)
68 //              putuserdata(id_string);
69
70
71         /* loop through all frames in encoding/decoding order */
72         for(i = 0; 
73                 i < frames_scaled; 
74                 i++)
75         {
76 //printf("putseq 1\n");
77                 if(i != 0 && verbose)
78                 {
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)));
89                 }
90                 fflush(stderr);
91
92                 /* f0: lowest frame number in current GOP
93                  *
94                  * first GOP contains N-(M-1) frames,
95                  * all other GOPs contain N frames
96                  */
97                 f0 = N*((i+(M-1))/N) - (M-1);
98
99                 if (f0<0)
100                         f0=0;
101
102                 if(i == 0 || (i - 1) % M == 0)
103                 {
104
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!  */
114
115                         for (j=0; j<3; j++)
116                         {
117                                 unsigned char *tmp;
118                                 oldorgframe[j] = neworgframe[j];
119                                 tmp = oldrefframe[j];
120                                 oldrefframe[j] = newrefframe[j];
121                                 newrefframe[j] = tmp;
122                         }
123
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.
127                         */
128
129                         cur_picture.curorg = neworgframe;
130                         cur_picture.curref = newrefframe;
131 //printf("putseq 1 %p %p %p\n", curorg[0], curorg[1], curorg[2]);
132
133
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;
138
139                         if (i==f0) /* first displayed frame in GOP is I */
140                         {
141                                 /* I frame */
142                                 cur_picture.pict_type = I_TYPE;
143
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;
148
149                                 /* n: number of frames in current GOP
150                                  *
151                                  * first GOP contains (M-1) less (B) frames
152                                  */
153                                 n = (i==0) ? N-(M-1) : N;
154
155                                 /* last GOP may contain less frames */
156                                 if (n > end_frame-f0)
157                                         n = end_frame-f0;
158
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;
164
165                                 /* number of B frames */
166                                 nb = n - np - 1;
167
168                                 for(k = 0; k < processors; k++)
169                                         ratectl_init_GOP(ratectl[k], np, nb);
170                                 
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.
174                                  */
175 //                              putgophdr(f0,i==0, i!=0 && seq_header_every_gop);
176                                 if(seq_header_every_gop) putseqhdr();
177                                 putgophdr(f0, i == 0);
178                         }
179                         else
180                         {
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;
189                         }
190                 }
191                 else
192                 {
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.
196                         */
197                         cur_picture.curorg = auxorgframe;
198                         cur_picture.curref = auxframe;
199
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;
212                 }
213
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];
219
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]);
224
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;
235
236         if (fieldpic)
237                 {
238 //printf("putseq 4\n");
239                         cur_picture.topfirst = opt_topfirst;
240                         if (!quiet)
241                         {
242                                 fprintf(stderr,"\nfirst field  (%s) ",
243                                                 cur_picture.topfirst ? "top" : "bot");
244                                 fflush(stderr);
245                         }
246
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);
251
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);
255
256                         putpict(&cur_picture);          /* Quantisation: blocks -> qblocks */
257 #ifndef OUTPUT_STAT
258                         if( cur_picture.pict_type!=B_TYPE)
259                         {
260 #endif
261                                 iquantize( &cur_picture );
262                                 itransform(&cur_picture,predframe,cur_picture.curref);
263 /*
264  *                              calcSNR(cur_picture.curorg,cur_picture.curref);
265  *                              stats();
266  */
267 #ifndef OUTPUT_STAT
268                         }
269 #endif
270                         if (!quiet)
271                         {
272                                 fprintf(stderr,"second field (%s) ",cur_picture.topfirst ? "bot" : "top");
273                                 fflush(stderr);
274                         }
275
276                         cur_picture.pict_struct = cur_picture.topfirst ? BOTTOM_FIELD : TOP_FIELD;
277
278                         ipflag = (cur_picture.pict_type==I_TYPE);
279                         if (ipflag)
280                         {
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;
289                         }
290
291                         motion_estimation(&cur_picture, &mc_data ,1,ipflag);
292
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);
296
297                         putpict(&cur_picture);  /* Quantisation: blocks -> qblocks */
298
299 #ifndef OUTPUT_STAT
300                         if( cur_picture.pict_type!=B_TYPE)
301                         {
302 #endif
303                                 iquantize( &cur_picture );
304                                 itransform(&cur_picture,predframe,cur_picture.curref);
305 /*
306  *                              calcSNR(cur_picture.curorg,cur_picture.curref);
307  *                              stats();
308  */
309 #ifndef OUTPUT_STAT
310                         }
311 #endif
312                                 
313                 }
314                 else
315                 {
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");
320
321 /* do motion_estimation
322  *
323  * uses source frames (...orgframe) for full pel search
324  * and reconstructed frames (...refframe) for half pel search
325  */
326
327                         motion_estimation(&cur_picture,&mc_data,0,0);
328
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");
334
335                         transform(&cur_picture,predframe,cur_picture.curorg);
336 //printf("putseq 5\n");
337
338 /* Side-effect: quantisation blocks -> qblocks */
339                         putpict(&cur_picture);  
340 //printf("putseq 6\n");
341
342 #ifndef OUTPUT_STAT
343                         if( cur_picture.pict_type!=B_TYPE)
344                         {
345 #endif
346                                 iquantize( &cur_picture );
347 //printf("putseq 5\n");
348                                 itransform(&cur_picture,predframe,cur_picture.curref);
349 //printf("putseq 6\n");
350 /*
351  *                              calcSNR(cur_picture.curorg,cur_picture.curref);
352  *                              stats();
353  */
354 #ifndef OUTPUT_STAT
355                         }
356 #endif
357                 }
358                 writeframe(f + frame0, cur_picture.curref);
359                         
360 //printf("putseq 7\n");
361         }
362         putseqend();
363         if(verbose) fprintf(stderr, "\nDone.  Be sure to visit heroinewarrior.com for updates.\n");
364 }