使用libavformat将H.264帧复用到RTP中

时间:2016-11-22 20:15:15

标签: c++ c ffmpeg libav libavformat

我有一个编码器,可以产生一系列H.264 I帧和P帧。我正在尝试使用libavformat来复用并通过RTP传输这些帧,但我被卡住了。

我的程序发送RTP数据,但RTP时间戳每个连续帧递增1,而不是90000 / fps。它看起来似乎没有为H.264 NAL做正确的帧,因为我无法在Wireshark中将流解码为H.264。

我怀疑我没有正确设置编解码器信息,但它出现在输出格式上下文的许多地方,因此不清楚究竟需要设置什么。这些示例似乎都是从编码器复制编解码器上下文信息,这不是我的用例。

这就是我正在尝试的:

int main() {
    AVFormatContext context = avformat_alloc_context();

    if (!context) {
        printf("avformat_alloc_context failed\n");
        return;
    }

    AVOutputFormat *format = av_guess_format("rtp", NULL, NULL);

    if (!format) {
        printf("av_guess_format failed\n");
        return;
    }

    context->oformat = format;

    snprintf(context->filename, sizeof(context->filename), "rtp://%s:%d", "192.168.2.16", 10000);

    if (avio_open(&(context->pb), context->filename, AVIO_FLAG_READ_WRITE) < 0) {
        printf("avio_open failed\n");
        return;
    }

    stream = avformat_new_stream(context, NULL);

    if (!stream) {
        printf("avformat_new_stream failed\n");
        return;
    }

    stream->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
    stream->codecpar->codec_id = AV_CODEC_ID_H264;
    stream->codecpar->width = 1920;
    stream->codecpar->height = 1080;

    avformat_write_header(context, NULL);

    ...
    write packets
    ...
}

示例写包:

int write_packet(uint8_t *data, int size) {
    AVPacket p;
    av_init_packet(&p);
    p.data = buffer;
    p.size = size;
    p.stream_index = stream->index;

    av_interleaved_write_frame(context, &p);
}

我甚至到目前为止都在构建libx264,找到编码器,并将编解码器上下文信息从那里复制到流codecpar中,结果相同。我的目标是在没有libx264和任何其他不需要的库的情况下构建,但不清楚libx264是否需要默认值,例如时基。

如何初始化libavformat RTP复用器以通过RTCP + RTP正确发送H.264帧?

0 个答案:

没有答案