2012-05-02 10 views
9

¿Alguien sabe cómo detectar que un archivo de video es una película en 3D?¿Cómo detectar que una película es en 3D?

He intentado usar la herramienta ffmpeg, pero no he podido averiguar cómo hacerlo.

sample

+0

No estoy seguro de si ayuda: Detecte la relación de aspecto. La película 3D tiene doble ancho, p. 3840 x 1080 – Raptor

+0

¿Qué obtienes cuando ejecutas 'ffprobe 3dvideo.mp4'? – d33pika

Respuesta

6

Depende del formato.

Nivel de flujo: Para AVC, puede buscar los mensajes de SEI de la disposición de empaque de cuadros. Para MVC, podría buscar NAL de extensión de corte (tipo = 20).

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

Miré a su archivo. Es AVC 3D con marco tipo 3 (uno al lado del otro - L está a la izquierda, R a la derecha). Extraí la secuencia H.264 y encontré en el desplazamiento de bytes 0x23: 00 00 00 01 06 2D este es un mensaje SEI (06) de la disposición de empaquetado de cuadros de tipo (2D). De hecho su archivo contiene información que indica 3D

herramienta de línea de Comannd para detectar 3D

  1. Extraer el flujo H.264 usando mp4box -raw 1 82-3D-LHelEIJVxiE.mp4 (http://gpac.wp.mines-telecom.fr/mp4box/)

tomar el tren elemental de H.264 82-3D-LHelEIJVxiE_track1.h264 y ejecutarlo a TRAVÉS el código followin:

#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

¿Puedes ejecutar mp4box + una parte de mi código? ¿Necesita código fuente o binarios? ¿Qué plataforma? –

0

herramienta de línea de Comannd detectar 3D:

  1. Extracto de la corriente H.264 usando mp4box -raw 1 82-3D-LHelEIJVxiE.mp4 (http://gpac.wp.mines-telecom.fr/mp4box/)

toman el flujo elemental H.264 82-3D-LHelEIJVxiE_track1.h264 y ejecútelo a través del siguiente código:

#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; 
} 
Cuestiones relacionadas