multiplexor.cpp

来自「Motion JPEG编解码器源代码」· C++ 代码 · 共 1,502 行 · 第 1/4 页

CPP
1,502
字号
/* *  multiplexor.cpp:  Program/System stream Multiplex despatcher  * *  Copyright (C) 2003 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. */#define STREAM_LOGGING#include <config.h>#include <math.h>#include <stdlib.h>#include <mjpeg_types.h>#include <mjpeg_logging.h>#include <format_codes.h>#include "interact.hpp"#include "videostrm.hpp"#include "stillsstream.hpp"#include "audiostrm.hpp"#ifdef ZALPHA#include "zalphastrm.hpp"#endif#include "multiplexor.hpp"/**************** * * Constructor - sets up per-run stuff and initialised parameters * that control syntax of generated stream from the job options set * by the user. * ***************/Multiplexor::Multiplexor(MultiplexJob &job, OutputStream &output){    underrun_ignore = 0;    underruns = 0;	start_of_new_pack = false;    InitSyntaxParameters(job);    InitInputStreams(job);    psstrm = new PS_Stream(mpeg, sector_size, output, max_segment_size );}/****************************************************************** * * Initialisation of stream syntax paramters based on selected user * options.  Depending of mux_format some selections may only act as * defaults or may simply be ignored if they are inconsistent with the * selected output format. * ******************************************************************/void Multiplexor::InitSyntaxParameters(MultiplexJob &job){	seg_starts_with_video = false;	audio_buffer_size = 4 * 1024;    mux_format = job.mux_format;    vbr = job.VBR;    packets_per_pack = job.packets_per_pack;    data_rate = job.data_rate;    mpeg = job.mpeg;    always_sys_header_in_pack = job.always_system_headers;    sector_transport_size = job.sector_size;    sector_size = job.sector_size;	split_at_seq_end = !job.multifile_segment;    workarounds = job.workarounds;    max_segment_size = static_cast<off_t>(job.max_segment_size)                       * static_cast<off_t>(1024 * 1024);    max_PTS = static_cast<clockticks>(job.max_PTS) * CLOCKS;	video_delay = static_cast<clockticks>(job.video_offset);	audio_delay = static_cast<clockticks>(job.audio_offset); 	switch( mux_format  )	{	case MPEG_FORMAT_VCD :		data_rate = 75*2352;  			 /* 75 raw CD sectors/sec */ 	case MPEG_FORMAT_VCD_NSR : /* VCD format, non-standard rate */		mjpeg_info( "Selecting VCD output profile");		video_buffers_iframe_only = false;		mpeg = 1;	 	packets_per_pack = 1;	  	sys_header_in_pack1 = 0;	  	always_sys_header_in_pack = 0;	  	sector_transport_size = 2352;	      /* Each 2352 bytes with 2324 bytes payload */	  	transport_prefix_sectors = 30;	  	sector_size = 2324;		buffers_in_video = 1;		always_buffers_in_video = 0;		buffers_in_audio = 1;   		// This is needed as otherwise we have		always_buffers_in_audio = 1;	//  to stuff the packer header which                                         // must be 13 bytes for VCD audio		vcd_zero_stuffing = 20;         // The famous 20 zero bytes for VCD                                        // audio sectors.		dtspts_for_all_vau = false;		sector_align_iframeAUs = false;        timestamp_iframe_only = false;		seg_starts_with_video = true;        if( job.video_tracks == 0 )        {            mjpeg_info( "Audio-only VCD track - variable-bit-rate (VCD2.0)");            vbr = true;        }		break;			case  MPEG_FORMAT_MPEG2 : 		mjpeg_info( "Selecting generic MPEG2 output profile");		mpeg = 2;	 	packets_per_pack = 1;	  	sys_header_in_pack1 = 1;	  	always_sys_header_in_pack = 0;	  	sector_transport_size = 2048;	      /* Each 2352 bytes with 2324 bytes payload */	  	transport_prefix_sectors = 0;	  	sector_size = 2048;		buffers_in_video = 1;		always_buffers_in_video = 0;		buffers_in_audio = 1;		always_buffers_in_audio = 1;		vcd_zero_stuffing = 0;		vbr = true;        	dtspts_for_all_vau = 0;        	timestamp_iframe_only = false;        	video_buffers_iframe_only = false;		break;	case MPEG_FORMAT_SVCD :		data_rate = 150*2324;	case MPEG_FORMAT_SVCD_NSR :		/* Non-standard data-rate */		mjpeg_info( "Selecting SVCD output profile");		mpeg = 2;	 	packets_per_pack = 1;	  	sys_header_in_pack1 = 0;	  	always_sys_header_in_pack = 0;	  	sector_transport_size = 2324;	  	transport_prefix_sectors = 0;	  	sector_size = 2324;		vbr = true;		buffers_in_video = 1;		always_buffers_in_video = 0;		buffers_in_audio = 1;		always_buffers_in_audio = 0;		vcd_zero_stuffing = 0;        dtspts_for_all_vau = 0;		sector_align_iframeAUs = true;		seg_starts_with_video = true;        timestamp_iframe_only = false;        video_buffers_iframe_only = false;		break;	case MPEG_FORMAT_VCD_STILL :		data_rate = 75*2352;  			 /* 75 raw CD sectors/sec */ 	  	vbr = false;		mpeg = 1;		split_at_seq_end = false;	 	packets_per_pack = 1;	  	sys_header_in_pack1 = 0;	  	always_sys_header_in_pack = 0;	  	sector_transport_size = 2352;	      /* Each 2352 bytes with 2324 bytes payload */	  	transport_prefix_sectors = 0;	  	sector_size = 2324;		buffers_in_video = 1;		always_buffers_in_video = 0;		buffers_in_audio = 1;		always_buffers_in_audio = 0;		vcd_zero_stuffing = 20;		dtspts_for_all_vau = 1;		sector_align_iframeAUs = true;        timestamp_iframe_only = false;        video_buffers_iframe_only = false;		break;	case MPEG_FORMAT_SVCD_STILL :		mjpeg_info( "Selecting SVCD output profile");		if( data_rate == 0 )			data_rate = 150*2324;		mpeg = 2;	 	packets_per_pack = 1;	  	sys_header_in_pack1 = 0;	  	always_sys_header_in_pack = 0;	  	sector_transport_size = 2324;	  	transport_prefix_sectors = 0;	  	sector_size = 2324;		vbr = true;		buffers_in_video = 1;		always_buffers_in_video = 0;		buffers_in_audio = 1;		always_buffers_in_audio = 0;		vcd_zero_stuffing = 0;        dtspts_for_all_vau = 0;		sector_align_iframeAUs = true;        timestamp_iframe_only = false;        video_buffers_iframe_only = false;		break;    case MPEG_FORMAT_DVD :		mjpeg_info( "Selecting generic DVD output profile (PROVISIONAL)");        if( data_rate == 0 )            data_rate = 1260000;		mpeg = 2;	 	packets_per_pack = 1;	  	sys_header_in_pack1 = false; // Handle by control packets	  	always_sys_header_in_pack = false;	  	sector_transport_size = 2048;	  	transport_prefix_sectors = 0;	  	sector_size = 2048;		buffers_in_video = true;		always_buffers_in_video = false;		buffers_in_audio = true;		always_buffers_in_audio = false;		vcd_zero_stuffing = 0;        dtspts_for_all_vau = 0;		sector_align_iframeAUs = true;        timestamp_iframe_only = true;        video_buffers_iframe_only = true;		vbr = true;        break;    case MPEG_FORMAT_DVD_NAV :		mjpeg_info( "Selecting dvdauthor DVD output profile");        if( data_rate == 0 )            data_rate = 1260000;		mpeg = 2;	 	packets_per_pack = 1;	  	sys_header_in_pack1 = false; // Handle by control packets	  	always_sys_header_in_pack = false;	  	sector_transport_size = 2048;	  	transport_prefix_sectors = 0;	  	sector_size = 2048;		buffers_in_video = true;		always_buffers_in_video = false;		buffers_in_audio = true;		always_buffers_in_audio = false;		vcd_zero_stuffing = 0;        dtspts_for_all_vau = 0;		sector_align_iframeAUs = true;        timestamp_iframe_only = true;        video_buffers_iframe_only = true;		vbr = true;        seg_starts_with_video = true; // Needs special NAV sector 1st!        break;			 	default : /* MPEG_FORMAT_MPEG1 - auto format MPEG1 */		mjpeg_info( "Selecting generic MPEG1 output profile");		//mpeg = 1;		sys_header_in_pack1 = 1;		transport_prefix_sectors = 0;		buffers_in_video = 1;		always_buffers_in_video = 1;		buffers_in_audio = 0;		always_buffers_in_audio = 1;		vcd_zero_stuffing = 0;        dtspts_for_all_vau = 0;		sector_align_iframeAUs = false;        timestamp_iframe_only = false;        video_buffers_iframe_only = false;		break;	}}/************************************** * * Initialise the elementary stream readers / output sector formatter * objects for the various kinds of input stream. * *************************************/void Multiplexor::InitInputStreams(MultiplexJob &job){    //    // S(VCD) Stills are sufficiently unusual to require their own    // special initialisation    //	if( MPEG_STILLS_FORMAT(job.mux_format) )        InitInputStreamsForStills( job );    else        InitInputStreamsForVideo( job );}void Multiplexor::InitInputStreamsForStills(MultiplexJob & job ){	std::vector<VideoParams *>::iterator vidparm = job.video_param.begin();    unsigned int frame_interval;    unsigned int i;    vector<JobStream *> video_strms;    job.GetInputStreams( video_strms, MPEG_VIDEO );    vector<JobStream *> mpa_strms;    job.GetInputStreams( mpa_strms, MPEG_AUDIO );    switch( job.mux_format )    {    case MPEG_FORMAT_VCD_STILL :        mjpeg_info( "Multiplexing VCD stills: %d stills streams.", video_strms.size() );        {            frame_interval = 30; // 30 Frame periods            if( mpa_strms.size() > 0 && video_strms.size() > 2  )                mjpeg_error_exit1("VCD stills: no more than two streams (one normal one hi-res) possible");            VCDStillsStream *str[2];                        for( i = 0; i< video_strms.size(); ++i )            {                FrameIntervals *ints =                     new ConstantFrameIntervals( frame_interval );                str[i] =                     new VCDStillsStream( *(video_strms[i]->bs),                                         new StillsParams( *vidparm, ints),                                         *this );                estreams.push_back( str[i] );                vstreams.push_back( str[i] );                str[i]->Init();                ++vidparm;            }            if( video_strms.size() == 2 )            {                str[0]->SetSibling(str[1]);                str[1]->SetSibling(str[0]);            }        }        break;    case MPEG_FORMAT_SVCD_STILL :        mjpeg_info( "Multiplexing SVCD stills: %d stills streams %d audio streams", video_strms.size(), mpa_strms.size() );        frame_interval = 30;        if( video_strms.size() > 1 )        {            mjpeg_error_exit1("SVCD stills streams may only contain a single video stream");        }        else if( video_strms.size() > 0 )        {            ConstantFrameIntervals *intervals;            StillsStream *str;            intervals = new ConstantFrameIntervals( frame_interval );            str = new StillsStream( *(video_strms[0]->bs),                                    new StillsParams( *vidparm, intervals ),                                    *this );            estreams.push_back( str );            vstreams.push_back( str );            str->Init();        }        for( i = 0 ; i < mpa_strms.size() ; ++i )        {            AudioStream *audioStrm = new MPAStream( *(mpa_strms[i]->bs), *this);            audioStrm->Init ( i);            estreams.push_back(audioStrm);            astreams.push_back(audioStrm);        }        break;    default:        mjpeg_error_exit1("Only VCD and SVCD stills format for the moment...");    }}void Multiplexor::InitInputStreamsForVideo(MultiplexJob & job ){    mjpeg_info( "Multiplexing video program stream!" );    unsigned int audio_track = 0;    unsigned int video_track = 0;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?