1、mpegpsdemux插件不支持G.711的原因
1.1、ISO13818支持的音频类型
![](https://img-blog.csdnimg.cn/bcbde55971c648f2886e88bc6f5be1b1.png)
1.2、GB28181支持的音视频类型
![](https://img-blog.csdnimg.cn/97e85f8113484edb83f74d0a0bb52d69.png)
总结:由于官方插件mpegpsdemux插件是按ISO13818国际标准实现的,所以不支持G.711的编码需要修改源码。
2、源码分析并修改支持G.711
2.1、定义G.711宏
/* Stream type assignments
*
* 0x00 ITU-T | ISO/IEC Reserved
* 0x01 ISO/IEC 11172 Video
* 0x02 ITU-T Rec. H.262 | ISO/IEC 13818-2 Video or
* ISO/IEC 11172-2 constrained parameter video
* stream
* 0x03 ISO/IEC 11172 Audio
* 0x04 ISO/IEC 13818-3 Audio
* 0x05 ITU-T Rec. H.222.0 | ISO/IEC 13818-1
* private_sections
* 0x06 ITU-T Rec. H.222.0 | ISO/IEC 13818-1 PES
* packets containing private data
* 0x07 ISO/IEC 13522 MHEG
* 0x08 ITU-T Rec. H.222.0 | ISO/IEC 13818-1 Annex A
* DSM CC
* 0x09 ITU-T Rec. H.222.1
* 0x0A ISO/IEC 13818-6 type A
* 0x0B ISO/IEC 13818-6 type B
* 0x0C ISO/IEC 13818-6 type C
* 0x0D ISO/IEC 13818-6 type D
* 0x0E ISO/IEC 13818-1 auxiliary
* 0x0F-0x7F ITU-T Rec. H.222.0 | ISO/IEC 13818-1 Reserved
* 0x80-0xFF User Private
*/
#define ST_RESERVED 0x00
#define ST_VIDEO_MPEG1 0x01
#define ST_VIDEO_MPEG2 0x02
#define ST_AUDIO_MPEG1 0x03
#define ST_AUDIO_MPEG2 0x04
#define ST_PRIVATE_SECTIONS 0x05
#define ST_PRIVATE_DATA 0x06
#define ST_MHEG 0x07
#define ST_DSMCC 0x08
#define ST_H222_1 0x09
#define ST_AUDIO_ALAW 0x90 //G.711
#define ST_AUDIO_MULAW 0x91
2.2、解析流时创建G.711流的GstPad
static GstPsStream *
gst_ps_demux_create_stream(GstPsDemux * demux, gint id, gint stream_type,
gint layer)
{
GstPsStream *stream;
GstPadTemplate *template;
gchar *name;
GstPsDemuxClass *klass = GST_PS_DEMUX_GET_CLASS(demux);
GstCaps *caps;
GstClockTime threshold = SEGMENT_THRESHOLD;
GstEvent *event;
gchar *stream_id;
name = NULL;
template = NULL;
caps = NULL;
GST_DEBUG_OBJECT(demux, "create stream id 0x%02x, type 0x%02x", id,
stream_type);
switch (stream_type) {
case ST_VIDEO_MPEG1:
case ST_VIDEO_MPEG2:
case ST_VIDEO_MPEG4:
case ST_GST_VIDEO_MPEG1_OR_2:
{
gint mpeg_version = 1;
if (stream_type == ST_VIDEO_MPEG2 ||
(stream_type == ST_GST_VIDEO_MPEG1_OR_2 && demux->is_mpeg2_pack)) {
mpeg_version = 2;
}
if (stream_type == ST_VIDEO_MPEG4) {
mpeg_version = 4;
}
template = klass->video_template;
name = g_strdup_printf("video_%02x", id);
caps = gst_caps_new_simple("video/mpeg",
"mpegversion", G_TYPE_INT, mpeg_version,
"systemstream", G_TYPE_BOOLEAN, FALSE,
"parsed", G_TYPE_BOOLEAN, FALSE, NULL);
threshold = VIDEO_SEGMENT_THRESHOLD;
break;
}
case ST_AUDIO_MPEG1:
case ST_AUDIO_MPEG2:
template = klass->audio_template;
name = g_strdup_printf("audio_%02x", id);
if (layer) {
caps = gst_caps_new_simple("audio/mpeg",
"mpegversion", G_TYPE_INT, 1, "layer", G_TYPE_INT, layer, NULL);
}
else {
caps = gst_caps_new_simple("audio/mpeg",
"mpegversion", G_TYPE_INT, 1, NULL);
}
break;
case ST_PRIVATE_SECTIONS:
case ST_PRIVATE_DATA:
case ST_MHEG:
case ST_DSMCC:
break;
case ST_AUDIO_AAC_ADTS:
template = klass->audio_template;
name = g_strdup_printf("audio_%02x", id);
caps = gst_caps_new_simple("audio/mpeg",
"mpegversion", G_TYPE_INT, 4,
"stream-format", G_TYPE_STRING, "adts", NULL);
break;
case ST_AUDIO_AAC_LOAS: // LATM/LOAS AAC syntax
template = klass->audio_template;
name = g_strdup_printf("audio_%02x", id);
caps = gst_caps_new_simple("audio/mpeg",
"mpegversion", G_TYPE_INT, 4,
"stream-format", G_TYPE_STRING, "loas", NULL);
break;
case ST_VIDEO_H264:
template = klass->video_template;
name = g_strdup_printf("video_%02x", id);
caps = gst_caps_new_simple("video/x-h264",
"stream-format", G_TYPE_STRING, "byte-stream", NULL);
threshold = VIDEO_SEGMENT_THRESHOLD;
break;
case ST_VIDEO_H265:
template = klass->video_template;
name = g_strdup_printf("video_%02x", id);
caps = gst_caps_new_simple("video/x-h265",
"stream-format", G_TYPE_STRING, "byte-stream", NULL);
threshold = VIDEO_SEGMENT_THRESHOLD;
break;
case ST_PS_AUDIO_AC3:
template = klass->audio_template;
name = g_strdup_printf("audio_%02x", id);
caps = gst_caps_new_empty_simple("audio/x-private1-ac3");
break;
case ST_PS_AUDIO_DTS:
template = klass->audio_template;
name = g_strdup_printf("audio_%02x", id);
caps = gst_caps_new_empty_simple("audio/x-private1-dts");
break;
case ST_PS_AUDIO_LPCM:
template = klass->audio_template;
name = g_strdup_printf("audio_%02x", id);
caps = gst_caps_new_empty_simple("audio/x-private1-lpcm");
break;
case ST_PS_DVD_SUBPICTURE:
template = klass->subpicture_template;
name = g_strdup_printf("subpicture_%02x", id);
caps = gst_caps_new_empty_simple("subpicture/x-dvd");
break;
case ST_GST_AUDIO_RAWA52:
template = klass->audio_template;
name = g_strdup_printf("audio_%02x", id);
caps = gst_caps_new_empty_simple("audio/ac3");
break;
case ST_AUDIO_ALAW: //G.711支持
template = klass->audio_template;
name = g_strdup_printf("audio_%02x", id);
caps = gst_caps_new_empty_simple("audio/x_alaw");
break;
case ST_AUDIO_MULAW:
template = klass->audio_template;
name = g_strdup_printf("audio_%02x", id);
caps = gst_caps_new_empty_simple("audio/x-mulaw");
break;
default:
break;
}
if (name == NULL || template == NULL || caps == NULL) {
g_free(name);
if (caps)
gst_caps_unref(caps);
return FALSE;
}
stream = g_new0(GstPsStream, 1);
stream->id = id;
stream->discont = TRUE;
stream->need_segment = TRUE;
stream->notlinked = FALSE;
stream->type = stream_type;
stream->pending_tags = NULL;
stream->pad = gst_pad_new_from_template(template, name);
stream->segment_thresh = threshold;
gst_pad_set_event_function(stream->pad,
GST_DEBUG_FUNCPTR(gst_ps_demux_src_event));
gst_pad_set_query_function(stream->pad,
GST_DEBUG_FUNCPTR(gst_ps_demux_src_query));
gst_pad_use_fixed_caps(stream->pad);
/* needed for set_caps to work */
if (!gst_pad_set_active(stream->pad, TRUE)) {
GST_WARNING_OBJECT(demux, "Failed to activate pad %" GST_PTR_FORMAT,
stream->pad);
}
stream_id = gst_pad_create_stream_id_printf(stream->pad, GST_ELEMENT_CAST(demux),"%02x", id);
event = gst_pad_get_sticky_event(demux->sinkpad, GST_EVENT_STREAM_START, 0);
if (event) {
if (gst_event_parse_group_id(event, &demux->group_id))
demux->have_group_id = TRUE;
else
demux->have_group_id = FALSE;
gst_event_unref(event);
}
else if (!demux->have_group_id) {
demux->have_group_id = TRUE;
demux->group_id = gst_util_group_id_next();
}
event = gst_event_new_stream_start(stream_id);
if (demux->have_group_id)
gst_event_set_group_id(event, demux->group_id);
gst_pad_push_event(stream->pad, event);
g_free(stream_id);
gst_pad_set_caps(stream->pad, caps);
if (!stream->pending_tags)
stream->pending_tags = gst_tag_list_new_empty();
gst_pb_utils_add_codec_description_to_tag_list(stream->pending_tags, NULL,caps);
GST_DEBUG_OBJECT(demux, "create pad %s, caps %" GST_PTR_FORMAT, name, caps);
gst_caps_unref(caps);
g_free(name);
return stream;
}