如何检测电影是3D?

mih*_*ela 9 3d ffmpeg

有谁知道如何检测视频文件是3D电影?

我尝试过使用ffmpeg工具,但我没有成功找到怎么做.

样品

Mar*_*ann 7

这取决于格式.

在流级别:对于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的Comannd线工具

  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;
}
Run Code Online (Sandbox Code Playgroud)