GStreamer官方插件mpegpsdemux支持G.711

1、mpegpsdemux插件不支持G.711的原因
1.1、ISO13818支持的音频类型
1.2、GB28181支持的音视频类型
总结:由于官方插件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;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值