2012-05-02 8 views
9

誰かがビデオファイルが3D映画であることを検出する方法を知っていますか?映画が3Dであることを検出するにはどうすればよいですか?

私はffmpegツールを使ってみましたが、やり方を見つけることに成功しませんでした。

sample

+0

わかりやすい:アスペクト比を検出してください。 3Dムービーは2倍の幅を持ちます。 3840 x 1080 – Raptor

+0

'ffprobe 3dvideo.mp4'を実行するとどうなりますか? – d33pika

答えて

6

それは形式によって異なります。

オンストリームレベル: AVCの場合、フレームパッキング配置SEIメッセージを検索できます。 MVCでは、スライス拡張NAL(type = 20)を探すことができます。

http://www.merl.com/reports/docs/TR2011-022.pdf

私はあなたのファイルを見ました。フレーム梱包タイプ3(横並び - Lは左、右はR)のAVC 3Dです。私はH.264ストリームを取り出し、バイトオフセット0x23:00 00 01 01 2Dで見つけました。これはタイプのフレームパッキング配列(2D)のSEIメッセージ(06)です。確かに、あなたのファイルは、3D

  1. は1 82-3D-LHelEIJVxiE.mp4(http://gpac.wp.mines-telecom.fr/mp4box/

-raw mp4boxを使用してH.264ストリームを抽出し検出するために、3D

Comanndラインツールを示す情報が含まれています82-3D-LHelEIJVxiE_track1.h264 H.264エレメンタリ・ストリームを取得し、それがfollowinコードthrought実行します。

#include <iostream> 
#include <fstream> 

typedef unsigned char uint8_t; 


enum ResultCode 
{ 
    E_Error = -1, 
    E_OK  = 0, 
    E_No3D = 2, 
    E_Found3D = 3, 

}; 

enum NALType 
{ 
    NALType_Unknown    = 0, 
    NALType_Slice    = 1, 
    NALType_Slice_DPA   = 2, 
    NALType_Slice_DPB   = 3, 
    NALType_Slice_DPC   = 4, 
    NALType_Slice_IDR   = 5, 
    NALType_SEI     = 6, 
    NALType_SPS     = 7, 
    NALType_PPS     = 8, 
    NALType_AU_Delimiter  = 9, 
    NALType_SequenceEnd   = 10, 
    NALType_StreamEnd   = 11, 
    NALType_FillerData   = 12, 
    NALType_CodedSliceExtension = 20, 

    NALType_MAX     = 0x1f 
}; 

enum SEIType 
{ 
    SEIType_FramePackingArrangement = 0x2D 
}; 


enum StartCodeState 
{ 
    StartCodeState_none, 
    StartCodeState_0, 
    StartCodeState_0_0, 
    StartCodeState_0_0_1 
}; 


int Is3D(std::ifstream & inputFile) 
{ 
    int nResult = E_OK; 

    StartCodeState eStartCodeState = StartCodeState_none; 

    while((E_OK == nResult) && (! inputFile.eof())) 
    { 
     uint8_t byte = inputFile.get(); 

     switch(eStartCodeState) 
     { 
     case StartCodeState_none : 
      eStartCodeState = (byte == 0) ? StartCodeState_0 : StartCodeState_none; 
      break; 

     case StartCodeState_0 : 
      eStartCodeState = (byte == 0) ? StartCodeState_0_0 : StartCodeState_none; 
      break; 

     case StartCodeState_0_0 : 
      switch(byte) 
      { 
       case 0 : eStartCodeState = StartCodeState_0_0; break; 
       case 1 : eStartCodeState = StartCodeState_0_0_1; break; 
       default : eStartCodeState = StartCodeState_none; 

      } 

     default: 
      ; 
     } 

     if( eStartCodeState == StartCodeState_0_0_1) 
     { 
     uint8_t cNALType = inputFile.get(); 
       cNALType &= NALType_MAX; 

     switch(cNALType) 
     { 
      case NALType_CodedSliceExtension : 
       nResult = E_Found3D; 
       break; 

      case NALType_SEI : 
      { 
       uint8_t cSEIType = inputFile.get(); 
       if(cSEIType == SEIType_FramePackingArrangement) 
       { 
        nResult = E_Found3D; 
       } 
       break; 
      } 

      default: 
       ; 
     } 

     eStartCodeState = StartCodeState_none; 
     } 
    } 

    return nResult; 
} 


int main(int argc, char * argv[]) 
{ 
    int nResult = E_OK; 

    if(argc != 2) 
    { 
     nResult = E_Error; 

     std::cerr << "Usage: " 
       << argv[0] 
       << " <H.264 elementary stream input file>" 
       << std::endl; 

    } 

    if(E_OK == nResult) 
    { 
     std::ifstream inputFile(argv[1], std::ios::binary); 

     if(inputFile.is_open()) 
     { 
     if(E_Found3D == Is3D(inputFile)) 
     { 
      std::cout << "File: " 
         << argv[1] 
         << " contains 3D." 
         << std::endl; 

      nResult = E_Found3D; 

     } 
     else 
     { 
      std::cout << "No 3D found" << std::endl; 

      nResult = E_No3D; 
     } 


     } 
     else 
     { 
     std::cerr << "Error opening input file: " 
        << argv[1] 
        << std::endl; 

     nResult = E_Error; 
     } 
    } 

    return nResult; 
} 
+0

mp4box +自分のコードを実行できますか?ソースコードやバイナリが必要ですか?どのプラットフォームですか? –

0

Comanndラインツールへの3D検出:

  1. はmp4box -raw 1 82-3D-LHelEIJVxiE.mp4(http://gpac.wp.mines-telecom.fr/mp4box/に)

を使用してH.264ストリームを抽出H.264エレメンタリストリーム82-3D-LHelEIJVxiE_track1.h264を取ります次のコードを実行してください:

#include <iostream> 
#include <fstream> 

typedef unsigned char uint8_t; 


enum ResultCode 
{ 
    E_Error = -1, 
    E_OK  = 0, 
    E_No3D = 2, 
    E_Found3D = 3, 

}; 

enum NALType 
{ 
    NALType_Unknown    = 0, 
    NALType_Slice    = 1, 
    NALType_Slice_DPA   = 2, 
    NALType_Slice_DPB   = 3, 
    NALType_Slice_DPC   = 4, 
    NALType_Slice_IDR   = 5, 
    NALType_SEI     = 6, 
    NALType_SPS     = 7, 
    NALType_PPS     = 8, 
    NALType_AU_Delimiter  = 9, 
    NALType_SequenceEnd   = 10, 
    NALType_StreamEnd   = 11, 
    NALType_FillerData   = 12, 
    NALType_CodedSliceExtension = 20, 

    NALType_MAX     = 0x1f 
}; 

enum SEIType 
{ 
    SEIType_FramePackingArrangement = 0x2D 
}; 


enum StartCodeState 
{ 
    StartCodeState_none, 
    StartCodeState_0, 
    StartCodeState_0_0, 
    StartCodeState_0_0_1 
}; 


int Is3D(std::ifstream & inputFile) 
{ 
    int nResult = E_OK; 

    StartCodeState eStartCodeState = StartCodeState_none; 

    while((E_OK == nResult) && (! inputFile.eof())) 
    { 
     uint8_t byte = inputFile.get(); 

     switch(eStartCodeState) 
     { 
     case StartCodeState_none : 
      eStartCodeState = (byte == 0) ? StartCodeState_0 : StartCodeState_none; 
      break; 

     case StartCodeState_0 : 
      eStartCodeState = (byte == 0) ? StartCodeState_0_0 : StartCodeState_none; 
      break; 

     case StartCodeState_0_0 : 
      switch(byte) 
      { 
       case 0 : eStartCodeState = StartCodeState_0_0; break; 
       case 1 : eStartCodeState = StartCodeState_0_0_1; break; 
       default : eStartCodeState = StartCodeState_none; 

      } 

     default: 
      ; 
     } 

     if( eStartCodeState == StartCodeState_0_0_1) 
     { 
     uint8_t cNALType = inputFile.get(); 
       cNALType &= NALType_MAX; 

     switch(cNALType) 
     { 
      case NALType_CodedSliceExtension : 
       nResult = E_Found3D; 
       break; 

      case NALType_SEI : 
      { 
       uint8_t cSEIType = inputFile.get(); 
       if(cSEIType == SEIType_FramePackingArrangement) 
       { 
        nResult = E_Found3D; 
       } 
       break; 
      } 

      default: 
       ; 
     } 

     eStartCodeState = StartCodeState_none; 
     } 
    } 

    return nResult; 
} 


int main(int argc, char * argv[]) 
{ 
    int nResult = E_OK; 

    if(argc != 2) 
    { 
     nResult = E_Error; 

     std::cerr << "Usage: " 
       << argv[0] 
       << " <H.264 elementary stream input file>" 
       << std::endl; 

    } 

    if(E_OK == nResult) 
    { 
     std::ifstream inputFile(argv[1], std::ios::binary); 

     if(inputFile.is_open()) 
     { 
     if(E_Found3D == Is3D(inputFile)) 
     { 
      std::cout << "File: " 
         << argv[1] 
         << " contains 3D." 
         << std::endl; 

      nResult = E_Found3D; 

     } 
     else 
     { 
      std::cout << "No 3D found" << std::endl; 

      nResult = E_No3D; 
     } 


     } 
     else 
     { 
     std::cerr << "Error opening input file: " 
        << argv[1] 
        << std::endl; 

     nResult = E_Error; 
     } 
    } 

    return nResult; 
} 
関連する問題