0

使用以下代码,我通过 UDP 获得相同的数据,但是返回有关Sequence Parameter SetsDecodeFrameNoDelay的错误。

我在 libvlc 配置或 openh264 使用中缺少什么吗?

广播部分:

// broadcaster.h
class Broadcaster
{
    ...

    std::vector<uint8_t> audioBuffer_;
    std::vector<uint8_t> videoBuffer_;
};

// broadcaster.cpp
void cbVideoPrerender(void* p_video_data, uint8_t** pp_pixel_buffer, int size)
{
    Broadcaster::instance()->videoPrerender(p_video_data, pp_pixel_buffer, size);
}

void cbVideoPostrender(
    void* p_video_data, uint8_t* p_pixel_buffer, int width, int height, int pixel_pitch, int size, int64_t pts)
{
    Broadcaster::instance()->videoPostrender(p_video_data, p_pixel_buffer, width, height, pixel_pitch, size, pts);
}

void Broadcaster::videoPrerender(void* p_video_data, uint8_t** pp_pixel_buffer, int size)
{
    spdlog::debug("videoPrerender");
    videoBuffer_.resize(size);
    *pp_pixel_buffer = videoBuffer_.data();
}

void Broadcaster::videoPostrender(
    void* p_video_data, uint8_t* p_pixel_buffer, int width, int height, int pixel_pitch, int size, int64_t pts)
{
    spdlog::debug("videoPostrender");

    std::vector<unsigned char> frame;
    frame.resize(size);
    memcpy(frame.data(), p_pixel_buffer, size);
    spdlog::debug("size: {}", size);
    // sending data over UDP
}

Broadcaster::Broadcaster()
{
    std::ostringstream stream;
    stream << "#transcode{vcodec=h264,venc=x264{profile=baseline,level=3.0},vb=800,scale=1,acodec=mp3,ab=128,channels=2,samplerate=44100}:smem{";
    stream << "video-prerender-callback=" << (long long int)(intptr_t)(void*)&cbVideoPrerender << ",";
    stream << "video-postrender-callback=" << (long long int)(intptr_t)(void*)&cbVideoPostrender << ",";
    stream << "audio-prerender-callback=" << (long long int)(intptr_t)(void*)&cbAudioPrerender << ",";
    stream << "audio-postrender-callback=" << (long long int)(intptr_t)(void*)&cbAudioPostrender << ",";
    stream << "audio-data=" << (long long int)0 << ",";
    stream << "video-data=" << (long long int)0 << "";
    stream << "},";

    inst_ = libvlc_new(0, NULL);

    std::vector<const char*> params = {
        "sout", "sout-all", "screen-top=0", "screen-left=0", "screen-width=1920", "screen-height=1080", "screen-fps=10"};

    libvlc_vlm_add_broadcast(inst_, "stream", "screen://", stream.str().c_str(), params.size(), params.data(), 1, 0);
}

解码部分(基于https://github.com/cisco/openh264/wiki/UsageExampleForDecoder):

// streamwindow.h
class StreamWindow
{
    ...

    ISVCDecoder*   pSvcDecoder_;
    unsigned char* pData_[3];
    SDecodingParam sDecParam_ = {0};
};

// streamwindow.cpp
static spdlog::level::level_enum openh264_to_spdlog(int level)
{
    switch (level)
    {
    case WELS_LOG_QUIET:
        return spdlog::level::level_enum::trace;
    case WELS_LOG_ERROR:
        return spdlog::level::level_enum::err;
    case WELS_LOG_WARNING:
        return spdlog::level::level_enum::warn;
    case WELS_LOG_INFO:
        return spdlog::level::level_enum::info;
    case WELS_LOG_DEBUG:
        return spdlog::level::level_enum::debug;
    case WELS_LOG_DETAIL:
        return spdlog::level::level_enum::info;
    default:
        return spdlog::level::level_enum::debug;
    }
}

static void openh264_spdlog(void* context, int level, const char* message)
{
    spdlog::log(openh264_to_spdlog(level), message);
}

StreamWindow::StreamWindow()
{
    WelsCreateDecoder(&pSvcDecoder_);
    sDecParam_.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_SVC;
    pSvcDecoder_->Initialize(&sDecParam_);

    int               log_level = WELS_LOG_DETAIL;
    WelsTraceCallback callback_function;
    callback_function = openh264_spdlog;
    pSvcDecoder_->SetOption(DECODER_OPTION_TRACE_LEVEL, &log_level);
    pSvcDecoder_->SetOption(DECODER_OPTION_TRACE_CALLBACK, (void*)&callback_function);

    ...
}

// called on received udp data
void StreamWindow::decodeStreamData(unsigned char* data, int size)
{
    SBufferInfo sDstBufInfo;
    memset(&sDstBufInfo, 0, sizeof(SBufferInfo));
    DECODING_STATE iRet = pSvcDecoder_->DecodeFrameNoDelay(data, size, pData_, &sDstBufInfo);
    if (iRet != 0)
    {
        spdlog::warn("DecodeFrameNoDelay failed: 0x{0:x}", iRet);
    }

    ...
}

编辑:

libVLC 日志

[00007f2f440011f0] x264 encoder: using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
[00007f2f440011f0] x264 encoder: profile Constrained Baseline, level 3.0, 4:2:0, 8-bit
[00007f2f440011f0] x264 encoder: final ratefactor: 38.99
[00007f2f440011f0] x264 encoder: using SAR=1/1
[00007f2f440011f0] x264 encoder: using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
[00007f2f440011f0] x264 encoder: profile Constrained Baseline, level 3.0, 4:2:0, 8-bit

decodeStreamData 日志

[2020-09-07 21:52:38.463] [debug] decodeStreamData, size: 47022
[2020-09-07 21:52:38.464] [warning] [OpenH264] this = 0x0x5630b8e202b0, Warning:parse_nal(), no exist Sequence Parameter Sets ahead of sequence when try to decode NAL(type:5).
[2020-09-07 21:52:38.464] [info] [OpenH264] this = 0x0x5630b8e202b0, Info:decode failed, failure type:16 

[2020-09-07 21:52:38.464] [warning] DecodeFrameNoDelay failed: 0x10
4

1 回答 1

0

VLC 日志报告流是高调的。Open264 仅支持基线配置文件。

于 2020-09-07T15:19:57.263 回答