ffmpeg添加mpeg ps流的pcm的编码支持

    ffmpeg的mpegenc.c中,缺少了psm头的写入,而ps流的封包应当是 ps<-sys<-psm<-pes,即pes在写入sys头之后写pes之前应当先写入psm头,因此mpegenc.c中需要增加写入psm头的函数,如下:
static uint8_t get_stream_type(int stream_codec_id)
{
    uint8_t res = 0;
    switch(stream_codec_id)
    {
        case AV_CODEC_ID_PCM_MULAW:
            res = STREAM_TYPE_AUDIO_PCM_MULAW;
            break;
        case AV_CODEC_ID_MPEG2VIDEO:
            res = STREAM_TYPE_VIDEO_MPEG2;
            break;
        case AV_CODEC_ID_MP3:
            res = STREAM_TYPE_AUDIO_MPEG2;
            break;
        case AV_CODEC_ID_MPEG4:
            res = STREAM_TYPE_VIDEO_MPEG4;
            break;
        case AV_CODEC_ID_AC3:
            res = STREAM_TYPE_AUDIO_AC3;
            break;
        case AV_CODEC_ID_AAC:
            res = STREAM_TYPE_AUDIO_AAC;
            break;
        case AV_CODEC_ID_H264:
            res = STREAM_TYPE_VIDEO_H264;
            break;
        default:
            break;
    }
    return res;
}

static int put_psm_header(AVFormatContext *ctx,uint8_t *buf)
{
    MpegMuxContext *s = ctx->priv_data;
    int size, i, private_stream_coded, id;
    PutBitContext pb;
    int streamnum = 0;
    for (int i = 0 ; i < ctx->nb_streams; i++)
    {
        if (ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO
            || ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
        {
            streamnum++;
        }
    }
    int streminfolen = streamnum * 4;

    init_put_bits(&pb, buf, (16 + streminfolen) * 8);

    put_bits32(&pb, 0x000001bc);
    put_bits(&pb, 16, 10 + streminfolen);         /*program stream map length*/
    put_bits(&pb, 1, 1);          /*current next indicator */
    put_bits(&pb, 2, 3);          /*reserved*/
    put_bits(&pb, 5, 0);          /*program stream map version*/
    put_bits(&pb, 7, 0x7F);       /*reserved */
    put_bits(&pb, 1, 1);          /*marker bit */
    put_bits(&pb, 16,0);          /*programe stream info length*/
    put_bits(&pb, 16, streminfolen);         /*elementary stream map length  is*/
    for (int i = 0 ; i < ctx->nb_streams; i++)
    {
        AVStream* st = ctx->streams[i];
        if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO || st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
        {
            put_bits(&pb, 8, get_stream_type(st->codec->codec_id));       /*stream_type*/
            if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
            {
                put_bits(&pb, 8, AUDIO_ID);       /*elementary_stream_id*/
            }
            if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
            {
                put_bits(&pb, 8, VIDEO_ID);       /*elementary_stream_id*/
            }
            put_bits(&pb, 16, 0);         /*elementary_stream_info_length is*/
        }
    }
    uint32_t crc = 0;//crc32(0, buf, 13 + streminfolen);
    /*audio*/
    /*crc (2e b9 0f 3d)*/
    put_bits32(&pb, crc);       /*crc */
    flush_put_bits(&pb);
    return 16 + streminfolen;
}
    其中get_stream_type函数是用来依据编码器ID得到流类型关键字,该函数被put_psm_header调用,而put_psm_header函数是用来写入psm头的,在mpegenc.c中查找调用put_system_header函数的调用,该函数是用来写system头的,该函数中CRC值写了0进去,因为参照mpeg.c中并没有判断该数值,如果要提高输出的兼容性,应当计算起始标志之后,即头四个字节之后的crc值写进去。 该函数的调用方式一般如下:
                size = put_system_header(ctx, buf_ptr, id);
                buf_ptr += size;
    在每段该代码后都加上
                size = put_psm_header(ctx, buf_ptr);
                buf_ptr += size;
即可实现将psm头写入到mpeg流中。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值