Easy Video Frame LIBrary
EVFLIB 1.2
"evflib.h" by I.N. 2018/5/30 |
内容
1.
はじめに
特長,
動作環境,
環境設定,
インストール方法,
アンインストール方法,
使用手順
2.
説明
基本的なこと,
各種情報の取得,
画像フォーマット,
フレームバッファ,
読み込めるファイル形式
3.
サンプルプログラム
最も単純なプログラム,
Win32 コンソール アプリケーションの例,
ESPLIBを併用した例(1),
ESPLIBを併用した例(2)
4.
関数リファレンス
5.おわりに
著作権・使用許諾,
バージョンアップ履歴,
作者のウェブサイト,
作者への連絡先,
開発環境
はじめに
本製品をお買い上げいただき誠にありがとうございます.(無料です)
このライブラリ関数を使えば,動画ファイルからフレーム画像を取り出すプログラムを手軽に作成できます.
特長
(1) 内部でDirectShowを使用しており,様々な動画形式のファイルを読むことができます.
(2) 1フレームずつ画像データを取り出すことができます.
(3) 任意のフレーム番号へ移動(シーク)することもできます.
(4) 画像サイズ,ビット数,フレーム数,現在位置等の情報を取得することができます.
(5) 画像フォーマットは32ビットおよび24ビットから選択できます.
(6) フレームバッファ(転送先)の変更ができます.
(7) 最大10個のファイルを同時に開くことができます.
動作環境
OS:Windows 7/10 (これ以外では未確認)
必要ソフト:Visual C++
例1 Visual Studio Professional 2017 + qedit.h ※1※2
例2 Visual C++ 2008 Professional ※1
※1 DirectX SDKはなくてもよい.
※2 Visual C++ 2010以降にはqedit.hがついてこないため,
VC++2008あるいは適当なWindows SDKに入っているqedit.hをコピーして持ってくる.
対応する動画ファイル形式:.avi/.mpg/.wmv/.mov/.mp4/.flv等 ※3
※3 PC構成やインストールされているコーデック,アプリケーション等にも依ります.(詳しくは後述)
環境設定
・
Visual C++ のインストール
あらかじめ,Visual C++ をインストールしておいて下さい.
・
Visual C++ 2008では
インストール以外,特にすることはありません.
・
Visual C++ 2010以降では
Visual C++ 2010以降にはqedit.hがありません.
Visual C++ 2008についてきたqedit.hをVisual C++ 2010以降の方にもコピーしておきます. 例えば,C:\Program
Files\Microsoft SDKs\Windows\v6.0A\Include\qedit.h を C:\Program Files\Microsoft
SDKs\Windows\v7.0A\Include\へコピーします.
他の方法(例えば,適当なWindows SDKをインストールする)でqedit.hを入手しても構いません.
インストール方法
インストールと言う程のことでもありませんが,evflib.hを適当なディレクトリに置いて使用してください.
evflib.hが置いてあるディレクトリへのパスが通っていれば,evflib.hはどこに置いても構いません.
メインのソースファイルと同じディレクトリに置いて,プログラムの先頭で#inlude "evflib.h"と書くのが簡単な方法です.
また,下記の方法でインストールすると,どのプロジェクトからも共通に使うことができます.
Visual C++ 2008 の場合
以下の2方法を例として挙げておきます.(他の方法でも構いません.)
方法1:
evflib.h を適当なフォルダに置きます.そして,Visual C++ で「ツール」→「オプション」→「プロジェクトおよびソリューション」→「VC++ディレクトリ」→「ディレクトリを表示するプロジェクト:インクルードファイル」の画面を表示させ,evflib.h
を置いた先のフォルダ名を追加登録します.
方法2:
Visual C++ が C:\Program Files\Microsoft Visual Studio 9.0 フォルダにインストールされている場合を例にとると,C:\Program
Files\Microsoft Visual Studio 9.0\VC\include フォルダの中に evflib.h をコピーする.
Visual C++ 2010以降 の場合
各プロジェクトのプロパティで,evflib.h が置いてあるディレクトリを,インクルードファイルのディレクトリに追加する.
アンインストール方法
evflib.h を削除するだけです.
方法1でインストールした場合
インストールの時と同じ手順で「ディレクトリを表示するプロジェクト:インクルードファイル」の画面を表示させ,自分が追加したフォルダ名の登録を削除する.
方法2でインストールした場合
C:\Program Files\Microsoft Visual Studio 9.0\VC\include フォルダの中にある evflib.h
を削除する.
使用手順
プログラムの先頭で evflib.hをインクルードするだけです.
プログラムソースファイルの拡張子は .cpp にして下さい.
OpenCVを併用する場合は,
cv.hの方を先にインクルードしておいてください.
説明
基本的なこと
動画ファイルを開くため最初に
EVF_Open()を使います.
画像データの格納に必要なメモリ領域のサイズを得るには
EVF_BufferSize()を使います.
画像データを取得するには
EVF_GetFrame()を使います.
次のフレームへ進めるときは
EVF_Next()を使います.複数フレームずつのステップも可能です.
取得位置を任意のフレームまで飛ばすときは
EVF_Seek()を使います.
終了するときは最後に
EVF_Close()を使ってファイルを閉じて下さい.
各種情報の取得
画像のサイズを知るには
EVF_WX(), EVF_WY()を使います.
画像のビット数を知るには
EVF_Bit()を使います.
総フレーム数を知るには
EVF_Frames()を使います.
(ただし,推定値です.動画の終わりは
EVF_Next()や
EVF_Seek()の戻り値で判定します.)
現在のフレーム番号(読み込み位置)を知るには
EVF_Frame()を使います.
現在の位置(時刻)を知るには
EVF_CurTime()を使います.
平均フレーム時間を知るには
EVF_AvgTime()を使います.
動画の全体時間を知るには
EVF_MaxTime()を使います.
フレームレートを知るには
EVF_FrameRate()を使います.
画像フォーマット
デフォルトの画像フォーマットは,OpenCVのヘッダファイル(cv.h)が読み込まれていればMEDIASUBTYPE_RGB24,読み込まれていなければMEDIASUBTYPE_RGB32になります.
MEDIASUBTYPE_RGB24の場合,画像データの並び(バイト単位)は[B][G][R]です.また,MEDIASUBTYPE_RGB32の場合,画像データの並び(バイト単位)は[B][G][R][0]です.
デフォルト以外の画像フォーマットを使用したい場合は,
EVF_Open()で3番目の引数に指定します.
例: EVF_Open(0,"example.mpg",MEDIASUBTYPE_RGB24);このように
EVF_Open()を使うとファイル毎に独立した画像フォーマットを設定できます.詳しくは
EVF_Open()を参照してください.
また,デフォルトの画像フォーマットを変更したいときは,
#define EVF_TYPE MEDIASUBTYPE_RGB24
#include <evflib.h>
のように,evflib.hのインクルードより前でEVF_TYPEを定義してください.
フレームバッファ
EVFLIBでは
EVF_Open()の実行時に画像データを格納するためのフレームバッファを内部で自動的に確保します.画像データは取得毎にそのフレームバッファへ格納されます.
EVF_GetFrame()はそのフレームバッファからユーザが指定したメモリ領域へ画像データをユーザ側のタイミングで転送(コピー)する関数です.
もし「自前でフレームバッファを用意するから,画像データを
EVF_Next()や
EVF_Seek()による取得毎に自動でそのフレームバッファに転送(格納)してくれ」という場合には,
EVF_SetBuffer()を使います.このようにすると無駄な転送が減り,より高速なプログラムを作成できるでしょう.
読み込めるファイル形式
どのファイル形式が開けるのかは,PC構成やWindowsのバージョンやアップデート状況,インストールされているコーデックやアプリケーション等によって変わります.(この点については,作者は詳しいことを知りません.また,貴方のPC構成やソフトウェア環境について作者が知っている可能性も低いので,質問はご遠慮下さい.)
EVF_Open()で動画ファイルが開けない(エラー終了する)場合でも,コーデック/コーデックパックをPCへ追加インストールすれば,開けるようになる場合があります.作者が試した中で効果があったコーデックパックの例として,CCCP(Combined
Community Codec Pack)やK-Lite Codec Packがあります.
動画編集ソフトや動画再生ソフトがインストールされているPC環境では,様々な動画形式を開ける場合があります.
画像フォーマットがデフォルトの32ビット(MEDIASUBTYPE_RGB32)では黒い画像しか得られないけど,24ビット(MEDIASUBTYPE_RGB24)を指定したら正常な画像が得られるようになる場合もあります.
サンプルプログラム
最も単純なプログラム
最も単純なWin32 コンソール アプリケーションの例です.
動画の画像サイズは320x240であることが前提です.
最初のフレームをimg0[]に格納し,次のフレームをimg1[]に格納して,終了です.
このプログラムの意味はほとんどありませんが,EVFLIBの使い方が簡単であることを示すための例です.
#include "evflib.h"
int img0[320*240];
int img1[320*240];
int main(void)
{
EVF_Open(0,"movie.mpg");
EVF_GetFrame(0,img0);
EVF_Next(0);
EVF_GetFrame(0,img1);
EVF_Close(0);
return 0;
}
|
Win32 コンソール アプリケーションの例
動画ファイルを開き,フレーム番号500から最後までの画像を順番に取得し,配列img[]に格納(上書き)します.
画像の表示はありません.
// evflib.hの使用例 (Win32 Console Application)
#include <stdio.h>
#include "evflib.h"
#define FILENAME "C:\\Users\\Public\\Videos\\Sample Videos\\Wildlife.wmv"
int main(void)
{
int r= EVF_Open(0,FILENAME); //ファイルを開く
printf("Open:%d [%s]\n",r,FILENAME);
if(r) return 1;
//情報の表示
printf("WX,WY,BIT=%d,%d,%d\n", EVF_WX(0), EVF_WY(0), EVF_Bit(0));
printf("BufferSize=%d\n", EVF_BufferSize(0));
printf("AvgTime=%I64d\n", EVF_AvgTime(0));
printf("MaxTime=%I64d\n", EVF_MaxTime(0));
printf("Frames=%d\n", EVF_Frames(0));
printf("FrameRate=%f\n", EVF_FrameRate(0));
printf("count_per_seek=%d\n", evf_s[0].count_per_seek);
unsigned char *img= new BYTE[ EVF_BufferSize(0) ];
if(img==NULL) return 2;
r= EVF_Seek(0,500); //頭出し(フレーム500から)
printf("Seek:%d f:%d t:%I64d\n",r,EVF_Frame(0),EVF_CurTime(0));
printf("Hit enter key.\n");
getchar();
for(;;){
EVF_GetFrame(0,img); //画像の取得
//---imgに入った画像を使ってここで何か処理をする---
r=EVF_Next(0); //次のフレームへ
printf("Next:%d f:%d\n",r,EVF_Frame(0));
if(r) break;
}
r= EVF_Close(0); //ファイルを閉じる
printf("Close:%d\n",r);
delete[] img;
return 0;
}
|
ESPLIBを併用した例(1)
EVFLIBとESPLIBを使って,フレーム画像を表示するアプリケーション例です.
プログラム実行後,Filenameの欄にファイル名を入力して,Startをクリックしてください.
各ボタンをクリックするとその機能を試すことができます.
[ボタン名 : 機能]
Next, GetFrame : EVF_Next()で次のフレームに移動し,画像を取得し,表示します.
Seek +1, GetFrame : EVF_Seek()で次のフレームに移動し,画像を取得し,表示します.
All by Next : EVF_Next()を使って,終わりまで再生します.
All by Seek +1 : EVF_Seek()を使って,終わりまで再生します.
(このボタンはテスト用です.本来はEVF_Next()でフレームを進めます)
Next n : nの欄へ入力された数でEVF_Next()を実行します.
nフレームだけ飛ばすことができますが,大きいnでは,時間がかかる場合もあります.
また,表示の更新はありませんので,下のGetFrameボタンを使ってください.
Seek s : sの欄に入力されたフレーム番号へ移動します.
表示の更新はありませんので,下のGetFrameボタンを使ってください.
GetFrame : 画像を取得し,表示します.
Disp.info. : 動画ファイルの情報を表示します.
Stopのクリックでファイルを閉じます.
ESPLIBのインストール方法や使用方法は割愛させていただきます.
//evflib.hのプログラム例
#include "esplib.h"
#include "evflib.h"
#define FILENAME "C:\\Users\\Public\\Videos\\Sample Videos\\Wildlife.wmv"
void ESP_Ready(void)
{
// ESPLIB --- Automatic Source Generator
// [Text Window]
ESP_OpenTextWindow(0,0,518,345,211);
// [Input Box]
ESP_OpenInputBox(361,518,3);
ESP_ResizeInputBox(80,395);
ESP_SetInputBoxTitle(0,"Filename");
ESP_SetInputBoxTitle(1,"n");
ESP_SetInputBoxTitle(2,"s");
// [Button Box]
ESP_OpenButtonBox(361,644,4,2);
ESP_ResizeButtonBox(623,66);
ESP_SetButtonBoxTitle(0,"Next, GetFrame");
ESP_SetButtonBoxTitle(1,"Seek +1, GetFrame");
ESP_SetButtonBoxTitle(2,"All by Next");
ESP_SetButtonBoxTitle(3,"All by Seek +1");
ESP_SetButtonBoxTitle(4,"Next n");
ESP_SetButtonBoxTitle(5,"Seek s");
ESP_SetButtonBoxTitle(6,"GetFrame");
ESP_SetButtonBoxTitle(7,"Disp.info.");
// [Main Window]
ESP_PlaceMain(864,518);
ESP_SetForeground(ESPMAINWINDOW);
ESP_SetInputBoxS(0,FILENAME);
ESP_SetInputBoxI(1,1);
}
void disp_info(void)
{
ESP_Printf("WX,WY,BIT=%d,%d,%d\n", EVF_WX(0), EVF_WY(0), EVF_Bit(0));
ESP_Printf("BufferSize=%d\n", EVF_BufferSize(0));
ESP_Printf("AvgTime=%I64d\n", EVF_AvgTime(0));
ESP_Printf("MaxTime=%I64d\n", EVF_MaxTime(0));
ESP_Printf("Frames=%d\n", EVF_Frames(0));
ESP_Printf("FrameRate=%f\n", EVF_FrameRate(0));
ESP_Printf("count_per_seek=%d\n",evf_s[0].count_per_seek);
}
void ESP_Main(void)
{
int r;
char file[MAX_PATH];
ESP_GetInputBoxS(0,file,sizeof(file));
r= EVF_Open(0,file,MEDIASUBTYPE_RGB24);
ESP_Printf("Open:%d [%s]\n",r,file);
if(r) return;
int wx= EVF_WX(0);
int wy= EVF_WY(0);
int *img32= new int[wx*wy];
ESP_CreateImage(0,"Image",0,0,wx,wy, wy>480?50:100);
int upd=0;
ESP_SetButtonBox(6);
ESP_SetButtonBox(7);
for(;;){
if(ESP_STOP)break;
if(ESP_GetButtonBox(0)){
r=EVF_Next(0);
ESP_Printf("Next:%d f:%d\n",r,EVF_Frame(0));
EVF_GetFrame24to32(0,img32);
upd=1;
}
if(ESP_GetButtonBox(1)){
r=EVF_Seek(0,EVF_Frame(0)+1);
ESP_Printf("Seek:%d f:%d t:%I64d\n",r,EVF_Frame(0),EVF_CurTime(0));
EVF_GetFrame24to32(0,img32);
upd=1;
}
if(ESP_GetButtonBox(2)){
for(;;){
if(ESP_STOP) break;
r=EVF_Next(0);
ESP_Printf("Next:%d f:%d\n",r,EVF_Frame(0));
if(r) break;
EVF_GetFrame24to32(0,img32);
ESP_PutWindow(img32,0,0,evf_s[0].wx,evf_s[0].wy);
ESP_Update();
}
}
if(ESP_GetButtonBox(3)){
for(;;){
if(ESP_STOP) break;
r=EVF_Seek(0,EVF_Frame(0)+1);
ESP_Printf("Seek:%d f:%d t:%I64d\n",r,EVF_Frame(0),EVF_CurTime(0));
if(r) break;
EVF_GetFrame24to32(0,img32);
ESP_PutWindow(img32,0,0,evf_s[0].wx,evf_s[0].wy);
ESP_Update();
}
}
if(ESP_GetButtonBox(4)){
int n=ESP_GetInputBoxI(1);
r=EVF_Next(0,n);
ESP_Printf("Next:%d f:%d\n",r,EVF_Frame(0));
}
if(ESP_GetButtonBox(5)){
int s=ESP_GetInputBoxI(2);
r=EVF_Seek(0,s);
ESP_Printf("Seek:%d f:%d t:%I64d\n",r,EVF_Frame(0),EVF_CurTime(0));
}
if(ESP_GetButtonBox(7)) disp_info();
if(ESP_GetButtonBox(6)){
r= EVF_GetFrame24to32(0,img32);
ESP_Printf("GetFrame:%d\n",r);
upd=1;
}
if(upd){
upd=0;
ESP_PutWindow(img32,0,0,evf_s[0].wx,evf_s[0].wy);
ESP_Update();
}
}
r= EVF_Close(0);
ESP_DestroyImage(0);
delete[] img32;
ESP_Printf("Close:%d\n",r);
}
void ESP_Finish(void)
{
}
|
ESPLIBを併用した例(2)
4つの動画ファイルを同時に開いて表示します.
動画の画像サイズは640x480であることが前提です.
EVFLIBとESPLIBを使用しています.
//4ファイル同時再生
#include "esplib.h"
#include "evflib.h"
const char *file[4]={
"movie1.MOV",
"movie2.wmv",
"movie3.AVI",
"movie4.mpg"
};
void disp_info(int i)
{
ESP_Printf("WX,WY,BIT=%d,%d,%d\n", EVF_WX(i), EVF_WY(i), EVF_Bit(i));
ESP_Printf("BufferSize=%d\n", EVF_BufferSize(i));
ESP_Printf("AvgTime=%I64d\n", EVF_AvgTime(i));
ESP_Printf("MaxTime=%I64d\n", EVF_MaxTime(i));
ESP_Printf("Frames=%d\n", EVF_Frames(i));
ESP_Printf("FrameRate=%f\n", EVF_FrameRate(i));
ESP_Printf("count_per_seek=%d\n",evf_s[i].count_per_seek);
}
void ESP_Ready(void)
{
// ESPLIB --- Automatic Source Generator
// [Image Window]
ESP_CreateImage(0,"Video 0",0,0,640,480,50);
ESP_CreateImage(1,"Video 1",336,0,640,480,50);
ESP_CreateImage(2,"Video 2",0,278,640,480,50);
ESP_CreateImage(3,"Video 3",336,278,640,480,50);
// [Text Window]
ESP_OpenTextWindow(0,672,0,306,748);
// [Main Window]
ESP_PlaceMain(210,597);
ESP_SetForeground(ESPMAINWINDOW);
for(int i=0;i<4;i++){
int r= EVF_Open(i,file[i]); //ファイルを開く
ESP_Printf("\nr=%d [%s]\n",r,file[i]);
if(r) return;
disp_info(i);
}
}
void ESP_Main(void)
{
int f[4]={1,1,1,1}; //実行フラグ
for(;;){
if(ESP_STOP) break;
ESP_Printf("Frame ");
for(int i=0;i<4;i++){
ESP_Printf("%d ",EVF_Frame(i)); //フレーム番号
if(f[i]){
EVF_GetFrame(i,ESP_VramPtr[i]); //画像の取得
ESP_Update_(i); //ウィンドウ更新
int r= EVF_Next(i); //次のフレームへ
if(r) f[i]=0;
}
}
ESP_Printf("\n");
}
}
void ESP_Finish(void)
{
int r;
for(int i=0;i<4;i++){
r= EVF_Close(i); //ファイルを閉じる
ESP_PrintfU("Close %d: r=%d\n",i,r);
}
Sleep(500);
}
|
関数リファレンス
EVFLIBの各関数の動作やそれによって取得できる情報は,動画ファイルやPC構成によって微妙に異なることがありますので,あらかじめご了承ください.
int EVF_Open(int i, const char *filename);
int EVF_Open(int i, const char *filename, GUID mstype);
説明
指定された動画ファイルを開きます.
ファイル毎に最初に1回だけ使用します.
ファイルが開けると,始め(フレーム番号0)の画像が内部バッファへ格納された状態になっています.
ファイルの使用が終わったら
EVF_Close()で終了処理を行ってください.
3番目の引数に画像フォーマットを指定することもできます.省略時は,MEDIASUBTYPE_RGB32です.
ただし,省略時の画像フォーマットはEVF_TYPEが定義されていると変わります.
引数
i:識別番号(0〜9)
同時に複数のファイルが開ける仕様のため,識別番号を付けます.0から順番に使う必要はありません.
他の関数では,引数として,この識別番号が必要です.
filename:動画ファイルのファイル名
mstype:画像フォーマット(この引数はオプション)
デフォルトの画像フォーマットから変更したい場合,この引数を使います.
これによりファイル毎に異なる画像フォーマットを指定することができます.
動作確認したフォーマット:
MEDIASUBTYPE_RGB32
MEDIASUBTYPE_RGB24
戻り値
0:正常終了
0以外:エラー終了
エラーが出るかどうかは,動画ファイルの形式,PC構成,Windowsのバージョン,コーデックのインストール状況にも依ります.
代表的な値と理由:
1 i値が不正.
2 すでに開かれている.
9 ファイルが見つからない.
17, 18 フィルタ間の接続に失敗.対応していない動画形式である可能性が高いです.
24 バッファサイズが確定しなかった.対応していない動画形式である可能性が高いです.
備考:EVFLIB内部では最初のサンプルが得られてバッファサイズが確定するまで,
最大EVF_TIMEOUT_BUFSIZE(5秒)待機します.
使用例
EVF_Open(0, "c:\\video\\movie1.avi");
EVF_Open(5, "video.mpg", MEDIASUBTYPE_RGB24);
int EVF_Close(int i);
説明
終了処理を行います.ファイルを閉じるため最後に1回呼びます.
引数
i:識別番号(0〜9)
戻り値
0:正常終了
1:エラー(ファイルが開かれていない,i値が正しくないなど)
使用例
EVF_Close(0);
int EVF_BufferSize(int i);
説明
EVF_GetFrame()によって画像データを取得するときに必要なメモリ領域の大きさを返します.
必要なメモリ領域の大きさは画像の画素数(幅,高さ)やフォーマット(32bit or 24bit)によって変わります.
備考:
ほとんどの場合,32ビット画像では(幅*高さ*4)バイト,24ビット画像では(幅*高さ*3)バイトです.
しかし,24ビットでは,(幅*3)が4の倍数ではない場合,調整用のバイトがライン毎に付加されますので,
常に(幅*高さ*3)バイトであるとは限りません.
引数
i:識別番号(0〜9)
戻り値
画像を格納するために必要なメモリ領域の大きさ(単位:バイト)
使用例
int size;
size=EVF_BufferSize(0);
int EVF_GetFrame(int i, void *dst);
説明
現在のフレーム番号の画像データを取得します.
EVFLIBの内部バッファから転送先dstへ画像データをコピーします.
EVF_SetBuffer()によって画像データの転送先が変更されている場合,この関数を使用する必要はなくなります.
EVF_SetBuffer()により転送先が変更されている場合にこの関数を使うと,無意味なデータがdstへコピーされます.
引数
i:識別番号(0〜9)
dst:画像データを格納する領域の先頭アドレス(ポインタ)
格納されたデータの構造はフォーマットによって異なります.
MEDIASUBTYPE_RGB32の場合,1ピクセル=int型(4バイト,0xrrggbb)です.
MEDIASUBTYPE_RGB24の場合,1ピクセル=3バイト,[B][G][R]…です.
戻り値
0:正常終了
1:エラー(ファイルが開かれていない,i値が正しくないなど)
使用例
int buffer[320*240];
EVF_GetFrame(0,buffer);
int EVF_GetFrame24to32(int i, int *dst);
説明
現在のフレーム番号の画像データを取得します.
ただし,24ビットから32ビットへ画像フォーマットを変換しながらコピーします.
EVFLIBの内部バッファにある元データは24ビットであり,また,格納先dstは32ビットであることを前提とした処理をします.
引数
i:識別番号(0〜9)
dst:画像データを格納する領域の先頭アドレス(ポインタ)
戻り値
0:正常終了
1:エラー(ファイルが開かれていない,i値が正しくないなど)
使用例
EVF_Open(0, "video.mpg", MEDIASUBTYPE_RGB24);
int buffer[320*240];
EVF_GetFrame24to32(0,buffer);
int EVF_Next(int i);
int EVF_Next(int i, int step);
説明
取得位置(フレーム番号)を1フレーム進めます.
この関数の実行後は,新しい画像データが内部バッファに格納された状態になります.
ただし,
EVF_SetBuffer()により転送先が変更されている場合は,画像データは内部バッファではなく,
変更後のフレームバッファに格納された状態になります.
2番目の引数を使うと,step数だけ進めることができます.大きなstep値を指定すると,処理時間がかかる場合があります.
一度にたくさんスキップさせる場合は,
EVF_Seek()を使います.
引数
i:識別番号(0〜9)
step:進めるフレーム数(この引数はオプション.省略すると1)
戻り値
0:正常終了
0以外:エラー
代表的な値と理由:
1 ファイルが開かれていない,i値が正しくないなど
5 動画の最後に達した等の理由で画像が取得できなかった
この場合,EVF_TIMEOUT_PAUSE(1秒)やEVF_TIMEOUT_WAIT(1秒)の
タイムアウト時間が経過した後に制御が戻ってきます.
使用例
EVF_Next(0);
EVF_Next(0,100);
int EVF_Seek(int i, int frame);
説明
取得位置(フレーム番号)を任意のフレームまで飛ばします.動画の頭出し用です.
ただし,平均フレーム時間*フレーム数でジャンプさせるだけなので,正確なフレーム位置ではない場合もあります.
この関数の実行後は,指定されたフレーム番号の画像データが内部バッファに格納された状態になっています.
ただし,
EVF_SetBuffer()により転送先が変更されている場合は,画像データはそちらのフレームバッファに格納されます.
処理時間がかかる場合もあるため,1フレームずつ進めるような使い方には適していません.
1フレームずつ進める場合は,
EVF_Next()を使います.
引数
i:識別番号(0〜9)
frame:フレーム番号(動画の先頭を0とする絶対値)
戻り値
0:正常終了
0以外:エラー
代表的な値と理由:
1 ファイルが開かれていない,i値が正しくないなど
2 シークに失敗
5 動画の最後に達した等の理由で画像が取得できなかった
現在位置(時刻)が合計時間に達すると最後と判定します.
あるいは,現在位置(フレーム)が総フレーム数に達すると最後と判定します.
それ以外の理由で,画像データが来ない場合,EVF_TIMEOUT_WAIT(1秒)の
タイムアウト時間が経過した後に制御が戻ってきます.
使用例
EVF_Seek(0, 100);
EVF_Seek(0, EVF_Frame(0)+1);
int EVF_SetBuffer(int i, void *buffer);
説明
フレームバッファを内部バッファから指定のアドレスへ変更します.
EVF_Open()を実行後は,内部で自動的に確保したフレームバッファが使用されますが,
それ以外のフレームバッファを使用する場合に,この関数を使用します.
ここで指定されたフレームバッファには
EVF_Next()あるいは
EVF_Seek()毎に画像データが格納(上書き)されます.
buffer には画像データが格納されるため,あらかじめユーザ側で必要なメモリ領域を確保しておいてください.
必要なメモリ領域のサイズは,
EVF_BufferSize()で知ることができます.
引数
i:識別番号(0〜9)
buffer:フレームバッファの先頭アドレス
戻り値
0:正常終了
1:エラー(ファイルが開かれていない,i値が正しくないなど)
使用例
int buf[640*480];
EVF_SetBuffer(0, buf);
int EVF_Frames(int i);
説明
動画の総フレーム数を返します.
ただし,合計時間/平均フレーム時間から推定した値のため,実際にフレーム数とは異なる場合もあります.
動画の終わりは
EVF_Next()や
EVF_Seek()の戻り値で判定するのが確実です.
引数
i:識別番号(0〜9)
戻り値
総フレーム数
0:エラー(ファイルが開かれていない,i値が正しくないなど)
int EVF_Frame(int i);
説明
現在位置(フレーム番号)を返します.
EVF_GetFrame()で取得される画像はこの位置の画像です.
現在位置は,
EVF_Next()や
EVF_Seek()の実行により更新されます.
引数
i:識別番号(0〜9)
戻り値
現在位置(フレーム番号)(動画の先頭を0とする絶対値)
0:エラー(ファイルが開かれていない,i値が正しくないなど)
LONGLONG EVF_AvgTime(int i);
説明
動画の平均フレーム時間を返します.
引数
i:識別番号(0〜9)
戻り値
平均フレーム時間(単位:100ns)
0:エラー(ファイルが開かれていない,i値が正しくないなど)
LONGLONG EVF_MaxTime(int i);
説明
動画の合計時間を返します.
引数
i:識別番号(0〜9)
戻り値
合計時間(単位:100ns)
0:エラー(ファイルが開かれていない,i値が正しくないなど)
LONGLONG EVF_CurTime(int i);
説明
現在位置(時刻)を返します.
現在位置(時刻)は,
EVF_Seek()の実行により更新されます.
EVF_Next()の実行では更新されません.
引数
i:識別番号(0〜9)
戻り値
現在位置(時刻)(100ns単位)
0:エラー(ファイルが開かれていない,i値が正しくないなど)
double EVF_FrameRate(int i);
説明
動画ファイルのフレームレートを返します.ただし,平均フレーム時間から推定(逆数)した値です.
引数
i:識別番号(0〜9)
戻り値
フレームレート(単位:fps)
0:エラー(ファイルが開かれていない,i値が正しくないなど)
int EVF_WX(int i);
int EVF_WY(int i);
説明
画像のサイズ(幅または高さ)を返します.
引数
i:識別番号(0〜9)
戻り値
幅(単位:ピクセル) EVF_WX()の場合
高さ(単位:ピクセル) EVF_WY()の場合
0:エラー(ファイルが開かれていない,i値が正しくないなど)
int EVF_Bit(int i);
説明
画像フォーマットのビット数を返します.
引数
i:識別番号(0〜9)
戻り値
ビット数(32 or 24)
0:エラー(ファイルが開かれていない,i値が正しくないなど)
著作権・使用許諾
EVFLIB のすべての著作権はI.N.にあります.
EVFLIB はフリーソフトウェアであり配布・転載は自由です.
EVFLIB の改造・変更は自由に行っても構いません.
EVFLIB を使用した際の著作権表示は特に必要ありません.
EVFLIB の使用目的・用途は限定しません.
EVFLIB を使用したことによって生じたいかなる損害等も,作者は一切その責任を負わないこととします.
バージョンアップ履歴
ver.1.2 2017/5/30
Visual C++ 2017対応
ver.1.1 2016/5/23
Windows 10, K-Lite Codec Packの環境でEVF_Close()時に強制終了する問題を修正.
ver.1.0 2013/9/2
"evflib.h"の誕生.
作者のウェブサイト
EVFLIBの最新情報や作者の他のソフト,ライブラリがあります.
http://www.geocities.jp/in_subaru/
作者への連絡先
EVFLIBに関する質問やバグ情報などは下記URL(ブログ&ゲストブック)にて対応いたします.
http://blogs.yahoo.co.jp/in_subaru
開発環境
OS:Windows 10 Pro (x64) version 1803
言語:Visual Studio Professional 2015/2017
End of help.