【问题标题】:Streaming H.264 over UDP using FFmpeg, and "dimensions not set" error使用 FFmpeg 通过 UDP 流式传输 H.264,以及“未设置尺寸”错误
【发布时间】:2015-11-22 03:53:03
【问题描述】:

到目前为止,我正在尝试通过 UDP 流式传输 H.264,但没有成功。这是可以重现问题的最小代码。

编译,

g++ -o test -lavcodec -lavformat -lavutil test.cpp

补充信息,我开始ffplay如下。目前没有用。

ffplay -i udp://127.0.0.1:8554/live.sdp

我的代码输出(见avio_open()调用),

[libx264 @ 0x6a26c0] using mv_range_thread = 24
[libx264 @ 0x6a26c0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.1 Cache64
[libx264 @ 0x6a26c0] profile High, level 3.1
Output #0, h264, to 'udp://127.0.0.1:8554/live.sdp':
    Stream #0:0, 0, 0/0: Video: h264 (libx264), -1 reference frame, none, q=-1--1
[h264 @ 0x6a2020] dimensions not set
Cannot write header to stream: Success

还有代码,

extern "C" {
    #include <libavcodec/avcodec.h>
    #include <libavformat/avformat.h>
    #include <libavutil/avutil.h>
}

#include <iostream>
using namespace std;

int main() {
    AVCodecContext* m_codecContext;
    AVCodec* m_codec;
    AVFormatContext* m_formatContext;
    AVStream* m_stream;

    unsigned m_outWidth = 768;
    unsigned m_outHeight = 608;

    av_register_all();
    avcodec_register_all();
    avformat_network_init();

    int errorStatus = 0;
    char errorLog[128] = { 0 };
    av_log_set_level(AV_LOG_TRACE);

    string m_output("udp://127.0.0.1:8554/live.sdp");

    if (avformat_alloc_output_context2(&m_formatContext, NULL, "h264", m_output.c_str()) < 0) {
        cerr << "Cannot allocate output context: "
             << av_make_error_string(errorLog, 128, errorStatus) << endl;
        return -1;
    }

    AVOutputFormat *m_outputFormat = m_formatContext->oformat;

    m_codec = avcodec_find_encoder(AV_CODEC_ID_H264);
    if (!m_codec) {
        cerr << "Cannot find an encoder: "
             << av_make_error_string(errorLog, 128, errorStatus) << endl;
        return -1;
    }

    m_codecContext = avcodec_alloc_context3(m_codec);
    if (!m_codecContext) {
        cerr << "Cannot allocate a codec context: "
             << av_make_error_string(errorLog, 128, errorStatus) << endl;
        return -1;
    }

    m_codecContext->pix_fmt = AV_PIX_FMT_YUV420P;
    m_codecContext->width = m_outWidth;
    m_codecContext->height = m_outHeight;

    if (avcodec_open2(m_codecContext, m_codec, NULL) < 0) {
        cerr << "Cannot open codec: "
             << av_make_error_string(errorLog, 128, errorStatus) << endl;
        return -1;
    }

    m_stream = avformat_new_stream(m_formatContext, m_codec);
    if (!m_stream) {
        cerr << "Cannot create a new stream: "
             << av_make_error_string(errorLog, 128, errorStatus) << endl;
        return -1;
    }

    av_dump_format(m_formatContext, 0, m_output.c_str(), 1);

    if ((errorStatus = avio_open(&m_formatContext->pb, m_output.c_str(), AVIO_FLAG_WRITE)) < 0) {
        cerr << "Cannot open output: "
             << av_make_error_string(errorLog, 128, errorStatus) << endl;
        return -1;
    }

    if (avformat_write_header(m_formatContext, NULL) < 0) {
        cerr << "Cannot write header to stream: "
             << av_make_error_string(errorLog, 128, errorStatus) << endl;
        return -1;
    }

    cout << "All done." << endl;

    return 0;
}

对于那些有更多时间来解决我的问题的人,当我将m_output 更改为rtsp://127.0.0.1:8554/live.sdp,并将ffplay 命令更改为ffplay -rtsp_flags listen -i rtsp://127.0.0.1:8554/live.sdp 时,我得到了错误,

[libx264 @ 0x1e056c0] using mv_range_thread = 24
[libx264 @ 0x1e056c0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.1 Cache64
[libx264 @ 0x1e056c0] profile High, level 3.1
Output #0, h264, to 'rtsp://127.0.0.1:8554/live.sdp':
    Stream #0:0, 0, 0/0: Video: h264 (libx264), -1 reference frame, none, q=-1--1
Cannot open output: Protocol not found

我是否天真地期望流协议会这样改变?

【问题讨论】:

    标签: c++ ffmpeg streaming video-streaming rtsp


    【解决方案1】:

    显然我正在创建和初始化一个AVCodecContext,然后没有使用它。AVStream 有自己的AVCodecContext(这很明智,因为不同的流通常需要不同的编码器),它就是我需要使用尺寸和像素格式进行初始化。为此,我还需要将调用交换为avformat_new_stream()avcodec_open2(),然后先调用前者。这是修复的差异。

    请注意,m_codecContext 已被完全删除。

    --- rtsp-so.cpp.orig    2015-09-03 17:34:08.190375415 +0200
    +++ rtsp-so.cpp 2015-09-03 17:43:42.166542704 +0200
    @@ -8,7 +8,6 @@
     using namespace std;
    
     int main() {
    -    AVCodecContext* m_codecContext;
         AVCodec* m_codec;
         AVFormatContext* m_formatContext;
         AVStream* m_stream;
    @@ -41,32 +40,25 @@
             return -1;
         }
    
    -    m_codecContext = avcodec_alloc_context3(m_codec);
    -    if (!m_codecContext) {
    -        cerr << "Cannot allocate a codec context: "
    +    m_stream = avformat_new_stream(m_formatContext, m_codec);
    +    if (!m_stream) {
    +        cerr << "Cannot create a new stream: "
                  << av_make_error_string(errorLog, 128, errorStatus) << endl;
             return -1;
         }
    
    -    m_codecContext->pix_fmt = AV_PIX_FMT_YUV420P;
    -    m_codecContext->width = m_outWidth;
    -    m_codecContext->height = m_outHeight;
    +    av_dump_format(m_formatContext, 0, m_output.c_str(), 1);
    
    -    if (avcodec_open2(m_codecContext, m_codec, NULL) < 0) {
    -        cerr << "Cannot open codec: "
    -             << av_make_error_string(errorLog, 128, errorStatus) << endl;
    -        return -1;
    -    }
    +    m_stream->codec->pix_fmt = AV_PIX_FMT_YUV420P;
    +    m_stream->codec->width = m_outWidth;
    +    m_stream->codec->height = m_outHeight;
    
    -    m_stream = avformat_new_stream(m_formatContext, m_codec);
    -    if (!m_stream) {
    -        cerr << "Cannot create a new stream: "
    +    if (avcodec_open2(m_stream->codec, m_codec, NULL) < 0) {
    +        cerr << "Cannot open codec: "
                  << av_make_error_string(errorLog, 128, errorStatus) << endl;
             return -1;
         }
    
    -    av_dump_format(m_formatContext, 0, m_output.c_str(), 1);
    -
         if ((errorStatus = avio_open(&m_formatContext->pb, m_output.c_str(), AVIO_FLAG_WRITE)) < 0) {
             cerr << "Cannot open output: "
                  << av_make_error_string(errorLog, 128, errorStatus) << endl;
    

    【讨论】:

      猜你喜欢
      • 2012-04-25
      • 2018-01-24
      • 2013-05-01
      • 2013-06-23
      • 2022-08-09
      • 2016-01-16
      • 1970-01-01
      • 2013-09-22
      • 2020-08-18
      相关资源
      最近更新 更多