Updated VGMStream with FFmpeg support, and moved the supported formats over to that plug-in.
This commit is contained in:
parent
96576da089
commit
ff46687597
13 changed files with 928 additions and 10 deletions
|
@ -328,6 +328,21 @@
|
||||||
836F705718BDC2190095E648 /* util.h in Headers */ = {isa = PBXBuildFile; fileRef = 836F6F1B18BDC2190095E648 /* util.h */; };
|
836F705718BDC2190095E648 /* util.h in Headers */ = {isa = PBXBuildFile; fileRef = 836F6F1B18BDC2190095E648 /* util.h */; };
|
||||||
836F705818BDC2190095E648 /* vgmstream.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F1C18BDC2190095E648 /* vgmstream.c */; };
|
836F705818BDC2190095E648 /* vgmstream.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F1C18BDC2190095E648 /* vgmstream.c */; };
|
||||||
836F705918BDC2190095E648 /* vgmstream.h in Headers */ = {isa = PBXBuildFile; fileRef = 836F6F1D18BDC2190095E648 /* vgmstream.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
836F705918BDC2190095E648 /* vgmstream.h in Headers */ = {isa = PBXBuildFile; fileRef = 836F6F1D18BDC2190095E648 /* vgmstream.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
|
838BDB641D3AF08C0022CA6F /* libavcodec.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 838BDB611D3AF08C0022CA6F /* libavcodec.a */; };
|
||||||
|
838BDB651D3AF08C0022CA6F /* libavformat.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 838BDB621D3AF08C0022CA6F /* libavformat.a */; };
|
||||||
|
838BDB661D3AF08C0022CA6F /* libavutil.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 838BDB631D3AF08C0022CA6F /* libavutil.a */; };
|
||||||
|
838BDB681D3AF70D0022CA6F /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 838BDB671D3AF70D0022CA6F /* libz.tbd */; };
|
||||||
|
838BDB6A1D3AF7140022CA6F /* libiconv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 838BDB691D3AF7140022CA6F /* libiconv.tbd */; };
|
||||||
|
838BDB6C1D3AFAB10022CA6F /* ffmpeg_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 838BDB6B1D3AFAB10022CA6F /* ffmpeg_decoder.c */; };
|
||||||
|
838BDB6E1D3B043C0022CA6F /* ffmpeg.c in Sources */ = {isa = PBXBuildFile; fileRef = 838BDB6D1D3B043C0022CA6F /* ffmpeg.c */; };
|
||||||
|
838BDB711D3B1F990022CA6F /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 838BDB701D3B1F990022CA6F /* CoreFoundation.framework */; };
|
||||||
|
838BDB731D3B1FA50022CA6F /* VideoDecodeAcceleration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 838BDB721D3B1FA50022CA6F /* VideoDecodeAcceleration.framework */; };
|
||||||
|
838BDB751D3B1FAD0022CA6F /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 838BDB741D3B1FAD0022CA6F /* QuartzCore.framework */; };
|
||||||
|
838BDB771D3B1FB60022CA6F /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 838BDB761D3B1FB60022CA6F /* Security.framework */; };
|
||||||
|
838BDB791D3B1FBE0022CA6F /* VideoToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 838BDB781D3B1FBE0022CA6F /* VideoToolbox.framework */; };
|
||||||
|
838BDB7B1D3B1FC20022CA6F /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 838BDB7A1D3B1FC20022CA6F /* CoreMedia.framework */; };
|
||||||
|
838BDB7D1D3B1FCC0022CA6F /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 838BDB7C1D3B1FCC0022CA6F /* CoreVideo.framework */; };
|
||||||
|
838BDB7F1D3B1FD10022CA6F /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 838BDB7E1D3B1FD10022CA6F /* Cocoa.framework */; };
|
||||||
83A5F75F198DF021009AF94C /* bfwav.c in Sources */ = {isa = PBXBuildFile; fileRef = 83A5F75E198DF021009AF94C /* bfwav.c */; };
|
83A5F75F198DF021009AF94C /* bfwav.c in Sources */ = {isa = PBXBuildFile; fileRef = 83A5F75E198DF021009AF94C /* bfwav.c */; };
|
||||||
83BAFB6C19F45EB3005DAB60 /* bfstm.c in Sources */ = {isa = PBXBuildFile; fileRef = 83BAFB6B19F45EB3005DAB60 /* bfstm.c */; };
|
83BAFB6C19F45EB3005DAB60 /* bfstm.c in Sources */ = {isa = PBXBuildFile; fileRef = 83BAFB6B19F45EB3005DAB60 /* bfstm.c */; };
|
||||||
83D731101A7394BF00CA1366 /* g7221.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83D730EB1A738EB300CA1366 /* g7221.framework */; };
|
83D731101A7394BF00CA1366 /* g7221.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83D730EB1A738EB300CA1366 /* g7221.framework */; };
|
||||||
|
@ -770,6 +785,21 @@
|
||||||
836F6F1B18BDC2190095E648 /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = "<group>"; };
|
836F6F1B18BDC2190095E648 /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = "<group>"; };
|
||||||
836F6F1C18BDC2190095E648 /* vgmstream.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vgmstream.c; sourceTree = "<group>"; };
|
836F6F1C18BDC2190095E648 /* vgmstream.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vgmstream.c; sourceTree = "<group>"; };
|
||||||
836F6F1D18BDC2190095E648 /* vgmstream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vgmstream.h; sourceTree = "<group>"; };
|
836F6F1D18BDC2190095E648 /* vgmstream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vgmstream.h; sourceTree = "<group>"; };
|
||||||
|
838BDB611D3AF08C0022CA6F /* libavcodec.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavcodec.a; path = ../../ThirdParty/ffmpeg/lib/libavcodec.a; sourceTree = "<group>"; };
|
||||||
|
838BDB621D3AF08C0022CA6F /* libavformat.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavformat.a; path = ../../ThirdParty/ffmpeg/lib/libavformat.a; sourceTree = "<group>"; };
|
||||||
|
838BDB631D3AF08C0022CA6F /* libavutil.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libavutil.a; path = ../../ThirdParty/ffmpeg/lib/libavutil.a; sourceTree = "<group>"; };
|
||||||
|
838BDB671D3AF70D0022CA6F /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
|
||||||
|
838BDB691D3AF7140022CA6F /* libiconv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libiconv.tbd; path = usr/lib/libiconv.tbd; sourceTree = SDKROOT; };
|
||||||
|
838BDB6B1D3AFAB10022CA6F /* ffmpeg_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffmpeg_decoder.c; sourceTree = "<group>"; };
|
||||||
|
838BDB6D1D3B043C0022CA6F /* ffmpeg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffmpeg.c; sourceTree = "<group>"; };
|
||||||
|
838BDB701D3B1F990022CA6F /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
|
||||||
|
838BDB721D3B1FA50022CA6F /* VideoDecodeAcceleration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = VideoDecodeAcceleration.framework; path = System/Library/Frameworks/VideoDecodeAcceleration.framework; sourceTree = SDKROOT; };
|
||||||
|
838BDB741D3B1FAD0022CA6F /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
||||||
|
838BDB761D3B1FB60022CA6F /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
|
||||||
|
838BDB781D3B1FBE0022CA6F /* VideoToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = VideoToolbox.framework; path = System/Library/Frameworks/VideoToolbox.framework; sourceTree = SDKROOT; };
|
||||||
|
838BDB7A1D3B1FC20022CA6F /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; };
|
||||||
|
838BDB7C1D3B1FCC0022CA6F /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; };
|
||||||
|
838BDB7E1D3B1FD10022CA6F /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
||||||
83A5F75E198DF021009AF94C /* bfwav.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bfwav.c; sourceTree = "<group>"; };
|
83A5F75E198DF021009AF94C /* bfwav.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bfwav.c; sourceTree = "<group>"; };
|
||||||
83BAFB6B19F45EB3005DAB60 /* bfstm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bfstm.c; sourceTree = "<group>"; };
|
83BAFB6B19F45EB3005DAB60 /* bfstm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bfstm.c; sourceTree = "<group>"; };
|
||||||
83D730E51A738EB200CA1366 /* g7221.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = g7221.xcodeproj; path = ../g7221/g7221.xcodeproj; sourceTree = "<group>"; };
|
83D730E51A738EB200CA1366 /* g7221.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = g7221.xcodeproj; path = ../g7221/g7221.xcodeproj; sourceTree = "<group>"; };
|
||||||
|
@ -785,8 +815,21 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
838BDB7F1D3B1FD10022CA6F /* Cocoa.framework in Frameworks */,
|
||||||
|
838BDB7D1D3B1FCC0022CA6F /* CoreVideo.framework in Frameworks */,
|
||||||
|
838BDB7B1D3B1FC20022CA6F /* CoreMedia.framework in Frameworks */,
|
||||||
|
838BDB791D3B1FBE0022CA6F /* VideoToolbox.framework in Frameworks */,
|
||||||
|
838BDB771D3B1FB60022CA6F /* Security.framework in Frameworks */,
|
||||||
|
838BDB751D3B1FAD0022CA6F /* QuartzCore.framework in Frameworks */,
|
||||||
|
838BDB731D3B1FA50022CA6F /* VideoDecodeAcceleration.framework in Frameworks */,
|
||||||
|
838BDB711D3B1F990022CA6F /* CoreFoundation.framework in Frameworks */,
|
||||||
|
838BDB6A1D3AF7140022CA6F /* libiconv.tbd in Frameworks */,
|
||||||
|
838BDB681D3AF70D0022CA6F /* libz.tbd in Frameworks */,
|
||||||
83D731891A749D1500CA1366 /* g719.framework in Frameworks */,
|
83D731891A749D1500CA1366 /* g719.framework in Frameworks */,
|
||||||
83D731101A7394BF00CA1366 /* g7221.framework in Frameworks */,
|
83D731101A7394BF00CA1366 /* g7221.framework in Frameworks */,
|
||||||
|
838BDB641D3AF08C0022CA6F /* libavcodec.a in Frameworks */,
|
||||||
|
838BDB651D3AF08C0022CA6F /* libavformat.a in Frameworks */,
|
||||||
|
838BDB661D3AF08C0022CA6F /* libavutil.a in Frameworks */,
|
||||||
8313E3E61902020400B4B6F1 /* mpg123.framework in Frameworks */,
|
8313E3E61902020400B4B6F1 /* mpg123.framework in Frameworks */,
|
||||||
830F885C19C9124C00420FB0 /* Vorbis.framework in Frameworks */,
|
830F885C19C9124C00420FB0 /* Vorbis.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
|
@ -844,6 +887,16 @@
|
||||||
836F6B3B18BDB8880095E648 /* Frameworks */ = {
|
836F6B3B18BDB8880095E648 /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
838BDB7E1D3B1FD10022CA6F /* Cocoa.framework */,
|
||||||
|
838BDB7C1D3B1FCC0022CA6F /* CoreVideo.framework */,
|
||||||
|
838BDB7A1D3B1FC20022CA6F /* CoreMedia.framework */,
|
||||||
|
838BDB781D3B1FBE0022CA6F /* VideoToolbox.framework */,
|
||||||
|
838BDB761D3B1FB60022CA6F /* Security.framework */,
|
||||||
|
838BDB741D3B1FAD0022CA6F /* QuartzCore.framework */,
|
||||||
|
838BDB721D3B1FA50022CA6F /* VideoDecodeAcceleration.framework */,
|
||||||
|
838BDB701D3B1F990022CA6F /* CoreFoundation.framework */,
|
||||||
|
838BDB691D3AF7140022CA6F /* libiconv.tbd */,
|
||||||
|
838BDB671D3AF70D0022CA6F /* libz.tbd */,
|
||||||
836F6B3E18BDB8880095E648 /* Other Frameworks */,
|
836F6B3E18BDB8880095E648 /* Other Frameworks */,
|
||||||
);
|
);
|
||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
|
@ -852,6 +905,9 @@
|
||||||
836F6B3E18BDB8880095E648 /* Other Frameworks */ = {
|
836F6B3E18BDB8880095E648 /* Other Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
838BDB611D3AF08C0022CA6F /* libavcodec.a */,
|
||||||
|
838BDB621D3AF08C0022CA6F /* libavformat.a */,
|
||||||
|
838BDB631D3AF08C0022CA6F /* libavutil.a */,
|
||||||
8315231718BDECA1009AE289 /* VorbisNoDot.xcodeproj */,
|
8315231718BDECA1009AE289 /* VorbisNoDot.xcodeproj */,
|
||||||
8313E33D1901FBDC00B4B6F1 /* mpg123.xcodeproj */,
|
8313E33D1901FBDC00B4B6F1 /* mpg123.xcodeproj */,
|
||||||
83D730E51A738EB200CA1366 /* g7221.xcodeproj */,
|
83D730E51A738EB200CA1366 /* g7221.xcodeproj */,
|
||||||
|
@ -899,6 +955,7 @@
|
||||||
836F6DDF18BDC2180095E648 /* coding */ = {
|
836F6DDF18BDC2180095E648 /* coding */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
838BDB6B1D3AFAB10022CA6F /* ffmpeg_decoder.c */,
|
||||||
832389511D224C0800482226 /* hca_decoder.c */,
|
832389511D224C0800482226 /* hca_decoder.c */,
|
||||||
83D7318B1A749EEE00CA1366 /* g719_decoder.c */,
|
83D7318B1A749EEE00CA1366 /* g719_decoder.c */,
|
||||||
836F6DE018BDC2180095E648 /* acm_decoder.c */,
|
836F6DE018BDC2180095E648 /* acm_decoder.c */,
|
||||||
|
@ -980,6 +1037,7 @@
|
||||||
836F6E2718BDC2180095E648 /* meta */ = {
|
836F6E2718BDC2180095E648 /* meta */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
838BDB6D1D3B043C0022CA6F /* ffmpeg.c */,
|
||||||
8323894F1D2246C300482226 /* hca.c */,
|
8323894F1D2246C300482226 /* hca.c */,
|
||||||
83EDE5D61A70951A005F5D84 /* mca.c */,
|
83EDE5D61A70951A005F5D84 /* mca.c */,
|
||||||
83EDE5D71A70951A005F5D84 /* btsnd.c */,
|
83EDE5D71A70951A005F5D84 /* btsnd.c */,
|
||||||
|
@ -1605,6 +1663,7 @@
|
||||||
836F6F4A18BDC2190095E648 /* interleave.c in Sources */,
|
836F6F4A18BDC2190095E648 /* interleave.c in Sources */,
|
||||||
836F6FFD18BDC2190095E648 /* ps2_stm.c in Sources */,
|
836F6FFD18BDC2190095E648 /* ps2_stm.c in Sources */,
|
||||||
83EDE5D81A70951A005F5D84 /* mca.c in Sources */,
|
83EDE5D81A70951A005F5D84 /* mca.c in Sources */,
|
||||||
|
838BDB6C1D3AFAB10022CA6F /* ffmpeg_decoder.c in Sources */,
|
||||||
836F6FA518BDC2190095E648 /* nds_rrds.c in Sources */,
|
836F6FA518BDC2190095E648 /* nds_rrds.c in Sources */,
|
||||||
836F702F18BDC2190095E648 /* spt_spd.c in Sources */,
|
836F702F18BDC2190095E648 /* spt_spd.c in Sources */,
|
||||||
836F704618BDC2190095E648 /* x360_tra.c in Sources */,
|
836F704618BDC2190095E648 /* x360_tra.c in Sources */,
|
||||||
|
@ -1697,6 +1756,7 @@
|
||||||
836F6F4118BDC2190095E648 /* blocked.c in Sources */,
|
836F6F4118BDC2190095E648 /* blocked.c in Sources */,
|
||||||
836F6F3B18BDC2190095E648 /* ws_decoder.c in Sources */,
|
836F6F3B18BDC2190095E648 /* ws_decoder.c in Sources */,
|
||||||
836F6F4518BDC2190095E648 /* emff_blocked.c in Sources */,
|
836F6F4518BDC2190095E648 /* emff_blocked.c in Sources */,
|
||||||
|
838BDB6E1D3B043C0022CA6F /* ffmpeg.c in Sources */,
|
||||||
836F6F5D18BDC2190095E648 /* xa_blocked.c in Sources */,
|
836F6F5D18BDC2190095E648 /* xa_blocked.c in Sources */,
|
||||||
836F6F3418BDC2190095E648 /* nwa_decoder.c in Sources */,
|
836F6F3418BDC2190095E648 /* nwa_decoder.c in Sources */,
|
||||||
836F6F6918BDC2190095E648 /* adx_header.c in Sources */,
|
836F6F6918BDC2190095E648 /* adx_header.c in Sources */,
|
||||||
|
@ -1790,8 +1850,12 @@
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
HEADER_SEARCH_PATHS = "$(SRCROOT)/vgmstream/ext_libs";
|
HEADER_SEARCH_PATHS = (
|
||||||
|
"$(SRCROOT)/vgmstream/ext_libs",
|
||||||
|
../../ThirdParty/ffmpeg/include,
|
||||||
|
);
|
||||||
INSTALL_PATH = "@loader_path/../Frameworks";
|
INSTALL_PATH = "@loader_path/../Frameworks";
|
||||||
|
LIBRARY_SEARCH_PATHS = ../../ThirdParty/ffmpeg/lib;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
|
@ -1830,8 +1894,12 @@
|
||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
HEADER_SEARCH_PATHS = "$(SRCROOT)/vgmstream/ext_libs";
|
HEADER_SEARCH_PATHS = (
|
||||||
|
"$(SRCROOT)/vgmstream/ext_libs",
|
||||||
|
../../ThirdParty/ffmpeg/include,
|
||||||
|
);
|
||||||
INSTALL_PATH = "@loader_path/../Frameworks";
|
INSTALL_PATH = "@loader_path/../Frameworks";
|
||||||
|
LIBRARY_SEARCH_PATHS = ../../ThirdParty/ffmpeg/lib;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
|
|
|
@ -108,6 +108,11 @@ void decode_at3plus(VGMSTREAM *vgmstream,
|
||||||
sample * outbuf, int channelspacing, int32_t samples_to_do, int channel);
|
sample * outbuf, int channelspacing, int32_t samples_to_do, int channel);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
void decode_ffmpeg(VGMSTREAM *stream,
|
||||||
|
sample * outbuf, int32_t samples_to_do, int channels);
|
||||||
|
#endif
|
||||||
|
|
||||||
void decode_acm(ACMStream * acm, sample * outbuf,
|
void decode_acm(ACMStream * acm, sample * outbuf,
|
||||||
int32_t samples_to_do, int channelspacing);
|
int32_t samples_to_do, int channelspacing);
|
||||||
|
|
||||||
|
|
225
Frameworks/vgmstream/vgmstream/src/coding/ffmpeg_decoder.c
Normal file
225
Frameworks/vgmstream/vgmstream/src/coding/ffmpeg_decoder.c
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
#include "../vgmstream.h"
|
||||||
|
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
|
||||||
|
static void convert_audio(sample *outbuf, const uint8_t *inbuf, int sampleCount, int bitsPerSample, int floatingPoint) {
|
||||||
|
int s;
|
||||||
|
switch (bitsPerSample) {
|
||||||
|
case 8:
|
||||||
|
{
|
||||||
|
for (s = 0; s < sampleCount; ++s) {
|
||||||
|
*outbuf++ = ((int)(*(inbuf++))-0x80) << 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
{
|
||||||
|
int16_t *s16 = (int16_t *)inbuf;
|
||||||
|
for (s = 0; s < sampleCount; ++s) {
|
||||||
|
*outbuf++ = *(s16++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
{
|
||||||
|
if (!floatingPoint) {
|
||||||
|
int32_t *s32 = (int32_t *)inbuf;
|
||||||
|
for (s = 0; s < sampleCount; ++s) {
|
||||||
|
*outbuf++ = (*(s32++)) >> 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
float *s32 = (float *)inbuf;
|
||||||
|
for (s = 0; s < sampleCount; ++s) {
|
||||||
|
float sample = *s32++;
|
||||||
|
int s16 = (int)(sample * 32768.0f);
|
||||||
|
if ((unsigned)(s16 + 0x8000) & 0xFFFF0000) {
|
||||||
|
s16 = (s16 >> 31) ^ 0x7FFF;
|
||||||
|
}
|
||||||
|
*outbuf++ = s16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 64:
|
||||||
|
{
|
||||||
|
if (floatingPoint) {
|
||||||
|
double *s64 = (double *)inbuf;
|
||||||
|
for (s = 0; s < sampleCount; ++s) {
|
||||||
|
double sample = *s64++;
|
||||||
|
int s16 = (int)(sample * 32768.0f);
|
||||||
|
if ((unsigned)(s16 + 0x8000) & 0xFFFF0000) {
|
||||||
|
s16 = (s16 >> 31) ^ 0x7FFF;
|
||||||
|
}
|
||||||
|
*outbuf++ = s16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void decode_ffmpeg(VGMSTREAM *vgmstream,
|
||||||
|
sample * outbuf, int32_t samples_to_do, int channels) {
|
||||||
|
ffmpeg_codec_data *data = (ffmpeg_codec_data *) vgmstream->codec_data;
|
||||||
|
|
||||||
|
int frameSize;
|
||||||
|
int dataSize;
|
||||||
|
|
||||||
|
int bytesToRead;
|
||||||
|
int bytesRead;
|
||||||
|
|
||||||
|
int errcode;
|
||||||
|
|
||||||
|
uint8_t *targetBuf;
|
||||||
|
|
||||||
|
AVFormatContext *formatCtx;
|
||||||
|
AVCodecContext *codecCtx;
|
||||||
|
AVPacket *lastReadPacket;
|
||||||
|
AVFrame *lastDecodedFrame;
|
||||||
|
|
||||||
|
int streamIndex;
|
||||||
|
|
||||||
|
int bytesConsumedFromDecodedFrame;
|
||||||
|
|
||||||
|
int readNextPacket;
|
||||||
|
int endOfStream;
|
||||||
|
int endOfAudio;
|
||||||
|
|
||||||
|
int toConsume;
|
||||||
|
|
||||||
|
int framesReadNow;
|
||||||
|
|
||||||
|
if (data->totalFrames && data->framesRead >= data->totalFrames) {
|
||||||
|
memset(outbuf, 0, samples_to_do * channels * sizeof(sample));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
frameSize = data->channels * (data->bitsPerSample / 8);
|
||||||
|
dataSize = 0;
|
||||||
|
|
||||||
|
bytesToRead = samples_to_do * frameSize;
|
||||||
|
bytesRead = 0;
|
||||||
|
|
||||||
|
targetBuf = data->sampleBuffer;
|
||||||
|
memset(targetBuf, 0, bytesToRead);
|
||||||
|
|
||||||
|
formatCtx = data->formatCtx;
|
||||||
|
codecCtx = data->codecCtx;
|
||||||
|
lastReadPacket = data->lastReadPacket;
|
||||||
|
lastDecodedFrame = data->lastDecodedFrame;
|
||||||
|
|
||||||
|
streamIndex = data->streamIndex;
|
||||||
|
|
||||||
|
bytesConsumedFromDecodedFrame = data->bytesConsumedFromDecodedFrame;
|
||||||
|
|
||||||
|
readNextPacket = data->readNextPacket;
|
||||||
|
endOfStream = data->endOfStream;
|
||||||
|
endOfAudio = data->endOfAudio;
|
||||||
|
|
||||||
|
while (bytesRead < bytesToRead) {
|
||||||
|
int planeSize;
|
||||||
|
int planar = av_sample_fmt_is_planar(codecCtx->sample_fmt);
|
||||||
|
dataSize = av_samples_get_buffer_size(&planeSize, codecCtx->channels,
|
||||||
|
lastDecodedFrame->nb_samples,
|
||||||
|
codecCtx->sample_fmt, 1);
|
||||||
|
|
||||||
|
if (dataSize < 0)
|
||||||
|
dataSize = 0;
|
||||||
|
|
||||||
|
while (readNextPacket && !endOfAudio) {
|
||||||
|
if (!endOfStream) {
|
||||||
|
av_packet_unref(lastReadPacket);
|
||||||
|
if ((errcode = av_read_frame(formatCtx, lastReadPacket)) < 0) {
|
||||||
|
if (errcode == AVERROR_EOF) {
|
||||||
|
endOfStream = 1;
|
||||||
|
}
|
||||||
|
if (formatCtx->pb && formatCtx->pb->error)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (lastReadPacket->stream_index != streamIndex)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((errcode = avcodec_send_packet(codecCtx, endOfStream ? NULL : lastReadPacket)) < 0) {
|
||||||
|
if (errcode != AVERROR(EAGAIN)) {
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
readNextPacket = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dataSize <= bytesConsumedFromDecodedFrame) {
|
||||||
|
if (endOfStream && endOfAudio)
|
||||||
|
break;
|
||||||
|
|
||||||
|
bytesConsumedFromDecodedFrame = 0;
|
||||||
|
|
||||||
|
if ((errcode = avcodec_receive_frame(codecCtx, lastDecodedFrame)) < 0) {
|
||||||
|
if (errcode == AVERROR_EOF) {
|
||||||
|
endOfAudio = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (errcode == AVERROR(EAGAIN)) {
|
||||||
|
readNextPacket = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dataSize = av_samples_get_buffer_size(&planeSize, codecCtx->channels, lastDecodedFrame->nb_samples, codecCtx->sample_fmt, 1);
|
||||||
|
|
||||||
|
if (dataSize < 0)
|
||||||
|
dataSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
toConsume = FFMIN((dataSize - bytesConsumedFromDecodedFrame), (bytesToRead - bytesRead));
|
||||||
|
|
||||||
|
if (!planar || channels == 1) {
|
||||||
|
memmove(targetBuf + bytesRead, (lastDecodedFrame->data[0] + bytesConsumedFromDecodedFrame), toConsume);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint8_t * out = (uint8_t *) targetBuf + bytesRead;
|
||||||
|
int bytesPerSample = data->bitsPerSample / 8;
|
||||||
|
int bytesConsumedPerPlane = bytesConsumedFromDecodedFrame / channels;
|
||||||
|
int toConsumePerPlane = toConsume / channels;
|
||||||
|
int s, ch;
|
||||||
|
for (s = 0; s < toConsumePerPlane; s += bytesPerSample) {
|
||||||
|
for (ch = 0; ch < channels; ++ch) {
|
||||||
|
memcpy(out, lastDecodedFrame->extended_data[ch] + bytesConsumedPerPlane + s, bytesPerSample);
|
||||||
|
out += bytesPerSample;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bytesConsumedFromDecodedFrame += toConsume;
|
||||||
|
bytesRead += toConsume;
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
framesReadNow = bytesRead / frameSize;
|
||||||
|
if (data->totalFrames && (data->framesRead + framesReadNow > data->totalFrames)) {
|
||||||
|
framesReadNow = (int)(data->totalFrames - data->framesRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
data->framesRead += framesReadNow;
|
||||||
|
|
||||||
|
// Convert the audio
|
||||||
|
convert_audio(outbuf, data->sampleBuffer, framesReadNow * channels, data->bitsPerSample, data->floatingPoint);
|
||||||
|
|
||||||
|
// Output the state back to the structure
|
||||||
|
data->bytesConsumedFromDecodedFrame = bytesConsumedFromDecodedFrame;
|
||||||
|
data->readNextPacket = readNextPacket;
|
||||||
|
data->endOfStream = endOfStream;
|
||||||
|
data->endOfAudio = endOfAudio;
|
||||||
|
|
||||||
|
// And pad if we ran short (end of file)
|
||||||
|
if (framesReadNow < samples_to_do) {
|
||||||
|
memset(outbuf + framesReadNow * channels, 0, sizeof(sample) * channels * (samples_to_do - framesReadNow));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -19,6 +19,11 @@ void render_vgmstream_nolayout(sample * buffer, int32_t sample_count, VGMSTREAM
|
||||||
if (samples_written+samples_to_do > sample_count)
|
if (samples_written+samples_to_do > sample_count)
|
||||||
samples_to_do=sample_count-samples_written;
|
samples_to_do=sample_count-samples_written;
|
||||||
|
|
||||||
|
if (!samples_to_do) {
|
||||||
|
memset(buffer + samples_written * vgmstream->channels, 0, sizeof(sample) * vgmstream->channels * (sample_count - samples_written));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
decode_vgmstream(vgmstream, samples_written, samples_to_do, buffer);
|
decode_vgmstream(vgmstream, samples_written, samples_to_do, buffer);
|
||||||
|
|
||||||
samples_written += samples_to_do;
|
samples_written += samples_to_do;
|
||||||
|
|
344
Frameworks/vgmstream/vgmstream/src/meta/ffmpeg.c
Normal file
344
Frameworks/vgmstream/vgmstream/src/meta/ffmpeg.c
Normal file
|
@ -0,0 +1,344 @@
|
||||||
|
#include "../vgmstream.h"
|
||||||
|
#include "meta.h"
|
||||||
|
#include "../util.h"
|
||||||
|
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
|
||||||
|
static volatile int g_ffmpeg_initialized = 0;
|
||||||
|
|
||||||
|
static void g_init_ffmpeg()
|
||||||
|
{
|
||||||
|
if (g_ffmpeg_initialized == 1)
|
||||||
|
{
|
||||||
|
while (g_ffmpeg_initialized < 2);
|
||||||
|
}
|
||||||
|
else if (g_ffmpeg_initialized == 0)
|
||||||
|
{
|
||||||
|
g_ffmpeg_initialized = 1;
|
||||||
|
av_log_set_flags(AV_LOG_SKIP_REPEATED);
|
||||||
|
av_log_set_level(AV_LOG_ERROR);
|
||||||
|
av_register_all();
|
||||||
|
g_ffmpeg_initialized = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ffmpeg_codec_data * init_ffmpeg_faux_riff(STREAMFILE *streamFile, int64_t fmt_offset, uint64_t stream_offset, uint64_t stream_size, int fmt_big_endian);
|
||||||
|
ffmpeg_codec_data * init_ffmpeg_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size) {
|
||||||
|
return init_ffmpeg_faux_riff(streamFile, -1, start, size, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
VGMSTREAM * init_vgmstream_ffmpeg_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size);
|
||||||
|
|
||||||
|
VGMSTREAM * init_vgmstream_ffmpeg(STREAMFILE *streamFile) {
|
||||||
|
return init_vgmstream_ffmpeg_offset( streamFile, 0, streamFile->get_size(streamFile) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_ffmpeg(ffmpeg_codec_data *data);
|
||||||
|
|
||||||
|
VGMSTREAM * init_vgmstream_ffmpeg_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size) {
|
||||||
|
VGMSTREAM *vgmstream = NULL;
|
||||||
|
|
||||||
|
ffmpeg_codec_data *data = init_ffmpeg_offset(streamFile, start, size);
|
||||||
|
|
||||||
|
if (!data) return NULL;
|
||||||
|
|
||||||
|
vgmstream = allocate_vgmstream(data->channels, 0);
|
||||||
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
|
vgmstream->loop_flag = 0;
|
||||||
|
vgmstream->codec_data = data;
|
||||||
|
vgmstream->channels = data->channels;
|
||||||
|
vgmstream->sample_rate = data->sampleRate;
|
||||||
|
vgmstream->num_samples = data->totalFrames;
|
||||||
|
vgmstream->coding_type = coding_FFmpeg;
|
||||||
|
vgmstream->layout_type = layout_none;
|
||||||
|
vgmstream->meta_type = meta_FFmpeg;
|
||||||
|
|
||||||
|
return vgmstream;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
free_ffmpeg(data);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ffmpeg_read(void *opaque, uint8_t *buf, int buf_size)
|
||||||
|
{
|
||||||
|
ffmpeg_codec_data *data = (ffmpeg_codec_data *) opaque;
|
||||||
|
uint64_t offset = data->offset;
|
||||||
|
int max_to_copy;
|
||||||
|
int ret;
|
||||||
|
if (data->header_insert_block) {
|
||||||
|
max_to_copy = 0;
|
||||||
|
if (offset < data->header_size) {
|
||||||
|
max_to_copy = (int)(data->header_size - offset);
|
||||||
|
if (max_to_copy > buf_size) {
|
||||||
|
max_to_copy = buf_size;
|
||||||
|
}
|
||||||
|
memcpy(buf, data->header_insert_block + offset, max_to_copy);
|
||||||
|
buf += max_to_copy;
|
||||||
|
buf_size -= max_to_copy;
|
||||||
|
offset += max_to_copy;
|
||||||
|
if (!buf_size) {
|
||||||
|
data->offset = offset;
|
||||||
|
return max_to_copy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
offset -= data->header_size;
|
||||||
|
}
|
||||||
|
ret = read_streamfile(buf, offset + data->start, buf_size, data->streamfile);
|
||||||
|
if (ret > 0) {
|
||||||
|
offset += ret;
|
||||||
|
if (data->header_insert_block) {
|
||||||
|
ret += max_to_copy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (data->header_insert_block) {
|
||||||
|
offset += data->header_size;
|
||||||
|
}
|
||||||
|
data->offset = offset;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ffmpeg_write(void *opaque, uint8_t *buf, int buf_size)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence)
|
||||||
|
{
|
||||||
|
ffmpeg_codec_data *data = (ffmpeg_codec_data *) opaque;
|
||||||
|
if (whence & AVSEEK_SIZE) {
|
||||||
|
return data->size + data->header_size;
|
||||||
|
}
|
||||||
|
whence &= ~(AVSEEK_SIZE | AVSEEK_FORCE);
|
||||||
|
switch (whence) {
|
||||||
|
case SEEK_CUR:
|
||||||
|
offset += data->offset;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SEEK_END:
|
||||||
|
offset += data->size;
|
||||||
|
if (data->header_insert_block)
|
||||||
|
offset += data->header_size;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (offset > data->size + data->header_size)
|
||||||
|
offset = data->size + data->header_size;
|
||||||
|
return data->offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
ffmpeg_codec_data * init_ffmpeg_faux_riff(STREAMFILE *streamFile, int64_t fmt_offset, uint64_t start, uint64_t size, int big_endian) {
|
||||||
|
char filename[PATH_LIMIT];
|
||||||
|
|
||||||
|
ffmpeg_codec_data * data;
|
||||||
|
|
||||||
|
int errcode, i;
|
||||||
|
|
||||||
|
int streamIndex;
|
||||||
|
AVCodecParameters *codecPar;
|
||||||
|
|
||||||
|
AVRational tb;
|
||||||
|
|
||||||
|
g_init_ffmpeg();
|
||||||
|
|
||||||
|
data = ( ffmpeg_codec_data * ) calloc(1, sizeof(ffmpeg_codec_data));
|
||||||
|
|
||||||
|
if (!data) return 0;
|
||||||
|
|
||||||
|
streamFile->get_name( streamFile, filename, sizeof(filename) );
|
||||||
|
|
||||||
|
data->streamfile = streamFile->open(streamFile, filename, STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||||
|
if (!data->streamfile) goto fail;
|
||||||
|
|
||||||
|
data->start = start;
|
||||||
|
data->size = size;
|
||||||
|
|
||||||
|
if (fmt_offset > 0) {
|
||||||
|
int max_header_size = (int)(start - fmt_offset);
|
||||||
|
uint8_t *p;
|
||||||
|
if (max_header_size < 18) goto fail;
|
||||||
|
data->header_insert_block = p = av_malloc(max_header_size + 8 + 4 + 8 + 8);
|
||||||
|
if (!data->header_insert_block) goto fail;
|
||||||
|
if (read_streamfile(p + 8 + 4 + 8, fmt_offset, max_header_size, streamFile) != max_header_size) goto fail;
|
||||||
|
if (big_endian) {
|
||||||
|
p += 8 + 4 + 8;
|
||||||
|
put_16bitLE(p, get_16bitBE(p));
|
||||||
|
put_16bitLE(p + 2, get_16bitBE(p + 2));
|
||||||
|
put_32bitLE(p + 4, get_32bitBE(p + 4));
|
||||||
|
put_32bitLE(p + 8, get_32bitBE(p + 8));
|
||||||
|
put_16bitLE(p + 12, get_16bitBE(p + 12));
|
||||||
|
put_16bitLE(p + 14, get_16bitBE(p + 14));
|
||||||
|
put_16bitLE(p + 16, get_16bitBE(p + 16));
|
||||||
|
p -= 8 + 4 + 8;
|
||||||
|
}
|
||||||
|
data->header_size = 8 + 4 + 8 + 8 + 18 + get_16bitLE(p + 8 + 4 + 8 + 16);
|
||||||
|
// Meh, dunno how to handle swapping the extra data
|
||||||
|
// FFmpeg doesn't need most of this data anyway
|
||||||
|
if ((unsigned)(get_16bitLE(p + 8 + 4 + 8) - 0x165) < 2)
|
||||||
|
memset(p + 8 + 4 + 8 + 18, 0, 34);
|
||||||
|
|
||||||
|
// Fill out the RIFF structure
|
||||||
|
memcpy(p, "RIFF", 4);
|
||||||
|
put_32bitLE(p + 4, data->header_size + size - 8);
|
||||||
|
memcpy(p + 8, "WAVE", 4);
|
||||||
|
memcpy(p + 12, "fmt ", 4);
|
||||||
|
put_32bitLE(p + 16, 18 + get_16bitLE(p + 8 + 4 + 8 + 16));
|
||||||
|
memcpy(p + data->header_size - 8, "data", 4);
|
||||||
|
put_32bitLE(p + data->header_size - 4, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
data->buffer = av_malloc(128 * 1024);
|
||||||
|
if (!data->buffer) goto fail;
|
||||||
|
|
||||||
|
data->ioCtx = avio_alloc_context(data->buffer, 128 * 1024, 0, data, ffmpeg_read, ffmpeg_write, ffmpeg_seek);
|
||||||
|
if (!data->ioCtx) goto fail;
|
||||||
|
|
||||||
|
data->formatCtx = avformat_alloc_context();
|
||||||
|
if (!data->formatCtx) goto fail;
|
||||||
|
|
||||||
|
data->formatCtx->pb = data->ioCtx;
|
||||||
|
|
||||||
|
if ((errcode = avformat_open_input(&data->formatCtx, "", NULL, NULL)) < 0) goto fail;
|
||||||
|
|
||||||
|
if ((errcode = avformat_find_stream_info(data->formatCtx, NULL)) < 0) goto fail;
|
||||||
|
|
||||||
|
streamIndex = -1;
|
||||||
|
|
||||||
|
for (i = 0; i < data->formatCtx->nb_streams; ++i) {
|
||||||
|
codecPar = data->formatCtx->streams[i]->codecpar;
|
||||||
|
if (codecPar->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||||
|
streamIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (streamIndex < 0) goto fail;
|
||||||
|
|
||||||
|
data->streamIndex = streamIndex;
|
||||||
|
|
||||||
|
data->codecCtx = avcodec_alloc_context3(NULL);
|
||||||
|
if (!data->codecCtx) goto fail;
|
||||||
|
|
||||||
|
if ((errcode = avcodec_parameters_to_context(data->codecCtx, codecPar)) < 0) goto fail;
|
||||||
|
|
||||||
|
av_codec_set_pkt_timebase(data->codecCtx, data->formatCtx->streams[streamIndex]->time_base);
|
||||||
|
|
||||||
|
data->codec = avcodec_find_decoder(data->codecCtx->codec_id);
|
||||||
|
if (!data->codec) goto fail;
|
||||||
|
|
||||||
|
if ((errcode = avcodec_open2(data->codecCtx, data->codec, NULL)) < 0) goto fail;
|
||||||
|
|
||||||
|
data->lastDecodedFrame = av_frame_alloc();
|
||||||
|
if (!data->lastDecodedFrame) goto fail;
|
||||||
|
av_frame_unref(data->lastDecodedFrame);
|
||||||
|
data->lastReadPacket = malloc(sizeof(AVPacket));
|
||||||
|
if (!data->lastReadPacket) goto fail;
|
||||||
|
av_new_packet(data->lastReadPacket, 0);
|
||||||
|
data->readNextPacket = 1;
|
||||||
|
data->bytesConsumedFromDecodedFrame = INT_MAX;
|
||||||
|
|
||||||
|
data->sampleRate = data->codecCtx->sample_rate;
|
||||||
|
data->channels = data->codecCtx->channels;
|
||||||
|
data->floatingPoint = 0;
|
||||||
|
|
||||||
|
switch (data->codecCtx->sample_fmt) {
|
||||||
|
case AV_SAMPLE_FMT_U8:
|
||||||
|
case AV_SAMPLE_FMT_U8P:
|
||||||
|
data->bitsPerSample = 8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AV_SAMPLE_FMT_S16:
|
||||||
|
case AV_SAMPLE_FMT_S16P:
|
||||||
|
data->bitsPerSample = 16;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AV_SAMPLE_FMT_S32:
|
||||||
|
case AV_SAMPLE_FMT_S32P:
|
||||||
|
data->bitsPerSample = 32;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AV_SAMPLE_FMT_FLT:
|
||||||
|
case AV_SAMPLE_FMT_FLTP:
|
||||||
|
data->bitsPerSample = 32;
|
||||||
|
data->floatingPoint = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AV_SAMPLE_FMT_DBL:
|
||||||
|
case AV_SAMPLE_FMT_DBLP:
|
||||||
|
data->bitsPerSample = 64;
|
||||||
|
data->floatingPoint = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
tb.num = 1; tb.den = data->codecCtx->sample_rate;
|
||||||
|
|
||||||
|
data->totalFrames = av_rescale_q(data->formatCtx->streams[streamIndex]->duration, data->formatCtx->streams[streamIndex]->time_base, tb);
|
||||||
|
data->bitrate = (int)((data->codecCtx->bit_rate) / 1000);
|
||||||
|
data->framesRead = 0;
|
||||||
|
data->endOfStream = 0;
|
||||||
|
data->endOfAudio = 0;
|
||||||
|
|
||||||
|
if (data->totalFrames < 0)
|
||||||
|
data->totalFrames = 0;
|
||||||
|
|
||||||
|
data->sampleBuffer = av_malloc( 2048 * (data->bitsPerSample / 8) * data->channels );
|
||||||
|
if (!data->sampleBuffer)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
free_ffmpeg(data);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_ffmpeg(ffmpeg_codec_data *data) {
|
||||||
|
if (data->lastReadPacket) {
|
||||||
|
av_packet_unref(data->lastReadPacket);
|
||||||
|
free(data->lastReadPacket);
|
||||||
|
data->lastReadPacket = NULL;
|
||||||
|
}
|
||||||
|
if (data->lastDecodedFrame) {
|
||||||
|
av_free(data->lastDecodedFrame);
|
||||||
|
data->lastDecodedFrame = NULL;
|
||||||
|
}
|
||||||
|
if (data->codecCtx) {
|
||||||
|
avcodec_close(data->codecCtx);
|
||||||
|
avcodec_free_context(&(data->codecCtx));
|
||||||
|
data->codecCtx = NULL;
|
||||||
|
}
|
||||||
|
if (data->formatCtx) {
|
||||||
|
avformat_close_input(&(data->formatCtx));
|
||||||
|
data->formatCtx = NULL;
|
||||||
|
}
|
||||||
|
if (data->ioCtx) {
|
||||||
|
// buffer passed in is occasionally freed and replaced.
|
||||||
|
// the replacement must be freed as well.
|
||||||
|
data->buffer = data->ioCtx->buffer;
|
||||||
|
av_free(data->ioCtx);
|
||||||
|
data->ioCtx = NULL;
|
||||||
|
}
|
||||||
|
if (data->buffer) {
|
||||||
|
av_free(data->buffer);
|
||||||
|
data->buffer = NULL;
|
||||||
|
}
|
||||||
|
if (data->sampleBuffer) {
|
||||||
|
av_free(data->sampleBuffer);
|
||||||
|
data->sampleBuffer = NULL;
|
||||||
|
}
|
||||||
|
if (data->header_insert_block) {
|
||||||
|
av_free(data->header_insert_block);
|
||||||
|
data->header_insert_block = NULL;
|
||||||
|
}
|
||||||
|
if (data->streamfile) {
|
||||||
|
close_streamfile(data->streamfile);
|
||||||
|
data->streamfile = NULL;
|
||||||
|
}
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -115,6 +115,17 @@ VGMSTREAM * init_vgmstream_hca(STREAMFILE *streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_hca_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size);
|
VGMSTREAM * init_vgmstream_hca_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size);
|
||||||
|
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
ffmpeg_codec_data * init_ffmpeg_faux_riff(STREAMFILE *streamFile, int64_t fmt_offset, uint64_t stream_offset, uint64_t stream_size, int fmt_big_endian);
|
||||||
|
ffmpeg_codec_data * init_ffmpeg_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size);
|
||||||
|
|
||||||
|
void free_ffmpeg(ffmpeg_codec_data *);
|
||||||
|
|
||||||
|
VGMSTREAM * init_vgmstream_ffmpeg_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size);
|
||||||
|
|
||||||
|
VGMSTREAM * init_vgmstream_ffmpeg(STREAMFILE *streamFile);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
||||||
VGMSTREAM * init_vgmstream_mp4_aac(STREAMFILE * streamFile);
|
VGMSTREAM * init_vgmstream_mp4_aac(STREAMFILE * streamFile);
|
||||||
|
|
||||||
|
|
|
@ -172,6 +172,14 @@ int read_fmt(int big_endian,
|
||||||
fmt->coding_type = coding_NGC_DSP;
|
fmt->coding_type = coding_NGC_DSP;
|
||||||
fmt->interleave = 8;
|
fmt->interleave = 8;
|
||||||
break;
|
break;
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
case 0x270:
|
||||||
|
case 0xFFFE:
|
||||||
|
fmt->coding_type = coding_FFmpeg;
|
||||||
|
fmt->block_size = 2048;
|
||||||
|
fmt->interleave = 0;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
#ifdef VGM_USE_MAIATRAC3PLUS
|
#ifdef VGM_USE_MAIATRAC3PLUS
|
||||||
case 0xFFFE: /* WAVEFORMATEXTENSIBLE */
|
case 0xFFFE: /* WAVEFORMATEXTENSIBLE */
|
||||||
if (read_32bit(current_chunk+0x20,streamFile) == 0xE923AABF &&
|
if (read_32bit(current_chunk+0x20,streamFile) == 0xE923AABF &&
|
||||||
|
@ -203,6 +211,10 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) {
|
||||||
|
|
||||||
struct riff_fmt_chunk fmt;
|
struct riff_fmt_chunk fmt;
|
||||||
|
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
ffmpeg_codec_data *ffmpeg_data = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
off_t file_size = -1;
|
off_t file_size = -1;
|
||||||
int sample_count = 0;
|
int sample_count = 0;
|
||||||
int fact_sample_count = -1;
|
int fact_sample_count = -1;
|
||||||
|
@ -231,7 +243,7 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) {
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
if (strcasecmp("wav",filename_extension(filename)) &&
|
if (strcasecmp("wav",filename_extension(filename)) &&
|
||||||
strcasecmp("lwav",filename_extension(filename))
|
strcasecmp("lwav",filename_extension(filename))
|
||||||
#ifdef VGM_USE_MAIATRAC3PLUS
|
#if defined(VGM_USE_MAIATRAC3PLUS) || defined(VGM_USE_FFMPEG)
|
||||||
&& strcasecmp("at3",filename_extension(filename))
|
&& strcasecmp("at3",filename_extension(filename))
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
|
@ -367,6 +379,16 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) {
|
||||||
break;
|
break;
|
||||||
case coding_NGC_DSP:
|
case coding_NGC_DSP:
|
||||||
break;
|
break;
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
case coding_FFmpeg:
|
||||||
|
{
|
||||||
|
ffmpeg_data = init_ffmpeg_offset(streamFile, 0, streamFile->get_size(streamFile) );
|
||||||
|
if ( !ffmpeg_data ) goto fail;
|
||||||
|
|
||||||
|
sample_count = ffmpeg_data->totalFrames;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
#ifdef VGM_USE_MAIATRAC3PLUS
|
#ifdef VGM_USE_MAIATRAC3PLUS
|
||||||
case coding_AT3plus:
|
case coding_AT3plus:
|
||||||
sample_count = (data_size / fmt.block_size) * 2048 * fmt.channel_count;
|
sample_count = (data_size / fmt.block_size) * 2048 * fmt.channel_count;
|
||||||
|
@ -400,6 +422,9 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) {
|
||||||
case coding_PCM8_U_int:
|
case coding_PCM8_U_int:
|
||||||
case coding_MS_IMA:
|
case coding_MS_IMA:
|
||||||
case coding_MSADPCM:
|
case coding_MSADPCM:
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
case coding_FFmpeg:
|
||||||
|
#endif
|
||||||
#ifdef VGM_USE_MAIATRAC3PLUS
|
#ifdef VGM_USE_MAIATRAC3PLUS
|
||||||
case coding_AT3plus:
|
case coding_AT3plus:
|
||||||
#endif
|
#endif
|
||||||
|
@ -415,6 +440,9 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) {
|
||||||
switch (fmt.coding_type) {
|
switch (fmt.coding_type) {
|
||||||
case coding_MSADPCM:
|
case coding_MSADPCM:
|
||||||
case coding_MS_IMA:
|
case coding_MS_IMA:
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
case coding_FFmpeg:
|
||||||
|
#endif
|
||||||
#ifdef VGM_USE_MAIATRAC3PLUS
|
#ifdef VGM_USE_MAIATRAC3PLUS
|
||||||
case coding_AT3plus:
|
case coding_AT3plus:
|
||||||
#endif
|
#endif
|
||||||
|
@ -426,6 +454,12 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
if (fmt.coding_type == coding_FFmpeg) {
|
||||||
|
vgmstream->codec_data = ffmpeg_data;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef VGM_USE_MAIATRAC3PLUS
|
#ifdef VGM_USE_MAIATRAC3PLUS
|
||||||
if (fmt.coding_type == coding_AT3plus) {
|
if (fmt.coding_type == coding_AT3plus) {
|
||||||
maiatrac3plus_codec_data *data = malloc(sizeof(maiatrac3plus_codec_data));
|
maiatrac3plus_codec_data *data = malloc(sizeof(maiatrac3plus_codec_data));
|
||||||
|
@ -527,6 +561,9 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) {
|
||||||
|
|
||||||
/* clean up anything we may have opened */
|
/* clean up anything we may have opened */
|
||||||
fail:
|
fail:
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
if (ffmpeg_data) free_ffmpeg(ffmpeg_data);
|
||||||
|
#endif
|
||||||
if (vgmstream) close_vgmstream(vgmstream);
|
if (vgmstream) close_vgmstream(vgmstream);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -280,6 +280,32 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
case 0xB:
|
||||||
|
/* XMA1/XMA2 */
|
||||||
|
{
|
||||||
|
uint16_t codec_id = read_16bit(post_meta_offset, streamFile);
|
||||||
|
if (codec_id == 0x165 || codec_id == 0x166)
|
||||||
|
{
|
||||||
|
ffmpeg_codec_data *ffmpeg_data = init_ffmpeg_faux_riff(streamFile, post_meta_offset, start_offset, streamFile->get_size(streamFile) - start_offset, read_32bit == read_32bitBE);
|
||||||
|
if (!ffmpeg_data) goto fail;
|
||||||
|
|
||||||
|
vgmstream->codec_data = ffmpeg_data;
|
||||||
|
|
||||||
|
vgmstream->coding_type = coding_FFmpeg;
|
||||||
|
vgmstream->layout_type = layout_none;
|
||||||
|
|
||||||
|
vgmstream->num_samples = ffmpeg_data->totalFrames;
|
||||||
|
|
||||||
|
if (loop_flag) {
|
||||||
|
vgmstream->loop_start_sample = loop_start;
|
||||||
|
vgmstream->loop_end_sample = loop_end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else goto fail;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -287,7 +313,7 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
|
||||||
vgmstream->meta_type = meta_SQEX_SCD;
|
vgmstream->meta_type = meta_SQEX_SCD;
|
||||||
|
|
||||||
/* open the file for reading */
|
/* open the file for reading */
|
||||||
if (vgmstream->layout_type != layout_scd_int)
|
if (vgmstream->layout_type != layout_scd_int && vgmstream->coding_type != coding_FFmpeg)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
STREAMFILE * file;
|
STREAMFILE * file;
|
||||||
|
|
|
@ -339,6 +339,9 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = {
|
||||||
init_vgmstream_3ds_idsp,
|
init_vgmstream_3ds_idsp,
|
||||||
init_vgmstream_g1l,
|
init_vgmstream_g1l,
|
||||||
init_vgmstream_hca,
|
init_vgmstream_hca,
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
init_vgmstream_ffmpeg,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#define INIT_VGMSTREAM_FCNS (sizeof(init_vgmstream_fcns)/sizeof(init_vgmstream_fcns[0]))
|
#define INIT_VGMSTREAM_FCNS (sizeof(init_vgmstream_fcns)/sizeof(init_vgmstream_fcns[0]))
|
||||||
|
@ -363,6 +366,13 @@ VGMSTREAM * init_vgmstream_internal(STREAMFILE *streamFile, int do_dfs) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sanify loops! */
|
||||||
|
if (vgmstream->loop_flag) {
|
||||||
|
if ((vgmstream->loop_end_sample <= vgmstream->loop_start_sample) ||
|
||||||
|
(vgmstream->loop_end_sample > vgmstream->num_samples))
|
||||||
|
vgmstream->loop_flag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* dual file stereo */
|
/* dual file stereo */
|
||||||
if (do_dfs && (
|
if (do_dfs && (
|
||||||
(vgmstream->meta_type == meta_DSP_STD) ||
|
(vgmstream->meta_type == meta_DSP_STD) ||
|
||||||
|
@ -495,6 +505,24 @@ void reset_vgmstream(VGMSTREAM * vgmstream) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
if (vgmstream->coding_type==coding_FFmpeg) {
|
||||||
|
ffmpeg_codec_data *data = (ffmpeg_codec_data *) vgmstream->codec_data;
|
||||||
|
|
||||||
|
if (data->formatCtx) {
|
||||||
|
avformat_seek_file(data->formatCtx, -1, 0, 0, 0, AVSEEK_FLAG_ANY);
|
||||||
|
}
|
||||||
|
if (data->codecCtx) {
|
||||||
|
avcodec_flush_buffers(data->codecCtx);
|
||||||
|
}
|
||||||
|
data->readNextPacket = 1;
|
||||||
|
data->bytesConsumedFromDecodedFrame = INT_MAX;
|
||||||
|
data->framesRead = 0;
|
||||||
|
data->endOfStream = 0;
|
||||||
|
data->endOfAudio = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (vgmstream->coding_type==coding_ACM) {
|
if (vgmstream->coding_type==coding_ACM) {
|
||||||
mus_acm_codec_data *data = vgmstream->codec_data;
|
mus_acm_codec_data *data = vgmstream->codec_data;
|
||||||
int i;
|
int i;
|
||||||
|
@ -643,6 +671,16 @@ void close_vgmstream(VGMSTREAM * vgmstream) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
if (vgmstream->coding_type==coding_FFmpeg) {
|
||||||
|
ffmpeg_codec_data *data = (ffmpeg_codec_data *) vgmstream->codec_data;
|
||||||
|
if (vgmstream->codec_data) {
|
||||||
|
free_ffmpeg(data);
|
||||||
|
vgmstream->codec_data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
||||||
if (vgmstream->coding_type==coding_MP4_AAC) {
|
if (vgmstream->coding_type==coding_MP4_AAC) {
|
||||||
mp4_aac_codec_data *data = (mp4_aac_codec_data *) vgmstream->codec_data;
|
mp4_aac_codec_data *data = (mp4_aac_codec_data *) vgmstream->codec_data;
|
||||||
|
@ -1032,6 +1070,18 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
|
||||||
#ifdef VGM_USE_G719
|
#ifdef VGM_USE_G719
|
||||||
case coding_G719:
|
case coding_G719:
|
||||||
return 48000/50;
|
return 48000/50;
|
||||||
|
#endif
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
case coding_FFmpeg:
|
||||||
|
{
|
||||||
|
ffmpeg_codec_data *data = (ffmpeg_codec_data *) vgmstream->codec_data;
|
||||||
|
if (vgmstream->codec_data) {
|
||||||
|
int64_t samplesRemain = data->totalFrames - data->framesRead;
|
||||||
|
return samplesRemain > 2048 ? 2048 : samplesRemain;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
case coding_LSF:
|
case coding_LSF:
|
||||||
return 54;
|
return 54;
|
||||||
|
@ -1147,6 +1197,9 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
|
||||||
#endif
|
#endif
|
||||||
#ifdef VGM_USE_MAIATRAC3PLUS
|
#ifdef VGM_USE_MAIATRAC3PLUS
|
||||||
case coding_AT3plus:
|
case coding_AT3plus:
|
||||||
|
#endif
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
case coding_FFmpeg:
|
||||||
#endif
|
#endif
|
||||||
case coding_MSADPCM:
|
case coding_MSADPCM:
|
||||||
case coding_MTAF:
|
case coding_MTAF:
|
||||||
|
@ -1425,6 +1478,14 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to
|
||||||
buffer+samples_written*vgmstream->channels,samples_to_do,
|
buffer+samples_written*vgmstream->channels,samples_to_do,
|
||||||
vgmstream->channels);
|
vgmstream->channels);
|
||||||
break;
|
break;
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
case coding_FFmpeg:
|
||||||
|
decode_ffmpeg(vgmstream,
|
||||||
|
buffer+samples_written*vgmstream->channels,
|
||||||
|
samples_to_do,
|
||||||
|
vgmstream->channels);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
||||||
case coding_MP4_AAC:
|
case coding_MP4_AAC:
|
||||||
decode_mp4_aac(vgmstream->codec_data,
|
decode_mp4_aac(vgmstream->codec_data,
|
||||||
|
@ -1717,6 +1778,20 @@ int vgmstream_do_loop(VGMSTREAM * vgmstream) {
|
||||||
data->sample_ptr = clHCA_samplesPerBlock;
|
data->sample_ptr = clHCA_samplesPerBlock;
|
||||||
data->samples_discard = 0;
|
data->samples_discard = 0;
|
||||||
}
|
}
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
if (vgmstream->coding_type==coding_FFmpeg) {
|
||||||
|
ffmpeg_codec_data *data = (ffmpeg_codec_data *)(vgmstream->codec_data);
|
||||||
|
int64_t ts;
|
||||||
|
data->framesRead = vgmstream->loop_start_sample;
|
||||||
|
ts = data->framesRead * (data->formatCtx->duration) / data->totalFrames;
|
||||||
|
avformat_seek_file(data->formatCtx, -1, ts - 1000, ts, ts, AVSEEK_FLAG_ANY);
|
||||||
|
avcodec_flush_buffers(data->codecCtx);
|
||||||
|
data->readNextPacket = 1;
|
||||||
|
data->bytesConsumedFromDecodedFrame = INT_MAX;
|
||||||
|
data->endOfStream = 0;
|
||||||
|
data->endOfAudio = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
||||||
if (vgmstream->coding_type==coding_MP4_AAC) {
|
if (vgmstream->coding_type==coding_MP4_AAC) {
|
||||||
mp4_aac_codec_data *data = (mp4_aac_codec_data *)(vgmstream->codec_data);
|
mp4_aac_codec_data *data = (mp4_aac_codec_data *)(vgmstream->codec_data);
|
||||||
|
@ -2012,6 +2087,25 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
|
||||||
snprintf(temp,TEMPSIZE,"ATRAC3plus");
|
snprintf(temp,TEMPSIZE,"ATRAC3plus");
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
case coding_FFmpeg:
|
||||||
|
{
|
||||||
|
ffmpeg_codec_data *data = (ffmpeg_codec_data *) vgmstream->codec_data;
|
||||||
|
if (vgmstream->codec_data) {
|
||||||
|
if (data->codec) {
|
||||||
|
snprintf(temp,TEMPSIZE,data->codec->long_name);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
snprintf(temp,TEMPSIZE,"FFmpeg");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
snprintf(temp,TEMPSIZE,"FFmpeg");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case coding_ACM:
|
case coding_ACM:
|
||||||
snprintf(temp,TEMPSIZE,"InterPlay ACM");
|
snprintf(temp,TEMPSIZE,"InterPlay ACM");
|
||||||
break;
|
break;
|
||||||
|
@ -3183,6 +3277,14 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
|
||||||
case meta_XB3D_ADX:
|
case meta_XB3D_ADX:
|
||||||
snprintf(temp, TEMPSIZE,"Xenoblade 3D ADX Header");
|
snprintf(temp, TEMPSIZE,"Xenoblade 3D ADX Header");
|
||||||
break;
|
break;
|
||||||
|
case meta_HCA:
|
||||||
|
snprintf(temp, TEMPSIZE,"CRI MiddleWare HCA Header");
|
||||||
|
break;
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
case meta_FFmpeg:
|
||||||
|
snprintf(temp, TEMPSIZE,"FFmpeg supported file format");
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
snprintf(temp,TEMPSIZE,"THEY SHOULD HAVE SENT A POET");
|
snprintf(temp,TEMPSIZE,"THEY SHOULD HAVE SENT A POET");
|
||||||
}
|
}
|
||||||
|
@ -3376,6 +3478,18 @@ static int get_vgmstream_channel_count(VGMSTREAM * vgmstream)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
if (vgmstream->coding_type==coding_FFmpeg) {
|
||||||
|
ffmpeg_codec_data *data = (ffmpeg_codec_data *) vgmstream->codec_data;
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
||||||
if (vgmstream->coding_type==coding_MP4_AAC) {
|
if (vgmstream->coding_type==coding_MP4_AAC) {
|
||||||
mp4_aac_codec_data *data = (mp4_aac_codec_data *) vgmstream->codec_data;
|
mp4_aac_codec_data *data = (mp4_aac_codec_data *) vgmstream->codec_data;
|
||||||
|
@ -3408,6 +3522,13 @@ static STREAMFILE * get_vgmstream_streamfile(VGMSTREAM * vgmstream, int channel)
|
||||||
|
|
||||||
return data->streamfile;
|
return data->streamfile;
|
||||||
}
|
}
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
if (vgmstream->coding_type==coding_FFmpeg) {
|
||||||
|
ffmpeg_codec_data *data = (ffmpeg_codec_data *) vgmstream->codec_data;
|
||||||
|
|
||||||
|
return data->streamfile;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
||||||
if (vgmstream->coding_type==coding_MP4_AAC) {
|
if (vgmstream->coding_type==coding_MP4_AAC) {
|
||||||
mp4_aac_codec_data *data = (mp4_aac_codec_data *) vgmstream->codec_data;
|
mp4_aac_codec_data *data = (mp4_aac_codec_data *) vgmstream->codec_data;
|
||||||
|
|
|
@ -17,6 +17,7 @@ enum { PATH_LIMIT = 32768 };
|
||||||
/* disabled by default, defined for builds that support it */
|
/* disabled by default, defined for builds that support it */
|
||||||
#define VGM_USE_G7221
|
#define VGM_USE_G7221
|
||||||
#define VGM_USE_G719
|
#define VGM_USE_G719
|
||||||
|
#define VGM_USE_FFMPEG
|
||||||
|
|
||||||
#include "streamfile.h"
|
#include "streamfile.h"
|
||||||
#ifdef BUILD_VGMSTREAM
|
#ifdef BUILD_VGMSTREAM
|
||||||
|
@ -55,6 +56,11 @@ enum { PATH_LIMIT = 32768 };
|
||||||
|
|
||||||
#include "clHCA.h"
|
#include "clHCA.h"
|
||||||
|
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
#include <libavcodec/avcodec.h>
|
||||||
|
#include <libavformat/avformat.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef BUILD_VGMSTREAM
|
#ifdef BUILD_VGMSTREAM
|
||||||
#include "coding/acm_decoder.h"
|
#include "coding/acm_decoder.h"
|
||||||
#include "coding/nwa_decoder.h"
|
#include "coding/nwa_decoder.h"
|
||||||
|
@ -166,6 +172,10 @@ typedef enum {
|
||||||
|
|
||||||
coding_CRI_HCA, /* CRI High Compression Audio */
|
coding_CRI_HCA, /* CRI High Compression Audio */
|
||||||
|
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
coding_FFmpeg,
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
||||||
coding_MP4_AAC,
|
coding_MP4_AAC,
|
||||||
#endif
|
#endif
|
||||||
|
@ -598,6 +608,9 @@ typedef enum {
|
||||||
meta_MCA, // Capcom MCA "MADP"
|
meta_MCA, // Capcom MCA "MADP"
|
||||||
meta_XB3D_ADX, // Xenoblade Chronicles 3D ADX
|
meta_XB3D_ADX, // Xenoblade Chronicles 3D ADX
|
||||||
meta_HCA,
|
meta_HCA,
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
meta_FFmpeg,
|
||||||
|
#endif
|
||||||
#ifdef VGM_USE_MP4V2
|
#ifdef VGM_USE_MP4V2
|
||||||
meta_MP4,
|
meta_MP4,
|
||||||
#endif
|
#endif
|
||||||
|
@ -842,6 +855,51 @@ typedef struct {
|
||||||
// clHCA exists here
|
// clHCA exists here
|
||||||
} hca_codec_data;
|
} hca_codec_data;
|
||||||
|
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
typedef struct {
|
||||||
|
STREAMFILE *streamfile;
|
||||||
|
|
||||||
|
// offset and total size of raw stream data
|
||||||
|
uint64_t start;
|
||||||
|
uint64_t size;
|
||||||
|
|
||||||
|
// offset into stream, includes header_size if header exists
|
||||||
|
uint64_t offset;
|
||||||
|
|
||||||
|
// inserted header, ie. fake RIFF header
|
||||||
|
uint8_t *header_insert_block;
|
||||||
|
uint64_t header_size;
|
||||||
|
|
||||||
|
// stream info
|
||||||
|
int channels;
|
||||||
|
int bitsPerSample;
|
||||||
|
int floatingPoint;
|
||||||
|
int sampleRate;
|
||||||
|
int64_t totalFrames;
|
||||||
|
int64_t framesRead;
|
||||||
|
int bitrate;
|
||||||
|
|
||||||
|
// Intermediate buffer
|
||||||
|
uint8_t *sampleBuffer;
|
||||||
|
|
||||||
|
// FFmpeg context used for metadata
|
||||||
|
AVCodec *codec;
|
||||||
|
|
||||||
|
// FFmpeg decoder state
|
||||||
|
unsigned char *buffer;
|
||||||
|
AVIOContext *ioCtx;
|
||||||
|
int streamIndex;
|
||||||
|
AVFormatContext *formatCtx;
|
||||||
|
AVCodecContext *codecCtx;
|
||||||
|
AVFrame *lastDecodedFrame;
|
||||||
|
AVPacket *lastReadPacket;
|
||||||
|
int bytesConsumedFromDecodedFrame;
|
||||||
|
int readNextPacket;
|
||||||
|
int endOfStream;
|
||||||
|
int endOfAudio;
|
||||||
|
} ffmpeg_codec_data;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef VGM_USE_MP4V2
|
#ifdef VGM_USE_MP4V2
|
||||||
typedef struct {
|
typedef struct {
|
||||||
STREAMFILE *streamfile;
|
STREAMFILE *streamfile;
|
||||||
|
|
|
@ -29,6 +29,19 @@ int ffmpeg_write(void *opaque, uint8_t *buf, int buf_size)
|
||||||
int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence)
|
int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence)
|
||||||
{
|
{
|
||||||
id source = (__bridge id) opaque;
|
id source = (__bridge id) opaque;
|
||||||
|
if (whence & AVSEEK_SIZE)
|
||||||
|
{
|
||||||
|
if ([source seekable])
|
||||||
|
{
|
||||||
|
int64_t curOffset = [source tell];
|
||||||
|
[source seek:0 whence:SEEK_END];
|
||||||
|
int64_t size = [source tell];
|
||||||
|
[source seek:curOffset whence:SEEK_SET];
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
whence &= ~(AVSEEK_SIZE | AVSEEK_FORCE);
|
||||||
return [source seekable] ? ([source seek:offset whence:whence] ? [source tell] : -1) : -1;
|
return [source seekable] ? ([source seek:offset whence:whence] ? [source tell] : -1) : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,7 +457,7 @@ int lockmgr_callback(void ** mutex, enum AVLockOp op)
|
||||||
|
|
||||||
+ (NSArray *)fileTypes
|
+ (NSArray *)fileTypes
|
||||||
{
|
{
|
||||||
return [NSArray arrayWithObjects:@"wma", @"asf", @"xwma", @"xma", @"tak", @"mp3", @"mp2", @"m2a", @"mpa", @"ape", @"ac3", @"dts", @"dtshd", @"at3", @"wav", @"tta", @"vqf", @"vqe", @"vql", nil];
|
return [NSArray arrayWithObjects:@"wma", @"asf", @"tak", @"mp3", @"mp2", @"m2a", @"mpa", @"ape", @"ac3", @"dts", @"dtshd", @"wav", @"tta", @"vqf", @"vqe", @"vql", nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSArray *)mimeTypes
|
+ (NSArray *)mimeTypes
|
||||||
|
|
|
@ -320,6 +320,7 @@
|
||||||
GCC_PREFIX_HEADER = "vgmstream/vgmstream-Prefix.pch";
|
GCC_PREFIX_HEADER = "vgmstream/vgmstream-Prefix.pch";
|
||||||
HEADER_SEARCH_PATHS = (
|
HEADER_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
|
../../ThirdParty/ffmpeg/include,
|
||||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||||
../../Frameworks/Vorbis/include,
|
../../Frameworks/Vorbis/include,
|
||||||
../../Frameworks/Ogg/include,
|
../../Frameworks/Ogg/include,
|
||||||
|
@ -343,6 +344,7 @@
|
||||||
GCC_PREFIX_HEADER = "vgmstream/vgmstream-Prefix.pch";
|
GCC_PREFIX_HEADER = "vgmstream/vgmstream-Prefix.pch";
|
||||||
HEADER_SEARCH_PATHS = (
|
HEADER_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
|
../../ThirdParty/ffmpeg/include,
|
||||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||||
../../Frameworks/Vorbis/include,
|
../../Frameworks/Vorbis/include,
|
||||||
../../Frameworks/Ogg/include,
|
../../Frameworks/Ogg/include,
|
||||||
|
|
|
@ -130,7 +130,7 @@ VGMSTREAM *init_vgmstream_from_cogfile(const char *path) {
|
||||||
sampleRate = stream->sample_rate;
|
sampleRate = stream->sample_rate;
|
||||||
channels = stream->channels;
|
channels = stream->channels;
|
||||||
totalFrames = get_vgmstream_play_samples( 2.0, 10.0, 10.0, stream );
|
totalFrames = get_vgmstream_play_samples( 2.0, 10.0, 10.0, stream );
|
||||||
framesFade = sampleRate * 10;
|
framesFade = stream->loop_flag ? sampleRate * 10 : 0;
|
||||||
framesLength = totalFrames - framesFade;
|
framesLength = totalFrames - framesFade;
|
||||||
|
|
||||||
framesRead = 0;
|
framesRead = 0;
|
||||||
|
@ -161,14 +161,17 @@ VGMSTREAM *init_vgmstream_from_cogfile(const char *path) {
|
||||||
{
|
{
|
||||||
BOOL repeatone = IsRepeatOneSet();
|
BOOL repeatone = IsRepeatOneSet();
|
||||||
|
|
||||||
if (!repeatone && framesRead >= totalFrames)
|
if (!repeatone) {
|
||||||
return 0;
|
if (framesRead >= totalFrames) return 0;
|
||||||
|
else if (framesRead + frames > totalFrames)
|
||||||
|
frames = totalFrames - framesRead;
|
||||||
|
}
|
||||||
|
|
||||||
sample * sbuf = (sample *) buf;
|
sample * sbuf = (sample *) buf;
|
||||||
|
|
||||||
render_vgmstream( sbuf, frames, stream );
|
render_vgmstream( sbuf, frames, stream );
|
||||||
|
|
||||||
if ( !repeatone && framesRead + frames > framesLength ) {
|
if ( !repeatone && framesFade && framesRead + frames > framesLength ) {
|
||||||
long fadeStart = (framesLength > framesRead) ? framesLength : framesRead;
|
long fadeStart = (framesLength > framesRead) ? framesLength : framesRead;
|
||||||
long fadeEnd = (framesRead + frames) > totalFrames ? totalFrames : (framesRead + frames);
|
long fadeEnd = (framesRead + frames) > totalFrames ? totalFrames : (framesRead + frames);
|
||||||
long fadePos;
|
long fadePos;
|
||||||
|
@ -231,7 +234,7 @@ VGMSTREAM *init_vgmstream_from_cogfile(const char *path) {
|
||||||
|
|
||||||
+ (NSArray *)fileTypes
|
+ (NSArray *)fileTypes
|
||||||
{
|
{
|
||||||
return [NSArray arrayWithObjects:@"2dx9", @"aaap", @"aax", @"acm", @"adp", @"adpcm", @"ads", @"adx", @"afc", @"agsc", @"ahx",@"aifc", @"aiff", @"aix", @"amts", @"as4", @"asd", @"asf", @"asr", @"ass", @"ast", @"aud", @"aus", @"baf", @"baka", @"bar", @"bcstm", @"bcwav", @"bfstm", @"bfwav", @"bfwavnsmbu", @"bg00", @"bgw", @"bh2pcm", @"bmdx", @"bns", @"bnsf", @"bo2", @"brstm", @"caf", @"capdsp", @"ccc", @"cfn", @"cnk", @"dcs", @"dcsw", @"ddsp", @"de2", @"dmsg", @"dsp", @"dvi", @"dxh", @"eam", @"emff", @"enth", @"fag", @"filp", @"fsb", @"fwav", @"gca", @"gcm", @"gcsw", @"gcw", @"genh", @"gms", @"gsp", @"hca", @"hgc1", @"his", @"hps", @"hwas", @"idsp", @"idvi", @"ikm", @"ild", @"int", @"isd", @"ish", @"ivaud", @"ivb", @"joe", @"kces", @"kcey", @"khv", @"kraw", @"leg", @"logg", @"lps", @"lsf", @"lwav", @"matx", @"mcg", @"mi4", @"mib", @"mic", @"mihb", @"mpdsp", @"msa", @"mss", @"msvp", @"mus", @"musc", @"musx", @"mwv", @"myspd", @"ndp", @"npsf", @"nus3bank", @"nwa", @"omu", @"otm", @"p3d", @"pcm", @"pdt", @"pnb", @"pos", @"psh", @"psw", @"raw", @"rkv", @"rnd", @"rrds", @"rsd", @"rsf", @"rstm", @"rwar", @"rwav", @"rws", @"rwsd", @"rwx", @"rxw", @"s14", @"sab", @"sad", @"sap", @"sc", @"scd", @"sd9", @"sdt", @"seg", @"sfl", @"sfs", @"sl3", @"sli", @"smp", @"smpl", @"snd", @"sng", @"sns", @"spd", @"sps", @"spsd", @"spt", @"spw", @"ss2", @"ss7", @"ssm", @"sss", @"ster", @"sth", @"stm", @"stma", @"str", @"strm", @"sts", @"stx", @"svag", @"svs", @"swav", @"swd", @"tec", @"thp", @"tk5", @"tydsp", @"um3", @"vag", @"vas", @"vgs", @"vig", @"vjdsp", @"voi", @"vpk", @"vs", @"vsf", @"waa", @"wac", @"wad", @"wam", @"was", @"wavm", @"wb", @"wii", @"wp2", @"wsd", @"wsi", @"wvs", @"xa", @"xa2", @"xa30", @"xmu", @"xss", @"xvas", @"xwav", @"xwb", @"ydsp", @"ymf", @"zsd", @"zwdsp", nil];
|
return [NSArray arrayWithObjects:@"2dx9", @"aaap", @"aax", @"acm", @"adp", @"adpcm", @"ads", @"adx", @"afc", @"agsc", @"ahx",@"aifc", @"aiff", @"aix", @"amts", @"as4", @"asd", @"asf", @"asr", @"ass", @"ast", @"at3", @"aud", @"aus", @"baf", @"baka", @"bar", @"bcstm", @"bcwav", @"bfstm", @"bfwav", @"bfwavnsmbu", @"bg00", @"bgw", @"bh2pcm", @"bmdx", @"bns", @"bnsf", @"bo2", @"brstm", @"caf", @"capdsp", @"ccc", @"cfn", @"cnk", @"dcs", @"dcsw", @"ddsp", @"de2", @"dmsg", @"dsp", @"dvi", @"dxh", @"eam", @"emff", @"enth", @"fag", @"filp", @"fsb", @"fwav", @"gca", @"gcm", @"gcsw", @"gcw", @"genh", @"gms", @"gsp", @"hca", @"hgc1", @"his", @"hps", @"hwas", @"idsp", @"idvi", @"ikm", @"ild", @"int", @"isd", @"ish", @"ivaud", @"ivb", @"joe", @"kces", @"kcey", @"khv", @"kraw", @"leg", @"logg", @"lps", @"lsf", @"lwav", @"matx", @"mcg", @"mi4", @"mib", @"mic", @"mihb", @"mpdsp", @"msa", @"mss", @"msvp", @"mus", @"musc", @"musx", @"mwv", @"myspd", @"ndp", @"npsf", @"nus3bank", @"nwa", @"omu", @"otm", @"p3d", @"pcm", @"pdt", @"pnb", @"pos", @"psh", @"psw", @"raw", @"rkv", @"rnd", @"rrds", @"rsd", @"rsf", @"rstm", @"rwar", @"rwav", @"rws", @"rwsd", @"rwx", @"rxw", @"s14", @"sab", @"sad", @"sap", @"sc", @"scd", @"sd9", @"sdt", @"seg", @"sfl", @"sfs", @"sl3", @"sli", @"smp", @"smpl", @"snd", @"sng", @"sns", @"spd", @"sps", @"spsd", @"spt", @"spw", @"ss2", @"ss7", @"ssm", @"sss", @"ster", @"sth", @"stm", @"stma", @"str", @"strm", @"sts", @"stx", @"svag", @"svs", @"swav", @"swd", @"tec", @"thp", @"tk5", @"tydsp", @"um3", @"vag", @"vas", @"vgs", @"vig", @"vjdsp", @"voi", @"vpk", @"vs", @"vsf", @"waa", @"wac", @"wad", @"wam", @"was", @"wavm", @"wb", @"wii", @"wp2", @"wsd", @"wsi", @"wvs", @"xa", @"xa2", @"xa30", @"xma", @"xmu", @"xss", @"xvas", @"xwav", @"xwb", @"xwma", @"ydsp", @"ymf", @"zsd", @"zwdsp", nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSArray *)mimeTypes
|
+ (NSArray *)mimeTypes
|
||||||
|
|
Loading…
Reference in a new issue