home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 9 / CD_ASCQ_09_1193.iso / news / 4441 / mpegcode / src / combine.c < prev    next >
C/C++ Source or Header  |  1993-09-27  |  11KB  |  425 lines

  1. /*===========================================================================*
  2.  * combine.c                                     *
  3.  *                                         *
  4.  *    Procedures to combine frames or GOPS into an MPEG sequence         *
  5.  *                                         *
  6.  * EXPORTED PROCEDURES:                                 *
  7.  *    GOPStoMPEG                                 *
  8.  *    FramesToMPEG                                 *
  9.  *                                         *
  10.  *===========================================================================*/
  11.  
  12. /*
  13.  * Copyright (c) 1993 The Regents of the University of California.
  14.  * All rights reserved.
  15.  *
  16.  * Permission to use, copy, modify, and distribute this software and its
  17.  * documentation for any purpose, without fee, and without written agreement is
  18.  * hereby granted, provided that the above copyright notice and the following
  19.  * two paragraphs appear in all copies of this software.
  20.  *
  21.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  22.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  23.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  24.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25.  *
  26.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  27.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  28.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  29.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  30.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  31.  */
  32.  
  33. /*  
  34.  *  $Header: /n/picasso/users/keving/encode/src/RCS/combine.c,v 1.1 1993/07/22 22:23:43 keving Exp keving $
  35.  *  $Log: combine.c,v $
  36.  * Revision 1.1  1993/07/22  22:23:43  keving
  37.  * nothing
  38.  *
  39.  */
  40.  
  41.  
  42. /*==============*
  43.  * HEADER FILES *
  44.  *==============*/
  45.  
  46. #include "all.h"
  47. #include <time.h>
  48. #include <errno.h>
  49. #include "mtypes.h"
  50. #include "frames.h"
  51. #include "search.h"
  52. #include "mpeg.h"
  53. #include "prototypes.h"
  54. #include "parallel.h"
  55. #include "param.h"
  56. #include "readframe.h"
  57. #include "mheaders.h"
  58. #include "fsize.h"
  59. #include "combine.h"
  60.  
  61.  
  62. static int    currentGOP;
  63.  
  64.  
  65. /*==================*
  66.  * GLOBAL VARIABLES *
  67.  *==================*/
  68. extern int  yuvWidth, yuvHeight;
  69. char    currentGOPPath[MAXPATHLEN];
  70. char    currentFramePath[MAXPATHLEN];
  71.  
  72.  
  73. /*===============================*
  74.  * INTERNAL PROCEDURE prototypes *
  75.  *===============================*/
  76.  
  77. static void    AppendFile _ANSI_ARGS_((FILE *outputFile, FILE *inputFile));
  78.  
  79.  
  80. /*=====================*
  81.  * EXPORTED PROCEDURES *
  82.  *=====================*/
  83.  
  84. /*===========================================================================*
  85.  *
  86.  * GOPStoMPEG
  87.  *
  88.  *    convert some number of GOP files into a single MPEG sequence file
  89.  *
  90.  * RETURNS:    nothing
  91.  *
  92.  * SIDE EFFECTS:    none
  93.  *
  94.  *===========================================================================*/
  95. void
  96. GOPStoMPEG(numGOPS, outputFileName, outputFilePtr)
  97.     int numGOPS;
  98.     char *outputFileName;
  99.     FILE *outputFilePtr;
  100. {
  101.     register int index;
  102.     BitBucket *bb;
  103.     char    fileName[1024];
  104.     char    inputFileName[1024];
  105.     FILE *inputFile;
  106.  
  107.     Fsize_Reset();
  108.     Fsize_Note(0, yuvWidth, yuvHeight);
  109.  
  110.     bb = Bitio_New(outputFilePtr);
  111.  
  112.     Mhead_GenSequenceHeader(bb, Fsize_x, Fsize_y, /* pratio */ 1,
  113.            /* pict_rate */ -1, /* bit_rate */ -1,
  114.            /* buf_size */ -1, /*c_param_flag */ 1,
  115.            /* iq_matrix */ NULL, /* niq_matrix */ NULL,
  116.            /* ext_data */ NULL, /* ext_data_size */ 0,
  117.            /* user_data */ NULL, /* user_data_size */ 0);
  118.  
  119.     /* it's byte-padded, so we can dump it now */
  120.     Bitio_Flush(bb);
  121.  
  122.     if ( numGOPS > 0 ) {
  123.     for ( index = 0; index < numGOPS; index++ ) {
  124.         GetNthInputFileName(inputFileName, index);
  125.         sprintf(fileName, "%s/%s", currentGOPPath, inputFileName);
  126.  
  127.         if ( (inputFile = fopen(fileName, "rb")) == NULL ) {
  128.         fprintf(stderr, "ERROR:  Couldn't read:  %s\n", fileName);
  129.         fflush(stderr);
  130.         exit(1);
  131.         }
  132.     
  133.         fprintf(stdout, "appending file:  %s\n", fileName);
  134.  
  135.         AppendFile(outputFilePtr, inputFile);
  136.     }
  137.     } else {
  138.     index = 0;
  139.     while ( TRUE ) {
  140.         sprintf(fileName, "%s.gop.%d", outputFileName, index);
  141.  
  142.         if ( (inputFile = fopen(fileName, "rb")) == NULL ) {
  143.         break;
  144.         }
  145.  
  146.         fprintf(stdout, "appending file:  %s\n", fileName);
  147.  
  148.         AppendFile(outputFilePtr, inputFile);
  149.  
  150.         index++;
  151.     }
  152.     }
  153.  
  154.     bb = Bitio_New(outputFilePtr);
  155.  
  156.     /* SEQUENCE END CODE */
  157.     Mhead_GenSequenceEnder(bb);
  158.  
  159.     Bitio_Flush(bb);
  160.  
  161.     fclose(outputFilePtr);
  162. }
  163.  
  164.  
  165. /*===========================================================================*
  166.  *
  167.  * FramestoMPEG
  168.  *
  169.  *    convert some number of frame files into a single MPEG sequence file
  170.  *
  171.  *    if parallel == TRUE, then when appending a file, blocks until that
  172.  *    file is actually ready
  173.  *
  174.  * RETURNS:    nothing
  175.  *
  176.  * SIDE EFFECTS:    none
  177.  *
  178.  *===========================================================================*/
  179. void
  180. FramesToMPEG(numFrames, outputFileName, outputFile, parallel)
  181.     int numFrames;
  182.     char *outputFileName;
  183.     FILE *outputFile;
  184.     boolean parallel;
  185. {
  186.     register int index;
  187.     BitBucket *bb;
  188.     char    fileName[1024];
  189.     char    inputFileName[1024];
  190.     FILE *inputFile;
  191.     FrameTable *entry, *ptr;
  192.  
  193.     tc_hrs = 0;    tc_min = 0; tc_sec = 0; tc_pict = 0;
  194.  
  195.     Fsize_Reset();
  196.     Fsize_Note(0, yuvWidth, yuvHeight);
  197.  
  198.     bb = Bitio_New(outputFile);
  199.     Mhead_GenSequenceHeader(bb, Fsize_x, Fsize_y, /* pratio */ 1,
  200.            /* pict_rate */ -1, /* bit_rate */ -1,
  201.            /* buf_size */ -1, /*c_param_flag */ 1,
  202.            /* iq_matrix */ NULL, /* niq_matrix */ NULL,
  203.            /* ext_data */ NULL, /* ext_data_size */ 0,
  204.            /* user_data */ NULL, /* user_data_size */ 0);
  205.     /* it's byte-padded, so we can dump it now */
  206.     Bitio_Flush(bb);
  207.  
  208.     /* need to do these in the right order!!! */
  209.     /* also need to add GOP headers */
  210.  
  211.     currentGOP = gopSize;
  212.     totalFramesSent = 0;
  213.  
  214.     if ( numFrames > 0 ) {
  215.     for ( index = 0; index < numFrames; index++ ) {
  216.         if ( FRAME_TYPE(index) == 'b' ) {
  217.         continue;
  218.         }
  219.  
  220.         if ( (FRAME_TYPE(index) == 'i') && (currentGOP >= gopSize) ) {
  221.         int closed;
  222.  
  223.         /* first, check to see if closed GOP */
  224.         if ( totalFramesSent == index ) {
  225.             closed = 1;
  226.         } else {
  227.             closed = 0;
  228.         }
  229.  
  230.         fprintf(stdout, "Creating new GOP (closed = %d) after %d frames\n",
  231.             closed, currentGOP);
  232.  
  233.         /* new GOP */
  234.         bb = Bitio_New(outputFile);
  235.         Mhead_GenGOPHeader(bb, /* drop_frame_flag */ 0,
  236.                tc_hrs, tc_min, tc_sec, tc_pict,
  237.                closed, /* broken_link */ 0,
  238.                /* ext_data */ NULL, /* ext_data_size */ 0,
  239.                /* user_data */ NULL, /* user_data_size */ 0);
  240.         Bitio_Flush(bb);
  241.         
  242.         currentGOP -= gopSize;
  243.         }
  244.  
  245.         if ( parallel ) {
  246.         WaitForOutputFile(index);
  247.         sprintf(fileName, "%s.frame.%d", outputFileName, index);
  248.         } else {
  249.         GetNthInputFileName(inputFileName, index);
  250.         sprintf(fileName, "%s/%s", currentFramePath, inputFileName);
  251.         }
  252.  
  253.         if ( (inputFile = fopen(fileName, "rb")) == NULL ) {
  254.         fprintf(stderr, "ERROR:  Couldn't read:  %s\n", fileName);
  255.         fflush(stderr);
  256.         exit(1);
  257.         }
  258.  
  259.         AppendFile(outputFile, inputFile);
  260.  
  261.         currentGOP++;
  262.         IncrementTCTime();
  263.  
  264.         if ( (index != 0) && ((index % framePatternLen) == 0) ) {
  265.         entry = &(frameTable[framePatternLen]);
  266.         } else {
  267.         entry = &(frameTable[index % framePatternLen]);
  268.         }
  269.  
  270.         /* now, follow nextOutput and output B-frames */
  271.         ptr = entry->nextOutput;
  272.         while ( ptr != NULL ) {
  273.         if ( parallel ) {
  274.             WaitForOutputFile(index - (entry->number - ptr->number));
  275.             sprintf(fileName, "%s.frame.%d", outputFileName,
  276.                 index - (entry->number - ptr->number));
  277.         } else {
  278.             GetNthInputFileName(inputFileName,
  279.                     index - (entry->number - ptr->number));
  280.             sprintf(fileName, "%s/%s", currentFramePath, inputFileName);
  281.         }
  282.  
  283.         if ( (inputFile = fopen(fileName, "rb")) == NULL ) {
  284.             fprintf(stderr, "ERROR:  Couldn't read:  %s\n", fileName);
  285.             exit(1);
  286.         }
  287.  
  288.         AppendFile(outputFile, inputFile);
  289.             
  290.         currentGOP++;
  291.         IncrementTCTime();
  292.  
  293.         ptr = ptr->nextOutput;
  294.         }
  295.     }
  296.     } else {
  297.     if ( parallel ) {
  298.         fprintf(stderr, "ERROR:  PARALLEL COMBINE WITH 0 FRAMES\n");
  299.         fprintf(stderr, "(please send bug report!)\n");
  300.         exit(1);
  301.     }
  302.  
  303.     index = 0;
  304.     while ( TRUE ) {
  305.         if ( FRAME_TYPE(index) == 'b' ) {
  306.         index++;
  307.         continue;
  308.         }
  309.  
  310.         if ( (FRAME_TYPE(index) == 'i') && (currentGOP >= gopSize) ) {
  311.         int closed;
  312.  
  313.         /* first, check to see if closed GOP */
  314.         if ( totalFramesSent == index ) {
  315.             closed = 1;
  316.         } else {
  317.             closed = 0;
  318.         }
  319.  
  320.         fprintf(stdout, "Creating new GOP (closed = %d) before frame %d\n",
  321.             closed, index);
  322.  
  323.         /* new GOP */
  324.         bb = Bitio_New(outputFile);
  325.         Mhead_GenGOPHeader(bb, /* drop_frame_flag */ 0,
  326.                tc_hrs, tc_min, tc_sec, tc_pict,
  327.                closed, /* broken_link */ 0,
  328.                /* ext_data */ NULL, /* ext_data_size */ 0,
  329.                /* user_data */ NULL, /* user_data_size */ 0);
  330.         Bitio_Flush(bb);
  331.         
  332.         currentGOP -= gopSize;
  333.         }
  334.  
  335.         sprintf(fileName, "%s.frame.%d", outputFileName, index);
  336.  
  337.         if ( (inputFile = fopen(fileName, "rb")) == NULL ) {
  338.         break;
  339.         }
  340.  
  341.         AppendFile(outputFile, inputFile);
  342.  
  343.         currentGOP++;
  344.         IncrementTCTime();
  345.  
  346.         if ( (index != 0) && ((index % framePatternLen) == 0) ) {
  347.         entry = &(frameTable[framePatternLen]);
  348.         } else {
  349.         entry = &(frameTable[index % framePatternLen]);
  350.         }
  351.  
  352.         /* now, follow nextOutput and output B-frames */
  353.         ptr = entry->nextOutput;
  354.         while ( ptr != NULL ) {
  355.         sprintf(fileName, "%s.frame.%d", outputFileName,
  356.             index - (entry->number - ptr->number));
  357.  
  358.         if ( (inputFile = fopen(fileName, "rb")) == NULL ) {
  359.             fprintf(stderr, "ERROR:  Couldn't read:  %s\n", fileName);
  360.             fflush(stderr);
  361.             exit(1);
  362.         }
  363.  
  364.         AppendFile(outputFile, inputFile);
  365.             
  366.         currentGOP++;
  367.         IncrementTCTime();
  368.  
  369.         ptr = ptr->nextOutput;
  370.         }
  371.  
  372.         index++;
  373.     }
  374.     }
  375.  
  376.     fprintf(stdout, "Wrote %d frames\n", totalFramesSent);
  377.     fflush(stdout);
  378.  
  379.     bb = Bitio_New(outputFile);
  380.  
  381.     /* SEQUENCE END CODE */
  382.     Mhead_GenSequenceEnder(bb);
  383.  
  384.     Bitio_Flush(bb);
  385.  
  386.     fclose(outputFile);
  387. }
  388.  
  389.  
  390. /*=====================*
  391.  * INTERNAL PROCEDURES *
  392.  *=====================*/
  393.  
  394. /*===========================================================================*
  395.  *
  396.  * AppendFile
  397.  *
  398.  *    appends the output file with the contents of the given input file
  399.  *
  400.  * RETURNS:    nothing
  401.  *
  402.  * SIDE EFFECTS:    none
  403.  *
  404.  *===========================================================================*/
  405. static void
  406. AppendFile(outputFile, inputFile)
  407.     FILE *outputFile;
  408.     FILE *inputFile;
  409. {
  410.     uint8   *data[9999];
  411.     int        readItems;
  412.  
  413.     readItems = 9999;
  414.     while ( readItems == 9999 ) {
  415.     readItems = fread(data, sizeof(uint8), 9999, inputFile);
  416.     if ( readItems > 0 ) {
  417.         fwrite(data, sizeof(uint8), readItems, outputFile);
  418.     }
  419.     }
  420.  
  421.     fclose(inputFile);
  422. }
  423.  
  424.  
  425.