Files
2026-08-24 10:03:24 +08:00

143 lines
5.7 KiB
C

/* GStreamer
* Copyright (C) 2023 <[email protected]>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "ts_patpmt_parse.h"
#include <gst/gst.h>
#include <stdio.h>
GST_DEBUG_CATEGORY_EXTERN(gst_amlhwdmx_table_debug);
#ifdef GST_CAT_DEFAULT
#undef GST_CAT_DEFAULT
#endif
#define GST_CAT_DEFAULT gst_amlhwdmx_table_debug
int adjust_PAT_table(TS_PAT *packet, unsigned char *buffer)
{
GST_DEBUG("adjust_PAT_table trace in");
memset(packet->program, 0, sizeof(TS_PAT_Program) * MAX_PROGRAM_NUM);
packet->program_num = 0;
packet->table_id = buffer[0];
packet->section_syntax_indicator = buffer[1] >> 7;
packet->zero = buffer[1] >> 6 & 0x1;
packet->reserved_1 = buffer[1] >> 4 & 0x3;
packet->section_length = (buffer[1] & 0x0F) << 8 | buffer[2];
packet->transport_stream_id = buffer[3] << 8 | buffer[4];
packet->reserved_2 = buffer[5] >> 6;
packet->version_number = buffer[5] >> 1 & 0x1F;
packet->current_next_indicator = (buffer[5] << 7) >> 7;
packet->section_number = buffer[6];
packet->last_section_number = buffer[7];
int len = 0;
len = 3 + packet->section_length;
packet->CRC_32 = (buffer[len - 4] & 0x000000FF) << 24 | (buffer[len - 3] & 0x000000FF) << 16 | (buffer[len - 2] & 0x000000FF) << 8 | (buffer[len - 1] & 0x000000FF);
int n = 0;
for (n = 0; n < packet->section_length - 12; n += 4)
{
unsigned program_num = buffer[8 + n] << 8 | buffer[9 + n];
packet->reserved_3 = buffer[10 + n] >> 5;
packet->network_PID = 0x00;
if (program_num == 0x00)
{
packet->network_PID = (buffer[10 + n] & 0x1F) << 8 | buffer[11 + n];
GST_DEBUG(" packet->network_PID %0x", packet->network_PID);
}
else
{
// TS_PAT_Program PAT_program;
// PAT_program.program_map_PID = (buffer[10 + n] & 0x1F) << 8 | buffer[11 + n];
// PAT_program.program_number = program_num;
// packet->program.push_back(PAT_program);
// TS_program.push_back(PAT_program);
packet->program[packet->program_num].program_map_PID = (buffer[10 + n] & 0x1F) << 8 | buffer[11 + n];
packet->program[packet->program_num].program_number = program_num;
GST_DEBUG("find PMT[%d] pid:%d, num:%d", packet->program_num, packet->program[packet->program_num].program_map_PID, packet->program[packet->program_num].program_number);
packet->program_num++;
}
}
return 0;
}
int adjust_PMT_table(TS_PMT *packet, unsigned char *buffer)
{
GST_DEBUG("adjust_PMT_table trace in");
memset(packet->PMT_Stream, 0, sizeof(TS_PMT_Stream) * MAX_STREAM_NUM);
packet->PMT_Stream_num = 0;
packet->table_id = buffer[0];
packet->section_syntax_indicator = buffer[1] >> 7;
packet->zero = buffer[1] >> 6 & 0x01;
packet->reserved_1 = buffer[1] >> 4 & 0x03;
packet->section_length = (buffer[1] & 0x0F) << 8 | buffer[2];
packet->program_number = buffer[3] << 8 | buffer[4];
packet->reserved_2 = buffer[5] >> 6;
packet->version_number = buffer[5] >> 1 & 0x1F;
packet->current_next_indicator = (buffer[5] << 7) >> 7;
packet->section_number = buffer[6];
packet->last_section_number = buffer[7];
packet->reserved_3 = buffer[8] >> 5;
packet->PCR_PID = ((buffer[8] << 8) | buffer[9]) & 0x1FFF;
packet->reserved_4 = buffer[10] >> 4;
packet->program_info_length = (buffer[10] & 0x0F) << 8 | buffer[11];
// Get CRC_32
int len = 0;
len = packet->section_length + 3;
packet->CRC_32 = (buffer[len - 4] & 0x000000FF) << 24 | (buffer[len - 3] & 0x000000FF) << 16 | (buffer[len - 2] & 0x000000FF) << 8 | (buffer[len - 1] & 0x000000FF);
int pos = 12;
// program info descriptor
if (packet->program_info_length != 0)
pos += packet->program_info_length;
// Get stream type and PID
for (; pos <= (packet->section_length + 2) - 4;)
{
TS_PMT_Stream *pmt_stream = &packet->PMT_Stream[packet->PMT_Stream_num];
pmt_stream->stream_type = buffer[pos];
packet->reserved_5 = buffer[pos + 1] >> 5;
pmt_stream->elementary_PID = ((buffer[pos + 1] << 8) | buffer[pos + 2]) & 0x1FFF;
packet->reserved_6 = buffer[pos + 3] >> 4;
pmt_stream->ES_info_length = (buffer[pos + 3] & 0x0F) << 8 | buffer[pos + 4];
memset(pmt_stream->descriptor, 0, STREAM_DESCRIPTOR_SIZE);
if (pmt_stream->ES_info_length != 0 && pmt_stream->ES_info_length < STREAM_DESCRIPTOR_SIZE)
{
memcpy(pmt_stream->descriptor,&buffer[pos + 5],pmt_stream->ES_info_length);
pos += pmt_stream->ES_info_length;
}
else
{
GST_ERROR("ES_info_length is %d",pmt_stream->ES_info_length);
}
pos += 5;
// packet->PMT_Stream.push_back(pmt_stream);
// TS_Stream_type.push_back(pmt_stream);
packet->PMT_Stream_num++;
if (packet->PMT_Stream_num >= MAX_STREAM_NUM)
{
GST_ERROR("PMT_Stream_num=%d, too many.", packet->PMT_Stream_num);
break;
}
}
return 0;
}