w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

mpeg.c
Go to the documentation of this file.
1 /*===========================================================================*
2  * mpeg.c *
3  * *
4  * Procedures to generate the MPEG sequence *
5  * *
6  * EXPORTED PROCEDURES: *
7  * GetMPEGStream *
8  * IncrementTCTime *
9  * SetStatFileName *
10  * SetGOPSize *
11  * PrintStartStats *
12  * *
13  *===========================================================================*/
14 
15 /*
16  * Copyright (c) 1995 The Regents of the University of California.
17  * All rights reserved.
18  *
19  * Permission to use, copy, modify, and distribute this software and its
20  * documentation for any purpose, without fee, and without written agreement is
21  * hereby granted, provided that the above copyright notice and the following
22  * two paragraphs appear in all copies of this software.
23  *
24  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
25  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
26  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
27  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
30  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
31  * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
32  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
33  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
34  */
35 
36 /*
37  * $Header: /n/picasso/project/mpeg/mpeg_dist/mpeg_encode/RCS/mpeg.c,v 1.24 1995/08/16 18:10:48 smoot Exp $
38  * $Log: mpeg.c,v $
39  * Revision 1.24 1995/08/16 18:10:48 smoot
40  * *** empty log message ***
41  *
42  * Revision 1.23 1995/08/07 21:48:08 smoot
43  * stdin bugs fixed
44  *
45  * Revision 1.22 1995/06/26 21:49:19 smoot
46  * added new frame ordering (hacks)^H^H^H^H^H code ;-)
47  *
48  * Revision 1.21 1995/06/21 18:30:41 smoot
49  * changed time structure to be ANSI
50  * changed file access to be binary (DOS!)
51  * added time to userdata
52  * Added a sleep to remote reads (NFS delay)
53  *
54  * Revision 1.20 1995/05/02 01:49:21 eyhung
55  * prints out true output bit rate and slightly untabified
56  *
57  * Revision 1.19 1995/05/02 00:45:35 eyhung
58  * endstats now contain correct output fbit rate at the specified frame rate
59  *
60  * Revision 1.18 1995/03/27 23:43:20 smoot
61  * killed printing long as int (compiler warning)
62  *
63  * Revision 1.17 1995/03/27 19:18:54 smoot
64  * fixed divide by zero for very quick encodings
65  *
66  * Revision 1.16 1995/02/02 22:03:37 smoot
67  * added types for MIPS
68  *
69  * Revision 1.15 1995/02/02 07:26:58 eyhung
70  * removed unused tempframe
71  *
72  * Revision 1.14 1995/02/01 05:01:35 eyhung
73  * Completed infinite coding-on-the-fly
74  *
75  * Revision 1.13 1995/02/01 02:34:02 eyhung
76  * Added full coding-on-the-fly
77  *
78  * Revision 1.12 1995/01/31 23:05:14 eyhung
79  * Added some stdin stuff
80  *
81  * Revision 1.11 1995/01/20 00:01:16 eyhung
82  * Added output file to PrintEndStats
83  *
84  * Revision 1.10 1995/01/19 23:08:51 eyhung
85  * Changed copyrights
86  *
87  * Revision 1.9 1995/01/17 18:55:54 smoot
88  * added right version number, and error if no frames selected
89  *
90  * Revision 1.8 1995/01/16 08:12:54 eyhung
91  * added realQuiet
92  *
93  * Revision 1.7 1994/12/07 00:40:36 smoot
94  * Added seperate P and B search ranges
95  *
96  * Revision 1.6 1994/11/28 21:46:45 smoot
97  * Added version printing
98  *
99  * Revision 1.5 1994/11/19 01:33:05 smoot
100  * put in userdata
101  *
102  * Revision 1.4 1994/11/14 22:36:22 smoot
103  * Merged specifics and rate control
104  *
105  * Revision 1.2 1994/03/15 00:27:11 keving
106  * nothing
107  *
108  * Revision 1.1 1993/12/22 19:19:01 keving
109  * nothing
110  *
111  * Revision 1.6 1993/07/22 22:23:43 keving
112  * nothing
113  *
114  * Revision 1.5 1993/06/30 20:06:09 keving
115  * nothing
116  *
117  * Revision 1.4 1993/06/03 21:08:08 keving
118  * nothing
119  *
120  * Revision 1.3 1993/02/19 18:10:12 keving
121  * nothing
122  *
123  * Revision 1.2 1993/02/17 23:18:20 dwallach
124  * checkin prior to keving's joining the project
125  *
126  */
127 
128 
129 /*==============*
130  * HEADER FILES *
131  *==============*/
132 
133 #include "all.h"
134 #include <time.h>
135 #include <errno.h>
136 #include <unistd.h>
137 #include "mtypes.h"
138 #include "frames.h"
139 #include "motion_search.h"
140 #include "mpeg.h"
141 #include "prototypes.h"
142 #include "parallel.h"
143 #include "param.h"
144 #include "readframe.h"
145 #include "fsize.h"
146 #include "mheaders.h"
147 #include "rate.h"
148 #ifdef MIPS
149 #include <sys/types.h>
150 #endif
151 #include <sys/stat.h>
152 
153 /*===========*
154  * VERSION *
155  *===========*/
156 
157 #define VERSION "1.5b"
158 
159 
160 /*===========*
161  * CONSTANTS *
162  *===========*/
163 
164 #define FPS_30 0x5 /* from MPEG standard sect. 2.4.3.2 */
165 #define ASPECT_1 0x1 /* aspect ratio, from MPEG standard sect. 2.4.3.2 */
166 
167 
168 /*==================*
169  * STATIC VARIABLES *
170  *==================*/
171 
173 static int framesOutput;
174 static int realStart, realEnd;
175 static int currentGOP;
176 static int timeMask;
177 static int numI, numP, numB;
178 
179 
180 /*==================*
181  * GLOBAL VARIABLES *
182  *==================*/
183 
184 /* important -- don't initialize anything here */
185 /* must be re-initted anyway in GenMPEGStream */
186 
187 extern int IOtime;
188 extern boolean resizeFrame;
190 int gopSize = 100; /* default */
196 char statFileName[256];
197 char bitRateFileName[256];
204 static int framesRead;
211 extern char userDataFileName[];
212 extern int mult_seq_headers;
213 
215 
216 /*===============================*
217  * INTERNAL PROCEDURE prototypes *
218  *===============================*/
219 
220 static void ShowRemainingTime _ANSI_ARGS_((void));
221 static void ComputeDHMSTime _ANSI_ARGS_((int32 someTime, char *timeText));
222 static void ComputeGOPFrames _ANSI_ARGS_((int whichGOP, int *firstFrame,
223  int *lastFrame, int numFrames));
224 static void PrintEndStats _ANSI_ARGS_((int inputFrameBits, int32 totalBits));
225 static void ProcessRefFrame _ANSI_ARGS_((MpegFrame *frame,
226  BitBucket *bb, int lastFrame,
227  char *outputFileName));
228 static void OpenBitRateFile _ANSI_ARGS_((void));
229 static void CloseBitRateFile _ANSI_ARGS_((void));
230 
231 
232 /*=====================*
233  * EXPORTED PROCEDURES *
234  *=====================*/
235 
236 /*===========================================================================*
237  *
238  * SetReferenceFrameType
239  *
240  * set the reference frame type to be original or decoded
241  *
242  * RETURNS: nothing
243  *
244  * SIDE EFFECTS: referenceFrame
245  *
246  *===========================================================================*/
247 void
249  char *type;
250 {
251  if ( strcmp(type, "ORIGINAL") == 0 ) {
253  } else if ( strcmp(type, "DECODED") == 0 ) {
255  } else {
256  fprintf(stderr, "ERROR: Illegal reference frame type: '%s'\n",
257  type);
258  exit(1);
259  }
260 }
261 
262 void
264  char *fileName;
265 {
267 }
268 
269 
270 /*===========================================================================*
271  *
272  * GenMPEGStream
273  *
274  * generate an MPEG sequence stream (generally)
275  * if whichGOP == frameStart == -1 then does complete MPEG sequence
276  * if whichGOP != -1 then does numbered GOP only (without sequence
277  * header)
278  * if frameStart != -1 then does numbered frames only (without any
279  * sequence or GOP headers)
280  *
281  * RETURNS: amount of time it took
282  *
283  * SIDE EFFECTS: too numerous to mention
284  *
285  *===========================================================================*/
286 int32
289  int whichGOP;
290  int frameStart;
291  int frameEnd;
292  int32 qtable[];
293  int32 niqtable[];
294  int numFrames;
295  FILE *ofp;
296  char *outputFileName;
297 {
298  extern void PrintItoIBitRate _ANSI_ARGS_((int numBits, int frameNum));
299  BitBucket *bb;
300  int i;
301  char frameType;
302  MpegFrame *frame = NULL;
303  MpegFrame *tempFrame;
304  int firstFrame, lastFrame;
305  int inputFrameBits = 0;
306  char inputFileName[1024];
307  time_t tempTimeStart, tempTimeEnd;
308  boolean firstFrameDone = FALSE;
309  int numBits;
310  int32 bitstreamMode, res;
311 
312  if ( (whichGOP == -1) && (frameStart == -1) &&
313  (! stdinUsed) && (FType_Type(numFrames-1) == 'b') ) {
314  fprintf(stderr, "\n");
315  fprintf(stderr, "WARNING: One or more B-frames at end will not be encoded.\n");
316  fprintf(stderr, " See FORCE_ENCODE_LAST_FRAME option in man page.\n");
317  fprintf(stderr, "\n");
318  }
319 
320  time(&timeStart);
321 
322  framesRead = 0;
323 
327 
328  Fsize_Reset();
329 
330  framesOutput = 0;
331 
332  if ( childProcess && separateConversion ) {
334  } else {
336  }
337 
338  if ( whichGOP != -1 ) {
339  ComputeGOPFrames(whichGOP, &firstFrame, &lastFrame, numFrames);
340 
341  realStart = firstFrame;
342  realEnd = lastFrame;
343 
344  if ( FType_Type(firstFrame) == 'b' ) {
345 
346  /* can't find the previous frame interactively */
347  if ( stdinUsed ) {
348  fprintf(stderr, "ERROR: Cannot encode GOP from stdin when first frame is a B-frame.\n");
349  exit(1);
350  }
351 
352  /* need to load in previous frame; call it an I frame */
353  frame = Frame_New(firstFrame-1, 'i');
354 
355  time(&tempTimeStart);
356 
357  if ( (referenceFrame == DECODED_FRAME) &&
358  childProcess ) {
359  WaitForDecodedFrame(firstFrame);
360 
361  if ( remoteIO ) {
362  GetRemoteDecodedRefFrame(frame, firstFrame-1);
363  } else {
364  ReadDecodedRefFrame(frame, firstFrame-1);
365  }
366  } else {
367  if ( remoteIO ) {
368  GetRemoteFrame(frame, firstFrame-1);
369  } else {
370  GetNthInputFileName(inputFileName, firstFrame-1);
371 
372  if ( childProcess && separateConversion ) {
373  ReadFrame(frame, inputFileName, slaveConversion, TRUE);
374  } else {
375  ReadFrame(frame, inputFileName, inputConversion, TRUE);
376  }
377  }
378  }
379 
380  framesRead++;
381 
382  time(&tempTimeEnd);
383  IOtime += (tempTimeEnd-tempTimeStart);
384  }
385  } else if ( frameStart != -1 ) {
386  if ( frameEnd > numFrames-1 ) {
387  fprintf(stderr, "ERROR: Specified last frame is out of bounds\n");
388  exit(1);
389  }
390 
392  realEnd = frameEnd;
393 
394  firstFrame = frameStart;
395  lastFrame = frameEnd;
396 
397  /* if first frame is P or B, need to read in P or I frame before it */
398  if ( FType_Type(firstFrame) != 'i' ) {
399 
400  /* can't find the previous frame interactively */
401  if ( stdinUsed ) {
402  fprintf(stderr, "ERROR: Cannot encode frames from stdin when first frame is not an I-frame.\n");
403  exit(1);
404  }
405 
406  firstFrame = FType_PastRef(firstFrame);
407  }
408 
409  /* if last frame is B, need to read in P or I frame after it */
410  if ( (FType_Type(lastFrame) == 'b') && (lastFrame != numFrames-1) ) {
411 
412  /* can't find the next reference frame interactively */
413  if ( stdinUsed ) {
414  fprintf(stderr, "ERROR: Cannot encode frames from stdin when last frame is a B-frame.\n");
415  exit(1);
416  }
417 
418  lastFrame = FType_FutureRef(lastFrame);
419  }
420 
421  if ( lastFrame > numFrames-1 ) { /* can't go last frame! */
422  lastFrame = numFrames-1;
423  }
424 
425  } else {
426  firstFrame = 0;
427  lastFrame = numFrames-1;
428 
429  realStart = 0;
430  realEnd = numFrames-1;
431  if ( numFrames == 0 ) {
432  fprintf(stderr, "ERROR: No frames selected!\n");
433  exit(1);
434  }
435  }
436 
437  /* count number of I, P, and B frames */
438  numI = 0; numP = 0; numB = 0;
439  timeMask = 0;
440  if (stdinUsed) {
441  numI = numP = numB = MAXINT/4;
442  } else {
443  for ( i = firstFrame; i <= lastFrame; i++ ) {
444  frameType = FType_Type(i);
445  switch(frameType) {
446  case 'i': numI++; timeMask |= 0x1; break;
447  case 'p': numP++; timeMask |= 0x2; break;
448  case 'b': numB++; timeMask |= 0x4; break;
449  }
450  }
451  }
452 
453  if ( ! childProcess ) {
454  if ( showBitRatePerFrame )
455  OpenBitRateFile();
457  }
458 
459  if ( frameStart == -1 ) {
460  bb = Bitio_New(ofp);
461  } else {
462  bb = NULL;
463  }
464 
465  tc_hrs = 0; tc_min = 0; tc_sec = 0; tc_pict = 0; tc_extra = 0;
466  for ( i = 0; i < firstFrame; i++ ) {
467  IncrementTCTime();
468  }
469 
470  totalFramesSent = firstFrame;
471  currentGOP = gopSize; /* so first I-frame generates GOP Header */
472 
473  /* Rate Control Initialization */
474  bitstreamMode = getRateMode();
475  if (bitstreamMode == FIXED_RATE) {
476  res = initRateControl();
477  /*
478  SetFrameRate();
479  */
480  }
481 
482 #ifdef BLEAH
483 fprintf(stdout, "firstFrame, lastFrame = %d, %d; real = %d, %d\n",
484  firstFrame, lastFrame, realStart, realEnd);
485 fflush(stdout);
486 #endif
487 
488  pastRefFrame = NULL;
490  for ( i = firstFrame; i <= lastFrame; i++) {
491 
492  /* break out of the near-infinite loop if input from stdin is done */
493 #if 0
494  char eofcheck[1];
495  if ( stdinUsed ) {
496  if (scanf("%c", eofcheck) != EOF) {
497  ungetc(eofcheck[0], stdin);
498  } else {
499  break;
500  }
501  }
502 #else
503  /*
504  ** For some reason the above version of this stdin EOF check does not
505  ** work right with jpeg files, the ungetc() is not padding anything to
506  ** stdin, I have no idea why (perhaps because a char is passed instead
507  ** of an int?), and it drove me nuts, so I wrote my own, slightly
508  ** cleaner version, and this one seems to work.
509  ** Dave Scott (dhs), UofO, 7/19/95.
510  */
511  if ( stdinUsed) {
512  int eofcheck_;
513  eofcheck_ = fgetc(stdin);
514  if ( eofcheck_ == EOF)
515  break;
516  else
517  ungetc(eofcheck_, stdin);
518  }
519 #endif
520  frameType = FType_Type(i);
521 
522  time(&tempTimeStart);
523 
524  /* skip non-reference frames if non-interactive
525  * read in non-reference frames if interactive */
526  if ( frameType == 'b' ) {
527  if ( stdinUsed ) {
528  frame = Frame_New(i, frameType);
529  ReadFrame(frame, "stdin", inputConversion, TRUE);
530 
531  framesRead++;
532 
533  time(&tempTimeEnd);
534  IOtime += (tempTimeEnd-tempTimeStart);
535 
536  /* Add the B frame to the end of the queue of B-frames
537  * for later encoding
538  */
539 
540  if (futureRefFrame != NULL) {
541  tempFrame = futureRefFrame;
542  while (tempFrame->next != NULL) {
543  tempFrame = tempFrame->next;
544  }
545  tempFrame->next = frame;
546  } else {
547  fprintf(stderr, "Yow, something wrong in neverland! (hit bad code in mpeg.c\n");
548  }
549  }
550  continue;
551  }
552 
553  frame = Frame_New(i, frameType);
554 
556  futureRefFrame = frame;
557 
558  if ( (referenceFrame == DECODED_FRAME) &&
559  ((i < realStart) || (i > realEnd)) ) {
561 
562  if ( remoteIO ) {
563  GetRemoteDecodedRefFrame(frame, i);
564  } else {
565  ReadDecodedRefFrame(frame, i);
566  }
567  } else {
568  if ( remoteIO ) {
569  GetRemoteFrame(frame, i);
570  } else {
571  GetNthInputFileName(inputFileName, i);
572  if ( childProcess && separateConversion ) {
573  ReadFrame(frame, inputFileName, slaveConversion, TRUE);
574  } else {
575  ReadFrame(frame, inputFileName, inputConversion, TRUE);
576  }
577  }
578  }
579 
580  framesRead++;
581 
582  time(&tempTimeEnd);
583  IOtime += (tempTimeEnd-tempTimeStart);
584 
585  if ( ! firstFrameDone ) {
586  char *userData = (char *)NULL;
587  int userDataSize = 0;
588 
589  inputFrameBits = 24*Fsize_x*Fsize_y;
591 
592  if ( (whichGOP == -1) && (frameStart == -1) ) {
593  DBG_PRINT(("Generating sequence header\n"));
594  bitstreamMode = getRateMode();
595  if (bitstreamMode == FIXED_RATE) {
596  bit_rate = getBitRate();
598  }
599  else {
600  bit_rate = -1;
601  buf_size = -1;
602  }
603 
604  if (strlen(userDataFileName) != 0) {
605  struct stat statbuf;
606  FILE *fp;
607 
608  stat(userDataFileName,&statbuf);
609  userDataSize = statbuf.st_size;
610  userData = malloc(userDataSize);
611  if ((fp = fopen(userDataFileName,"rb")) == NULL) {
612  fprintf(stderr,"Could not open userdata file-%s.\n",
614  userData = NULL;
615  userDataSize = 0;
616  goto write;
617  }
618  if (fread(userData,1,userDataSize,fp) != userDataSize) {
619  fprintf(stderr,"Could not read %d bytes from userdata file-%s.\n",
620  userDataSize,userDataFileName);
621  userData = NULL;
622  userDataSize = 0;
623  goto write;
624  }
625  } else { /* Put in our UserData Header */
626  time_t now;
627 
628  time(&now);
629  userData = malloc(100);
630  sprintf(userData,"MPEG stream encoded by UCB Encoder (mpeg_encode) v%s on %s.",
631  VERSION, ctime(&now));
632  userDataSize = strlen(userData);
633  }
634  write:
636  /* pratio */ aspectRatio,
637  /* pict_rate */ frameRate, /* bit_rate */ bit_rate,
638  /* buf_size */ buf_size, /*c_param_flag */ 1,
639  /* iq_matrix */ qtable, /* niq_matrix */ niqtable,
640  /* ext_data */ NULL, /* ext_data_size */ 0,
641  /* user_data */ (uint8*) userData, /* user_data_size */ userDataSize);
642  }
643 
644  firstFrameDone = TRUE;
645  }
646 
647  ProcessRefFrame(frame, bb, lastFrame, outputFileName);
648 
649  }
650 
651  if ( frame != NULL ) {
652  Frame_Free(frame);
653  }
654 
655  /* SEQUENCE END CODE */
656  if ( (whichGOP == -1) && (frameStart == -1) ) {
658  }
659 
660  if ( frameStart == -1 ) {
661  /* I think this is right, since (bb == NULL) if (frameStart != -1).
662  See above where "bb" is initialized */
663  numBits = bb->cumulativeBits;
664  } else {
665  /* What should the correct value be? Most likely 1. "numBits" is
666  used below, so we need to make sure it's properly initialized
667  to somthing (anything). */
668  numBits = 1;
669  }
670 
671  if ( frameStart == -1 ) {
672  Bitio_Flush(bb);
673  bb = NULL;
674  fclose(ofp);
675 
676  time(&timeEnd);
678 
679  if ( ! childProcess ) {
680  PrintEndStats(inputFrameBits, numBits);
681  }
682  } else {
683  time(&timeEnd);
685 
686  if ( ! childProcess ) {
687  PrintEndStats(inputFrameBits, 1);
688  }
689  }
690 
691  if ( FType_Type(realEnd) != 'i' ) {
693  }
694 
695  if ( (! childProcess) && showBitRatePerFrame )
697 
698 #ifdef BLEAH
699  if ( childProcess ) {
701  }
702 #endif
703 
704  if (! realQuiet) {
705  fprintf(stdout, "======FRAMES READ: %d\n", framesRead);
706  fflush(stdout);
707  }
708 
709  return diffTime;
710 }
711 
712 
713 /*===========================================================================*
714  *
715  * IncrementTCTime
716  *
717  * increment the tc time by one second (and update min, hrs if necessary)
718  * also increments totalFramesSent
719  *
720  * RETURNS: nothing
721  *
722  * SIDE EFFECTS: totalFramesSent, tc_pict, tc_sec, tc_min, tc_hrs, tc_extra
723  *
724  *===========================================================================*/
725 void
727 {
728  /* if fps = an integer, then tc_extra = 0 and is ignored
729 
730  otherwise, it is the number of extra 1/1001 frames we've passed by
731 
732  so far; for example, if fps = 24000/1001, then 24 frames = 24024/24000
733  seconds = 1 second + 24/24000 seconds = 1 + 1/1000 seconds; similary,
734  if fps = 30000/1001, then 30 frames = 30030/30000 = 1 + 1/1000 seconds
735  and if fps = 60000/1001, then 60 frames = 1 + 1/1000 seconds
736 
737  if fps = 24000/1001, then 1/1000 seconds = 24/1001 frames
738  if fps = 30000/1001, then 1/1000 seconds = 30/1001 frames
739  if fps = 60000/1001, then 1/1000 seconds = 60/1001 frames
740  */
741 
742  totalFramesSent++;
743  tc_pict++;
744  if ( tc_pict >= frameRateRounded ) {
745  tc_pict = 0;
746  tc_sec++;
747  if ( tc_sec == 60 ) {
748  tc_sec = 0;
749  tc_min++;
750  if ( tc_min == 60 ) {
751  tc_min = 0;
752  tc_hrs++;
753  }
754  }
755  if ( ! frameRateInteger ) {
757  if ( tc_extra >= 1001 ) { /* a frame's worth */
758  tc_pict++;
759  tc_extra -= 1001;
760  }
761  }
762  }
763 }
764 
765 
766 /*===========================================================================*
767  *
768  * SetStatFileName
769  *
770  * set the statistics file name
771  *
772  * RETURNS: nothing
773  *
774  * SIDE EFFECTS: statFileName
775  *
776  *===========================================================================*/
777 void
779  char *fileName;
780 {
782 }
783 
784 
785 /*===========================================================================*
786  *
787  * SetGOPSize
788  *
789  * set the GOP size (frames per GOP)
790  *
791  * RETURNS: nothing
792  *
793  * SIDE EFFECTS: gopSize
794  *
795  *===========================================================================*/
796 void
798  int size;
799 {
800  gopSize = size;
801 }
802 
803 
804 /*===========================================================================*
805  *
806  * PrintStartStats
807  *
808  * print out the starting statistics (stuff from the param file)
809  * firstFrame, lastFrame represent the first, last frames to be
810  * encoded
811  *
812  * RETURNS: nothing
813  *
814  * SIDE EFFECTS: none
815  *
816  *===========================================================================*/
817 void
818 PrintStartStats(firstFrame, lastFrame)
819  int firstFrame;
820  int lastFrame;
821 {
822  FILE *fpointer;
823  register int i;
824  char inputFileName[1024];
825 
826  if ( statFileName[0] == '\0' ) {
827  statFile = NULL;
828  } else {
829  statFile = fopen(statFileName, "a"); /* open for appending */
830  if ( statFile == NULL ) {
831  fprintf(stderr, "ERROR: Could not open stat file: %s\n", statFileName);
832  fprintf(stderr, " Sending statistics to stdout only.\n");
833  fprintf(stderr, "\n\n");
834  } else if (! realQuiet) {
835  fprintf(stdout, "Appending statistics to file: %s\n", statFileName);
836  fprintf(stdout, "\n\n");
837  }
838  }
839 
840  for ( i = 0; i < 2; i++ ) {
841  if ( ( i == 0 ) && (! realQuiet) ) {
842  fpointer = stdout;
843  } else if ( statFile != NULL ) {
844  fpointer = statFile;
845  } else {
846  continue;
847  }
848 
849  fprintf(fpointer, "MPEG ENCODER STATS (%s)\n",VERSION);
850  fprintf(fpointer, "------------------------\n");
851  fprintf(fpointer, "TIME STARTED: %s", ctime(&timeStart));
852  if ( getenv("HOST") != NULL ) {
853  fprintf(fpointer, "MACHINE: %s\n", getenv("HOST"));
854  } else {
855  fprintf(fpointer, "MACHINE: unknown\n");
856  }
857 
858  if ( stdinUsed ) {
859  fprintf(fpointer, "INPUT: stdin\n");
860  }
861 
862 
863  if ( firstFrame == -1 ) {
864  fprintf(fpointer, "OUTPUT: %s\n", outputFileName);
865  } else if ( ! stdinUsed ) {
866  GetNthInputFileName(inputFileName, firstFrame);
867  fprintf(fpointer, "FIRST FILE: %s/%s\n", currentPath, inputFileName);
868  GetNthInputFileName(inputFileName, lastFrame);
869  fprintf(fpointer, "LAST FILE: %s/%s\n", currentPath,
870  inputFileName);
871  }
872  if ( resizeFrame )
873  fprintf(fpointer, "RESIZED TO: %dx%d\n",
875  fprintf(fpointer, "PATTERN: %s\n", framePattern);
876  fprintf(fpointer, "GOP_SIZE: %d\n", gopSize);
877  fprintf(fpointer, "SLICES PER FRAME: %d\n", slicesPerFrame);
879  fprintf(fpointer, "RANGE: +/-%d\n", searchRangeP/2);
880  else fprintf(fpointer, "RANGES: +/-%d %d\n",
882  fprintf(fpointer, "PIXEL SEARCH: %s\n", pixelFullSearch ? "FULL" : "HALF");
883  fprintf(fpointer, "PSEARCH: %s\n", PSearchName());
884  fprintf(fpointer, "BSEARCH: %s\n", BSearchName());
885  fprintf(fpointer, "QSCALE: %d %d %d\n", qscaleI,
886  GetPQScale(), GetBQScale());
887  if (specificsOn)
888  fprintf(fpointer, "(Except as modified by Specifics file)\n");
889  if ( referenceFrame == DECODED_FRAME ) {
890  fprintf(fpointer, "REFERENCE FRAME: DECODED\n");
891  } else if ( referenceFrame == ORIGINAL_FRAME ) {
892  fprintf(fpointer, "REFERENCE FRAME: ORIGINAL\n");
893  } else {
894  fprintf(stderr, "ERROR: Illegal referenceFrame!!!\n");
895  exit(1);
896  }
897  /* For new Rate control parameters */
898  if (getRateMode() == FIXED_RATE) {
899  fprintf(fpointer, "PICTURE RATE: %d\n", frameRateRounded);
900  if (getBitRate() != -1) {
901  fprintf(fpointer, "\nBIT RATE: %d\n", getBitRate());
902  }
903  if (getBufferSize() != -1) {
904  fprintf(fpointer, "BUFFER SIZE: %d\n", getBufferSize());
905  }
906  }
907  }
908  if (! realQuiet) {
909  fprintf(stdout, "\n\n");
910  }
911 }
912 
913 
914 /*===========================================================================*
915  *
916  * NonLocalRefFrame
917  *
918  * decides if this frame can be referenced from a non-local process
919  *
920  * RETURNS: TRUE or FALSE
921  *
922  * SIDE EFFECTS: none
923  *
924  *===========================================================================*/
925 boolean
927  int id;
928 {
929  int lastIPid;
930  int nextIPid;
931 
932  if ( ! childProcess ) {
933  return FALSE;
934  }
935 
936  lastIPid = FType_PastRef(id);
937 
938  /* might be accessed by B-frame */
939  if ( lastIPid+1 < realStart ) {
940  return TRUE;
941  }
942 
943  /* if B-frame is out of range, then current frame can be ref'd by it */
944  nextIPid = FType_FutureRef(id);
945 
946  /* might be accessed by B-frame */
947  if ( nextIPid-1 > realEnd ) {
948  return TRUE;
949  }
950 
951  /* might be accessed by P-frame */
952  if ( (nextIPid > realEnd) && (FType_Type(nextIPid) == 'p') ) {
953  return TRUE;
954  }
955 
956  return FALSE;
957 }
958 
959 
960 
961 /*===========================================================================*
962  *
963  * SetFrameRate
964  *
965  * sets global frame rate variables. value passed is MPEG frame rate code.
966  *
967  * RETURNS: TRUE or FALSE
968  *
969  * SIDE EFFECTS: frameRateRounded, frameRateInteger
970  *
971  *===========================================================================*/
972 void
974 {
975  switch(frameRate) {
976  case 1:
977  frameRateRounded = 24;
979  break;
980  case 2:
981  frameRateRounded = 24;
983  break;
984  case 3:
985  frameRateRounded = 25;
987  break;
988  case 4:
989  frameRateRounded = 30;
991  break;
992  case 5:
993  frameRateRounded = 30;
995  break;
996  case 6:
997  frameRateRounded = 50;
999  break;
1000  case 7:
1001  frameRateRounded = 60;
1003  break;
1004  case 8:
1005  frameRateRounded = 60;
1007  break;
1008  }
1009  printf("frame rate(%d) set to %d\n", frameRate, frameRateRounded);
1010 }
1011 
1012 
1013 /*=====================*
1014  * INTERNAL PROCEDURES *
1015  *=====================*/
1016 
1017 /*===========================================================================*
1018  *
1019  * ComputeDHMSTime
1020  *
1021  * turn some number of seconds (someTime) into a string which
1022  * summarizes that time according to scale (days, hours, minutes, or
1023  * seconds)
1024  *
1025  * RETURNS: nothing
1026  *
1027  * SIDE EFFECTS: none
1028  *
1029  *===========================================================================*/
1030 static void
1031 ComputeDHMSTime(someTime, timeText)
1032  int32 someTime;
1033  char *timeText;
1034 {
1035  int days, hours, mins, secs;
1036 
1037  days = someTime / (24*60*60);
1038  someTime -= days*24*60*60;
1039  hours = someTime / (60*60);
1040  someTime -= hours*60*60;
1041  mins = someTime / 60;
1042  secs = someTime - mins*60;
1043 
1044  if ( days > 0 ) {
1045  sprintf(timeText, "Total time: %d days and %d hours", days, hours);
1046  } else if ( hours > 0 ) {
1047  sprintf(timeText, "Total time: %d hours and %d minutes", hours, mins);
1048  } else if ( mins > 0 ) {
1049  sprintf(timeText, "Total time: %d minutes and %d seconds", mins, secs);
1050  } else {
1051  sprintf(timeText, "Total time: %d seconds", secs);
1052  }
1053 }
1054 
1055 
1056 /*===========================================================================*
1057  *
1058  * ComputeGOPFrames
1059  *
1060  * calculate the first, last frames of the numbered GOP
1061  *
1062  * RETURNS: lastFrame, firstFrame changed
1063  *
1064  * SIDE EFFECTS: none
1065  *
1066  *===========================================================================*/
1067 static void
1068 ComputeGOPFrames(whichGOP, firstFrame, lastFrame, numFrames)
1069  int whichGOP;
1070  int *firstFrame;
1071  int *lastFrame;
1072  int numFrames;
1073 {
1074  int passedB;
1075  int currGOP;
1076  int gopNum, frameNum;
1077 
1078  /* calculate first, last frames of whichGOP GOP */
1079 
1080  *firstFrame = -1;
1081  *lastFrame = -1;
1082  gopNum = 0;
1083  frameNum = 0;
1084  passedB = 0;
1085  currGOP = 0;
1086  while ( *lastFrame == -1 ) {
1087  if ( frameNum >= numFrames ) {
1088  fprintf(stderr, "ERROR: There aren't that many GOPs!\n");
1089  exit(1);
1090  }
1091 
1092 #ifdef BLEAH
1093 if (! realQuiet) {
1094 fprintf(stdout, "GOP STARTS AT %d\n", frameNum-passedB);
1095 }
1096 #endif
1097 
1098  if ( gopNum == whichGOP ) {
1099  *firstFrame = frameNum;
1100  }
1101 
1102  /* go past one gop */
1103  /* must go past at least one frame */
1104  do {
1105  currGOP += (1 + passedB);
1106 
1107  frameNum++;
1108 
1109  passedB = 0;
1110  while ( (frameNum < numFrames) && (FType_Type(frameNum) == 'b') ) {
1111  frameNum++;
1112  passedB++;
1113  }
1114  } while ( (frameNum < numFrames) &&
1115  ((FType_Type(frameNum) != 'i') || (currGOP < gopSize)) );
1116 
1117  currGOP -= gopSize;
1118 
1119  if ( gopNum == whichGOP ) {
1120  *lastFrame = (frameNum-passedB-1);
1121  }
1122 
1123 #ifdef BLEAH
1124 if (! realQuiet) {
1125 fprintf(stdout, "GOP ENDS at %d\n", frameNum-passedB-1);
1126 }
1127 #endif
1128 
1129  gopNum++;
1130  }
1131 }
1132 
1133 
1134 /*===========================================================================*
1135  *
1136  * PrintEndStats
1137  *
1138  * print end statistics (summary, time information)
1139  *
1140  * RETURNS: nothing
1141  *
1142  * SIDE EFFECTS: none
1143  *
1144  *===========================================================================*/
1145 static void
1146 PrintEndStats(inputFrameBits, totalBits)
1147  int inputFrameBits;
1148  int32 totalBits;
1149 {
1150  FILE *fpointer;
1151  register int i;
1152  char timeText[256];
1153  float totalCPU;
1154 
1155  if (! realQuiet) {
1156  fprintf(stdout, "\n\n");
1157  }
1158 
1159  ComputeDHMSTime(diffTime, timeText);
1160 
1161  for ( i = 0; i < 2; i++ ) {
1162  if ( ( i == 0 ) && (! realQuiet) ) {
1163  fpointer = stdout;
1164  } else if ( statFile != NULL ) {
1165  fpointer = statFile;
1166  } else {
1167  continue;
1168  }
1169 
1170  fprintf(fpointer, "TIME COMPLETED: %s", ctime(&timeEnd));
1171  fprintf(fpointer, "%s\n\n", timeText);
1172 
1173  totalCPU = 0.0;
1174  totalCPU += ShowIFrameSummary(inputFrameBits, totalBits, fpointer);
1175  totalCPU += ShowPFrameSummary(inputFrameBits, totalBits, fpointer);
1176  totalCPU += ShowBFrameSummary(inputFrameBits, totalBits, fpointer);
1177  fprintf(fpointer, "---------------------------------------------\n");
1178  fprintf(fpointer, "Total Compression: %3d:1 (%9.4f bpp)\n",
1179  framesOutput*inputFrameBits/totalBits,
1180  24.0*(float)(totalBits)/(float)(framesOutput*inputFrameBits));
1181  if (diffTime > 0) {
1182  fprintf(fpointer, "Total Frames Per Second: %f (%ld mps)\n",
1183  (float)framesOutput/(float)diffTime,
1184  (long)((float)framesOutput*(float)inputFrameBits/(256.0*24.0*(float)diffTime)));
1185  } else {
1186  fprintf(fpointer, "Total Frames Per Second: Infinite!\n");
1187  }
1188  if ( totalCPU == 0.0 ) {
1189  fprintf(fpointer, "CPU Time: NONE!\n");
1190  } else {
1191  fprintf(fpointer, "CPU Time: %f fps (%ld mps)\n",
1192  (float)framesOutput/totalCPU,
1193  (long)((float)framesOutput*(float)inputFrameBits/(256.0*24.0*totalCPU)));
1194  }
1195  fprintf(fpointer, "Total Output Bit Rate (%d fps): %d bits/sec\n",
1197  fprintf(fpointer, "MPEG file created in : %s\n", outputFileName);
1198  fprintf(fpointer, "\n\n");
1199 
1200  if ( computeMVHist ) {
1201  ShowPMVHistogram(fpointer);
1202  ShowBBMVHistogram(fpointer);
1203  ShowBFMVHistogram(fpointer);
1204  }
1205  }
1206 
1207  if ( statFile != NULL ) {
1208  fclose(statFile);
1209  }
1210 }
1211 
1212 
1213 /*===========================================================================*
1214  *
1215  * ProcessRefFrame
1216  *
1217  * process an I or P frame -- encode it, and process any B frames that
1218  * we can now
1219  *
1220  * RETURNS: nothing
1221  *
1222  * SIDE EFFECTS: stuff appended to bb
1223  *
1224  *===========================================================================*/
1225 static void
1226  ProcessRefFrame(frame, bb, lastFrame, outputFileName)
1227 MpegFrame *frame;
1228 BitBucket *bb;
1229 int lastFrame;
1230 char *outputFileName;
1231 {
1232  MpegFrame *bFrame = NULL;
1233  char fileName[1024];
1234  char inputFileName[1024];
1235  FILE *fpointer = NULL;
1236  boolean separateFiles;
1237  int id;
1238  time_t tempTimeStart, tempTimeEnd;
1239 
1240  separateFiles = (bb == NULL);
1241 
1242  if ( separateFiles && (frame->id >= realStart) &&
1243  (frame->id <= realEnd) ) {
1244  if ( remoteIO ) {
1245  bb = Bitio_New(NULL);
1246  } else {
1247  sprintf(fileName, "%s.frame.%d", outputFileName, frame->id);
1248  if ( (fpointer = fopen(fileName, "wb")) == NULL ) {
1249  fprintf(stderr, "ERROR: Could not open output file(1): %s\n",
1250  fileName);
1251  exit(1);
1252  }
1253 
1254  bb = Bitio_New(fpointer);
1255  }
1256  }
1257 
1258  /* nothing to do */
1259  if ( frame->id < realStart ) {
1260  return;
1261  }
1262 
1263  /* first, output this frame */
1264  if ( frame->type == TYPE_IFRAME ) {
1265 
1266 #ifdef BLEAH
1267  fprintf(stdout, "I-frame %d, currentGOP = %d\n",
1268  frame->id, currentGOP);
1269  fflush(stdout);
1270 #endif
1271 
1272  /* only start a new GOP with I */
1273  /* don't start GOP if only doing frames */
1274  if ( (! separateFiles) && (currentGOP >= gopSize) ) {
1275  int closed;
1276  static int num_gop = 0;
1277 
1278  /* first, check to see if closed GOP */
1279  if ( totalFramesSent == frame->id || pastRefFrame == NULL) {
1280  closed = 1;
1281  } else {
1282  closed = 0;
1283  }
1284 
1285  /* new GOP */
1286  if (num_gop != 0 && mult_seq_headers && num_gop % mult_seq_headers == 0) {
1287  if (! realQuiet) {
1288  fprintf(stdout, "Creating new Sequence before GOP %d\n", num_gop);
1289  fflush(stdout);
1290  }
1291 
1293  /* pratio */ aspectRatio,
1294  /* pict_rate */ frameRate, /* bit_rate */ bit_rate,
1295  /* buf_size */ buf_size, /* c_param_flag */ 1,
1296  /* iq_matrix */ customQtable, /* niq_matrix */ customNIQtable,
1297  /* ext_data */ NULL, /* ext_data_size */ 0,
1298  /* user_data */ NULL, /* user_data_size */ 0);
1299  }
1300 
1301  if (! realQuiet) {
1302  fprintf(stdout, "Creating new GOP (closed = %c) before frame %d\n",
1303  "FT"[closed], frame->id);
1304  fflush(stdout);
1305  }
1306 
1307  num_gop++;
1308  Mhead_GenGOPHeader(bb, /* drop_frame_flag */ 0,
1310  closed, /* broken_link */ 0,
1311  /* ext_data */ NULL, /* ext_data_size */ 0,
1312  /* user_data */ NULL, /* user_data_size */ 0);
1313  currentGOP -= gopSize;
1314  if (pastRefFrame == NULL) {
1315  SetGOPStartTime(0);
1316  } else {
1318  }
1319  }
1320 
1321  if ( (frame->id >= realStart) && (frame->id <= realEnd) ) {
1322  GenIFrame(bb, frame);
1323 
1324  framesOutput++;
1325 
1326  if ( separateFiles ) {
1327  if ( remoteIO ) {
1328  SendRemoteFrame(frame->id, bb);
1329  } else {
1330  Bitio_Flush(bb);
1331  fclose(fpointer);
1332  }
1333  }
1334  }
1335 
1336  numI--;
1337  timeMask &= 0x6;
1338 
1339  currentGOP++;
1340  IncrementTCTime();
1341  } else {
1342  if ( (frame->id >= realStart) && (frame->id <= realEnd) ) {
1343  GenPFrame(bb, frame, pastRefFrame);
1344 
1345  framesOutput++;
1346 
1347  if ( separateFiles ) {
1348  if ( remoteIO ) {
1349  SendRemoteFrame(frame->id, bb);
1350  } else {
1351  Bitio_Flush(bb);
1352  fclose(fpointer);
1353  }
1354  }
1355  }
1356 
1357  numP--;
1358  timeMask &= 0x5;
1360 
1361  currentGOP++;
1362  IncrementTCTime();
1363  }
1364 
1365  /* now, output B-frames */
1366  if ( pastRefFrame != NULL ) {
1367  for ( id = pastRefFrame->id+1; id < futureRefFrame->id; id++ ) {
1368  if ( ! ((id >= realStart) && (id <= realEnd)) )
1369  continue;
1370 
1371  if ( ! stdinUsed ) {
1372  bFrame = Frame_New(id, 'b');
1373 
1374  time(&tempTimeStart);
1375 
1376  /* read B frame, output it */
1377  if ( remoteIO ) {
1378  GetRemoteFrame(bFrame, bFrame->id);
1379  } else {
1380  GetNthInputFileName(inputFileName, id);
1381  if ( childProcess && separateConversion ) {
1382  ReadFrame(bFrame, inputFileName, slaveConversion, TRUE);
1383  } else {
1384  ReadFrame(bFrame, inputFileName, inputConversion, TRUE);
1385  }
1386  }
1387 
1388  time(&tempTimeEnd);
1389  IOtime += (tempTimeEnd-tempTimeStart);
1390 
1391  framesRead++;
1392  } else {
1393 
1394  /* retrieve and remove B-frame from queue set up in
1395  * GenMPEGStream
1396  */
1397  bFrame = pastRefFrame->next;
1398  pastRefFrame->next = bFrame->next;
1399  }
1400 
1401 
1402  if ( separateFiles ) {
1403  if ( remoteIO ) {
1404  bb = Bitio_New(NULL);
1405  } else {
1406  sprintf(fileName, "%s.frame.%d", outputFileName,
1407  bFrame->id);
1408  if ( (fpointer = fopen(fileName, "wb")) == NULL ) {
1409  fprintf(stderr, "ERROR: Could not open output file(2): %s\n",
1410  fileName);
1411  exit(1);
1412  }
1413  bb = Bitio_New(fpointer);
1414  }
1415  }
1416 
1417  GenBFrame(bb, bFrame, pastRefFrame, futureRefFrame);
1418  framesOutput++;
1419 
1420  if ( separateFiles ) {
1421  if ( remoteIO ) {
1422  SendRemoteFrame(bFrame->id, bb);
1423  } else {
1424  Bitio_Flush(bb);
1425  fclose(fpointer);
1426  }
1427  }
1428 
1429  /* free this B frame right away */
1430  Frame_Free(bFrame);
1431 
1432  numB--;
1433  timeMask &= 0x3;
1435 
1436  currentGOP++;
1437  IncrementTCTime();
1438  }
1439  } else {
1440  /* SRS replicated code */
1441  for ( id = 0; id < futureRefFrame->id; id++ ) {
1442  if ( ! ((id >= realStart) && (id <= realEnd)) )
1443  continue;
1444 
1445  if ( ! stdinUsed ) {
1446  bFrame = Frame_New(id, 'b');
1447 
1448  time(&tempTimeStart);
1449 
1450  /* read B frame, output it */
1451  if ( remoteIO ) {
1452  GetRemoteFrame(bFrame, bFrame->id);
1453  } else {
1454  GetNthInputFileName(inputFileName, id);
1455  if ( childProcess && separateConversion ) {
1456  ReadFrame(bFrame, inputFileName, slaveConversion, TRUE);
1457  } else {
1458  ReadFrame(bFrame, inputFileName, inputConversion, TRUE);
1459  }
1460  }
1461 
1462  time(&tempTimeEnd);
1463  IOtime += (tempTimeEnd-tempTimeStart);
1464 
1465  framesRead++;
1466  } else {
1467 
1468  /* retrieve and remove B-frame from queue set up in
1469  * GenMPEGStream
1470  */
1471  printf("Yow, I doubt this works!\n");
1472  bFrame = pastRefFrame->next;
1473  pastRefFrame->next = bFrame->next;
1474  }
1475 
1476 
1477  if ( separateFiles ) {
1478  if ( remoteIO ) {
1479  bb = Bitio_New(NULL);
1480  } else {
1481  sprintf(fileName, "%s.frame.%d", outputFileName,
1482  bFrame->id);
1483  if ( (fpointer = fopen(fileName, "wb")) == NULL ) {
1484  fprintf(stderr, "ERROR: Could not open output file(2): %s\n",
1485  fileName);
1486  exit(1);
1487  }
1488  bb = Bitio_New(fpointer);
1489  }
1490  }
1491 
1492  GenBFrame(bb, bFrame, (MpegFrame *)NULL, futureRefFrame);
1493  framesOutput++;
1494 
1495  if ( separateFiles ) {
1496  if ( remoteIO ) {
1497  SendRemoteFrame(bFrame->id, bb);
1498  } else {
1499  Bitio_Flush(bb);
1500  fclose(fpointer);
1501  }
1502  }
1503 
1504  /* free this B frame right away */
1505  Frame_Free(bFrame);
1506 
1507  numB--;
1508  timeMask &= 0x3;
1510 
1511  currentGOP++;
1512  IncrementTCTime();
1513  }
1514 
1515  }
1516 
1517  /* now free previous frame, if there was one */
1518  if ( pastRefFrame != NULL ) {
1520  }
1521 
1522  /* note, we may still not free last frame if lastFrame is incorrect
1523  * (if the last frames are B frames, they aren't output!)
1524  */
1525 }
1526 
1527 
1528 /*===========================================================================*
1529  *
1530  * ShowRemainingTime
1531  *
1532  * print out an estimate of the time left to encode
1533  *
1534  * RETURNS: nothing
1535  *
1536  * SIDE EFFECTS: none
1537  *
1538  *===========================================================================*/
1539 static void
1541 {
1542  static int lastTime = 0;
1543  float total;
1544  time_t nowTime;
1545  float secondsPerFrame;
1546 
1547  if ( childProcess ) {
1548  return /* nothing */;
1549  }
1550 
1551  if ( numI + numP + numB == 0 ) { /* no time left */
1552  return /* nothing */ ;
1553  }
1554 
1555  if ( timeMask != 0 ) { /* haven't encoded all types yet */
1556  return /* nothing */ ;
1557  }
1558 
1559  time(&nowTime);
1560  secondsPerFrame = (nowTime-timeStart)/(float)framesOutput;
1561  total = secondsPerFrame*(float)(numI+numP+numB);
1562 
1563 #ifdef BLEAH
1564  float timeI, timeP, timeB;
1565 
1566  timeI = EstimateSecondsPerIFrame();
1567  timeP = EstimateSecondsPerPFrame();
1568  timeB = EstimateSecondsPerBFrame();
1569  total = (float)numI*timeI + (float)numP*timeP + (float)numB*timeB;
1570 #endif
1571 
1572  if ( (quietTime >= 0) && (! realQuiet) && (! stdinUsed) &&
1573  ((lastTime < (int)total) || ((lastTime-(int)total) >= quietTime) ||
1574  (lastTime == 0) || (quietTime == 0)) ) {
1575  if ( total > 270.0 ) {
1576  fprintf(stdout, "ESTIMATED TIME OF COMPLETION: %d minutes\n",
1577  ((int)total+30)/60);
1578  } else {
1579  fprintf(stdout, "ESTIMATED TIME OF COMPLETION: %d seconds\n",
1580  (int)total);
1581  }
1582 
1583  lastTime = (int)total;
1584  }
1585 }
1586 
1587 
1588 void
1589 ReadDecodedRefFrame(frame, frameNumber)
1590  MpegFrame *frame;
1591  int frameNumber;
1592 {
1593  FILE *fpointer;
1594  char fileName[256];
1595  int width, height;
1596  register int y;
1597 
1598  width = Fsize_x;
1599  height = Fsize_y;
1600 
1601  sprintf(fileName, "%s.decoded.%d", outputFileName, frameNumber);
1602  if (! realQuiet) {
1603  fprintf(stdout, "reading %s\n", fileName);
1604  fflush(stdout);
1605  }
1606 
1607  if ((fpointer = fopen(fileName, "rb")) == NULL) {
1608  sleep(1);
1609  if ((fpointer = fopen(fileName, "rb")) == NULL) {
1610  fprintf(stderr, "Cannot open %s\n", fileName);
1611  exit(1);
1612  }}
1613 
1614  Frame_AllocDecoded(frame, TRUE);
1615 
1616  for ( y = 0; y < height; y++ ) {
1617  if (fread(frame->decoded_y[y], 1, width, fpointer) != width) {
1618  fprintf(stderr, "Could not read enough bytes from %s\n", fileName);
1619  }
1620  }
1621 
1622  for (y = 0; y < (height >> 1); y++) { /* U */
1623  if (fread(frame->decoded_cb[y], 1, width >> 1, fpointer) != (width>>1)) {
1624  fprintf(stderr, "Could not read enough bytes from %s\n", fileName);
1625  }
1626  }
1627 
1628  for (y = 0; y < (height >> 1); y++) { /* V */
1629  if (fread(frame->decoded_cr[y], 1, width >> 1, fpointer) != (width>>1)) {
1630  fprintf(stderr, "Could not read enough bytes from %s\n", fileName);
1631  }
1632  }
1633 
1634  fclose(fpointer);
1635 }
1636 
1637 
1638 static void
1640 {
1642  if ( bitRateFile == NULL ) {
1643  fprintf(stderr, "ERROR: Could not open bit rate file: %s\n", bitRateFileName);
1644  fprintf(stderr, "\n\n");
1646  }
1647 }
1648 
1649 
1650 static void
1652 {
1653 #ifdef BLEAH
1654  char command[256];
1655 #endif
1656 
1658 #ifdef BLEAH
1659  sprintf(command, "sort -n %s > /tmp/fubahr", bitRateFileName);
1660  system(command);
1661  sprintf(command, "mv /tmp/fubahr %s", bitRateFileName);
1662  system(command);
1663 #endif
1664 }
#define width(a)
Definition: aptex-macros.h:198
#define type(a)
Definition: aptex-macros.h:171
#define closed
#define height(a)
Definition: aptex-macros.h:200
static int numFrames
Definition: bframe.c:142
void GenBFrame(BitBucket *bb, MpegFrame *curr, MpegFrame *prev, MpegFrame *next)
Definition: bframe.c:202
void ResetBFrameStats()
Definition: bframe.c:847
int GetBQScale()
Definition: bframe.c:829
float EstimateSecondsPerBFrame()
Definition: bframe.c:994
float ShowBFrameSummary(int inputFrameBits, int32 totalBits, FILE *fpointer)
Definition: bframe.c:872
char * BSearchName()
Definition: bsearch.c:175
@ FALSE
Definition: dd.h:101
@ TRUE
Definition: dd.h:102
static int id
Definition: bifont.c:66
#define fopen
Definition: xxstdio.h:21
#define fread
Definition: xxstdio.h:25
#define fflush
Definition: xxstdio.h:24
#define fgetc
Definition: xxstdio.h:26
int strcmp()
Definition: coll.cpp:143
int printf()
char * strcpy()
void Frame_Free(MpegFrame *frame)
Definition: frame.c:482
MpegFrame * Frame_New(int id, int type)
Definition: frame.c:501
boolean stdinUsed
Definition: param.c:281
void Frame_AllocDecoded(MpegFrame *frame, boolean makeReference)
Definition: frame.c:700
#define TYPE_IFRAME
Definition: frame.h:45
int searchRangeP
Definition: psearch.c:104
int specificsOn
Definition: param.c:273
boolean realQuiet
Definition: main.c:155
int quietTime
Definition: main.c:154
int slicesPerFrame
Definition: iframe.c:215
float ShowIFrameSummary(int inputFrameBits, int32 totalBits, FILE *fpointer)
Definition: iframe.c:668
void GenIFrame(BitBucket *bb, MpegFrame *mf)
Definition: iframe.c:397
#define ORIGINAL_FRAME
Definition: frames.h:121
#define DECODED_FRAME
Definition: frames.h:122
int qscaleI
Definition: iframe.c:214
int pixelFullSearch
Definition: psearch.c:103
int searchRangeB
Definition: frames.h:359
void GenPFrame(BitBucket *bb, MpegFrame *current, MpegFrame *prev)
Definition: pframe.c:205
float ShowPFrameSummary(int inputFrameBits, int32 totalBits, FILE *fpointer)
Definition: pframe.c:788
int FType_PastRef(int currFrameNum)
Definition: frametype.c:164
int FType_Type(int frameNum)
Definition: frametype.c:80
int FType_FutureRef(int currFrameNum)
Definition: frametype.c:127
void Fsize_Reset()
Definition: fsize.c:71
int Fsize_x
Definition: fsize.c:51
int Fsize_y
Definition: fsize.c:52
static int numBits
Definition: iframe.c:167
void PrintItoIBitRate(int numBits, int frameNum)
Definition: iframe.c:991
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p scientific i
Definition: afcover.h:80
void exit()
#define EOF
Definition: afmparse.c:59
kerning y
Definition: ttdriver.c:212
#define MAXPATHLEN
Definition: gd_intern.h:8
char * getenv()
static int frameStart
Definition: main.c:140
static int frameEnd
Definition: main.c:141
#define fclose
Definition: debug.h:100
#define system(p)
Definition: win32lib.h:269
#define write
Definition: win32lib.h:103
#define fprintf
Definition: mendex.h:64
#define malloc
Definition: alloca.c:91
long time_t
Definition: types.h:18
unsigned int sleep()
int stat(const char *path, struct stat *sbuf)
#define sprintf
Definition: snprintf.c:44
long int32
Definition: tiff.h:67
unsigned char uint8
Definition: tiff.h:60
#define int32
Definition: unibasics.h:50
void Mhead_GenSequenceEnder(BitBucket *bbPtr)
Definition: mheaders.c:537
void Mhead_GenGOPHeader(BitBucket *bbPtr, int32 drop_frame_flag, int32 tc_hrs, int32 tc_min, int32 tc_sec, int32 tc_pict, int32 closed_gop, int32 broken_link, uint8 *ext_data, int32 ext_data_size, uint8 *user_data, int32 user_data_size)
Definition: mheaders.c:557
void Mhead_GenSequenceHeader(BitBucket *bbPtr, uint32 hsize, uint32 vsize, int32 pratio, int32 pict_rate, int32 bit_rate, int32 buf_size, int32 c_param_flag, int32 *iq_matrix, int32 *niq_matrix, uint8 *ext_data, int32 ext_data_size, uint8 *user_data, int32 user_data_size)
Definition: mheaders.c:378
void SetGOPStartTime(int index)
Definition: mheaders.c:318
char * PSearchName(void)
Definition: psearch.c:253
int32 tc_extra
Definition: mpeg.c:191
static void ProcessRefFrame(MpegFrame *frame, BitBucket *bb, int lastFrame, char *outputFileName)
Definition: mpeg.c:1226
char bitRateFileName[256]
Definition: mpeg.c:197
static int framesRead
Definition: mpeg.c:204
time_t timeEnd
Definition: mpeg.c:198
void PrintStartStats(int firstFrame, int lastFrame)
Definition: mpeg.c:818
boolean NonLocalRefFrame(int id)
Definition: mpeg.c:926
FILE * bitRateFile
Definition: mpeg.c:200
#define VERSION
Definition: mpeg.c:157
static int32 diffTime
Definition: mpeg.c:172
char statFileName[256]
Definition: mpeg.c:196
static void CloseBitRateFile(void)
Definition: mpeg.c:1651
int referenceFrame
Definition: mpeg.c:203
char userDataFileName[]
Definition: param.c:272
static void ComputeDHMSTime(int32 someTime, char *timeText)
Definition: mpeg.c:1031
int outputWidth
Definition: param.c:263
static void OpenBitRateFile(void)
Definition: mpeg.c:1639
#define ASPECT_1
Definition: mpeg.c:165
int32 buf_size
Definition: mpeg.c:214
static int currentGOP
Definition: mpeg.c:175
int totalFramesSent
Definition: mpeg.c:192
static void ComputeGOPFrames(int whichGOP, int *firstFrame, int *lastFrame, int numFrames)
Definition: mpeg.c:1068
static void ShowRemainingTime(void)
Definition: mpeg.c:1540
int IOtime
Definition: noparallel.c:100
int32 bit_rate
Definition: mpeg.c:214
#define FPS_30
Definition: mpeg.c:164
MpegFrame * pastRefFrame
Definition: mpeg.c:205
static int realStart
Definition: mpeg.c:174
MpegFrame * futureRefFrame
Definition: mpeg.c:206
void ReadDecodedRefFrame(MpegFrame *frame, int frameNumber)
Definition: mpeg.c:1589
int yuvHeight
Definition: mpeg.c:193
int aspectRatio
Definition: mpeg.c:210
static void PrintEndStats(int inputFrameBits, int32 totalBits)
Definition: mpeg.c:1146
int mult_seq_headers
Definition: param.c:282
void SetFrameRate()
Definition: mpeg.c:973
void SetStatFileName(char *fileName)
Definition: mpeg.c:778
static int realEnd
Definition: mpeg.c:174
int32 tc_sec
Definition: mpeg.c:191
void SetGOPSize(int size)
Definition: mpeg.c:797
static int framesOutput
Definition: mpeg.c:173
int32 GenMPEGStream(int whichGOP, int frameStart, int frameEnd, qtable, niqtable, int numFrames, FILE *ofp, char *outputFileName)
Definition: mpeg.c:287
int realWidth
Definition: mpeg.c:194
static int numB
Definition: mpeg.c:177
char * framePattern
Definition: mpeg.c:201
int32 tc_hrs
Definition: mpeg.c:191
boolean resizeFrame
Definition: readframe.c:174
void IncrementTCTime()
Definition: mpeg.c:726
time_t timeStart
Definition: mpeg.c:198
int frameRateRounded
Definition: mpeg.c:208
static int numP
Definition: mpeg.c:177
int realHeight
Definition: mpeg.c:194
int gopSize
Definition: mpeg.c:190
int32 tc_pict
Definition: mpeg.c:191
boolean frameRateInteger
Definition: mpeg.c:209
int yuvWidth
Definition: mpeg.c:193
int outputHeight
Definition: mpeg.c:189
int framePatternLen
Definition: mpeg.c:202
char currentPath[1024]
Definition: mpeg.c:195
int frameRate
Definition: mpeg.c:207
void SetReferenceFrameType(char *type)
Definition: mpeg.c:248
void SetBitRateFileName(char *fileName)
Definition: mpeg.c:263
FILE * statFile
Definition: mpeg.c:199
static int timeMask
Definition: mpeg.c:176
int32 tc_min
Definition: mpeg.c:191
static int numI
Definition: mpeg.c:177
int32 qtable[]
Definition: postdct.c:145
int32 niqtable[]
Definition: opts.c:50
int32 * customQtable
Definition: postdct.c:167
int32 * customNIQtable
Definition: postdct.c:168
#define DBG_PRINT(x)
Definition: mtypes.h:117
int GetPQScale(void)
Definition: pframe.c:770
void GetRemoteDecodedRefFrame(MpegFrame *frame, int frameNumber)
Definition: noparallel.c:275
void NoteFrameDone(int frameStart, int frameEnd)
Definition: noparallel.c:161
void SendRemoteFrame(int frameNumber, BitBucket *bb)
Definition: noparallel.c:172
void WaitForDecodedFrame(int id)
Definition: noparallel.c:259
boolean remoteIO
Definition: noparallel.c:98
void GetRemoteFrame(MpegFrame *frame, int frameNumber)
Definition: noparallel.c:184
boolean separateConversion
Definition: noparallel.c:99
boolean childProcess
Definition: main.c:150
boolean showBitRatePerFrame
Definition: main.c:159
char inputConversion[1024]
Definition: param.c:265
char slaveConversion[1024]
Definition: param.c:267
char outputFileName[256]
Definition: param.c:262
void GetNthInputFileName(char *fileName, int n)
Definition: param.c:821
int whichGOP
Definition: main.c:149
boolean computeMVHist
Definition: main.c:160
#define MAXINT
Definition: pbmtoepsi.c:22
#define res(length)
Definition: picttoppm.c:287
#define fp
static int size
Definition: ppmlabel.c:24
#define _ANSI_ARGS_(x)
Definition: ppmtoeyuv.c:64
void Bitio_Flush(BitBucket *bbPtr)
Definition: bitio.c:299
BitBucket * Bitio_New(FILE *filePtr)
Definition: bitio.c:136
void ShowBFMVHistogram(FILE *fpointer)
Definition: psearch.c:975
void ResetIFrameStats(void)
Definition: iframe.c:646
void SetBlocksPerSlice(void)
Definition: iframe.c:336
void ShowBBMVHistogram(FILE *fpointer)
Definition: psearch.c:928
float EstimateSecondsPerPFrame(void)
Definition: pframe.c:852
void ShowPMVHistogram(FILE *fpointer)
Definition: psearch.c:883
float EstimateSecondsPerIFrame(void)
Definition: iframe.c:718
void ResetPFrameStats(void)
Definition: pframe.c:726
time_t time()
char * ctime()
int getBitRate()
Definition: rate.c:863
int initRateControl()
Definition: rate.c:218
int getRateMode()
Definition: rate.c:806
int getBufferSize()
Definition: rate.c:916
#define FIXED_RATE
Definition: rate.h:22
void ReadFrame(MpegFrame *frame, char *fileName, char *conversion, boolean addPath)
Definition: readframe.c:231
void SetFileType(char *conversion)
Definition: readframe.c:421
int cumulativeBits
Definition: bitio.h:93
Definition: utils.c:99
int id
Definition: frame.h:57
struct mpegFrame * next
Definition: frame.h:95
uint8 ** decoded_cr
Definition: frame.h:77
int type
Definition: frame.h:55
uint8 ** decoded_cb
Definition: frame.h:77
uint8 ** decoded_y
Definition: frame.h:77
Definition: sh2.c:920
#define FILE
Definition: t1stdio.h:34
#define ungetc(c, f)
Definition: t1stdio.h:106
*job_name strlen((char *) job_name) - 4)
return() int(((double) *(font_tbl[cur_fnt].wtbl+(int)(*(font_tbl[cur_fnt].char_wi+(int)(ch - font_tbl[cur_fnt].char_f)% 256)))/(double)(1L<< 20)) *(double) font_tbl[cur_fnt].scale)
FILE * ofp
Definition: t1asm.c:89
const char * fileName
Definition: ugrep.cpp:52
#define hours
Definition: utmscale.cpp:21
#define days
Definition: utmscale.cpp:22
#define userData
Definition: xmlparse.c:555