1 /*
2  *  multiplexor.cpp:  Program/System stream Multiplex despatcher
3  *
4  *  Copyright (C) 2003 Andrew Stevens <andrew.stevens@philips.com>
5  *
6  *
7  *  This program is free software; you can redistribute it and/or
8  *  modify it under the terms of version 2 of the GNU General Public License
9  *  as published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  */
20 
21 #define STREAM_LOGGING
22 #include <config.h>
23 #include <math.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include <mjpeg_types.h>
28 #include <mjpeg_logging.h>
29 #include <format_codes.h>
30 
31 #include "interact.hpp"
32 #include "videostrm.hpp"
33 #include "stillsstream.hpp"
34 #include "audiostrm.hpp"
35 #ifdef ZALPHA
36 #include "zalphastrm.hpp"
37 #endif
38 #include "multiplexor.hpp"
39 
40 
41 /****************
42  *
43  * Constructor - sets up per-run stuff and initialised parameters
44  * that control syntax of generated stream from the job options set
45  * by the user.
46  *
47  ***************/
48 
Multiplexor(MultiplexJob & job,OutputStream & output)49 Multiplexor::Multiplexor(MultiplexJob &job, OutputStream &output)
50 {
51     underrun_ignore = 0;
52     underruns = 0;
53 	start_of_new_pack = false;
54     InitSyntaxParameters(job);
55     InitInputStreams(job);
56 
57     psstrm = new PS_Stream(mpeg, sector_size, output, max_segment_size );
58 
59 }
60 
61 
62 /******************************************************************
63  *
64  * Initialisation of stream syntax paramters based on selected user
65  * options.  Depending of mux_format some selections may only act as
66  * defaults or may simply be ignored if they are inconsistent with the
67  * selected output format.
68  *
69  ******************************************************************/
70 
71 
InitSyntaxParameters(MultiplexJob & job)72 void Multiplexor::InitSyntaxParameters(MultiplexJob &job)
73 {
74 	seg_starts_with_video = false;
75 	audio_buffer_size = 4 * 1024;
76     mux_format = job.mux_format;
77     vbr = job.VBR;
78     packets_per_pack = job.packets_per_pack;
79     data_rate = job.data_rate;
80     mpeg = job.mpeg;
81     always_sys_header_in_pack = job.always_system_headers;
82     sector_transport_size = job.sector_size;
83     sector_size = job.sector_size;
84 	split_at_seq_end = !job.multifile_segment;
85     workarounds = job.workarounds;
86     max_segment_size = static_cast<off_t>(job.max_segment_size)
87                        * static_cast<off_t>(1024 * 1024);
88     max_PTS = static_cast<clockticks>(job.max_PTS) * CLOCKS;
89 	video_delay = static_cast<clockticks>(job.video_offset);
90 	audio_delay = static_cast<clockticks>(job.audio_offset);
91  	switch( mux_format  )
92 	{
93 	case MPEG_FORMAT_VCD :
94 		data_rate = 75*2352;  			 /* 75 raw CD sectors/sec */
95 	case MPEG_FORMAT_VCD_NSR : /* VCD format, non-standard rate */
96 		mjpeg_info( "Selecting VCD output profile");
97 		video_buffers_iframe_only = false;
98 		mpeg = 1;
99 	 	packets_per_pack = 1;
100 	  	sys_header_in_pack1 = 0;
101 	  	always_sys_header_in_pack = 0;
102 	  	sector_transport_size = 2352;	      /* Each 2352 bytes with 2324 bytes payload */
103 	  	transport_prefix_sectors = 30;
104 	  	sector_size = 2324;
105 		buffers_in_video = 1;
106 		always_buffers_in_video = 0;
107 		buffers_in_audio = 1;   		// This is needed as otherwise we have
108 		always_buffers_in_audio = 1;	//  to stuff the packer header which
109                                         // must be 13 bytes for VCD audio
110 		vcd_zero_stuffing = 20;         // The famous 20 zero bytes for VCD
111                                         // audio sectors.
112 		dtspts_for_all_vau = false;
113 		sector_align_iframeAUs = false;
114         timestamp_iframe_only = false;
115 		seg_starts_with_video = true;
116         if( job.video_tracks == 0 )
117         {
118             mjpeg_info( "Audio-only VCD track - variable-bit-rate (VCD2.0)");
119             vbr = true;
120         }
121 		break;
122 
123 	case  MPEG_FORMAT_MPEG2 :
124 		mjpeg_info( "Selecting generic MPEG2 output profile");
125 		mpeg = 2;
126 	 	packets_per_pack = 1;
127 	  	sys_header_in_pack1 = 1;
128 	  	always_sys_header_in_pack = 0;
129 	  	sector_transport_size = 2048;	      /* Each 2352 bytes with 2324 bytes payload */
130 	  	transport_prefix_sectors = 0;
131 	  	sector_size = 2048;
132 		buffers_in_video = 1;
133 		always_buffers_in_video = 0;
134 		buffers_in_audio = 1;
135 		always_buffers_in_audio = 1;
136 		vcd_zero_stuffing = 0;
137 		vbr = true;
138         	dtspts_for_all_vau = 0;
139         	timestamp_iframe_only = false;
140         	video_buffers_iframe_only = false;
141 		break;
142 
143 	case MPEG_FORMAT_SVCD :
144 		data_rate = 150*2324;
145 
146 	case MPEG_FORMAT_SVCD_NSR :		/* Non-standard data-rate */
147 		mjpeg_info( "Selecting SVCD output profile");
148 		mpeg = 2;
149 	 	packets_per_pack = 1;
150 	  	sys_header_in_pack1 = 0;
151 	  	always_sys_header_in_pack = 0;
152 	  	sector_transport_size = 2324;
153 	  	transport_prefix_sectors = 0;
154 	  	sector_size = 2324;
155 		vbr = true;
156 		buffers_in_video = 1;
157 		always_buffers_in_video = 0;
158 		buffers_in_audio = 1;
159 		always_buffers_in_audio = 0;
160 		vcd_zero_stuffing = 0;
161         dtspts_for_all_vau = 0;
162 		sector_align_iframeAUs = true;
163 		seg_starts_with_video = true;
164         timestamp_iframe_only = false;
165         video_buffers_iframe_only = false;
166 		break;
167 
168 	case MPEG_FORMAT_VCD_STILL :
169 		data_rate = 75*2352;  			 /* 75 raw CD sectors/sec */
170 	  	vbr = false;
171 		mpeg = 1;
172 		split_at_seq_end = false;
173 	 	packets_per_pack = 1;
174 	  	sys_header_in_pack1 = 0;
175 	  	always_sys_header_in_pack = 0;
176 	  	sector_transport_size = 2352;	      /* Each 2352 bytes with 2324 bytes payload */
177 	  	transport_prefix_sectors = 0;
178 	  	sector_size = 2324;
179 		buffers_in_video = 1;
180 		always_buffers_in_video = 0;
181 		buffers_in_audio = 1;
182 		always_buffers_in_audio = 0;
183 		vcd_zero_stuffing = 20;
184 		dtspts_for_all_vau = 1;
185 		sector_align_iframeAUs = true;
186         timestamp_iframe_only = false;
187         video_buffers_iframe_only = false;
188 		break;
189 
190 	case MPEG_FORMAT_SVCD_STILL :
191 		mjpeg_info( "Selecting SVCD output profile");
192 		if( data_rate == 0 )
193 			data_rate = 150*2324;
194 		mpeg = 2;
195 	 	packets_per_pack = 1;
196 	  	sys_header_in_pack1 = 0;
197 	  	always_sys_header_in_pack = 0;
198 	  	sector_transport_size = 2324;
199 	  	transport_prefix_sectors = 0;
200 	  	sector_size = 2324;
201 		vbr = true;
202 		buffers_in_video = 1;
203 		always_buffers_in_video = 0;
204 		buffers_in_audio = 1;
205 		always_buffers_in_audio = 0;
206 		vcd_zero_stuffing = 0;
207         dtspts_for_all_vau = 0;
208 		sector_align_iframeAUs = true;
209         timestamp_iframe_only = false;
210         video_buffers_iframe_only = false;
211 		break;
212 
213     case MPEG_FORMAT_DVD :
214 		mjpeg_info( "Selecting generic DVD output profile (PROVISIONAL)");
215         if( data_rate == 0 )
216             data_rate = 1260000;
217 		mpeg = 2;
218 	 	packets_per_pack = 1;
219 	  	sys_header_in_pack1 = false; // Handle by control packets
220 	  	always_sys_header_in_pack = false;
221 	  	sector_transport_size = 2048;
222 	  	transport_prefix_sectors = 0;
223 	  	sector_size = 2048;
224 		buffers_in_video = true;
225 		always_buffers_in_video = false;
226 		buffers_in_audio = true;
227 		always_buffers_in_audio = false;
228 		vcd_zero_stuffing = 0;
229         dtspts_for_all_vau = 0;
230 		sector_align_iframeAUs = true;
231         timestamp_iframe_only = true;
232         video_buffers_iframe_only = true;
233 		vbr = true;
234         break;
235 
236     case MPEG_FORMAT_DVD_NAV :
237 		mjpeg_info( "Selecting dvdauthor DVD output profile");
238         if( data_rate == 0 )
239             data_rate = 1260000;
240 		mpeg = 2;
241 	 	packets_per_pack = 1;
242 	  	sys_header_in_pack1 = false; // Handle by control packets
243 	  	always_sys_header_in_pack = false;
244 	  	sector_transport_size = 2048;
245 	  	transport_prefix_sectors = 0;
246 	  	sector_size = 2048;
247 		buffers_in_video = true;
248 		always_buffers_in_video = false;
249 		buffers_in_audio = true;
250 		always_buffers_in_audio = false;
251 		vcd_zero_stuffing = 0;
252         dtspts_for_all_vau = 0;
253 		sector_align_iframeAUs = true;
254         timestamp_iframe_only = true;
255         video_buffers_iframe_only = true;
256 		vbr = true;
257         seg_starts_with_video = true; // Needs special NAV sector 1st!
258         break;
259 
260 	default : /* MPEG_FORMAT_MPEG1 - auto format MPEG1 */
261 		mjpeg_info( "Selecting generic MPEG1 output profile");
262 		//mpeg = 1;
263 		sys_header_in_pack1 = 1;
264 		transport_prefix_sectors = 0;
265 		buffers_in_video = 1;
266 		always_buffers_in_video = 1;
267 		buffers_in_audio = 0;
268 		always_buffers_in_audio = 1;
269 		vcd_zero_stuffing = 0;
270         dtspts_for_all_vau = 0;
271 		sector_align_iframeAUs = false;
272         timestamp_iframe_only = false;
273         video_buffers_iframe_only = false;
274 		break;
275 	}
276 }
277 
278 /**************************************
279  *
280  * Initialise the elementary stream readers / output sector formatter
281  * objects for the various kinds of input stream.
282  *
283  *************************************/
284 
InitInputStreams(MultiplexJob & job)285 void Multiplexor::InitInputStreams(MultiplexJob &job)
286 {
287     //
288     // S(VCD) Stills are sufficiently unusual to require their own
289     // special initialisation
290     //
291 	if( MPEG_STILLS_FORMAT(job.mux_format) )
292         InitInputStreamsForStills( job );
293     else
294         InitInputStreamsForVideo( job );
295 }
296 
InitInputStreamsForStills(MultiplexJob & job)297 void Multiplexor::InitInputStreamsForStills(MultiplexJob & job )
298 {
299 	std::vector<VideoParams *>::iterator vidparm = job.video_param.begin();
300     unsigned int frame_interval;
301     unsigned int i;
302     vector<JobStream *> video_strms;
303     job.GetInputStreams( video_strms, MPEG_VIDEO );
304     vector<JobStream *> mpa_strms;
305     job.GetInputStreams( mpa_strms, MPEG_AUDIO );
306 
307     switch( job.mux_format )
308     {
309     case MPEG_FORMAT_VCD_STILL :
310         mjpeg_info( "Multiplexing VCD stills: %d stills streams.", video_strms.size() );
311         {
312             frame_interval = 30; // 30 Frame periods
313             if( mpa_strms.size() > 0 && video_strms.size() > 2  )
314                 mjpeg_error_exit1("VCD stills: no more than two streams (one normal one hi-res) possible");
315 
316 
317             VCDStillsStream *str[2];
318 
319             for( i = 0; i< video_strms.size(); ++i )
320             {
321                 FrameIntervals *ints =
322                     new ConstantFrameIntervals( frame_interval );
323                 str[i] =
324                     new VCDStillsStream( *(video_strms[i]->bs),
325                                          new StillsParams( *vidparm, ints),
326                                          *this );
327                 estreams.push_back( str[i] );
328                 vstreams.push_back( str[i] );
329                 str[i]->Init();
330                 ++vidparm;
331             }
332             if( video_strms.size() == 2 )
333             {
334                 str[0]->SetSibling(str[1]);
335                 str[1]->SetSibling(str[0]);
336             }
337         }
338         break;
339     case MPEG_FORMAT_SVCD_STILL :
340         mjpeg_info( "Multiplexing SVCD stills: %d stills streams %d audio streams", video_strms.size(), mpa_strms.size() );
341         frame_interval = 30;
342         if( video_strms.size() > 1 )
343         {
344             mjpeg_error_exit1("SVCD stills streams may only contain a single video stream");
345         }
346         else if( video_strms.size() > 0 )
347         {
348             ConstantFrameIntervals *intervals;
349             StillsStream *str;
350             intervals = new ConstantFrameIntervals( frame_interval );
351             str = new StillsStream( *(video_strms[0]->bs),
352                                     new StillsParams( *vidparm, intervals ),
353                                     *this );
354             estreams.push_back( str );
355             vstreams.push_back( str );
356             str->Init();
357         }
358         for( i = 0 ; i < mpa_strms.size() ; ++i )
359         {
360             AudioStream *audioStrm = new MPAStream( *(mpa_strms[i]->bs), *this);
361             audioStrm->Init ( i);
362             estreams.push_back(audioStrm);
363             astreams.push_back(audioStrm);
364         }
365         break;
366     default:
367         mjpeg_error_exit1("Only VCD and SVCD stills format for the moment...");
368     }
369 
370 }
371 
InitInputStreamsForVideo(MultiplexJob & job)372 void Multiplexor::InitInputStreamsForVideo(MultiplexJob & job )
373 {
374     mjpeg_info( "Multiplexing video program stream!" );
375 
376     unsigned int audio_track = 0;
377     unsigned int video_track = 0;
378 	std::vector<VideoParams *>::iterator vidparm = job.video_param.begin();
379 	std::vector<LpcmParams *>::iterator lpcmparm = job.lpcm_param.begin();
380 
381 
382     std::vector<JobStream *>::iterator i;
383     for( i = job.streams.begin() ; i < job.streams.end() ; ++i )
384     {
385         switch( (*i)->kind )
386         {
387 
388         case MPEG_VIDEO :
389         {
390             VideoStream *videoStrm;
391             //
392             // The first video stream is made the master stream...
393             //
394             if( video_track == 0  && job.mux_format ==  MPEG_FORMAT_DVD_NAV )
395                 videoStrm = new DVDVideoStream( *(*i)->bs,
396                                                 *vidparm,
397                                                 *this);
398             else
399                     videoStrm = new VideoStream( *(*i)->bs,
400                                                  *vidparm,
401                                                  *this);
402             videoStrm->Init( video_track );
403             ++video_track;
404             ++vidparm;
405             estreams.push_back( videoStrm );
406             vstreams.push_back( videoStrm );
407         }
408         break;
409         case MPEG_AUDIO :
410         {
411             AudioStream *audioStrm = new MPAStream( *(*i)->bs, *this);
412             audioStrm->Init ( audio_track );
413             estreams.push_back(audioStrm);
414             astreams.push_back(audioStrm);
415            ++audio_track;
416         }
417         break;
418         case AC3_AUDIO :
419         {
420             AudioStream *audioStrm =  new AC3Stream( *(*i)->bs, *this);
421             audioStrm->Init ( audio_track );
422             estreams.push_back(audioStrm);
423             astreams.push_back(audioStrm);
424             ++audio_track;
425         }
426         break;
427         case DTS_AUDIO :
428         {
429             AudioStream *audioStrm = new DTSStream( *(*i)->bs, *this);
430             audioStrm->Init ( audio_track );
431             estreams.push_back(audioStrm);
432             astreams.push_back(audioStrm);
433             ++audio_track;
434         }
435         break;
436         case LPCM_AUDIO :
437         {
438             AudioStream *audioStrm =  new LPCMStream( *(*i)->bs, *lpcmparm, *this);
439             audioStrm->Init ( audio_track );
440             estreams.push_back(audioStrm);
441             astreams.push_back(audioStrm);
442             ++lpcmparm;
443             ++audio_track;
444         }
445         break;
446 #ifdef ZALPHA
447         // just copies the video parameters from the first video stream
448         case Z_ALPHA :
449         {
450             ZAlphaStream *zalphaStrm = new ZAlphaStream( *(*i)->bs, *(job.video_param.begin()), *this);
451             zalphaStrm->Init (0);
452             estreams.push_back(zalphaStrm);
453             vstreams.push_back(zalphaStrm);
454             //++vidparm;
455         }
456 #endif
457         }
458     }
459 }
460 
461 
462 /*******************************************************************
463 	Find the timecode corresponding to given position in the system stream
464    (assuming the SCR starts at 0 at the beginning of the stream
465 @param bytepos byte position in the stream
466 @param ts returns the number of clockticks the bytepos is from the file start
467 ****************************************************************** */
468 
ByteposTimecode(bitcount_t bytepos,clockticks & ts)469 void Multiplexor::ByteposTimecode(bitcount_t bytepos, clockticks &ts)
470 {
471 	ts = (bytepos*CLOCKS)/static_cast<bitcount_t>(dmux_rate);
472 }
473 
474 
475 /**********
476  *
477  * NextPosAndSCR - Update nominal (may be >= actual) byte count
478  * and SCR to next output sector.
479  *
480  ********/
481 
NextPosAndSCR()482 void Multiplexor::NextPosAndSCR()
483 {
484 	bytes_output += sector_transport_size;
485 	ByteposTimecode( bytes_output, current_SCR );
486     if (start_of_new_pack)
487     {
488         psstrm->CreatePack (&pack_header, current_SCR, mux_rate);
489         pack_header_ptr = &pack_header;
490         if( include_sys_header )
491             sys_header_ptr = &sys_header;
492         else
493             sys_header_ptr = NULL;
494 
495     }
496     else
497         pack_header_ptr = NULL;
498 }
499 
500 
501 /**********
502  *
503  * SetPosAndSCR - Update nominal (may be >= actual) byte count
504  * and SCR to next output sector.
505  * @param bytepos byte position in the stream
506  ********/
507 
SetPosAndSCR(bitcount_t bytepos)508 void Multiplexor::SetPosAndSCR( bitcount_t bytepos )
509 {
510 	bytes_output = bytepos;
511 	ByteposTimecode( bytes_output, current_SCR );
512     if (start_of_new_pack)
513     {
514         psstrm->CreatePack (&pack_header, current_SCR, mux_rate);
515         pack_header_ptr = &pack_header;
516         if( include_sys_header )
517             sys_header_ptr = &sys_header;
518         else
519             sys_header_ptr = NULL;
520 
521     }
522     else
523         pack_header_ptr = NULL;
524 }
525 
526 /*
527    Stream syntax parameters.
528 */
529 
530 
531 
532 
533 
534 typedef enum { start_segment, mid_segment,
535 			   runout_segment }
536 segment_state;
537 
538 
539 /**
540  * Compute the number of run-in sectors needed to fill up the buffers to
541  * suit the type of stream being muxed.
542  *
543  * For stills we have to ensure an entire buffer is loaded as we only
544  * ever process one frame at a time.
545  * @returns the number of run-in sectors needed to fill up the buffers to suit the type of stream being muxed.
546  */
547 
RunInSectors()548 unsigned int Multiplexor::RunInSectors()
549 {
550 	std::vector<ElementaryStream *>::iterator str;
551 	unsigned int sectors_delay = 1;
552 
553 	for( str = vstreams.begin(); str < vstreams.end(); ++str )
554 	{
555 
556 		if( MPEG_STILLS_FORMAT( mux_format ) )
557 		{
558 			sectors_delay += static_cast<unsigned int>(1.02*(*str)->BufferSize()) / sector_size+2;
559 		}
560 		else if( vbr )
561 			sectors_delay += 3*(*str)->BufferSize() / ( 4 * sector_size );
562 		else
563 			sectors_delay += 5 *(*str)->BufferSize() / ( 6 * sector_size );
564 	}
565     sectors_delay += astreams.size();
566 	return sectors_delay;
567 }
568 
569 /**********************************************************************
570  *
571  *  Initializes the output stream proper. Traverses the input files
572  *  and calculates their payloads.  Estimates the multiplex
573  *  rate. Estimates the necessary stream delay for the different
574  *  substreams.
575  *
576  *********************************************************************/
577 
578 
Init()579 void Multiplexor::Init()
580 {
581 	std::vector<ElementaryStream *>::iterator str;
582 	clockticks delay;
583 	unsigned int sectors_delay;
584 
585 	Pack_struc 			dummy_pack;
586 	Sys_header_struc 	dummy_sys_header;
587 	Sys_header_struc *sys_hdr;
588 	unsigned int nominal_rate_sum;
589 
590 	mjpeg_info("SYSTEMS/PROGRAM stream:");
591 	psstrm->Open();
592 
593     /* These are used to make (conservative) decisions
594 	   about whether a packet should fit into the recieve buffers...
595 	   Audio packets always have PTS fields, video packets needn'.
596 	   TODO: Really this should be encapsulated in Elementary stream...?
597 	*/
598 	psstrm->CreatePack (&dummy_pack, 0, mux_rate);
599 	if( always_sys_header_in_pack )
600 	{
601         vector<MuxStream *> muxstreams;
602         AppendMuxStreamsOf( estreams, muxstreams );
603 		psstrm->CreateSysHeader (&dummy_sys_header, mux_rate,
604 								 !vbr, 1,  true, true, muxstreams);
605 		sys_hdr = &dummy_sys_header;
606 	}
607 	else
608 		sys_hdr = NULL;
609 
610 	nominal_rate_sum = 0;
611 	for( str = estreams.begin(); str < estreams.end(); ++str )
612 	{
613 		switch( (*str)->Kind() )
614 		{
615 		case ElementaryStream::audio :
616 			(*str)->SetMaxPacketData(
617 				psstrm->PacketPayload( **str, NULL, NULL,
618 									   false, true, false )
619 				);
620 			(*str)->SetMinPacketData(
621 				psstrm->PacketPayload( **str, sys_hdr, &dummy_pack,
622 									   always_buffers_in_audio, true, false )
623 				);
624 
625 			break;
626 		case ElementaryStream::video :
627 			(*str)->SetMaxPacketData(
628 				psstrm->PacketPayload( **str, NULL, NULL,
629 									   false, false, false )
630 				);
631 			(*str)->SetMinPacketData(
632 				psstrm->PacketPayload( **str, sys_hdr, &dummy_pack,
633 									   always_buffers_in_video, true, true )
634 				);
635 			break;
636 		default :
637 			mjpeg_error_exit1("INTERNAL: Only audio and video payload calculations implemented!");
638 
639 		}
640 
641 		if( (*str)->NominalBitRate() == 0 && data_rate == 0)
642 			mjpeg_error_exit1( "Variable bit-rate stream present: output stream (max) data-rate *must* be specified!");
643 		nominal_rate_sum += (*str)->NominalBitRate();
644 	}
645 
646 	/* Attempt to guess a sensible mux rate for the given video and *
647 	 audio estreams. This is a rough and ready guess for MPEG-1 like
648 	 formats. */
649 
650 
651 	dmux_rate = static_cast<int>(1.0205 * nominal_rate_sum);
652 	dmux_rate = (dmux_rate/50 + 25)*50/8;
653 
654 	mjpeg_info ("rough-guess multiplexed stream data rate    : %07d", dmux_rate*8 );
655 	if( data_rate != 0 )
656 		mjpeg_info ("target data-rate specified               : %7d", data_rate*8 );
657 
658 	if( data_rate == 0 )
659 	{
660 		mjpeg_info( "Setting best-guess data rate.");
661 	}
662 	else if ( data_rate >= dmux_rate)
663 	{
664 		mjpeg_info( "Setting specified specified data rate: %7d", data_rate*8 );
665 		dmux_rate = data_rate;
666 	}
667 	else if ( data_rate < dmux_rate )
668 	{
669 		mjpeg_warn( "Target data rate lower than computed requirement!");
670 		mjpeg_warn( "N.b. a 20%% or so discrepancy in variable bit-rate");
671 		mjpeg_warn( "streams is common and harmless provided no time-outs will occur");
672 		dmux_rate = data_rate;
673 	}
674 
675 	mux_rate = dmux_rate/50;
676 
677 
678 	//
679 	// Now that all mux parameters are set we can trigger parsing
680 	// of actual input stream data and calculation of associated
681 	// PTS/DTS by causing the read of the first AU's...
682 	//
683 	for( str = estreams.begin(); str < estreams.end(); ++str )
684 	{
685 		(*str)->NextAU();
686 	}
687 
688     //
689     // Now that we have both output and input streams initialised and
690     // data-rates set we can make a decent job of setting the maximum
691     // STD buffer delay in video streams.
692     //
693 
694     for( str = vstreams.begin(); str < vstreams.end(); ++str )
695     {
696         static_cast<VideoStream*>(*str)->SetMaxStdBufferDelay( dmux_rate );
697     }
698 
699 	/* To avoid Buffer underflow, the DTS of the first video and audio AU's
700 	   must be offset sufficiently	forward of the SCR to allow the buffer
701 	   time to fill before decoding starts. Calculate the necessary delays...
702 	*/
703 
704 	sectors_delay = RunInSectors();
705 
706 	ByteposTimecode(
707 		static_cast<bitcount_t>(sectors_delay*sector_transport_size),
708 		delay );
709     video_delay += delay;
710     audio_delay += delay;
711 
712     /*
713      * The PTS of the first frame may be different from its DTS.
714      * Thus to hit perfect A/V sync we need to delay audio by the difference
715      * PTS-DTS.
716      *
717      */
718 
719     if(  vstreams.size() != 0 )
720     {
721         audio_delay += vstreams[0]->BasePTS()-vstreams[0]->BaseDTS();
722     }
723 
724 	mjpeg_info( "Run-in Sectors = %d Video delay = %lld Audio delay = %lld",
725 				sectors_delay,
726 				 video_delay / 300,
727 				 audio_delay / 300 );
728 
729     if( max_PTS != 0 )
730 
731         mjpeg_info( "Multiplexed stream will be ended at %lld seconds playback time\n", max_PTS/CLOCKS );
732 
733 }
734 
735 /**
736    Prints the current status of the substreams.
737    @param level the desired log level
738  */
MuxStatus(log_level_t level)739 void Multiplexor::MuxStatus(log_level_t level)
740 {
741 	std::vector<ElementaryStream *>::iterator str;
742 	for( str = estreams.begin(); str < estreams.end(); ++str )
743 	{
744 		switch( (*str)->Kind()  )
745 		{
746 		case ElementaryStream::video :
747 			mjpeg_log( level,
748 					   "Video %02x: buf=%7d frame=%06d sector=%08d",
749 					   (*str)->stream_id,
750 					   (*str)->BufferSize()-(*str)->bufmodel.Space(),
751 					   (*str)->DecodeOrder(),
752 					   (*str)->nsec
753 				);
754 			break;
755 		case ElementaryStream::audio :
756 			mjpeg_log( level,
757 					   "Audio %02x: buf=%7d frame=%06d sector=%08d",
758 					   (*str)->stream_id,
759 					   (*str)->BufferSize()-(*str)->bufmodel.Space(),
760 					   (*str)->DecodeOrder(),
761 					   (*str)->nsec
762 				);
763 			break;
764 		default :
765 			mjpeg_log( level,
766 					   "Other %02x: buf=%7d sector=%08d",
767 					   (*str)->stream_id,
768 					   (*str)->bufmodel.Space(),
769 					   (*str)->nsec
770 				);
771 			break;
772 		}
773 	}
774 	if( !vbr )
775 		mjpeg_log( level,
776 				   "Padding : sector=%08d",
777 				   pstrm.nsec
778 			);
779 
780 
781 }
782 
783 
784 /**
785    Append input substreams to the output multiplex stream.
786  */
AppendMuxStreamsOf(vector<ElementaryStream * > & elem,vector<MuxStream * > & mux)787 void Multiplexor::AppendMuxStreamsOf( vector<ElementaryStream *> &elem,
788                                        vector<MuxStream *> &mux )
789 {
790 	std::vector<ElementaryStream *>::iterator str;
791     for( str = elem.begin(); str < elem.end(); ++str )
792     {
793         mux.push_back( static_cast<MuxStream *>( *str ) );
794     }
795 }
796 
797 /******************************************************************
798     Program start-up packets.  Generate any irregular packets
799 needed at the start of the stream...
800 	Note: *must* leave a sensible in-stream system header in
801 	sys_header.
802 	TODO: get rid of this grotty sys_header global.
803 ******************************************************************/
OutputPrefix()804 void Multiplexor::OutputPrefix( )
805 {
806     vector<MuxStream *> vmux,amux,emux;
807     AppendMuxStreamsOf( vstreams, vmux );
808     AppendMuxStreamsOf( astreams, amux );
809     AppendMuxStreamsOf( estreams, emux );
810 
811 	/* Deal with transport padding */
812 	SetPosAndSCR( bytes_output +
813 				  transport_prefix_sectors*sector_transport_size );
814 
815 	/* VCD: Two padding packets with video and audio system headers */
816 
817 	switch (mux_format)
818 	{
819 	case MPEG_FORMAT_VCD :
820 	case MPEG_FORMAT_VCD_NSR :
821 
822 		/* Annoyingly VCD generates seperate system headers for
823 		   audio and video ... DOH... */
824 		if( astreams.size() > 1 || vstreams.size() > 1 ||
825 			astreams.size() + vstreams.size() != estreams.size() )
826 		{
827 				mjpeg_error_exit1("VCD man only have max. 1 audio and 1 video stream");
828 		}
829 
830         if( vstreams.size() > 0 )
831         {
832 		/* First packet carries video-info-only sys_header */
833 		psstrm->CreateSysHeader (&sys_header, mux_rate,
834 								 false, true,
835 								 true, true, vmux  );
836 		sys_header_ptr = &sys_header;
837 		pack_header_ptr = &pack_header;
838 	  	OutputPadding( false);
839         }
840 
841         if( astreams.size() > 0 )
842         {
843 
844             /* Second packet carries audio-info-only sys_header */
845             psstrm->CreateSysHeader (&sys_header, mux_rate,
846                                      false, true,
847                                      true, true, amux );
848             sys_header_ptr = &sys_header;
849             pack_header_ptr = &pack_header;
850             OutputPadding( true );
851         }
852         break;
853 
854 	case MPEG_FORMAT_SVCD :
855 	case MPEG_FORMAT_SVCD_NSR :
856 		/* First packet carries sys_header */
857 		psstrm->CreateSysHeader (&sys_header, mux_rate,  !vbr, true,
858                                  true, true, emux );
859 		sys_header_ptr = &sys_header;
860 		pack_header_ptr = &pack_header;
861 	  	OutputPadding(false);
862         break;
863 
864 	case MPEG_FORMAT_VCD_STILL :
865 		/* First packet carries small-still sys_header */
866 		/* TODO No support mixed-mode stills sequences... */
867 		psstrm->CreateSysHeader (&sys_header, mux_rate, false, false,
868 								 true, true, emux );
869 		sys_header_ptr = &sys_header;
870 		pack_header_ptr = &pack_header;
871 		OutputPadding(  false);
872         break;
873 
874 	case MPEG_FORMAT_SVCD_STILL :
875 		/* TODO: Video only at present */
876 		/* First packet carries video-info-only sys_header */
877 		psstrm->CreateSysHeader (&sys_header, mux_rate,
878 								 false, true,
879 								 true, true, vmux );
880 		sys_header_ptr = &sys_header;
881 		pack_header_ptr = &pack_header;
882 	  	OutputPadding( false);
883 		break;
884 
885     case MPEG_FORMAT_DVD_NAV :
886         /* A DVD System header is a weird thing.  We seem to need to
887            include buffer info about streams 0xb8, 0xb9, 0xbd, 0xbf even if
888            they're not physically present but the buffers for the actual
889            video streams aren't included.
890         */
891     {
892         // MANY DVD streams appear not to include system headers
893         // and some tools have weak parsers that can't handle all
894         // the possible variations. Soooo probably best not to generate
895         // them
896         DummyMuxStream dvd_0xb9_strm_dummy( 0xb9, 1, 232*1024 );
897         DummyMuxStream dvd_0xb8_strm_dummy( 0xb8, 0, 4096 );
898         DummyMuxStream dvd_0xbf_strm_dummy( 0xbf, 1, 2048 );
899         vector<MuxStream *> dvdmux;
900 		std::vector<MuxStream *>::iterator muxstr;
901         dvdmux.push_back( &dvd_0xb9_strm_dummy );
902         dvdmux.push_back( &dvd_0xb8_strm_dummy );
903         unsigned int max_priv1_buffer = 58*1024;
904         for( muxstr = amux.begin(); muxstr < amux.end(); ++muxstr )
905         {
906             // We mux *many* substreams on PRIVATE_STR_1
907             // we set the system header buffer size to the maximum
908             // of all those we find
909             if( (*muxstr)->stream_id == PRIVATE_STR_1 )
910             {
911                 if( (*muxstr)->BufferSize() > max_priv1_buffer )
912                     max_priv1_buffer = (*muxstr)->BufferSize();
913             }
914             // Now the *sane* thing to do if MPEG audio is present would be
915             // record this in the system header.  However, dvdauthor lacks
916             // a header parser and barfs if the system headers aren't exactly
917             // 18 bytes.  Soooo we simply skip them for now...
918             // TOOD: Add back in when dvdauthor can parse system headers
919             //else
920             //    dvdmux.push_back( *muxstr );
921         }
922 
923         DummyMuxStream dvd_priv1_strm_dummy( PRIVATE_STR_1, 1,
924                                              max_priv1_buffer );
925         dvdmux.push_back( &dvd_priv1_strm_dummy );
926 
927         dvdmux.push_back( &dvd_0xbf_strm_dummy );
928         psstrm->CreateSysHeader (&sys_header, mux_rate, !vbr, false,
929                                  true, true, dvdmux );
930         sys_header_ptr = &sys_header;
931         pack_header_ptr = &pack_header;
932         /* It is then followed up by a pair of PRIVATE_STR_2 packets which
933             we keep empty 'cos we don't know what goes there...
934         */
935     }
936     break;
937 
938     default :
939         /* Create the in-stream header in case it is needed */
940         psstrm->CreateSysHeader (&sys_header, mux_rate, !vbr, false,
941                                  true, true, emux );
942 
943 
944 	}
945 
946 
947 
948 }
949 
950 
951 
952 /******************************************************************
953     Program shutdown packets.  Generate any irregular packets
954     needed at the end of the stream...
955 
956 ******************************************************************/
957 
OutputSuffix()958 void Multiplexor::OutputSuffix()
959 {
960 	psstrm->CreatePack (&pack_header, current_SCR, mux_rate);
961 	psstrm->CreateSector (&pack_header, NULL,
962 						  0,
963 						  pstrm,
964 						  false,
965 						  true,
966 						  0, 0,
967 						  TIMESTAMPBITS_NO );
968 }
969 
970 /******************************************************************
971 
972 	Main multiplex iteration.
973 	Opens and closes all needed files and manages the correct
974 	call od the respective Video- and Audio- packet routines.
975 	The basic multiplexing is done here. Buffer capacity and
976 	Timestamp checking is also done here, decision is taken
977 	wether we should genereate a Video-, Audio- or Padding-
978 	packet.
979 ******************************************************************/
980 
981 
982 
Multiplex()983 void Multiplexor::Multiplex()
984 
985 {
986 	segment_state seg_state;
987 	std::vector<bool> completed;
988 	std::vector<bool>::iterator pcomp;
989 	std::vector<ElementaryStream *>::iterator str;
990 
991 	unsigned int packets_left_in_pack = 0; /* Suppress warning */
992 	bool padding_packet;
993 	bool video_first = true;
994 
995 	Init( );
996 
997 	unsigned int i;
998     for(i = 0; i < estreams.size() ; ++i )
999 		completed.push_back(false);
1000 
1001 
1002 	/*  Let's try to read in unit after unit and to write it out into
1003 		the outputstream. The only difficulty herein lies into the
1004 		buffer management, and into the fact the the actual access
1005 		unit *has* to arrive in time, that means the whole unit
1006 		(better yet, packet data), has to arrive before arrival of
1007 		DTS. If both buffers are full we'll generate a padding packet
1008 
1009 		Of course, when we start we're starting a new segment with no
1010 		bytes output...
1011 	*/
1012 
1013 	ByteposTimecode( sector_transport_size, ticks_per_sector );
1014 	seg_state = start_segment;
1015 	running_out = false;
1016 	for(;;)
1017 	{
1018 		bool completion = true;
1019 
1020 		for( str = estreams.begin(); str < estreams.end() ; ++str )
1021 			completion &= (*str)->MuxCompleted();
1022 		if( completion )
1023 			break;
1024 
1025 		/* A little state-machine for handling the transition from one
1026 		   segment to the next
1027 		*/
1028 		bool runout_incomplete;
1029 		VideoStream *master;
1030 		switch( seg_state )
1031 		{
1032 
1033 			/* Audio and slave video access units at end of segment.
1034 			   If there are any audio AU's whose PTS implies they
1035 			   should be played *before* the video AU starting the
1036 			   next segement is presented we mux them out.  Once
1037 			   they're gone we've finished this segment so we write
1038 			   the suffix switch file, and start muxing a new segment.
1039 			*/
1040 		case runout_segment :
1041 			runout_incomplete = false;
1042 			for( str = estreams.begin(); str < estreams.end(); ++str )
1043 			{
1044 				runout_incomplete |= !(*str)->RunOutComplete();
1045 			}
1046 
1047 			if( runout_incomplete )
1048 				break;
1049 
1050 			/* Otherwise we write the stream suffix and start a new
1051 			   stream file */
1052 			OutputSuffix();
1053 			psstrm->NextSegment();
1054 
1055 			running_out = false;
1056 			seg_state = start_segment;
1057 
1058 			/* Starting a new segment.
1059 			   We send the segment prefix, video and audio reciever
1060 			   buffers are assumed to start empty.  We reset the segment
1061 			   length count and hence the SCR.
1062 
1063 			*/
1064 
1065 		case start_segment :
1066 			mjpeg_info( "New sequence commences..." );
1067 			SetPosAndSCR(0);
1068 			MuxStatus( LOG_INFO );
1069 
1070 			for( str = estreams.begin(); str < estreams.end(); ++str )
1071 			{
1072 				(*str)->AllDemuxed();
1073 			}
1074 
1075 			packets_left_in_pack = packets_per_pack;
1076             start_of_new_pack = true;
1077 			include_sys_header = sys_header_in_pack1;
1078 			buffers_in_video = always_buffers_in_video;
1079 			video_first = seg_starts_with_video & (vstreams.size() > 0);
1080 			OutputPrefix();
1081 
1082 			/* Set the offset applied to the raw PTS/DTS of AU's to
1083                make the DTS of the first AU in the master (video) stream
1084                precisely the video delay plus whatever time we wasted in
1085                the sequence pre-amble.
1086 
1087                The DTS of the remaining streams are set so that
1088                (modulo the relevant delay offset) they maintain the
1089                same relative timing to the master stream.
1090 
1091 			*/
1092 
1093             clockticks ZeroSCR;
1094 
1095             if( vstreams.size() != 0 )
1096                 ZeroSCR = vstreams[0]->BaseDTS();
1097             else
1098                 ZeroSCR = estreams[0]->BaseDTS();
1099 
1100 			for( str = vstreams.begin(); str < vstreams.end(); ++str )
1101 				(*str)->SetSyncOffset(video_delay + current_SCR - ZeroSCR );
1102 			for( str = astreams.begin(); str < astreams.end(); ++str )
1103 				(*str)->SetSyncOffset(audio_delay + current_SCR - ZeroSCR );
1104 			pstrm.nsec = 0;
1105 			for( str = estreams.begin(); str < estreams.end(); ++str )
1106 				(*str)->nsec = 0;
1107 			seg_state = mid_segment;
1108 			break;
1109 
1110 		case mid_segment :
1111 			/* Once we exceed our file size limit, we need to
1112 			   start a new file soon.  If we want a single stream we
1113 			   simply switch.
1114 
1115 			   Otherwise we're in the last gop of the current segment
1116 			   (and need to start running streams out ready for a
1117 			   clean continuation in the next segment).
1118 			   TODO: runout_PTS really needs to be expressed in
1119 			   sync delay adjusted units...
1120 			*/
1121 
1122 			master =
1123 				vstreams.size() > 0 ?
1124 				static_cast<VideoStream*>(vstreams[0]) : 0 ;
1125 			if( psstrm->SegmentLimReached() )
1126 			{
1127 				if( split_at_seq_end )
1128                     mjpeg_warn( "File size exceeded before split-point in video stream" );
1129                 mjpeg_info( "Starting new output file...");
1130                 psstrm->NextSegment();
1131 			}
1132 			else if( master != 0 && master->SeqEndRunOut() )
1133 			{
1134                 const AUnit *nextIframe = master->NextIFrame();
1135 				if(  split_at_seq_end && nextIframe != 0)
1136 				{
1137 					runout_PTS = master->RequiredPTS(nextIframe);
1138                     mjpeg_info( "Sequence end marker! Running out...");
1139                     mjpeg_info("Run out PTS limit to AU %d %lld SCR=%lld",
1140                                nextIframe->dorder,
1141                                runout_PTS/300,
1142                                current_SCR/300 );
1143                     MuxStatus( LOG_INFO );
1144 					running_out = true;
1145 					seg_state = runout_segment;
1146 				}
1147                 else
1148                 {
1149                     mjpeg_warn( "Sequence end without following I-frame!" );
1150                 }
1151 			}
1152 			break;
1153 
1154 		}
1155 
1156 		padding_packet = false;
1157 		start_of_new_pack = (packets_left_in_pack == packets_per_pack);
1158 
1159 		for( str = estreams.begin(); str < estreams.end(); ++str )
1160 		{
1161 			(*str)->DemuxedTo(current_SCR);
1162 		}
1163 
1164 
1165 
1166 		//
1167 		// Find the ready-to-mux stream with the most urgent DTS
1168 		//
1169 		ElementaryStream *despatch = 0;
1170 		clockticks earliest = 0;
1171 		for( str = estreams.begin(); str < estreams.end(); ++str )
1172 		{
1173 #ifdef STREAM_LOGGING
1174             mjpeg_debug("%02x: SCR=%lld (%.3f) mux=%d %d reqDTS=%lld ",
1175                         (*str)->stream_id,
1176                         current_SCR,
1177                         static_cast<double>(current_SCR) /(90.0*300.0),
1178                         (*str)->MuxPossible(current_SCR),
1179                         (*str)->BufferSize()-(*str)->bufmodel.Space(),
1180                         (*str)->RequiredDTS()/300
1181 
1182 				);
1183 #endif
1184 			if( (*str)->MuxPossible(current_SCR) &&
1185 				( !video_first || (*str)->Kind() == ElementaryStream::video )
1186 				 )
1187 			{
1188 				if( despatch == 0 || earliest > (*str)->RequiredDTS() )
1189 				{
1190 					despatch = *str;
1191 					earliest = (*str)->RequiredDTS();
1192 				}
1193 			}
1194 		}
1195 
1196 		if( underrun_ignore > 0 )
1197 			--underrun_ignore;
1198 
1199 		if( despatch )
1200 		{
1201 			despatch->BufferAndOutputSector();
1202 			video_first = false;
1203 			if( current_SCR >=  earliest && underrun_ignore == 0)
1204 			{
1205 				mjpeg_warn( "Stream %02x: data will arrive too late sent(SCR)=%lld required(DTS)=%lld",
1206 							despatch->stream_id,
1207 							current_SCR/300,
1208 							earliest/300 );
1209 				MuxStatus( LOG_WARN );
1210 				// Give the stream a chance to recover
1211 				underrun_ignore = 300;
1212 				++underruns;
1213 				if( underruns > 10  )
1214 				{
1215 					//mjpeg_error_exit1("Too many frame drops -exiting" );
1216 				}
1217 			}
1218             if( despatch->nsec > 50 &&
1219                 despatch->Lookahead( ) != 0 && ! running_out)
1220                 despatch->UpdateBufferMinMax();
1221 			padding_packet = false;
1222 
1223 		}
1224 		else
1225 		{
1226             //
1227             // If we got here no stream could be muxed out.
1228             // We therefore generate padding packets if necessary
1229             // usually this is because reciever buffers are likely to be
1230             // full.
1231             //
1232             if( vbr )
1233             {
1234                 //
1235                 // VBR: For efficiency we bump SCR up to five times or
1236                 // until it looks like buffer status will change
1237                 NextPosAndSCR();
1238                 clockticks next_change = static_cast<clockticks>(0);
1239                 for( str = estreams.begin(); str < estreams.end(); ++str )
1240                 {
1241                     clockticks change_time = (*str)->bufmodel.NextChange();
1242                     if( next_change == 0 || change_time < next_change )
1243                     {
1244                         next_change = change_time;
1245                     }
1246                 }
1247 
1248                 unsigned int bumps = 5;
1249                 while( bumps > 0
1250                        && next_change > current_SCR + ticks_per_sector)
1251                 {
1252                     NextPosAndSCR();
1253                     --bumps;
1254                 }
1255 
1256             }
1257             else
1258             {
1259                 // Just output a padding packet
1260                 OutputPadding (	false);
1261             }
1262 			padding_packet = true;
1263 		}
1264 
1265 		/* Update the counter for pack packets.  VBR is a tricky
1266 		   case as here padding packets are "virtual" */
1267 
1268 		if( ! (vbr && padding_packet) )
1269 		{
1270 			--packets_left_in_pack;
1271 			if (packets_left_in_pack == 0)
1272 				packets_left_in_pack = packets_per_pack;
1273 		}
1274 
1275 		MuxStatus( LOG_DEBUG );
1276 		/* Unless sys headers are always required we turn them off after the first
1277 		   packet has been generated */
1278 		include_sys_header = always_sys_header_in_pack;
1279 
1280 		pcomp = completed.begin();
1281 		str = estreams.begin();
1282 		while( str < estreams.end() )
1283 		{
1284 			if( !(*pcomp) && (*str)->MuxCompleted() )
1285 			{
1286 				mjpeg_info( "STREAM %02x completed @ frame %d.", (*str)->stream_id, (*str)->DecodeOrder() );
1287 				MuxStatus( LOG_DEBUG );
1288 				(*pcomp) = true;
1289 			}
1290 			++str;
1291 			++pcomp;
1292 		}
1293 	}
1294 	// Tidy up
1295 
1296 	OutputSuffix( );
1297 	psstrm->Close();
1298 	mjpeg_info( "Multiplex completion at SCR=%lld.", current_SCR/300);
1299 	MuxStatus( LOG_INFO );
1300 	for( str = estreams.begin(); str < estreams.end(); ++str )
1301 	{
1302 		(*str)->Close();
1303         if( (*str)->nsec <= 50 )
1304             mjpeg_info( "BUFFERING stream too short for useful statistics");
1305         else
1306             mjpeg_info( "BUFFERING min %d Buf max %d",
1307                         (*str)->BufferMin(),
1308                         (*str)->BufferMax()
1309                 );
1310 	}
1311 
1312     if( underruns> 0 )
1313 	{
1314 		mjpeg_info( "MUX STATUS: Frame data under-runs detected!" ); // MEANX was exit
1315 	}
1316 	else
1317 	{
1318 		mjpeg_info( "MUX STATUS: no under-runs detected.");
1319 	}
1320 }
1321 
1322 /**
1323    Calculate the packet payload of the output stream at a certain timestamp.
1324 @param strm the output stream
1325 @param buffers the number of buffers
1326 @param PTSstamp presentation time stamp
1327 @param DTSstamp decoding time stamp
1328  */
PacketPayload(MuxStream & strm,bool buffers,bool PTSstamp,bool DTSstamp)1329 unsigned int Multiplexor::PacketPayload( MuxStream &strm, bool buffers,
1330 										  bool PTSstamp, bool DTSstamp )
1331 {
1332 	return psstrm->PacketPayload( strm, sys_header_ptr, pack_header_ptr,
1333 								  buffers,
1334 								  PTSstamp, DTSstamp)
1335         - strm.StreamHeaderSize();
1336 }
1337 
1338 /***************************************************
1339 
1340   WritePacket - Write out a normal packet carrying data from one of
1341               the elementary stream being muxed.
1342 @param max_packet_data_size the maximum packet data size allowed
1343 @param strm output mux stream
1344 @param buffers ?
1345 @param PTSstamp presentation time stamp of the packet
1346 @param DTSstamp decoding time stamp of the packet
1347 @param timestamps ?
1348 @param returns the written bytes/packets (?)
1349 ***************************************************/
1350 
1351 unsigned int
WritePacket(unsigned int max_packet_data_size,MuxStream & strm,bool buffers,clockticks PTS,clockticks DTS,uint8_t timestamps)1352 Multiplexor::WritePacket( unsigned int     max_packet_data_size,
1353                            MuxStream        &strm,
1354                            bool 	 buffers,
1355                            clockticks   	 PTS,
1356                            clockticks   	 DTS,
1357                            uint8_t 	 timestamps
1358 	)
1359 {
1360     unsigned int written =
1361         psstrm->CreateSector ( pack_header_ptr,
1362                                sys_header_ptr,
1363                                max_packet_data_size,
1364                                strm,
1365                                buffers,
1366                                false,
1367                                PTS,
1368                                DTS,
1369                                timestamps );
1370     NextPosAndSCR();
1371     return written;
1372 }
1373 
1374 /***************************************************
1375  *
1376  * WriteRawSector - Write out a packet carrying data for
1377  *                    a control packet with irregular content.
1378 @param rawsector data for the raw sector
1379 @param length length of the raw sector
1380  ***************************************************/
1381 
1382 void
WriteRawSector(uint8_t * rawsector,unsigned int length)1383 Multiplexor::WriteRawSector(  uint8_t *rawsector,
1384                                unsigned int     length
1385 	)
1386 {
1387     //
1388     // Writing raw sectors when packs stretch over multiple sectors
1389     // is a recipe for disaster!
1390     //
1391     assert( packets_per_pack == 1 );
1392 	psstrm->RawWrite( rawsector, length );
1393 	NextPosAndSCR();
1394 
1395 }
1396 
1397 
1398 
1399 /******************************************************************
1400 	OutputPadding
1401 
1402 	generates Pack/Sys Header/Packet information for a
1403 	padding stream and saves the sector
1404 
1405 	We have to pass in a special flag to cope with appalling mess VCD
1406 	makes of audio packets (the last 20 bytes being dropped thing) 0 =
1407 	Fill the packet completetely.  This include "audio packets" that
1408     include no actual audio, only a system header and padding.
1409 @param vcd_audio_pad flag for VCD audio padding
1410 ******************************************************************/
1411 
1412 
OutputPadding(bool vcd_audio_pad)1413 void Multiplexor::OutputPadding (bool vcd_audio_pad)
1414 
1415 {
1416     if( vcd_audio_pad )
1417         psstrm->CreateSector ( pack_header_ptr, sys_header_ptr,
1418                                0,
1419                                vcdapstrm,
1420                                false, false,
1421                                0, 0,
1422                                TIMESTAMPBITS_NO );
1423     else
1424         psstrm->CreateSector ( pack_header_ptr, sys_header_ptr,
1425                                0,
1426                                pstrm,
1427                                false, false,
1428                                0, 0,
1429                                TIMESTAMPBITS_NO );
1430     ++pstrm.nsec;
1431 	NextPosAndSCR();
1432 
1433 }
1434 
1435  /******************************************************************
1436  *	OutputGOPControlSector
1437  *  DVD System headers are carried in peculiar sectors carrying 2
1438  *  PrivateStream2 packets.   We're sticking 0's in the packets
1439  *  as we have no idea what's supposed to be in there.
1440  *
1441  * Thanks to Brent Byeler who worked out this work-around.
1442  *
1443  ******************************************************************/
1444 
OutputDVDPriv2()1445 void Multiplexor::OutputDVDPriv2 (	)
1446 {
1447     uint8_t *packet_size_field;
1448     uint8_t *index;
1449     uint8_t *sector_buf = new uint8_t[sector_size];
1450     unsigned int tozero;
1451     assert( sector_size == 2048 );
1452     PS_Stream::BufferSectorHeader( sector_buf,
1453                                 pack_header_ptr,
1454                                 &sys_header,
1455                                 index );
1456     PS_Stream::BufferPacketHeader( index,
1457                                    PRIVATE_STR_2,
1458                                    2,      // MPEG 2
1459                                    false,  // No buffers
1460                                    0,
1461                                    0,
1462                                    0,      // No timestamps
1463                                    0,
1464                                    TIMESTAMPBITS_NO,
1465                                    0, // Natural PES header length
1466                                    packet_size_field,
1467                                    index );
1468     tozero = sector_buf+1024-index;
1469     memset( index, 0, tozero);
1470     index += tozero;
1471     PS_Stream::BufferPacketSize( packet_size_field, index );
1472 
1473     PS_Stream::BufferPacketHeader( index,
1474                                    PRIVATE_STR_2,
1475                                    2,      // MPEG 2
1476                                    false,  // No buffers
1477                                    0,
1478                                    0,
1479                                    0,      // No timestamps
1480                                    0,
1481                                    TIMESTAMPBITS_NO,
1482                                    0, // Natural PES header length
1483                                    packet_size_field,
1484                                    index );
1485     tozero = sector_buf+2048-index;
1486     memset( index, 0, tozero );
1487     index += tozero;
1488     PS_Stream::BufferPacketSize( packet_size_field, index );
1489 
1490     WriteRawSector( sector_buf, sector_size );
1491 
1492 	delete [] sector_buf;
1493 }
1494 
1495 
1496 /*
1497  * Local variables:
1498  *  c-file-style: "stroustrup"
1499  *  tab-width: 4
1500  *  indent-tabs-mode: nil
1501  * End:
1502  */
1503