1 
2 /*
3  *  inptstrm.hpp:  Input stream classes for MPEG multiplexing
4  *
5  *  Copyright (C) 2001 Andrew Stevens <andrew.stevens@philips.com>
6  *
7  *
8  *  This program is free software; you can redistribute it and/or
9  *  modify it under the terms of version 2 of the GNU General Public License
10  *  as published by the Free Software Foundation.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20  */
21 
22 #ifndef __INPUTSTRM_H__
23 #define __INPUTSTRM_H__
24 
25 #include <stdio.h>
26 #include <vector>
27 #include <sys/stat.h>
28 
29 #include "mjpeg_types.h"
30 #include "mpegconsts.h"
31 #include "format_codes.h"
32 #include "mjpeg_logging.h"
33 
34 #include "mplexconsts.hpp"
35 #include "bits.hpp"
36 #include "aunitbuffer.hpp"
37 #include "decodebufmodel.hpp"
38 
39 using std::vector;
40 
41 class InputStream
42 {
43 public:
InputStream(IBitStream & istream)44 	InputStream( IBitStream &istream ) :
45 		stream_length(0),
46         bs( istream ),
47 		eoscan(false),
48 		last_buffered_AU(0),
49 		decoding_order(0),
50 		old_frames(0)
51 		{}
52 
SetBufSize(unsigned int buf_size)53 	void SetBufSize( unsigned int buf_size )
54 		{
55 			bs.SetBufSize( buf_size );
56 		}
57 
58     bitcount_t stream_length;
59 
60 protected:
61 	off_t      file_length;
62     IBitStream &bs;
63 	bool eoscan;
64 
65 	unsigned int last_buffered_AU;		// decode seq num of last buffered frame + 1
66    	bitcount_t AU_start;
67     uint32_t  syncword;
68     bitcount_t prev_offset;
69     unsigned int decoding_order;
70     unsigned int old_frames;
71 
72 };
73 
74 class Multiplexor;
75 
76 
77 class MuxStream
78 {
79 public:
80 	MuxStream();
81 
82     void Init( const int strm_id,
83                const unsigned int _buf_scale,
84 			   const unsigned int buf_size,
85 			   const unsigned int _zero_stuffing,
86 			   const bool bufs_in_first,
87 			   const bool always_bufs
88 		  );
89 
90 	unsigned int BufferSizeCode();
BufferSize()91 	inline unsigned int BufferSize() { return buffer_size; }
BufferScale()92 	inline unsigned int BufferScale() { return buffer_scale; }
93 
94 
SetMaxPacketData(unsigned int max)95 	inline void SetMaxPacketData( unsigned int max )
96 		{
97 			max_packet_data = max;
98 		}
SetMinPacketData(unsigned int min)99 	inline void SetMinPacketData( unsigned int min )
100 		{
101 			min_packet_data = min;
102 		}
MaxPacketData()103 	inline unsigned int MaxPacketData() { return max_packet_data; }
MinPacketData()104 	inline unsigned int MinPacketData() { return min_packet_data; }
NewAUNextSector()105     inline bool NewAUNextSector() { return new_au_next_sec; }
106 
107 	//
108 	//  Read the next packet payload (sub-stream headers plus
109 	//  parsed and spliced stream data) for a packet with the
110 	//  specified payload capacity.  Update the AU info.
111 	//
112 
113 	virtual unsigned int ReadPacketPayload(uint8_t *dst, unsigned int to_read) = 0;
114 
115     //
116     // Return the size of the substream headers...
117     //
StreamHeaderSize()118     virtual unsigned int StreamHeaderSize() { return 0; }
119 
120 public:  // TODO should go protected once encapsulation complete
121 	int        stream_id;
122 	unsigned int    buffer_scale;
123 	unsigned int 	buffer_size;
124 	DecodeBufModel  bufmodel;
125 	unsigned int 	max_packet_data;
126 	unsigned int	min_packet_data;
127 	unsigned int    zero_stuffing;
128 	unsigned int    nsec;
129     unsigned int    min_pes_header_len;
130 	bool buffers_in_header;
131 	bool always_buffers_in_header;
132 	bool new_au_next_sec;
133 	bool init;
134 };
135 
136 class DummyMuxStream : public MuxStream
137 {
138 public:
DummyMuxStream(const int strm_id,const unsigned int buf_scale,unsigned int buf_size)139     DummyMuxStream( const int strm_id,
140                     const unsigned int buf_scale,
141                     unsigned int buf_size )
142         {
143             stream_id = strm_id;
144             buffer_scale = buf_scale;
145             buffer_size = buf_size;
146         }
147 
ReadPacketPayload(uint8_t * dst,unsigned int to_read)148     unsigned int ReadPacketPayload(uint8_t *dst, unsigned int to_read)
149         {
150             abort();
151             return 0;
152         }
153 };
154 
155 
156 class ElementaryStream : public InputStream,
157 						 public MuxStream
158 {
159 public:
160 	enum stream_kind { audio, video, dummy };
161 	ElementaryStream( IBitStream &ibs,
162                       Multiplexor &into,
163 					  stream_kind kind
164 					  );
~ElementaryStream()165     virtual ~ElementaryStream () { }
166 	virtual void Close() = 0;
167 
168 	bool NextAU();
169 	AUnit *Lookahead( unsigned int n = 0);
170 	unsigned int BytesToMuxAUEnd(unsigned int sector_transport_size);
171 	bool MuxCompleted();
172 	virtual bool MuxPossible(clockticks currentSCR );
173 	void DemuxedTo( clockticks SCR );
174 	void SetTSOffset( clockticks baseTS );
175 	void AllDemuxed();
Kind()176 	inline stream_kind Kind() { return kind; }
BufferMin()177     inline unsigned int BufferMin() { return buffer_min; }
BufferMax()178     inline unsigned int BufferMax() { return buffer_max; }
BaseDTS()179     inline clockticks BaseDTS() { return au->DTS; };
BasePTS()180     inline clockticks BasePTS() { return au->PTS; };
181 
DecodeOrder()182     inline int        DecodeOrder() { return au->dorder; }
183 
RequiredDTS(const AUnit * unit)184     inline clockticks RequiredDTS( const AUnit *unit )
185         { return unit->DTS + timestamp_delay; };
RequiredPTS(const AUnit * unit)186     inline clockticks RequiredPTS( const AUnit *unit )
187         { return unit->PTS + timestamp_delay; };
RequiredDTS()188     inline clockticks RequiredDTS()
189         { return RequiredDTS(au); };
RequiredPTS()190     inline clockticks RequiredPTS()
191         { return  RequiredPTS(au); };
NextRequiredDTS()192     inline clockticks NextRequiredDTS()
193         {
194             AUnit *next = Lookahead();
195             if( next != 0 )
196                 return RequiredDTS(next);
197             else
198                 return 0;
199         };
NextRequiredPTS()200     inline clockticks NextRequiredPTS()
201         {
202             AUnit *next = Lookahead();
203             if( next != 0 )
204                 return RequiredPTS(next);
205             else
206                 return 0;
207         };
208 
209     void UpdateBufferMinMax();
210 
211 	void SetSyncOffset( clockticks timestamp_delay );
212 
213 	void BufferAndOutputSector();
214 
BuffersInHeader()215 	inline bool BuffersInHeader() { return buffers_in_header; }
216 	virtual unsigned int NominalBitRate() = 0;
217 	virtual bool RunOutComplete() = 0;
218 
219 
220     /******************************************************************
221      *  Reads the stream data from actual input stream, updates decode
222      *  buffer model and current access unit information from the
223      *  look-ahead scanning buffer to account for bytes_muxed bytes being
224      *  muxed out.
225      * TODO: No longer needs to be virtual
226      *
227      ******************************************************************/
228 	virtual unsigned int ReadPacketPayload(uint8_t *dst, unsigned int to_read);
229 
230     /********************************************************************
231      * Update stream-specific mux state information to reflect muxing of
232      * current AU.  first_in_sector is set true if AU is first muxed into
233      * the current sector.
234      *
235      *******************************************************************/
236 
AUMuxed(bool first_in_sector)237     virtual void AUMuxed( bool first_in_sector ) {}
238 
239     /**************************************************************
240      * The size of the stream-specific  sub-header (if any)
241      *************************************************************/
StreamHeaderSize()242     virtual unsigned int StreamHeaderSize() { return 0; }
243 
244     /*****************************************************************
245      * Reads/generates the stream-specific sub-header for AUs muxed
246      * since last call AUMuxed( true );
247      ****************************************************************/
248 
ReadStreamHeader(uint8_t * dst,unsigned int len)249     virtual void ReadStreamHeader( uint8_t *dst, unsigned int len ) {}
250 
251     bitcount_t bytes_read;
252 private:
253     void AUBufferLookaheadFill( unsigned int look_ahead);
254 
255 //protected:
256 public:
257 	virtual void FillAUbuffer(unsigned int frames_to_buffer) = 0;
258     virtual void OutputSector() = 0;
259 	AUStream aunits;
260 	void Muxed( unsigned int bytes_muxed );
261 	AUnit *au;
262 	clockticks timestamp_delay;
263 
264 	unsigned int au_unsent;
265 	AUnit *OLDnext();
266 	Multiplexor &muxinto;
267 	stream_kind kind;
268     unsigned int buffer_min;
269     unsigned int buffer_max;
270     int FRAME_CHUNK;
271 
272 };
273 
274 
275 
276 #endif // __INPUTSTRM_H__
277 
278 
279 /*
280  * Local variables:
281  *  c-file-style: "stroustrup"
282  *  tab-width: 4
283  *  indent-tabs-mode: nil
284  * End:
285  */
286