diff --git a/src/core/libraries/avplayer/avplayer_impl.cpp b/src/core/libraries/avplayer/avplayer_impl.cpp index d193e765..1c414c96 100644 --- a/src/core/libraries/avplayer/avplayer_impl.cpp +++ b/src/core/libraries/avplayer/avplayer_impl.cpp @@ -112,7 +112,7 @@ AvPlayer::AvPlayer(const SceAvPlayerInitData& data) m_state(std::make_unique(m_init_data)) {} s32 AvPlayer::PostInit(const SceAvPlayerPostInitData& data) { - m_post_init_data = data; + m_state->PostInit(data); return ORBIS_OK; } diff --git a/src/core/libraries/avplayer/avplayer_impl.h b/src/core/libraries/avplayer/avplayer_impl.h index b6ad940c..d7f28094 100644 --- a/src/core/libraries/avplayer/avplayer_impl.h +++ b/src/core/libraries/avplayer/avplayer_impl.h @@ -56,7 +56,6 @@ private: SceAvPlayerInitData m_init_data{}; SceAvPlayerInitData m_init_data_original{}; - SceAvPlayerPostInitData m_post_init_data{}; std::mutex m_file_io_mutex{}; std::atomic_bool m_has_source{}; diff --git a/src/core/libraries/avplayer/avplayer_source.cpp b/src/core/libraries/avplayer/avplayer_source.cpp index fcae180e..19925ba0 100644 --- a/src/core/libraries/avplayer/avplayer_source.cpp +++ b/src/core/libraries/avplayer/avplayer_source.cpp @@ -37,7 +37,8 @@ namespace Libraries::AvPlayer { using namespace Kernel; -AvPlayerSource::AvPlayerSource(AvPlayerStateCallback& state) : m_state(state) {} +AvPlayerSource::AvPlayerSource(AvPlayerStateCallback& state, bool use_vdec2) + : m_state(state), m_use_vdec2(use_vdec2) {} AvPlayerSource::~AvPlayerSource() { Stop(); @@ -129,18 +130,25 @@ bool AvPlayerSource::GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info LOG_WARNING(Lib_AvPlayer, "Stream {} language is unknown", stream_index); } switch (info.type) { - case SCE_AVPLAYER_VIDEO: + case SCE_AVPLAYER_VIDEO: { LOG_INFO(Lib_AvPlayer, "Stream {} is a video stream.", stream_index); info.details.video.aspect_ratio = f32(p_stream->codecpar->width) / p_stream->codecpar->height; - info.details.video.width = Common::AlignUp(u32(p_stream->codecpar->width), 16); - info.details.video.height = Common::AlignUp(u32(p_stream->codecpar->height), 16); + auto width = u32(p_stream->codecpar->width); + auto height = u32(p_stream->codecpar->height); + if (!m_use_vdec2) { + width = Common::AlignUp(width, 16); + height = Common::AlignUp(height, 16); + } + info.details.video.width = width; + info.details.video.height = height; if (p_lang_node != nullptr) { std::memcpy(info.details.video.language_code, p_lang_node->value, std::min(strlen(p_lang_node->value), size_t(3))); } break; - case SCE_AVPLAYER_AUDIO: + } + case SCE_AVPLAYER_AUDIO: { LOG_INFO(Lib_AvPlayer, "Stream {} is an audio stream.", stream_index); info.details.audio.channel_count = p_stream->codecpar->ch_layout.nb_channels; info.details.audio.sample_rate = p_stream->codecpar->sample_rate; @@ -150,7 +158,8 @@ bool AvPlayerSource::GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info std::min(strlen(p_lang_node->value), size_t(3))); } break; - case SCE_AVPLAYER_TIMEDTEXT: + } + case SCE_AVPLAYER_TIMEDTEXT: { LOG_WARNING(Lib_AvPlayer, "Stream {} is a timedtext stream.", stream_index); info.details.subs.font_size = 12; info.details.subs.text_size = 12; @@ -159,10 +168,12 @@ bool AvPlayerSource::GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info std::min(strlen(p_lang_node->value), size_t(3))); } break; - default: + } + default: { LOG_ERROR(Lib_AvPlayer, "Stream {} type is unknown: {}.", stream_index, info.type); return false; } + } return true; } @@ -189,8 +200,12 @@ bool AvPlayerSource::EnableStream(u32 stream_index) { LOG_ERROR(Lib_AvPlayer, "Could not open avcodec for video stream {}.", stream_index); return false; } - const auto width = Common::AlignUp(u32(m_video_codec_context->width), 16); - const auto height = Common::AlignUp(u32(m_video_codec_context->height), 16); + auto width = u32(m_video_codec_context->width); + auto height = u32(m_video_codec_context->height); + if (!m_use_vdec2) { + width = Common::AlignUp(width, 16); + height = Common::AlignUp(height, 16); + } const auto size = (width * height * 3) / 2; for (u64 index = 0; index < m_num_output_video_framebuffers; ++index) { m_video_buffers.Push(FrameBuffer(m_memory_replacement, 0x100, size)); @@ -316,7 +331,7 @@ bool AvPlayerSource::GetVideoData(SceAvPlayerFrameInfoEx& video_info) { auto frame = m_video_frames.Pop(); if (!frame.has_value()) { - LOG_WARNING(Lib_AvPlayer, "Could get video frame. EOF reached."); + LOG_TRACE(Lib_AvPlayer, "Could get video frame. EOF reached."); return false; } @@ -351,7 +366,7 @@ bool AvPlayerSource::GetAudioData(SceAvPlayerFrameInfo& audio_info) { auto frame = m_audio_frames.Pop(); if (!frame.has_value()) { - LOG_WARNING(Lib_AvPlayer, "Could get audio frame. EOF reached."); + LOG_TRACE(Lib_AvPlayer, "Could get audio frame. EOF reached."); return false; } @@ -537,9 +552,13 @@ AvPlayerSource::AVFramePtr AvPlayerSource::ConvertVideoFrame(const AVFrame& fram return nv12_frame; } -static void CopyNV12Data(u8* dst, const AVFrame& src) { - const auto width = Common::AlignUp(u32(src.width), 16); - const auto height = Common::AlignUp(u32(src.height), 16); +static void CopyNV12Data(u8* dst, const AVFrame& src, bool use_vdec2) { + auto width = u32(src.width); + auto height = u32(src.height); + if (!use_vdec2) { + width = Common::AlignUp(width, 16); + height = Common::AlignUp(height, 16); + } if (src.width == width) { std::memcpy(dst, src.data[0], src.width * src.height); @@ -561,7 +580,7 @@ Frame AvPlayerSource::PrepareVideoFrame(FrameBuffer buffer, const AVFrame& frame ASSERT(frame.format == AV_PIX_FMT_NV12); auto p_buffer = buffer.GetBuffer(); - CopyNV12Data(p_buffer, frame); + CopyNV12Data(p_buffer, frame, m_use_vdec2); const auto pkt_dts = u64(frame.pkt_dts) * 1000; const auto stream = m_avformat_context->streams[m_video_stream_index.value()]; @@ -570,8 +589,12 @@ Frame AvPlayerSource::PrepareVideoFrame(FrameBuffer buffer, const AVFrame& frame const auto num = time_base.num; const auto timestamp = (num != 0 && den > 1) ? (pkt_dts * num) / den : pkt_dts; - const auto width = Common::AlignUp(u32(frame.width), 16); - const auto height = Common::AlignUp(u32(frame.height), 16); + auto width = u32(frame.width); + auto height = u32(frame.height); + if (!m_use_vdec2) { + width = Common::AlignUp(width, 16); + height = Common::AlignUp(height, 16); + } return Frame{ .buffer = std::move(buffer), @@ -583,8 +606,8 @@ Frame AvPlayerSource::PrepareVideoFrame(FrameBuffer buffer, const AVFrame& frame { .video = { - .width = u32(width), - .height = u32(height), + .width = width, + .height = height, .aspect_ratio = AVRationalToF32(frame.sample_aspect_ratio), .crop_left_offset = u32(frame.crop_left), .crop_right_offset = u32(frame.crop_right + (width - frame.width)), diff --git a/src/core/libraries/avplayer/avplayer_source.h b/src/core/libraries/avplayer/avplayer_source.h index 90612214..505d7446 100644 --- a/src/core/libraries/avplayer/avplayer_source.h +++ b/src/core/libraries/avplayer/avplayer_source.h @@ -120,7 +120,7 @@ private: class AvPlayerSource { public: - AvPlayerSource(AvPlayerStateCallback& state); + AvPlayerSource(AvPlayerStateCallback& state, bool use_vdec2); ~AvPlayerSource(); bool Init(const SceAvPlayerInitData& init_data, std::string_view path); @@ -168,6 +168,7 @@ private: Frame PrepareVideoFrame(FrameBuffer buffer, const AVFrame& frame); AvPlayerStateCallback& m_state; + bool m_use_vdec2 = false; SceAvPlayerMemAllocator m_memory_replacement{}; u32 m_num_output_video_framebuffers{}; diff --git a/src/core/libraries/avplayer/avplayer_state.cpp b/src/core/libraries/avplayer/avplayer_state.cpp index 5cabdba2..e6610067 100644 --- a/src/core/libraries/avplayer/avplayer_state.cpp +++ b/src/core/libraries/avplayer/avplayer_state.cpp @@ -130,6 +130,10 @@ AvPlayerState::~AvPlayerState() { m_event_queue.Clear(); } +void AvPlayerState::PostInit(const SceAvPlayerPostInitData& post_init_data) { + m_post_init_data = post_init_data; +} + // Called inside GAME thread bool AvPlayerState::AddSource(std::string_view path, SceAvPlayerSourceType source_type) { if (path.empty()) { @@ -144,7 +148,9 @@ bool AvPlayerState::AddSource(std::string_view path, SceAvPlayerSourceType sourc return false; } - m_up_source = std::make_unique(*this); + m_up_source = std::make_unique( + *this, m_post_init_data.video_decoder_init.decoderType.video_type == + SCE_AVPLAYER_VIDEO_DECODER_TYPE_SOFTWARE2); if (!m_up_source->Init(m_init_data, path)) { SetState(AvState::Error); m_up_source.reset(); diff --git a/src/core/libraries/avplayer/avplayer_state.h b/src/core/libraries/avplayer/avplayer_state.h index 151eea52..d106127e 100644 --- a/src/core/libraries/avplayer/avplayer_state.h +++ b/src/core/libraries/avplayer/avplayer_state.h @@ -24,6 +24,7 @@ public: AvPlayerState(const SceAvPlayerInitData& init_data); ~AvPlayerState(); + void PostInit(const SceAvPlayerPostInitData& post_init_data); bool AddSource(std::string_view filename, SceAvPlayerSourceType source_type); s32 GetStreamCount(); bool GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info); @@ -68,6 +69,7 @@ private: std::unique_ptr m_up_source; SceAvPlayerInitData m_init_data{}; + SceAvPlayerPostInitData m_post_init_data{}; SceAvPlayerEventReplacement m_event_replacement{}; bool m_auto_start{}; u8 m_default_language[4]{};