画像を動画ファイルとして保存する

ここでは一連の画像を動画ファイルとして記録する方法について説明します。

このサンプルは IC Imaging Controlインストールディレクトリの %TOPLEVEL%\samples\VC\CreateVideoFileにあります。プログラムを実行するため、ディレクトリ内のソリューションファイルCreateVideoFile.slnを開きメニューからビルド -> ビルド CreateVideoFileと選択します。
そこからデバッグ -> スタートと選択することでプログラムを実行することができます。

このプログラムは利用可能なメディアストリームコンテナの一覧を作成し、ユーザーに対してそこから選択するよう求めるものです。次のステップでユーザーはファイルへの保存方法を下の3つから選択することができます。

  • Codec: これを選択した場合、利用可能なビデオコンプレッサの一覧が表示され、そこから一つ選択します。
  • Uncompressed: 非圧縮のフォーマットのリストから一つ選択します。
  • Unspecified:これを選択した場合、デバイス、デバイスパス上のフレームフィルタとオーバーレイ、シンクパスは非圧縮のフォーマットを指定します。

次のステップではファイル名を入力します。その入力後はプログラムは何かのキーが押されるまで待機状態となります。何かキーを押すとキャプ チャが開始され、エンターが押されるまでキャプチャしたデータをビデオファイルに書き込み続けます。

デバイスを開く

このサンプルでは%TOPLEVEL%\Samples\VC\Common\CmdHelper.hsetupDeviceFromFileを使用しています。この関数はデバイス選択ダイアログを表示し、その選択をコンフィギュレーションファイルに保存され、再度この関数が呼び出された際に読み込まれます。

Grabber grabber;
if( !setupDeviceFromFile( grabber ) )
{
  return 1;
}

ビデオデータ保存形式を選択する

ユーザーはビデオデータのファイルへの保存形式について、以下の3つから選択することができます。

  • Codec: 静的メソッドCodec::getAvailableCodecsクラスライブラリリファレンス>クラス>Codec>Codec::getAvailableCodecs Methodが利用可能なビデオコンプレッサの一覧を返します。
    そのリストはTOPLEVEL%\Samples\VC\Common\CmdHelper.h内のpresentUserChoicetoStringArrayPtrListPtrによってコンソールに表示されます。
  • Uncompressed: %TOPLEVEL%\Samples\VC\Common\CmdHelper.h内のpresentUserChoicetoStringArrayPtrListPtrによって非圧縮のフォーマットのリストs_UncompressedFormatListがコンソールに表示されます。
  • Unspecified:これを選択した場合、デバイス、デバイスパス上のフレームフィルタとオーバーレイ、シンクパスは非圧縮のフォーマットを指定します。

画像データをビデオファイルへ保存するためにMediaStreamSinkクラスライブラリリファレンス>クラス>MediaStreamSinkが作成、初期化されます。

// コンテナがコーデックをサポートしているかをチェック
if( pCont->isCustomCodecSupported() )
{
  static const char* pCodecOrCompressorChoice[] =
  {         
    "Codec",         
    "Uncompressed Video",         
    "Unspecified Type (デバイス、フレームフィルタ、あるいはオーバーレイによって指定される形式を使用)"     
  };       

  int idx = presentUserChoice( pCodecOrCompressorChoice, pCodecOrCompressorChoice + 3 );
  if( idx == -1 )     
  {         
    std::cerr << "圧縮、非圧縮どちらも選択されていません。" << std::endl;         
    return 1;     
  }

  if( idx == 0 )
  {         
    // ビデオコンプレッサ(コーデック)の一覧を取得         
    tCodecListPtr pCodecList =  Codec::getAvailableCodecs();         
    if( pCodecList == 0 )         
    {         
      std::cerr << "コーデッ クが見つかりません。" << std::endl;         
      return 1;         
    }
        
    int Compressor_idx = presentUserChoice( toStringArrayPtrListPtr( pCodecList ) );         
    if( Compressor_idx == -1 )         
    {         
      std::cerr << "コンプレッサが選択されていません。" << std::endl;             
      return 1;         
    }         
    tCodecPtr pCodec = pCodecList->at(  Compressor_idx );
        
    // コーデックがダイアログを持っている場合、それを表示         
    if( pCodec->hasDialog() )         
    {         
      std::cout << "コーデックのセットアップ: " << std::endl;         
      pCodec->callDialog();         
    }         
    // 指定されたコーデックでシンクを作成         
    pSink = MediaStreamSink::create( pCont,  pCodec );     
  }
  else if( idx == 1 )     
  {
    // 非圧縮のコーデックを選択させる         
    int UFL_idx = presentUserChoice
          ( s_UncompressedFormatList, s_UncompressedFormatList + s_UncompressedFormatListCount );
    if( UFL_idx == -1 )         
    {             
      std::cerr << "非圧縮フォーマットが未選択です" << std::endl;             
      return 1;
    }
    // 指定された非圧縮フォーマットでシンクを作成
    GUID fmt_id =  s_UncompressedFormatList[UFL_idx].id;

    pSink = MediaStreamSink::create( pCont,  fmt_id );
  }
  else
  {
    // デバイス、フレームフィルタ、あるいはオーバーレイによって 指定されたフォーマットでシンクを作成
    pSink = MediaStreamSink::create( pCont& nbsp;);
  }
}
else
{
  // デバイス、フレームフィルタ、あるいはオーバーレイによって指定 されたフォーマットでシンクを作成
  pSink = MediaStreamSink::create( pCont );
}

/* コーデックとコンテナの組み合わせが作成されなかった場合もあるため チェックする */
if( pSink == 0 )
{
  std::cerr << "選択されたシンクは構築できませんでした。" << std::endl;
  return 1;
}

ビデオ録画の制御

データをビデオファイルに保存する際、AVIファイルとして記録するためにMediaStreamSinkクラスライブラリリファレンス>クラス>MediaStreamSinkが作成、初期化されます。選択されるコーデックとファイル名が設定されます。
シンクは最初、ePAUSEをパラメータとして持つGrabberSinkType::setSinkModeクラスライブラリリファレンス>クラス>GrabberSinkType>GrabberSinkType::setSinkMode Methodの呼び出しによって停止させられています。

// 最初シンクは停止しているので、ビデオデータがファイルに書き込まれることはありません。
pSink->setSinkMode( GrabberSinkType::ePAUSE );

// シンクの適用
grabber.setSinkType( pSink );

// ライブモードの開始。ライブ画像は表示されますが、 pSink は停止しているため
// AVIファイルには何も書き込まれません。
if( !grabber.startLive( true ) )
{
  std::cerr << grabber.getLastError().toString() << std::endl;
  return -1;
}

fflush(stdin);

std::cout << "[enter]を押すとキャプチャを開始します。";
std::cin.get();

// シンクの開始。イメージストリームがAVIファイルに書き込まれます。
pSink->setSinkMode(GrabberSinkType::eRUN );

std::cout << "ビデオ録画が開始されました。" << std::endl;
std::cout << "[enter]を押すとキャプチャを停止します。!";
std::cin.get();

// ライブモードの停止。これでAVIファイルのディスクへの保存が停止します。
grabber.stopLive();

Grabber::startLiveクラスライブラリリファレンス>クラス>Grabber>Grabber::startLive Methodによってライブモードが開始されると、プログラムはユーザーの入力待ちの状態となります。AVI録画を開始するため、シンクの停止状態を解除します。