如何正确复用编码的h264数据包?

时间:2016-09-20 15:20:38

标签: c++ libav libavformat

我正在从我的网络摄像头抓取视频帧并尝试通过RTMP(特别是YouTube)直播。我已经能够从相机中成功抓取YUV420p帧,在h.264中对其进行编码,但是当我尝试将其发送到多路复用器时,它不会将其正确编码到流中。

我怀疑我在初始化时未能设置重要参数,或者在错误的顺序中做了某些事情。我也尝试过使用av_write_frame函数和av_interleaved_write_frame。

为了便于测试,我现在将输出转到flv文件。我将FILE_TEST_PATH定义为我希望保存文件的路径。

这是我的初始化函数:

void rtmp_stream::init(string url, int width, int height)
{
    //if(avio_open2(&formatCtx->pb, url.c_str(), AVIO_FLAG_READ_WRITE , NULL, NULL))
    if(avio_open2(&formatCtx->pb, FILE_TEST_PATH , AVIO_FLAG_WRITE, NULL, NULL))
    {
        printf("Error\n");
    }

    avformat_new_stream(formatCtx, codec);
    formatCtx->streams[0]->codecpar->format=AV_PIX_FMT_YUV420P;
    formatCtx->streams[0]->codecpar->bit_rate=4000000;
    formatCtx->streams[0]->codecpar->width=width;
    formatCtx->streams[0]->codecpar->height=height;
    formatCtx->streams[0]->codecpar->codec_id = codec->id;


    formatCtx->streams[0]->time_base=(AVRational){1,1000};
    strcpy(formatCtx->filename, FILE_TEST_PATH);

    /*
     * It says using stream->codec is depricated but yet it does not populate codecpar
     * without setting these up.
     */

    formatCtx->streams[0]->codec->width=width;
    formatCtx->streams[0]->codec->height=height;
    formatCtx->streams[0]->codec->pix_fmt=AV_PIX_FMT_YUV420P;
    formatCtx->streams[0]->codec->codec_id = codec->id;
    formatCtx->streams[0]->codec->bit_rate=4000000;
    formatCtx->streams[0]->codec->pix_fmt=AV_PIX_FMT_YUV420P;
    formatCtx->streams[0]->codec->max_b_frames=3;


    formatCtx->video_codec_id=formatCtx->streams[0]->codecpar->codec_id;

    codecCtx->bit_rate=4000000;
    codecCtx->bit_rate_tolerance=0;
    codecCtx->framerate=(AVRational){1,1};
    codecCtx->gop_size=12;
    codecCtx->height=height;
    codecCtx->width=width;
    codecCtx->pix_fmt=AV_PIX_FMT_YUV420P;
    codecCtx->time_base=(AVRational){1,25};
    codecCtx->max_b_frames=3;

    avcodec_open2(codecCtx, codec, NULL);
    avformat_write_header(formatCtx, NULL);

}

这是将编码的h.264数据包发送到多路复用器的代码

void rtmp_stream::send_packet()
{
    av_packet_rescale_ts(packet, codecCtx->time_base, formatCtx->streams[0]->time_base);
    if(av_write_frame(formatCtx, packet))
        printf("ERROR\n");
}

其他信息: 我知道相机的画面有效且有效。 我已将来自编码器的h.264数据包转储到“.h264”文件并在VLC中播放它们并且它们播放正常。 我现在也只是处理视频。

如果需要查看更多代码,我的git gub帐户中有代码。 https://github.com/chrismacias37/Heads-Up-Display

0 个答案:

没有答案