いつもお世話になっております。
mp4を読み込んでSeekMovieToGraph関数で現在の再生位置から少し前に戻して再生する。といったものを実装したのですが、
SeekMovieToGraph関数のところで処理に時間がかかり、その間処理が止まってしまいます。
どれくらい固まるかは差があるのですが、早いときでも100ms、遅いときだと700msほど処理が固まります。
(SeekMovieToGraph関数の前後にGetNowCount関数を置いて検証しました)
試しに拡張子をaviに変更しても変化は見られませんでした。
この関数の実行には時間がかかるものなのでしょうか。(私の探した限りでは言及している方を見かけなかったので)
また、この重い処理時間をなくす、もしくはマシにさせる方法はございますでしょうか。
【現状分かっていること】
・動画自体の進行?は正常で、Seekさせた直後に再生しても、処理はしばらく固まるものの、処理が再開された後は固まった時間含めて正しい再生位置で再生されています。
・動画の最初(0ms)にSeekさせた直後に再生させると、固まる時間は40〜50ms程度にまで短くなります。
そして、指定を0msから300ms程度までにすると固まる時間が増えていき、それ以降の指定だと先程の固まる時間になります。
一応検証に使ったコードを載せておきます。
#include <DxLib.h>
#include <cmath>
#include <cstring>
#define WINDOW_TITLE_TEXT "テンプレート"
#define EXTEND_WIDTH 1920
#define EXTEND_HEIGHT 1080
#define WINDOW_EXTENDRATE 2
using namespace std;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// exe起動時にLog.txtを出力する
SetOutApplicationLogValidFlag(TRUE);
SetUseCharCodeFormat(DX_CHARCODEFORMAT_UTF8);
// ウィンドウモードにする
ChangeWindowMode(TRUE);
// ウィンドウタイトルを設定
SetWindowText(WINDOW_TITLE_TEXT);
// ウィンドウのサイズを設定
SetGraphMode(EXTEND_WIDTH, EXTEND_HEIGHT, 16);
SetWindowSizeExtendRate(pow(WINDOW_EXTENDRATE, -0.5));
// ウィンドウのサイズ変更を不可にする
SetWindowSizeChangeEnableFlag(FALSE);
SetDoubleStartValidFlag(FALSE);
// 非アクティブ時でも実行を継続する設定
SetAlwaysRunFlag(TRUE);
// 垂直同期(TRUEだとFPS固定、FALSEだとPCの最大FPS)
SetWaitVSyncFlag(TRUE);
// アイコンを設定
SetWindowIconID(IDI_ICON1);
// DirectXを使用するバージョンを設定
SetUseDirect3DVersion(DX_DIRECT3D_11);
// Dxライブラリ初期化処理
if (DxLib_Init() == -1)
{
return -1; // エラーが起きたら直ちに終了
}
// ライティングは行わない
SetUseLighting(FALSE);
SetDXArchive();
const int movieHandle = LoadGraph("test.mp4");
if (movieHandle == -1)
{
DxLib_End();
return -1;
}
char keyState[256] = {};
char prevKeyState[256] = {};
const int seekBackMs = 2000; // 巻き戻し時間
SetDrawScreen(DX_SCREEN_BACK);
// メインループを追加
while (ProcessMessage() == 0)
{
if (ClearDrawScreen() != 0)
{
break;
}
GetHitKeyStateAll(keyState);
const bool pressedP = keyState[KEY_INPUT_P] && !prevKeyState[KEY_INPUT_P];
const bool pressedO = keyState[KEY_INPUT_O] && !prevKeyState[KEY_INPUT_O];
const bool pressedI = keyState[KEY_INPUT_I] && !prevKeyState[KEY_INPUT_I];
const bool pressedU = keyState[KEY_INPUT_U] && !prevKeyState[KEY_INPUT_U];
const bool pressedY = keyState[KEY_INPUT_Y] && !prevKeyState[KEY_INPUT_Y];
const bool pressedT = keyState[KEY_INPUT_T] && !prevKeyState[KEY_INPUT_T];
if (pressedP)
{
PlayMovieToGraph(movieHandle);
}
if (pressedO)
{
PauseMovieToGraph(movieHandle);
}
if (pressedI)
{
const int currentPos = TellMovieToGraph(movieHandle);
if (currentPos >= 0)
{
const int targetPos = currentPos - seekBackMs > 0 ? currentPos - seekBackMs : 0;
printf("Seek前:%d\n", GetNowCount());
SeekMovieToGraph(movieHandle, targetPos);
printf("Seek完了:%d\n", GetNowCount());
PlayMovieToGraph(movieHandle);
}
}
if (pressedU)
{
PauseMovieToGraph(movieHandle);
printf("リセット停止前:%d\n", GetNowCount());
SeekMovieToGraph(movieHandle, 0);
printf("リセット停止完了:%d\n", GetNowCount());
}
if (pressedY)
{
PauseMovieToGraph(movieHandle);
printf("リセット前:%d\n", GetNowCount());
SeekMovieToGraph(movieHandle, 0);
printf("リセット完了:%d\n", GetNowCount());
PlayMovieToGraph(movieHandle);
}
if (pressedT)
{
const int currentPos = TellMovieToGraph(movieHandle);
if (currentPos >= 0)
{
const int targetPos = currentPos - seekBackMs > 0 ? currentPos - seekBackMs : 0;
printf("Seek前:%d\n", GetNowCount());
SeekMovieToGraph(movieHandle, targetPos);
printf("Seek完了:%d\n", GetNowCount());
}
}
DrawExtendGraph(0, 0, EXTEND_WIDTH, EXTEND_HEIGHT, movieHandle, FALSE);
DrawFormatString(20, 20, GetColor(255, 255, 255), "P:再生 / O:停止 / I:%dms戻し再生 / U:リセット / Y:リセット直後に再生 / T:%dms戻し", seekBackMs, seekBackMs);
memcpy(prevKeyState, keyState, sizeof(keyState));
if (ScreenFlip() != 0)
{
break;
}
}
DeleteGraph(movieHandle);
DxLib_End();
return 0; // ソフトの終了
}
以下はLog.txtの出力です。
0:ChangeWindowMode実行
6:ウインドウモードフラグが立てられました
8:DXライブラリの初期化処理開始
14: システムの情報を出力します
14: DXライブラリ Ver3.24e
16: 論理プロセッサの数 : 8
16: OS Windows11 ( Build 26200 )
118: 現時点のCPU動作速度:大体2.79GHz
118: MMX命令を使用します
118: SSE命令が使用可能です
118: SSE2命令が使用可能です
119: CPUベンダ:GenuineIntel
121: CPU名:11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
122: COMの初期化... 成功
125: 非同期読み込み処理の初期化...成功
125: ファイルアクセス処理の初期化...成功
127: メモリ総量:16020.80MB 空きメモリ領域:4191.89MB
127: タイマーの精度を検査します
127: 精度結果 更新回数 マルチメディアタイマー:0 パフォーマンスカウンター:60
128: パフォーマンスカウンターを使用します タイマー精度 : 10000.000000 KHz
128:
129: ソフトの二重起動検査... 二重起動はされていませんでした
133: ウインドウクラスを登録します... 登録に成功しました
133: ウインドウモード起動用のウインドウを作成します
133: ディスプレイ情報のセットアップ開始
135: モニターの数:1 ディスプレイデバイスの数:4
169: No.0 モニター名:\\.\DISPLAY1 1920x1080 32bit 60Hz 144x144dpi
184: ディスプレイ情報のセットアップ完了
184: ウインドウ矩形 ( 275, 101 )-( 1638, 904 )
190: ウインドウの作成に成功しました
190: ウインドウを表示します
220: IMEを無効にしました
221: ウインドウスタイルをウインドウモード用に変更します... 完了
244: XInput DLL の読み込み中... 成功
245: DirectInput関係初期化処理
246: DirectInput8 の取得を試みます...成功
259: 引き続き初期化処理... 初期化成功
263: ジョイパッドの初期化...
263: XInput 対応コントローラーのチェックを開始します
264: XInput 対応コントローラー No.0 をチェック
264: XInput 対応コントローラー No.0 の接続は確認できませんでした
265: XInput 対応コントローラー No.1 をチェック
265: XInput 対応コントローラー No.1 の接続は確認できませんでした
266: XInput 対応コントローラー No.2 をチェック
266: XInput 対応コントローラー No.2 の接続は確認できませんでした
266: XInput 対応コントローラー No.3 をチェック
267: XInput 対応コントローラー No.3 の接続は確認できませんでした
267: XInput 対応コントローラーのチェック完了
268: DirectInput 対応ジョイパッドの列挙を開始します
290: DirectInput 対応ジョイパッドの列挙終了
290: ジョイパッドの初期化は正常に終了しました
290: マウスデバイスの初期化... 初期化成功
291: キーボードデバイスの初期化... 初期化成功
296: DirectInput 関連の初期化は正常に終了しました
301: WASAPI の初期化を行います
308: デバイス名 : スピーカー (Realtek(R) Audio)
539: デフォルト遅延時間 : 10.000 ms
539: 最小遅延時間 : 3.000 ms
540: 遅延時間 : 10.000 ms
540: チャンネル数 : 2 ch
540: 量子化ビット深度 : 32 bit
540: 有効ビット深度 : 32 bit
540: サンプリングレート : 48000 Hz
541: データ形式 : 浮動小数点型
839: 動作モード : 共有モード
840: WASAPI の初期化は正常に終了しました
841: d3d11.dll の読み込み.... 成功
843: dxgi.dll の読み込み.... 成功
843: API CreateDXGIFactory2 のアドレスを取得します.... 成功
844: IDXGIFactory2 を作成します.... 成功
852: API CreateDXGIFactory6 のアドレスを取得します.... 成功
853: IDXGIAdapter を列挙
854: Adapter No.0 Desc:Intel(R) Iris(R) Xe Graphics VRAM:128MB
854: Output Device No.0 Name:\\.\DISPLAY1 ( 0, 0 )-( 1920, 1080 )
854: Adapter No.1 Desc:Microsoft Basic Render Driver VRAM:0MB
855: API D3D11CreateDevice のアドレスを取得します.... 成功
855: IDXGIAdapter を取得します.... 成功
856: IDXGIAdapter1 を取得します.... 成功
857: IDXGIAdapter2 を取得します.... 成功
857: IDXGIAdapter3 を取得します.... 成功
858: IDXGIAdapter4 を取得します.... 成功
858: Direct3D 11 FeatureLevel 11_0 以上を対象とします
858: ID3D11Device オブジェクトを取得します.... 成功
901: IDXGIDevice1 を取得します.... 成功
902: IDXGIDevice1->SetMaximunFrameLatency( 1 ); を実行しました
902: [ウインドウモード 1920x1080 ( 281, 139 )-( 1638, 902 )]
902: IDXGISwapChain2 を作成します.... 成功
905: IDXGIFactory2->CreateSwapChainForHwnd の戻り値:0x00000000
905: IDXGIOutput を取得します.... 成功
905: Graphics Device:Intel(R) Iris(R) Xe Graphics
905: 画面のフォーマットは DXGI_FORMAT_R8G8B8A8_UNORM です
906: 16bit Zバッファフォーマットは DXGI_FORMAT_D16_UNORM です
906: 24bit Zバッファフォーマットは DXGI_FORMAT_D24_UNORM_S8_UINT です
907: 32bit Zバッファフォーマットは DXGI_FORMAT_D32_FLOAT です
907: 16bit カラーフォーマットは DXGI_FORMAT_B5G6R5_UNORM です
907: 32bit カラーフォーマットは DXGI_FORMAT_B8G8R8X8_UNORM です
907: アルファ付き 16bit カラーフォーマットは DXGI_FORMAT_B4G4R4A4_UNORM です
908: アルファ付き 32bit カラーフォーマットは DXGI_FORMAT_R8G8B8A8_UNORM です
908: アルファテスト用 16bit カラーフォーマットは DXGI_FORMAT_B5G5R5A1_UNORM です
909: アルファテスト用 32bit カラーフォーマットは DXGI_FORMAT_R8G8B8A8_UNORM です
909: DXT1テクスチャフォーマットは DXGI_FORMAT_BC1_UNORM です
909: DXT2テクスチャフォーマットは使えません
909: DXT3テクスチャフォーマットは DXGI_FORMAT_BC2_UNORM です
909: DXT4テクスチャフォーマットは使えません
910: DXT5テクスチャフォーマットは DXGI_FORMAT_BC3_UNORM です
910: BC7_UNORM テクスチャフォーマットは DXGI_FORMAT_BC7_UNORM です
910: BC7_UNORM_SRGB テクスチャフォーマットは DXGI_FORMAT_BC7_UNORM_SRGB です
911: ABGR 整数 16 ビット型カラーフォーマットは DXGI_FORMAT_R16G16B16A16_UNORM です
911: ABGR 浮動小数点 16 ビット型カラーフォーマットは DXGI_FORMAT_R16G16B16A16_FLOAT です
911: ABGR 浮動小数点 32 ビット型カラーフォーマットは DXGI_FORMAT_R32G32B32A32_FLOAT です
911: 1チャンネル整数 8 ビット型カラーフォーマットは DXGI_FORMAT_R8_UNORM です
912: 1チャンネル整数 16 ビット型カラーフォーマットは DXGI_FORMAT_R16_UNORM です
912: 1チャンネル浮動小数点 16 ビット型カラーフォーマットは DXGI_FORMAT_R16_FLOAT です
912: 1チャンネル浮動小数点 32 ビット型カラーフォーマットは DXGI_FORMAT_R32_FLOAT です
912: 2チャンネル整数 8 ビット型カラーフォーマットは DXGI_FORMAT_R8G8_UNORM です
913: 2チャンネル整数 16 ビット型カラーフォーマットは DXGI_FORMAT_R16G16_UNORM です
913: 2チャンネル浮動小数点 16 ビット型カラーフォーマットは DXGI_FORMAT_R16G16_FLOAT です
913: 2チャンネル浮動小数点 32 ビット型カラーフォーマットは DXGI_FORMAT_R32G32_FLOAT です
913: 描画用 16bit カラーフォーマットは DXGI_FORMAT_B5G6R5_UNORM です
914: 描画用 32bit カラーフォーマットは DXGI_FORMAT_B8G8R8X8_UNORM です
914: 描画用アルファ付き 32bit カラーフォーマットは DXGI_FORMAT_R8G8B8A8_UNORM です
914: 描画用 ABGR 整数 16 ビット型カラーフォーマットは DXGI_FORMAT_R16G16B16A16_UNORM です
914: 描画用 ABGR 浮動小数点 16 ビット型カラーフォーマットは DXGI_FORMAT_R16G16B16A16_FLOAT です
915: 描画用 ABGR 浮動小数点 32 ビット型カラーフォーマットは DXGI_FORMAT_R32G32B32A32_FLOAT です
915: 描画用1チャンネル整数 8 ビット型カラーフォーマットは DXGI_FORMAT_R8_UNORM です
915: 描画用1チャンネル整数 16 ビット型カラーフォーマットは DXGI_FORMAT_R16_UNORM です
915: 描画用1チャンネル浮動小数点 16 ビット型カラーフォーマットは DXGI_FORMAT_R16_FLOAT です
915: 描画用1チャンネル浮動小数点 32 ビット型カラーフォーマットは DXGI_FORMAT_R32_FLOAT です
916: 描画用2チャンネル整数 8 ビット型カラーフォーマットは DXGI_FORMAT_R8G8_UNORM です
916: 描画用2チャンネル整数 16 ビット型カラーフォーマットは DXGI_FORMAT_R16G16_UNORM です
916: 描画用2チャンネル浮動小数点 16 ビット型カラーフォーマットは DXGI_FORMAT_R16G16_FLOAT です
916: 描画用2チャンネル浮動小数点 32 ビット型カラーフォーマットは DXGI_FORMAT_R32G32_FLOAT です
916: 使用する機能レベル:D3D_FEATURE_LEVEL_11_1
917: 同時にレンダリングできるバッファの数:8
917: 最大テクスチャサイズ 幅:16384 高さ:16384
918: 標準描画用の頂点バッファの作成.... 成功
918: シェーダーコード関係の初期化.... 成功
944: 各種シェーダー用定数バッファの作成.... 成功
946: 各種 ID3D11InputLayout の作成.... 成功
961: 画像の単純転送処理の初期化... 成功
962: 深度バッファを作成します.... 成功
963: フォントの初期化を行います
965: フォントの初期化は正常に終了しました
1046: 文字コードバッファの初期化を行います... 完了しました
1065:DXライブラリの初期化処理終了
52191:ウインドウを閉じようとしています
52200:ウインドウが破棄されようとしています
52200:ソフトを終了する準備が整いました
52241:フォントの初期化を行います
52241:フォントの初期化は正常に終了しました
52265:d3d11.dll の解放 1
52266:dxgi.dll の解放 1
52267:Direct3D11 のオブジェクト数を出力
52267:Direct3D11 のオブジェクト合計数 : 0
52269:DirectInput 関連の終了処理... 完了
52272:サウンド関連の終了処理... 完了
52278:ウィンドウ関連の終了処理... 完了
52339:COMを終了... 完了
52339:
52340:Alloc memory dump
52340: Total size:0(0.000kb) Alloc num:0
52340: