Skip to content

Commit 3823bd2

Browse files
committed
playback function of Recorded AVI
1 parent 9af8e61 commit 3823bd2

File tree

13 files changed

+102
-41
lines changed

13 files changed

+102
-41
lines changed

MLDX12VideoCapture/MLAVICommon.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ enum MLFOURCC {
1515
MLFOURCC_strh = 0x68727473,
1616
MLFOURCC_strf = 0x66727473,
1717
MLFOURCC_vids = 0x73646976,
18+
MLFOURCC_auds = 0x73647561,
1819
MLFOURCC_v210 = 0x30313276,
1920
MLFOURCC_AVIX = 0x58495641,
2021
MLFOURCC_movi = 0x69766f6d,

MLDX12VideoCapture/MLAviReader.cpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,28 @@ MLAviReader::~MLAviReader(void)
1414
Close();
1515
}
1616

17+
MLVideoTime
18+
MLAviReader::FrameNrToTime(const int frameNr)
19+
{
20+
MLVideoTime r;
21+
memset(&r, 0, sizeof r);
22+
23+
if (FramesPerSec() == 0) {
24+
return r;
25+
}
26+
27+
r.frame = frameNr % FramesPerSec();
28+
const int totalSec = frameNr / FramesPerSec();
29+
30+
r.hour = totalSec / 3600;
31+
int remain = totalSec - r.hour * 3600;
32+
r.min = remain / 60;
33+
remain -= r.min * 60;
34+
r.sec = remain;
35+
36+
return r;
37+
}
38+
1739
float
1840
MLAviReader::DurationSec(void) const
1941
{
@@ -242,7 +264,8 @@ MLAviReader::ReadAviStreamFormatHeader(void)
242264
return false;
243265
}
244266

245-
if (bytes == 40) {
267+
if (mAviStreamHeader.fccType == MLFOURCC_vids
268+
&& bytes == 40) {
246269
// BITMAPINFOHEADER
247270
if (40 != fread(&mImageFormat, 1, 40, mFp)) {
248271
printf("Error: ReadAviStreamFormatHeader() read BITMAPINFOHEADER failed\n");
@@ -320,7 +343,7 @@ MLAviReader::GetImage(const int frameNr, const uint32_t buffBytes, uint8_t *buff
320343
}
321344

322345
ImagePosBytes pb = mImages[frameNr];
323-
if (pb.bytes < buffBytes) {
346+
if (buffBytes < pb.bytes) {
324347
printf("Error: buffBytes is too small\n");
325348
return E_FAIL;
326349
}

MLDX12VideoCapture/MLAviReader.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <stdio.h>
77
#include "Common.h"
88
#include "MLAVICommon.h"
9+
#include "MLVideoTime.h"
910

1011
class MLAviReader {
1112
public:
@@ -21,6 +22,8 @@ class MLAviReader {
2122

2223
float DurationSec(void) const;
2324

25+
MLVideoTime FrameNrToTime(const int frameNr);
26+
2427
/// @return > 0 : copied bytes, negative value: error.
2528
int GetImage(const int frameNr,
2629
const uint32_t buffBytes, uint8_t *buff);

MLDX12VideoCapture/MLDX12App.cpp

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,15 @@ MLDX12App::OnInit(void)
7272
{
7373
mVideoCaptureDeviceList.Init();
7474

75-
OutputDebugString(L"OnInit started\n");
75+
//OutputDebugString(L"OnInit started\n");
7676

7777
LoadPipeline();
7878
LoadAssets();
7979

8080
mDx12Imgui.Init(mDevice.Get());
8181
CreateImguiTexture();
8282

83-
OutputDebugString(L"OnInit end\n");
83+
//OutputDebugString(L"OnInit end\n");
8484
}
8585

8686
void
@@ -644,14 +644,27 @@ MLDX12App::OnRender(void)
644644
mCmdQ->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);
645645

646646
UpdateCapturedVideoTexture();
647+
UpdatePlayVideoTexture();
647648

648649
ThrowIfFailed(mSwapChain->Present(1, 0));
649650
MoveToNextFrame();
650651
}
651652

652653
void
653-
MLDX12App::DrawFullscreenTexture(TextureEnum texId)
654+
MLDX12App::DrawFullscreenTexture(TextureEnum texId, MLImage::ImageMode drawMode)
654655
{
656+
switch (drawMode) {
657+
case MLImage::IM_RGB:
658+
mCmdList->SetPipelineState(mPipelineStateRGB.Get());
659+
break;
660+
case MLImage::IM_YUV:
661+
mCmdList->SetPipelineState(mPipelineStateYUV.Get());
662+
break;
663+
default:
664+
assert(0);
665+
break;
666+
}
667+
655668
mCmdList->SetGraphicsRootSignature(mRootSignature.Get());
656669

657670
ID3D12DescriptorHeap* ppHeaps[] = { mSrvHeap.Get() };
@@ -664,10 +677,6 @@ MLDX12App::DrawFullscreenTexture(TextureEnum texId)
664677
mCmdList->RSSetViewports(1, &mViewport);
665678
mCmdList->RSSetScissorRects(1, &mScissorRect);
666679

667-
mCmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(
668-
mRenderTargets[mFrameIdx].Get(), D3D12_RESOURCE_STATE_PRESENT,
669-
D3D12_RESOURCE_STATE_RENDER_TARGET));
670-
671680
CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(mRtvHeap->GetCPUDescriptorHandleForHeapStart(),
672681
mFrameIdx, mRtvDescSize);
673682
mCmdList->OMSetRenderTargets(1, &rtvHandle, FALSE, nullptr);
@@ -681,31 +690,29 @@ void
681690
MLDX12App::PopulateCommandList(void)
682691
{
683692
ThrowIfFailed(mCmdAllocators[mFrameIdx]->Reset());
693+
ThrowIfFailed(mCmdList->Reset(mCmdAllocators[mFrameIdx].Get(), mPipelineStateRGB.Get()));
684694

685-
switch (mCaptureDrawMode) {
686-
case MLImage::IM_RGB:
687-
ThrowIfFailed(mCmdList->Reset(mCmdAllocators[mFrameIdx].Get(), mPipelineStateRGB.Get()));
688-
break;
689-
case MLImage::IM_YUV:
690-
ThrowIfFailed(mCmdList->Reset(mCmdAllocators[mFrameIdx].Get(), mPipelineStateYUV.Get()));
691-
break;
692-
default:
693-
break;
694-
}
695+
mCmdList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(
696+
mRenderTargets[mFrameIdx].Get(), D3D12_RESOURCE_STATE_PRESENT,
697+
D3D12_RESOURCE_STATE_RENDER_TARGET));
695698

696699
{ // clear screen
697-
const float clearColor[] = {0.0f, 0.2f, 0.4f, 1.0f};
700+
const float clearColorRGBA[] = {0.4f, 0.4f, 0.4f, 1.0f};
698701
CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(mRtvHeap->GetCPUDescriptorHandleForHeapStart(),
699702
mFrameIdx, mRtvDescSize);
700703
mCmdList->OMSetRenderTargets(1, &rtvHandle, FALSE, nullptr);
701-
mCmdList->ClearRenderTargetView(rtvHandle, clearColor, 0, nullptr);
704+
mCmdList->ClearRenderTargetView(rtvHandle, clearColorRGBA, 0, nullptr);
702705
}
703706

704707
// 全クライアント領域を覆う矩形にテクスチャを貼って描画。
705-
DrawFullscreenTexture((TextureEnum)(TE_CAPVIDEO0 + mIdToShowCapVideoTex));
708+
DrawFullscreenTexture(
709+
(TextureEnum)(TE_CAPVIDEO0 + mIdToShowCapVideoTex),
710+
mCaptureDrawMode);
706711

707712
if (0.0f < mPlayAlpha) {
708-
DrawFullscreenTexture((TextureEnum)(TE_PLAYVIDEO0 + mIdToShowPlayVideoTex));
713+
DrawFullscreenTexture(
714+
(TextureEnum)(TE_PLAYVIDEO0 + mIdToShowPlayVideoTex),
715+
mPlayDrawMode);
709716
}
710717

711718
// Start the Dear ImGui frame
@@ -966,7 +973,7 @@ MLDX12App::ShowPlaybackWindow(void)
966973
if (mAviReader.Open(path)) {
967974
const MLBitmapInfoHeader &bi = mAviReader.ImageFormat();
968975

969-
if (bi.biWidth != 3840 || bi.biHeight != 2160 || bi.biCompression != MLFOURCC_v210) {
976+
if (bi.biCompression != MLFOURCC_v210) {
970977
sprintf_s(mPlayMsg, "Error: Not supported AVI format : %s", mReadPath);
971978
ImGui::OpenPopup("ErrorPlayPopup");
972979
mAviReader.Close();
@@ -986,8 +993,18 @@ MLDX12App::ShowPlaybackWindow(void)
986993
mAviReader.Close();
987994
mPlayAlpha = 0.0f;
988995
}
989-
ImGui::Text("Total %d frames, %d fps, %.1f sec",
990-
mAviReader.NumFrames(), mAviReader.FramesPerSec(), mAviReader.DurationSec());
996+
ImGui::Text("%d x %d, %d fps, %.1f sec",
997+
mAviReader.ImageFormat().biWidth, mAviReader.ImageFormat().biHeight,
998+
mAviReader.FramesPerSec(), mAviReader.DurationSec());
999+
1000+
{
1001+
// hour:min:sec:frameを算出。
1002+
auto vt = mAviReader.FrameNrToTime(mPlayFrameNr);
1003+
1004+
ImGui::Text("%02d:%02d:%02d:%02d",
1005+
vt.hour, vt.min, vt.sec, vt.frame);
1006+
}
1007+
9911008
// シークバー。
9921009
ImGui::DragInt("Frame number", &mPlayFrameNr, 1.0f, 0, mAviReader.NumFrames() - 1);
9931010

@@ -1007,8 +1024,6 @@ MLDX12App::ShowPlaybackWindow(void)
10071024
mConverter.CreateGammaTable(mDrawGamma, mDrawGainR, mDrawGainG, mDrawGainB);
10081025
}
10091026
}
1010-
1011-
UpdatePlayVideoTexture();
10121027
}
10131028

10141029
ImGui::End();
@@ -1175,6 +1190,9 @@ MLDX12App::UpdateVideoTexture(MLImage &ci, ComPtr<ID3D12Resource> &tex, TextureE
11751190
srvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
11761191
srvDesc.Texture2D.MipLevels = 1;
11771192
mDevice->CreateShaderResourceView(tex.Get(), &srvDesc, srvHandle);
1193+
} else {
1194+
mCmdListTexUpload->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(tex.Get(),
1195+
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_COPY_DEST));
11781196
}
11791197

11801198
// texUploadHeapがスコープから外れる前にcommandListを実行しなければならない。
@@ -1191,9 +1209,6 @@ MLDX12App::UpdateVideoTexture(MLImage &ci, ComPtr<ID3D12Resource> &tex, TextureE
11911209
nullptr,
11921210
IID_PPV_ARGS(&texUploadHeap)));
11931211

1194-
mCmdListTexUpload->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(tex.Get(),
1195-
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_COPY_DEST));
1196-
11971212
D3D12_SUBRESOURCE_DATA textureData = {};
11981213
textureData.pData = &ci.data[0];
11991214
textureData.RowPitch = ci.width * pixelBytes;
@@ -1279,7 +1294,7 @@ MLDX12App::UpdatePlayVideoTexture(void)
12791294
}
12801295

12811296
UpdateVideoTexture(ci, mTexPlayVideo[!mIdToShowPlayVideoTex],
1282-
(TextureEnum)(TE_CAPVIDEO0 + !mIdToShowPlayVideoTex));
1297+
(TextureEnum)(TE_PLAYVIDEO0 + !mIdToShowPlayVideoTex));
12831298

12841299
mPlayDrawMode = ci.imgMode;
12851300

MLDX12VideoCapture/MLDX12App.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ class MLDX12App : public MLDX12, IMLVideoCaptureCallback {
161161
void CreateImguiTexture(void);
162162
void ImGuiCommands(void);
163163

164-
void DrawFullscreenTexture(TextureEnum texId);
164+
void DrawFullscreenTexture(TextureEnum texId, MLImage::ImageMode drawMode);
165165

166166
void ShowCaptureSettingsWindow(void);
167167
void ShowPlaybackWindow(void);

MLDX12VideoCapture/MLDX12VideoCapture.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
<ClInclude Include="imstb_rectpack.h" />
3131
<ClInclude Include="imstb_textedit.h" />
3232
<ClInclude Include="imstb_truetype.h" />
33+
<ClInclude Include="MLVideoTime.h" />
3334
<ClInclude Include="WinApp.h" />
3435
</ItemGroup>
3536
<ItemGroup>

MLDX12VideoCapture/MLDX12VideoCapture.vcxproj.filters

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@
8080
<ClInclude Include="MLImage.h">
8181
<Filter>Header Files</Filter>
8282
</ClInclude>
83+
<ClInclude Include="MLVideoTime.h">
84+
<Filter>Header Files</Filter>
85+
</ClInclude>
8386
</ItemGroup>
8487
<ItemGroup>
8588
<ClCompile Include="Main.cpp">

MLDX12VideoCapture/MLVideoTime.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#pragma once
2+
3+
struct MLVideoTime {
4+
int hour;
5+
int min;
6+
int sec;
7+
int frame;
8+
};

MLDX12VideoCapture/Main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ wWinMain(
3030

3131
MLDX12App app(1920, 1080);
3232

33-
int rv = WinApp::Run(&app, hInstance, nCmdShow);
33+
int rv = WinApp::Run(&app, hInstance, nCmdShow, L"MLDX12VideoCapture");
3434

3535
if (coInitialized) {
3636
CoUninitialize();

MLDX12VideoCapture/WinApp.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,30 @@
1515
#include "imgui_impl_win32.h"
1616

1717
HWND WinApp::mHwnd = nullptr;
18+
std::wstring WinApp::mTitle = L"WinApp";
1819

1920
int
20-
WinApp::Run(MLDX12* pDX12, HINSTANCE hInstance, int nCmdShow)
21+
WinApp::Run(MLDX12* pDX12, HINSTANCE hInstance, int nCmdShow, const wchar_t *title)
2122
{
23+
if (title) {
24+
mTitle = title;
25+
}
26+
2227
WNDCLASSEX wc = { 0 };
2328
wc.cbSize = sizeof(WNDCLASSEX);
2429
wc.style = CS_HREDRAW | CS_VREDRAW;
2530
wc.lpfnWndProc = WindowProc;
2631
wc.hInstance = hInstance;
2732
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
28-
wc.lpszClassName = L"DXSampleClass";
33+
wc.lpszClassName = mTitle.c_str();
2934
RegisterClassEx(&wc);
3035

3136
RECT rect = { 0, 0, static_cast<LONG>(pDX12->Width()), static_cast<LONG>(pDX12->Height()) };
3237
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
3338

3439
mHwnd = CreateWindow(
3540
wc.lpszClassName,
36-
L"WinApp",
41+
mTitle.c_str(),
3742
WS_OVERLAPPEDWINDOW,
3843
CW_USEDEFAULT,
3944
CW_USEDEFAULT,
@@ -100,7 +105,7 @@ WinApp::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
100105

101106
case WM_SIZE:
102107
if (pDX12) {
103-
OutputDebugString(L"WM_SIZE\n");
108+
//OutputDebugString(L"WM_SIZE\n");
104109
RECT windowR = {};
105110
GetWindowRect(hWnd, &windowR);
106111
pDX12->SetWindowBounds(

0 commit comments

Comments
 (0)