お世話になります。

現在x64版のDirect Showを利用して、aviファイルから任意のフレーム画像を取得する
プログラムを作成しております。

Direct Showは今まで使ったことが無かったのですが、ネットにあるサンプルなどを
参考に手探りで作業を進めております。最終的にはx64版を作る必要があるのですが、
メインで作業しているPCが32bit環境であるため、とりあえずx86版で作業を進め、
なんとか期待する動作をするものが出来ました。

最終的に処理する動画ファイルは1440x810のものと、3840x2160の2つがあり、
x86版ではどちらも期待する動作をしてくれるのですが、x64にてコンパイルし64bit環境で
動作させると1440x810の方は問題ないのですが、3840x2160の方はうまく動作しません。

なお、プログラムは以下のような流れでDirectShowを利用しております。

CoInitialize
CoCreateInstance( CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, &pIGB);
pIGB->QueryInterface( IID_IMediaControl, &pIMC );
pIGB->QueryInterface( IID_IID_IMediaSeeking, &pIMS );
CoCreateInstance( CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, &pIBF );
pIBF->QueryInterface( IID_ISampleGrabber, &pISG );
pIGB->AddFilter( pIBF, NULL );
pISG->SetMediaType(&stMT); // stMTはMEDIATYPE_Video,MEDIASUBTYPE_RGB24,FORMAT_VideoInfoを設定
pIGB->RenderFile( ファイル名, NULL );
:

調べてみると、RenderFileのところでx64の場合はVFW_E_NO_TRANSPORTが帰ってきているようです。なお、その64bit環境でx86コンパイルしたものを動かすと問題なく動作します。

なお、もともとDirect X SDK 9.0を使っていましたが、念のため最新版のものをダウンロードして
試してみましたが、症状は変わりませんでした。また、Videoドライバも変えてみましたが、同様に
変化なしです。

どんな原因が考えられるか、どなたかご助言頂ければ助かります。

なお、開発環境・動作環境は以下の通りです。

Windows 7 Pro 64bit版
VisualStudio 2010 Pro
Direct X SDK 9.0 or Direct X Jun_2010
C++ (純粋なネィティブプログラム)

このQ&Aに関連する最新のQ&A

A 回答 (1件)

↓あたりを参考に調べてみてはいかがでしょうか。



VFW_E_NO_TRANSPORTについてのQ&A
http://social.msdn.microsoft.com/Forums/en-US/wi …

DirectShowのフィルタについて(ちょっと古い情報みたいです。)
http://www.geocities.co.jp/SiliconValley/7406/ti …

grapheditについて
http://blogs.msdn.com/b/windows_multimedia_jp/ar …

この回答への補足

grapheditを使ってフィルタを自動生成してみたところ、
x64版では同じ様にピン関係のエラーが表示され、うまくいきませんでした。
ただしx86版では問題なく自動生成されたので、x86版の結果を頼りに
x64版で手動でフィルタを追加していったところ、AVI SplitterからAVI Decompressorへの
入力で失敗していることがわかりました。

結局のところ64bit版のコーデックが無いために、このようなエラーになっていたようです。
(考えてみれば当然な気がしますが、全然気づきませんでした^^;)

なにぶん動画関係とか疎かったので、頂いた情報は大変参考になりました。
ありがとうございました!!

補足日時:2011/04/14 11:40
    • good
    • 0
この回答へのお礼

情報ありがとうございます!
さっそく確認してみます^^

お礼日時:2011/04/14 09:29

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

QVC++ DirectShow グラフにフィルターを追加する方法

DirectShowにてビデオキャプチャデバイスから
ファイルに保存する(プレビューウィンドウ付き)で
普通にAVIファイルには保存できますがフィルターのMicrosoft Video 1を追加して圧縮をして保存するようにしたいと思います。
(上記フィルタは本当に圧縮かどうかはわかりませんが。。。
GraphEditで確認したところ圧縮(保存ファイルサイズが激減)したようでしたので。。)
現在のフィルターグラフにMicrosoft Video 1を追加する方法をご教示願えればと思います。
初心者なのでMSDNなど見てもいまいち理解できません。
簡単なサンプルなどあれば助かります。
よろしくお願い致します。

Aベストアンサー

 こんばんは。以下のURLが参考になります。

 http://msdn.microsoft.com/ja-jp/library/cc973418.aspx
 http://msdn.microsoft.com/ja-jp/library/cc353106.aspx
 http://www.codeguru.com/forum/showthread.php?t=392724

 圧縮コーデックの一覧から、Microsoft Video 1を探し出して見つかればフィルタを作成して、SplitterとMuxの間に挟み込めばOK見たいです。
 大分乱暴なコードですが、以下で圧縮が出来ました。参考程度に。

#include <stdio.h>
#include <dshow.h>
#include <qedit.h>

#pragma comment(lib, "strmiids.lib")

//コーデックを探す
static IBaseFilter* FindCodec(BSTR bstrDesire)
{
ICreateDevEnum *pSysDevEnum = NULL;
IEnumMoniker *pEnum = NULL;
IMoniker *pMoniker = NULL;
IBaseFilter *pFilter = NULL;

HRESULT hr = ::CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pSysDevEnum);
if(FAILED(hr))
return pFilter;

hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory, &pEnum, 0);
if(hr != S_OK)
return pFilter;

while (S_OK == pEnum->Next(1, &pMoniker, NULL))
{
IPropertyBag *pPropBag = NULL;
pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPropBag);
VARIANT var;
::VariantInit(&var);
hr = pPropBag->Read(L"FriendlyName", &var, 0);
if(SUCCEEDED(hr))
{
::wprintf(L"[codec %s]\n", var.bstrVal);

//見つかったのでフィルタを作成する
if(::lstrcmp(var.bstrVal, bstrDesire) == 0)
{
pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)&pFilter);
}
}
::VariantClear(&var);
pPropBag->Release();
pMoniker->Release();

//見つかっているのでループから抜ける
if(pFilter)break;
}

//最後の後始末
pSysDevEnum->Release();
pEnum->Release();
return pFilter;
}

int main()
{
IGraphBuilder *pGraph = NULL;
IMediaControl *pControl = NULL;
IMediaEvent *pEvent = NULL;

::CoInitialize(NULL);

//グラフの作成
::CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&pGraph);

//コントロールとイベントの作成
pGraph->QueryInterface(IID_IMediaControl, (void **)&pControl);
pGraph->QueryInterface(IID_IMediaEvent, (void **)&pEvent);

//グラフビルダーの作成
ICaptureGraphBuilder2* pBuilder = NULL;
::CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void **)&pBuilder);

//フィルタの作成
IBaseFilter *pFileSource;
pGraph->AddSourceFilter( L"test.avi", L"Source", &pFileSource);

IBaseFilter *pAviSplit;
::CoCreateInstance(CLSID_AviSplitter, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pAviSplit);

IBaseFilter *pAviMux;
::CoCreateInstance(CLSID_AviDest, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pAviMux);

IBaseFilter *pWriter;
::CoCreateInstance(CLSID_FileWriter, 0, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void **)&pWriter);

IBaseFilter *pMSVideo1 = ::FindCodec(L"Microsoft Video 1");

//出力先の設定
IFileSinkFilter *pSink= NULL;
pWriter->QueryInterface(IID_IFileSinkFilter, (void**)&pSink);
pSink->SetFileName(L"testresult.avi", NULL);
pSink->Release();

//フィルタを追加
pGraph->AddFilter(pFileSource, L"AVI Source");
pGraph->AddFilter(pAviSplit, L"AVI Splitter");
pGraph->AddFilter(pAviMux, L"AVI MUX");
pGraph->AddFilter(pWriter, L"AVI Writer");
pGraph->AddFilter(pMSVideo1, L"Microsoft Video 1");

//フィルタ同士の接続
pBuilder->SetFiltergraph(pGraph);
pBuilder->RenderStream(0, 0, pFileSource, 0, pAviSplit);
pBuilder->RenderStream(0, &MEDIATYPE_Video, pAviSplit, pMSVideo1, pAviMux);//split⇔mux間にMS Video1を挟み込む
pBuilder->RenderStream(0, &MEDIATYPE_Audio, pAviSplit, 0, pAviMux);
pBuilder->RenderStream(0, 0, pAviMux, 0, pWriter);

//書き込みスタート
pControl->Run();

//達成まで待つ
long evCode;
pEvent->WaitForCompletion(INFINITE, &evCode);

//停止 此れがないと駄目
pControl->Stop();

//始末
pControl->Release();
pEvent->Release();
pGraph->Release();
pFileSource->Release();
pAviSplit->Release();
pAviMux->Release();
pWriter->Release();
pMSVideo1->Release();
pBuilder->Release();
return 0;
}

 こんばんは。以下のURLが参考になります。

 http://msdn.microsoft.com/ja-jp/library/cc973418.aspx
 http://msdn.microsoft.com/ja-jp/library/cc353106.aspx
 http://www.codeguru.com/forum/showthread.php?t=392724

 圧縮コーデックの一覧から、Microsoft Video 1を探し出して見つかればフィルタを作成して、SplitterとMuxの間に挟み込めばOK見たいです。
 大分乱暴なコードですが、以下で圧縮が出来ました。参考程度に。

#include <stdio.h>
#include <dshow.h>
#include <qedit.h>

...続きを読む

Qfatal error LNK1120: 外部参照 1 が未解決です

またわからないことが・・・
教えて下さい。
以下をVC++2005でコンパイルすると、

MSVCRTD.lib(crtexew.obj) : error LNK2019: 未解決の外部シンボル _WinMain@16 が関数 ___tmainCRTStartup で参照されました。
C:\Documents and Settings\tomato\My Documents\Visual Studio 2005\Projects\a\Debug\a.exe : fatal error LNK1120: 外部参照 1 が未解決です。

と警告がでて通りません。
何のことでしょうか。

#include<stdio.h>
#include<process.h>

struct meibo{
  char name[20];
  char tel[20];
  char address[20];
};

void message( void );
void input( FILE *fp, int cnt , struct meibo *a, int *end );

void main( void )
{
  struct meibo a[20];
  FILE *fp;
  int cnt, end;

  if( (fp=fopen( "meibo.dat", "w" ) ) == NULL ){
    printf( "Can not open the meibo.dat.\n" );
    exit( 1 );
  }

  message();

  fprintf( fp, "番号, 名前, TEL, 住所\n" );
  fflush( fp );

  cnt = 0;
  end = 0;
  while( end == 0 ){
    input( fp, cnt, &a[cnt], &end );
    cnt++;
    fflush( fp );
    if( cnt == 20 ){
      printf( "人数が一杯です.終了します.\n" );
      end = 1;
    }
  }
  fclose( fp );
}

void message( void )
{
  printf( "名前, TEL, 住所, endを入力してください.\n" );
  printf( "継続の時はend=0," );
  printf( "中止の時は,end=1と入力してください.\n" );
}

void input( FILE *fp, int cnt, struct meibo *a, int *end )
{
  printf( "名前-->" );
  scanf( "%s", a->name );
  printf( "TEL -->" );
  scanf( "%s", a->tel );
  printf( "住所-->" );
  scanf( "%s", a->address );
  printf( "Exit? Continue:0 Exit:1 -->" );
  scanf( "%d", end );
  printf( "\n" );
  fprintf( fp, "%2d, %s, %s, %s\n",
    cnt+1, a->name, a->tel, a->address );
}

またわからないことが・・・
教えて下さい。
以下をVC++2005でコンパイルすると、

MSVCRTD.lib(crtexew.obj) : error LNK2019: 未解決の外部シンボル _WinMain@16 が関数 ___tmainCRTStartup で参照されました。
C:\Documents and Settings\tomato\My Documents\Visual Studio 2005\Projects\a\Debug\a.exe : fatal error LNK1120: 外部参照 1 が未解決です。

と警告がでて通りません。
何のことでしょうか。

#include<stdio.h>
#include<process.h>

struct meibo{
  char name[20];
...続きを読む

Aベストアンサー

http://www.a.math.ryukoku.ac.jp/~hig/course/compsci2_2005/man/faq.html
にある現象と同じではないでしょうか、一度お試しください。

QDLL参照時に指定されたモジュールが見つかりません。(HRESULT からの例外 0x8007007E) が発生してしまう。

C++プロジェクト(Windowsフォームアプリ)を作成し、あるサイトで公開されているDLLを実装し→コンパイル→デバッグ実行させた所、問題なく動作が確認できたのですが、
クラスライブラリで作成したC++新規プロジェクトに同じくDLLを実装し、同一ソリューション内にC#又はC++でWindowsフォームアプリを作成し、先に作成したクラスライブラリプロジェクトを参照させる形態で作成した際に、コンパイル→デバッグ実行させた所、コンパイルは通ったのですがデバッグ実行時に、DLLを参照しようとしたタイミングで
「DLL参照時に指定されたモジュールが見つかりません。(HRESULT からの例外 0x8007007E) が発生してしまう。」
というエラーが発生してしまいました。

何故Windowsフォームアプリ単体時にはDLLが参照できたのに、クラスライブラリにし複数プロジェクトにして実行するとエラーが発生してしまうのか、どなたか原因、解法等 心得ておられましたら御指南のほど宜しくお願いします。

以下 事象詳細です。
開発環境:Microsoft Visual Studio 2008
公開DLL:USB-IOを制御する目的のUSBIODLLDemo.dllというDLLです。

<成功時>
1.C++プロジェクト(Windowsフォームアプリ)新規作成
2.DLLがインストールされているフォルダから.dllファイル, .hファイル、.libファイルをコピーしプロジェクト新規作成したフォルダにコピーする
3.プロジェクトのプロパティ→構成プロパティ→リンカ→入力→追加の依存ファイル に.libファイル名を記入
4.ダウンロードの.hファイルから
__declspec(dllimport) BYTE __stdcall GetNo(void);
__declspec(dllimport) void __stdcall P1Write(BYTE newVal);
__declspec(dllimport) BYTE __stdcall P1WriteBit(BYTE Bit, BOOL Tf01);
__declspec(dllimport) BYTE __stdcall P1Read(void);
 をコピーしstdafx.h へ貼付け。
5.stdafx.hへ貼り付けた宣言がこのままではコンパイルが通らなかったため
#define BYTE unsigned char
#define BOOL bool
 を追記。
6.ダウンロードしたDLLの関数を使用した一文を実装
7.コンパイル→デバッグ実行→ 無事実行完了!

<エラー発生時> *下記事象ではC#Winフォームアプリを挙げていますがC++Winフォームアプリで試しても同じ結果になりました。
1.C++プロジェクト(クラスライブラリ)新規作成
2.DLLがインストールされているフォルダから.dllファイル, .hファイル、.libファイルをコピーしプロジェクト新規作成したフォルダにコピーする
3.プロジェクトのプロパティ→構成プロパティ→リンカ→入力→追加の依存ファイル に.libファイル名を記入
4.ダウンロードの.hファイルから
__declspec(dllimport) BYTE __stdcall GetNo(void);
__declspec(dllimport) void __stdcall P1Write(BYTE newVal);
__declspec(dllimport) BYTE __stdcall P1WriteBit(BYTE Bit, BOOL Tf01);
__declspec(dllimport) BYTE __stdcall P1Read(void);
 をコピーしStdafx.h へ貼付け。
5.Stdafx.hへ貼り付けた宣言がこのままではコンパイルが通らなかったため
#define BYTE unsigned char
#define BOOL bool
 を追記。
6.ダウンロードしたDLLの関数を使用した一文を実装(公開関数として)

7.C#プロジェクト(Windowsフォームアプリ)新規追加 *C++(Windowsフォームアプリ)でやっても同じ結果になりました。
8.新しい参照の追加で上のクラスライブラリプロジェクトを追加
9.フォームアプリ側でクラスライブラリプロジェクトの関数を実行する処理を実装
clsTest ctst;
ctst.Exec();

10.コンパイル→デバッグ実行→DLLを参照しようとしたタイミングでエラー発生!
「DLL参照時に指定されたモジュールが見つかりません。(HRESULT からの例外 0x8007007E) が発生してしまう。」
*クラスライブラリ側の、DLLの関数を呼んでいる部分をコメントアウトするとエラー無く実行できてしまいます。

C++プロジェクト(Windowsフォームアプリ)を作成し、あるサイトで公開されているDLLを実装し→コンパイル→デバッグ実行させた所、問題なく動作が確認できたのですが、
クラスライブラリで作成したC++新規プロジェクトに同じくDLLを実装し、同一ソリューション内にC#又はC++でWindowsフォームアプリを作成し、先に作成したクラスライブラリプロジェクトを参照させる形態で作成した際に、コンパイル→デバッグ実行させた所、コンパイルは通ったのですがデバッグ実行時に、DLLを参照しようとしたタイミングで
「DLL参...続きを読む

Aベストアンサー

やるならば ソリューション名をつけて複数のプロジェクトをまとめたほうがいいように思います

VC++/C#で新規にプロジェクト(ソリューション)を生成する際のダイアログの『ソリューションのディレクトリを作成』にチェックを入れて
『USBIODEMO』などといった具合にします
その中に.NET用のクラスライブラリのプロジェクトを作成します
こうすると
USBIODEMO\Debug(または Release)に出来上がったDLLが生成されます
同じように テスト用のFormアプリをVCのプロジェクトで作成します
コンパイル/リンクがうまくいけば 上記のフォルダに EXEが生成されます
この状態でFormEXEのデバッグを行ってやれば 質問のようなエラーは回避できると思います

C#の場合は 元の『USBIODLLDemo.dll』をC#のプロジェクトの『bin\debug(またはRelease)』にコピーしないといけないでしょう

つまりは クラスライブラリのDLLは見つかったが 元の『USBIODLLDemo.dll』が見つからなかった
という現象ではないかと思います

アプリの参照はクラスライブラリーまでなのでクラスライブのDLLまではコピーしたりする面倒を見てくれます
クラスライブラリが参照しているDLLまで面倒見てくれないためなのかもしれません

DLLの検索順についてWebなどで検索してみましょう

やるならば ソリューション名をつけて複数のプロジェクトをまとめたほうがいいように思います

VC++/C#で新規にプロジェクト(ソリューション)を生成する際のダイアログの『ソリューションのディレクトリを作成』にチェックを入れて
『USBIODEMO』などといった具合にします
その中に.NET用のクラスライブラリのプロジェクトを作成します
こうすると
USBIODEMO\Debug(または Release)に出来上がったDLLが生成されます
同じように テスト用のFormアプリをVCのプロジェクトで作成します
コンパイル/リンクがう...続きを読む


人気Q&Aランキング

おすすめ情報