| |
| /* |
| * 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 <andrew.stevens@philips.com> |
| * |
| * |
| * 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 <config.h> |
| #include <stdio.h> |
| #include <vector> |
| #include <sys/stat.h> |
| |
| #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: |
| */ |