/* This is the main class structure for accessing mpeg streams. */ /* (c)1994 Alexis 'Milamber' Ashley */ /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __MPEG__ #define __MPEG__ #include "list.H" // This is a templated list class #include "frame.H" // This class defines what a YUV frame is. #include "bstream.H" // This class provides bit oriented file i/o #include "decoder.h" // This is the top level decoder file #include "encoders_frame.h" // This file holds the encoders structures #include class Mpeg { public: enum status { okay, file_not_found, invalid_file, end_of_file, bad_seek, bad_frame, out_of_memory, unknown_error, ABORT }; typedef unsigned long int abs_addr; struct hms_addr { unsigned short int hours; unsigned short int mins; unsigned short int secs; unsigned short int hsecs; }; Mpeg(void); // Default Class Constructor. ~Mpeg(void); // Class Destructor. status Open(const char *filename); // Opens an mpeg file for reading. status ParseFile(void); // Parses the file to allow the class // to build the required data structures. status Close(void); // Closes an mpeg file. status MakeNewFile(const char *filename); //Makes a new mpeg file from current data status Seek(abs_addr); // Moves pointer to the specified frame status Seek(hms_addr); // Moves pointer to the specified frame abs_addr GetPos_abs(void) const; // Returns current pointer as absolute addr hms_addr GetPos_hms(void) const; // Returns current pointer as h:m:s addr status NextFrame(void); // Moves pointer to the next frame status PreviousFrame(void); // Moves pointer to the previous frame status Read(frame &); // Reads a frame status Write(const frame &); // Overwrites the current frame status Undo(void); // Undoes the last write to current frame status Delete(void); // Deletes current frame status Insert(int no_of_frames, frame **); // Inserts a number of frames unsigned int Height(void) const; // Returns the height of the frames unsigned int Width(void) const; // Returns the width of the frames abs_addr Length(void) const; // Returns length of mpeg file, in frames hms_addr RunningTime(void) const; // Returns length of file in hms format int FrameRate(void) const; // Returns frame rate in frames per second void RegisterCallback(void (*call_back)(byte *,abs_addr), byte * const data); // The function specified will be called // at the end of every write operation, // and during file loads and saves private: /* ****** Private Structures ****** */ enum file_loc {MpegFile, TempFile}; // Where the frame can be found struct Fstruct { file_loc location; long list_pos; // Position in the Mpeg or temp list // this frame can be found at. frame *cache; // Holds frame if currently cached }; enum frame_type {Bad_Frame=0,I_Frame=1,P_Frame=2,B_Frame=3, D_Frame=4}; struct MpegFrame { frame_type type; // Frame type int temp_ref; // The frame's temporal reference unsigned long int file_pos; // The file pointer position }; struct TempFrame { unsigned long int file_pos; // The file pointer position file_loc prev_loc; // The frame's previous location long prev_list_pos; // The frame's previous position }; struct Ostruct { frame_type ftype; abs_addr pos; Fstruct FS; }; struct mpg_cache { long pos; frame *Frame; }; /* ****** Private data *********** */ VidStream *mpeg_stream; // This data structure is used by the decoder List FList; // This is a list of all frames List MList; // This is a list of the I, P & B frames in // the currently open mpeg file List TList; // This is a list of the YUV frames in the // temp file List OList; // This list is used during making a new file List frame_cache; // The list of currently cached frames fstream tio; // This class controls access to the temp file ibstream mio; // This class controls access to the mpeg file char *mpegname; // The name of the mpeg file char tempname[80]; // The name of the temp file long file_length; // The length of the (virtual) file, in frames long cache_size; // Number of frames that cache will fit static const int fps_table[16]; //The table of valid frames per second values static const int min_frame_type=1; // Min number for a valid frame type static const int max_frame_type=4; // Max number for a valid frame type static const frame_type FrameTypes[max_frame_type+1]; // The list of valid frame types static const long gopSize=10; // The number of frames between GOP headers static const int pattern_size=8; // The size of the IBBPBBI pattern static const char pattern[pattern_size]; // The IBBPBBI pattern static const int mpegcache_size=12; // The size of the mpeg frame cache mpg_cache MpegCache[mpegcache_size]; // The mpeg frame cache int cache_curpos; // Current position in the cache void (*callback)(byte *,abs_addr); // Stores the callback function byte *callback_data; // Points to the callback's data /* ********* Private Functions ************ */ status MpegRead(long int pos,frame &); // Reads a frame from the mpeg file status TempRead(long int pos,frame &); // Reads a frame from the temp file void CheckCache(void); // Makes room in cache for a frame void ConvertPictImage(PictImage *img,frame *Frame); // Converts decoder's // PictImage struct to frame class void WriteSequenceHeader(obstream *file); // Writes the sequence start header void WriteSequenceEnder(obstream *file); // Writes the sequence end header void WriteGOPHeader(obstream *file,long frame_no,int closed); // Writes a GOP header void SeekHeader(ibstream *file,long pos,long startcode); // Seeks to header 'startcode' long NextStartCode(ibstream *file); // Returns code of next start code void CopyOrEncodeFrame(obstream *file, Ostruct &OS, int temp_ref); // Chooses whether a frame should be // copied from the old mpeg, or encoded void CopyFrame(obstream *file, long in_file_pos, int temp_ref); // Copies 1 frame from mio to file, at in_file_pos void EncodeFrame(obstream *file, Ostruct OS, int temp_ref); // Encodes 1 frame to file void MakeEncoderFrame(EncoderMpegFrame *mf,Ostruct OS); }; #endif