improved format detection
This commit is contained in:
parent
4256d2b403
commit
7106e8650b
|
@ -19,6 +19,8 @@ namespace Media {
|
|||
|
||||
enum class MediaType;
|
||||
enum class GeneralMediaFormat;
|
||||
class MpegAudioFrameStream;
|
||||
class WaveAudioStream;
|
||||
|
||||
/*!
|
||||
* \brief Specifies the track type.
|
||||
|
@ -33,11 +35,10 @@ enum class TrackType
|
|||
OggStream /**< The track is a Media::OggStream. */
|
||||
};
|
||||
|
||||
class MpegAudioFrameStream;
|
||||
|
||||
class LIB_EXPORT AbstractTrack : public StatusProvider
|
||||
{
|
||||
friend class MpegAudioFrameStream; // this is a temporary solution, until I have a better design
|
||||
friend class MpegAudioFrameStream;
|
||||
friend class WaveAudioStream;
|
||||
|
||||
public:
|
||||
virtual ~AbstractTrack();
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
#include "mediafourcc.h"
|
||||
|
||||
#include "../mediaformat.h"
|
||||
|
||||
namespace Media {
|
||||
|
||||
namespace Fourccs {
|
||||
|
||||
/*!
|
||||
* \brief Returns the media format for the specified \a fourcc.
|
||||
*/
|
||||
MediaFormat fourccToMediaFormat(uint32 fourcc) {
|
||||
switch(fourcc) {
|
||||
case XvidMpeg4:
|
||||
return MediaFormat(GeneralMediaFormat::Mpeg4Video, SubFormats::Mpeg4Asp);
|
||||
default: return MediaFormat(); // TODO: cover more FOURCCs
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,354 +0,0 @@
|
|||
#ifndef MEDIAFOURCC_H
|
||||
#define MEDIAFOURCC_H
|
||||
|
||||
#include <c++utilities/application/global.h>
|
||||
#include <c++utilities/conversion/types.h>
|
||||
|
||||
namespace Media {
|
||||
|
||||
class MediaFormat;
|
||||
|
||||
namespace Fourccs {
|
||||
|
||||
enum KnownValues {
|
||||
AMParedesPredictor = 0x31393738,
|
||||
VuyBlackmagic = 0x32565559,
|
||||
Ivx1 = 0x33495630,
|
||||
Ivx2 = 0x33495631,
|
||||
Ivx3 = 0x33495632,
|
||||
FfmpegDivxMsMpeg4V3 = 0x33495644,
|
||||
Ivx4 = 0x33495658,
|
||||
PlanarRgbCodec = 0x38425053,
|
||||
AutodeskAnimatorCodecRle1 = 0x41415334,
|
||||
AutodeskAnimatorCodecRle2 = 0x41415343,
|
||||
KensingtonCodec = 0x41425952,
|
||||
StreamboxActl2 = 0x4143544C,
|
||||
Wavecodec = 0x41445631,
|
||||
Advj = 0x4144564A,
|
||||
IntelIndeoVideo32 = 0x4145494B,
|
||||
ArrayVideooneMpeg1ICapture = 0x41454D49,
|
||||
AutodeskAnimatorFlc256Color = 0x41464C43,
|
||||
AfliAutodeskAnimatorFli256Color = 0x41464C49,
|
||||
Cineform10BitVisuallyPerfectHdWavelet = 0x41484456,
|
||||
Ajpg = 0x414A5047,
|
||||
Ampg = 0x414D5047,
|
||||
Anim = 0x414E494D,
|
||||
AngelpotionDefinitive1 = 0x41503431,
|
||||
AngelpotionDefinitive2 = 0x41503432,
|
||||
AlparysoftLosslessCodec = 0x41534C43,
|
||||
AsusVideo = 0x41535631,
|
||||
AsusVideo2 = 0x41535632,
|
||||
AsusVideo20 = 0x41535658,
|
||||
Atm4 = 0x41544D34,
|
||||
Aura2CodecYuv422 = 0x41555232,
|
||||
Aura1CodecYuv411 = 0x41555241,
|
||||
Avc1 = 0x41564331,
|
||||
Avrn = 0x4156524E,
|
||||
Ba81 = 0x42413831,
|
||||
BinkVideo = 0x42494E4B,
|
||||
Blz0 = 0x424C5A30,
|
||||
ProsumerVideo = 0x42543230,
|
||||
Btcv = 0x42544356,
|
||||
BroadwayMpegCapturecompression = 0x42573130,
|
||||
Byr1 = 0x42595231,
|
||||
Byr2 = 0x42595232,
|
||||
Cc12 = 0x43433132,
|
||||
Cdvc = 0x43445643,
|
||||
Cfcc = 0x43464343,
|
||||
Cgdi = 0x43474449,
|
||||
Cham = 0x4348414D,
|
||||
WebcamJpeg = 0x434A5047,
|
||||
Cmyk = 0x434D594B,
|
||||
Cpla = 0x43504C41,
|
||||
Cram = 0x4352414D,
|
||||
CamstudioCodec = 0x43534344,
|
||||
Ctrx = 0x43545258,
|
||||
Cinepak = 0x43564944,
|
||||
Cwlt = 0x43574C54,
|
||||
ConexantYuv411 = 0x43585931,
|
||||
ConexantYuv422 = 0x43585932,
|
||||
CreativeYuv = 0x43595556,
|
||||
Cyuy = 0x43595559,
|
||||
D261 = 0x44323631,
|
||||
D263 = 0x44323633,
|
||||
Davc = 0x44415643,
|
||||
Dcl1 = 0x44434C31,
|
||||
Dcl2 = 0x44434C32,
|
||||
Dcl3 = 0x44434C33,
|
||||
Dcl4 = 0x44434C34,
|
||||
Dcl5 = 0x44434C35,
|
||||
DivxMpeg41 = 0x44495633,
|
||||
DivxMpeg42 = 0x44495634,
|
||||
Div5 = 0x44495635,
|
||||
Divx = 0x44495658,
|
||||
Dm4V = 0x444D3456,
|
||||
RainbowRunnerHardwareCompression = 0x444D4231,
|
||||
Dmb2 = 0x444D4232,
|
||||
Dmk2 = 0x444D4B32,
|
||||
Dsvd = 0x44535644,
|
||||
TruemotionS = 0x4455434B,
|
||||
Dvcpro = 0x44563235,
|
||||
Dvcpro50 = 0x44563530,
|
||||
Dvan = 0x4456414E,
|
||||
Dvcs = 0x44564353,
|
||||
Dve2 = 0x44564532,
|
||||
Smpte370M = 0x44564831,
|
||||
ConsumerDv50Mbps = 0x44564844,
|
||||
ConsumerDv25Mbps = 0x44565344,
|
||||
ConsumerDv125Mbps = 0x4456534C,
|
||||
Dvx1 = 0x44565831,
|
||||
Dvx2 = 0x44565832,
|
||||
Dvx3 = 0x44565833,
|
||||
DivxMpeg43 = 0x44583530,
|
||||
Dxgm = 0x4458474D,
|
||||
Dxtc = 0x44585443,
|
||||
Dxtn = 0x4458544E,
|
||||
ElsaQuickCodec = 0x454B5130,
|
||||
Elk0 = 0x454C4B30,
|
||||
EtymonixMpeg2Video = 0x454D3256,
|
||||
Eyestream7Codec = 0x45533037,
|
||||
Escp = 0x45534350,
|
||||
EtreppidVideoCodec1 = 0x45545631,
|
||||
EtreppidVideoCodec2 = 0x45545632,
|
||||
Etvc = 0x45545643,
|
||||
FfmpegCodec = 0x46465631,
|
||||
Fljp = 0x464C4A50,
|
||||
Ffmpeg = 0x464D5034,
|
||||
FmscreenCaptureCodec = 0x464D5643,
|
||||
FrapsCodec = 0x46505331,
|
||||
ForwardMotionJpegWithAlphaChannel = 0x46525741,
|
||||
ForwardMotionJpeg = 0x46525744,
|
||||
Fvf1 = 0x46564631,
|
||||
Geompeg4 = 0x47454F58,
|
||||
Gjpg = 0x474A5047,
|
||||
MotionLzw = 0x474C5A57,
|
||||
MotionJpeg1 = 0x47504547,
|
||||
Gwlt = 0x47574C54,
|
||||
H260ThroughH269 = 0x48323630,
|
||||
RawYuv422 = 0x48445943,
|
||||
H265Hevc = 0x48455643,
|
||||
HuffmanLosslessCodec = 0x48465955,
|
||||
Hmcr = 0x484D4352,
|
||||
Hmrr = 0x484D5252,
|
||||
ItuH263 = 0x49323633,
|
||||
Iclb = 0x49434C42,
|
||||
Igor = 0x49474F52,
|
||||
Ijpg = 0x494A5047,
|
||||
Ilvc = 0x494C5643,
|
||||
Ilvr = 0x494C5652,
|
||||
GigaAviDvCodec = 0x49504456,
|
||||
Indeo21 = 0x49523231,
|
||||
Iraw = 0x49524157,
|
||||
Isme = 0x49534D45,
|
||||
Indeo3 = 0x49563330,
|
||||
Indeo32 = 0x49563332,
|
||||
IndeoInteractive1 = 0x49563430,
|
||||
IndeoInteractive2 = 0x49563530,
|
||||
Jbyr = 0x4A425952,
|
||||
JpegStillImage = 0x4A504547,
|
||||
JpegLight = 0x4A50474C,
|
||||
Kmvc = 0x4B4D5643,
|
||||
L261 = 0x4C323631,
|
||||
LeadH263 = 0x4C323633,
|
||||
Lbyr = 0x4C425952,
|
||||
LeadmcmwVideoCodec = 0x4C434D57,
|
||||
LeadMjpeg20001 = 0x4C435732,
|
||||
LeadVideoCodec = 0x4C454144,
|
||||
Lgry = 0x4C475259,
|
||||
LeadJpeg411 = 0x4C4A3131,
|
||||
LeadJpeg422 = 0x4C4A3232,
|
||||
LeadMjpeg20002 = 0x4C4A324B,
|
||||
LeadJpeg444 = 0x4C4A3434,
|
||||
LeadMjpegCodec = 0x4C4A5047,
|
||||
LeadMpeg2VideoCodec = 0x4C4D5032,
|
||||
LeadMpeg4VideoCodec = 0x4C4D5034,
|
||||
Lsvc = 0x4C535643,
|
||||
Lsvm = 0x4C53564D,
|
||||
LightningStrikeVideoCodec = 0x4C535658,
|
||||
LempelzivoberhumerCodec = 0x4C5A4F31,
|
||||
M261 = 0x4D323631,
|
||||
M263 = 0x4D323633,
|
||||
M4CcM4Cc = 0x4D344343,
|
||||
M4S2 = 0x4D345332,
|
||||
Mc12 = 0x4D433132,
|
||||
Mcam = 0x4D43414D,
|
||||
MotionJpeg2000 = 0x4D4A3243,
|
||||
MotionJpeg2 = 0x4D4A5047,
|
||||
Mmes = 0x4D4D4553,
|
||||
EvalDownload1 = 0x4D503241,
|
||||
EvalDownload2 = 0x4D503254,
|
||||
EvalDownload3 = 0x4D503256,
|
||||
Mpeg4 = 0x4D503432,
|
||||
Mp43 = 0x4D503433,
|
||||
EvalDownload4 = 0x4D503441,
|
||||
Mp4S = 0x4D503453,
|
||||
EvalDownload5 = 0x4D503454,
|
||||
EvalDownload6 = 0x4D503456,
|
||||
Mpeg = 0x4D504547,
|
||||
Mpg4 = 0x4D504734,
|
||||
Mpgi = 0x4D504749,
|
||||
Mr16 = 0x4D523136,
|
||||
Mrca = 0x4D524341,
|
||||
Mrle = 0x4D524C45,
|
||||
Msvc = 0x4D535643,
|
||||
Avimszh = 0x4D535A48,
|
||||
Mtx1ThroughMtx9 = 0x4D545831,
|
||||
MotionPixelsMvi1Codec = 0x4D564931,
|
||||
MotionPixelsMvi2Codec = 0x4D564932,
|
||||
AwareMotionWavelets = 0x4D575631,
|
||||
Navi = 0x4E415649,
|
||||
Ndsc = 0x4E445343,
|
||||
Ndsm = 0x4E44534D,
|
||||
Ndsp = 0x4E445350,
|
||||
Ndss = 0x4E445353,
|
||||
Ndxc = 0x4E445843,
|
||||
Ndxh = 0x4E445848,
|
||||
Ndxp = 0x4E445850,
|
||||
Ndxs = 0x4E445853,
|
||||
Nhvu = 0x4E485655,
|
||||
Ntn1 = 0x4E544E31,
|
||||
Ntn2 = 0x4E544E32,
|
||||
Nvds = 0x4E564453,
|
||||
Nvhs = 0x4E564853,
|
||||
Nvs0Nvs5 = 0x4E565330,
|
||||
Nvt0Nvt5 = 0x4E565430,
|
||||
DvcCodec = 0x50445643,
|
||||
Pgvv = 0x50475656,
|
||||
Phmo = 0x50484D4F,
|
||||
Pim1 = 0x50494D31,
|
||||
Pim2 = 0x50494D32,
|
||||
PegasusLosslessJpeg = 0x50494D4A,
|
||||
VideoXl = 0x5049584C,
|
||||
Pjpg = 0x504A5047,
|
||||
Pvez = 0x5056455A,
|
||||
Pvmm = 0x50564D4D,
|
||||
PegasusWavelet2000Compression = 0x50565732,
|
||||
Qpeg = 0x51504547,
|
||||
Qpeq = 0x51504551,
|
||||
Rgbt = 0x52474254,
|
||||
Rle = 0x524C450,
|
||||
Rle4 = 0x524C4534,
|
||||
Rle8 = 0x524C4538,
|
||||
Rmp4 = 0x524D5034,
|
||||
AppleVideo = 0x52505A41,
|
||||
Rt21 = 0x52543231,
|
||||
Rv20 = 0x52563230,
|
||||
Rv30 = 0x52563330,
|
||||
Rv40 = 0x52563430,
|
||||
VideocapC210 = 0x53343232,
|
||||
San3 = 0x53414E33,
|
||||
Sdcc = 0x53444343,
|
||||
Sedg = 0x53454447,
|
||||
SurfaceFittingMethod = 0x53464D43,
|
||||
Smp4 = 0x534D5034,
|
||||
Smsc = 0x534D5343,
|
||||
Smsd = 0x534D5344,
|
||||
Smsv = 0x534D5356,
|
||||
Sp40 = 0x53503430,
|
||||
Sp44 = 0x53503434,
|
||||
Sp54 = 0x53503534,
|
||||
Spig = 0x53504947,
|
||||
Sqz2 = 0x53515A32,
|
||||
Stva = 0x53545641,
|
||||
Stvb = 0x53545642,
|
||||
Stvc = 0x53545643,
|
||||
Stvx = 0x53545658,
|
||||
Stvy = 0x53545659,
|
||||
VideoR1 = 0x53563130,
|
||||
SorensonVideo1 = 0x53565131,
|
||||
Svq3 = 0x53565133,
|
||||
Tlms = 0x544C4D53,
|
||||
Tlst = 0x544C5354,
|
||||
Tm20 = 0x544D3230,
|
||||
Tm2X = 0x544D3258,
|
||||
Tmic = 0x544D4943,
|
||||
Tmot = 0x544D4F54,
|
||||
TruemotionRt20 = 0x54523230,
|
||||
TechsmithScreenCaptureCodec = 0x54534343,
|
||||
Tv10 = 0x54563130,
|
||||
Tvjp = 0x54564A50,
|
||||
Tvmj = 0x54564D4A,
|
||||
Ty0N = 0x5459304E,
|
||||
Ty2C = 0x54593243,
|
||||
Ty2N = 0x5459324E,
|
||||
Clearvideo = 0x55434F44,
|
||||
Ultimotion = 0x554C5449,
|
||||
V210 = 0x56323130,
|
||||
V261 = 0x56323631,
|
||||
V655 = 0x56363535,
|
||||
Vcr1 = 0x56435231,
|
||||
Vcr2 = 0x56435232,
|
||||
Vcr39 = 0x56435233,
|
||||
Vdct = 0x56444354,
|
||||
Vdom = 0x56444F4D,
|
||||
Vdow = 0x56444F57,
|
||||
VideotizerYuvCodec = 0x5644545A,
|
||||
Videogrampix = 0x56475058,
|
||||
Vids = 0x56494453,
|
||||
VfapiCodec = 0x56494650,
|
||||
Vivo = 0x5649564F,
|
||||
Vixl = 0x5649584C,
|
||||
Vlv1 = 0x564C5631,
|
||||
Vp30 = 0x56503330,
|
||||
Vp31 = 0x56503331,
|
||||
Vp40 = 0x56503430,
|
||||
Vp50 = 0x56503530,
|
||||
Vp60 = 0x56503630,
|
||||
Vp61 = 0x56503631,
|
||||
Vp62 = 0x56503632,
|
||||
Vp70 = 0x56503730,
|
||||
Vp80 = 0x56503830,
|
||||
Vqc1 = 0x56514331,
|
||||
Vqc2 = 0x56514332,
|
||||
Vqjc = 0x56514A43,
|
||||
VssVideo = 0x56535356,
|
||||
Vuuu = 0x56555555,
|
||||
Vx1K = 0x5658314B,
|
||||
Vx2K = 0x5658324B,
|
||||
Vxsp = 0x56585350,
|
||||
AtiYuv1 = 0x56595539,
|
||||
AtiYuv2 = 0x56595559,
|
||||
Wbvc = 0x57425643,
|
||||
Wham = 0x5748414D,
|
||||
WinnovSoftwareCompression = 0x57494E58,
|
||||
WinbondJpeg = 0x574A5047,
|
||||
Wmv1 = 0x574D5631,
|
||||
Wmv2 = 0x574D5632,
|
||||
WindowsMediaVideo9 = 0x574D5633,
|
||||
Wmva = 0x574D5641,
|
||||
WinnovHardwareCompression = 0x574E5631,
|
||||
Wvc1 = 0x57564331,
|
||||
X263 = 0x58323633,
|
||||
H264 = 0x58323634,
|
||||
Xlv0 = 0x584C5630,
|
||||
Xmpg = 0x584D5047,
|
||||
XvidMpeg4 = 0x58564944,
|
||||
Xwv0Xwv9 = 0x58575630,
|
||||
Xxan = 0x5858414E,
|
||||
BppGrayscaleVideo = 0x5931360,
|
||||
Y411 = 0x59343131,
|
||||
BrooktreeYuv411 = 0x59343150,
|
||||
Y444 = 0x59343434,
|
||||
Y8 = 0x593800,
|
||||
Yc12 = 0x59433132,
|
||||
Yuv8 = 0x59555638,
|
||||
Yuv9RawFormat = 0x59555639,
|
||||
Yuvp = 0x59555650,
|
||||
Yuy2 = 0x59555932,
|
||||
Yuyv = 0x59555956,
|
||||
Yuv420Planar = 0x59563132,
|
||||
Yv16 = 0x59563136,
|
||||
Yv92 = 0x59563932,
|
||||
Zlib = 0x5A4C4942,
|
||||
TheDoxboxProject = 0x5A4D4256,
|
||||
Zpeg = 0x5A504547,
|
||||
Zygovideo = 0x5A59474F
|
||||
};
|
||||
|
||||
LIB_EXPORT MediaFormat fourccToMediaFormat(uint32 fourcc);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // MEDIAFOURCC_H
|
12
general.pri
12
general.pri
|
@ -12,7 +12,17 @@ unix {
|
|||
QMAKE_LFLAGS += "-Wl,--rpath=./"
|
||||
}
|
||||
# prefix
|
||||
targetprefix = .
|
||||
targetprefix = $$(TARGET_PREFIX)
|
||||
equals(targetprefix, "") {
|
||||
win32 {
|
||||
targetprefix = ../../..
|
||||
} else {
|
||||
targetprefix = ../..
|
||||
}
|
||||
}
|
||||
message("Using target prefix \"$${targetprefix}\".")
|
||||
# print install root
|
||||
message("Using install root \"$$(INSTALL_ROOT)\".")
|
||||
# target
|
||||
CONFIG(debug, debug|release) {
|
||||
TARGET = $$targetprefix/$${projectname}d
|
||||
|
|
|
@ -562,13 +562,11 @@ template <class ImplementationType>
|
|||
typename GenericFileElement<ImplementationType>::implementationType *GenericFileElement<ImplementationType>::childById(const GenericFileElement<ImplementationType>::identifierType &id)
|
||||
{
|
||||
parse(); // ensure element is parsed
|
||||
implementationType *child = firstChild();
|
||||
while(child) {
|
||||
for(implementationType *child = firstChild(); child; child = child->nextSibling()) {
|
||||
child->parse();
|
||||
if(child->id() == id) {
|
||||
return child;
|
||||
}
|
||||
child = child->nextSibling();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -591,13 +589,11 @@ template <class ImplementationType>
|
|||
typename GenericFileElement<ImplementationType>::implementationType *GenericFileElement<ImplementationType>::siblingById(const GenericFileElement<ImplementationType>::identifierType &id, bool includeThis)
|
||||
{
|
||||
parse(); // ensure element is parsed
|
||||
implementationType *sibling = includeThis ? static_cast<implementationType*>(this) : nextSibling();
|
||||
while(sibling) {
|
||||
for(implementationType *sibling = includeThis ? static_cast<implementationType*>(this) : nextSibling(); sibling; sibling = sibling->nextSibling()) {
|
||||
sibling->parse();
|
||||
if(sibling->id() == id) {
|
||||
return sibling;
|
||||
}
|
||||
sibling = sibling->nextSibling();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
#include "matroskaid.h"
|
||||
|
||||
#include "../avi/bitmapinfoheader.h"
|
||||
#include "../avi/mediafourcc.h"
|
||||
#include "../wav/waveaudiostream.h"
|
||||
#include "../mp4/mp4ids.h"
|
||||
|
||||
#include "../mediaformat.h"
|
||||
#include "../exceptions.h"
|
||||
|
@ -81,6 +82,8 @@ MediaFormat MatroskaTrack::codecIdToMediaFormat(const string &codecId)
|
|||
fmt.general = GeneralMediaFormat::Theora;
|
||||
} else if(part1 == "V_PRORES") {
|
||||
fmt.general = GeneralMediaFormat::ProRes;
|
||||
} else if(part1 == "V_VP8") {
|
||||
fmt.general = GeneralMediaFormat::Vp8;
|
||||
} else if(part1 == "A_MPEG") {
|
||||
fmt.general = GeneralMediaFormat::Mpeg1Audio;
|
||||
if(part2 == "L1") {
|
||||
|
@ -345,7 +348,6 @@ void MatroskaTrack::internalParseHeader()
|
|||
switch(m_format.general) {
|
||||
EbmlElement *codecPrivateElement;
|
||||
case GeneralMediaFormat::MicrosoftVideoCodecManager:
|
||||
case GeneralMediaFormat::MicrosoftAudioCodecManager:
|
||||
if((codecPrivateElement = m_trackElement->childById(MatroskaIds::CodecPrivate))) {
|
||||
// parse bitmap info header to determine actual format
|
||||
if(codecPrivateElement->dataSize() >= 0x28) {
|
||||
|
@ -356,7 +358,20 @@ void MatroskaTrack::internalParseHeader()
|
|||
m_formatId += " \"";
|
||||
m_formatId += interpretIntegerAsString(bitmapInfoHeader.compression);
|
||||
m_formatId += "\"";
|
||||
m_format += Fourccs::fourccToMediaFormat(bitmapInfoHeader.compression);
|
||||
m_format += FourccIds::fourccToMediaFormat(bitmapInfoHeader.compression);
|
||||
} else {
|
||||
addNotification(NotificationType::Critical, "BITMAPINFOHEADER structure (in \"CodecPrivate\"-element) is truncated.", context);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GeneralMediaFormat::MicrosoftAudioCodecManager:
|
||||
if((codecPrivateElement = m_trackElement->childById(MatroskaIds::CodecPrivate))) {
|
||||
// parse WAVE header to determine actual format
|
||||
if(codecPrivateElement->dataSize() >= 16) {
|
||||
m_istream->seekg(codecPrivateElement->dataOffset());
|
||||
WaveFormatHeader waveFormatHeader;
|
||||
waveFormatHeader.parse(reader());
|
||||
WaveAudioStream::addInfo(waveFormatHeader, *this);
|
||||
} else {
|
||||
addNotification(NotificationType::Critical, "BITMAPINFOHEADER structure (in \"CodecPrivate\"-element) is truncated.", context);
|
||||
}
|
||||
|
|
|
@ -137,12 +137,14 @@ const char *MediaFormat::name() const
|
|||
}
|
||||
case GeneralMediaFormat::Theora: return "Theora";
|
||||
case GeneralMediaFormat::Tiff: return "Tagged Image File Format";
|
||||
case GeneralMediaFormat::TimedText: return "Timed Text";
|
||||
case GeneralMediaFormat::Tta: return "The True Audio";
|
||||
case GeneralMediaFormat::UncompressedVideoFrames: return "uncompressed video frames";
|
||||
case GeneralMediaFormat::Vc1: return "Windows Media Video";
|
||||
case GeneralMediaFormat::VobBtn: return "VobBtn Buttons";
|
||||
case GeneralMediaFormat::VobSub: return "VobSub";
|
||||
case GeneralMediaFormat::Vorbis: return "Vorbis";
|
||||
case GeneralMediaFormat::Vp8: return "VP8";
|
||||
case GeneralMediaFormat::WavPack: return "WavPack";
|
||||
default: return "unknown";
|
||||
}
|
||||
|
@ -280,12 +282,14 @@ const char *MediaFormat::abbreviation() const
|
|||
}
|
||||
case GeneralMediaFormat::Theora: return "Theora";
|
||||
case GeneralMediaFormat::Tiff: return "TIFF";
|
||||
case GeneralMediaFormat::TimedText: return "Timed Text";
|
||||
case GeneralMediaFormat::Tta: return "TTA";
|
||||
case GeneralMediaFormat::UncompressedVideoFrames: return "uncompressed video frames";
|
||||
case GeneralMediaFormat::Vc1: return "VC-1";
|
||||
case GeneralMediaFormat::VobBtn: return "VobBtn";
|
||||
case GeneralMediaFormat::VobSub: return "VobSub";
|
||||
case GeneralMediaFormat::Vorbis: return "Vorbis";
|
||||
case GeneralMediaFormat::Vp8: return "VP8";
|
||||
case GeneralMediaFormat::WavPack: return "WavPack";
|
||||
default: return "";
|
||||
}
|
||||
|
|
|
@ -71,12 +71,14 @@ enum class GeneralMediaFormat
|
|||
TextSubtitle, /**< Text subtitle */
|
||||
Theora, /**< Theora */
|
||||
Tiff, /**< TIFF */
|
||||
TimedText, /** < Timed Text */
|
||||
Tta, /**< The True Audio lessles audio compressor */
|
||||
UncompressedVideoFrames, /**< uncompressed RGB */
|
||||
Vc1, /**< VC-1 */
|
||||
VobBtn, /**< VobBtn */
|
||||
VobSub, /**< VobSub */
|
||||
Vorbis, /**< Vorbis */
|
||||
Vp8, /** < VP8 */
|
||||
WavPack /**< WavPack */
|
||||
};
|
||||
|
||||
|
|
|
@ -193,7 +193,7 @@ bool Mp4Atom::isPadding() const
|
|||
uint64 Mp4Atom::firstChildOffset() const
|
||||
{
|
||||
using namespace Mp4AtomIds;
|
||||
using namespace Mp4FormatIds;
|
||||
using namespace FourccIds;
|
||||
if(isParent()) {
|
||||
switch(id()) {
|
||||
case Meta: return headerSize() + 0x4;
|
||||
|
|
|
@ -40,42 +40,64 @@ namespace Mp4MediaTypeIds {
|
|||
* \brief Encapsulates all supported MP4 media format IDs (aka "FOURCCs").
|
||||
* \sa http://wiki.multimedia.cx/?title=QuickTime_container
|
||||
*/
|
||||
namespace Mp4FormatIds {
|
||||
namespace FourccIds {
|
||||
|
||||
MediaFormat fourccToMediaFormat(uint32 fourccId)
|
||||
{
|
||||
switch(fourccId) {
|
||||
case Mp4FormatIds::Mpeg4Video:
|
||||
case Mpeg:
|
||||
return GeneralMediaFormat::Mpeg1Video;
|
||||
case Mpeg2Imx30: case Mpeg2Imx50:
|
||||
return GeneralMediaFormat::Mpeg2Video;
|
||||
case Mpeg4Video:
|
||||
return GeneralMediaFormat::Mpeg4Video;
|
||||
case Mp4FormatIds::Avc1:
|
||||
case Mp4FormatIds::Avc2:
|
||||
case Mp4FormatIds::Avc3:
|
||||
case Mp4FormatIds::Avc4:
|
||||
case Avc1: case Avc2: case Avc3: case Avc4: case H264Decoder1: case H264Decoder2:
|
||||
case H264Decoder3: case H264Decoder4: case H264Decoder5: case H264Decoder6:
|
||||
return MediaFormat(GeneralMediaFormat::Mpeg4Video, SubFormats::Mpeg4Avc);
|
||||
case Mp4FormatIds::H263:
|
||||
case H263: case XvidDecoder1: case XvidDecoder2:
|
||||
case XvidDecoder3: case XvidDecoder4: case XvidDecoder5:
|
||||
case Divx5Decoder:
|
||||
return MediaFormat(GeneralMediaFormat::Mpeg4Video, SubFormats::Mpeg4Asp);
|
||||
case Mp4FormatIds::Tiff:
|
||||
case Divx4Decoder1: case Divx4Decoder2: case Divx4Decoder3:
|
||||
case Divx4Decoder4: case Divx4Decoder5: case Divx4Decoder6: case Divx4Decoder7:
|
||||
return MediaFormat(GeneralMediaFormat::Mpeg4Video, SubFormats::Mpeg4Sp);
|
||||
case Tiff:
|
||||
return GeneralMediaFormat::Tiff;
|
||||
case Mp4FormatIds::Raw:
|
||||
case AppleTextAtsuiCodec:
|
||||
return GeneralMediaFormat::TimedText;
|
||||
case Raw:
|
||||
return GeneralMediaFormat::UncompressedVideoFrames;
|
||||
case Mp4FormatIds::Jpeg:
|
||||
case Jpeg:
|
||||
return GeneralMediaFormat::Jpeg;
|
||||
case Mp4FormatIds::Gif:
|
||||
case Gif:
|
||||
return GeneralMediaFormat::Gif;
|
||||
case Mp4FormatIds::AdpcmAcm:
|
||||
case Png:
|
||||
return GeneralMediaFormat::Png;
|
||||
case AdpcmAcm:
|
||||
return GeneralMediaFormat::AdpcmAcm;
|
||||
case Mp4FormatIds::ImaadpcmAcm:
|
||||
case ImaadpcmAcm:
|
||||
return GeneralMediaFormat::ImaadpcmAcm;
|
||||
case Mp4FormatIds::Mp3CbrOnly:
|
||||
case Mp3CbrOnly: case Mp3:
|
||||
return MediaFormat(GeneralMediaFormat::Mpeg1Audio, SubFormats::Mpeg1Layer3);
|
||||
case Mp4FormatIds::Mpeg4Audio:
|
||||
case Mpeg4Audio:
|
||||
return GeneralMediaFormat::Aac;
|
||||
case Mp4FormatIds::Alac:
|
||||
case Alac:
|
||||
return GeneralMediaFormat::Alac;
|
||||
case Mp4FormatIds::Ac3:
|
||||
case Ac3:
|
||||
return GeneralMediaFormat::Ac3;
|
||||
case Mp4FormatIds::Ac4:
|
||||
case Ac4:
|
||||
return GeneralMediaFormat::Ac4;
|
||||
case Rv20: case Rv30: case Rv40:
|
||||
return GeneralMediaFormat::RealVideo;
|
||||
case Int24: case Int32:
|
||||
return MediaFormat(GeneralMediaFormat::Pcm);
|
||||
case Int16Be:
|
||||
return MediaFormat(GeneralMediaFormat::Pcm, SubFormats::PcmIntBe);
|
||||
case Int16Le:
|
||||
return MediaFormat(GeneralMediaFormat::Pcm, SubFormats::PcmIntLe);
|
||||
case FloatingPoint32Bit: case FloatingPoint64Bit:
|
||||
return MediaFormat(GeneralMediaFormat::Pcm, SubFormats::PcmFloatIeee);
|
||||
// TODO: map more FOURCCs
|
||||
default:
|
||||
return GeneralMediaFormat::Unknown;
|
||||
}
|
||||
|
@ -113,7 +135,7 @@ MediaFormat streamObjectTypeFormat(byte streamObjectTypeId)
|
|||
case ParameterSetsForAvc: return MediaFormat(GeneralMediaFormat::Mpeg4Video, SubFormats::Mpeg4AvcParams);
|
||||
case Als: return GeneralMediaFormat::Als;
|
||||
case Sa0c: return GeneralMediaFormat::Sa0c;
|
||||
case Aac: return GeneralMediaFormat::Aac;
|
||||
case Aac: return MediaFormat(GeneralMediaFormat::Aac, SubFormats::AacMpeg4LowComplexityProfile);
|
||||
case Mpeg2VideoSimpleProfile: return MediaFormat(GeneralMediaFormat::Mpeg4Video, SubFormats::Mpeg2SimpleProfile);
|
||||
case Mpeg2VideoMainProfile: return MediaFormat(GeneralMediaFormat::Mpeg4Video, SubFormats::Mpeg2SnrProfile);
|
||||
case Mpeg2VideoSnrProfile: return MediaFormat(GeneralMediaFormat::Mpeg4Video, SubFormats::Mpeg2SpatialProfile);
|
||||
|
|
257
mp4/mp4ids.h
257
mp4/mp4ids.h
|
@ -135,36 +135,259 @@ enum KnownValue : uint32 {
|
|||
};
|
||||
}
|
||||
|
||||
namespace Mp4FormatIds {
|
||||
namespace FourccIds {
|
||||
enum KnownValue : uint32 {
|
||||
Cinepak = 0x63766964, /**< Cinepak */
|
||||
Mpeg4Video = 0x6d703476, /**< MPEG-4 video */
|
||||
Graphics = 0x736D6320, /**< Graphics */
|
||||
Ac3 = 0x61632d33, /**< Dolby Digital */
|
||||
Ac4 = 0x61632d34, /**< ? */
|
||||
AdpcmAcm = 0x6D730002, /**< ? */
|
||||
Agsm = 0x6167736D,
|
||||
Alac = 0x616C6163, /**< Apple Losless Audio Codec */
|
||||
Alaw = 0x616C6177,
|
||||
Alaw21 = 0x616C6177,
|
||||
AlphaCompositor = 0x626C6E64,
|
||||
AlphaGain = 0x6761696E,
|
||||
AmrNarrowband = 0x73616D72,
|
||||
Animation = 0x726C6520, /**< Animation */
|
||||
Appl1 = 0x6476690,
|
||||
Appl2 = 0x6C70630,
|
||||
Apple16BitGray = 0x62313667,
|
||||
Apple32BitGrayWithAlpha = 0x62333261,
|
||||
Apple48BitRgb = 0x62343872,
|
||||
Apple64BitArgb1 = 0x62363461,
|
||||
Apple64BitArgb2 = 0x62617365,
|
||||
Apple64BitArgb3 = 0x626C6974,
|
||||
AppleAnimation = 0x726C6520,
|
||||
AppleAvrJpeg = 0x61767220,
|
||||
AppleBmp = 0x57524C45,
|
||||
AppleCinepak = 0x63766964,
|
||||
AppleCmyk = 0x636D796B,
|
||||
AppleComponentVideoYuv422 = 0x79757632,
|
||||
AppleCurve = 0x70617468,
|
||||
AppleDvc = 0x64766320,
|
||||
AppleDvcpro = 0x64767070,
|
||||
AppleDvcpro501 = 0x6476356E,
|
||||
AppleDvcpro502 = 0x64763570,
|
||||
AppleDvcpro50Ntsc = 0x6476356E,
|
||||
AppleDvcpro50Pal = 0x64763570,
|
||||
AppleDvcproPal = 0x64767070,
|
||||
AppleDvDvcproNtsc = 0x6476630,
|
||||
AppleDvp = 0x64766370,
|
||||
AppleDvPal = 0x64766370,
|
||||
AppleFlc = 0x666C6963,
|
||||
AppleGif = 0x67696620,
|
||||
AppleGraphics = 0x736D630,
|
||||
AppleGsm101 = 0x6167736D,
|
||||
AppleH261 = 0x68323631,
|
||||
AppleIntermediateCodec = 0x69636F64,
|
||||
AppleLossless = 0x616C6163,
|
||||
AppleMacpaint = 0x504E5447,
|
||||
AppleMicrosoftVideo1 = 0x6D737663,
|
||||
AppleMotionJpegA = 0x6D6A7061,
|
||||
AppleMotionJpegB = 0x6D6A7062,
|
||||
AppleMpeg4Compressor = 0x6D703476,
|
||||
AppleMpeg4Decompressor = 0x6D703476,
|
||||
AppleOpendmlJpeg = 0x646D6231,
|
||||
ApplePhotoCd = 0x6B706364,
|
||||
ApplePhotoJpeg = 0x6A706567,
|
||||
ApplePixletVideo = 0x70786C74,
|
||||
ApplePlanarRgb = 0x38425053,
|
||||
ApplePng = 0x706E670,
|
||||
AppleQuickdraw = 0x71647277,
|
||||
AppleR408 = 0x72343038,
|
||||
AppleScalingCodec = 0x7363616C,
|
||||
AppleSgi = 0x2E534749,
|
||||
AppleSorensonYuv9Codec = 0x73797639,
|
||||
AppleTextAtsuiCodec = 0x74657874,
|
||||
AppleTga = 0x7467610,
|
||||
AppleTiff = 0x74696666,
|
||||
AppleV408 = 0x76343038,
|
||||
AppleVcH263 = 0x68323633,
|
||||
AppleVideo = 0x72707A61, /**< Apple video */
|
||||
Png = 0x706E6720, /**< Portable Network Graphics */
|
||||
AppleYuv420Codec1 = 0x6A343230,
|
||||
AppleYuv420Codec2 = 0x6D797576,
|
||||
AppleYuv420Codec3 = 0x79343230,
|
||||
AppleYuv422Codec2Vuy = 0x32767579,
|
||||
AppleYuv422Codec4 = 0x79757678,
|
||||
AppleYuv422CodecYuvs = 0x79757673,
|
||||
AppleYuv422CodecYuvu = 0x79757675,
|
||||
Avc0Media = 0x64726D69,
|
||||
Avc1 = 0x61766331, /**< H.264/MPEG-4 AVC video */
|
||||
Avc2 = 0x61766332, /**< H.264/MPEG-4 AVC video */
|
||||
Avc3 = 0x61766333, /**< H.264/MPEG-4 AVC video */
|
||||
Avc4 = 0x61766334, /**< H.264/MPEG-4 AVC video */
|
||||
H263 = 0x68323633, /**< H.263/MPEG-4 ASP video */
|
||||
Tiff = 0x74696666, /**< Tagged Image File Format */
|
||||
Jpeg = 0x6a706567, /**< JPEG */
|
||||
Raw = 0x72617720, /**< Uncompressed RGB */
|
||||
Blur = 0x626C7572,
|
||||
Bps8 = 0x38627073,
|
||||
BrightnessAndContrast = 0x6272636F,
|
||||
ChannelCompositor = 0x6368616E,
|
||||
ChromaKey = 0x636B6579,
|
||||
Cinepak = 0x63766964, /**< Cinepak */
|
||||
Cloud = 0x636C6F75,
|
||||
ColorStyle = 0x736F6C72,
|
||||
Colorsync = 0x73796E63,
|
||||
ColorTint = 0x74696E74,
|
||||
CrossFade = 0x64736C76,
|
||||
Cvid = 0x63766964,
|
||||
Divx3Decoder1 = 0x41503431,
|
||||
Divx3Decoder10 = 0x636F6C30,
|
||||
Divx3Decoder11 = 0x636F6C31,
|
||||
Divx3Decoder12 = 0x64697633,
|
||||
Divx3Decoder13 = 0x64697634,
|
||||
Divx3Decoder14 = 0x64697635,
|
||||
Divx3Decoder15 = 0x64697636,
|
||||
Divx3Decoder16 = 0x6D703433,
|
||||
Divx3Decoder17 = 0x6D706733,
|
||||
Divx3Decoder2 = 0x434F4C30,
|
||||
Divx3Decoder3 = 0x434F4C31,
|
||||
Divx3Decoder4 = 0x44495633,
|
||||
Divx3Decoder5 = 0x44495634,
|
||||
Divx3Decoder6 = 0x44495635,
|
||||
Divx3Decoder7 = 0x44495636,
|
||||
Divx3Decoder8 = 0x4D503433,
|
||||
Divx3Decoder9 = 0x4D504733,
|
||||
Divx4Decoder1 = 0x44495658,
|
||||
Divx4Decoder2 = 0x4D345332,
|
||||
Divx4Decoder3 = 0x4D503453,
|
||||
Divx4Decoder4 = 0x554D5034,
|
||||
Divx4Decoder5 = 0x64697678,
|
||||
Divx4Decoder6 = 0x6D347332,
|
||||
Divx4Decoder7 = 0x6D703473,
|
||||
Divx5Decoder = 0x44583530,
|
||||
Drm = 0x64726D73,
|
||||
Dvca = 0x64766361,
|
||||
DvcPro501 = 0x64763570,
|
||||
DvcPro502 = 0x6476356E,
|
||||
DvcProPal = 0x64767070,
|
||||
EdgeDetection = 0x65646765,
|
||||
Emboss = 0x656D6273,
|
||||
Explode = 0x78706C6F,
|
||||
FilmNoise = 0x666D6E73,
|
||||
Fire = 0x66697265,
|
||||
FlashPixImage = 0x66706978,
|
||||
FlashScreenVideoDecoder = 0x46535631,
|
||||
FloatingPoint32Bit = 0x666C3332,
|
||||
FloatingPoint64Bit = 0x666C3634,
|
||||
GeneralConvolution = 0x67656E6B,
|
||||
Gif = 0x67696620, /**< CompuServe Graphics Interchange Format */
|
||||
NtscDv25Video = 0x64766320, /**< NTSC DV-25 video */
|
||||
PalDv25Video = 0x64766370, /**< PAL DV-25 video */
|
||||
Glass = 0x676C6173,
|
||||
GradientWipe = 0x6D617474,
|
||||
Graphics = 0x736D6320, /**< Graphics */
|
||||
H263 = 0x68323633, /**< H.263/MPEG-4 ASP video */
|
||||
H264Decoder1 = 0x44415643,
|
||||
H264Decoder2 = 0x48323634,
|
||||
H264Decoder3 = 0x56535348,
|
||||
H264Decoder4 = 0x58323634,
|
||||
H264Decoder5 = 0x68323634,
|
||||
H264Decoder6 = 0x78323634,
|
||||
Hdv3 = 0x68647633,
|
||||
HslBalance = 0x68736C62,
|
||||
Ima4 = 0x696D6134,
|
||||
Ima41 = 0x696D6134,
|
||||
ImaadpcmAcm = 0x6D730011, /**< ? */
|
||||
Implode = 0x6D706C6F,
|
||||
Int16Be = 0x74776F73,
|
||||
Int16Le = 0x736F7774,
|
||||
Int24 = 0x696E3234,
|
||||
Int32 = 0x696E3332,
|
||||
Iris = 0x736D7032,
|
||||
IvxDecoder1 = 0x33495632,
|
||||
IvxDecoder2 = 0x33495644,
|
||||
IvxDecoder3 = 0x33697632,
|
||||
IvxDecoder4 = 0x33697664,
|
||||
Jpeg = 0x6a706567, /**< JPEG */
|
||||
Jpeg2000Decoder = 0x6D6A7032,
|
||||
Law21 = 0x756C6177,
|
||||
LensFlare = 0x6C656E73,
|
||||
Lle = 0x726C6520,
|
||||
Mac3 = 0x6D616333,
|
||||
Mac6 = 0x6D616336,
|
||||
Mace31 = 0x4D414333,
|
||||
Mace61 = 0x4D414336,
|
||||
MatrixWipe = 0x736D7034,
|
||||
MotionJpegA = 0x6D6A7061, /**< Motion-JPEG (format A) */
|
||||
MotionJpegB = 0x6D6A7062, /**< Motion-JPEG (format B) */
|
||||
Mp3 = 0x2e6d7033, /**< MPEG-1 Layer 3 */
|
||||
Mp3CbrOnly = 0x6D730055, /**< MPEG-1 Layer 3 (constant bitrate only) */
|
||||
Mpeg = 0x4D504547,
|
||||
Mpeg2Imx30 = 0x6D78336E,
|
||||
Mpeg2Imx50 = 0x6D783570,
|
||||
Mpeg4Audio = 0x6d703461, /**< MPEG-4 audio */
|
||||
Mpeg4Decoder1 = 0x464D5034,
|
||||
Mpeg4Decoder2 = 0x53454447,
|
||||
Mpeg4Decoder3 = 0x57563146,
|
||||
Mpeg4Stream = 0x6d703473, /**< MPEG-4 stream (other then video/audio) */
|
||||
Alac = 0x616C6163, /**< Apple Losless Audio Codec */
|
||||
Ac3 = 0x61632d33, /**< Dolby Digital */
|
||||
Ac4 = 0x61632d34, /**< ? */
|
||||
AdpcmAcm = 0x6D730002, /**< ? */
|
||||
ImaadpcmAcm = 0x6D730011, /**< ? */
|
||||
Mp3CbrOnly = 0x6D730055 /**< MPEG-1 Layer 3 (constant bitrate only) */
|
||||
Mpeg4Video = 0x6d703476, /**< MPEG-4 video */
|
||||
MsMpeg4V1Decoder1 = 0x44495631,
|
||||
MsMpeg4V1Decoder2 = 0x4D504734,
|
||||
MsMpeg4V1Decoder3 = 0x64697631,
|
||||
MsMpeg4V1Decoder4 = 0x6D706734,
|
||||
MsMpeg4V2Decoder5 = 0x44495632,
|
||||
MsMpeg4V2Decoder6 = 0x4D503432,
|
||||
MsMpeg4V2Decoder7 = 0x64697632,
|
||||
MsMpeg4V2Decoder8 = 0x6D703432,
|
||||
NtscDv25Video = 0x64766320, /**< NTSC DV-25 video */
|
||||
Oggs = 0x4F676753,
|
||||
PalDv25Video = 0x64766370, /**< PAL DV-25 video */
|
||||
PdfImage = 0x70646620,
|
||||
Png = 0x706E6720, /**< Portable Network Graphics */
|
||||
Push = 0x70757368,
|
||||
Qclp = 0x51636C70,
|
||||
QdesignMusic1Decoder = 0x51444D43,
|
||||
QdesignMusic2 = 0x51444D32,
|
||||
Qdmc = 0x51444D43,
|
||||
Qdrw = 0x71647277,
|
||||
QtvrCubicCodec = 0x63757061,
|
||||
QtvrCylindricalCodec = 0x6C747061,
|
||||
QualcommPurevoice = 0x51636C70,
|
||||
QualcommQcelp = 0x51636C71,
|
||||
Radial = 0x736D7033,
|
||||
Raw = 0x72617720, /**< Uncompressed RGB */
|
||||
RgbBalance = 0x72676262,
|
||||
Ripple = 0x7269706C,
|
||||
Rpza = 0x72707A61,
|
||||
Rv20 = 0x52563230,
|
||||
Rv30 = 0x52563330,
|
||||
Rv40 = 0x52563430,
|
||||
Sharpen = 0x73687270,
|
||||
Slide = 0x736C6964,
|
||||
Smc = 0x736D6320,
|
||||
SorensonH263Decoder = 0x464C5631,
|
||||
SorensonVideo3Compressor = 0x53565133,
|
||||
SorensonVideoDecompressor = 0x53565131,
|
||||
Sowt = 0x736F7774,
|
||||
SpecialEffectsAndFilters = 0x67656666,
|
||||
Svq1 = 0x73767131,
|
||||
Svq3 = 0x73767133,
|
||||
Tiff = 0x74696666, /**< Tagged Image File Format */
|
||||
TravelingMatte = 0x74726176,
|
||||
TruemotionVp6Decoder1 = 0x56503632,
|
||||
TruemotionVp6Decoder2 = 0x56503646,
|
||||
Twos = 0x74776F73,
|
||||
Ulaw = 0x756C6177,
|
||||
Ulaw21 = 0x756C6177,
|
||||
VcmImageCodec = 0x4D6A7067,
|
||||
Vdva = 0x76647661,
|
||||
WindowsMediaAudio7 = 0x574D4131,
|
||||
WindowsMediaAudio9Professional = 0x574D4133,
|
||||
WindowsMediaAudio9Standard = 0x574D4132,
|
||||
Wipe = 0x736D7074,
|
||||
WmvImageCodec1 = 0x4D347332,
|
||||
WmvImageCodec2 = 0x4D703432,
|
||||
WmvImageCodec3 = 0x4D703433,
|
||||
WmvImageCodec4 = 0x4D703453,
|
||||
WmvImageCodec5 = 0x574D5631,
|
||||
WmvImageCodec6 = 0x574D5632,
|
||||
WmvImageCodec7 = 0x574D5633,
|
||||
XvidDecoder1 = 0x424C5A30,
|
||||
XvidDecoder2 = 0x58564944,
|
||||
XvidDecoder3 = 0x58564958,
|
||||
XvidDecoder4 = 0x58766944,
|
||||
XvidDecoder5 = 0x78766964,
|
||||
Yuv422HardwareAccelerationCodecYuvs1 = 0x32767579,
|
||||
Yuv422HardwareAccelerationCodecYuvs2 = 0x61633136,
|
||||
Yuv422HardwareAccelerationCodecYuvs3 = 0x61633332,
|
||||
Yuv422HardwareAccelerationCodecYuvs4 = 0x61634247,
|
||||
Yuv422HardwareAccelerationCodecYuvs5 = 0x79757673,
|
||||
Zoom = 0x7A6F6F6D
|
||||
};
|
||||
|
||||
LIB_EXPORT MediaFormat fourccToMediaFormat(uint32 fourccId);
|
||||
|
|
|
@ -79,30 +79,28 @@ void Mp4TagField::reparse(Mp4Atom &ilstChild)
|
|||
ilstChild.parse(); // ensure child has been parsed
|
||||
setId(ilstChild.id());
|
||||
context = "parsing MP4 tag field " + ilstChild.idToString();
|
||||
Mp4Atom *dataAtom = ilstChild.firstChild();
|
||||
iostream &stream = ilstChild.stream();
|
||||
BinaryReader &reader = ilstChild.container().reader();
|
||||
int dataAtomFound = 0;
|
||||
int meanAtomFound = 0;
|
||||
int nameAtomFound = 0;
|
||||
while(dataAtom) {
|
||||
int dataAtomFound = 0, meanAtomFound = 0, nameAtomFound = 0;
|
||||
for(Mp4Atom *dataAtom = ilstChild.firstChild(); dataAtom; dataAtom = dataAtom->nextSibling()) {
|
||||
try {
|
||||
dataAtom->parse();
|
||||
if((dataAtom->id() == Mp4AtomIds::Data) && (dataAtom->totalSize() > 16)) {
|
||||
++dataAtomFound;
|
||||
if(dataAtomFound > 1) {
|
||||
if(dataAtomFound == 2) {
|
||||
addNotification(NotificationType::Warning, "Tag atom contains more than one data atom. The addiational data atoms will be ignored.", context);
|
||||
}
|
||||
dataAtom = dataAtom->nextSibling();
|
||||
if(dataAtom->id() == Mp4AtomIds::Data) {
|
||||
if(dataAtom->dataSize() < 8) {
|
||||
addNotification(NotificationType::Warning, "Truncated child atom \"data\" in tag atom (ilst child) found. (will be ignored)", context);
|
||||
continue;
|
||||
}
|
||||
stream.seekg(dataAtom->startOffset() + 8);
|
||||
if(reader.readByte() != 0) {
|
||||
addNotification(NotificationType::Warning, "The version indicator byte is not zero, the tag atom might not be parsed correctly.", context);
|
||||
if(++dataAtomFound > 1) {
|
||||
if(dataAtomFound == 2) {
|
||||
addNotification(NotificationType::Warning, "Multiple \"data\" child atom in tag atom (ilst child) found. (will be ignored)", context);
|
||||
}
|
||||
m_parsedRawDataType = reader.readUInt24BE();
|
||||
setTypeInfo(m_parsedRawDataType);
|
||||
continue;
|
||||
}
|
||||
stream.seekg(dataAtom->dataOffset());
|
||||
if(reader.readByte() != 0) {
|
||||
addNotification(NotificationType::Warning, "The version indicator byte is not zero, the tag atom might be unsupported and hence not be parsed correctly.", context);
|
||||
}
|
||||
setTypeInfo(m_parsedRawDataType = reader.readUInt24BE());
|
||||
try { // try to show warning if parsed raw data type differs from expected raw data type for this atom id
|
||||
vector<uint32> expectedRawDataTypes = this->expectedRawDataTypes();
|
||||
if(find(expectedRawDataTypes.cbegin(), expectedRawDataTypes.cend(), m_parsedRawDataType) == expectedRawDataTypes.cend()) {
|
||||
|
@ -115,8 +113,8 @@ void Mp4TagField::reparse(Mp4Atom &ilstChild)
|
|||
m_langIndicator = reader.readUInt16BE();
|
||||
switch(m_parsedRawDataType) {
|
||||
case RawDataType::Utf8: case RawDataType::Utf16:
|
||||
stream.seekg(dataAtom->startOffset() + 16);
|
||||
value().assignText(reader.readString(dataAtom->totalSize() - 16), (m_parsedRawDataType == RawDataType::Utf16) ? TagTextEncoding::Utf16BigEndian : TagTextEncoding::Utf8);
|
||||
stream.seekg(dataAtom->dataOffset() + 8);
|
||||
value().assignText(reader.readString(dataAtom->dataSize() - 8), (m_parsedRawDataType == RawDataType::Utf16) ? TagTextEncoding::Utf16BigEndian : TagTextEncoding::Utf8);
|
||||
break;
|
||||
case RawDataType::Gif: case RawDataType::Jpeg: case RawDataType::Png: case RawDataType::Bmp: {
|
||||
switch(m_parsedRawDataType) {
|
||||
|
@ -135,21 +133,21 @@ void Mp4TagField::reparse(Mp4Atom &ilstChild)
|
|||
default:
|
||||
;
|
||||
}
|
||||
streamsize coverSize = dataAtom->totalSize() - 16;
|
||||
streamsize coverSize = dataAtom->dataSize() - 8;
|
||||
unique_ptr<char []> coverData = make_unique<char []>(coverSize);
|
||||
stream.read(coverData.get(), coverSize);
|
||||
value().assignData(move(coverData), coverSize, TagDataType::Picture);
|
||||
break;
|
||||
} case RawDataType::BeSignedInt: {
|
||||
int number = 0;
|
||||
if(dataAtom->totalSize() > (16 + 4)) {
|
||||
if(dataAtom->dataSize() > (8 + 4)) {
|
||||
addNotification(NotificationType::Warning, "Data atom stores integer of invalid size. Trying to read data anyways.", context);
|
||||
}
|
||||
if(dataAtom->totalSize() >= (16 + 4)) {
|
||||
if(dataAtom->dataSize() >= (8 + 4)) {
|
||||
number = reader.readInt32BE();
|
||||
} else if(dataAtom->totalSize() == (16 + 2)) {
|
||||
} else if(dataAtom->dataSize() == (8 + 2)) {
|
||||
number = reader.readInt16BE();
|
||||
} else if(dataAtom->totalSize() == (16 + 1)) {
|
||||
} else if(dataAtom->dataSize() == (8 + 1)) {
|
||||
number = reader.readChar();
|
||||
}
|
||||
switch(ilstChild.id()) {
|
||||
|
@ -162,14 +160,14 @@ void Mp4TagField::reparse(Mp4Atom &ilstChild)
|
|||
break;
|
||||
} case RawDataType::BeUnsignedInt: {
|
||||
int number = 0;
|
||||
if(dataAtom->totalSize() > (16 + 4)) {
|
||||
if(dataAtom->dataSize() > (8 + 4)) {
|
||||
addNotification(NotificationType::Warning, "Data atom stores integer of invalid size. Trying to read data anyways.", context);
|
||||
}
|
||||
if(dataAtom->totalSize() >= (16 + 4)) {
|
||||
if(dataAtom->dataSize() >= (8 + 4)) {
|
||||
number = static_cast<int>(reader.readUInt32BE());
|
||||
} else if(dataAtom->totalSize() == (16 + 2)) {
|
||||
} else if(dataAtom->dataSize() == (8 + 2)) {
|
||||
number = static_cast<int>(reader.readUInt16BE());
|
||||
} else if(dataAtom->totalSize() == (16 + 1)) {
|
||||
} else if(dataAtom->dataSize() == (8 + 1)) {
|
||||
number = static_cast<int>(reader.readByte());
|
||||
}
|
||||
switch(ilstChild.id()) {
|
||||
|
@ -185,29 +183,29 @@ void Mp4TagField::reparse(Mp4Atom &ilstChild)
|
|||
// track number, disk number and genre have no specific data type id
|
||||
case TrackPosition:
|
||||
case DiskPosition: {
|
||||
if(dataAtom->totalSize() < (16 + 6)) {
|
||||
if(dataAtom->dataSize() < (8 + 6)) {
|
||||
addNotification(NotificationType::Warning, "Track/disk position is truncated. Trying to read data anyways.", context);
|
||||
}
|
||||
uint16 pos = 0, total = 0;
|
||||
if(dataAtom->totalSize() >= (16 + 4)) {
|
||||
if(dataAtom->dataSize() >= (8 + 4)) {
|
||||
stream.seekg(2, ios_base::cur);
|
||||
pos = reader.readUInt16BE();
|
||||
}
|
||||
if(dataAtom->totalSize() >= (16 + 6)) {
|
||||
if(dataAtom->dataSize() >= (8 + 6)) {
|
||||
total = reader.readUInt16BE();
|
||||
}
|
||||
value().assignPosition(PositionInSet(pos, total));
|
||||
break;
|
||||
}
|
||||
case PreDefinedGenre:
|
||||
if(dataAtom->totalSize() < (16 + 2)) {
|
||||
if(dataAtom->dataSize() < (8 + 2)) {
|
||||
addNotification(NotificationType::Warning, "Genre index is truncated.", context);
|
||||
} else {
|
||||
value().assignStandardGenreIndex(reader.readUInt16BE() - 1);
|
||||
}
|
||||
break;
|
||||
default: // no supported data type, read raw data
|
||||
streamsize dataSize = dataAtom->totalSize() - 16;
|
||||
streamsize dataSize = dataAtom->dataSize() - 8;
|
||||
unique_ptr<char []> data = make_unique<char[]>(dataSize);
|
||||
stream.read(data.get(), dataSize);
|
||||
if(ilstChild.id() == Mp4TagAtomIds::Cover) {
|
||||
|
@ -217,31 +215,35 @@ void Mp4TagField::reparse(Mp4Atom &ilstChild)
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if((dataAtom->id() == Mp4AtomIds::Mean) && (dataAtom->totalSize() > 12)) {
|
||||
++meanAtomFound;
|
||||
if(meanAtomFound > 1) {
|
||||
if(meanAtomFound == 2)
|
||||
} else if(dataAtom->id() == Mp4AtomIds::Mean) {
|
||||
if(dataAtom->dataSize() < 8) {
|
||||
addNotification(NotificationType::Warning, "Truncated child atom \"mean\" in tag atom (ilst child) found. (will be ignored)", context);
|
||||
continue;
|
||||
}
|
||||
if(++meanAtomFound > 1) {
|
||||
if(meanAtomFound == 2) {
|
||||
addNotification(NotificationType::Warning, "Tag atom contains more than one mean atom. The addiational mean atoms will be ignored.", context);
|
||||
dataAtom = dataAtom->nextSibling();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
stream.seekg(dataAtom->startOffset() + 12);
|
||||
m_mean = reader.readString(dataAtom->totalSize() - 12);
|
||||
} else if((dataAtom->id() == Mp4AtomIds::Name) && (dataAtom->totalSize() > 12)) {
|
||||
++nameAtomFound;
|
||||
if(nameAtomFound > 1) {
|
||||
if(nameAtomFound == 2)
|
||||
stream.seekg(dataAtom->dataOffset() + 4);
|
||||
m_mean = reader.readString(dataAtom->dataSize() - 4);
|
||||
} else if(dataAtom->id() == Mp4AtomIds::Name) {
|
||||
if(dataAtom->dataSize() < 4) {
|
||||
addNotification(NotificationType::Warning, "Truncated child atom \"name\" in tag atom (ilst child) found. (will be ignored)", context);
|
||||
continue;
|
||||
}
|
||||
if(++nameAtomFound > 1) {
|
||||
if(nameAtomFound == 2) {
|
||||
addNotification(NotificationType::Warning, "Tag atom contains more than one name atom. The addiational name atoms will be ignored.", context);
|
||||
dataAtom = dataAtom->nextSibling();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
stream.seekg(dataAtom->startOffset() + 12);
|
||||
m_name = reader.readString(dataAtom->totalSize() - 12);
|
||||
stream.seekg(dataAtom->dataOffset() + 4);
|
||||
m_name = reader.readString(dataAtom->dataSize() - 4);
|
||||
} else {
|
||||
addNotification(NotificationType::Warning, "Unkown child atom \"" + dataAtom->idToString() + "\" in tag atom (ilst child) found. (will be ignored)", context);
|
||||
}
|
||||
|
||||
dataAtom = dataAtom->nextSibling();
|
||||
} catch(Failure &) {
|
||||
addNotification(NotificationType::Warning, "Unable to parse all childs atom in tag atom (ilst child) found. (will be ignored)", context);
|
||||
}
|
||||
|
|
|
@ -1050,7 +1050,7 @@ void Mp4Track::makeSampleTable()
|
|||
|
||||
void Mp4Track::internalParseHeader()
|
||||
{
|
||||
const string context("parsing MP4 track");
|
||||
static const string context("parsing MP4 track");
|
||||
using namespace Mp4AtomIds;
|
||||
if(!m_trakAtom) {
|
||||
addNotification(NotificationType::Critical, "Trak atom is null.", context);
|
||||
|
@ -1058,59 +1058,43 @@ void Mp4Track::internalParseHeader()
|
|||
}
|
||||
// get atoms
|
||||
try {
|
||||
m_tkhdAtom = m_trakAtom->childById(TrackHeader);
|
||||
if(!m_tkhdAtom) {
|
||||
if(!(m_tkhdAtom = m_trakAtom->childById(TrackHeader))) {
|
||||
addNotification(NotificationType::Critical, "No tkhd atom found.", context);
|
||||
throw InvalidDataException();
|
||||
}
|
||||
m_mdiaAtom = m_trakAtom->childById(Media);
|
||||
if(!m_mdiaAtom) {
|
||||
if(!(m_mdiaAtom = m_trakAtom->childById(Media))) {
|
||||
addNotification(NotificationType::Critical, "No mdia atom found.", context);
|
||||
throw InvalidDataException();
|
||||
}
|
||||
m_mdhdAtom = m_mdiaAtom->childById(MediaHeader);
|
||||
if(!m_mdhdAtom) {
|
||||
if(!(m_mdhdAtom = m_mdiaAtom->childById(MediaHeader))) {
|
||||
addNotification(NotificationType::Critical, "No mdhd atom found.", context);
|
||||
throw InvalidDataException();
|
||||
}
|
||||
m_hdlrAtom = m_mdiaAtom->childById(HandlerReference);
|
||||
if(!m_hdlrAtom) {
|
||||
if(!(m_hdlrAtom = m_mdiaAtom->childById(HandlerReference))) {
|
||||
addNotification(NotificationType::Critical, "No hdlr atom found.", context);
|
||||
throw InvalidDataException();
|
||||
}
|
||||
m_minfAtom = m_mdiaAtom->childById(MediaInformation);
|
||||
if(!m_minfAtom) {
|
||||
if(!(m_minfAtom = m_mdiaAtom->childById(MediaInformation))) {
|
||||
addNotification(NotificationType::Critical, "No minf atom found.", context);
|
||||
throw InvalidDataException();
|
||||
}
|
||||
m_stblAtom = m_minfAtom->childById(SampleTable);
|
||||
if(!m_stblAtom) {
|
||||
if(!(m_stblAtom = m_minfAtom->childById(SampleTable))) {
|
||||
addNotification(NotificationType::Critical, "No stbl atom found.", context);
|
||||
throw InvalidDataException();
|
||||
}
|
||||
m_stsdAtom = m_stblAtom->childById(SampleDescription);
|
||||
if(!m_stsdAtom) {
|
||||
if(!(m_stsdAtom = m_stblAtom->childById(SampleDescription))) {
|
||||
addNotification(NotificationType::Critical, "No stsd atom found.", context);
|
||||
throw InvalidDataException();
|
||||
}
|
||||
m_stcoAtom = m_stblAtom->childById(ChunkOffset);
|
||||
if(!m_stcoAtom) {
|
||||
m_stblAtom->childById(ChunkOffset64);
|
||||
}
|
||||
if(!m_stcoAtom) {
|
||||
if(!(m_stcoAtom = m_stblAtom->childById(ChunkOffset)) && !(m_stcoAtom = m_stblAtom->childById(ChunkOffset64))) {
|
||||
addNotification(NotificationType::Critical, "No stco/co64 atom found.", context);
|
||||
throw InvalidDataException();
|
||||
}
|
||||
m_stscAtom = m_stblAtom->childById(SampleToChunk);
|
||||
if(!m_stscAtom) {
|
||||
if(!(m_stscAtom = m_stblAtom->childById(SampleToChunk))) {
|
||||
addNotification(NotificationType::Critical, "No stsc atom found.", context);
|
||||
throw InvalidDataException();
|
||||
}
|
||||
m_stszAtom = m_stblAtom->childById(SampleSize);
|
||||
if(!m_stszAtom) {
|
||||
m_stszAtom = m_stblAtom->childById(CompactSampleSize);
|
||||
}
|
||||
if(!m_stszAtom) {
|
||||
if(!(m_stszAtom = m_stblAtom->childById(SampleSize)) && !(m_stszAtom = m_stblAtom->childById(CompactSampleSize))) {
|
||||
addNotification(NotificationType::Critical, "No stsz/stz2 atom found.", context);
|
||||
throw InvalidDataException();
|
||||
}
|
||||
|
@ -1206,7 +1190,7 @@ void Mp4Track::internalParseHeader()
|
|||
codecConfigContainerAtom->parse();
|
||||
// parse FOURCC
|
||||
m_formatId = interpretIntegerAsString<uint32>(codecConfigContainerAtom->id());
|
||||
m_format = Mp4FormatIds::fourccToMediaFormat(codecConfigContainerAtom->id());
|
||||
m_format = FourccIds::fourccToMediaFormat(codecConfigContainerAtom->id());
|
||||
// parse AVC configuration
|
||||
//codecConfigContainerAtom->childById(Mp4AtomIds::AvcConfiguration);
|
||||
// parse MPEG-4 elementary stream descriptor
|
||||
|
|
|
@ -69,7 +69,6 @@ SOURCES += \
|
|||
mediaformat.cpp \
|
||||
avc/avcconfiguration.cpp \
|
||||
mp4/mpeg4descriptor.cpp \
|
||||
avi/mediafourcc.cpp \
|
||||
avi/bitmapinfoheader.cpp
|
||||
|
||||
HEADERS += \
|
||||
|
@ -137,7 +136,6 @@ HEADERS += \
|
|||
avc/avcconfiguration.h \
|
||||
generictagfield.h \
|
||||
mp4/mpeg4descriptor.h \
|
||||
avi/mediafourcc.h \
|
||||
avi/bitmapinfoheader.h
|
||||
|
||||
LIBS += -lz
|
||||
|
@ -163,7 +161,7 @@ INCLUDEPATH += ../
|
|||
# installs
|
||||
target.path = $$(INSTALL_ROOT)/lib
|
||||
INSTALLS += target
|
||||
for(dir, $$list(./ avc id3 matroska mp4 mpegaudio ogg vorbis wav)) {
|
||||
for(dir, $$list(./ avc id3 matroska mp4 mpegaudio ogg vorbis wav avi)) {
|
||||
eval(inc_$${dir} = $${dir})
|
||||
inc_$${dir}.path = $$(INSTALL_ROOT)/include/$$projectname/$${dir}
|
||||
inc_$${dir}.files = $${dir}/*.h
|
||||
|
|
|
@ -3,10 +3,56 @@
|
|||
#include "../exceptions.h"
|
||||
#include "../mediaformat.h"
|
||||
|
||||
#include <c++utilities/io/binaryreader.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace Media {
|
||||
|
||||
/*!
|
||||
* \class Media::WaveFormatHeader
|
||||
* \brief The WaveFormatHeader class parses the WAVEFORMATEX structure defined by MS.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \brief Constructs a new WaveFormatHeader.
|
||||
*/
|
||||
WaveFormatHeader::WaveFormatHeader() :
|
||||
formatTag(0),
|
||||
channelCount(0),
|
||||
sampleRate(0),
|
||||
bytesPerSecond(0),
|
||||
chunkSize(0),
|
||||
bitsPerSample(0)
|
||||
{}
|
||||
|
||||
/*!
|
||||
* \brief Parses the WAVE header using the specified \a reader.
|
||||
* \remarks Reads 16 bytes from the associated stream.
|
||||
*/
|
||||
void WaveFormatHeader::parse(IoUtilities::BinaryReader &reader)
|
||||
{
|
||||
formatTag = reader.readUInt16LE();
|
||||
channelCount = reader.readUInt16LE();
|
||||
sampleRate = reader.readUInt32LE();
|
||||
bytesPerSecond = reader.readUInt32LE();
|
||||
chunkSize = reader.readUInt16LE();
|
||||
bitsPerSample = reader.readUInt16LE();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the media format denoted by the format tag.
|
||||
*/
|
||||
MediaFormat WaveFormatHeader::format() const
|
||||
{
|
||||
switch(formatTag) {
|
||||
case 0x0001u: return GeneralMediaFormat::Pcm;
|
||||
case 0x0050u: return MediaFormat(GeneralMediaFormat::Mpeg1Audio, SubFormats::Mpeg1Layer2);
|
||||
case 0x0055u: return MediaFormat(GeneralMediaFormat::Mpeg1Audio, SubFormats::Mpeg1Layer3);
|
||||
default: return GeneralMediaFormat::Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \class Media::WaveAudioStream
|
||||
* \brief Implementation of Media::AbstractTrack for the
|
||||
|
@ -33,6 +79,20 @@ TrackType WaveAudioStream::type() const
|
|||
return TrackType::WaveAudioStream;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Adds the information from the specified \a waveHeader to the specified \a track.
|
||||
*/
|
||||
void WaveAudioStream::addInfo(const WaveFormatHeader &waveHeader, AbstractTrack &track)
|
||||
{
|
||||
track.m_format = waveHeader.format();
|
||||
track.m_channelCount = waveHeader.channelCount;
|
||||
track.m_sampleRate = waveHeader.sampleRate;
|
||||
track.m_bytesPerSecond = waveHeader.bytesPerSecond;
|
||||
track.m_chunkSize = waveHeader.chunkSize;
|
||||
track.m_bitsPerSample = waveHeader.bitsPerSample;
|
||||
track.m_bitrate = waveHeader.bitrate();
|
||||
}
|
||||
|
||||
void WaveAudioStream::internalParseHeader()
|
||||
{
|
||||
if(!m_istream) {
|
||||
|
@ -44,27 +104,9 @@ void WaveAudioStream::internalParseHeader()
|
|||
uint32 restHeaderLen = m_reader.readUInt32LE();
|
||||
m_dataOffset = static_cast<uint64>(m_istream->tellg()) + static_cast<uint64>(restHeaderLen);
|
||||
if(restHeaderLen >= 16u) {
|
||||
switch(m_reader.readUInt16LE()) {
|
||||
case 0x0001u:
|
||||
m_format = GeneralMediaFormat::Pcm;
|
||||
break;
|
||||
case 0x0050u:
|
||||
m_format = MediaFormat(GeneralMediaFormat::Mpeg1Audio, SubFormats::Mpeg1Layer2);
|
||||
break;
|
||||
case 0x0055u:
|
||||
m_format = MediaFormat(GeneralMediaFormat::Mpeg1Audio, SubFormats::Mpeg1Layer3);
|
||||
break;
|
||||
default:
|
||||
m_format = GeneralMediaFormat::Unknown;
|
||||
}
|
||||
m_channelCount = m_reader.readUInt16LE();
|
||||
m_sampleRate = m_reader.readUInt32LE();
|
||||
m_bytesPerSecond = m_reader.readUInt32LE();
|
||||
m_chunkSize = m_reader.readUInt16LE();
|
||||
m_bitsPerSample = m_reader.readUInt16LE();
|
||||
m_bitrate = m_bitsPerSample * m_sampleRate * m_channelCount;
|
||||
} else {
|
||||
m_format = GeneralMediaFormat::Unknown;
|
||||
WaveFormatHeader waveHeader;
|
||||
waveHeader.parse(m_reader);
|
||||
addInfo(waveHeader, *this);
|
||||
}
|
||||
if(restHeaderLen > 16u) {
|
||||
m_istream->seekg(m_dataOffset, ios_base::beg);
|
||||
|
|
|
@ -3,13 +3,36 @@
|
|||
|
||||
#include "../abstracttrack.h"
|
||||
|
||||
#include <c++utilities/io/binaryreader.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
namespace Media
|
||||
{
|
||||
|
||||
class LIB_EXPORT WaveFormatHeader
|
||||
{
|
||||
public:
|
||||
WaveFormatHeader();
|
||||
|
||||
void parse(IoUtilities::BinaryReader &reader);
|
||||
MediaFormat format() const;
|
||||
uint32 bitrate() const;
|
||||
|
||||
uint16 formatTag;
|
||||
uint16 channelCount;
|
||||
uint16 sampleRate;
|
||||
uint16 bytesPerSecond;
|
||||
uint16 chunkSize;
|
||||
uint16 bitsPerSample;
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Calculates the bitrate from the header data.
|
||||
*/
|
||||
inline uint32 WaveFormatHeader::bitrate() const
|
||||
{
|
||||
return bitsPerSample * sampleRate * channelCount;
|
||||
}
|
||||
|
||||
class LIB_EXPORT WaveAudioStream : public AbstractTrack
|
||||
{
|
||||
public:
|
||||
|
@ -18,6 +41,8 @@ public:
|
|||
|
||||
virtual TrackType type() const;
|
||||
|
||||
static void addInfo(const WaveFormatHeader &waveHeader, AbstractTrack &track);
|
||||
|
||||
protected:
|
||||
virtual void internalParseHeader();
|
||||
|
||||
|
|
Loading…
Reference in New Issue