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 + -
显示快捷键?