/* * aux_pes.c * * Copyright (C) Thomas Oestreich - June 2001 * * This file is part of transcode, a video stream processing tool * * transcode is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * transcode 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 GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "transcode.h" #include "libtc/libtc.h" #include "ioaux.h" #include "aux_pes.h" static char * aspect_ratio_information_str[16] = { "Invalid Aspect Ratio", "1:1", "4:3", "16:9", "2.21:1", "Invalid Aspect Ratio", "Invalid Aspect Ratio", "Invalid Aspect Ratio", "4:3", "Invalid Aspect Ratio", "Invalid Aspect Ratio", "4:3", "Invalid Aspect Ratio", "Invalid Aspect Ratio", "Invalid Aspect Ratio" }; static char * frame_rate_str[16] = { "Invalid frame_rate_code", "23.976", "24", "25" , "29.97", "30" , "50", "59.94", "60" , "1", "5", "10", "12", "15", //libmpeg3 only "Invalid frame_rate_code", "Invalid frame_rate_code" }; int stats_sequence_silent(uint8_t * buffer, seq_info_t *seq_info) { int horizontal_size; int vertical_size; int aspect_ratio_information; int frame_rate_code; int bit_rate_value; vertical_size = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2]; horizontal_size = ((vertical_size >> 12) + 15) & ~15; vertical_size = ((vertical_size & 0xfff) + 15) & ~15; aspect_ratio_information = buffer[3] >> 4; frame_rate_code = buffer[3] & 15; bit_rate_value = (buffer[4] << 10) | (buffer[5] << 2) | (buffer[6] >> 6); if(aspect_ratio_information < 0 || aspect_ratio_information>15) { tc_log_error(__FILE__, "****** invalid MPEG sequence header detected (%d/%d|%d/%d) ******", aspect_ratio_information, 16, frame_rate_code, 16); return(-1); } if(frame_rate_code < 0 || frame_rate_code>15) { tc_log_error(__FILE__, "****** invalid MPEG sequence header detected (%d/%d|%d/%d) ******", frame_rate_code, 16, aspect_ratio_information, 8); return(-1); } //fill out user structure seq_info->w = horizontal_size; seq_info->h = vertical_size; seq_info->ari = aspect_ratio_information; seq_info->frc = frame_rate_code; seq_info->brv = bit_rate_value; return(0); } int stats_sequence(uint8_t * buffer, seq_info_t *seq_info) { int horizontal_size; int vertical_size; int aspect_ratio_information; int frame_rate_code; int bit_rate_value; int vbv_buffer_size_value; int constrained_parameters_flag; int load_intra_quantizer_matrix; int load_non_intra_quantizer_matrix; vertical_size = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2]; horizontal_size = ((vertical_size >> 12) + 15) & ~15; vertical_size = ((vertical_size & 0xfff) + 15) & ~15; aspect_ratio_information = buffer[3] >> 4; frame_rate_code = buffer[3] & 15; bit_rate_value = (buffer[4] << 10) | (buffer[5] << 2) | (buffer[6] >> 6); vbv_buffer_size_value = ((buffer[6] << 5) | (buffer[7] >> 3)) & 0x3ff; constrained_parameters_flag = buffer[7] & 4; load_intra_quantizer_matrix = buffer[7] & 2; if (load_intra_quantizer_matrix) buffer += 64; load_non_intra_quantizer_matrix = buffer[7] & 1; if(aspect_ratio_information < 0 || aspect_ratio_information>15) { tc_log_error(__FILE__, "****** invalid MPEG sequence header detected (%d/%d|%d/%d) ******", aspect_ratio_information, 16, frame_rate_code, 16); return(-1); } if(frame_rate_code < 0 || frame_rate_code>15) { tc_log_error(__FILE__, "****** invalid MPEG sequence header detected (%d/%d|%d/%d) ******", frame_rate_code, 16, aspect_ratio_information, 8); return(-1); } tc_log_msg(__FILE__, "sequence: %dx%d %s, %s fps, %5.0f kbps, VBV %d kB%s%s%s", horizontal_size, vertical_size, aspect_ratio_information_str [aspect_ratio_information], frame_rate_str [frame_rate_code], bit_rate_value * 400.0 / 1000.0, 2 * vbv_buffer_size_value, constrained_parameters_flag ? " , CP":"", load_intra_quantizer_matrix ? " , Custom Intra Matrix":"", load_non_intra_quantizer_matrix ? " , Custom Non-Intra Matrix":""); //fill out user structure seq_info->w = horizontal_size; seq_info->h = vertical_size; seq_info->ari = aspect_ratio_information; seq_info->frc = frame_rate_code; seq_info->brv = bit_rate_value; return(0); } int get_pts_dts(char *buffer, unsigned long *pts, unsigned long *dts) { unsigned int pes_header_bytes = 0; unsigned int pts_dts_flags; int pes_header_data_length; int has_pts_dts=0; unsigned int ptr=0; /* drop first 8 bits */ ++ptr; pts_dts_flags = (buffer[ptr++] >> 6) & 0x3; pes_header_data_length = buffer[ptr++]; switch(pts_dts_flags) { case 2: *pts = (buffer[ptr++] >> 1) & 7; //low 4 bits (7==1111) *pts <<= 15; *pts |= (stream_read_int16(&buffer[ptr]) >> 1); ptr+=2; *pts <<= 15; *pts |= (stream_read_int16(&buffer[ptr]) >> 1); ptr+=2; pes_header_bytes += 5; has_pts_dts=1; break; case 3: *pts = (buffer[ptr++] >> 1) & 7; //low 4 bits (7==1111) *pts <<= 15; *pts |= (stream_read_int16(&buffer[ptr]) >> 1); ptr+=2; *pts <<= 15; *pts |= (stream_read_int16(&buffer[ptr]) >> 1); ptr+=2; *dts = (buffer[ptr++] >> 1) & 7; *dts <<= 15; *dts |= (stream_read_int16(&buffer[ptr]) >> 1); ptr+=2; *dts <<= 15; *dts |= (stream_read_int16(&buffer[ptr]) >> 1); ptr+=2; pes_header_bytes += 10; has_pts_dts=1; break; default: has_pts_dts=0; *dts=*pts=0; break; } return(has_pts_dts); }