/*! * COPYRIGHT (C) 2020 Emeric Grange - All Rights Reserved * * This file is part of MiniVideo. * * MiniVideo is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * MiniVideo 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with MiniVideo. If not, see . * * \file pes.c * \author Emeric Grange * \date 2012 */ // minivideo headers #include "pes.h" #include "minivideo/bitstream_utils.h" #include "minivideo/minitraces.h" // C standard libraries #include #include #include #include /* ************************************************************************** */ /*! * \brief Jumpy protect your parsing - PES edition. * \param bitstr: Our bitstream reader. * \param header: A pointer to a PES header structure. * \return SUCCESS or FAILURE if the jump could not be done. * * 'Jumpy' is in charge of checking your position into the stream after your * parser finish parsing a box / list / chunk / element, never leaving you * stranded in the middle of nowhere with no easy way to get back on track. * It will check available informations to known if the current element has been * fully parsed, and if not perform a jump (or even a rewind) to the next known * element. */ int jumpy_pes(Bitstream_t *bitstr, PesHeader_t *header) { int retcode = SUCCESS; // Done as a precaution, because the parsing of some boxes (like ESDS...) // can leave us in the middle of a byte and that will never be caught by // offset checks (cause they works on the assumption that we are byte aligned) bitstream_force_alignment(bitstr); // Check if we need a jump int64_t current_pos = bitstream_get_absolute_byte_offset(bitstr); if (current_pos != header->offset_end) { int64_t file_size = bitstream_get_full_size(bitstr); // If the offset_end is past the last byte of the file, we do not need to jump // The parser will pick that fact and finish up... if (header->offset_end >= file_size) { bitstr->bitstream_offset = file_size; return SUCCESS; } // Now, do we need to go forward or backward to reach our goal? // Then, can we move in our current buffer or do we need to reload a new one? if (current_pos < header->offset_end) { int64_t jump = header->offset_end - current_pos; if (jump < (UINT_MAX/8)) retcode = skip_bits(bitstr, (unsigned int)(jump*8)); else retcode = bitstream_goto_offset(bitstr, header->offset_end); } else { int64_t rewind = current_pos - header->offset_end; if (rewind > 0) { if (rewind > (UINT_MAX/8)) retcode = rewind_bits(bitstr, (unsigned int)(rewind*8)); else retcode = bitstream_goto_offset(bitstr, header->offset_end); } } } return retcode; } /* ************************************************************************** */ /*! * \brief Parse PES packet header, common to all PES packet types. * \param *bitstr: The bitstream to use. * \param *header: A pointer to a PES header structure. * \return 1 if succeed, 0 otherwise. * * From 'ISO/IEC 13818-1' specification: * 2.4.3.6 PES packet. * Table 2-17 – PES packet. */ int parse_pes_header(Bitstream_t *bitstr, PesHeader_t *header) { TRACE_2(MPS, "> parse_pes_header()"); header->offset_start = bitstream_get_absolute_byte_offset(bitstr); header->start_code = read_bits(bitstr, 32); header->stream_id = header->start_code & 0x000000FF; header->payload_length = read_bits(bitstr, 16); header->packet_length = header->payload_length + 6; header->offset_end = header->offset_start + header->packet_length; return SUCCESS; } /* ************************************************************************** */ /*! * \brief Parse PES packet. * \param *bitstr: The bitstream to use. * \param *header: A pointer to a PES header structure. * \param *packet: A pointer to a PES packet structure. * \return 1 if succeed, 0 otherwise. * * From 'ISO/IEC 13818-1' specification: * 2.4.3.6 PES packet. * Table 2-17 – PES packet. * * Parse both MPEG-1 (ISO/IEC 11172-1) and MPEG-2 (ISO/IEC 13818-1) PES packets. */ int parse_pes(Bitstream_t *bitstr, PesHeader_t *header, PesPacket_t *packet) { TRACE_2(MPS, "> parse_pes()"); int retcode = SUCCESS; TRACE_INFO(MPS, "parse_pes() 0x%X @ %lli", header->start_code, bitstream_get_absolute_byte_offset(bitstr)); // "regular" PES packet? if ((header->stream_id != SID_PROGRAM_STREAM_MAP) && (header->stream_id != SID_PADDING) && (header->stream_id != SID_PRIVATE_STREAM_2) && (header->stream_id != SID_ECM_STREAM) && (header->stream_id != SID_EMM_STREAM) && (header->stream_id != SID_PROGRAM_STREAM_DIRECTORY) && (header->stream_id != SID_DSMCC_STREAM) && (header->stream_id != SID_2221E)) { unsigned checkversion = next_bits(bitstr, 2); // Parse MPEG-2 PES header if ((checkversion & 0x02) == 0x02) { packet->mpeg_version = 2; if (read_bits(bitstr, 2) != 2) { TRACE_ERROR(MPS, "wrong 'marker_bits'"); return FAILURE; } packet->PES_scrambling_control = read_bits(bitstr, 2); packet->PES_priority = read_bit(bitstr); packet->data_alignment_indicator = read_bit(bitstr); packet->copyright = read_bit(bitstr); packet->original_or_copy = read_bit(bitstr); packet->PTS_DTS_flag = read_bits(bitstr, 2); packet->ESCR_flag = read_bit(bitstr); packet->ES_rate_flag = read_bit(bitstr); packet->DSM_trick_mode_flag = read_bit(bitstr); packet->additional_copy_info_flag = read_bit(bitstr); packet->PES_CRC_flag = read_bit(bitstr); packet->PES_extension_flag = read_bit(bitstr); packet->PES_header_data_length = read_bits(bitstr, 8); if (packet->PTS_DTS_flag == 2) { if (read_bits(bitstr, 4) != 2) { TRACE_ERROR(MPS, "wrong 'marker_bit'"); return FAILURE; } packet->PTS = read_bits(bitstr, 3) << 30; MARKER_BIT packet->PTS += read_bits(bitstr, 15) << 15; MARKER_BIT packet->PTS += read_bits(bitstr, 15); MARKER_BIT } else if (packet->PTS_DTS_flag == 3) { if (read_bits(bitstr, 4) != 3) { TRACE_ERROR(MPS, "wrong 'marker_bit'"); return FAILURE; } packet->PTS = read_bits(bitstr, 3) << 30; MARKER_BIT packet->PTS += read_bits(bitstr, 15) << 15; MARKER_BIT packet->PTS += read_bits(bitstr, 15); MARKER_BIT if (read_bits(bitstr, 4) != 1) { TRACE_ERROR(MPS, "wrong 'marker_bit'"); return FAILURE; } packet->DTS = read_bits(bitstr, 3) << 30; MARKER_BIT packet->DTS += read_bits(bitstr, 15) << 15; MARKER_BIT packet->DTS += read_bits(bitstr, 15); MARKER_BIT } if (packet->ESCR_flag == 1) { packet->ESCR_base = read_bits(bitstr, 3) << 30; MARKER_BIT packet->ESCR_base += read_bits(bitstr, 15) << 15; MARKER_BIT packet->ESCR_base += read_bits(bitstr, 15); MARKER_BIT packet->ESCR_extension = read_bits(bitstr, 9); MARKER_BIT } if (packet->ES_rate_flag == 1) { MARKER_BIT packet->ES_rate = read_bits(bitstr, 22); MARKER_BIT } if (packet->DSM_trick_mode_flag == 1) { packet->trick_mode_control = read_bits(bitstr, 3); if (packet->trick_mode_control == TM_FAST_FORWARD) { packet->field_id = read_bits(bitstr, 2); packet->intra_slice_refresh = read_bit(bitstr); packet->frequency_truncation = read_bits(bitstr, 2); } else if (packet->trick_mode_control == TM_SLOW_MOTION) { packet->rep_cntrl = read_bits(bitstr, 5); } else if (packet->trick_mode_control == TM_FREEZE_FRAME) { packet->field_id = read_bits(bitstr, 2); /*int reserved =*/ read_bits(bitstr, 3); } else if (packet->trick_mode_control == TM_FAST_REVERSE) { packet->field_id = read_bits(bitstr, 2); packet->intra_slice_refresh = read_bit(bitstr); packet->frequency_truncation = read_bits(bitstr, 2); } else if (packet->trick_mode_control == TM_SLOW_REVERSE) { packet->rep_cntrl = read_bits(bitstr, 5); } else { /*int reserved =*/ read_bits(bitstr, 5); } } if (packet->additional_copy_info_flag == 1) { MARKER_BIT packet->additional_copy_info = read_bits(bitstr, 7); } if (packet->PES_CRC_flag == 1) { packet->previous_PES_packet_CRC = read_bits(bitstr, 16); } if (packet->PES_extension_flag == 1) { packet->PES_private_data_flag = read_bit(bitstr); packet->pack_header_field_flag = read_bit(bitstr); packet->program_packet_sequence_counter_flag = read_bit(bitstr); packet->PSTD_buffer_flag = read_bit(bitstr); /*int reserved =*/ read_bits(bitstr, 3); packet->PES_extension_flag_2 = read_bit(bitstr); if (packet->PES_private_data_flag == 1) { for (int i = 0; i < 16; i++) { packet->PES_private_data[i] = read_bits(bitstr, 8); } } if (packet->pack_header_field_flag == 1) { packet->pack_field_length = read_bits(bitstr, 8); // TODO //parse_pack_header(bitstr, wtf); } if (packet->program_packet_sequence_counter_flag == 1) { MARKER_BIT packet->program_packet_sequence_counter = read_bits(bitstr, 7); MARKER_BIT packet->MPEG1_MPEG2_identifier = read_bit(bitstr); packet->original_stuff_length = read_bits(bitstr, 6); } if (packet->PSTD_buffer_flag == 1) { if (read_bits(bitstr, 2) != 1) { TRACE_ERROR(MPS, "wrong 'marker_bit'"); return FAILURE; } packet->PSTD_buffer_scale = read_bit(bitstr); packet->PSTD_buffer_size = read_bits(bitstr, 13); } if (packet->PES_extension_flag_2 == 1) { MARKER_BIT packet->PES_extension_field_length = read_bits(bitstr, 7); for (int i = 0; i < packet->PES_extension_field_length; i++) { /*int reserved =*/ read_bits(bitstr, 8); } } } } else // Parse MPEG-1 PES header { packet->mpeg_version = 1; packet->PES_header_data_length = 0; // We will emulate this field // MPEG-1: up to 16 stuffing bytes here (optional) while (next_bits(bitstr, 8) == 0xFF) { skip_bits(bitstr, 8); packet->PES_header_data_length++; } // Optional if (next_bits(bitstr, 2) == 1) { skip_bits(bitstr, 2); packet->PES_header_data_length += 2; packet->PSTD_buffer_scale = read_bit(bitstr); packet->PSTD_buffer_size = read_bits(bitstr, 13); } if (next_bits(bitstr, 8) == 0x0F) { skip_bits(bitstr, 8); packet->PES_header_data_length++; } else { if (next_bits(bitstr, 2) != 0) { TRACE_ERROR(MPS, "wrong 'marker_bit' PESv1"); return FAILURE; } packet->PTS_DTS_flag = read_bits(bitstr, 2); if (packet->PTS_DTS_flag == 2) { packet->PES_header_data_length += 5; packet->PTS = read_bits(bitstr, 3) << 30; MARKER_BIT packet->PTS += read_bits(bitstr, 15) << 15; MARKER_BIT packet->PTS += read_bits(bitstr, 15); MARKER_BIT } else if (packet->PTS_DTS_flag == 3) { packet->PES_header_data_length += 10; packet->PTS = read_bits(bitstr, 3) << 30; MARKER_BIT packet->PTS += read_bits(bitstr, 15) << 15; MARKER_BIT packet->PTS += read_bits(bitstr, 15); MARKER_BIT if (read_bits(bitstr, 4) != 1) { TRACE_ERROR(MPS, "wrong 'marker_bit' (PTS_DTS_flag==3)"); return FAILURE; } packet->DTS = read_bits(bitstr, 3) << 30; MARKER_BIT packet->DTS += read_bits(bitstr, 15) << 15; MARKER_BIT packet->DTS += read_bits(bitstr, 15); MARKER_BIT } else { packet->PES_header_data_length++; if (read_bits(bitstr, 4) == 0x0F) { TRACE_ERROR(MPS, "wrong 'marker_bit' (PTS_DTS_flag==0)"); return FAILURE; } } } } // Skip packet data //retcode = skip_pes_data(bitstr, packet); /* // TODO int i = 0, N1 = 0, N2 = 0; for (i = 0; i < N1; i++) { if (read_bits(bitstr, 8) != 0xFF) { TRACE_ERROR(MPS, BLD_GREEN "wrong 'stuffing_byte'" CLR_RESET); return FAILURE; } } for (i = 0; i < N2; i++) { uint8_t PES_packet_data_byte = read_bits(bitstr, 8); } */ } return retcode; } /* ************************************************************************** */ void print_pes(PesHeader_t *header, PesPacket_t *packet) { TRACE_INFO(MPS, BLD_GREEN "print_pes()" CLR_RESET); // Header TRACE_INFO(MPS, " packet_start_offset = %lli", header->offset_start); TRACE_INFO(MPS, " packet_end_offset = %lli", header->offset_end); TRACE_INFO(MPS, " packet_start_code = 0x%06X", header->start_code); TRACE_INFO(MPS, " stream_id = 0x%02X", header->start_code); TRACE_INFO(MPS, " PES_packet_length = %i", header->payload_length); // "regular" PES packet? if ((header->stream_id != SID_PROGRAM_STREAM_MAP) && (header->stream_id != SID_PADDING) && (header->stream_id != SID_PRIVATE_STREAM_2) && (header->stream_id != SID_ECM_STREAM) && (header->stream_id != SID_EMM_STREAM) && (header->stream_id != SID_PROGRAM_STREAM_DIRECTORY) && (header->stream_id != SID_DSMCC_STREAM) && (header->stream_id != SID_2221E)) { TRACE_1(MPS, " PES_scrambling_control = %i", packet->PES_scrambling_control); TRACE_1(MPS, " PES_priority = %i", packet->PES_priority); TRACE_1(MPS, " data_alignment_indicator = %i", packet->data_alignment_indicator); TRACE_1(MPS, " copyright = %i", packet->copyright); TRACE_1(MPS, " original_or_copy = %i", packet->original_or_copy); TRACE_1(MPS, " PTS_DTS_flag = %i", packet->PTS_DTS_flag); TRACE_1(MPS, " ESCR_flag = %i", packet->ESCR_flag); TRACE_1(MPS, " ES_rate_flag = %i", packet->ES_rate_flag); TRACE_1(MPS, " DSM_trick_mode_flag = %i", packet->DSM_trick_mode_flag); TRACE_1(MPS, " additional_copy_info_flag= %i", packet->additional_copy_info_flag); TRACE_1(MPS, " PES_CRC_flag = %i", packet->PES_CRC_flag); TRACE_1(MPS, " PES_extension_flag = %i", packet->PES_extension_flag); TRACE_1(MPS, " PES_header_data_length = %i", packet->PES_header_data_length); if (packet->PTS_DTS_flag == 2) { TRACE_1(MPS, " PTS = %i", packet->PTS); } else if (packet->PTS_DTS_flag == 3) { TRACE_1(MPS, " PTS = %i", packet->PTS); TRACE_1(MPS, " DTS = %i", packet->DTS); } if (packet->ESCR_flag == 1) { TRACE_1(MPS, " ESCR_base = %i", packet->ESCR_base); TRACE_1(MPS, " ESCR_extension = %i", packet->ESCR_extension); } if (packet->ES_rate_flag == 1) { TRACE_1(MPS, " ES_rate = %i", packet->ES_rate); } if (packet->DSM_trick_mode_flag == 1) { TRACE_1(MPS, " trick_mode_control= %i", packet->trick_mode_control); if (packet->trick_mode_control == TM_FAST_FORWARD) { TRACE_1(MPS, " field_id = %i", packet->field_id); TRACE_1(MPS, " intra_slice_refresh = %i", packet->intra_slice_refresh); TRACE_1(MPS, " frequency_truncation = %i", packet->frequency_truncation); } else if (packet->trick_mode_control == TM_SLOW_MOTION) { TRACE_1(MPS, " rep_cntrl= %i", packet->rep_cntrl); } else if (packet->trick_mode_control == TM_FREEZE_FRAME) { TRACE_1(MPS, " field_id= %i", packet->field_id); } else if (packet->trick_mode_control == TM_FAST_REVERSE) { TRACE_1(MPS, " field_id = %i", packet->field_id); TRACE_1(MPS, " intra_slice_refresh = %i", packet->intra_slice_refresh); TRACE_1(MPS, " frequency_truncation = %i", packet->frequency_truncation); } else if (packet->trick_mode_control == TM_SLOW_REVERSE) { TRACE_1(MPS, " rep_cntrl= %i", packet->rep_cntrl); } } if (packet->additional_copy_info_flag == 1) { TRACE_1(MPS, " additional_copy_info= %i", packet->additional_copy_info); } if (packet->PES_CRC_flag == 1) { TRACE_1(MPS, " previous_PES_packet_CRC= %i", packet->previous_PES_packet_CRC); } if (packet->PES_extension_flag == 1) { TRACE_1(MPS, " PES_private_data_flag = %i", packet->PES_private_data_flag); TRACE_1(MPS, " pack_header_field_flag = %i", packet->pack_header_field_flag); TRACE_1(MPS, " program_packet_sequence_counter_flag= %i", packet->program_packet_sequence_counter_flag); TRACE_1(MPS, " PSTD_buffer_flag = %i", packet->PSTD_buffer_flag); TRACE_1(MPS, " PES_extension_flag_2 = %i", packet->PES_extension_flag_2); if (packet->PES_private_data_flag == 1) { int i = 0; for (i = 0; i < 16; i++) { TRACE_1(MPS, " PES_private_data[%i]= %i", i, packet->PES_private_data[i]); } } if (packet->pack_header_field_flag == 1) { TRACE_1(MPS, " pack_field_length= %i", packet->pack_field_length); // TODO //parse_pack_header(bitstr, wtf); } if (packet->program_packet_sequence_counter_flag == 1) { TRACE_1(MPS, " program_packet_sequence_counter = %i", packet->program_packet_sequence_counter); TRACE_1(MPS, " MPEG1_MPEG2_identifier = %i", packet->MPEG1_MPEG2_identifier); TRACE_1(MPS, " original_stuff_length = %i", packet->original_stuff_length); } if (packet->PSTD_buffer_flag == 1) { TRACE_1(MPS, " PSTD_buffer_scale= %i", packet->PSTD_buffer_scale); TRACE_1(MPS, " PSTD_buffer_size = %i", packet->PSTD_buffer_size); } if (packet->PES_extension_flag_2 == 1) { TRACE_1(MPS, " PES_extension_field_length= %i", packet->PES_extension_field_length); for (int i = 0; i < packet->PES_extension_field_length; i++) { TRACE_1(MPS, " reserved= xx"); } } } } } /* ************************************************************************** */ /*! * \brief parse_pes_padding * \param bitstr: Our bitstream reader. * \param header * \param packet * \return 1 if succeed, 0 otherwise. */ int parse_pes_padding(Bitstream_t *bitstr, PesHeader_t *header, PesPacket_t *packet) { TRACE_INFO(MPS, BLD_GREEN " parse_pes_padding()" CLR_RESET); int retcode = SUCCESS; if (header->payload_length != 0) { skip_bits(bitstr, header->payload_length * 8); TRACE_INFO(MPS, " > skip_padding_packet() >> %i bytes", header->payload_length); retcode = SUCCESS; } else { while (read_bits(bitstr, 8) == 0xFF) { // Manually skipping the padding bytes } } return retcode; } /* ************************************************************************** */ /*! * \brief Parse the 'body' of a PES packet containing audio data. * \param bitstr: Our bitstream reader. * \param header * \param packet * \param map * \return */ //int parse_pes_a(Bitstream_t *bitstr, PesHeader_t *header, PesPacket_t *packet, // MediaStream_t *map) //{ // TRACE_2(MPS, "> parse_pes_a()"); // int retcode = SUCCESS; // // if (header->stream_id == SID_PRIVATE_STREAM_1) // { // // Look for a known "non-MPEG" start code // uint32_t startcode = read_bits(bitstr, 32); // // if ((startcode & 0xFF000000) == 0x80000000) // { // map->stream_codec = CODEC_AC3; // // //pc_uint16 crc1 = (read & 0x0000FFFF); // uint8_t read = read_bits(bitstr, 8); // uint8_t fscod = (read & 0xC0) >> 6; // uint8_t frmsizcod = (read & 0x3F); // // switch (fscod) // { // case 0: // map->sampling_rate = 48000.0; // break; // case 1: // map->sampling_rate = 44100.0; // break; // case 2: // map->sampling_rate = 32000.0; // break; // default: // TRACE_WARNING(MPS, "Unsupported AC3 fscod %u", fscod); // retcode = FAILURE; // break; // } // // switch (frmsizcod) // { // case 0: // case 1: // map->bitrate_avg = 32; // break; // case 2: // case 3: // map->bitrate_avg = 40; // break; // case 4: // case 5: // map->bitrate_avg = 48; // break; // case 6: // case 7: // map->bitrate_avg = 56; // break; // case 8: // case 9: // map->bitrate_avg = 64; // break; // case 10: // case 11: // map->bitrate_avg = 80; // break; // case 12: // case 13: // map->bitrate_avg = 96; // break; // case 14: // case 15: // map->bitrate_avg = 112; // break; // case 16: // case 17: // map->bitrate_avg = 128; // break; // case 18: // case 19: // map->bitrate_avg = 160; // break; // case 20: // case 21: // map->bitrate_avg = 192; // break; // case 22: // case 23: // map->bitrate_avg = 224; // break; // case 24: // case 25: // map->bitrate_avg = 256; // break; // case 26: // case 27: // map->bitrate_avg = 320; // break; // case 28: // case 29: // map->bitrate_avg = 384; // break; // case 30: // case 31: // map->bitrate_avg = 448; // break; // case 32: // case 33: // map->bitrate_avg = 512; // break; // case 34: // case 35: // map->bitrate_avg = 576; // break; // case 36: // case 37: // map->bitrate_avg = 640; // break; // default: // TRACE_WARNING(MPS, "Unsupported AC3 frmsizcod %u", frmsizcod); // retcode = FAILURE; // break; // } // } // else if ((startcode == 0x7FFE8001) || // (startcode == 0x64582025)) // { // map->stream_codec = CODEC_DTS; // // // 28 first bits are ignored // uint32_t read = read_bits(bitstr, 16); // read = read_bits(bitstr, 32); // // //uint32_t FSIZE = 0; // Might be necessary to skip the frame and go read the extension // //uint32_t AMODE = (read & 0x000FC000) >> 18; // uint32_t SFREQ = (read & 0x00003C00) >> 10; // uint32_t RATE = (read & 0x000003E0) >> 5; // // switch (SFREQ) // { // case 1: // map->sampling_rate = 8000; // break; // case 2: // map->sampling_rate = 16000; // break; // case 3: // map->sampling_rate = 32000; // break; // case 6: // map->sampling_rate = 11025; // break; // case 7: // map->sampling_rate = 22050; // break; // case 8: // map->sampling_rate = 44100; // break; // case 11: // map->sampling_rate = 12000; // break; // case 12: // map->sampling_rate = 24000; // break; // case 13: // map->sampling_rate = 48000; // break; // default: // TRACE_WARNING(MPS, "Unsupported DTS SFREQ %u", SFREQ); // retcode = FAILURE; // break; // } // // switch (RATE) // { // case 0: // map->bitrate_avg = 32000; // break; // case 1: // map->bitrate_avg = 56000; // break; // case 2: // map->bitrate_avg = 64000; // break; // case 3: // map->bitrate_avg = 96000; // break; // case 4: // map->bitrate_avg = 112000; // break; // case 5: // map->bitrate_avg = 128000; // break; // case 6: // map->bitrate_avg = 192000; // break; // case 7: // map->bitrate_avg = 224000; // break; // case 8: // map->bitrate_avg = 256000; // break; // case 9: // map->bitrate_avg = 320000; // break; // case 10: // map->bitrate_avg = 384000; // break; // case 11: // map->bitrate_avg = 448000; // break; // case 12: // map->bitrate_avg = 512000; // break; // case 13: // map->bitrate_avg = 576000; // break; // case 14: // map->bitrate_avg = 640000; // break; // case 15: // map->bitrate_avg = 768000; // break; // case 16: // map->bitrate_avg = 960000; // break; // case 17: // map->bitrate_avg = 1024000; // break; // case 18: // map->bitrate_avg = 1152000; // break; // case 19: // map->bitrate_avg = 1280000; // break; // case 20: // map->bitrate_avg = 1344000; // break; // case 21: // map->bitrate_avg = 1408000; // break; // case 22: // map->bitrate_avg = 1411000; // break; // case 23: // map->bitrate_avg = 1472000; // break; // case 24: // map->bitrate_avg = 1536000; // break; // case 29: // map->bitrate_avg = 2048000; // Speficifation says "open" // break; // default: // TRACE_WARNING(MPS, "Unsupported DTS RATE %u", RATE); // retcode = FAILURE; // break; // } // } // else // audio codec in private stream could also be : LPCM, AAC, ... ? // { // TRACE_WARNING(MPS, "Unknown audio codec (0x%08X) inside audio private stream", startcode); // retcode = FAILURE; // } // } // else // { // // Look for a known MP3 start code // uint16_t read = read_bits(bitstr, 16); // // if ((read & 0xFFF0) == 0xFFF0) // { // uint16_t audio_version_id = (read & 0x000C) >> 2; // uint16_t layer_index = (read & 0x0003); // // read = read_bits(bitstr, 8); // uint16_t bitrate_index = (read & 0x0078) >> 3; // uint16_t samplingrate_index = (read & 0x0006) >> 1; // // uint32_t _mpeg_version = 0; // uint32_t _mpeg_layer = 0; // // switch (audio_version_id) // { // case 0x00: // _mpeg_version = 3; // MPEG-2.5 // break; // // case 0x01: // case 0x02: // _mpeg_version = 2; // MPEG-2 // break; // // case 0x03: // _mpeg_version = 1; // MPEG-1 // break; // } // // switch (layer_index) // { // case 0x03: // _mpeg_layer = 1; // Layer 1 // map->stream_codec = CODEC_MPEG_L1; // break; // // case 0x02: // _mpeg_layer = 2; // Layer 2 // map->stream_codec = CODEC_MPEG_L2; // break; // // default: // case 0x01: // case 0x00: // reserved // _mpeg_layer = 3; // Layer 3 // map->stream_codec = CODEC_MPEG_L3; // break; // } // // //map->bitrate = bitrate_index_table[_mpeg_version - 1][_mpeg_layer - 1][bitrate_index]; // //map->sampling_rate = samplingrate_index_table[_mpeg_version - 1][samplingrate_index]; // //_mpeg_sampleperframe = sampleperframe_table[_mpeg_version - 1][_mpeg_layer - 1]; // } // else // { // TRACE_WARNING(MPS, "Unknown ES type (0x%04X) inside PES audio packet (id: 0x%02X)", // read, header->stream_id); // retcode = FAILURE; // } // } // // return retcode; //} // ///* ************************************************************************** */ // ///*! // * \brief Parse the 'body' of a PES packet containing video data. // * \param bitstr: Our bitstream reader. // * \param header // * \param packet // * \param map // * \return // */ //int parse_pes_v(Bitstream_t *bitstr, PesHeader_t *header, PesPacket_t *packet, // MediaStream_t *map) //{ // TRACE_2(MPS, "> parse_pes_v()"); // int retcode = SUCCESS; // // // Avoid trying to get infos from a splitted video sample // if (packet->PTS) // { // TRACE_2(MPS, "Trying get_video_infos() @ "); // // TRACE_INFO(MPS, "parse_pes_v() 0x%X @ %lli", // header->start_code, bitstream_get_absolute_byte_offset(bitstr)); // // // Look for a sequence header start code // uint32_t start_code = read_bits(bitstr, 32); // // // MPEG-1/2 // if (start_code == 0x000001B3) // { // uint32_t sizes = read_bits(bitstr, 32); // uint32_t aspect_ratio_index = (sizes & 0x000000F0) >> 4; // uint32_t framerate_index = (sizes & 0x0000000F); // // map->color_matrix = COLOR_SPC_BT709; // map->width = (sizes & 0xFFF00000) >> 20; // map->height = (sizes & 0x000FFF00) >> 8; // // uint32_t _mpeg_version = 2; // // if (_mpeg_version == 1) // { // map->stream_codec = CODEC_MPEG1; // // switch (aspect_ratio_index) // { // case 1: // map->display_aspect_ratio = 1.0; // break; // case 8: // case 12: // map->display_aspect_ratio = (4.0 / 3.0); // break; // case 3: // case 6: // map->display_aspect_ratio = (16.0 / 9.0); // break; // default: // TRACE_WARNING(MPS, "Unsupported MPEG-1 aspect_ratio_index %u", aspect_ratio_index); // retcode = FAILURE; // break; // } // } // else // if (_mpeg_version == 2) // { // map->stream_codec = CODEC_MPEG2; // // switch (aspect_ratio_index) // { // case 1: // map->video_aspect_ratio = 1.0; // break; // case 2: // map->video_aspect_ratio = (4.0 / 3.0); // break; // case 3: // map->video_aspect_ratio = (16.0 / 9.0); // break; // case 4: // map->video_aspect_ratio = (2.21 / 1.0); // break; // default: // TRACE_WARNING(MPS, "Unsupported MPEG-2 aspect_ratio_index %u", aspect_ratio_index); // retcode = FAILURE; // break; // } // } // // switch (framerate_index) // { // case 1: // map->framerate = 23.976; // map->framerate_num = 24000; // map->framerate_base = 1001; // break; // case 2: // map->framerate = 24.0; // map->framerate_num = 24; // map->framerate_base = 1; // break; // case 3: // map->framerate = 25.0; // map->framerate_num = 25; // map->framerate_base = 1; // break; // case 4: // map->framerate = 29.970; // map->framerate_num = 30000; // map->framerate_base = 1001; // break; // case 5: // map->framerate = 30.0; // map->framerate_num = 30; // map->framerate_base = 1; // break; // case 6: // map->framerate = 50.0; // map->framerate_num = 50; // map->framerate_base = 1; // break; // case 7: // map->framerate = 59.940; // map->framerate_num = 60000; // map->framerate_base = 1001; // break; // case 8: // map->framerate = 60.0; // map->framerate_num = 60; // map->framerate_base = 1; // break; // default: // TRACE_WARNING(MPS, "Unsupported MPEG-1/2 framerate_index %u", framerate_index); // retcode = FAILURE; // break; // } // } // else // { // TRACE_WARNING(MPS, "Unknown ES type (0x%08X) inside PES video packet (id: 0x%02X)", // start_code, header->stream_id); // retcode = FAILURE; // } // } // // return retcode; //} /* ************************************************************************** */