143 lines
5.7 KiB
C
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;
|
|
}
|