From 007134838b9d48d7cd770b6a731ce77e5140499b Mon Sep 17 00:00:00 2001 From: dijunkun Date: Wed, 8 Nov 2023 16:29:16 +0800 Subject: [PATCH] Fix openh264 decoder frame loss --- .../decode/openh264/openh264_decoder.cpp | 81 +++++-------------- .../video/decode/openh264/openh264_decoder.h | 5 +- .../video/decode/video_decoder_factory.cpp | 4 +- .../encode/openh264/openh264_encoder.cpp | 6 +- .../video/encode/video_encoder_factory.cpp | 4 +- xmake.lua | 1 - 6 files changed, 26 insertions(+), 75 deletions(-) diff --git a/src/media/video/decode/openh264/openh264_decoder.cpp b/src/media/video/decode/openh264/openh264_decoder.cpp index ed5a0b0..ba7734a 100644 --- a/src/media/video/decode/openh264/openh264_decoder.cpp +++ b/src/media/video/decode/openh264/openh264_decoder.cpp @@ -26,7 +26,7 @@ static const int YUV420P_BUFFER_SIZE = 1280 * 720 * 3 / 2; void CopyYUVWithStride(uint8_t *srcY, uint8_t *srcU, uint8_t *srcV, int width, int height, int strideY, int strideU, int strideV, - uint8_t *dst) { + uint8_t *yuv_data_) { int actualWidth = width; int actualHeight = height; @@ -35,21 +35,21 @@ void CopyYUVWithStride(uint8_t *srcY, uint8_t *srcU, uint8_t *srcV, int width, int actualStrideV = actualWidth / 2; for (int row = 0; row < actualHeight; row++) { - memcpy(dst, srcY, actualStrideY); + memcpy(yuv_data_, srcY, actualStrideY); srcY += strideY; - dst += actualStrideY; + yuv_data_ += actualStrideY; } for (int row = 0; row < actualHeight / 2; row++) { - memcpy(dst, srcU, actualStrideU); + memcpy(yuv_data_, srcU, actualStrideU); srcU += strideU; - dst += actualStrideU; + yuv_data_ += actualStrideU; } for (int row = 0; row < actualHeight / 2; row++) { - memcpy(dst, srcV, actualStrideV); + memcpy(yuv_data_, srcV, actualStrideV); srcV += strideV; - dst += actualStrideV; + yuv_data_ += actualStrideV; } } @@ -88,23 +88,6 @@ OpenH264Decoder::~OpenH264Decoder() { delete nv12_frame_; } - if (pData[0]) { - delete pData[0]; - } - - if (pData[1]) { - delete pData[1]; - } - - if (pData[2]) { - delete pData[2]; - } - - if (pData_tmp) { - delete pData_tmp; - pData_tmp = nullptr; - } - if (SAVE_H264_STREAM && h264_stream_) { fflush(h264_stream_); h264_stream_ = nullptr; @@ -137,14 +120,6 @@ int OpenH264Decoder::Init() { decoded_frame_size_ = YUV420P_BUFFER_SIZE; decoded_frame_ = new uint8_t[YUV420P_BUFFER_SIZE]; nv12_frame_ = new uint8_t[YUV420P_BUFFER_SIZE]; - // pData[0] = new uint8_t[1280 * 720]; - // pData[1] = new uint8_t[1280 * 720 / 4]; - // pData[2] = new uint8_t[1280 * 720 / 4]; - - pData_tmp = new uint8_t[frame_width_ * frame_height_ * 3 / 2]; - // *pData = pData_tmp; - // *(pData + 1) = pData_tmp + frame_width_ * frame_height_; - // *(pData + 2) = pData_tmp + (frame_width_ * frame_height_ * 5) / 4; if (WelsCreateDecoder(&openh264_decoder_) != 0) { LOG_ERROR("Failed to create OpenH264 decoder"); @@ -160,11 +135,9 @@ int OpenH264Decoder::Init() { int32_t iRet = openh264_decoder_->Initialize(&sDecParam); - int trace_level = WELS_LOG_WARNING; + int trace_level = WELS_LOG_QUIET; openh264_decoder_->SetOption(DECODER_OPTION_TRACE_LEVEL, &trace_level); - LOG_ERROR("inited"); - printf("1 this is %p\n", this); return 0; } @@ -182,36 +155,18 @@ int OpenH264Decoder::Decode( SBufferInfo sDstBufInfo = {0}; memset(&sDstBufInfo, 0, sizeof(SBufferInfo)); - unsigned char *dst[3]; + int iRet = openh264_decoder_->DecodeFrameNoDelay(data, size, yuv_data_, + &sDstBufInfo); - int iRet = openh264_decoder_->DecodeFrame2(data, size, dst, &sDstBufInfo); - // int iRet = - // openh264_decoder_->DecodeFrameNoDelay(data, size, dst, &sDstBufInfo); - - if (iRet != 0) { - return -1; - } - - // int num_of_buffer = 0; - // iRet = openh264_decoder_->GetOption( - // DECODER_OPTION_NUM_OF_FRAMES_REMAINING_IN_BUFFER, &num_of_buffer); - - // LOG_ERROR("Number of buffer {} {}", num_of_buffer, iRet); - - // iRet = openh264_decoder_->FlushFrame(dst, &sDstBufInfo); - // if (iRet != 0) { - // LOG_ERROR("FlushFrame state: {}", iRet); - // return -1; - // } - - if (1) { + if (sDstBufInfo.iBufferStatus == 1) { if (on_receive_decoded_frame) { - CopyYUVWithStride( - dst[0], dst[1], dst[2], sDstBufInfo.UsrData.sSystemBuffer.iWidth, - sDstBufInfo.UsrData.sSystemBuffer.iHeight, - sDstBufInfo.UsrData.sSystemBuffer.iStride[0], - sDstBufInfo.UsrData.sSystemBuffer.iStride[1], - sDstBufInfo.UsrData.sSystemBuffer.iStride[1], decoded_frame_); + CopyYUVWithStride(yuv_data_[0], yuv_data_[1], yuv_data_[2], + sDstBufInfo.UsrData.sSystemBuffer.iWidth, + sDstBufInfo.UsrData.sSystemBuffer.iHeight, + sDstBufInfo.UsrData.sSystemBuffer.iStride[0], + sDstBufInfo.UsrData.sSystemBuffer.iStride[1], + sDstBufInfo.UsrData.sSystemBuffer.iStride[1], + decoded_frame_); if (SAVE_NV12_STREAM) { fwrite((unsigned char *)decoded_frame_, 1, diff --git a/src/media/video/decode/openh264/openh264_decoder.h b/src/media/video/decode/openh264/openh264_decoder.h index b70e9f2..e1121ae 100644 --- a/src/media/video/decode/openh264/openh264_decoder.h +++ b/src/media/video/decode/openh264/openh264_decoder.h @@ -35,12 +35,9 @@ class OpenH264Decoder : public VideoDecoder { uint8_t* decoded_frame_ = nullptr; int decoded_frame_size_ = 0; uint8_t* nv12_frame_ = nullptr; - unsigned char* pData[3] = {}; int frame_width_ = 1280; int frame_height_ = 720; - - uint8_t* pData_tmp = nullptr; - uint8_t* pData_tmp_2 = nullptr; + unsigned char* yuv_data_[3]; }; #endif \ No newline at end of file diff --git a/src/media/video/decode/video_decoder_factory.cpp b/src/media/video/decode/video_decoder_factory.cpp index 5e330a6..a0c440c 100644 --- a/src/media/video/decode/video_decoder_factory.cpp +++ b/src/media/video/decode/video_decoder_factory.cpp @@ -26,8 +26,8 @@ std::unique_ptr VideoDecoderFactory::CreateVideoDecoder( return nullptr; } } else { - return std::make_unique(FfmpegVideoDecoder()); - // return std::make_unique(OpenH264Decoder()); + // return std::make_unique(FfmpegVideoDecoder()); + return std::make_unique(OpenH264Decoder()); } #endif } diff --git a/src/media/video/encode/openh264/openh264_encoder.cpp b/src/media/video/encode/openh264/openh264_encoder.cpp index 5deccb8..92419fe 100644 --- a/src/media/video/encode/openh264/openh264_encoder.cpp +++ b/src/media/video/encode/openh264/openh264_encoder.cpp @@ -120,8 +120,8 @@ int OpenH264Encoder::Init() { encoded_frame_ = new uint8_t[YUV420P_BUFFER_SIZE]; - // int trace_level = WELS_LOG_WARNING; - // openh264_encoder_->SetOption(ENCODER_OPTION_TRACE_LEVEL, &trace_level); + int trace_level = WELS_LOG_QUIET; + openh264_encoder_->SetOption(ENCODER_OPTION_TRACE_LEVEL, &trace_level); // Create encoder parameters based on the layer configuration. SEncParamExt encoder_params = CreateEncoderParams(); @@ -196,7 +196,7 @@ int OpenH264Encoder::Encode( return -1; } -#if 0 +#if 1 size_t required_capacity = 0; size_t fragments_count = 0; for (int layer = 0; layer < info.iLayerNum; ++layer) { diff --git a/src/media/video/encode/video_encoder_factory.cpp b/src/media/video/encode/video_encoder_factory.cpp index fdfc588..405d7b9 100644 --- a/src/media/video/encode/video_encoder_factory.cpp +++ b/src/media/video/encode/video_encoder_factory.cpp @@ -26,8 +26,8 @@ std::unique_ptr VideoEncoderFactory::CreateVideoEncoder( return nullptr; } } else { - return std::make_unique(FFmpegVideoEncoder()); - // return std::make_unique(OpenH264Encoder()); + // return std::make_unique(FFmpegVideoEncoder()); + return std::make_unique(OpenH264Encoder()); } #endif } diff --git a/xmake.lua b/xmake.lua index 2081048..1b35d13 100644 --- a/xmake.lua +++ b/xmake.lua @@ -31,7 +31,6 @@ if is_os("windows") then add_packages("vcpkg::libnice") add_requires("openh264 2.1.1", {configs = {shared = false}}) elseif is_os("linux") then - add_requireconfs("ffmpeg.x264", {configs = {pic = true}}) add_requires("ffmpeg 5.1.2") add_requires("glib", {system = true}) add_requires("vcpkg::libnice 0.1.21")