Skip to content

Commit

Permalink
while (true) の追加
Browse files Browse the repository at this point in the history
  • Loading branch information
enm10k committed Apr 8, 2024
1 parent 33f988e commit 1a1cb15
Showing 1 changed file with 70 additions and 68 deletions.
138 changes: 70 additions & 68 deletions src/hwenc_vpl/vpl_video_decoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,20 +228,59 @@ int32_t VplVideoDecoderImpl::Decode(const webrtc::EncodedImage& input_image,
// これだとキューイングしたデータとずれるので、本当は surface と一緒に保存して利用するべき
uint64_t pts = input_image.RtpTimestamp();

mfxStatus sts;
mfxSyncPoint syncp;
mfxFrameSurface1* out_surface = nullptr;
RTC_LOG(LS_VERBOSE) << "before DataOffset=" << bitstream_.DataOffset
<< " DataLength=" << bitstream_.DataLength;
while (true) {
sts = decoder_->DecodeFrameAsync(&bitstream_, &*surface, &out_surface,
&syncp);
if (sts == MFX_WRN_DEVICE_BUSY) {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
continue;
mfxStatus sts;
mfxSyncPoint syncp;
mfxFrameSurface1* out_surface = nullptr;
RTC_LOG(LS_VERBOSE) << "before DataOffset=" << bitstream_.DataOffset
<< " DataLength=" << bitstream_.DataLength;
while (true) {
sts = decoder_->DecodeFrameAsync(&bitstream_, &*surface, &out_surface,
&syncp);
RTC_LOG(LS_VERBOSE) << "DecodeFrameAsync sts=" << sts;
if (sts == MFX_WRN_DEVICE_BUSY) {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
continue;
}
// 受信した映像のサイズが変わってたら width_, height_ を更新する
if (sts == MFX_WRN_VIDEO_PARAM_CHANGED) {
mfxVideoParam param;
memset(&param, 0, sizeof(param));
sts = decoder_->GetVideoParam(&param);
if (sts != MFX_ERR_NONE) {
return WEBRTC_VIDEO_CODEC_ERROR;
}

if (width_ != param.mfx.FrameInfo.CropW ||
height_ != param.mfx.FrameInfo.CropH) {
RTC_LOG(LS_INFO) << "Change Frame Size: " << width_ << "x" << height_
<< " to " << param.mfx.FrameInfo.CropW << "x"
<< param.mfx.FrameInfo.CropH;
width_ = param.mfx.FrameInfo.CropW;
height_ = param.mfx.FrameInfo.CropH;
}
continue;
}

break;
}
RTC_LOG(LS_VERBOSE) << "after DataOffset=" << bitstream_.DataOffset
<< " DataLength=" << bitstream_.DataLength;
if (sts == MFX_ERR_MORE_DATA) {
// もっと入力が必要なので出直す
return WEBRTC_VIDEO_CODEC_OK;
}
if (!syncp) {
RTC_LOG(LS_WARNING) << "Failed to DecodeFrameAsync: syncp is null, sts="
<< (int)sts;
return WEBRTC_VIDEO_CODEC_OK;
}
// 受信した映像のサイズが変わってたら width_, height_ を更新する
if (sts == MFX_WRN_VIDEO_PARAM_CHANGED) {
VPL_CHECK_RESULT(sts, MFX_ERR_NONE, sts);

// H264 は sts == MFX_WRN_VIDEO_PARAM_CHANGED でハンドリングできるのでここではチェックしない
// VP9 は受信フレームのサイズが変わっても MFX_WRN_VIDEO_PARAM_CHANGED を返さないようなので、
// ここで毎フレーム情報を取得してサイズを更新する。
if (codec_ == MFX_CODEC_VP9) {
mfxVideoParam param;
memset(&param, 0, sizeof(param));
sts = decoder_->GetVideoParam(&param);
Expand All @@ -257,65 +296,28 @@ int32_t VplVideoDecoderImpl::Decode(const webrtc::EncodedImage& input_image,
width_ = param.mfx.FrameInfo.CropW;
height_ = param.mfx.FrameInfo.CropH;
}
continue;
}

break;
}
RTC_LOG(LS_VERBOSE) << "after DataOffset=" << bitstream_.DataOffset
<< " DataLength=" << bitstream_.DataLength;
if (sts == MFX_ERR_MORE_DATA) {
// もっと入力が必要なので出直す
return WEBRTC_VIDEO_CODEC_OK;
}
if (!syncp) {
RTC_LOG(LS_WARNING) << "Failed to DecodeFrameAsync: syncp is null, sts="
<< (int)sts;
return WEBRTC_VIDEO_CODEC_OK;
sts = MFXVideoCORE_SyncOperation(GetVplSession(session_), syncp, 600000);
VPL_CHECK_RESULT(sts, MFX_ERR_NONE, sts);

// NV12 から I420 に変換
rtc::scoped_refptr<webrtc::I420Buffer> i420_buffer =
buffer_pool_.CreateI420Buffer(width_, height_);
libyuv::NV12ToI420(out_surface->Data.Y, out_surface->Data.Pitch,
out_surface->Data.UV, out_surface->Data.Pitch,
i420_buffer->MutableDataY(), i420_buffer->StrideY(),
i420_buffer->MutableDataU(), i420_buffer->StrideU(),
i420_buffer->MutableDataV(), i420_buffer->StrideV(),
width_, height_);

webrtc::VideoFrame decoded_image = webrtc::VideoFrame::Builder()
.set_video_frame_buffer(i420_buffer)
.set_timestamp_rtp(pts)
.build();
decode_complete_callback_->Decoded(decoded_image, absl::nullopt,
absl::nullopt);
}
VPL_CHECK_RESULT(sts, MFX_ERR_NONE, sts);

// H264 は sts == MFX_WRN_VIDEO_PARAM_CHANGED でハンドリングできるのでここではチェックしない
// VP9 は受信フレームのサイズが変わっても MFX_WRN_VIDEO_PARAM_CHANGED を返さないようなので、
// ここで毎フレーム情報を取得してサイズを更新する。
if (codec_ == MFX_CODEC_VP9) {
mfxVideoParam param;
memset(&param, 0, sizeof(param));
sts = decoder_->GetVideoParam(&param);
if (sts != MFX_ERR_NONE) {
return WEBRTC_VIDEO_CODEC_ERROR;
}

if (width_ != param.mfx.FrameInfo.CropW ||
height_ != param.mfx.FrameInfo.CropH) {
RTC_LOG(LS_INFO) << "Change Frame Size: " << width_ << "x" << height_
<< " to " << param.mfx.FrameInfo.CropW << "x"
<< param.mfx.FrameInfo.CropH;
width_ = param.mfx.FrameInfo.CropW;
height_ = param.mfx.FrameInfo.CropH;
}
}

sts = MFXVideoCORE_SyncOperation(GetVplSession(session_), syncp, 600000);
VPL_CHECK_RESULT(sts, MFX_ERR_NONE, sts);

// NV12 から I420 に変換
rtc::scoped_refptr<webrtc::I420Buffer> i420_buffer =
buffer_pool_.CreateI420Buffer(width_, height_);
libyuv::NV12ToI420(out_surface->Data.Y, out_surface->Data.Pitch,
out_surface->Data.UV, out_surface->Data.Pitch,
i420_buffer->MutableDataY(), i420_buffer->StrideY(),
i420_buffer->MutableDataU(), i420_buffer->StrideU(),
i420_buffer->MutableDataV(), i420_buffer->StrideV(),
width_, height_);

webrtc::VideoFrame decoded_image = webrtc::VideoFrame::Builder()
.set_video_frame_buffer(i420_buffer)
.set_timestamp_rtp(pts)
.build();
decode_complete_callback_->Decoded(decoded_image, absl::nullopt,
absl::nullopt);

return WEBRTC_VIDEO_CODEC_OK;
}

Expand Down

0 comments on commit 1a1cb15

Please sign in to comment.