ビデオファイルが3Dムービーであることを検出する方法を知っている人はいますか?
ffmpeg ツールを使用してみましたが、方法を見つけることができませんでした。
形式によって異なります。
ストリーム レベル: AVC の場合、フレーム パッキング アレンジメント SEI メッセージを探すことができます。MVC の場合、スライス拡張 NAL (タイプ = 20) を探すことができます。
http://www.merl.com/reports/docs/TR2011-022.pdf
私はあなたのファイルを見ました。フレーム パッキング タイプ 3 の AVC 3D です (サイド バイ サイド - 左が L、右が R)。H.264 ストリームを抽出したところ、バイト オフセット 0x23: 00 00 00 01 06 2D で見つかりました。これは、フレーム パッキング アレンジメント (2D) タイプの SEI メッセージ (06) です。確かに、あなたのファイルには3Dを示す情報が含まれています
3D を検出するためのコマンド ライン ツール
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;
}