amlhwdmx: CB1 deal with private data [1/1]
PD#SWPL-180067
Problem:
e-ac3 codec, can't play, need to deal with
GST_MPEGTS_STREAM_TYPE_PRIVATE_PES_PACKETS
Solution:
add deal with GST_MPEGTS_STREAM_TYPE_PRIVATE_PES_PACKETS
Verify:
ap222
Change-Id: I542a7b0f25911a7e0f1df44968a998d2e430798c
Signed-off-by: hanghang.luo <hanghang.luo@amlogic.com>
diff --git a/src/aml_defs.h b/src/aml_defs.h
index 68b1ac0..b221c70 100644
--- a/src/aml_defs.h
+++ b/src/aml_defs.h
@@ -116,7 +116,6 @@
#define GST_AML_TS_INFO_VIDEO_PID "video-pid"
#define GST_AML_TS_INFO_AUDIO_PID "audio-pid"
-
/** for debug **/
// #define DBG_SECMEM
@@ -169,6 +168,93 @@
/* 0x80 - 0xff : User Private (or defined in other specs) */
} GstMpegtsStreamType;
+/**
+ * GstMpegtsDVBDescriptorType:
+ *
+ * The type of #GstMpegtsDescriptor
+ *
+ * These values correspond to the registered descriptor type from
+ * the various DVB specifications.
+ *
+ * Consult the relevant specifications for more details.
+ */
+typedef enum {
+ /* 64-127 DVB tags ETSI EN 300 468
+ * (Specification for Service Information (SI) in DVB systems)
+ */
+ GST_MTS_DESC_DVB_NETWORK_NAME = 0x40,
+ GST_MTS_DESC_DVB_SERVICE_LIST = 0x41,
+ GST_MTS_DESC_DVB_STUFFING = 0x42,
+ GST_MTS_DESC_DVB_SATELLITE_DELIVERY_SYSTEM = 0x43,
+ GST_MTS_DESC_DVB_CABLE_DELIVERY_SYSTEM = 0x44,
+ GST_MTS_DESC_DVB_VBI_DATA = 0x45,
+ GST_MTS_DESC_DVB_VBI_TELETEXT = 0x46,
+ GST_MTS_DESC_DVB_BOUQUET_NAME = 0x47,
+ GST_MTS_DESC_DVB_SERVICE = 0x48,
+ GST_MTS_DESC_DVB_COUNTRY_AVAILABILITY = 0x49,
+ GST_MTS_DESC_DVB_LINKAGE = 0x4A,
+ GST_MTS_DESC_DVB_NVOD_REFERENCE = 0x4B,
+ GST_MTS_DESC_DVB_TIME_SHIFTED_SERVICE = 0x4C,
+ GST_MTS_DESC_DVB_SHORT_EVENT = 0x4D,
+ GST_MTS_DESC_DVB_EXTENDED_EVENT = 0x4E,
+ GST_MTS_DESC_DVB_TIME_SHIFTED_EVENT = 0x4F,
+ GST_MTS_DESC_DVB_COMPONENT = 0x50,
+ GST_MTS_DESC_DVB_MOSAIC = 0x51,
+ GST_MTS_DESC_DVB_STREAM_IDENTIFIER = 0x52,
+ GST_MTS_DESC_DVB_CA_IDENTIFIER = 0x53,
+ GST_MTS_DESC_DVB_CONTENT = 0x54,
+ GST_MTS_DESC_DVB_PARENTAL_RATING = 0x55,
+ GST_MTS_DESC_DVB_TELETEXT = 0x56,
+ GST_MTS_DESC_DVB_TELEPHONE = 0x57,
+ GST_MTS_DESC_DVB_LOCAL_TIME_OFFSET = 0x58,
+ GST_MTS_DESC_DVB_SUBTITLING = 0x59,
+ GST_MTS_DESC_DVB_TERRESTRIAL_DELIVERY_SYSTEM = 0x5A,
+ GST_MTS_DESC_DVB_MULTILINGUAL_NETWORK_NAME = 0x5B,
+ GST_MTS_DESC_DVB_MULTILINGUAL_BOUQUET_NAME = 0x5C,
+ GST_MTS_DESC_DVB_MULTILINGUAL_SERVICE_NAME = 0x5D,
+ GST_MTS_DESC_DVB_MULTILINGUAL_COMPONENT = 0x5E,
+ GST_MTS_DESC_DVB_PRIVATE_DATA_SPECIFIER = 0x5F,
+ GST_MTS_DESC_DVB_SERVICE_MOVE = 0x60,
+ GST_MTS_DESC_DVB_SHORT_SMOOTHING_BUFFER = 0x61,
+ GST_MTS_DESC_DVB_FREQUENCY_LIST = 0x62,
+ /**
+ * GST_MTS_DESC_DVB_PARTIAL_TRANSPORT_STREAM:
+ *
+ * Partial Transport Stream descriptor. Only present in SIT Sections.
+ *
+ * See also: %GST_MPEGTS_SECTION_SIT, %GstMpegtsSIT
+ */
+ GST_MTS_DESC_DVB_PARTIAL_TRANSPORT_STREAM = 0x63,
+ GST_MTS_DESC_DVB_DATA_BROADCAST = 0x64,
+ GST_MTS_DESC_DVB_SCRAMBLING = 0x65,
+ GST_MTS_DESC_DVB_DATA_BROADCAST_ID = 0x66,
+ GST_MTS_DESC_DVB_TRANSPORT_STREAM = 0x67,
+ GST_MTS_DESC_DVB_DSNG = 0x68,
+ GST_MTS_DESC_DVB_PDC = 0x69,
+ GST_MTS_DESC_DVB_AC3 = 0x6A,
+ GST_MTS_DESC_DVB_ANCILLARY_DATA = 0x6B,
+ GST_MTS_DESC_DVB_CELL_LIST = 0x6C,
+ GST_MTS_DESC_DVB_CELL_FREQUENCY_LINK = 0x6D,
+ GST_MTS_DESC_DVB_ANNOUNCEMENT_SUPPORT = 0x6E,
+ GST_MTS_DESC_DVB_APPLICATION_SIGNALLING = 0x6F,
+ GST_MTS_DESC_DVB_ADAPTATION_FIELD_DATA = 0x70,
+ GST_MTS_DESC_DVB_SERVICE_IDENTIFIER = 0x71,
+ GST_MTS_DESC_DVB_SERVICE_AVAILABILITY = 0x72,
+ GST_MTS_DESC_DVB_DEFAULT_AUTHORITY = 0x73,
+ GST_MTS_DESC_DVB_RELATED_CONTENT = 0x74,
+ GST_MTS_DESC_DVB_TVA_ID = 0x75,
+ GST_MTS_DESC_DVB_CONTENT_IDENTIFIER = 0x76,
+ GST_MTS_DESC_DVB_TIMESLICE_FEC_IDENTIFIER = 0x77,
+ GST_MTS_DESC_DVB_ECM_REPETITION_RATE = 0x78,
+ GST_MTS_DESC_DVB_S2_SATELLITE_DELIVERY_SYSTEM = 0x79,
+ GST_MTS_DESC_DVB_ENHANCED_AC3 = 0x7A,
+ GST_MTS_DESC_DVB_DTS = 0x7B,
+ GST_MTS_DESC_DVB_AAC = 0x7C,
+ GST_MTS_DESC_DVB_XAIT_LOCATION = 0x7D,
+ GST_MTS_DESC_DVB_FTA_CONTENT_MANAGEMENT = 0x7E,
+ GST_MTS_DESC_DVB_EXTENSION = 0x7F,
+} GstMpegtsDVBDescriptorType;
+
/* audio codec types(using in seure case. copy from aml_aucpu.h) */
typedef enum
{
diff --git a/src/gstamldmx.c b/src/gstamldmx.c
index b6b7c73..04c00f6 100644
--- a/src/gstamldmx.c
+++ b/src/gstamldmx.c
@@ -1313,8 +1313,21 @@
}
case GST_MPEGTS_STREAM_TYPE_PRIVATE_PES_PACKETS:
{
+ GPtrArray * array = NULL;
+
GST_LOG("private data");
- // TODO: handle codec info saves in descriptor
+ array = gst_parse_descriptors (pmt_stream->descriptor, pmt_stream->ES_info_length);
+ if (gst_find_descriptor(array, GST_MTS_DESC_DVB_ENHANCED_AC3))
+ {
+ GST_LOG("ac3 audio");
+ is_audio = TRUE;
+ caps = gst_caps_new_empty_simple("audio/x-eac3");
+ }
+ else
+ {
+ GST_WARNING("can't parse des");
+ }
+ g_ptr_array_free(array, TRUE);
break;
}
case GST_MPEGTS_STREAM_TYPE_AUDIO_AAC_ADTS:
diff --git a/src/gstamldmxfilter.c b/src/gstamldmxfilter.c
index 4d6eec8..5810c0a 100644
--- a/src/gstamldmxfilter.c
+++ b/src/gstamldmxfilter.c
@@ -23,12 +23,26 @@
#include <gst/allocators/gstdmabuf.h>
#include <stdio.h>
+typedef struct
+{
+ guint8 tag;
+ guint8 tag_extension;
+ guint8 length;
+ guint8 *data;
+ guint32 codec_tag;
+
+ /*< private >*/
+ /* Padding for future extension */
+ gpointer _gst_reserved[GST_PADDING];
+} GstMpegtsDescriptor ;
+
static gint get_prog_id(GstAmlhwdmx *amlhwdmx, int fid);
static GstBuffer *gst_es_filter_construct_buf(GstDmxSrcStreamPad *spad, int dev_no, int fid, const guint *data, int len);
static GstBuffer *gst_es_filter_construct_non_sec_buf(GstAmlhwdmx *amlhwdmx, int dev_no, int fid, const guint *data, int len);
static GstBuffer *gst_es_filter_construct_sec_buf(GstAmlhwdmx *amlhwdmx, int dev_no, int fid, const guint *data, int len);
static void gst_es_filter_dbg_non_sec_header(GstAmlhwdmx *amlhwdmx, const guint *data, int len);
-static GstAucpuStreamType gst_amlhwdmx_convert_acodectype_gst2dmx(GstMpegtsStreamType type);
+static GstAucpuStreamType gst_amlhwdmx_convert_acodectype_gst2dmx(TS_PMT_Stream stream);
+static void gst_descriptor_free(GstMpegtsDescriptor * desc);
void gst_parse_pat_cb(int dev_no, int fid, const guint *data, int len, void *user_data)
{
@@ -161,10 +175,10 @@
}
case GST_STREAM_TYPE_AUDIO:
{
- GstAucpuStreamType acodec_type;
+ GstAucpuStreamType acodec_type = MEDIA_UNKNOWN;
es_fpara->pes_type = DMX_PES_AUDIO0;
- acodec_type = gst_amlhwdmx_convert_acodectype_gst2dmx(amlhwdmx->sinkpad.pmt_para[progid].pmt.PMT_Stream[i].stream_type);
+ acodec_type = gst_amlhwdmx_convert_acodectype_gst2dmx(amlhwdmx->sinkpad.pmt_para[progid].pmt.PMT_Stream[i]);
if (acodec_type == MEDIA_UNKNOWN)
{
GST_ERROR_OBJECT(amlhwdmx, "parse acodec type error");
@@ -255,6 +269,133 @@
gst_amladapterpipe_push(adapter_pipe, buf);
}
+/**
+ * gst_descriptor_free:
+ * @desc: The descriptor to free
+ *
+ * Frees @desc
+ */
+static void gst_descriptor_free(GstMpegtsDescriptor * desc)
+{
+ g_return_val_if_fail(desc != NULL, NULL);
+ g_return_val_if_fail(desc->data != NULL, NULL);
+
+ g_free ((gpointer) desc->data);
+ g_slice_free (GstMpegtsDescriptor, desc);
+}
+
+/**
+ * gst_parse_descriptors:
+ * @buffer: (transfer none): descriptors to parse
+ * @buf_len: Size of @buffer
+ *
+ * Parses the descriptors present in @buffer and returns them as an
+ * array.
+ *
+ * Note: The data provided in @buffer will not be copied.
+ *
+ * Returns: (transfer full) (element-type GstMpegtsDescriptor): an
+ * array of the parsed descriptors or %NULL if there was an error.
+ * Release with #g_array_unref when done with it.
+ */
+GPtrArray* gst_parse_descriptors(guint8 * buffer, gsize buf_len)
+{
+ GPtrArray *res;
+ guint8 length;
+ guint8 *data;
+ guint i, nb_desc = 0;
+
+ /* fast-path */
+ if (buf_len == 0)
+ return g_ptr_array_new ();
+
+ data = buffer;
+
+ GST_MEMDUMP ("Full descriptor array", buffer, buf_len);
+
+ while (data - buffer < buf_len) {
+ data++; /* skip tag */
+ length = *data++;
+
+ if (data - buffer > buf_len) {
+ GST_WARNING ("invalid descriptor length %d now at %d max %"
+ G_GSIZE_FORMAT, length, (gint) (data - buffer), buf_len);
+ return NULL;
+ }
+
+ data += length;
+ nb_desc++;
+ }
+
+ GST_DEBUG ("Saw %d descriptors, read %" G_GSIZE_FORMAT " bytes",
+ nb_desc, (gsize) (data - buffer));
+
+ if (data - buffer != buf_len) {
+ GST_WARNING ("descriptors size %d expected %" G_GSIZE_FORMAT,
+ (gint) (data - buffer), buf_len);
+ return NULL;
+ }
+
+ res =
+ g_ptr_array_new_full (nb_desc + 1,
+ (GDestroyNotify) gst_descriptor_free);
+
+ data = buffer;
+
+ for (i = 0; i < nb_desc; i++) {
+ GstMpegtsDescriptor *desc = g_slice_new0 (GstMpegtsDescriptor);
+
+ desc->data = data;
+ desc->tag = *data++;
+ desc->length = *data++;
+ desc->codec_tag = *(guint32 *)data;
+ /* Copy the data now that we known the size */
+ desc->data = g_memdup2 (desc->data, desc->length + 2);
+ GST_LOG ("descriptor 0x%02x length:%d codec_tag %x ", desc->tag, desc->length, desc->codec_tag);
+ GST_MEMDUMP ("descriptor", desc->data + 2, desc->length);
+ /* extended descriptors */
+ if (G_UNLIKELY (desc->tag == 0x7f))
+ desc->tag_extension = *data;
+
+ data += desc->length;
+
+ /* Set the descriptor in the array */
+ g_ptr_array_index (res, i) = desc;
+ }
+
+ res->len = nb_desc;
+
+ return res;
+}
+
+/**
+ * gst_find_descriptor:
+ * @descriptors: (element-type GstMpegtsDescriptor) (transfer none): an array
+ * of #GstMpegtsDescriptor
+ * @tag: the tag to look for
+ *
+ * Finds the first descriptor of type @tag in the array.
+ *
+ * Note: To look for descriptors that can be present more than once in an
+ * array of descriptors, iterate the #GArray manually.
+ *
+ * Returns: (transfer none): the first descriptor matching @tag, else %NULL.
+ */
+const void* gst_find_descriptor(GPtrArray * descriptors, guint8 tag)
+{
+ guint i, nb_desc;
+
+ g_return_val_if_fail (descriptors != NULL, NULL);
+
+ nb_desc = descriptors->len;
+ for (i = 0; i < nb_desc; i++) {
+ GstMpegtsDescriptor *desc = g_ptr_array_index (descriptors, i);
+ if (desc->tag == tag)
+ return (const GstMpegtsDescriptor *) desc;
+ }
+ return NULL;
+}
+
void gst_es_filter_reset(GstAmlhwdmx *amlhwdmx)
{
gint dmxret;
@@ -520,25 +661,42 @@
}
}
-static GstAucpuStreamType gst_amlhwdmx_convert_acodectype_gst2dmx(GstMpegtsStreamType type)
+static GstAucpuStreamType gst_amlhwdmx_convert_acodectype_gst2dmx(TS_PMT_Stream stream)
{
-
- GST_DEBUG("input type:0x%x", type);
-
+ GstMpegtsStreamType type = stream.stream_type;
+ GST_DEBUG("stream type:0x%x ", type);
switch (type)
{
- case GST_MPEGTS_STREAM_TYPE_AUDIO_MPEG1:
- case GST_MPEGTS_STREAM_TYPE_AUDIO_MPEG2:
- return MEDIA_MPX;
- case GST_MPEGTS_STREAM_TYPE_AUDIO_AAC_ADTS:
- case GST_MPEGTS_STREAM_TYPE_AUDIO_AAC_CLEAN:
- return MEDIA_AAC_ADTS;
- case GST_MPEGTS_STREAM_TYPE_AUDIO_AAC_LATM:
- return MEDIA_AAC_LOAS;
- case GST_MPEGTS_STREAM_TYPE_AUDIO_EAC3:
- case GST_MPEGTS_STREAM_TYPE_AUDIO_AC3_PLUS:
- return MEDIA_AC3;
- default:
- return MEDIA_UNKNOWN;
+ case GST_MPEGTS_STREAM_TYPE_AUDIO_MPEG1:
+ case GST_MPEGTS_STREAM_TYPE_AUDIO_MPEG2:
+ return MEDIA_MPX;
+ case GST_MPEGTS_STREAM_TYPE_AUDIO_AAC_ADTS:
+ case GST_MPEGTS_STREAM_TYPE_AUDIO_AAC_CLEAN:
+ return MEDIA_AAC_ADTS;
+ case GST_MPEGTS_STREAM_TYPE_AUDIO_AAC_LATM:
+ return MEDIA_AAC_LOAS;
+ case GST_MPEGTS_STREAM_TYPE_AUDIO_EAC3:
+ case GST_MPEGTS_STREAM_TYPE_AUDIO_AC3_PLUS:
+ return MEDIA_AC3;
+ case GST_MPEGTS_STREAM_TYPE_PRIVATE_PES_PACKETS:
+ {
+ GPtrArray *array = NULL;
+ GstMpegtsDVBDescriptorType des_type;
+
+ array = gst_parse_descriptors(stream.descriptor, stream.ES_info_length);
+ if (gst_find_descriptor(array, GST_MTS_DESC_DVB_ENHANCED_AC3))
+ des_type = GST_MTS_DESC_DVB_ENHANCED_AC3;
+ g_ptr_array_free(array, TRUE);
+ GST_DEBUG("des type:0x%x ", des_type);
+ switch (des_type)
+ {
+ case GST_MTS_DESC_DVB_ENHANCED_AC3:
+ return MEDIA_AC3;
+ default:
+ return MEDIA_UNKNOWN;
+ }
+ }
+ default:
+ return MEDIA_UNKNOWN;
}
}
\ No newline at end of file
diff --git a/src/gstamldmxfilter.h b/src/gstamldmxfilter.h
index cb57600..ab0133d 100644
--- a/src/gstamldmxfilter.h
+++ b/src/gstamldmxfilter.h
@@ -29,6 +29,8 @@
void gst_parse_pat_cb(int dev_no, int fid, const guint *data, int len, void *user_data);
void gst_parse_pmt_cb(int dev_no, int fid, const guint *data, int len, void *user_data);
void gst_parse_es_cb(int dev_no, int fid, const guint *data, int len, void *user_data);
+const void * gst_find_descriptor (GPtrArray * descriptors, guint8 tag);
+GPtrArray *gst_parse_descriptors (guint8 * buffer, gsize buf_len);
void gst_es_filter_reset(GstAmlhwdmx *amlhwdmx);
void gst_pmt_filter_reset(GstAmlhwdmx *amlhwdmx);
void gst_pat_filter_reset(GstAmlhwdmx *amlhwdmx);
diff --git a/src/ts_patpmt_parse.c b/src/ts_patpmt_parse.c
index d2e0ed0..ecf62eb 100644
--- a/src/ts_patpmt_parse.c
+++ b/src/ts_patpmt_parse.c
@@ -112,21 +112,25 @@
packet->reserved_6 = buffer[pos + 3] >> 4;
pmt_stream->ES_info_length = (buffer[pos + 3] & 0x0F) << 8 | buffer[pos + 4];
- pmt_stream->descriptor = 0x00;
- if (pmt_stream->ES_info_length != 0)
+ memset(pmt_stream->descriptor, 0, STREAM_DESCRIPTOR_SIZE);
+ if (pmt_stream->ES_info_length != 0 && pmt_stream->ES_info_length < STREAM_DESCRIPTOR_SIZE)
{
- pmt_stream->descriptor = buffer[pos + 5];
-
- for (int len = 2; len <= pmt_stream->ES_info_length; len++)
- {
- pmt_stream->descriptor = pmt_stream->descriptor << 8 | buffer[pos + 4 + len];
- }
+ 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;
}
diff --git a/src/ts_patpmt_parse.h b/src/ts_patpmt_parse.h
index 64b2cc0..47712ae 100644
--- a/src/ts_patpmt_parse.h
+++ b/src/ts_patpmt_parse.h
@@ -36,6 +36,8 @@
#define STREAM_TYPE_AUDIO_AAC 0x0f
#define STREAM_TYPE_AUDIO_AC3 0x81
+#define STREAM_DESCRIPTOR_SIZE 128
+
GST_DEBUG_CATEGORY_EXTERN(gst_amlhwdmx_debug);
#define GST_CAT_DEFAULT gst_amlhwdmx_debug
@@ -72,7 +74,7 @@
unsigned stream_type : 8;
unsigned elementary_PID : 13;
unsigned ES_info_length : 12;
- unsigned descriptor;
+ unsigned char descriptor[STREAM_DESCRIPTOR_SIZE];
} TS_PMT_Stream;
typedef struct TS_PMT