/* * inptstrm.hh: Input stream classes for MPEG multiplexing * TODO: Split into the base classes and the different types of * actual input stream. * * Copyright (C) 2001 Andrew Stevens * * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public License * as published by the Free Software Foundation. * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef __INPUTSTRM_H__ #define __INPUTSTRM_H__ #include #include #include #include #include "mjpeg_types.h" #include "mpegconsts.h" #include "format_codes.h" #include "mjpeg_logging.h" #include "mplexconsts.hh" #include "bits.hh" #include "aunit.hh" #include "vector.hh" #include "buffer.hh" class InputStream { public: InputStream (IBitStream & istream):bs (istream), eoscan (false), stream_length (0), last_buffered_AU (0), decoding_order (0), old_frames (0) { } void SetBufSize (unsigned int buf_size) { bs.SetBufSize (buf_size); } protected: IBitStream & bs; bool eoscan; bitcount_t stream_length; off_t file_length; unsigned int last_buffered_AU; // decode seq num of last buffered frame + 1 bitcount_t AU_start; uint32_t syncword; bitcount_t prev_offset; unsigned int decoding_order; unsigned int old_frames; }; // // Abstract forward reference... // class OutputStream; class MuxStream { public: MuxStream (); void Init (const int strm_id, const unsigned int _buf_scale, const unsigned int buf_size, const unsigned int _zero_stuffing, const bool bufs_in_first, const bool always_bufs); unsigned int BufferSizeCode (); inline unsigned int BufferSize () { return buffer_size; } inline unsigned int BufferScale () { return buffer_scale; } inline void SetMaxPacketData (unsigned int max) { max_packet_data = max; } inline void SetMinPacketData (unsigned int min) { min_packet_data = min; } inline unsigned int MaxPacketData () { return max_packet_data; } inline unsigned int MinPacketData () { return min_packet_data; } inline bool NewAUNextSector () { return new_au_next_sec; } // // Read the next packet payload (sub-stream headers plus // parsed and spliced stream data) for a packet with the // specified payload capacity. Update the AU info. // virtual unsigned int ReadPacketPayload (uint8_t * dst, unsigned int to_read) = 0; // // Return the size of the substream headers... // virtual unsigned int StreamHeaderSize () { return 0; } public: // TODO should go protected once encapsulation complete int stream_id; unsigned int buffer_scale; unsigned int buffer_size; BufferModel bufmodel; unsigned int max_packet_data; unsigned int min_packet_data; unsigned int zero_stuffing; unsigned int nsec; bool buffers_in_header; bool always_buffers_in_header; bool new_au_next_sec; bool init; }; class DummyMuxStream:public MuxStream { public: DummyMuxStream (const int strm_id, const unsigned int buf_scale, unsigned int buf_size) { stream_id = strm_id; buffer_scale = buf_scale; buffer_size = buf_size; } unsigned int ReadPacketPayload (uint8_t * dst, unsigned int to_read) { abort (); return 0; } }; class ElementaryStream:public InputStream, public MuxStream { public: enum stream_kind { audio, video, dummy }; ElementaryStream (IBitStream & ibs, OutputStream & into, stream_kind kind); virtual void Close () = 0; bool NextAU (); Aunit *Lookahead (); unsigned int BytesToMuxAUEnd (unsigned int sector_transport_size); bool MuxCompleted (); virtual bool MuxPossible (clockticks currentSCR); void DemuxedTo (clockticks SCR); void SetTSOffset (clockticks baseTS); void AllDemuxed (); inline stream_kind Kind () { return kind; } inline int BufferMin () { return buffer_min; } inline int BufferMax () { return buffer_max; } inline clockticks RequiredDTS () { return au->DTS + timestamp_delay; }; inline clockticks RequiredPTS () { return au->PTS + timestamp_delay; }; inline clockticks NextRequiredDTS () { Aunit *next = Lookahead (); if (next != 0) return next->DTS + timestamp_delay; else return 0; }; inline clockticks NextRequiredPTS () { Aunit *next = Lookahead (); if (next != 0) return next->PTS + timestamp_delay; else return 0; }; void UpdateBufferMinMax (); void SetSyncOffset (clockticks timestamp_delay); inline bool BuffersInHeader () { return buffers_in_header; } virtual unsigned int NominalBitRate () = 0; virtual bool RunOutComplete () = 0; virtual void OutputSector () = 0; virtual unsigned int ReadPacketPayload (uint8_t * dst, unsigned int to_read); protected: virtual void FillAUbuffer (unsigned int frames_to_buffer) = 0; virtual void InitAUbuffer () = 0; virtual bool AUBufferNeedsRefill () = 0; AUStream aunits; void Muxed (unsigned int bytes_muxed); public: // TODO should go protected once encapsulation complete // N.b. currently length=0 is used to indicate an ended // stream. // au itself should simply disappear Aunit * au; clockticks timestamp_delay; protected: unsigned int au_unsent; Aunit *next (); OutputStream & muxinto; stream_kind kind; int buffer_min; int buffer_max; int FRAME_CHUNK; }; #endif // __INPUTSTRM_H__ /* * Local variables: * c-file-style: "stroustrup" * tab-width: 4 * indent-tabs-mode: nil * End: */