如何检测一部电影是否为3D?

11

有人知道如何检测一个视频文件是否为3D电影吗?

我尝试使用ffmpeg工具,但是没有成功找到如何实现。

样例文件


不确定是否有帮助:检测宽高比。3D电影具有双倍宽度,例如3840 x 1080。 - Raptor
当您运行 ffprobe 3dvideo.mp4 时,会得到什么? - d33pika
1个回答

9

这取决于格式。

在流级别上: 对于AVC,您可以查找帧包装排列SEI消息。 对于MVC,您可以查找切片扩展NAL(类型=20)。

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

我查看了您的文件。它是AVC 3D,帧包装类型为3(左右侧边 - L在左侧,R在右侧)。我提取了H.264流并在字节偏移0x23处找到:00 00 00 01 06 2D,这是一个SEI消息(06),类型为帧包装排列(2D)。确实,您的文件包含指示3D的信息

检测3D的命令行工具

  1. 使用mp4box -raw 1 82-3D-LHelEIJVxiE.mp4提取h.264流(http://gpac.wp.mines-telecom.fr/mp4box/

获取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;
}

你能运行mp4box加上我的一段代码吗?需要源代码还是二进制文件?在什么平台上? - Markus Schumann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接