diff --git a/src/cge/cge/audio_encoder.cpp b/src/cge/cge/audio_encoder.cpp index 52199d5..f8c61a5 100644 --- a/src/cge/cge/audio_encoder.cpp +++ b/src/cge/cge/audio_encoder.cpp @@ -116,7 +116,7 @@ int AudioEncoder::EncodingThread() { size_t frame_bytes = codec_context_->frame_size * (codec_context_->bits_per_raw_sample + 7) / 8 * - codec_context_->channels; + codec_context_->ch_layout.nb_channels; size_t shared_mem_size = sizeof(SharedAudioFrames) + sizeof(PackedAudioFrame) + frame_bytes * kNumberOfSharedFrames; @@ -132,7 +132,7 @@ int AudioEncoder::EncodingThread() { } SharedAudioFrames* saf = shared_frames_; strcpy_s(saf->codec_name, codec_name_.data()); - saf->channels = codec_context_->channels; + saf->channels = codec_context_->ch_layout.nb_channels; saf->frame_size = codec_context_->frame_size; saf->sample_bits = codec_context_->bits_per_raw_sample; saf->sample_format = codec_context_->sample_fmt; @@ -249,8 +249,9 @@ int AudioEncoder::AddStream(const AVCodec*& codec) { // std::cerr << "invaild channels " << source_audio_info_.channels << ".\n"; // return -1; // } - codec_context_->channels = kTargetChannels; - codec_context_->channel_layout = kTargetChannelLayout; + codec_context_->ch_layout = AV_CHANNEL_LAYOUT_STEREO; + //codec_context_->channels = kTargetChannels; + //codec_context_->channel_layout = kTargetChannelLayout; if (codec_name_ == "opus") { codec_context_->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; } @@ -280,19 +281,21 @@ int AudioEncoder::Open(const AVCodec* codec, AVDictionary** opts) { } sound_capturer_.SetOutputInfo( - codec_context_->channel_layout, codec_context_->sample_fmt, + codec_context_->ch_layout, codec_context_->sample_fmt, codec_context_->sample_rate, codec_context_->frame_size); #if _DEBUG - APP_DEBUG() << "channel layout: " << codec_context_->channel_layout << '\n'; + APP_DEBUG() << "channel layout: " << codec_context_->ch_layout.u.mask << '\n'; APP_DEBUG() << "sample format: " << codec_context_->sample_fmt << '\n'; APP_DEBUG() << "sample rate: " << codec_context_->sample_rate << '\n'; APP_DEBUG() << "frame size: " << codec_context_->frame_size << '\n'; - if (source_audio_info_.channel_layout != codec_context_->channel_layout) { + if (0 != av_channel_layout_compare(&source_audio_info_.channel_layout, + &codec_context_->ch_layout)) { + APP_DEBUG() << "resample channel layout " - << source_audio_info_.channel_layout << " to " - << codec_context_->channel_layout << ".\n"; + << source_audio_info_.channel_layout.u.mask << " to " + << codec_context_->ch_layout.u.mask << ".\n"; } if (source_audio_info_.sample_format != codec_context_->sample_fmt) { APP_DEBUG() << "resample format " << source_audio_info_.sample_format @@ -334,7 +337,7 @@ int AudioEncoder::InitializeFrame(AVFrame*& frame) const noexcept { frame->nb_samples = codec_context_->frame_size; frame->format = codec_context_->sample_fmt; frame->sample_rate = codec_context_->sample_rate; - frame->channel_layout = codec_context_->channel_layout; + av_channel_layout_copy(&frame->ch_layout, &codec_context_->ch_layout); int error_code = av_frame_get_buffer(frame, 0); if (error_code < 0) { diff --git a/src/cge/cge/audio_resampler.cpp b/src/cge/cge/audio_resampler.cpp index 70ec7c7..1ec17c5 100644 --- a/src/cge/cge/audio_resampler.cpp +++ b/src/cge/cge/audio_resampler.cpp @@ -18,10 +18,10 @@ #include "audio_resampler.h" -int AudioResampler::Initialize(int64_t in_channel_layout, +int AudioResampler::Initialize(const AVChannelLayout* in_channel_layout, AVSampleFormat in_sample_format, int in_sample_rate, - int64_t out_channel_layout, + AVChannelLayout* out_channel_layout, AVSampleFormat out_sample_format, int out_sample_rate, int frame_size) noexcept { @@ -30,22 +30,24 @@ int AudioResampler::Initialize(int64_t in_channel_layout, std::lock_guard lock(mutex_); - out_channel_layout_ = out_channel_layout; + av_channel_layout_copy(&out_channel_layout_, out_channel_layout); out_sample_format_ = out_sample_format; out_sample_rate_ = out_sample_rate; frame_size_ = frame_size; - if (in_channel_layout != out_channel_layout || + if (0 != av_channel_layout_compare(in_channel_layout, out_channel_layout) || in_sample_format != out_sample_format || in_sample_rate != out_sample_rate) { in_sample_rate_ = in_sample_rate; - resampler_context_ = swr_alloc_set_opts( - nullptr, out_channel_layout, out_sample_format, out_sample_rate, - in_channel_layout, in_sample_format, in_sample_rate, 0, nullptr); + // resampler_context_ = swr_alloc_set_opts(nullptr, ...); + int ec = swr_alloc_set_opts2(&resampler_context_, out_channel_layout, + out_sample_format, out_sample_rate, + in_channel_layout, in_sample_format, + in_sample_rate, 0, nullptr); if (nullptr == resampler_context_) { - ATLTRACE2(atlTraceException, 0, "!swr_alloc_set_opts()\n"); - return AVERROR(ENOMEM); + ATLTRACE2(atlTraceException, 0, "!swr_alloc_set_opts2(), #%d\n", ec); + return ec; } int error = swr_init(resampler_context_); @@ -63,9 +65,8 @@ int AudioResampler::Initialize(int64_t in_channel_layout, } } - fifo_ = av_audio_fifo_alloc( - out_sample_format_, - av_get_channel_layout_nb_channels(out_channel_layout_), frame_size_ * 3); + fifo_ = av_audio_fifo_alloc(out_sample_format_, + out_channel_layout_.nb_channels, frame_size_ * 3); if (nullptr == fifo_) { ATLTRACE2(atlTraceException, 0, "!av_audio_fifo_alloc()\n"); return AVERROR(ENOMEM); @@ -109,7 +110,7 @@ int AudioResampler::Store(const uint8_t* in, return AVERROR_EXIT; } } else { - int channel_count = av_get_channel_layout_nb_channels(out_channel_layout_); + int channel_count = out_channel_layout_.nb_channels; auto converted_samples = static_cast(uint8_ptr_pool_.ordered_malloc(channel_count)); if (nullptr == converted_samples) { @@ -196,7 +197,7 @@ int AudioResampler::InitializeFrame(AVFrame*& frame, frame->nb_samples = frame_size; frame->format = out_sample_format_; frame->sample_rate = out_sample_rate_; - frame->channel_layout = out_channel_layout_; + frame->ch_layout = out_channel_layout_; if (0 == frame_size) { return 0; diff --git a/src/cge/cge/audio_resampler.h b/src/cge/cge/audio_resampler.h index e66afb7..cc78d29 100644 --- a/src/cge/cge/audio_resampler.h +++ b/src/cge/cge/audio_resampler.h @@ -23,10 +23,10 @@ class AudioResampler { AudioResampler() noexcept {} ~AudioResampler() noexcept { Free(); } - int Initialize(int64_t in_channel_layout, + int Initialize(const AVChannelLayout* in_channel_layout, enum AVSampleFormat in_sample_format, int in_sample_rate, - int64_t out_channel_layout, + AVChannelLayout* out_channel_layout, enum AVSampleFormat out_sample_format, int out_sample_rate, int frame_size) noexcept; @@ -38,7 +38,7 @@ class AudioResampler { private: int in_sample_rate_ = 0; - int64_t out_channel_layout_ = 0; + AVChannelLayout out_channel_layout_{}; AVSampleFormat out_sample_format_ = AV_SAMPLE_FMT_NONE; int out_sample_rate_ = 0; int frame_size_ = 0; diff --git a/src/cge/cge/cge.cpp b/src/cge/cge/cge.cpp index a674d85..3f22582 100644 --- a/src/cge/cge/cge.cpp +++ b/src/cge/cge/cge.cpp @@ -58,7 +58,7 @@ namespace po = boost::program_options; using namespace std::literals::string_view_literals; -constexpr auto kProgramInfo{"KSYUN Edge Cloud Gaming Engine v0.4 Beta"sv}; +constexpr auto kProgramInfo{"KSYUN Edge Cloud Gaming Engine v0.5 Beta"sv}; constexpr uint64_t kDefaultAudioBitrate = 128000; constexpr auto kDefaultBindAddress{"::"sv}; diff --git a/src/cge/cge/game_session.cpp b/src/cge/cge/game_session.cpp index 1713dae..1a25db5 100644 --- a/src/cge/cge/game_session.cpp +++ b/src/cge/cge/game_session.cpp @@ -22,7 +22,7 @@ #include "game_service.h" #include "user_manager.h" -#define USER_MANAGER 1 +#define USER_MANAGER !_DEBUG using namespace std::literals::chrono_literals; diff --git a/src/cge/cge/sound_capturer.cpp b/src/cge/cge/sound_capturer.cpp index 523abdc..8c96e5e 100644 --- a/src/cge/cge/sound_capturer.cpp +++ b/src/cge/cge/sound_capturer.cpp @@ -29,14 +29,18 @@ constexpr REFERENCE_TIME kReferenceTimePerSecond = 10000000; constexpr REFERENCE_TIME kReferenceTimePerMilliSecond = 10000; namespace { -int64_t GetChannelLayout(const WAVEFORMATEX* wave_format) noexcept { +void GetChannelLayout(const WAVEFORMATEX* wave_format, + AVChannelLayout* channel_layout) noexcept { assert(nullptr != wave_format); if (WAVE_FORMAT_EXTENSIBLE == wave_format->wFormatTag) { - return reinterpret_cast(wave_format) - ->dwChannelMask; + av_channel_layout_from_mask( + channel_layout, + reinterpret_cast(wave_format) + ->dwChannelMask); + } else { + av_channel_layout_default(channel_layout, wave_format->nChannels); } - return av_get_default_channel_layout(wave_format->nChannels); } AVSampleFormat GetSampleFormat(const WAVEFORMATEX* wave_format) noexcept { @@ -172,8 +176,9 @@ HRESULT SoundCapturer::GetAudioInfo(AudioInfo* info) { info->sample_rate = wave_format->nSamplesPerSec; info->sample_bits = wave_format->wBitsPerSample; - info->channel_layout = GetChannelLayout(wave_format); - info->channels = wave_format->nChannels; + // info->channel_layout = GetChannelLayout(wave_format); + // info->channels = wave_format->nChannels; + GetChannelLayout(wave_format, &info->channel_layout); info->sample_format = GetSampleFormat(wave_format); return hr; } @@ -254,12 +259,14 @@ HRESULT SoundCapturer::CaptureThread() { kReferenceTimePerMilliSecond); // convert to milliseconds ATLTRACE2(atlTraceUtil, 0, "time_between_fires = %d\n", time_between_fires); - assert(0 != out_channel_layout_); + // assert(0 != out_channel_layout_); assert(AV_SAMPLE_FMT_NONE != out_sample_format_); assert(0 != out_sample_rate_); + AVChannelLayout in_channel_layout; + GetChannelLayout(wave_format, &in_channel_layout); int error_code = audio_resampler_.Initialize( - GetChannelLayout(wave_format), GetSampleFormat(wave_format), - wave_format->nSamplesPerSec, out_channel_layout_, out_sample_format_, + &in_channel_layout, GetSampleFormat(wave_format), + wave_format->nSamplesPerSec, &out_channel_layout_, out_sample_format_, out_sample_rate_, frame_size_); if (error_code < 0) { APP_ERROR() << "Initialize resampler failed with " << error_code << ".\n"; @@ -273,7 +280,7 @@ HRESULT SoundCapturer::CaptureThread() { return hr; } SharedAudioFrames* saf = shared_frame_; - if (saf->channels != av_get_channel_layout_nb_channels(out_channel_layout_) || + if (saf->channels != out_channel_layout_.nb_channels || saf->frame_size != frame_size_ || saf->sample_format != out_sample_format_) { APP_ERROR() << "Invalid audio frame format.\n"; diff --git a/src/cge/cge/sound_capturer.h b/src/cge/cge/sound_capturer.h index 27dadbd..65eeb81 100644 --- a/src/cge/cge/sound_capturer.h +++ b/src/cge/cge/sound_capturer.h @@ -33,8 +33,9 @@ _CRT_END_C_HEADER struct AudioInfo { int sample_rate; int sample_bits; - int64_t channel_layout; - int channels; + //int64_t channel_layout; + //int channels; + AVChannelLayout channel_layout; AVSampleFormat sample_format; }; @@ -47,7 +48,7 @@ class SoundCapturer { bool Initialize() noexcept; void Run(); void Stop(); - void SetOutputInfo(int64_t channel_layout, + void SetOutputInfo(AVChannelLayout channel_layout, AVSampleFormat sample_format, int sample_rate, int frame_size) noexcept { @@ -74,7 +75,7 @@ class SoundCapturer { CHandle shared_frame_ready_event_; UINT32 frames_ = 0; - int64_t out_channel_layout_ = 0; + AVChannelLayout out_channel_layout_{}; AVSampleFormat out_sample_format_ = AV_SAMPLE_FMT_NONE; int out_sample_rate_ = 0; int frame_size_ = 0; diff --git a/src/cge/cge/video_encoder.cpp b/src/cge/cge/video_encoder.cpp index fe693e4..6555e44 100644 --- a/src/cge/cge/video_encoder.cpp +++ b/src/cge/cge/video_encoder.cpp @@ -139,9 +139,37 @@ int VideoEncoder::EncodingThread() { << saved_frame_info_.height << ", format: " << saved_frame_info_.format << ", window: " << saved_frame_info_.window << '\n'; + if (VideoFrameType::kNone == saved_frame_info_.type) { + return ERROR_INVALID_DATA; + } - if (VideoFrameType::kYuv == saved_frame_info_.type) { - size_t yuv_size = 4 * saved_frame_info_.width * saved_frame_info_.height; + if (VideoFrameType::kTexture == saved_frame_info_.type) { + HRESULT hr = shared_texture_frames_.OpenMapping( + object_namer_.Get(kSharedVideoTextureFramesFileMappingName).data(), + sizeof(SharedVideoTextureFrames)); + if (FAILED(hr)) { + APP_ERROR() << "OpenMapping() failed with 0x" << std::hex << hr << '\n'; + restart = true; + return hr; + } + } else { + size_t pixel_size = saved_frame_info_.width * saved_frame_info_.height; + size_t yuv_size; + switch (saved_frame_info_.type) { + case VideoFrameType::kI420: + [[fallthrough]]; + case VideoFrameType::kJ420: + yuv_size = pixel_size + (pixel_size >> 1); + break; + case VideoFrameType::kI422: + [[fallthrough]]; + case VideoFrameType::kJ422: + yuv_size = 2 * pixel_size; + break; + case VideoFrameType::kI444: + yuv_size = 3 * pixel_size; + break; + } size_t frames_size = sizeof(SharedVideoYuvFrames) + sizeof(PackedVideoYuvFrame) * kNumberOfSharedFrames + yuv_size * kNumberOfSharedFrames; @@ -164,15 +192,6 @@ int VideoEncoder::EncodingThread() { restart = true; return -1; } - } else if (VideoFrameType::kTexture == saved_frame_info_.type) { - HRESULT hr = shared_texture_frames_.OpenMapping( - object_namer_.Get(kSharedVideoTextureFramesFileMappingName).data(), - sizeof(SharedVideoTextureFrames)); - if (FAILED(hr)) { - APP_ERROR() << "OpenMapping() failed with 0x" << std::hex << hr << '\n'; - restart = true; - return hr; - } } const AVCodec* codec = nullptr; @@ -196,7 +215,9 @@ int VideoEncoder::EncodingThread() { APP_ERROR() << "Init frame failed with " << error_code << ".\n"; return error_code; } - BOOST_SCOPE_EXIT_ALL(&frame) { av_frame_free(&frame); }; + BOOST_SCOPE_EXIT_ALL(&frame) { + av_frame_free(&frame); + }; for (;;) { error_code = EncodeFrame(frame); @@ -344,9 +365,35 @@ int VideoEncoder::Open(const AVCodec* codec, AVDictionary** opts) { codec_context_->time_base = stream_->time_base; codec_context_->max_b_frames = 0; codec_context_->gop_size = gop_; - codec_context_->pix_fmt = HardwareEncoder::QSV == hardware_encoder_ - ? AV_PIX_FMT_NV12 - : AV_PIX_FMT_YUV420P; + + switch (saved_frame_info_.type) { + case VideoFrameType::kI420: + [[fallthrough]]; + case VideoFrameType::kTexture: + if (HardwareEncoder::QSV == hardware_encoder_) { + codec_context_->pix_fmt = AV_PIX_FMT_NV12; + } else { + codec_context_->pix_fmt = AV_PIX_FMT_YUV420P; + } + break; + case VideoFrameType::kJ420: + if (HardwareEncoder::QSV == hardware_encoder_) { + codec_context_->pix_fmt = AV_PIX_FMT_NV12; + } else { + codec_context_->pix_fmt = AV_PIX_FMT_YUV420P; + codec_context_->color_range = AVCOL_RANGE_JPEG; + } + break; + case VideoFrameType::kJ422: + codec_context_->color_range = AVCOL_RANGE_JPEG; + [[fallthrough]]; + case VideoFrameType::kI422: + codec_context_->pix_fmt = AV_PIX_FMT_YUV422P; + break; + case VideoFrameType::kI444: + codec_context_->pix_fmt = AV_PIX_FMT_YUV444P; + break; + } codec_context_->codec_id = GetCodecID(); codec_context_->flags |= AV_CODEC_FLAG_LOW_DELAY; if (format_context_->oformat->flags & AVFMT_GLOBALHEADER) { @@ -446,7 +493,25 @@ int VideoEncoder::InitializeFrame(AVFrame*& frame) const noexcept { return AVERROR(ENOMEM); } - frame->format = AV_PIX_FMT_YUV420P; + switch (saved_frame_info_.type) { + case VideoFrameType::kJ420: + frame->color_range = AVCOL_RANGE_JPEG; + [[fallthrough]]; + case VideoFrameType::kI420: + [[fallthrough]]; + case VideoFrameType::kTexture: + frame->format = AV_PIX_FMT_YUV420P; + break; + case VideoFrameType::kJ422: + frame->color_range = AVCOL_RANGE_JPEG; + [[fallthrough]]; + case VideoFrameType::kI422: + frame->format = AV_PIX_FMT_YUV422P; + break; + case VideoFrameType::kI444: + frame->format = AV_PIX_FMT_YUV444P; + break; + } frame->width = codec_context_->width; frame->height = codec_context_->height; frame->pict_type = AV_PICTURE_TYPE_NONE; @@ -464,6 +529,9 @@ int VideoEncoder::EncodeFrame(AVFrame* frame) noexcept { assert(nullptr != codec_context_); assert(nullptr != frame); assert(nullptr != shared_frame_info_); + assert(nullptr != shared_frame_info_); + + assert(VideoFrameType::kNone != saved_frame_info_.type); if (produce_keyframe_) { produce_keyframe_ = false; @@ -473,21 +541,7 @@ int VideoEncoder::EncodeFrame(AVFrame* frame) noexcept { } int error_code = 0; - if (VideoFrameType::kYuv == saved_frame_info_.type) { - assert(nullptr != shared_yuv_frames_); - auto yuv_frames = - reinterpret_cast(shared_yuv_frames_.GetData()); - auto yuv_frame = reinterpret_cast(yuv_frames->data); - auto yuv_frame1 = reinterpret_cast( - yuv_frames->data + yuv_frames->data_size); - - if (yuv_frame->stats.timestamp < yuv_frame1->stats.timestamp) { - yuv_frame = yuv_frame1; - } - ATLTRACE2(atlTraceUtil, 0, "latest video frame %llu\n", - yuv_frame->stats.timestamp); - error_code = EncodeYuvFrame(frame, yuv_frame->data); - } else if (VideoFrameType::kTexture == saved_frame_info_.type) { + if (VideoFrameType::kTexture == saved_frame_info_.type) { assert(nullptr != shared_texture_frames_); HRESULT hr = GetSharedTexture(); if (FAILED(hr)) { @@ -508,7 +562,9 @@ int VideoEncoder::EncodeFrame(AVFrame* frame) noexcept { ATLTRACE2(atlTraceException, 0, "!Map(IDXGISurface), #0x%08X\n", hr); return hr; } - BOOST_SCOPE_EXIT_ALL(&) { staging_surface->Unmap(); }; + BOOST_SCOPE_EXIT_ALL(&) { + staging_surface->Unmap(); + }; uint32_t width = saved_frame_info_.width; uint32_t height = saved_frame_info_.height; @@ -520,6 +576,7 @@ int VideoEncoder::EncodeFrame(AVFrame* frame) noexcept { uint8_t* v = u + (pixel_size >> 2); { + // TO-DO: Texture is alwayse convert to YUV420P now! if (DXGI_FORMAT_R8G8B8A8_UNORM == saved_frame_info_.format) { ABGRToI420(mapped_rect.pBits, mapped_rect.Pitch, y, width, u, uv_stride, v, uv_stride, width, height); @@ -533,6 +590,20 @@ int VideoEncoder::EncodeFrame(AVFrame* frame) noexcept { } } error_code = EncodeYuvFrame(frame, yuv_frame_data_.data()); + } else { + assert(nullptr != shared_yuv_frames_); + auto yuv_frames = + reinterpret_cast(shared_yuv_frames_.GetData()); + auto yuv_frame = reinterpret_cast(yuv_frames->data); + auto yuv_frame1 = reinterpret_cast( + yuv_frames->data + yuv_frames->data_size); + + if (yuv_frame->stats.timestamp < yuv_frame1->stats.timestamp) { + yuv_frame = yuv_frame1; + } + ATLTRACE2(atlTraceUtil, 0, "latest video frame %llu\n", + yuv_frame->stats.timestamp); + error_code = EncodeYuvFrame(frame, yuv_frame->data); } return error_code; } @@ -569,7 +640,9 @@ int VideoEncoder::EncodeYuvFrame(AVFrame* frame, const uint8_t* yuv) noexcept { if (nullptr == packet) { return ERROR_OUTOFMEMORY; } - BOOST_SCOPE_EXIT_ALL(&packet) { av_packet_free(&packet); }; + BOOST_SCOPE_EXIT_ALL(&packet) { + av_packet_free(&packet); + }; for (int written = -1;;) { error_code = avcodec_receive_packet(codec_context_, packet); @@ -579,7 +652,9 @@ int VideoEncoder::EncodeYuvFrame(AVFrame* frame, const uint8_t* yuv) noexcept { } break; } - BOOST_SCOPE_EXIT_ALL(&packet) { av_packet_unref(packet); }; + BOOST_SCOPE_EXIT_ALL(&packet) { + av_packet_unref(packet); + }; packet->stream_index = stream_->index; written = av_write_frame(format_context_, packet); diff --git a/src/cge/manual_video_source/manual_video_source.cpp b/src/cge/manual_video_source/manual_video_source.cpp deleted file mode 100644 index 0937aa5..0000000 --- a/src/cge/manual_video_source/manual_video_source.cpp +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright 2020-present Ksyun - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// C -#include -#include - -// C++, SDL -#include - -// C++, ATL -#include -#include -#include - -// C++, Boost -#include -#include - -#include "sdl_hack/sdl_hack.h" - -// UMU -#include "umu/env.h" - -#pragma comment(lib, "sdl2.lib") -#pragma comment(lib, "sdl2main.lib") -#pragma comment(lib, "SDL2_ttf.lib") - -#pragma comment(lib, "yuv.lib") - -namespace po = boost::program_options; - -namespace { - -using namespace regame; - -bool global_mode = false; -VideoFrameType frame_type = VideoFrameType::kYuv; - -TTF_Font* font = nullptr; -SDL_Window* sdl_win = nullptr; -SDL_Renderer* renderer = nullptr; -int render_driver = -1; - -void Refresh(SdlHack& sdl_hack, SDL_KeyboardEvent key) { - char text[32]; - snprintf(text, std::size(text) - 1, "%c", key.keysym.sym); - - SDL_Rect rect = {50, 50, 120, 200}; - SDL_Color color = {255, 0, 0, 128}; - SDL_Surface* surface = TTF_RenderText_Blended(font, text, color); - SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface); - if (nullptr == texture) { - SDL_DestroyRenderer(renderer); - renderer = SDL_GetRenderer(sdl_win); - texture = SDL_CreateTextureFromSurface(renderer, surface); - if (nullptr == texture) { - SDL_FreeSurface(surface); - return; - } - } - SDL_RenderClear(renderer); - SDL_RenderCopy(renderer, texture, nullptr, &rect); - SDL_DestroyTexture(texture); - SDL_FreeSurface(surface); - - snprintf(text, std::size(text) - 1, "@ %u", key.timestamp); - - rect = {200, 120, 360, 100}; - color = {255, 255, 255, 128}; - surface = TTF_RenderText_Blended(font, text, color); - texture = SDL_CreateTextureFromSurface(renderer, surface); - SDL_RenderCopy(renderer, texture, nullptr, &rect); - SDL_DestroyTexture(texture); - SDL_FreeSurface(surface); - - if (sdl_hack.IsStarted() && -1 != render_driver) { - sdl_hack.CopyTexture(renderer); - } - - SDL_RenderPresent(renderer); -} - -void Mouse(SdlHack& sdl_hack, std::string_view message, int x, int y) { - SDL_Rect rect = {30, 20, 150, 100}; - SDL_Color color = {255, 0, 0, 128}; - SDL_Surface* surface = TTF_RenderText_Blended(font, message.data(), color); - SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface); - if (nullptr == texture) { - SDL_DestroyRenderer(renderer); - renderer = SDL_GetRenderer(sdl_win); - texture = SDL_CreateTextureFromSurface(renderer, surface); - if (nullptr == texture) { - SDL_FreeSurface(surface); - return; - } - } - SDL_RenderClear(renderer); - SDL_RenderCopy(renderer, texture, nullptr, &rect); - SDL_DestroyTexture(texture); - SDL_FreeSurface(surface); - - char text[40]; - snprintf(text, std::size(text) - 1, "%d,%d", x, y); - - rect = {190, 20, 420, 100}; - color = {255, 255, 255, 128}; - surface = TTF_RenderText_Blended(font, text, color); - texture = SDL_CreateTextureFromSurface(renderer, surface); - SDL_RenderCopy(renderer, texture, nullptr, &rect); - SDL_DestroyTexture(texture); - SDL_FreeSurface(surface); - - if (sdl_hack.IsStarted() && -1 != render_driver) { - sdl_hack.CopyTexture(renderer); - } - - SDL_RenderPresent(renderer); -} - -bool ParseCommandLine(_In_ LPWSTR command_line) { - std::string type; - po::options_description desc("Usage"); - desc.add_options()("help,h", "Produce help message")( - "global-mode", po::value(&global_mode)->default_value(false), - "Set global mode")("frame-type", - po::value(&type)->default_value("yuv"), - "Set video frame type, can be one of {yuv, tex}"); - po::variables_map vm; - auto parser = po::wcommand_line_parser(po::split_winmain(command_line)); - parser.options(desc); - po::store(parser.run(), vm); - po::notify(vm); - - if (vm.count("help")) { - std::stringstream ss; - ss << desc; - MessageBox(nullptr, CA2T(ss.str().data()).m_psz, L"Help", - MB_ICONINFORMATION); - return false; - } - - if (0 == type.compare("tex")) { - frame_type = VideoFrameType::kTexture; - } - - return true; -} - -} // namespace - -int APIENTRY wWinMain(_In_ HINSTANCE hInstance, - _In_opt_ HINSTANCE hPrevInstance, - _In_ LPWSTR command_line, - _In_ int nCmdShow) { - if (!ParseCommandLine(command_line)) { - return 0; - } - - if (SDL_Init(SDL_INIT_EVERYTHING) < 0) { - return -1; - } - BOOST_SCOPE_EXIT_ALL(&) { SDL_Quit(); }; - - if (TTF_Init() == -1) { - CString error_text; - error_text.Format(_T("TTF_Init() failed: %s\n"), - CA2T(TTF_GetError()).m_psz); - MessageBox(nullptr, error_text, nullptr, MB_ICONERROR); - return -1; - } - BOOST_SCOPE_EXIT_ALL(&) { TTF_Quit(); }; - - font = TTF_OpenFont( - umu::env::ExpandEnvironmentStringA("%windir%\\Fonts\\simhei.ttf").data(), - 80); - if (nullptr == font) { - CString error_text; - error_text.Format(_T("TTF_OpenFont(simhei.ttf) failed: %s\n"), - CA2T(TTF_GetError()).m_psz); - MessageBox(nullptr, error_text, nullptr, MB_ICONERROR); - return -1; - } - BOOST_SCOPE_EXIT_ALL(&) { TTF_CloseFont(font); }; - - SdlHack sdl_hack; - if (!sdl_hack.Initialize()) { - return -1; - } - if (!sdl_hack.Run(global_mode, frame_type)) { - return -1; - } - - CStringA title("SDL Text - "); - sdl_win = SDL_CreateWindow(title, 400, 200, 640, 300, SDL_WINDOW_RESIZABLE); - if (nullptr == sdl_win) { - CString error_text; - error_text.Format(_T("SDL_CreateWindow() failed: %s\n"), - CA2T(TTF_GetError()).m_psz); - MessageBox(nullptr, error_text, nullptr, MB_ICONERROR); - return -1; - } - BOOST_SCOPE_EXIT_ALL(&) { SDL_DestroyWindow(sdl_win); }; - - SDL_version linked; - SDL_GetVersion(&linked); - title.AppendFormat("SDL %u.%u.%u, ", linked.major, linked.minor, - linked.patch); - - int num = SDL_GetNumRenderDrivers(); - for (int i = 0; i < num; ++i) { - SDL_RendererInfo info{}; - if (0 == SDL_GetRenderDriverInfo(i, &info)) { - if (CStringA("direct3d11") == info.name) { - render_driver = i; - title.Append(info.name); - break; - } - } - } - - renderer = SDL_CreateRenderer(sdl_win, render_driver, 0); - if (nullptr == renderer) { - CString error_text; - error_text.Format(_T("SDL_CreateRenderer() failed: %s\n"), - CA2T(SDL_GetError()).m_psz); - MessageBox(nullptr, error_text, nullptr, MB_ICONERROR); - return -1; - } - BOOST_SCOPE_EXIT_ALL(&) { SDL_DestroyRenderer(renderer); }; - - if (-1 == render_driver) { - SDL_RendererInfo info = {}; - SDL_GetRendererInfo(renderer, &info); - title.Append(info.name); - MessageBox(nullptr, - _T("Only support direct3d11.\r\n") - _T("Please compile SDL2 with SDL_VIDEO_RENDER_D3D11=1."), - nullptr, MB_ICONERROR); - } - - if (global_mode) { - title.Append(", global"); - } else { - title.Append(", local"); - } - - if (VideoFrameType::kTexture == frame_type) { - title.Append(", tex"); - } else { - title.Append(", yuv"); - } - - SDL_SetWindowTitle(sdl_win, title); - - SDL_RenderClear(renderer); - SDL_RenderPresent(renderer); - - for (;;) { - SDL_Event sdl_event; - if (SDL_PollEvent(&sdl_event)) { - switch (sdl_event.type) { - case SDL_QUIT: - sdl_hack.Free(); - return 0; - case SDL_KEYDOWN: - Refresh(sdl_hack, sdl_event.key); - break; - case SDL_MOUSEMOTION: - Mouse(sdl_hack, "Motion", sdl_event.motion.xrel, - sdl_event.motion.yrel); - break; - case SDL_MOUSEWHEEL: - Mouse(sdl_hack, "Wheel", sdl_event.wheel.x, sdl_event.wheel.y); - break; - case SDL_MOUSEBUTTONDOWN: - Mouse(sdl_hack, "Down", sdl_event.button.x, sdl_event.button.y); - break; - case SDL_MOUSEBUTTONUP: - Mouse(sdl_hack, "Up", sdl_event.button.x, sdl_event.button.y); - break; - } - } - } - return 0; -} diff --git a/src/cge/manual_video_source/manual_video_source.vcxproj b/src/cge/manual_video_source/manual_video_source.vcxproj deleted file mode 100644 index 57e0037..0000000 --- a/src/cge/manual_video_source/manual_video_source.vcxproj +++ /dev/null @@ -1,258 +0,0 @@ - - - - - Debug - Win32 - - - MTRelease - Win32 - - - MTRelease - x64 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - - - - - 16.0 - Win32Proj - {29b11fe9-8d7b-46dc-a66d-7369ba6ebe18} - sdlclick - 10.0 - - - - Application - true - v143 - Unicode - - - Application - false - v143 - true - Unicode - - - Application - false - v143 - true - Unicode - - - Application - true - v143 - Unicode - - - Application - false - v143 - true - Unicode - - - Application - false - v143 - true - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - true - $(SolutionDir)bin\$(PlatformTarget)\$(Configuration)\ - $(SolutionDir)tmp\$(PlatformTarget)\$(Configuration)\$(ProjectName)\ - $(BOOST_ROOT);$(SDL2_ROOT)\include;$(IncludePath) - $(BOOST_ROOT)\stage\lib;$(SDL2_ROOT)\lib\$(PlatformTarget);$(LibraryPath) - - - false - $(SolutionDir)bin\$(PlatformTarget)\$(Configuration)\ - $(SolutionDir)tmp\$(PlatformTarget)\$(Configuration)\$(ProjectName)\ - $(BOOST_ROOT);$(SDL2_ROOT)\include;$(IncludePath) - $(BOOST_ROOT)\stage\lib;$(SDL2_ROOT)\lib\$(PlatformTarget);$(LibraryPath) - - - false - $(SolutionDir)bin\$(PlatformTarget)\$(Configuration)\ - $(SolutionDir)tmp\$(PlatformTarget)\$(Configuration)\$(ProjectName)\ - $(BOOST_ROOT);$(SDL2_ROOT)\include;$(IncludePath) - $(BOOST_ROOT)\stage\lib;$(SDL2_ROOT)\lib\$(PlatformTarget);$(LibraryPath) - - - true - $(SolutionDir)bin\$(PlatformTarget)\$(Configuration)\ - $(SolutionDir)tmp\$(PlatformTarget)\$(Configuration)\$(ProjectName)\ - $(BOOST_ROOT);$(SDL2_ROOT)\include;$(IncludePath) - $(BOOST_ROOT)\stage\lib;$(SDL2_ROOT)\lib\$(PlatformTarget);$(LibraryPath) - - - false - $(SolutionDir)bin\$(PlatformTarget)\$(Configuration)\ - $(SolutionDir)tmp\$(PlatformTarget)\$(Configuration)\$(ProjectName)\ - $(BOOST_ROOT);$(SDL2_ROOT)\include;$(IncludePath) - $(BOOST_ROOT)\stage\lib;$(SDL2_ROOT)\lib\$(PlatformTarget);$(LibraryPath) - - - false - $(SolutionDir)bin\$(PlatformTarget)\$(Configuration)\ - $(SolutionDir)tmp\$(PlatformTarget)\$(Configuration)\$(ProjectName)\ - $(BOOST_ROOT);$(SDL2_ROOT)\include;$(IncludePath) - $(BOOST_ROOT)\stage\lib;$(SDL2_ROOT)\lib\$(PlatformTarget);$(LibraryPath) - - - - Level3 - true - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - stdcpplatest - ..\;..\..\deps\;..\..\deps\include;..\..\deps\umu\include;%(AdditionalIncludeDirectories) - - - Windows - true - ..\..\deps\lib\$(PlatformTarget);..\..\deps\lib\$(PlatformTarget)\$(Configuration)\; - - - - - Level3 - true - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - stdcpplatest - ..\;..\..\deps\;..\..\deps\include;..\..\deps\umu\include;%(AdditionalIncludeDirectories) - - - Windows - true - true - true - ..\..\deps\lib\$(PlatformTarget);..\..\deps\lib\$(PlatformTarget)\$(Configuration)\; - - - - - Level3 - true - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - stdcpplatest - ..\;..\..\deps\;..\..\deps\include;..\..\deps\umu\include;%(AdditionalIncludeDirectories) - MultiThreaded - - - Windows - true - true - false - ..\..\deps\lib\$(PlatformTarget);..\..\deps\lib\$(PlatformTarget)\$(Configuration)\; - - - - - Level3 - true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - stdcpplatest - ..\;..\..\deps\;..\..\deps\include;..\..\deps\umu\include;%(AdditionalIncludeDirectories) - - - Windows - true - ..\..\deps\lib\$(PlatformTarget);..\..\deps\lib\$(PlatformTarget)\$(Configuration)\; - - - - - Level3 - true - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - stdcpplatest - ..\;..\..\deps\;..\..\deps\include;..\..\deps\umu\include;%(AdditionalIncludeDirectories) - - - Windows - true - true - true - ..\..\deps\lib\$(PlatformTarget);..\..\deps\lib\$(PlatformTarget)\$(Configuration)\; - - - - - Level3 - true - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - stdcpplatest - ..\;..\..\deps\;..\..\deps\include;..\..\deps\umu\include;%(AdditionalIncludeDirectories) - MultiThreaded - - - Windows - true - true - false - ..\..\deps\lib\$(PlatformTarget);..\..\deps\lib\$(PlatformTarget)\$(Configuration)\; - - - - - - \ No newline at end of file diff --git a/src/cge/manual_video_source/manual_video_source.vcxproj.filters b/src/cge/manual_video_source/manual_video_source.vcxproj.filters deleted file mode 100644 index 37b5bbd..0000000 --- a/src/cge/manual_video_source/manual_video_source.vcxproj.filters +++ /dev/null @@ -1,25 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Source Files - - - Source Files - - - \ No newline at end of file diff --git a/src/cge/sdl_hack/sdl_hack.cpp b/src/cge/sdl_hack/sdl_hack.cpp index 7c43a80..284657f 100644 --- a/src/cge/sdl_hack/sdl_hack.cpp +++ b/src/cge/sdl_hack/sdl_hack.cpp @@ -177,31 +177,23 @@ HRESULT CaptureTexture(_In_ ID3D11DeviceContext* context, } // namespace bool SdlHack::Initialize() noexcept { - SDL_version compiled; - SDL_VERSION(&compiled); - if (2 == compiled.major && 0 == compiled.minor && 12 <= compiled.patch) { + if (SDL_VERSION_ATLEAST(2, 0, 12)) { SDL_GetVersion(&linked_); - if (2 == linked_.major && 0 == linked_.minor && 12 == linked_.patch) { + if (2 == linked_.major && 0 == linked_.minor && + (12 == linked_.patch || 14 == linked_.patch || 16 == linked_.patch || + 18 == linked_.patch || 20 == linked_.patch || 22 == linked_.patch)) { // yes - } else if (2 == linked_.major && 0 == linked_.minor && - 14 == linked_.patch) { - // yes - } else if (2 == linked_.major && 0 == linked_.minor && - 16 == linked_.patch) { - // yes - } else if (2 == linked_.major && 0 == linked_.minor && - 18 == linked_.patch) { - // yes - } else if (2 == linked_.major && 0 == linked_.minor && - 20 == linked_.patch) { + } else if (2 == linked_.major && 24 == linked_.minor && + (0 == linked_.patch || 1 == linked_.patch)) { // yes } else { CString error_text; error_text.Format( _T("Compiled with SDL %u.%u.%u\nLinked to SDL %u.%u.%u"), - compiled.major, compiled.minor, compiled.patch, linked_.major, + SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL, linked_.major, linked_.minor, linked_.patch); - MessageBox(nullptr, error_text, _T("Warning"), MB_ICONWARNING); + MessageBox(nullptr, error_text, _T("Unsupported version"), + MB_ICONWARNING); } } else { MessageBox(nullptr, _T("sdl_internal.h is only for SDL 2.0.12+!"), nullptr, @@ -317,6 +309,12 @@ void SdlHack::CopyTexture(SDL_Renderer* renderer) { } else if (2 == linked_.major && 0 == linked_.minor && 20 == linked_.patch) { render_data = static_cast( reinterpret_cast(renderer)->driverdata); + } else if ((2 == linked_.major && 0 == linked_.minor && + 22 == linked_.patch) || + (2 == linked_.major && 24 == linked_.minor && + (0 == linked_.patch || 1 == linked_.patch))) { + render_data = static_cast( + reinterpret_cast(renderer)->driverdata); } else { ATLTRACE2(atlTraceException, 0, "Unsupported SDL version: %u.%u.%u!\n", linked_.major, linked_.minor, linked_.patch); @@ -327,12 +325,20 @@ void SdlHack::CopyTexture(SDL_Renderer* renderer) { } switch (frame_type_) { - case VideoFrameType::kYuv: - CopyTextureToSharedYuv(render_data); - break; case VideoFrameType::kTexture: CopyTextureToSharedTexture(render_data); break; + case VideoFrameType::kI420: + [[fallthrough]]; + case VideoFrameType::kJ420: + [[fallthrough]]; + case VideoFrameType::kI422: + [[fallthrough]]; + case VideoFrameType::kJ422: + [[fallthrough]]; + case VideoFrameType::kI444: + CopyTextureToSharedYuv(render_data); + break; } } @@ -561,12 +567,28 @@ void SdlHack::CopyTextureToSharedYuv(D3D11_RenderData* render_data) { } if (should_update) { - width_ = desc.Width & ~1; - height_ = desc.Height & ~1; + switch (frame_type_) { + case VideoFrameType::kI420: + [[fallthrough]]; + case VideoFrameType::kJ420: + [[fallthrough]]; + case VideoFrameType::kI422: + [[fallthrough]]; + case VideoFrameType::kJ422: + width_ = desc.Width & ~1; + height_ = desc.Height & ~1; + break; + case VideoFrameType::kI444: + width_ = desc.Width; + height_ = desc.Height; + break; + default: + assert(false); + } SharedVideoFrameInfo* svfi = shared_frame_info_; svfi->timestamp = tick.QuadPart; - svfi->type = VideoFrameType::kYuv; + svfi->type = frame_type_; svfi->width = width_; svfi->height = height_; svfi->format = desc.Format; @@ -577,8 +599,27 @@ void SdlHack::CopyTextureToSharedYuv(D3D11_RenderData* render_data) { } svfi->window = reinterpret_cast(window); } else { - UINT width = desc.Width & ~1; - UINT height = desc.Height & ~1; + UINT width; + UINT height; + switch (frame_type_) { + case VideoFrameType::kI420: + [[fallthrough]]; + case VideoFrameType::kJ420: + [[fallthrough]]; + case VideoFrameType::kI422: + [[fallthrough]]; + case VideoFrameType::kJ422: + width = desc.Width & ~1; + height = desc.Height & ~1; + break; + case VideoFrameType::kI444: + width = desc.Width; + height = desc.Height; + break; + default: + assert(false); + } + if (width != width_ || height != height_) { width_ = width; height_ = height; @@ -631,7 +672,25 @@ void SdlHack::CopyTextureToSharedYuv(D3D11_RenderData* render_data) { }; size_t pixel_size = width_ * height_; - size_t frame_size = 4 * pixel_size; + size_t frame_size; + switch (frame_type_) { + case VideoFrameType::kI420: + [[fallthrough]]; + case VideoFrameType::kJ420: + frame_size = pixel_size + (pixel_size >> 1); // 1.5 + break; + case VideoFrameType::kI422: + [[fallthrough]]; + case VideoFrameType::kJ422: + frame_size = 2 * pixel_size; + break; + case VideoFrameType::kI444: + frame_size = 3 * pixel_size; + break; + default: + assert(false); + } + size_t data_size = sizeof(PackedVideoYuvFrame) + frame_size; ATLTRACE2(atlTraceUtil, 0, "Frame[%zu] %u * %u, %zu + %zu = %zu\n", frame_count_, desc.Width, desc.Height, sizeof(PackedVideoYuvFrame), @@ -667,8 +726,8 @@ void SdlHack::CopyTextureToSharedYuv(D3D11_RenderData* render_data) { return; } - ATLTRACE2(atlTraceUtil, 0, "MapSharedMem size = %zu + %zu * 2 = %zu\n", - sizeof(SharedVideoYuvFrames), data_size, + ATLTRACE2(atlTraceUtil, 0, "MapSharedMem size = %zu + %zu * %zu = %zu\n", + sizeof(SharedVideoYuvFrames), data_size, kNumberOfSharedFrames, sizeof(SharedVideoYuvFrames) + data_size * kNumberOfSharedFrames); } auto frames = @@ -678,23 +737,83 @@ void SdlHack::CopyTextureToSharedYuv(D3D11_RenderData* render_data) { auto frame = reinterpret_cast( static_cast(shared_yuv_frames_) + sizeof(SharedVideoYuvFrames) + (frame_count_ % kNumberOfSharedFrames) * data_size); - const int uv_stride = width_ >> 1; uint8_t* y = reinterpret_cast(frame->data); uint8_t* u = y + pixel_size; - uint8_t* v = u + (pixel_size >> 2); - { - umu::TimeMeasure tm(stats.elapsed.yuv_convert); - if (DXGI_FORMAT_R8G8B8A8_UNORM == desc.Format) { - ABGRToI420(mapped_rect.pBits, mapped_rect.Pitch, y, width_, u, uv_stride, - v, uv_stride, width_, height_); - } else if (DXGI_FORMAT_B8G8R8A8_UNORM == desc.Format) { - ARGBToI420(mapped_rect.pBits, mapped_rect.Pitch, y, width_, u, uv_stride, - v, uv_stride, width_, height_); - } else { - ATLTRACE2(atlTraceException, 0, "Unsupported format %u.", desc.Format); + switch (umu::TimeMeasure tm(stats.elapsed.yuv_convert); frame_type_) { + case regame::VideoFrameType::kI420: { + const int uv_stride = width_ >> 1; + uint8_t* v = u + (pixel_size >> 2); + + if (DXGI_FORMAT_R8G8B8A8_UNORM == desc.Format) { + ABGRToI420(mapped_rect.pBits, mapped_rect.Pitch, y, width_, u, + uv_stride, v, uv_stride, width_, height_); + } else if (DXGI_FORMAT_B8G8R8A8_UNORM == desc.Format) { + ARGBToI420(mapped_rect.pBits, mapped_rect.Pitch, y, width_, u, + uv_stride, v, uv_stride, width_, height_); + } else { + ATLTRACE2(atlTraceException, 0, "Unsupported format %u.", desc.Format); + } + break; } - } + case regame::VideoFrameType::kJ420: { + const int uv_stride = width_ >> 1; + uint8_t* v = u + (pixel_size >> 2); + + if (DXGI_FORMAT_R8G8B8A8_UNORM == desc.Format) { + // ABGRToJ420(mapped_rect.pBits, mapped_rect.Pitch, y, width_, u, + // uv_stride, v, uv_stride, width_, height_); + } else if (DXGI_FORMAT_B8G8R8A8_UNORM == desc.Format) { + // ARGBToJ420(mapped_rect.pBits, mapped_rect.Pitch, y, width_, u, + // uv_stride, v, uv_stride, width_, height_); + } else { + ATLTRACE2(atlTraceException, 0, "Unsupported format %u.", desc.Format); + } + break; + } + case regame::VideoFrameType::kI422: { + const int uv_stride = width_; + uint8_t* v = u + (pixel_size >> 1); + + if (DXGI_FORMAT_R8G8B8A8_UNORM == desc.Format) { + // TO-DO + } else if (DXGI_FORMAT_B8G8R8A8_UNORM == desc.Format) { + // ARGBToI422(mapped_rect.pBits, mapped_rect.Pitch, y, width_, u, + // uv_stride, v, uv_stride, width_, height_); + } else { + ATLTRACE2(atlTraceException, 0, "Unsupported format %u.", desc.Format); + } + break; + } + case regame::VideoFrameType::kJ422: { + const int uv_stride = width_; + uint8_t* v = u + (pixel_size >> 1); + + if (DXGI_FORMAT_R8G8B8A8_UNORM == desc.Format) { + // TO-DO + } else if (DXGI_FORMAT_B8G8R8A8_UNORM == desc.Format) { + // ARGBToJ422(mapped_rect.pBits, mapped_rect.Pitch, y, width_, u, + // uv_stride, v, uv_stride, width_, height_); + } else { + ATLTRACE2(atlTraceException, 0, "Unsupported format %u.", desc.Format); + } + break; + } + case regame::VideoFrameType::kI444: { + const int uv_stride = width_; + uint8_t* v = u + pixel_size; + + if (DXGI_FORMAT_R8G8B8A8_UNORM == desc.Format) { + // TO-DO + } else if (DXGI_FORMAT_B8G8R8A8_UNORM == desc.Format) { + // ARGBToI444(mapped_rect.pBits, mapped_rect.Pitch, y, width_, u, + // uv_stride, v, uv_stride, width_, height_); + } else { + ATLTRACE2(atlTraceException, 0, "Unsupported format %u.", desc.Format); + } + break; + } + } // end of switch ATLTRACE2(atlTraceUtil, 0, "frame[%zd] stats.elapsed.yuv_convert = %llu, \n", frame_count_, stats.elapsed.yuv_convert); diff --git a/src/cge/video_source.sln b/src/cge/video_source.sln index 3982b46..13c2d86 100644 --- a/src/cge/video_source.sln +++ b/src/cge/video_source.sln @@ -5,8 +5,6 @@ VisualStudioVersion = 17.1.32210.238 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "video_source", "video_source\video_source.vcxproj", "{AC8D2A50-497D-4358-99CB-1522376F3546}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "manual_video_source", "manual_video_source\manual_video_source.vcxproj", "{29B11FE9-8D7B-46DC-A66D-7369BA6EBE18}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -29,18 +27,6 @@ Global {AC8D2A50-497D-4358-99CB-1522376F3546}.Release|x64.Build.0 = Release|x64 {AC8D2A50-497D-4358-99CB-1522376F3546}.Release|x86.ActiveCfg = Release|Win32 {AC8D2A50-497D-4358-99CB-1522376F3546}.Release|x86.Build.0 = Release|Win32 - {29B11FE9-8D7B-46DC-A66D-7369BA6EBE18}.Debug|x64.ActiveCfg = Debug|x64 - {29B11FE9-8D7B-46DC-A66D-7369BA6EBE18}.Debug|x64.Build.0 = Debug|x64 - {29B11FE9-8D7B-46DC-A66D-7369BA6EBE18}.Debug|x86.ActiveCfg = Debug|Win32 - {29B11FE9-8D7B-46DC-A66D-7369BA6EBE18}.Debug|x86.Build.0 = Debug|Win32 - {29B11FE9-8D7B-46DC-A66D-7369BA6EBE18}.MTRelease|x64.ActiveCfg = MTRelease|x64 - {29B11FE9-8D7B-46DC-A66D-7369BA6EBE18}.MTRelease|x64.Build.0 = MTRelease|x64 - {29B11FE9-8D7B-46DC-A66D-7369BA6EBE18}.MTRelease|x86.ActiveCfg = MTRelease|Win32 - {29B11FE9-8D7B-46DC-A66D-7369BA6EBE18}.MTRelease|x86.Build.0 = MTRelease|Win32 - {29B11FE9-8D7B-46DC-A66D-7369BA6EBE18}.Release|x64.ActiveCfg = Release|x64 - {29B11FE9-8D7B-46DC-A66D-7369BA6EBE18}.Release|x64.Build.0 = Release|x64 - {29B11FE9-8D7B-46DC-A66D-7369BA6EBE18}.Release|x86.ActiveCfg = Release|Win32 - {29B11FE9-8D7B-46DC-A66D-7369BA6EBE18}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/cge/video_source/video_source.cpp b/src/cge/video_source/video_source.cpp index 4e933c4..605fd04 100644 --- a/src/cge/video_source/video_source.cpp +++ b/src/cge/video_source/video_source.cpp @@ -35,8 +35,6 @@ #include "umu/env.h" -#pragma comment(lib, "dxguid.lib") - #pragma comment(lib, "sdl2.lib") #pragma comment(lib, "sdl2main.lib") #pragma comment(lib, "SDL2_ttf.lib") @@ -49,8 +47,12 @@ namespace { using namespace regame; -bool global_mode = false; -VideoFrameType frame_type = VideoFrameType::kYuv; +struct Config { + bool global_mode{false}; + bool manual{false}; + + VideoFrameType frame_type{VideoFrameType::kNone}; +}; TTF_Font* font = nullptr; SDL_Window* sdl_win = nullptr; @@ -75,7 +77,7 @@ void Refresh(SdlHack& sdl_hack) { } SDL_RenderClear(renderer); - SDL_RenderCopy(renderer, texture, NULL, &rect); + SDL_RenderCopy(renderer, texture, nullptr, &rect); SDL_DestroyTexture(texture); SDL_FreeSurface(surface); @@ -91,7 +93,7 @@ void Refresh(SdlHack& sdl_hack) { color = {0, 255, 0, 192}; surface = TTF_RenderText_Blended(font, "G", color); texture = SDL_CreateTextureFromSurface(renderer, surface); - SDL_RenderCopy(renderer, texture, NULL, &rect); + SDL_RenderCopy(renderer, texture, nullptr, &rect); SDL_DestroyTexture(texture); SDL_FreeSurface(surface); @@ -99,7 +101,7 @@ void Refresh(SdlHack& sdl_hack) { color = {0, 0, 255, 255}; surface = TTF_RenderText_Blended(font, "B", color); texture = SDL_CreateTextureFromSurface(renderer, surface); - SDL_RenderCopy(renderer, texture, NULL, &rect); + SDL_RenderCopy(renderer, texture, nullptr, &rect); SDL_DestroyTexture(texture); SDL_FreeSurface(surface); @@ -111,14 +113,95 @@ void Refresh(SdlHack& sdl_hack) { SDL_RenderPresent(renderer); } -bool ParseCommandLine(_In_ LPWSTR command_line) { +void ManualRefresh(SdlHack& sdl_hack, SDL_KeyboardEvent key) { + char text[32]; + snprintf(text, std::size(text) - 1, "%c", key.keysym.sym); + + SDL_Rect rect = {50, 50, 120, 200}; + SDL_Color color = {255, 0, 0, 128}; + SDL_Surface* surface = TTF_RenderText_Blended(font, text, color); + SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface); + if (nullptr == texture) { + SDL_DestroyRenderer(renderer); + renderer = SDL_GetRenderer(sdl_win); + texture = SDL_CreateTextureFromSurface(renderer, surface); + if (nullptr == texture) { + SDL_FreeSurface(surface); + return; + } + } + SDL_RenderClear(renderer); + SDL_RenderCopy(renderer, texture, nullptr, &rect); + SDL_DestroyTexture(texture); + SDL_FreeSurface(surface); + + snprintf(text, std::size(text) - 1, "@ %u", key.timestamp); + + rect = {200, 120, 360, 100}; + color = {255, 255, 255, 128}; + surface = TTF_RenderText_Blended(font, text, color); + texture = SDL_CreateTextureFromSurface(renderer, surface); + SDL_RenderCopy(renderer, texture, nullptr, &rect); + SDL_DestroyTexture(texture); + SDL_FreeSurface(surface); + + if (sdl_hack.IsStarted() && -1 != render_driver) { + sdl_hack.CopyTexture(renderer); + } + + SDL_RenderPresent(renderer); +} + +void Mouse(SdlHack& sdl_hack, std::string_view message, int x, int y) { + SDL_Rect rect = {30, 20, 150, 100}; + SDL_Color color = {255, 0, 0, 128}; + SDL_Surface* surface = TTF_RenderText_Blended(font, message.data(), color); + SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface); + if (nullptr == texture) { + SDL_DestroyRenderer(renderer); + renderer = SDL_GetRenderer(sdl_win); + texture = SDL_CreateTextureFromSurface(renderer, surface); + if (nullptr == texture) { + SDL_FreeSurface(surface); + return; + } + } + SDL_RenderClear(renderer); + SDL_RenderCopy(renderer, texture, nullptr, &rect); + SDL_DestroyTexture(texture); + SDL_FreeSurface(surface); + + char text[40]; + snprintf(text, std::size(text) - 1, "%d,%d", x, y); + + rect = {190, 20, 420, 100}; + color = {255, 255, 255, 128}; + surface = TTF_RenderText_Blended(font, text, color); + texture = SDL_CreateTextureFromSurface(renderer, surface); + SDL_RenderCopy(renderer, texture, nullptr, &rect); + SDL_DestroyTexture(texture); + SDL_FreeSurface(surface); + + if (sdl_hack.IsStarted() && -1 != render_driver) { + sdl_hack.CopyTexture(renderer); + } + + SDL_RenderPresent(renderer); +} + +std::tuple ParseCommandLine(_In_ LPWSTR command_line) { std::string type; + Config config{}; + po::options_description desc("Usage"); desc.add_options()("help,h", "Produce help message")( - "global-mode", po::value(&global_mode)->default_value(false), + "global-mode", po::value(&config.global_mode)->default_value(false), "Set global mode")("frame-type", - po::value(&type)->default_value("yuv"), - "Set video frame type, can be one of {yuv, tex}"); + po::value(&type)->default_value("tex"), + "Set video frame type, can be one of {tex, i420, " + "j420, i422, j422, i444}")( + "manual", po::value(&config.manual)->default_value(false), + "Manual mode"); po::variables_map vm; auto parser = po::wcommand_line_parser(po::split_winmain(command_line)); parser.options(desc); @@ -130,14 +213,24 @@ bool ParseCommandLine(_In_ LPWSTR command_line) { ss << desc; MessageBox(nullptr, CA2T(ss.str().data()).m_psz, L"Help", MB_ICONINFORMATION); - return false; + return {false, config}; } if (0 == type.compare("tex")) { - frame_type = VideoFrameType::kTexture; + config.frame_type = VideoFrameType::kTexture; + } else if (0 == type.compare("i420")) { + config.frame_type = VideoFrameType::kI420; + } else if (0 == type.compare("j420")) { + config.frame_type = VideoFrameType::kJ420; + } else if (0 == type.compare("i422")) { + config.frame_type = VideoFrameType::kI422; + } else if (0 == type.compare("j422")) { + config.frame_type = VideoFrameType::kJ422; + } else if (0 == type.compare("i444")) { + config.frame_type = VideoFrameType::kI444; } - return true; + return {true, config}; } } // namespace @@ -146,14 +239,17 @@ int APIENTRY wWinMain(_In_ HINSTANCE /*instance*/, _In_opt_ HINSTANCE /*prev_instance*/, _In_ LPWSTR command_line, _In_ int /*show*/) { - if (!ParseCommandLine(command_line)) { + auto [parsed, config] = ParseCommandLine(command_line); + if (!parsed) { return 0; } if (SDL_Init(SDL_INIT_EVERYTHING) < 0) { return -1; } - BOOST_SCOPE_EXIT_ALL(&) { SDL_Quit(); }; + BOOST_SCOPE_EXIT_ALL(&) { + SDL_Quit(); + }; if (TTF_Init() == -1) { CString error_text; @@ -162,7 +258,9 @@ int APIENTRY wWinMain(_In_ HINSTANCE /*instance*/, MessageBox(nullptr, error_text, nullptr, MB_ICONERROR); return -1; } - BOOST_SCOPE_EXIT_ALL(&) { TTF_Quit(); }; + BOOST_SCOPE_EXIT_ALL(&) { + TTF_Quit(); + }; font = TTF_OpenFont( umu::env::ExpandEnvironmentStringA("%windir%\\Fonts\\simhei.ttf").data(), @@ -174,13 +272,15 @@ int APIENTRY wWinMain(_In_ HINSTANCE /*instance*/, MessageBox(nullptr, error_text, nullptr, MB_ICONERROR); return -1; } - BOOST_SCOPE_EXIT_ALL(&) { TTF_CloseFont(font); }; + BOOST_SCOPE_EXIT_ALL(&) { + TTF_CloseFont(font); + }; SdlHack sdl_hack; if (!sdl_hack.Initialize()) { return -1; } - if (!sdl_hack.Run(global_mode, frame_type)) { + if (!sdl_hack.Run(config.global_mode, config.frame_type)) { return -1; } @@ -193,7 +293,9 @@ int APIENTRY wWinMain(_In_ HINSTANCE /*instance*/, MessageBox(nullptr, error_text, nullptr, MB_ICONERROR); return -1; } - BOOST_SCOPE_EXIT_ALL(&) { SDL_DestroyWindow(sdl_win); }; + BOOST_SCOPE_EXIT_ALL(&) { + SDL_DestroyWindow(sdl_win); + }; SDL_version linked; SDL_GetVersion(&linked); @@ -222,7 +324,9 @@ int APIENTRY wWinMain(_In_ HINSTANCE /*instance*/, MessageBox(nullptr, error_text, nullptr, MB_ICONERROR); return -1; } - BOOST_SCOPE_EXIT_ALL(&) { SDL_DestroyRenderer(renderer); }; + BOOST_SCOPE_EXIT_ALL(&) { + SDL_DestroyRenderer(renderer); + }; if (-1 == render_driver) { SDL_RendererInfo info = {}; @@ -234,33 +338,87 @@ int APIENTRY wWinMain(_In_ HINSTANCE /*instance*/, nullptr, MB_ICONERROR); } - if (global_mode) { + if (config.global_mode) { title.Append(", global"); } else { title.Append(", local"); } - if (VideoFrameType::kTexture == frame_type) { - title.Append(", tex"); - } else { - title.Append(", yuv"); + switch (config.frame_type) { + case VideoFrameType::kTexture: + title.Append(", tex"); + break; + case VideoFrameType::kI420: + title.Append(", i420"); + break; + case VideoFrameType::kJ420: + title.Append(", j420"); + break; + case VideoFrameType::kI422: + title.Append(", i422"); + break; + case VideoFrameType::kJ422: + title.Append(", j422"); + break; + case VideoFrameType::kI444: + title.Append(", i444"); + break; + default: + MessageBox(nullptr, _T("Unsupported frame-type!"), nullptr, MB_ICONERROR); + return -1; + } + + if (config.manual) { + title.Append(", manual"); } SDL_SetWindowTitle(sdl_win, title); - for (;;) { - SDL_Event sdl_event; - if (SDL_PollEvent(&sdl_event)) { - if (SDL_QUIT == sdl_event.type) { - sdl_hack.Free(); - break; - } else if (SDL_KEYDOWN == sdl_event.type) { - if (SDLK_ESCAPE == sdl_event.key.keysym.sym) { + if (config.manual) { + SDL_RenderClear(renderer); + SDL_RenderPresent(renderer); + + for (;;) { + SDL_Event sdl_event; + if (SDL_PollEvent(&sdl_event)) { + switch (sdl_event.type) { + case SDL_QUIT: + sdl_hack.Free(); + return 0; + case SDL_KEYDOWN: + ManualRefresh(sdl_hack, sdl_event.key); + break; + case SDL_MOUSEMOTION: + Mouse(sdl_hack, "Motion", sdl_event.motion.xrel, + sdl_event.motion.yrel); + break; + case SDL_MOUSEWHEEL: + Mouse(sdl_hack, "Wheel", sdl_event.wheel.x, sdl_event.wheel.y); + break; + case SDL_MOUSEBUTTONDOWN: + Mouse(sdl_hack, "Down", sdl_event.button.x, sdl_event.button.y); + break; + case SDL_MOUSEBUTTONUP: + Mouse(sdl_hack, "Up", sdl_event.button.x, sdl_event.button.y); + break; + } + } + } + } else { + for (;;) { + SDL_Event sdl_event; + if (SDL_PollEvent(&sdl_event)) { + if (SDL_QUIT == sdl_event.type) { + sdl_hack.Free(); break; + } else if (SDL_KEYDOWN == sdl_event.type) { + if (SDLK_ESCAPE == sdl_event.key.keysym.sym) { + break; + } } + } else { + Refresh(sdl_hack); } - } else { - Refresh(sdl_hack); } } return 0; diff --git a/src/deps/include/regame/sdl_internal.h b/src/deps/include/regame/sdl_internal.h index 5cd7c3b..bb4e3e4 100644 --- a/src/deps/include/regame/sdl_internal.h +++ b/src/deps/include/regame/sdl_internal.h @@ -41,6 +41,9 @@ freely, subject to the following restrictions: * 2.0.16 * 2.0.18 * 2.0.20 + * 2.0.22 + * 2.24.0 + * 2.24.1 */ #pragma once @@ -1044,6 +1047,204 @@ struct SDL_Renderer_2_0_20 { void* driverdata; }; +// 2.0.22 +/** + * A rectangle, with the origin at the upper left (double precision). + */ +typedef struct SDL_DRect { + double x; + double y; + double w; + double h; +} SDL_DRect; + +/* Define the SDL 2.0.22 - 2.24.1 renderer structure */ +struct SDL_Renderer_2_0_22 { + const void* magic; + + void (*WindowEvent)(SDL_Renderer* renderer, const SDL_WindowEvent* event); + int (*GetOutputSize)(SDL_Renderer* renderer, int* w, int* h); + SDL_bool (*SupportsBlendMode)(SDL_Renderer* renderer, + SDL_BlendMode blendMode); + int (*CreateTexture)(SDL_Renderer* renderer, SDL_Texture* texture); + int (*QueueSetViewport)(SDL_Renderer* renderer, SDL_RenderCommand* cmd); + int (*QueueSetDrawColor)(SDL_Renderer* renderer, SDL_RenderCommand* cmd); + int (*QueueDrawPoints)(SDL_Renderer* renderer, + SDL_RenderCommand* cmd, + const SDL_FPoint* points, + int count); + int (*QueueDrawLines)(SDL_Renderer* renderer, + SDL_RenderCommand* cmd, + const SDL_FPoint* points, + int count); + int (*QueueFillRects)(SDL_Renderer* renderer, + SDL_RenderCommand* cmd, + const SDL_FRect* rects, + int count); + int (*QueueCopy)(SDL_Renderer* renderer, + SDL_RenderCommand* cmd, + SDL_Texture* texture, + const SDL_Rect* srcrect, + const SDL_FRect* dstrect); + int (*QueueCopyEx)(SDL_Renderer* renderer, + SDL_RenderCommand* cmd, + SDL_Texture* texture, + const SDL_Rect* srcquad, + const SDL_FRect* dstrect, + const double angle, + const SDL_FPoint* center, + const SDL_RendererFlip flip, + float scale_x, + float scale_y); + int (*QueueGeometry)(SDL_Renderer* renderer, + SDL_RenderCommand* cmd, + SDL_Texture* texture, + const float* xy, + int xy_stride, + const SDL_Color* color, + int color_stride, + const float* uv, + int uv_stride, + int num_vertices, + const void* indices, + int num_indices, + int size_indices, + float scale_x, + float scale_y); + + int (*RunCommandQueue)(SDL_Renderer* renderer, + SDL_RenderCommand* cmd, + void* vertices, + size_t vertsize); + int (*UpdateTexture)(SDL_Renderer* renderer, + SDL_Texture* texture, + const SDL_Rect* rect, + const void* pixels, + int pitch); +#if SDL_HAVE_YUV + int (*UpdateTextureYUV)(SDL_Renderer* renderer, + SDL_Texture* texture, + const SDL_Rect* rect, + const Uint8* Yplane, + int Ypitch, + const Uint8* Uplane, + int Upitch, + const Uint8* Vplane, + int Vpitch); + int (*UpdateTextureNV)(SDL_Renderer* renderer, + SDL_Texture* texture, + const SDL_Rect* rect, + const Uint8* Yplane, + int Ypitch, + const Uint8* UVplane, + int UVpitch); +#endif + int (*LockTexture)(SDL_Renderer* renderer, + SDL_Texture* texture, + const SDL_Rect* rect, + void** pixels, + int* pitch); + void (*UnlockTexture)(SDL_Renderer* renderer, SDL_Texture* texture); + void (*SetTextureScaleMode)(SDL_Renderer* renderer, + SDL_Texture* texture, + SDL_ScaleMode scaleMode); + int (*SetRenderTarget)(SDL_Renderer* renderer, SDL_Texture* texture); + int (*RenderReadPixels)(SDL_Renderer* renderer, + const SDL_Rect* rect, + Uint32 format, + void* pixels, + int pitch); + void (*RenderPresent)(SDL_Renderer* renderer); + void (*DestroyTexture)(SDL_Renderer* renderer, SDL_Texture* texture); + + void (*DestroyRenderer)(SDL_Renderer* renderer); + + int (*SetVSync)(SDL_Renderer* renderer, int vsync); + + int (*GL_BindTexture)(SDL_Renderer* renderer, + SDL_Texture* texture, + float* texw, + float* texh); + int (*GL_UnbindTexture)(SDL_Renderer* renderer, SDL_Texture* texture); + + void* (*GetMetalLayer)(SDL_Renderer* renderer); + void* (*GetMetalCommandEncoder)(SDL_Renderer* renderer); + + /* The current renderer info */ + SDL_RendererInfo info; + + /* The window associated with the renderer */ + SDL_Window* window; + SDL_bool hidden; + + /* The logical resolution for rendering */ + int logical_w; + int logical_h; + int logical_w_backup; + int logical_h_backup; + + /* Whether or not to force the viewport to even integer intervals */ + SDL_bool integer_scale; + + /* The drawable area within the window */ + SDL_DRect viewport; + SDL_DRect viewport_backup; + + /* The clip rectangle within the window */ + SDL_DRect clip_rect; + SDL_DRect clip_rect_backup; + + /* Wether or not the clipping rectangle is used. */ + SDL_bool clipping_enabled; + SDL_bool clipping_enabled_backup; + + /* The render output coordinate scale */ + SDL_FPoint scale; + SDL_FPoint scale_backup; + + /* The pixel to point coordinate scale */ + SDL_FPoint dpi_scale; + + /* Whether or not to scale relative mouse motion */ + SDL_bool relative_scaling; + + /* The method of drawing lines */ + SDL_RenderLineMethod line_method; + + /* Remainder from scaled relative motion */ + float xrel; + float yrel; + + /* The list of textures */ + SDL_Texture* textures; + SDL_Texture* target; + SDL_mutex* target_mutex; + + SDL_Color color; /**< Color for drawing operations values */ + SDL_BlendMode blendMode; /**< The drawing blend mode */ + + SDL_bool always_batch; + SDL_bool batching; + SDL_RenderCommand* render_commands; + SDL_RenderCommand* render_commands_tail; + SDL_RenderCommand* render_commands_pool; + Uint32 render_command_generation; + Uint32 last_queued_color; + SDL_DRect last_queued_viewport; + SDL_DRect last_queued_cliprect; + SDL_bool last_queued_cliprect_enabled; + SDL_bool color_queued; + SDL_bool viewport_queued; + SDL_bool cliprect_queued; + + void* vertex_data; + size_t vertex_data_used; + size_t vertex_data_allocation; + + void* driverdata; +}; + + // UMU: Texture struct SDL_SW_YUVTexture { diff --git a/src/deps/include/regame/shared_mem_info.h b/src/deps/include/regame/shared_mem_info.h index 767f834..9bb1c9e 100644 --- a/src/deps/include/regame/shared_mem_info.h +++ b/src/deps/include/regame/shared_mem_info.h @@ -51,7 +51,15 @@ struct SharedAudioFrames { PackedAudioFrame frame0; }; -enum class VideoFrameType : std::uint32_t { kNone = 0, kYuv, kTexture }; +enum class VideoFrameType : std::uint32_t { + kNone = 0, + kTexture, + kI420, // YUV420P + kJ420, // YUV420P, AVCOL_RANGE_JPEG + kI422, // YUV422P + kJ422, // YUV422P, AVCOL_RANGE_JPEG + kI444, // YUV444P +}; struct SharedVideoFrameInfo { std::uint64_t timestamp; @@ -110,7 +118,7 @@ constexpr std::wstring_view kSharedAudioFrameFileMappingName{ L"{185A6EAB-BA8D-4FFB-BE3F-135C72A61606}"}; constexpr std::wstring_view kVideoStartedEventName{ - L"{75B053EC-7CF7-4608-961F-3D2663F3FB2D}"}; + L"{4BBDEBFF-4711-4F99-B3D5-8171B7D1B09B}"}; // since v0.5 constexpr std::wstring_view kVideoStoppedEventName{ L"{6D27BAD8-A314-4421-8CC1-1285E940631D}"}; constexpr std::wstring_view kSharedVideoFrameReadyEventName{ diff --git a/src/deps/yuv.sln b/src/deps/yuv.sln index 89c0afb..0426116 100644 --- a/src/deps/yuv.sln +++ b/src/deps/yuv.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30011.22 +# Visual Studio Version 17 +VisualStudioVersion = 17.3.32929.385 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yuv", "yuv\yuv.vcxproj", "{32D0DFDB-00D5-4167-B3F9-DC871B867179}" EndProject