三次元日誌 RSSフィード

2012-10-26

[]リンクエラー

1>LINK : fatal error LNK1123: COFF への変換中に障害が発生しました: ファイルが無効であるか、または壊れています。

のメモ。

VC2012をインストールすると、VC2010で出るようになるっぽい。

リンクオプションでインクリメンタルリンクをNOにする。

premake4.lua的には

flags {
  "NoIncrementalLink"
}

premake4.4新機能

2012-07-19

[]macbook airgentoo linuxインストールする

gentoo-3.3.8

その1

その2

gentooのinstall環境としてubuntuのbootable usbメモリを作る。

その3

ubuntuusbメモリから起動して、

handbookを見てインストールを進める

fdisk
1 /dev/sda1 boot EFI領域 # 温存
2 /dev/sda2 HFS+ OSX # 温存
3 /dev/sda3 swap 1G
4 /dev/sda4 ext4 残り全部 
必要なカーネルオプション

素の状態からmake menuconfigしたものから変更した部分のメモ

General
  .config

Processor
  core2

FileSystem
  ext4
  fuse
  dos
    codepage 932
    charset utf8
    NTFS
  Network
    CIFS # samba
  Miscellaneous
    HFS+

Device
  NetWork
    Wireless
      80211 # 後でブロードコムの内臓無線ドライバをビルドするのに必要
    USB
      asix # 外付けのUSB-ether

  USB
    roothub transaction # タッチパッドの認識に必要 http://forums.gentoo.org/viewtopic-t-878287-start-0.html

  InputDevice
    Mice
      BCM5974 # タッチパッド

  Graphics
    agp
      Intel440
    DRM

  Sound
    alsa
      pci
        Intel HD # カーネル組み込みからモジュールに変更した
broadcomのドライバをビルドしてインストールする

その4

grub2をefiサポートでビルドする

--disable-werror
--disable-nls

起動成功

その5 ネットワーク設定

wpa_supplicant

2012-06-02

[]USBカメラを静止画で取得する(サンプルグラバ)

DirectXのテクスチャにDirectShowを出力する方法を試してみた。

最初に、

を参考にしたのだが、

strmbase.lib(strmbasd.lib)をVC2010でビルドするのに失敗して

コンパイルを通すことがそもそもできなかったorz

仕方ないのでDirectShow基本ライブラリに含まれるCBaseVideoRendererを使うのはおいておいて、SampleGrabberを使う手法をやってみた。

SampleGrabberを使う

こちらを参考にした。

qedit.hが無い

VC2010とは別にインストールした古いWindowsSDKに含まれていた

C:\Program Files\Microsoft SDKs\Windows\v6.1\Include\qedit.h

昔のDirectX(DirectShowが含まれているやつ)でもいいらしい

dxtrans.hが無い

C:\Program Files\Microsoft SDKs\Windows\v6.1\Include\qedit.h

を直接修正するらしい

ようやく実装開始

DirectShowは含まれるライブラリが転々としているせいで、どこにインクルードやリンクがあるのか探すので苦労する・・・

入力と出力を持つフィルタを作って、これらをグラフに追加して連結する仕組みだとわかった。

ということで、出力を持つUSBカメラフィルタと入力をもつサンプルグラバを連結した。

ComMovie.h

#pragma once
#include <atlbase.h>
#include <dshow.h>
#include <qedit.h>
#pragma comment(lib, "strmiids")
#include <vector>


class Com
{
public:
    Com()
    {
        CoInitialize(NULL);
    }

    ~Com()
    {
        CoUninitialize();
    }
};


class ComMovieSource
{
    Com m_com;

    CComPtr<IGraphBuilder> m_graphBuilder;
    CComQIPtr<IMediaControl> m_mediaControl;

    CComPtr<ICaptureGraphBuilder2> m_captureGraphBulider;

    // 出力
    CComPtr<IBaseFilter> m_sampleGrabberFilter;
    CComQIPtr<ISampleGrabber> m_sampleGrabber;

    // 入力
    CComPtr<IBaseFilter> m_deviceFilter;

    int m_w;
    int m_h;

    std::vector<BYTE> m_buffer;

public:
    ComMovieSource();
    ~ComMovieSource();
    HRESULT Initialize();
    int GetWidth(){ return m_w; }
    int GetHeight(){ return m_h; }
    HRESULT Update();
    void *GetSample(){ return m_buffer.empty() ? 0 : &m_buffer[0]; }
    size_t GetSampleSize(){ return m_buffer.size(); }
};

ComMovie.cpp

#include "ComMovie.h"


ComMovieSource::ComMovieSource()
    : m_w(0), m_h(0)
{
}

ComMovieSource::~ComMovieSource()
{
}

HRESULT ComMovieSource::Initialize()
{
    if(m_graphBuilder){
        return S_OK;
    }

    // filter graph
    if (FAILED(m_graphBuilder.CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC))){
        return E_FAIL;
    }

    // add sample grabber
    if(FAILED(m_sampleGrabberFilter.CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC))){
        return E_FAIL;
    }

    m_sampleGrabberFilter.QueryInterface(&m_sampleGrabber);
    if(!m_sampleGrabber){
        return E_FAIL;
    }

    AM_MEDIA_TYPE amt;
    ZeroMemory(&amt, sizeof(amt));
    amt.majortype  = MEDIATYPE_Video;
    amt.subtype	   = MEDIASUBTYPE_RGB32;
    amt.formattype = FORMAT_VideoInfo; 
    m_sampleGrabber->SetMediaType(&amt);
    if(FAILED(m_graphBuilder->AddFilter(m_sampleGrabberFilter, L"Sample Grabber"))){
        return E_FAIL;
    }

    // add capture filter
    if(FAILED(m_captureGraphBulider.CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC))){
        return E_FAIL;
    }
    if(FAILED(m_captureGraphBulider->SetFiltergraph(m_graphBuilder))){
        return E_FAIL;
    }

    // デバイスを列挙するためのCreateDevEnumを生成
    CComPtr<ICreateDevEnum> createDevEnum;
    if(FAILED(createDevEnum.CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER))){
        return E_FAIL;
    }
    CComPtr<IEnumMoniker> enumMoniker;
    createDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &enumMoniker, 0);
    if(!enumMoniker){
        // no device
        return E_FAIL;
    }
    enumMoniker->Reset();
    while(true){
        CComPtr<IMoniker> moniker ;
        DWORD nFetched;
        if(FAILED(enumMoniker->Next(1, &moniker, &nFetched))){
            return E_FAIL;
        }
        if(nFetched<1){
            break;
        }

        // ToDo: 条件に合うデバイスをバインドする
        {
            // 一個目のUSBカメラ
            moniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&m_deviceFilter);
            break;
        }
    }

    if(FAILED(m_graphBuilder->AddFilter(m_deviceFilter, L"Video Input Device"))){
        return E_FAIL;
    }

    // デバイスとグラバフィルタを連結する
    if(FAILED(m_captureGraphBulider->RenderStream(&PIN_CATEGORY_PREVIEW,
                    NULL, m_deviceFilter, NULL, m_sampleGrabberFilter))){
        return E_FAIL;
    }

    // 画像サイズ
    if(FAILED(m_sampleGrabber->GetConnectedMediaType(&amt))){
        return E_FAIL;
    }
    VIDEOINFOHEADER *pVideoInfoHeader =
        (VIDEOINFOHEADER *)amt.pbFormat;

    m_w=pVideoInfoHeader->bmiHeader.biWidth;
    m_h=pVideoInfoHeader->bmiHeader.biHeight;
    m_buffer.resize(amt.lSampleSize);

    // 開始
    m_sampleGrabber->SetBufferSamples(TRUE);
    m_graphBuilder.QueryInterface(&m_mediaControl);
    if(!m_mediaControl){
        return E_FAIL;
    }
    if(FAILED(m_mediaControl->Run())){
        return E_FAIL;
    }

    return S_OK;
}

HRESULT ComMovieSource::Update()
{
    if(m_buffer.empty()){
        return E_FAIL;
    }
    // 現在表示されている映像を静止画として取得
    long nBufferSize=m_buffer.size();
    HRESULT hr=m_sampleGrabber->GetCurrentBuffer(&nBufferSize, (long*)&m_buffer[0]);
    if(SUCCEEDED(hr) && nBufferSize==m_buffer.size()){
        return S_OK;
    }
    return E_FAIL;
}

2012-05-27

[]DirectShowプログラミング開始

OpenCVとかKinectに行く前の下準備で、DirectShowをマスターすることにした。

この本を読みながら進めている。

VC2010 expressedition

を使う。

DirectShowのインストール

VCとDirectXのバージョンによって情報が錯綜しているのだけど、

VC2010 expresseditionに関しては下記にdshow.hが存在した。

最初から入っているということでよさげ。

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include

動作確認

本の最初のDirectShowサンプルをC++風?に書いてみた。

#include <iostream>
#include <string>
#include <dshow.h>
#include <vector>
#pragma comment(lib, "strmiids")


class Com
{
public:
    Com()
    {
        CoInitialize(NULL);
    }

    ~Com()
    {
        CoUninitialize();
    }
};


class ComGraphBuilder
{
    IGraphBuilder *pigb;
public:
    ComGraphBuilder()
        : pigb(0)
    {
        HRESULT hr=CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
                IID_IGraphBuilder, (void**) &pigb);
    }

    ~ComGraphBuilder()
    {
        if(pigb){
            pigb->Release();
        }
    }

    bool RenderFile(const std::wstring &file)
    {
        return pigb->RenderFile(file.c_str(), NULL)==S_OK;
    }

    IGraphBuilder* Get(){ return pigb; }
};


class ComMediaControl
{
    IMediaControl *pimc;
public:
    ComMediaControl(IGraphBuilder *pigb)
        : pimc(0)
    {
        HRESULT hr=pigb->QueryInterface(IID_IMediaControl, (void**)&pimc);
    }

    ~ComMediaControl()
    {
        if(pimc){
            pimc->Release();
        }
    }

    void Run()
    {
        pimc->Run();
    }

    IMediaControl *Get(){ return pimc; }
};


static std::wstring to_WideChar(UINT uCodePage, const std::string &text)
{
    int size=MultiByteToWideChar(uCodePage, 0, text.c_str(), -1, NULL, 0);
    std::vector<wchar_t> buf(size);
    size=MultiByteToWideChar(uCodePage, 0, text.c_str(), -1, &buf[0], buf.size());
    return std::wstring(buf.begin(), buf.begin()+size);
}


int main(int argc, char **argv)
{
    if(argc<2){
        std::cout << "usage: " << argv[0] << "  {file}" << std::endl;
        return 0;
    }

    Com com;

    ComGraphBuilder gb;
    if(!gb.Get()){
        return 1;
    }

    ComMediaControl mc(gb.Get());
    if(!mc.Get()){
        return 2;
    }

    if(!gb.RenderFile(to_WideChar(CP_OEMCP, argv[1]))){
        return 3;
    }

    mc.Run();

    std::cout << "hit any key" << std::endl;
    std::string line;
    std::getline(std::cin, line);

    return 0;
}

2012-04-30

[][]その3。サンプルのビルド

samples/Samples_Express.sln

をVC#2010 ExpressEditionで開く(ダブルクリックだと何故か開かないので、vc#のファイルを開くを使う)。

ソリューションに含まれる各プロジェクトで

参照コンポーネント'SlimDX'が見つかりませんと出る。

インストールしてあるSlimDXとバージョンがあっていないようだ。

参照で!マークのついているSlimDXを削除して、インストールしてあるSlimDXを追加しなおす。

"*.csproj"の内容を直接置換しても直せた。

SlimDX, Version=2.0.12.43

SlimDX, Version=2.0.13.43