From 6a7c773d516beb165eb9513a41e0bc8b59e8ffc6 Mon Sep 17 00:00:00 2001 From: rigaya Date: Wed, 8 Nov 2023 18:00:57 +0900 Subject: [PATCH] =?UTF-8?q?AV1=E3=81=A7colormatrix=E7=AD=89=E3=82=92?= =?UTF-8?q?=E9=81=A9=E5=88=87=E3=81=AB=E5=8F=8D=E6=98=A0=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=E3=80=82(=20#93=20)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VCECore/rgy_output.cpp | 85 ++++++++++++++++++++----------- VCECore/rgy_output_avcodec.cpp | 91 ++++++++++++++++++++++------------ 2 files changed, 113 insertions(+), 63 deletions(-) diff --git a/VCECore/rgy_output.cpp b/VCECore/rgy_output.cpp index 981080c2..4377b9a0 100644 --- a/VCECore/rgy_output.cpp +++ b/VCECore/rgy_output.cpp @@ -321,7 +321,7 @@ RGY_ERR RGYOutputRaw::Init(const TCHAR *strFileName, const VideoInfo *pVideoOutp } if (ENCODER_VCEENC) { // HEVCの10bitの時、エンコーダがおかしなVUIを設定することがあるのでこれを常に上書き - const bool override_always = pVideoOutputInfo->codec == RGY_CODEC_HEVC; + const bool override_always = pVideoOutputInfo->codec == RGY_CODEC_HEVC || pVideoOutputInfo->codec == RGY_CODEC_AV1; if (override_always || pVideoOutputInfo->vui.format != 5 /*undef*/) { av_dict_set_int(&bsfPrm, "video_format", pVideoOutputInfo->vui.format, 0); AddMessage(RGY_LOG_DEBUG, _T("set video_format %d by %s filter\n"), pVideoOutputInfo->vui.format, bsf_tname.c_str()); @@ -423,20 +423,58 @@ RGY_ERR RGYOutputRaw::WriteNextFrame(RGYBitstream *pBitstream) { if (!m_noOutput) { #if ENABLE_AVSW_READER if (m_pBsfc) { - uint8_t nal_type = 0; - std::vector nal_list; - if (m_VideoOutputInfo.codec == RGY_CODEC_HEVC) { - nal_type = NALU_HEVC_SPS; - nal_list = parse_nal_hevc(pBitstream->data(), pBitstream->size()); - } else if (m_VideoOutputInfo.codec == RGY_CODEC_H264) { - nal_type = NALU_H264_SPS; - nal_list = parse_nal_h264(pBitstream->data(), pBitstream->size()); - } - auto sps_nal = std::find_if(nal_list.begin(), nal_list.end(), [nal_type](nal_info info) { return info.type == nal_type; }); - if (sps_nal != nal_list.end()) { + if (m_VideoOutputInfo.codec == RGY_CODEC_H264 || m_VideoOutputInfo.codec == RGY_CODEC_HEVC) { + uint8_t nal_type = 0; + std::vector nal_list; + if (m_VideoOutputInfo.codec == RGY_CODEC_HEVC) { + nal_type = NALU_HEVC_SPS; + nal_list = parse_nal_hevc(pBitstream->data(), pBitstream->size()); + } else if (m_VideoOutputInfo.codec == RGY_CODEC_H264) { + nal_type = NALU_H264_SPS; + nal_list = parse_nal_h264(pBitstream->data(), pBitstream->size()); + } + auto sps_nal = std::find_if(nal_list.begin(), nal_list.end(), [nal_type](nal_info info) { return info.type == nal_type; }); + if (sps_nal != nal_list.end()) { + AVPacket *pkt = m_pkt.get(); + av_new_packet(pkt, (int)sps_nal->size); + memcpy(pkt->data, sps_nal->ptr, sps_nal->size); + int ret = 0; + if (0 > (ret = av_bsf_send_packet(m_pBsfc.get(), pkt))) { + av_packet_unref(pkt); + AddMessage(RGY_LOG_ERROR, _T("failed to send packet to %s bitstream filter: %s.\n"), + char_to_tstring(m_pBsfc->filter->name).c_str(), qsv_av_err2str(ret).c_str()); + return RGY_ERR_UNKNOWN; + } + ret = av_bsf_receive_packet(m_pBsfc.get(), pkt); + if (ret == AVERROR(EAGAIN)) { + return RGY_ERR_NONE; + } else if ((ret < 0 && ret != AVERROR_EOF) || pkt->size < 0) { + AddMessage(RGY_LOG_ERROR, _T("failed to run %s bitstream filter: %s.\n"), + char_to_tstring(m_pBsfc->filter->name).c_str(), qsv_av_err2str(ret).c_str()); + return RGY_ERR_UNKNOWN; + } + const auto new_data_size = pBitstream->size() + pkt->size - sps_nal->size; + const auto sps_nal_offset = sps_nal->ptr - pBitstream->data(); + const auto next_nal_orig_offset = sps_nal_offset + sps_nal->size; + const auto next_nal_new_offset = sps_nal_offset + pkt->size; + const auto stream_orig_length = pBitstream->size(); + if (bsfcBufferLength < new_data_size) { + free(bsfcBuffer); + bsfcBufferLength = new_data_size * 2; + bsfcBuffer = (uint8_t *)malloc(bsfcBufferLength); + } + if (sps_nal_offset > 0) { + memcpy(bsfcBuffer, pBitstream->data(), sps_nal_offset); + } + memcpy(bsfcBuffer + sps_nal_offset, pkt->data, pkt->size); + memcpy(bsfcBuffer + next_nal_new_offset, pBitstream->data() + next_nal_orig_offset, stream_orig_length - next_nal_orig_offset); + pBitstream->copy(bsfcBuffer, new_data_size); + av_packet_unref(pkt); + } + } else if (m_VideoOutputInfo.codec == RGY_CODEC_AV1) { AVPacket *pkt = m_pkt.get(); - av_new_packet(pkt, (int)sps_nal->size); - memcpy(pkt->data, sps_nal->ptr, sps_nal->size); + av_new_packet(pkt, (int)pBitstream->size()); + memcpy(pkt->data, pBitstream->data(), pBitstream->size()); int ret = 0; if (0 > (ret = av_bsf_send_packet(m_pBsfc.get(), pkt))) { av_packet_unref(pkt); @@ -452,22 +490,9 @@ RGY_ERR RGYOutputRaw::WriteNextFrame(RGYBitstream *pBitstream) { char_to_tstring(m_pBsfc->filter->name).c_str(), qsv_av_err2str(ret).c_str()); return RGY_ERR_UNKNOWN; } - const auto new_data_size = pBitstream->size() + pkt->size - sps_nal->size; - const auto sps_nal_offset = sps_nal->ptr - pBitstream->data(); - const auto next_nal_orig_offset = sps_nal_offset + sps_nal->size; - const auto next_nal_new_offset = sps_nal_offset + pkt->size; - const auto stream_orig_length = pBitstream->size(); - if (bsfcBufferLength < new_data_size) { - free(bsfcBuffer); - bsfcBufferLength = new_data_size * 2; - bsfcBuffer = (uint8_t *)malloc(bsfcBufferLength); - } - if (sps_nal_offset > 0) { - memcpy(bsfcBuffer, pBitstream->data(), sps_nal_offset); - } - memcpy(bsfcBuffer + sps_nal_offset, pkt->data, pkt->size); - memcpy(bsfcBuffer + next_nal_new_offset, pBitstream->data() + next_nal_orig_offset, stream_orig_length - next_nal_orig_offset); - pBitstream->copy(bsfcBuffer, new_data_size); + pBitstream->clear(); + pBitstream->append(pkt->data, pkt->size); + av_bsf_flush(m_pBsfc.get()); av_packet_unref(pkt); } } diff --git a/VCECore/rgy_output_avcodec.cpp b/VCECore/rgy_output_avcodec.cpp index f4e3f451..be1cc1a7 100644 --- a/VCECore/rgy_output_avcodec.cpp +++ b/VCECore/rgy_output_avcodec.cpp @@ -1051,7 +1051,7 @@ RGY_ERR RGYOutputAvcodec::InitVideo(const VideoInfo *videoOutputInfo, const Avco } if (ENCODER_VCEENC || ENCODER_MPP) { // HEVCの10bitの時、エンコーダがおかしなVUIを設定することがあるのでこれを常に上書き - const bool override_always = ENCODER_VCEENC && videoOutputInfo->codec == RGY_CODEC_HEVC; + const bool override_always = ENCODER_VCEENC && (videoOutputInfo->codec == RGY_CODEC_HEVC || videoOutputInfo->codec == RGY_CODEC_AV1); if (override_always || videoOutputInfo->vui.format != 5 /*undef*/) { if (videoOutputInfo->codec == RGY_CODEC_H264 || videoOutputInfo->codec == RGY_CODEC_HEVC) { av_dict_set_int(&bsfPrm, "video_format", videoOutputInfo->vui.format, 0); @@ -2701,21 +2701,61 @@ RGY_ERR RGYOutputAvcodec::WriteNextFrameInternalOneFrame(RGYBitstream *bitstream //AVParserを使用して必要に応じてframeTypeを取得する VidCheckStreamAVParser(bitstream); - if (m_Mux.video.bsfc && m_VideoOutputInfo.codec != RGY_CODEC_AV1) { - int target_nal = 0; - std::vector nal_list; - if (m_VideoOutputInfo.codec == RGY_CODEC_HEVC) { - target_nal = NALU_HEVC_SPS; - nal_list = m_Mux.video.parse_nal_hevc(bitstream->data(), bitstream->size()); - } else if (m_VideoOutputInfo.codec == RGY_CODEC_H264) { - target_nal = NALU_H264_SPS; - nal_list = m_Mux.video.parse_nal_h264(bitstream->data(), bitstream->size()); - } - auto sps_nal = std::find_if(nal_list.begin(), nal_list.end(), [target_nal](nal_info info) { return info.type == target_nal; }); - if (sps_nal != nal_list.end()) { + if (m_Mux.video.bsfc) { + if (m_VideoOutputInfo.codec == RGY_CODEC_H264 || m_VideoOutputInfo.codec == RGY_CODEC_HEVC) { + int target_nal = 0; + std::vector nal_list; + if (m_VideoOutputInfo.codec == RGY_CODEC_HEVC) { + target_nal = NALU_HEVC_SPS; + nal_list = m_Mux.video.parse_nal_hevc(bitstream->data(), bitstream->size()); + } else if (m_VideoOutputInfo.codec == RGY_CODEC_H264) { + target_nal = NALU_H264_SPS; + nal_list = m_Mux.video.parse_nal_h264(bitstream->data(), bitstream->size()); + } + auto sps_nal = std::find_if(nal_list.begin(), nal_list.end(), [target_nal](nal_info info) { return info.type == target_nal; }); + if (sps_nal != nal_list.end()) { + AVPacket *pkt = m_Mux.video.pktOut; + av_new_packet(pkt, (int)sps_nal->size); + memcpy(pkt->data, sps_nal->ptr, sps_nal->size); + int ret = 0; + if (0 > (ret = av_bsf_send_packet(m_Mux.video.bsfc, pkt))) { + av_packet_unref(pkt); + AddMessage(RGY_LOG_ERROR, _T("failed to send packet to %s bitstream filter: %s.\n"), + char_to_tstring(m_Mux.video.bsfc->filter->name).c_str(), qsv_av_err2str(ret).c_str()); + return RGY_ERR_UNKNOWN; + } + ret = av_bsf_receive_packet(m_Mux.video.bsfc, pkt); + if (ret == AVERROR(EAGAIN)) { + return RGY_ERR_NONE; + } else if ((ret < 0 && ret != AVERROR_EOF) || pkt->size < 0) { + AddMessage(RGY_LOG_ERROR, _T("failed to run %s bitstream filter: %s.\n"), + char_to_tstring(m_Mux.video.bsfc->filter->name).c_str(), qsv_av_err2str(ret).c_str()); + return RGY_ERR_UNKNOWN; + } + const auto new_data_size = bitstream->size() + pkt->size - sps_nal->size; + const auto sps_nal_offset = sps_nal->ptr - bitstream->data(); + const auto next_nal_orig_offset = sps_nal_offset + sps_nal->size; + const auto next_nal_new_offset = sps_nal_offset + pkt->size; + const auto stream_orig_length = bitstream->size(); + if (m_Mux.video.bsfcBufferLength < new_data_size) { + free(m_Mux.video.bsfcBuffer); + m_Mux.video.bsfcBufferLength = new_data_size * 2; + m_Mux.video.bsfcBuffer = (uint8_t *)malloc(m_Mux.video.bsfcBufferLength); + } + if (sps_nal_offset > 0) { + memcpy(m_Mux.video.bsfcBuffer, bitstream->data(), sps_nal_offset); + } + memcpy(m_Mux.video.bsfcBuffer + sps_nal_offset, pkt->data, pkt->size); + memcpy(m_Mux.video.bsfcBuffer + next_nal_new_offset, bitstream->data() + next_nal_orig_offset, stream_orig_length - next_nal_orig_offset); + bitstream->copy(m_Mux.video.bsfcBuffer, new_data_size); + av_packet_unref(pkt); + + av_bsf_flush(m_Mux.video.bsfc); + } + } else if (m_VideoOutputInfo.codec == RGY_CODEC_AV1) { AVPacket *pkt = m_Mux.video.pktOut; - av_new_packet(pkt, (int)sps_nal->size); - memcpy(pkt->data, sps_nal->ptr, sps_nal->size); + av_new_packet(pkt, (int)bitstream->size()); + memcpy(pkt->data, bitstream->data(), bitstream->size()); int ret = 0; if (0 > (ret = av_bsf_send_packet(m_Mux.video.bsfc, pkt))) { av_packet_unref(pkt); @@ -2731,25 +2771,10 @@ RGY_ERR RGYOutputAvcodec::WriteNextFrameInternalOneFrame(RGYBitstream *bitstream char_to_tstring(m_Mux.video.bsfc->filter->name).c_str(), qsv_av_err2str(ret).c_str()); return RGY_ERR_UNKNOWN; } - const auto new_data_size = bitstream->size() + pkt->size - sps_nal->size; - const auto sps_nal_offset = sps_nal->ptr - bitstream->data(); - const auto next_nal_orig_offset = sps_nal_offset + sps_nal->size; - const auto next_nal_new_offset = sps_nal_offset + pkt->size; - const auto stream_orig_length = bitstream->size(); - if (m_Mux.video.bsfcBufferLength < new_data_size) { - free(m_Mux.video.bsfcBuffer); - m_Mux.video.bsfcBufferLength = new_data_size * 2; - m_Mux.video.bsfcBuffer = (uint8_t *)malloc(m_Mux.video.bsfcBufferLength); - } - if (sps_nal_offset > 0) { - memcpy(m_Mux.video.bsfcBuffer, bitstream->data(), sps_nal_offset); - } - memcpy(m_Mux.video.bsfcBuffer + sps_nal_offset, pkt->data, pkt->size); - memcpy(m_Mux.video.bsfcBuffer + next_nal_new_offset, bitstream->data() + next_nal_orig_offset, stream_orig_length - next_nal_orig_offset); - bitstream->copy(m_Mux.video.bsfcBuffer, new_data_size); - av_packet_unref(pkt); - + bitstream->clear(); + bitstream->append(pkt->data, pkt->size); av_bsf_flush(m_Mux.video.bsfc); + av_packet_unref(pkt); } }