📄 multplex.cpp
字号:
} } programFile = open(programFilename, O_WRONLY| O_CREAT | O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); if (programFile <= 0) { sprintf(tmpStr, "Unable to open program file %s: %s.", programFilename, strerrno()); DisplayError(tmpStr); goto exit1; } } else programFile = outputFile; /* read in first access unit information */ picture_start = FALSE; audio_frame_start = FALSE; audio1_frame_start = FALSE; empty_vaunit_struc (&video_au); empty_aaunit_struc (&audio_au); empty_aaunit_struc (&audio1_au); if (which_streams & STREAMS_AUDIO) { if (fread (&audio_au, sizeof(Aaunit_struc), 1, aunits_info) != 1) { sprintf(tmpStr, "Unable to read from audio units file %s: %s.", audio_units, strerrno()); DisplayError(tmpStr); goto exit1; } audio_frame_start = TRUE; audio_counter++; } if (which_streams & STREAMS_AUDIO1) { if (fread (&audio1_au, sizeof(Aaunit_struc), 1, aunits1_info) != 1) { sprintf(tmpStr, "Unable to read from secondary audio units file %s: %s.", audio1_units, strerrno()); DisplayError(tmpStr); goto exit1; } audio1_frame_start = TRUE; audio1_counter++; } if (which_streams & STREAMS_VIDEO) { if (fread (&video_au, sizeof(Vaunit_struc), 1, vunits_info) != 1) { sprintf(tmpStr, "Unable to read from video units file %s: %s.", video_units, strerrno()); DisplayError(tmpStr); goto exit1; } picture_start = TRUE; video_counter++; } write_pack = packets_per_pack; video_buffer_size = init_video_buffer_size * 1024; audio_buffer_size = init_audio_buffer_size * 1024; audio1_buffer_size = init_audio1_buffer_size * 1024; /* initialize buffer structure */ init_buffer_struc (&video_buffer,video_buffer_size); init_buffer_struc (&audio_buffer,audio_buffer_size); init_buffer_struc (&audio1_buffer,audio1_buffer_size); if (which_streams & STREAMS_VIDEO) { switch (use_computed_bitrate) { case COMPBITRATE_NONE: video_rate = video_info->bit_rate * 50; if (video_rate) break; case COMPBITRATE_MAX: video_rate = video_info->comp_max_bit_rate * 50; break; case COMPBITRATE_AVG: video_rate = video_info->comp_avg_bit_rate * 50; break; } } // if (VBR_multiplex && !user_mux_rate) // video_rate = (int)ceil((double)video_rate * 1.25); audio_frame_clocks = 0.0; audio1_frame_clocks = 0.0; if (which_streams & STREAMS_AUDIO) { if (audio_info->layer) { /* MPEG */ audio_id = AUDIO_STR_0; audio_rate = bitrate_index[3-audio_info->layer][audio_info->bit_rate]*125; audio_buffer_size1 = audio_buffer_size / 128; audio_frame_clocks = (double)samples[3 - audio_info->layer] / (double)frequency[audio_info->layer] * 27000.0; } else { /* AC3 */ audio_id = PRIVATE_STREAM1; audio_subid = AC3_STREAM1; audio_rate = audio_info->bit_rate*128; audio_buffer_size1 = audio_buffer_size / 1024; audio_buffer_scale = 1; audio_frame_clocks = 1536.0 / (double)ac3_frequency[audio_info->frequency] * 27000.0; } } if (which_streams & STREAMS_AUDIO1) { if (audio1_info->layer) { /* MPEG */ audio1_id = AUDIO_STR_1; audio1_rate = bitrate_index[3-audio1_info->layer][audio1_info->bit_rate]*125; audio1_buffer_size1 = audio1_buffer_size / 128; audio1_frame_clocks = (double)samples[3 - audio1_info->layer] / (double)frequency[audio1_info->layer] * 27000.0; } else { /* AC3 */ audio1_id = PRIVATE_STREAM1; if (!audio_subid) audio1_subid = AC3_STREAM1; else audio1_subid = AC3_STREAM2; audio1_rate = audio1_info->bit_rate*128; audio1_buffer_size1 = audio1_buffer_size / 1024; audio1_buffer_scale = 1; audio1_frame_clocks = 1536.0 / (double)ac3_frequency[audio1_info->frequency] * 27000.0; } } data_rate = video_rate + audio_rate + audio1_rate; if (always_sys_header) { if (mplex_type > MPEG_VCD) min_packet_data = sector_size - MPEG2_PACK_HEADER_SIZE - SYS_HEADER_SIZE - PACKET_HEADER_SIZE - MPEG2_AFTER_PACKET_LENGTH; else min_packet_data = sector_size - MPEG1_PACK_HEADER_SIZE - SYS_HEADER_SIZE - PACKET_HEADER_SIZE - MPEG1_AFTER_PACKET_LENGTH; /* if we do not have all streams, we have 3 or 6 more bytes in the sys header free */ if (!(which_streams & STREAMS_VIDEO)) min_packet_data += 3; if (!(which_streams & STREAMS_AUDIO)) min_packet_data += 3; if (!(which_streams & STREAMS_AUDIO1)) min_packet_data += 3; } else { if (mplex_type > MPEG_VCD) min_packet_data = sector_size - MPEG2_PACK_HEADER_SIZE - ((PACKET_HEADER_SIZE + MPEG2_AFTER_PACKET_LENGTH) * packets_per_pack); else min_packet_data = sector_size - MPEG1_PACK_HEADER_SIZE - ((PACKET_HEADER_SIZE + MPEG1_AFTER_PACKET_LENGTH) * packets_per_pack); } vpacket_data_size = min_packet_data / packets_per_pack; if (mplex_type == MPEG_VCD) apacket_data_size = vpacket_data_size - 15; // allow 5 more for no DTS fields else apacket_data_size = vpacket_data_size + 5; // allow 5 more for no DTS fields dmux_rate = ceil((double)(data_rate) * ((double)(sector_size)/(double)(min_packet_data))); mux_rate = (uint)ceil(dmux_rate / 50.); if (user_mux_rate) { if (user_mux_rate < (int)mux_rate) DisplayInfo(" NOTE: Mux rate may be too low for data rate, watch for PTS/DTS underflows."); mux_rate = user_mux_rate; } dmux_rate = mux_rate * 50; sectors_per_sec = floor(dmux_rate / sector_size); clock_inc = CLOCKS / sectors_per_sec; clock_inc_2 = clock_inc * 2.0; if (which_streams & STREAMS_VIDEO) { if (max_file_size) max_file_size_GOP = (uint)(max_file_size * 1048576 - dmux_rate); else max_file_size_GOP = 0; if (mux_start_time) { start_time = mux_start_time * 1000; if (start_time > get_timecode(&video_info->last_PTS) / 27000) { sprintf(tmpStr, "Mux start time is greater than the total time %u seconds.", (unsigned int)(get_timecode(&video_info->last_PTS) / CLOCKS)); DisplayError(tmpStr); goto exit1; } if (start_time > (unsigned int)(get_timecode(&video_au.PTS) / 27000)) output_on = 0; } else start_time = 0; if (mux_stop_time) stop_time = mux_stop_time * 1000; else stop_time = 0; } /* DTS of the first units is supposed to be zero. To avoid Buffer underflow, we have to compute how long it takes for all first Video and Audio access units to arrive at the system standard decoder buffer. This delay is added as a kind of startup delay to all of the TimeStamps. We compute a ceiling based on the number of sectors we will have to transport for the first access units */ video_delay = ceil(((double)video_au.length / (double)vpacket_data_size) + ((double)audio_au.length / (double)apacket_data_size) + ((double)audio1_au.length / (double)apacket_data_size)) * (double)sector_size / dmux_rate * (double)CLOCKS; if (!always_sys_header) video_delay += clock_inc; // account for a padding packet with the system header audio_delay = audio1_delay = video_delay; if (video_delay_ms) video_delay = (double)video_delay_ms*(double)(CLOCKS / 1000); if (audio_delay_ms) audio_delay = (double)audio_delay_ms*(double)(CLOCKS / 1000); if (audio1_delay_ms) audio1_delay = (double)audio1_delay_ms*(double)(CLOCKS / 1000); delay = (double)sectors_delay*(double)(CLOCKS / 1000); bytes_output = (uint)(sector_size * sectors_per_sec * sectors_delay / 1000); clock_cycles = delay; extra_clock_cycles = 0.0; audio_delay += delay; audio1_delay += delay; video_delay += delay; make_timecode(audio_delay, &SCR_audio_delay); make_timecode(audio1_delay, &SCR_audio1_delay); make_timecode(video_delay, &SCR_video_delay); if (max_file_size_GOP || start_time || stop_time) { org_audio_delay = audio_delay; org_audio1_delay = audio1_delay; org_video_delay = video_delay; first_audio_PTS = get_timecode(&audio_au.PTS); first_audio1_PTS = get_timecode(&audio1_au.PTS); first_video_PTS = get_timecode(&video_au.PTS); first_video_DTS = get_timecode(&video_au.DTS); } add_to_timecode(&SCR_video_delay, &video_au.DTS); add_to_timecode(&SCR_video_delay, &video_au.PTS); add_to_timecode(&SCR_audio_delay, &audio_au.PTS); add_to_timecode(&SCR_audio1_delay, &audio1_au.PTS); /* Let's try to read in unit after unit and to write it out into the outputstream. The only difficulty herein lies into the buffer management, and into the fact the the actual access unit *has* to arrive in time, that means the whole unit (better yet, packet data), has to arrive before arrival of DTS. If both buffers are full we'll generate a padding packet */ DisplayInfo(" "); DisplayInfo(" Multiplexing information"); if (which_streams & STREAMS_VIDEO) { sprintf(tmpStr, " Video stream data rate : %d bytes/sec (%u bits/sec)", video_rate, video_rate << 3); DisplayInfo(tmpStr); } if (which_streams & STREAMS_AUDIO) { sprintf(tmpStr, " Audio stream 1 data rate : %d bytes/sec (%u bits/sec)", audio_rate, audio_rate << 3); DisplayInfo(tmpStr); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -