Skip to content

Commit

Permalink
AV1でcolormatrix等を適切に反映するように。( #93 )
Browse files Browse the repository at this point in the history
  • Loading branch information
rigaya committed Nov 8, 2023
1 parent 62aa71f commit 6a7c773
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 63 deletions.
85 changes: 55 additions & 30 deletions VCECore/rgy_output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down Expand Up @@ -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_info> 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_info> 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);
Expand All @@ -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);
}
}
Expand Down
91 changes: 58 additions & 33 deletions VCECore/rgy_output_avcodec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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_info> 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_info> 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);
Expand All @@ -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);
}
}

Expand Down

0 comments on commit 6a7c773

Please sign in to comment.