Czy ktoś wie, jak wykryć, że plik wideo jest filmem 3D?Jak wykryć, że film jest 3D?
Próbowałem używać narzędzia ffmpeg, ale nie udało mi się znaleźć sposobu.
Czy ktoś wie, jak wykryć, że plik wideo jest filmem 3D?Jak wykryć, że film jest 3D?
Próbowałem używać narzędzia ffmpeg, ale nie udało mi się znaleźć sposobu.
To zależy od formatu.
Na poziomie strumienia: W przypadku AVC można wyszukać komunikaty SEI dotyczące rozmieszczenia ramek. Dla MVC możesz szukać NAL-ów dla przedłużenia plasterek (typ = 20).
http://www.merl.com/reports/docs/TR2011-022.pdf
Spojrzałem na pliku. Jest to AVC 3D z ramą typu pakowania 3 (obok siebie - L jest po lewej, R po prawej). Wyodrębniłem strumień H.264 i znalazłem przy przesunięciu bajtu 0x23: 00 00 00 01 06 2D jest to komunikat SEI (06) układu pakowania ramek typu (2D). Rzeczywiście plik zawiera informacje wskazujące 3D
Comannd narzędzie do wykrywania linii 3D
podjąć elementarny strumień H.264 82-3D-LHelEIJVxiE_track1.h264 i uruchomić go przechadzkę kod 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;
}
Czy możesz uruchomić mp4box + kawałek mojego kodu? Czy potrzebujesz kodu źródłowego lub plików binarnych? Jaka platforma? –
narzędzia Comannd linia wykryć 3D:
się elementarny strumień H.264 82-3D-LHelEIJVxiE_track1.h264 i uruchom go za pomocą następującego kodu:
#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;
}
Nie wiem, czy to pomaga: Wykryj współczynnik kształtu. Film 3D ma podwójną szerokość, np. 3840 x 1080 – Raptor
Co otrzymasz, gdy uruchomisz 'ffprobe 3dvideo.mp4'? – d33pika