Added TAK support
parent
a8df4ddab5
commit
2f730e1822
|
@ -271,6 +271,39 @@
|
|||
830F0DD117FC934D00042E8F /* spdif.c in Sources */ = {isa = PBXBuildFile; fileRef = 830F0DCF17FC934D00042E8F /* spdif.c */; };
|
||||
830F0DD217FC934D00042E8F /* spdif.h in Headers */ = {isa = PBXBuildFile; fileRef = 830F0DD017FC934D00042E8F /* spdif.h */; };
|
||||
830F0DD617FC93E400042E8F /* xwma.c in Sources */ = {isa = PBXBuildFile; fileRef = 830F0DD417FC93E400042E8F /* xwma.c */; };
|
||||
833C3795180328A300CBA602 /* takdec.c in Sources */ = {isa = PBXBuildFile; fileRef = 833C3794180328A300CBA602 /* takdec.c */; };
|
||||
833C379A180328B300CBA602 /* tak_parser.c in Sources */ = {isa = PBXBuildFile; fileRef = 833C3796180328B300CBA602 /* tak_parser.c */; };
|
||||
833C379B180328B300CBA602 /* tak.c in Sources */ = {isa = PBXBuildFile; fileRef = 833C3797180328B300CBA602 /* tak.c */; };
|
||||
833C379C180328B300CBA602 /* tak.h in Headers */ = {isa = PBXBuildFile; fileRef = 833C3798180328B300CBA602 /* tak.h */; };
|
||||
833C379D180328B300CBA602 /* takdec.c in Sources */ = {isa = PBXBuildFile; fileRef = 833C3799180328B300CBA602 /* takdec.c */; };
|
||||
833C379F18032A2700CBA602 /* unary.h in Headers */ = {isa = PBXBuildFile; fileRef = 833C379E18032A2700CBA602 /* unary.h */; };
|
||||
833C37A218032A2F00CBA602 /* rawdec.c in Sources */ = {isa = PBXBuildFile; fileRef = 833C37A018032A2F00CBA602 /* rawdec.c */; };
|
||||
833C37A318032A2F00CBA602 /* rawdec.h in Headers */ = {isa = PBXBuildFile; fileRef = 833C37A118032A2F00CBA602 /* rawdec.h */; };
|
||||
833C37A618032A5000CBA602 /* apetag.c in Sources */ = {isa = PBXBuildFile; fileRef = 833C37A418032A5000CBA602 /* apetag.c */; };
|
||||
833C37A718032A5000CBA602 /* apetag.h in Headers */ = {isa = PBXBuildFile; fileRef = 833C37A518032A5000CBA602 /* apetag.h */; };
|
||||
833C37A918032AAD00CBA602 /* img2.c in Sources */ = {isa = PBXBuildFile; fileRef = 833C37A818032AAD00CBA602 /* img2.c */; };
|
||||
833C37B118032AEF00CBA602 /* diracdsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 833C37AA18032AEF00CBA602 /* diracdsp.c */; };
|
||||
833C37B218032AEF00CBA602 /* diracdsp.h in Headers */ = {isa = PBXBuildFile; fileRef = 833C37AB18032AEF00CBA602 /* diracdsp.h */; };
|
||||
833C37B318032AEF00CBA602 /* dsputil.c in Sources */ = {isa = PBXBuildFile; fileRef = 833C37AC18032AEF00CBA602 /* dsputil.c */; };
|
||||
833C37B418032AEF00CBA602 /* dsputil.h in Headers */ = {isa = PBXBuildFile; fileRef = 833C37AD18032AEF00CBA602 /* dsputil.h */; };
|
||||
833C37B518032AEF00CBA602 /* diracdsp_mmx.c in Sources */ = {isa = PBXBuildFile; fileRef = 833C37AE18032AEF00CBA602 /* diracdsp_mmx.c */; };
|
||||
833C37B618032AEF00CBA602 /* diracdsp_mmx.h in Headers */ = {isa = PBXBuildFile; fileRef = 833C37AF18032AEF00CBA602 /* diracdsp_mmx.h */; };
|
||||
833C37B718032AEF00CBA602 /* dsputil_x86.h in Headers */ = {isa = PBXBuildFile; fileRef = 833C37B018032AEF00CBA602 /* dsputil_x86.h */; };
|
||||
833C37C218032CF600CBA602 /* dirac_arith.c in Sources */ = {isa = PBXBuildFile; fileRef = 833C37BA18032CF600CBA602 /* dirac_arith.c */; };
|
||||
833C37C318032CF600CBA602 /* dirac_arith.h in Headers */ = {isa = PBXBuildFile; fileRef = 833C37BB18032CF600CBA602 /* dirac_arith.h */; };
|
||||
833C37C418032CF600CBA602 /* dirac_dwt.c in Sources */ = {isa = PBXBuildFile; fileRef = 833C37BC18032CF600CBA602 /* dirac_dwt.c */; };
|
||||
833C37C518032CF600CBA602 /* dirac_dwt.h in Headers */ = {isa = PBXBuildFile; fileRef = 833C37BD18032CF600CBA602 /* dirac_dwt.h */; };
|
||||
833C37C618032CF600CBA602 /* dirac_parser.c in Sources */ = {isa = PBXBuildFile; fileRef = 833C37BE18032CF600CBA602 /* dirac_parser.c */; };
|
||||
833C37C718032CF600CBA602 /* dirac.c in Sources */ = {isa = PBXBuildFile; fileRef = 833C37BF18032CF600CBA602 /* dirac.c */; };
|
||||
833C37C818032CF600CBA602 /* dirac.h in Headers */ = {isa = PBXBuildFile; fileRef = 833C37C018032CF600CBA602 /* dirac.h */; };
|
||||
833C37C918032CF600CBA602 /* diracdec.c in Sources */ = {isa = PBXBuildFile; fileRef = 833C37C118032CF600CBA602 /* diracdec.c */; };
|
||||
833C37CE18032D4800CBA602 /* golomb.c in Sources */ = {isa = PBXBuildFile; fileRef = 833C37CA18032D4800CBA602 /* golomb.c */; };
|
||||
833C37CF18032D4800CBA602 /* golomb.h in Headers */ = {isa = PBXBuildFile; fileRef = 833C37CB18032D4800CBA602 /* golomb.h */; };
|
||||
833C37D018032D4800CBA602 /* dirac_dwt.c in Sources */ = {isa = PBXBuildFile; fileRef = 833C37CC18032D4800CBA602 /* dirac_dwt.c */; };
|
||||
833C37D118032D4800CBA602 /* dirac_dwt.h in Headers */ = {isa = PBXBuildFile; fileRef = 833C37CD18032D4800CBA602 /* dirac_dwt.h */; };
|
||||
833C37D318032E4800CBA602 /* dsputil_init.c in Sources */ = {isa = PBXBuildFile; fileRef = 833C37D218032E4800CBA602 /* dsputil_init.c */; };
|
||||
833C37D518032E7000CBA602 /* jrevdct.c in Sources */ = {isa = PBXBuildFile; fileRef = 833C37D418032E7000CBA602 /* jrevdct.c */; };
|
||||
833C37D718032EA500CBA602 /* idct_xvid.h in Headers */ = {isa = PBXBuildFile; fileRef = 833C37D618032EA500CBA602 /* idct_xvid.h */; };
|
||||
83BCB8E217FCA64400760340 /* avconfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 83BCB8DF17FCA64400760340 /* avconfig.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
83BCB8E317FCA64400760340 /* timecode.c in Sources */ = {isa = PBXBuildFile; fileRef = 83BCB8E017FCA64400760340 /* timecode.c */; };
|
||||
83BCB8E417FCA64400760340 /* timecode.h in Headers */ = {isa = PBXBuildFile; fileRef = 83BCB8E117FCA64400760340 /* timecode.h */; };
|
||||
|
@ -548,6 +581,39 @@
|
|||
830F0DCF17FC934D00042E8F /* spdif.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = spdif.c; sourceTree = "<group>"; };
|
||||
830F0DD017FC934D00042E8F /* spdif.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = spdif.h; sourceTree = "<group>"; };
|
||||
830F0DD417FC93E400042E8F /* xwma.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xwma.c; sourceTree = "<group>"; };
|
||||
833C3794180328A300CBA602 /* takdec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = takdec.c; sourceTree = "<group>"; };
|
||||
833C3796180328B300CBA602 /* tak_parser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tak_parser.c; sourceTree = "<group>"; };
|
||||
833C3797180328B300CBA602 /* tak.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tak.c; sourceTree = "<group>"; };
|
||||
833C3798180328B300CBA602 /* tak.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tak.h; sourceTree = "<group>"; };
|
||||
833C3799180328B300CBA602 /* takdec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = takdec.c; sourceTree = "<group>"; };
|
||||
833C379E18032A2700CBA602 /* unary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unary.h; sourceTree = "<group>"; };
|
||||
833C37A018032A2F00CBA602 /* rawdec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rawdec.c; sourceTree = "<group>"; };
|
||||
833C37A118032A2F00CBA602 /* rawdec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rawdec.h; sourceTree = "<group>"; };
|
||||
833C37A418032A5000CBA602 /* apetag.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = apetag.c; sourceTree = "<group>"; };
|
||||
833C37A518032A5000CBA602 /* apetag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = apetag.h; sourceTree = "<group>"; };
|
||||
833C37A818032AAD00CBA602 /* img2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = img2.c; sourceTree = "<group>"; };
|
||||
833C37AA18032AEF00CBA602 /* diracdsp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = diracdsp.c; sourceTree = "<group>"; };
|
||||
833C37AB18032AEF00CBA602 /* diracdsp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = diracdsp.h; sourceTree = "<group>"; };
|
||||
833C37AC18032AEF00CBA602 /* dsputil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dsputil.c; sourceTree = "<group>"; };
|
||||
833C37AD18032AEF00CBA602 /* dsputil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dsputil.h; sourceTree = "<group>"; };
|
||||
833C37AE18032AEF00CBA602 /* diracdsp_mmx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = diracdsp_mmx.c; path = x86/diracdsp_mmx.c; sourceTree = "<group>"; };
|
||||
833C37AF18032AEF00CBA602 /* diracdsp_mmx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = diracdsp_mmx.h; path = x86/diracdsp_mmx.h; sourceTree = "<group>"; };
|
||||
833C37B018032AEF00CBA602 /* dsputil_x86.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dsputil_x86.h; path = x86/dsputil_x86.h; sourceTree = "<group>"; };
|
||||
833C37BA18032CF600CBA602 /* dirac_arith.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dirac_arith.c; sourceTree = "<group>"; };
|
||||
833C37BB18032CF600CBA602 /* dirac_arith.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dirac_arith.h; sourceTree = "<group>"; };
|
||||
833C37BC18032CF600CBA602 /* dirac_dwt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dirac_dwt.c; sourceTree = "<group>"; };
|
||||
833C37BD18032CF600CBA602 /* dirac_dwt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dirac_dwt.h; sourceTree = "<group>"; };
|
||||
833C37BE18032CF600CBA602 /* dirac_parser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dirac_parser.c; sourceTree = "<group>"; };
|
||||
833C37BF18032CF600CBA602 /* dirac.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dirac.c; sourceTree = "<group>"; };
|
||||
833C37C018032CF600CBA602 /* dirac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dirac.h; sourceTree = "<group>"; };
|
||||
833C37C118032CF600CBA602 /* diracdec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = diracdec.c; sourceTree = "<group>"; };
|
||||
833C37CA18032D4800CBA602 /* golomb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = golomb.c; sourceTree = "<group>"; };
|
||||
833C37CB18032D4800CBA602 /* golomb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = golomb.h; sourceTree = "<group>"; };
|
||||
833C37CC18032D4800CBA602 /* dirac_dwt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dirac_dwt.c; sourceTree = "<group>"; };
|
||||
833C37CD18032D4800CBA602 /* dirac_dwt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dirac_dwt.h; sourceTree = "<group>"; };
|
||||
833C37D218032E4800CBA602 /* dsputil_init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dsputil_init.c; sourceTree = "<group>"; };
|
||||
833C37D418032E7000CBA602 /* jrevdct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = jrevdct.c; sourceTree = "<group>"; };
|
||||
833C37D618032EA500CBA602 /* idct_xvid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = idct_xvid.h; sourceTree = "<group>"; };
|
||||
83BCB8DF17FCA64400760340 /* avconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = avconfig.h; sourceTree = "<group>"; };
|
||||
83BCB8E017FCA64400760340 /* timecode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = timecode.c; sourceTree = "<group>"; };
|
||||
83BCB8E117FCA64400760340 /* timecode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = timecode.h; sourceTree = "<group>"; };
|
||||
|
@ -635,6 +701,29 @@
|
|||
830F0B8E17FC4FB900042E8F /* libavcodec */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
833C37D418032E7000CBA602 /* jrevdct.c */,
|
||||
833C37CA18032D4800CBA602 /* golomb.c */,
|
||||
833C37CB18032D4800CBA602 /* golomb.h */,
|
||||
833C37BA18032CF600CBA602 /* dirac_arith.c */,
|
||||
833C37BB18032CF600CBA602 /* dirac_arith.h */,
|
||||
833C37BC18032CF600CBA602 /* dirac_dwt.c */,
|
||||
833C37BD18032CF600CBA602 /* dirac_dwt.h */,
|
||||
833C37BE18032CF600CBA602 /* dirac_parser.c */,
|
||||
833C37BF18032CF600CBA602 /* dirac.c */,
|
||||
833C37C018032CF600CBA602 /* dirac.h */,
|
||||
833C37C118032CF600CBA602 /* diracdec.c */,
|
||||
833C37AA18032AEF00CBA602 /* diracdsp.c */,
|
||||
833C37AB18032AEF00CBA602 /* diracdsp.h */,
|
||||
833C37AC18032AEF00CBA602 /* dsputil.c */,
|
||||
833C37AD18032AEF00CBA602 /* dsputil.h */,
|
||||
833C37AE18032AEF00CBA602 /* diracdsp_mmx.c */,
|
||||
833C37AF18032AEF00CBA602 /* diracdsp_mmx.h */,
|
||||
833C37B018032AEF00CBA602 /* dsputil_x86.h */,
|
||||
833C379E18032A2700CBA602 /* unary.h */,
|
||||
833C3796180328B300CBA602 /* tak_parser.c */,
|
||||
833C3797180328B300CBA602 /* tak.c */,
|
||||
833C3798180328B300CBA602 /* tak.h */,
|
||||
833C3799180328B300CBA602 /* takdec.c */,
|
||||
830F0D9017FC8EAC00042E8F /* dvdata.c */,
|
||||
830F0D9117FC8EAC00042E8F /* dvdata.h */,
|
||||
830F0D8017FC8E8B00042E8F /* aac_tablegen_decl.h */,
|
||||
|
@ -764,6 +853,12 @@
|
|||
830F0BAD17FC4FB900042E8F /* libavformat */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
833C37A818032AAD00CBA602 /* img2.c */,
|
||||
833C37A418032A5000CBA602 /* apetag.c */,
|
||||
833C37A518032A5000CBA602 /* apetag.h */,
|
||||
833C37A018032A2F00CBA602 /* rawdec.c */,
|
||||
833C37A118032A2F00CBA602 /* rawdec.h */,
|
||||
833C3794180328A300CBA602 /* takdec.c */,
|
||||
830F0DD417FC93E400042E8F /* xwma.c */,
|
||||
830F0DCF17FC934D00042E8F /* spdif.c */,
|
||||
830F0DD017FC934D00042E8F /* spdif.h */,
|
||||
|
@ -948,6 +1043,10 @@
|
|||
830F0D0717FC80B400042E8F /* x86 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
833C37D618032EA500CBA602 /* idct_xvid.h */,
|
||||
833C37D218032E4800CBA602 /* dsputil_init.c */,
|
||||
833C37CC18032D4800CBA602 /* dirac_dwt.c */,
|
||||
833C37CD18032D4800CBA602 /* dirac_dwt.h */,
|
||||
830F0DC317FC92EE00042E8F /* videodsp_init.c */,
|
||||
830F0DBD17FC922C00042E8F /* h264chroma_init.c */,
|
||||
830F0DA917FC8FBD00042E8F /* dct_init.c */,
|
||||
|
@ -1007,6 +1106,7 @@
|
|||
B09E94940D74834B0064F138 /* config.h in Headers */,
|
||||
830F0BD217FC4FB900042E8F /* avcodec.h in Headers */,
|
||||
830F0D7217FC8C1300042E8F /* ast.h in Headers */,
|
||||
833C37A718032A5000CBA602 /* apetag.h in Headers */,
|
||||
830F0D8917FC8E8B00042E8F /* aac_tablegen.h in Headers */,
|
||||
830F0D3117FC841B00042E8F /* imgutils.h in Headers */,
|
||||
830F0C6C17FC7DB100042E8F /* bprint.h in Headers */,
|
||||
|
@ -1030,6 +1130,8 @@
|
|||
830F0CFB17FC7F1E00042E8F /* thread.h in Headers */,
|
||||
830F0D6617FC8A3300042E8F /* options_table.h in Headers */,
|
||||
830F0CF317FC7F1E00042E8F /* raw.h in Headers */,
|
||||
833C37B618032AEF00CBA602 /* diracdsp_mmx.h in Headers */,
|
||||
833C37B418032AEF00CBA602 /* dsputil.h in Headers */,
|
||||
830F0C3F17FC554D00042E8F /* timer.h in Headers */,
|
||||
830F0D1E17FC82AB00042E8F /* colorspace.h in Headers */,
|
||||
830F0DBA17FC921D00042E8F /* cpu.h in Headers */,
|
||||
|
@ -1037,15 +1139,18 @@
|
|||
830F0BDF17FC4FB900042E8F /* put_bits.h in Headers */,
|
||||
830F0C7217FC7DB100042E8F /* rc4.h in Headers */,
|
||||
830F0C2517FC527400042E8F /* bswap.h in Headers */,
|
||||
833C379F18032A2700CBA602 /* unary.h in Headers */,
|
||||
830F0CDD17FC7F1E00042E8F /* faandct.h in Headers */,
|
||||
830F0D0B17FC80B400042E8F /* lsp_mips.h in Headers */,
|
||||
830F0C2B17FC54F800042E8F /* srtp.h in Headers */,
|
||||
830F0D5E17FC89BD00042E8F /* options_table.h in Headers */,
|
||||
830F0CEC17FC7F1E00042E8F /* lsp.h in Headers */,
|
||||
830F0D6517FC8A3300042E8F /* audiointerleave.h in Headers */,
|
||||
833C37A318032A2F00CBA602 /* rawdec.h in Headers */,
|
||||
830F0D3D17FC846C00042E8F /* random_seed.h in Headers */,
|
||||
830F0CCA17FC7F1E00042E8F /* bytestream.h in Headers */,
|
||||
830F0D0317FC7F4000042E8F /* sinewin_tablegen.h in Headers */,
|
||||
833C37C518032CF600CBA602 /* dirac_dwt.h in Headers */,
|
||||
830F0CDF17FC7F1E00042E8F /* faanidct.h in Headers */,
|
||||
830F0DD217FC934D00042E8F /* spdif.h in Headers */,
|
||||
830F0BDE17FC4FB900042E8F /* parser.h in Headers */,
|
||||
|
@ -1072,6 +1177,7 @@
|
|||
830F0C6A17FC7DB100042E8F /* avassert.h in Headers */,
|
||||
830F0D6D17FC8C0700042E8F /* aactab.h in Headers */,
|
||||
830F0BEC17FC4FB900042E8F /* wmavoice_data.h in Headers */,
|
||||
833C37D118032D4800CBA602 /* dirac_dwt.h in Headers */,
|
||||
830F0D7917FC8C7300042E8F /* mpeg4audio.h in Headers */,
|
||||
830F0C3A17FC554D00042E8F /* des.h in Headers */,
|
||||
830F0BF117FC4FB900042E8F /* avi.h in Headers */,
|
||||
|
@ -1088,6 +1194,7 @@
|
|||
830F0CDB17FC7F1E00042E8F /* error_resilience.h in Headers */,
|
||||
830F0C4A17FC7CA300042E8F /* avio_internal.h in Headers */,
|
||||
830F0C7017FC7DB100042E8F /* pixdesc.h in Headers */,
|
||||
833C37C318032CF600CBA602 /* dirac_arith.h in Headers */,
|
||||
830F0CF717FC7F1E00042E8F /* rnd_avg.h in Headers */,
|
||||
830F0D4117FC848D00042E8F /* sha.h in Headers */,
|
||||
830F0CEE17FC7F1E00042E8F /* mpeg12data.h in Headers */,
|
||||
|
@ -1098,7 +1205,9 @@
|
|||
830F0CF117FC7F1E00042E8F /* ratecontrol.h in Headers */,
|
||||
830F0C1417FC500B00042E8F /* fft-internal.h in Headers */,
|
||||
830F0D8E17FC8E8B00042E8F /* sbr.h in Headers */,
|
||||
833C37B218032AEF00CBA602 /* diracdsp.h in Headers */,
|
||||
830F0C3D17FC554D00042E8F /* internal.h in Headers */,
|
||||
833C37D718032EA500CBA602 /* idct_xvid.h in Headers */,
|
||||
830F0CF617FC7F1E00042E8F /* rl.h in Headers */,
|
||||
830F0D8D17FC8E8B00042E8F /* dv_profile.h in Headers */,
|
||||
830F0D3917FC844E00042E8F /* parseutils.h in Headers */,
|
||||
|
@ -1109,6 +1218,7 @@
|
|||
830F0C4C17FC7CA300042E8F /* internal.h in Headers */,
|
||||
830F0BFC17FC4FB900042E8F /* bswap.h in Headers */,
|
||||
830F0D8A17FC8E8B00042E8F /* aacps.h in Headers */,
|
||||
833C37C818032CF600CBA602 /* dirac.h in Headers */,
|
||||
830F0BD617FC4FB900042E8F /* fft.h in Headers */,
|
||||
830F0CE317FC7F1E00042E8F /* frame_thread_encoder.h in Headers */,
|
||||
830F0BE617FC4FB900042E8F /* wmadata.h in Headers */,
|
||||
|
@ -1116,11 +1226,14 @@
|
|||
830F0D2417FC82AB00042E8F /* fifo.h in Headers */,
|
||||
830F0BD917FC4FB900042E8F /* mathops.h in Headers */,
|
||||
830F0C3C17FC554D00042E8F /* float_dsp.h in Headers */,
|
||||
833C37CF18032D4800CBA602 /* golomb.h in Headers */,
|
||||
830F0C8117FC7ED100042E8F /* crc.h in Headers */,
|
||||
833C379C180328B300CBA602 /* tak.h in Headers */,
|
||||
830F0DB817FC921D00042E8F /* asm.h in Headers */,
|
||||
830F0CC517FC7F1E00042E8F /* acelp_pitch_delay.h in Headers */,
|
||||
830F0D8F17FC8E8B00042E8F /* sbrdsp.h in Headers */,
|
||||
830F0CCE17FC7F1E00042E8F /* celp_math.h in Headers */,
|
||||
833C37B718032AEF00CBA602 /* dsputil_x86.h in Headers */,
|
||||
830F0CFA17FC7F1E00042E8F /* sinewin.h in Headers */,
|
||||
830F0CC717FC7F1E00042E8F /* acelp_vectors.h in Headers */,
|
||||
);
|
||||
|
@ -1189,6 +1302,7 @@
|
|||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
833C37A918032AAD00CBA602 /* img2.c in Sources */,
|
||||
830F0D6717FC8A3300042E8F /* options.c in Sources */,
|
||||
830F0DAF17FC8FBD00042E8F /* fmtconvert_init.c in Sources */,
|
||||
830F0DD617FC93E400042E8F /* xwma.c in Sources */,
|
||||
|
@ -1203,11 +1317,15 @@
|
|||
830F0DAE17FC8FBD00042E8F /* fft_init.c in Sources */,
|
||||
830F0D2F17FC841B00042E8F /* error.c in Sources */,
|
||||
830F0BDB17FC4FB900042E8F /* mdct.c in Sources */,
|
||||
833C37A618032A5000CBA602 /* apetag.c in Sources */,
|
||||
830F0D5817FC893E00042E8F /* bitstream.c in Sources */,
|
||||
833C37A218032A2F00CBA602 /* rawdec.c in Sources */,
|
||||
830F0C7617FC7DCB00042E8F /* avstring.c in Sources */,
|
||||
830F0DCD17FC933100042E8F /* w64.c in Sources */,
|
||||
833C37D518032E7000CBA602 /* jrevdct.c in Sources */,
|
||||
830F0BE217FC4FB900042E8F /* utils.c in Sources */,
|
||||
830F0CF917FC7F1E00042E8F /* sinewin.c in Sources */,
|
||||
833C37C418032CF600CBA602 /* dirac_dwt.c in Sources */,
|
||||
830F0CE417FC7F1E00042E8F /* h264chroma_template.c in Sources */,
|
||||
830F0BEF17FC4FB900042E8F /* asf.c in Sources */,
|
||||
830F0BD517FC4FB900042E8F /* fft.c in Sources */,
|
||||
|
@ -1225,13 +1343,16 @@
|
|||
830F0D3317FC841B00042E8F /* opt.c in Sources */,
|
||||
830F0D7317FC8C1300042E8F /* astdec.c in Sources */,
|
||||
830F0D5317FC891800042E8F /* file_open.c in Sources */,
|
||||
833C379D180328B300CBA602 /* takdec.c in Sources */,
|
||||
830F0D7B17FC8E2400042E8F /* avidec.c in Sources */,
|
||||
830F0D4F17FC862400042E8F /* utils.c in Sources */,
|
||||
830F0BEB17FC4FB900042E8F /* wmavoice.c in Sources */,
|
||||
833C37B318032AEF00CBA602 /* dsputil.c in Sources */,
|
||||
830F0CC217FC7F1E00042E8F /* acelp_filters.c in Sources */,
|
||||
830F0DB017FC8FBD00042E8F /* hpeldsp_init.c in Sources */,
|
||||
830F0C1B17FC523000042E8F /* url.c in Sources */,
|
||||
830F0CC417FC7F1E00042E8F /* acelp_pitch_delay.c in Sources */,
|
||||
833C37C218032CF600CBA602 /* dirac_arith.c in Sources */,
|
||||
830F0CEB17FC7F1E00042E8F /* lsp.c in Sources */,
|
||||
830F0D1317FC815000042E8F /* constants.c in Sources */,
|
||||
830F0BE417FC4FB900042E8F /* wma_common.c in Sources */,
|
||||
|
@ -1242,9 +1363,12 @@
|
|||
830F0CE917FC7F1E00042E8F /* imgconvert.c in Sources */,
|
||||
830F0CE717FC7F1E00042E8F /* hpeldsp.c in Sources */,
|
||||
830F0CCB17FC7F1E00042E8F /* celp_filters.c in Sources */,
|
||||
833C37B518032AEF00CBA602 /* diracdsp_mmx.c in Sources */,
|
||||
830F0BF717FC4FB900042E8F /* format.c in Sources */,
|
||||
830F0CC817FC7F1E00042E8F /* avpacket.c in Sources */,
|
||||
833C37CE18032D4800CBA602 /* golomb.c in Sources */,
|
||||
830F0C3917FC554D00042E8F /* des.c in Sources */,
|
||||
833C37C918032CF600CBA602 /* diracdec.c in Sources */,
|
||||
830F0CD217FC7F1E00042E8F /* dct32_float.c in Sources */,
|
||||
830F0D3217FC841B00042E8F /* intfloat_readwrite.c in Sources */,
|
||||
830F0DC917FC931700042E8F /* pcm.c in Sources */,
|
||||
|
@ -1255,6 +1379,7 @@
|
|||
830F0D4D17FC862400042E8F /* time.c in Sources */,
|
||||
830F0C0817FC4FB900042E8F /* mem.c in Sources */,
|
||||
830F0CDE17FC7F1E00042E8F /* faanidct.c in Sources */,
|
||||
833C379B180328B300CBA602 /* tak.c in Sources */,
|
||||
830F0CC917FC7F1E00042E8F /* bit_depth_template.c in Sources */,
|
||||
830F0D4017FC848D00042E8F /* sha.c in Sources */,
|
||||
830F0BF417FC4FB900042E8F /* aviobuf.c in Sources */,
|
||||
|
@ -1275,13 +1400,16 @@
|
|||
830F0C8217FC7ED100042E8F /* dict.c in Sources */,
|
||||
830F0D7817FC8C7300042E8F /* mpeg4audio.c in Sources */,
|
||||
830F0D5F17FC89BD00042E8F /* options.c in Sources */,
|
||||
833C37D318032E4800CBA602 /* dsputil_init.c in Sources */,
|
||||
830F0DB917FC921D00042E8F /* cpu.c in Sources */,
|
||||
830F0C7D17FC7E4E00042E8F /* mathematics.c in Sources */,
|
||||
830F0BDD17FC4FB900042E8F /* parser.c in Sources */,
|
||||
830F0C5C17FC7CEA00042E8F /* id3v1.c in Sources */,
|
||||
830F0CFC17FC7F1E00042E8F /* videodsp.c in Sources */,
|
||||
830F0D8C17FC8E8B00042E8F /* dv_profile.c in Sources */,
|
||||
833C37B118032AEF00CBA602 /* diracdsp.c in Sources */,
|
||||
830F0CD017FC7F1E00042E8F /* dct.c in Sources */,
|
||||
833C3795180328A300CBA602 /* takdec.c in Sources */,
|
||||
830F0DC217FC929E00042E8F /* mux.c in Sources */,
|
||||
830F0BF517FC4FB900042E8F /* cutils.c in Sources */,
|
||||
830F0D2E17FC841B00042E8F /* channel_layout.c in Sources */,
|
||||
|
@ -1289,13 +1417,17 @@
|
|||
830F0BE717FC4FB900042E8F /* wmadec.c in Sources */,
|
||||
830F0CC617FC7F1E00042E8F /* acelp_vectors.c in Sources */,
|
||||
830F0DC417FC92EE00042E8F /* videodsp_init.c in Sources */,
|
||||
833C379A180328B300CBA602 /* tak_parser.c in Sources */,
|
||||
830F0C2E17FC551F00042E8F /* asfcrypt.c in Sources */,
|
||||
830F0D6C17FC8C0700042E8F /* aactab.c in Sources */,
|
||||
830F0D9217FC8EAC00042E8F /* dvdata.c in Sources */,
|
||||
833C37D018032D4800CBA602 /* dirac_dwt.c in Sources */,
|
||||
830F0BF617FC4FB900042E8F /* file.c in Sources */,
|
||||
830F0D3817FC844E00042E8F /* parseutils.c in Sources */,
|
||||
830F0D2017FC82AB00042E8F /* cpu.c in Sources */,
|
||||
833C37C618032CF600CBA602 /* dirac_parser.c in Sources */,
|
||||
830F0CED17FC7F1E00042E8F /* mpeg12data.c in Sources */,
|
||||
833C37C718032CF600CBA602 /* dirac.c in Sources */,
|
||||
830F0D7E17FC8E4800042E8F /* dv.c in Sources */,
|
||||
830F0C7B17FC7E4E00042E8F /* crc.c in Sources */,
|
||||
830F0BE817FC4FB900042E8F /* wmalosslessdec.c in Sources */,
|
||||
|
|
|
@ -13,6 +13,10 @@
|
|||
#define TUNECPU generic
|
||||
#define HAVE_MMX 0
|
||||
#define HAVE_MMX_INLINE 0
|
||||
#define HAVE_SSE 0
|
||||
#define HAVE_SSE2 0
|
||||
#define HAVE_SSSE3_EXTERNAL 0
|
||||
#define HAVE_SSE4_EXTERNAL 0
|
||||
#define emms_c()
|
||||
#define HAVE_MMX2 0
|
||||
#define HAVE_MMXEXT 0
|
||||
|
@ -28,7 +32,7 @@
|
|||
#define HAVE_LOCALTIME_R 1
|
||||
#define HAVE_LRINTF 1
|
||||
#undef HAVE_VHOOK
|
||||
#undef CONFIG_ENCODERS
|
||||
#define CONFIG_ENCODERS 0
|
||||
#define CONFIG_DECODERS 1
|
||||
#undef CONFIG_MPEGAUDIO_HP
|
||||
#undef CONFIG_VIDEO4LINUX
|
||||
|
@ -61,7 +65,7 @@
|
|||
#define CONFIG_MEMORY_POISONING 0
|
||||
#define FF_MEMORY_POISON 0x2a
|
||||
#define CONFIG_MDCT 1
|
||||
#define CONFIG_DSPUTIL 0
|
||||
#define CONFIG_DSPUTIL 1
|
||||
#define FFMPEG_CONFIGURATION "Xcode mess lol"
|
||||
#define FFMPEG_LICENSE "LGPL"
|
||||
#undef CONFIG_FFSERVER
|
||||
|
@ -134,7 +138,7 @@
|
|||
#define CONFIG_CSCD_DECODER 0
|
||||
#define CONFIG_CYUV_DECODER 0
|
||||
#define CONFIG_DFA_DECODER 0
|
||||
#define CONFIG_DIRAC_DECODER 0
|
||||
#define CONFIG_DIRAC_DECODER 1
|
||||
#define CONFIG_DNXHD_ENCODER 0
|
||||
#define CONFIG_DNXHD_DECODER 0
|
||||
#define CONFIG_DPX_ENCODER 0
|
||||
|
@ -440,7 +444,7 @@
|
|||
#define CONFIG_SONIC_DECODER 0
|
||||
#define CONFIG_SONIC_LS_ENCODER 0
|
||||
#define CONFIG_SONIC_LS_DECODER 0
|
||||
#define CONFIG_TAK_DECODER 0
|
||||
#define CONFIG_TAK_DECODER 1
|
||||
#define CONFIG_TRUEHD_DECODER 0
|
||||
#define CONFIG_TRUESPEECH_DECODER 0
|
||||
#define CONFIG_TTA_ENCODER 0
|
||||
|
@ -652,7 +656,7 @@
|
|||
#define CONFIG_CAVSVIDEO_PARSER 0
|
||||
#define CONFIG_COOK_PARSER 0
|
||||
#define CONFIG_DCA_PARSER 0
|
||||
#define CONFIG_DIRAC_PARSER 0
|
||||
#define CONFIG_DIRAC_PARSER 1
|
||||
#define CONFIG_DNXHD_PARSER 0
|
||||
#define CONFIG_DVBSUB_PARSER 0
|
||||
#define CONFIG_DVDSUB_PARSER 0
|
||||
|
@ -671,7 +675,7 @@
|
|||
#define CONFIG_PNM_PARSER 0
|
||||
#define CONFIG_RV30_PARSER 0
|
||||
#define CONFIG_RV40_PARSER 0
|
||||
#define CONFIG_TAK_PARSER 0
|
||||
#define CONFIG_TAK_PARSER 1
|
||||
#define CONFIG_VC1_PARSER 0
|
||||
#define CONFIG_VORBIS_PARSER 0
|
||||
#define CONFIG_VP3_PARSER 0
|
||||
|
@ -980,7 +984,7 @@
|
|||
#define CONFIG_SUBVIEWER_DEMUXER 0
|
||||
#define CONFIG_SWF_MUXER 0
|
||||
#define CONFIG_SWF_DEMUXER 0
|
||||
#define CONFIG_TAK_DEMUXER 0
|
||||
#define CONFIG_TAK_DEMUXER 1
|
||||
#define CONFIG_TEE_MUXER 0
|
||||
#define CONFIG_TEDCAPTIONS_DEMUXER 0
|
||||
#define CONFIG_TG2_MUXER 0
|
||||
|
|
|
@ -0,0 +1,334 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Marco Gerards <marco@gnu.org>
|
||||
* Copyright (C) 2009 David Conrad
|
||||
* Copyright (C) 2011 Jordi Ortiz
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Dirac Decoder
|
||||
* @author Marco Gerards <marco@gnu.org>, David Conrad, Jordi Ortiz <nenjordi@gmail.com>
|
||||
*/
|
||||
|
||||
#include "libavutil/imgutils.h"
|
||||
#include "dirac.h"
|
||||
#include "avcodec.h"
|
||||
#include "golomb.h"
|
||||
#include "mpeg12data.h"
|
||||
|
||||
/* defaults for source parameters */
|
||||
static const dirac_source_params dirac_source_parameters_defaults[] = {
|
||||
{ 640, 480, 2, 0, 0, 1, 1, 640, 480, 0, 0, 1, 0 },
|
||||
{ 176, 120, 2, 0, 0, 9, 2, 176, 120, 0, 0, 1, 1 },
|
||||
{ 176, 144, 2, 0, 1, 10, 3, 176, 144, 0, 0, 1, 2 },
|
||||
{ 352, 240, 2, 0, 0, 9, 2, 352, 240, 0, 0, 1, 1 },
|
||||
{ 352, 288, 2, 0, 1, 10, 3, 352, 288, 0, 0, 1, 2 },
|
||||
{ 704, 480, 2, 0, 0, 9, 2, 704, 480, 0, 0, 1, 1 },
|
||||
{ 704, 576, 2, 0, 1, 10, 3, 704, 576, 0, 0, 1, 2 },
|
||||
{ 720, 480, 1, 1, 0, 4, 2, 704, 480, 8, 0, 3, 1 },
|
||||
{ 720, 576, 1, 1, 1, 3, 3, 704, 576, 8, 0, 3, 2 },
|
||||
{ 1280, 720, 1, 0, 1, 7, 1, 1280, 720, 0, 0, 3, 3 },
|
||||
{ 1280, 720, 1, 0, 1, 6, 1, 1280, 720, 0, 0, 3, 3 },
|
||||
{ 1920, 1080, 1, 1, 1, 4, 1, 1920, 1080, 0, 0, 3, 3 },
|
||||
{ 1920, 1080, 1, 1, 1, 3, 1, 1920, 1080, 0, 0, 3, 3 },
|
||||
{ 1920, 1080, 1, 0, 1, 7, 1, 1920, 1080, 0, 0, 3, 3 },
|
||||
{ 1920, 1080, 1, 0, 1, 6, 1, 1920, 1080, 0, 0, 3, 3 },
|
||||
{ 2048, 1080, 0, 0, 1, 2, 1, 2048, 1080, 0, 0, 4, 4 },
|
||||
{ 4096, 2160, 0, 0, 1, 2, 1, 4096, 2160, 0, 0, 4, 4 },
|
||||
{ 3840, 2160, 1, 0, 1, 7, 1, 3840, 2160, 0, 0, 3, 3 },
|
||||
{ 3840, 2160, 1, 0, 1, 6, 1, 3840, 2160, 0, 0, 3, 3 },
|
||||
{ 7680, 4320, 1, 0, 1, 7, 1, 3840, 2160, 0, 0, 3, 3 },
|
||||
{ 7680, 4320, 1, 0, 1, 6, 1, 3840, 2160, 0, 0, 3, 3 },
|
||||
};
|
||||
|
||||
/* [DIRAC_STD] Table 10.4 - Available preset pixel aspect ratio values */
|
||||
static const AVRational dirac_preset_aspect_ratios[] = {
|
||||
{1, 1},
|
||||
{10, 11},
|
||||
{12, 11},
|
||||
{40, 33},
|
||||
{16, 11},
|
||||
{4, 3},
|
||||
};
|
||||
|
||||
/* [DIRAC_STD] Values 9,10 of 10.3.5 Frame Rate.
|
||||
* Table 10.3 Available preset frame rate values
|
||||
*/
|
||||
static const AVRational dirac_frame_rate[] = {
|
||||
{15000, 1001},
|
||||
{25, 2},
|
||||
};
|
||||
|
||||
/* [DIRAC_STD] This should be equivalent to Table 10.5 Available signal
|
||||
* range presets */
|
||||
static const struct {
|
||||
uint8_t bitdepth;
|
||||
enum AVColorRange color_range;
|
||||
} pixel_range_presets[] = {
|
||||
{8, AVCOL_RANGE_JPEG},
|
||||
{8, AVCOL_RANGE_MPEG},
|
||||
{10, AVCOL_RANGE_MPEG},
|
||||
{12, AVCOL_RANGE_MPEG},
|
||||
};
|
||||
|
||||
static const enum AVColorPrimaries dirac_primaries[] = {
|
||||
AVCOL_PRI_BT709,
|
||||
AVCOL_PRI_SMPTE170M,
|
||||
AVCOL_PRI_BT470BG,
|
||||
};
|
||||
|
||||
static const struct {
|
||||
enum AVColorPrimaries color_primaries;
|
||||
enum AVColorSpace colorspace;
|
||||
enum AVColorTransferCharacteristic color_trc;
|
||||
} dirac_color_presets[] = {
|
||||
{ AVCOL_PRI_BT709, AVCOL_SPC_BT709, AVCOL_TRC_BT709 },
|
||||
{ AVCOL_PRI_SMPTE170M, AVCOL_SPC_BT470BG, AVCOL_TRC_BT709 },
|
||||
{ AVCOL_PRI_BT470BG, AVCOL_SPC_BT470BG, AVCOL_TRC_BT709 },
|
||||
{ AVCOL_PRI_BT709, AVCOL_SPC_BT709, AVCOL_TRC_BT709 },
|
||||
{ AVCOL_PRI_BT709, AVCOL_SPC_BT709, AVCOL_TRC_UNSPECIFIED /* DCinema */ },
|
||||
};
|
||||
|
||||
/* [DIRAC_STD] Table 10.2 Supported chroma sampling formats + luma Offset */
|
||||
static const enum AVPixelFormat dirac_pix_fmt[2][3] = {
|
||||
{ AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P },
|
||||
{ AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ420P },
|
||||
};
|
||||
|
||||
/* [DIRAC_STD] 10.3 Parse Source Parameters.
|
||||
* source_parameters(base_video_format) */
|
||||
static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb,
|
||||
dirac_source_params *source)
|
||||
{
|
||||
AVRational frame_rate = {0,0};
|
||||
unsigned luma_depth = 8, luma_offset = 16;
|
||||
int idx;
|
||||
int chroma_x_shift, chroma_y_shift;
|
||||
|
||||
/* [DIRAC_STD] 10.3.2 Frame size. frame_size(video_params) */
|
||||
/* [DIRAC_STD] custom_dimensions_flag */
|
||||
if (get_bits1(gb)) {
|
||||
source->width = svq3_get_ue_golomb(gb); /* [DIRAC_STD] FRAME_WIDTH */
|
||||
source->height = svq3_get_ue_golomb(gb); /* [DIRAC_STD] FRAME_HEIGHT */
|
||||
}
|
||||
|
||||
/* [DIRAC_STD] 10.3.3 Chroma Sampling Format.
|
||||
* chroma_sampling_format(video_params) */
|
||||
/* [DIRAC_STD] custom_chroma_format_flag */
|
||||
if (get_bits1(gb))
|
||||
/* [DIRAC_STD] CHROMA_FORMAT_INDEX */
|
||||
source->chroma_format = svq3_get_ue_golomb(gb);
|
||||
if (source->chroma_format > 2U) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Unknown chroma format %d\n",
|
||||
source->chroma_format);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
/* [DIRAC_STD] 10.3.4 Scan Format. scan_format(video_params) */
|
||||
/* [DIRAC_STD] custom_scan_format_flag */
|
||||
if (get_bits1(gb))
|
||||
/* [DIRAC_STD] SOURCE_SAMPLING */
|
||||
source->interlaced = svq3_get_ue_golomb(gb);
|
||||
if (source->interlaced > 1U)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
/* [DIRAC_STD] 10.3.5 Frame Rate. frame_rate(video_params) */
|
||||
if (get_bits1(gb)) { /* [DIRAC_STD] custom_frame_rate_flag */
|
||||
source->frame_rate_index = svq3_get_ue_golomb(gb);
|
||||
|
||||
if (source->frame_rate_index > 10U)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
if (!source->frame_rate_index) {
|
||||
/* [DIRAC_STD] FRAME_RATE_NUMER */
|
||||
frame_rate.num = svq3_get_ue_golomb(gb);
|
||||
/* [DIRAC_STD] FRAME_RATE_DENOM */
|
||||
frame_rate.den = svq3_get_ue_golomb(gb);
|
||||
}
|
||||
}
|
||||
/* [DIRAC_STD] preset_frame_rate(video_params, index) */
|
||||
if (source->frame_rate_index > 0) {
|
||||
if (source->frame_rate_index <= 8)
|
||||
frame_rate = ff_mpeg12_frame_rate_tab[source->frame_rate_index];
|
||||
else
|
||||
/* [DIRAC_STD] Table 10.3 values 9-10 */
|
||||
frame_rate = dirac_frame_rate[source->frame_rate_index-9];
|
||||
}
|
||||
av_reduce(&avctx->time_base.num, &avctx->time_base.den,
|
||||
frame_rate.den, frame_rate.num, 1<<30);
|
||||
|
||||
/* [DIRAC_STD] 10.3.6 Pixel Aspect Ratio.
|
||||
* pixel_aspect_ratio(video_params) */
|
||||
if (get_bits1(gb)) { /* [DIRAC_STD] custom_pixel_aspect_ratio_flag */
|
||||
/* [DIRAC_STD] index */
|
||||
source->aspect_ratio_index = svq3_get_ue_golomb(gb);
|
||||
|
||||
if (source->aspect_ratio_index > 6U)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
if (!source->aspect_ratio_index) {
|
||||
avctx->sample_aspect_ratio.num = svq3_get_ue_golomb(gb);
|
||||
avctx->sample_aspect_ratio.den = svq3_get_ue_golomb(gb);
|
||||
}
|
||||
}
|
||||
/* [DIRAC_STD] Take value from Table 10.4 Available preset pixel
|
||||
* aspect ratio values */
|
||||
if (source->aspect_ratio_index > 0)
|
||||
avctx->sample_aspect_ratio =
|
||||
dirac_preset_aspect_ratios[source->aspect_ratio_index-1];
|
||||
|
||||
/* [DIRAC_STD] 10.3.7 Clean area. clean_area(video_params) */
|
||||
if (get_bits1(gb)) { /* [DIRAC_STD] custom_clean_area_flag */
|
||||
/* [DIRAC_STD] CLEAN_WIDTH */
|
||||
source->clean_width = svq3_get_ue_golomb(gb);
|
||||
/* [DIRAC_STD] CLEAN_HEIGHT */
|
||||
source->clean_height = svq3_get_ue_golomb(gb);
|
||||
/* [DIRAC_STD] CLEAN_LEFT_OFFSET */
|
||||
source->clean_left_offset = svq3_get_ue_golomb(gb);
|
||||
/* [DIRAC_STD] CLEAN_RIGHT_OFFSET */
|
||||
source->clean_right_offset = svq3_get_ue_golomb(gb);
|
||||
}
|
||||
|
||||
/* [DIRAC_STD] 10.3.8 Signal range. signal_range(video_params)
|
||||
* WARNING: Some adaptation seems to be done using the
|
||||
* AVCOL_RANGE_MPEG/JPEG values */
|
||||
if (get_bits1(gb)) { /* [DIRAC_STD] custom_signal_range_flag */
|
||||
/* [DIRAC_STD] index */
|
||||
source->pixel_range_index = svq3_get_ue_golomb(gb);
|
||||
|
||||
if (source->pixel_range_index > 4U)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
/* This assumes either fullrange or MPEG levels only */
|
||||
if (!source->pixel_range_index) {
|
||||
luma_offset = svq3_get_ue_golomb(gb);
|
||||
luma_depth = av_log2(svq3_get_ue_golomb(gb))+1;
|
||||
svq3_get_ue_golomb(gb); /* chroma offset */
|
||||
svq3_get_ue_golomb(gb); /* chroma excursion */
|
||||
avctx->color_range = luma_offset ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
|
||||
}
|
||||
}
|
||||
/* [DIRAC_STD] Table 10.5
|
||||
* Available signal range presets <--> pixel_range_presets */
|
||||
if (source->pixel_range_index > 0) {
|
||||
idx = source->pixel_range_index-1;
|
||||
luma_depth = pixel_range_presets[idx].bitdepth;
|
||||
avctx->color_range = pixel_range_presets[idx].color_range;
|
||||
}
|
||||
|
||||
if (luma_depth > 8)
|
||||
av_log(avctx, AV_LOG_WARNING, "Bitdepth greater than 8\n");
|
||||
|
||||
avctx->pix_fmt = dirac_pix_fmt[!luma_offset][source->chroma_format];
|
||||
avcodec_get_chroma_sub_sample(avctx->pix_fmt, &chroma_x_shift, &chroma_y_shift);
|
||||
if ((source->width % (1<<chroma_x_shift)) || (source->height % (1<<chroma_y_shift))) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Dimensions must be a integer multiply of the chroma subsampling\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
|
||||
/* [DIRAC_STD] 10.3.9 Colour specification. colour_spec(video_params) */
|
||||
if (get_bits1(gb)) { /* [DIRAC_STD] custom_colour_spec_flag */
|
||||
/* [DIRAC_STD] index */
|
||||
idx = source->color_spec_index = svq3_get_ue_golomb(gb);
|
||||
|
||||
if (source->color_spec_index > 4U)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
avctx->color_primaries = dirac_color_presets[idx].color_primaries;
|
||||
avctx->colorspace = dirac_color_presets[idx].colorspace;
|
||||
avctx->color_trc = dirac_color_presets[idx].color_trc;
|
||||
|
||||
if (!source->color_spec_index) {
|
||||
/* [DIRAC_STD] 10.3.9.1 Colour primaries */
|
||||
if (get_bits1(gb)) {
|
||||
idx = svq3_get_ue_golomb(gb);
|
||||
if (idx < 3U)
|
||||
avctx->color_primaries = dirac_primaries[idx];
|
||||
}
|
||||
/* [DIRAC_STD] 10.3.9.2 Colour matrix */
|
||||
if (get_bits1(gb)) {
|
||||
idx = svq3_get_ue_golomb(gb);
|
||||
if (!idx)
|
||||
avctx->colorspace = AVCOL_SPC_BT709;
|
||||
else if (idx == 1)
|
||||
avctx->colorspace = AVCOL_SPC_BT470BG;
|
||||
}
|
||||
/* [DIRAC_STD] 10.3.9.3 Transfer function */
|
||||
if (get_bits1(gb) && !svq3_get_ue_golomb(gb))
|
||||
avctx->color_trc = AVCOL_TRC_BT709;
|
||||
}
|
||||
} else {
|
||||
idx = source->color_spec_index;
|
||||
avctx->color_primaries = dirac_color_presets[idx].color_primaries;
|
||||
avctx->colorspace = dirac_color_presets[idx].colorspace;
|
||||
avctx->color_trc = dirac_color_presets[idx].color_trc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* [DIRAC_STD] 10. Sequence Header. sequence_header() */
|
||||
int avpriv_dirac_parse_sequence_header(AVCodecContext *avctx, GetBitContext *gb,
|
||||
dirac_source_params *source)
|
||||
{
|
||||
unsigned version_major;
|
||||
unsigned video_format, picture_coding_mode;
|
||||
int ret;
|
||||
|
||||
/* [DIRAC_SPEC] 10.1 Parse Parameters. parse_parameters() */
|
||||
version_major = svq3_get_ue_golomb(gb);
|
||||
svq3_get_ue_golomb(gb); /* version_minor */
|
||||
avctx->profile = svq3_get_ue_golomb(gb);
|
||||
avctx->level = svq3_get_ue_golomb(gb);
|
||||
/* [DIRAC_SPEC] sequence_header() -> base_video_format as defined in
|
||||
* 10.2 Base Video Format, table 10.1 Dirac predefined video formats */
|
||||
video_format = svq3_get_ue_golomb(gb);
|
||||
|
||||
if (version_major < 2)
|
||||
av_log(avctx, AV_LOG_WARNING, "Stream is old and may not work\n");
|
||||
else if (version_major > 2)
|
||||
av_log(avctx, AV_LOG_WARNING, "Stream may have unhandled features\n");
|
||||
|
||||
if (video_format > 20U)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
/* Fill in defaults for the source parameters. */
|
||||
*source = dirac_source_parameters_defaults[video_format];
|
||||
|
||||
/* [DIRAC_STD] 10.3 Source Parameters
|
||||
* Override the defaults. */
|
||||
if (ret = parse_source_parameters(avctx, gb, source))
|
||||
return ret;
|
||||
|
||||
if (ret = av_image_check_size(source->width, source->height, 0, avctx))
|
||||
return ret;
|
||||
|
||||
avcodec_set_dimensions(avctx, source->width, source->height);
|
||||
|
||||
/* [DIRAC_STD] picture_coding_mode shall be 0 for fields and 1 for frames
|
||||
* currently only used to signal field coding */
|
||||
picture_coding_mode = svq3_get_ue_golomb(gb);
|
||||
if (picture_coding_mode != 0) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Unsupported picture coding mode %d\n",
|
||||
picture_coding_mode);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Marco Gerards <marco@gnu.org>
|
||||
* Copyright (C) 2009 David Conrad
|
||||
* Copyright (C) 2011 Jordi Ortiz
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_DIRAC_H
|
||||
#define AVCODEC_DIRAC_H
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Interface to Dirac Decoder/Encoder
|
||||
* @author Marco Gerards <marco@gnu.org>
|
||||
* @author David Conrad
|
||||
* @author Jordi Ortiz
|
||||
*/
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "get_bits.h"
|
||||
|
||||
typedef struct dirac_source_params {
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
uint8_t chroma_format; ///< 0: 444 1: 422 2: 420
|
||||
|
||||
uint8_t interlaced;
|
||||
uint8_t top_field_first;
|
||||
|
||||
uint8_t frame_rate_index; ///< index into dirac_frame_rate[]
|
||||
uint8_t aspect_ratio_index; ///< index into dirac_aspect_ratio[]
|
||||
|
||||
uint16_t clean_width;
|
||||
uint16_t clean_height;
|
||||
uint16_t clean_left_offset;
|
||||
uint16_t clean_right_offset;
|
||||
|
||||
uint8_t pixel_range_index; ///< index into dirac_pixel_range_presets[]
|
||||
uint8_t color_spec_index; ///< index into dirac_color_spec_presets[]
|
||||
} dirac_source_params;
|
||||
|
||||
int avpriv_dirac_parse_sequence_header(AVCodecContext *avctx, GetBitContext *gb,
|
||||
dirac_source_params *source);
|
||||
|
||||
#endif /* AVCODEC_DIRAC_H */
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Marco Gerards <marco@gnu.org>
|
||||
* Copyright (C) 2009 David Conrad
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Arithmetic decoder for Dirac
|
||||
* @author Marco Gerards <marco@gnu.org>
|
||||
*/
|
||||
|
||||
#include "dirac_arith.h"
|
||||
|
||||
|
||||
const uint16_t ff_dirac_prob[256] = {
|
||||
0, 2, 5, 8, 11, 15, 20, 24,
|
||||
29, 35, 41, 47, 53, 60, 67, 74,
|
||||
82, 89, 97, 106, 114, 123, 132, 141,
|
||||
150, 160, 170, 180, 190, 201, 211, 222,
|
||||
233, 244, 256, 267, 279, 291, 303, 315,
|
||||
327, 340, 353, 366, 379, 392, 405, 419,
|
||||
433, 447, 461, 475, 489, 504, 518, 533,
|
||||
548, 563, 578, 593, 609, 624, 640, 656,
|
||||
672, 688, 705, 721, 738, 754, 771, 788,
|
||||
805, 822, 840, 857, 875, 892, 910, 928,
|
||||
946, 964, 983, 1001, 1020, 1038, 1057, 1076,
|
||||
1095, 1114, 1133, 1153, 1172, 1192, 1211, 1231,
|
||||
1251, 1271, 1291, 1311, 1332, 1352, 1373, 1393,
|
||||
1414, 1435, 1456, 1477, 1498, 1520, 1541, 1562,
|
||||
1584, 1606, 1628, 1649, 1671, 1694, 1716, 1738,
|
||||
1760, 1783, 1806, 1828, 1851, 1874, 1897, 1920,
|
||||
1935, 1942, 1949, 1955, 1961, 1968, 1974, 1980,
|
||||
1985, 1991, 1996, 2001, 2006, 2011, 2016, 2021,
|
||||
2025, 2029, 2033, 2037, 2040, 2044, 2047, 2050,
|
||||
2053, 2056, 2058, 2061, 2063, 2065, 2066, 2068,
|
||||
2069, 2070, 2071, 2072, 2072, 2072, 2072, 2072,
|
||||
2072, 2071, 2070, 2069, 2068, 2066, 2065, 2063,
|
||||
2060, 2058, 2055, 2052, 2049, 2045, 2042, 2038,
|
||||
2033, 2029, 2024, 2019, 2013, 2008, 2002, 1996,
|
||||
1989, 1982, 1975, 1968, 1960, 1952, 1943, 1934,
|
||||
1925, 1916, 1906, 1896, 1885, 1874, 1863, 1851,
|
||||
1839, 1827, 1814, 1800, 1786, 1772, 1757, 1742,
|
||||
1727, 1710, 1694, 1676, 1659, 1640, 1622, 1602,
|
||||
1582, 1561, 1540, 1518, 1495, 1471, 1447, 1422,
|
||||
1396, 1369, 1341, 1312, 1282, 1251, 1219, 1186,
|
||||
1151, 1114, 1077, 1037, 995, 952, 906, 857,
|
||||
805, 750, 690, 625, 553, 471, 376, 255
|
||||
};
|
||||
|
||||
const uint8_t ff_dirac_next_ctx[DIRAC_CTX_COUNT] = {
|
||||
[CTX_ZPZN_F1] = CTX_ZP_F2,
|
||||
[CTX_ZPNN_F1] = CTX_ZP_F2,
|
||||
[CTX_ZP_F2] = CTX_ZP_F3,
|
||||
[CTX_ZP_F3] = CTX_ZP_F4,
|
||||
[CTX_ZP_F4] = CTX_ZP_F5,
|
||||
[CTX_ZP_F5] = CTX_ZP_F6,
|
||||
[CTX_ZP_F6] = CTX_ZP_F6,
|
||||
[CTX_NPZN_F1] = CTX_NP_F2,
|
||||
[CTX_NPNN_F1] = CTX_NP_F2,
|
||||
[CTX_NP_F2] = CTX_NP_F3,
|
||||
[CTX_NP_F3] = CTX_NP_F4,
|
||||
[CTX_NP_F4] = CTX_NP_F5,
|
||||
[CTX_NP_F5] = CTX_NP_F6,
|
||||
[CTX_NP_F6] = CTX_NP_F6,
|
||||
[CTX_DELTA_Q_F] = CTX_DELTA_Q_F,
|
||||
};
|
||||
|
||||
int16_t ff_dirac_prob_branchless[256][2];
|
||||
|
||||
void ff_dirac_init_arith_decoder(DiracArith *c, GetBitContext *gb, int length)
|
||||
{
|
||||
int i;
|
||||
align_get_bits(gb);
|
||||
|
||||
length = FFMIN(length, get_bits_left(gb)/8);
|
||||
|
||||
c->bytestream = gb->buffer + get_bits_count(gb)/8;
|
||||
c->bytestream_end = c->bytestream + length;
|
||||
skip_bits_long(gb, length*8);
|
||||
|
||||
c->low = 0;
|
||||
for (i = 0; i < 4; i++) {
|
||||
c->low <<= 8;
|
||||
if (c->bytestream < c->bytestream_end)
|
||||
c->low |= *c->bytestream++;
|
||||
else
|
||||
c->low |= 0xff;
|
||||
}
|
||||
|
||||
c->counter = -16;
|
||||
c->range = 0xffff;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
ff_dirac_prob_branchless[i][0] = ff_dirac_prob[255-i];
|
||||
ff_dirac_prob_branchless[i][1] = -ff_dirac_prob[i];
|
||||
}
|
||||
|
||||
for (i = 0; i < DIRAC_CTX_COUNT; i++)
|
||||
c->contexts[i] = 0x8000;
|
||||
}
|
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Marco Gerards <marco@gnu.org>
|
||||
* Copyright (C) 2009 David Conrad
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Arithmetic decoder for Dirac
|
||||
* @author Marco Gerards <marco@gnu.org>
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_DIRAC_ARITH_H
|
||||
#define AVCODEC_DIRAC_ARITH_H
|
||||
|
||||
#include "bytestream.h"
|
||||
#include "get_bits.h"
|
||||
|
||||
enum dirac_arith_contexts {
|
||||
CTX_ZPZN_F1,
|
||||
CTX_ZPNN_F1,
|
||||
CTX_NPZN_F1,
|
||||
CTX_NPNN_F1,
|
||||
CTX_ZP_F2,
|
||||
CTX_ZP_F3,
|
||||
CTX_ZP_F4,
|
||||
CTX_ZP_F5,
|
||||
CTX_ZP_F6,
|
||||
CTX_NP_F2,
|
||||
CTX_NP_F3,
|
||||
CTX_NP_F4,
|
||||
CTX_NP_F5,
|
||||
CTX_NP_F6,
|
||||
CTX_COEFF_DATA,
|
||||
CTX_SIGN_NEG,
|
||||
CTX_SIGN_ZERO,
|
||||
CTX_SIGN_POS,
|
||||
CTX_ZERO_BLOCK,
|
||||
CTX_DELTA_Q_F,
|
||||
CTX_DELTA_Q_DATA,
|
||||
CTX_DELTA_Q_SIGN,
|
||||
|
||||
DIRAC_CTX_COUNT
|
||||
};
|
||||
|
||||
// Dirac resets the arith decoder between decoding various types of data,
|
||||
// so many contexts are never used simultaneously. Thus, we can reduce
|
||||
// the number of contexts needed by reusing them.
|
||||
#define CTX_SB_F1 CTX_ZP_F5
|
||||
#define CTX_SB_DATA 0
|
||||
#define CTX_PMODE_REF1 0
|
||||
#define CTX_PMODE_REF2 1
|
||||
#define CTX_GLOBAL_BLOCK 2
|
||||
#define CTX_MV_F1 CTX_ZP_F2
|
||||
#define CTX_MV_DATA 0
|
||||
#define CTX_DC_F1 CTX_ZP_F5
|
||||
#define CTX_DC_DATA 0
|
||||
|
||||
typedef struct {
|
||||
unsigned low;
|
||||
uint16_t range;
|
||||
int16_t counter;
|
||||
|
||||
const uint8_t *bytestream;
|
||||
const uint8_t *bytestream_end;
|
||||
|
||||
uint16_t contexts[DIRAC_CTX_COUNT];
|
||||
} DiracArith;
|
||||
|
||||
extern const uint8_t ff_dirac_next_ctx[DIRAC_CTX_COUNT];
|
||||
extern const uint16_t ff_dirac_prob[256];
|
||||
extern int16_t ff_dirac_prob_branchless[256][2];
|
||||
|
||||
static inline void renorm(DiracArith *c)
|
||||
{
|
||||
#if HAVE_FAST_CLZ
|
||||
int shift = 14 - av_log2_16bit(c->range-1) + ((c->range-1)>>15);
|
||||
|
||||
c->low <<= shift;
|
||||
c->range <<= shift;
|
||||
c->counter += shift;
|
||||
#else
|
||||
while (c->range <= 0x4000) {
|
||||
c->low <<= 1;
|
||||
c->range <<= 1;
|
||||
c->counter++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void refill(DiracArith *c)
|
||||
{
|
||||
int counter = c->counter;
|
||||
|
||||
if (counter >= 0) {
|
||||
int new = bytestream_get_be16(&c->bytestream);
|
||||
|
||||
// the spec defines overread bits to be 1, and streams rely on this
|
||||
if (c->bytestream > c->bytestream_end) {
|
||||
new |= 0xff;
|
||||
if (c->bytestream > c->bytestream_end+1)
|
||||
new |= 0xff00;
|
||||
|
||||
c->bytestream = c->bytestream_end;
|
||||
}
|
||||
|
||||
c->low += new << counter;
|
||||
counter -= 16;
|
||||
}
|
||||
c->counter = counter;
|
||||
}
|
||||
|
||||
static inline int dirac_get_arith_bit(DiracArith *c, int ctx)
|
||||
{
|
||||
int prob_zero = c->contexts[ctx];
|
||||
int range_times_prob, bit;
|
||||
unsigned low = c->low;
|
||||
int range = c->range;
|
||||
|
||||
range_times_prob = (c->range * prob_zero) >> 16;
|
||||
|
||||
#if HAVE_FAST_CMOV && HAVE_INLINE_ASM
|
||||
low -= range_times_prob << 16;
|
||||
range -= range_times_prob;
|
||||
bit = 0;
|
||||
__asm__(
|
||||
"cmpl %5, %4 \n\t"
|
||||
"setae %b0 \n\t"
|
||||
"cmovb %3, %2 \n\t"
|
||||
"cmovb %5, %1 \n\t"
|
||||
: "+q"(bit), "+r"(range), "+r"(low)
|
||||
: "r"(c->low), "r"(c->low>>16),
|
||||
"r"(range_times_prob)
|
||||
);
|
||||
#else
|
||||
bit = (low >> 16) >= range_times_prob;
|
||||
if (bit) {
|
||||
low -= range_times_prob << 16;
|
||||
range -= range_times_prob;
|
||||
} else {
|
||||
range = range_times_prob;
|
||||
}
|
||||
#endif
|
||||
|
||||
c->contexts[ctx] += ff_dirac_prob_branchless[prob_zero>>8][bit];
|
||||
c->low = low;
|
||||
c->range = range;
|
||||
|
||||
renorm(c);
|
||||
refill(c);
|
||||
return bit;
|
||||
}
|
||||
|
||||
static inline int dirac_get_arith_uint(DiracArith *c, int follow_ctx, int data_ctx)
|
||||
{
|
||||
int ret = 1;
|
||||
while (!dirac_get_arith_bit(c, follow_ctx)) {
|
||||
ret <<= 1;
|
||||
ret += dirac_get_arith_bit(c, data_ctx);
|
||||
follow_ctx = ff_dirac_next_ctx[follow_ctx];
|
||||
}
|
||||
return ret-1;
|
||||
}
|
||||
|
||||
static inline int dirac_get_arith_int(DiracArith *c, int follow_ctx, int data_ctx)
|
||||
{
|
||||
int ret = dirac_get_arith_uint(c, follow_ctx, data_ctx);
|
||||
if (ret && dirac_get_arith_bit(c, data_ctx+1))
|
||||
ret = -ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ff_dirac_init_arith_decoder(DiracArith *c, GetBitContext *gb, int length);
|
||||
|
||||
#endif /* AVCODEC_DIRAC_ARITH_H */
|
|
@ -0,0 +1,572 @@
|
|||
/*
|
||||
* Copyright (C) 2004-2010 Michael Niedermayer <michaelni@gmx.at>
|
||||
* Copyright (C) 2008 David Conrad
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libavutil/attributes.h"
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/common.h"
|
||||
#include "dsputil.h"
|
||||
#include "dirac_dwt.h"
|
||||
#include "libavcodec/x86/dirac_dwt.h"
|
||||
|
||||
|
||||
static inline int mirror(int v, int m)
|
||||
{
|
||||
while ((unsigned)v > (unsigned)m) {
|
||||
v = -v;
|
||||
if (v < 0)
|
||||
v += 2 * m;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static void vertical_compose53iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
|
||||
int width)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < width; i++)
|
||||
b1[i] -= (b0[i] + b2[i] + 2) >> 2;
|
||||
}
|
||||
|
||||
|
||||
static av_always_inline
|
||||
void interleave(IDWTELEM *dst, IDWTELEM *src0, IDWTELEM *src1, int w2, int add, int shift)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < w2; i++) {
|
||||
dst[2*i ] = (src0[i] + add) >> shift;
|
||||
dst[2*i+1] = (src1[i] + add) >> shift;
|
||||
}
|
||||
}
|
||||
|
||||
static void horizontal_compose_dirac53i(IDWTELEM *b, IDWTELEM *temp, int w)
|
||||
{
|
||||
const int w2 = w >> 1;
|
||||
int x;
|
||||
|
||||
temp[0] = COMPOSE_53iL0(b[w2], b[0], b[w2]);
|
||||
for (x = 1; x < w2; x++) {
|
||||
temp[x ] = COMPOSE_53iL0 (b[x+w2-1], b[x ], b[x+w2]);
|
||||
temp[x+w2-1] = COMPOSE_DIRAC53iH0(temp[x-1], b[x+w2-1], temp[x]);
|
||||
}
|
||||
temp[w-1] = COMPOSE_DIRAC53iH0(temp[w2-1], b[w-1], temp[w2-1]);
|
||||
|
||||
interleave(b, temp, temp+w2, w2, 1, 1);
|
||||
}
|
||||
|
||||
static void horizontal_compose_dd97i(IDWTELEM *b, IDWTELEM *tmp, int w)
|
||||
{
|
||||
const int w2 = w >> 1;
|
||||
int x;
|
||||
|
||||
tmp[0] = COMPOSE_53iL0(b[w2], b[0], b[w2]);
|
||||
for (x = 1; x < w2; x++)
|
||||
tmp[x] = COMPOSE_53iL0(b[x+w2-1], b[x], b[x+w2]);
|
||||
|
||||
// extend the edges
|
||||
tmp[-1] = tmp[0];
|
||||
tmp[w2+1] = tmp[w2] = tmp[w2-1];
|
||||
|
||||
for (x = 0; x < w2; x++) {
|
||||
b[2*x ] = (tmp[x] + 1)>>1;
|
||||
b[2*x+1] = (COMPOSE_DD97iH0(tmp[x-1], tmp[x], b[x+w2], tmp[x+1], tmp[x+2]) + 1)>>1;
|
||||
}
|
||||
}
|
||||
|
||||
static void horizontal_compose_dd137i(IDWTELEM *b, IDWTELEM *tmp, int w)
|
||||
{
|
||||
const int w2 = w >> 1;
|
||||
int x;
|
||||
|
||||
tmp[0] = COMPOSE_DD137iL0(b[w2], b[w2], b[0], b[w2 ], b[w2+1]);
|
||||
tmp[1] = COMPOSE_DD137iL0(b[w2], b[w2], b[1], b[w2+1], b[w2+2]);
|
||||
for (x = 2; x < w2-1; x++)
|
||||
tmp[x] = COMPOSE_DD137iL0(b[x+w2-2], b[x+w2-1], b[x], b[x+w2], b[x+w2+1]);
|
||||
tmp[w2-1] = COMPOSE_DD137iL0(b[w-3], b[w-2], b[w2-1], b[w-1], b[w-1]);
|
||||
|
||||
// extend the edges
|
||||
tmp[-1] = tmp[0];
|
||||
tmp[w2+1] = tmp[w2] = tmp[w2-1];
|
||||
|
||||
for (x = 0; x < w2; x++) {
|
||||
b[2*x ] = (tmp[x] + 1)>>1;
|
||||
b[2*x+1] = (COMPOSE_DD97iH0(tmp[x-1], tmp[x], b[x+w2], tmp[x+1], tmp[x+2]) + 1)>>1;
|
||||
}
|
||||
}
|
||||
|
||||
static av_always_inline
|
||||
void horizontal_compose_haari(IDWTELEM *b, IDWTELEM *temp, int w, int shift)
|
||||
{
|
||||
const int w2 = w >> 1;
|
||||
int x;
|
||||
|
||||
for (x = 0; x < w2; x++) {
|
||||
temp[x ] = COMPOSE_HAARiL0(b[x ], b[x+w2]);
|
||||
temp[x+w2] = COMPOSE_HAARiH0(b[x+w2], temp[x]);
|
||||
}
|
||||
|
||||
interleave(b, temp, temp+w2, w2, shift, shift);
|
||||
}
|
||||
|
||||
static void horizontal_compose_haar0i(IDWTELEM *b, IDWTELEM *temp, int w)
|
||||
{
|
||||
horizontal_compose_haari(b, temp, w, 0);
|
||||
}
|
||||
|
||||
static void horizontal_compose_haar1i(IDWTELEM *b, IDWTELEM *temp, int w)
|
||||
{
|
||||
horizontal_compose_haari(b, temp, w, 1);
|
||||
}
|
||||
|
||||
static void horizontal_compose_fidelityi(IDWTELEM *b, IDWTELEM *tmp, int w)
|
||||
{
|
||||
const int w2 = w >> 1;
|
||||
int i, x;
|
||||
IDWTELEM v[8];
|
||||
|
||||
for (x = 0; x < w2; x++) {
|
||||
for (i = 0; i < 8; i++)
|
||||
v[i] = b[av_clip(x-3+i, 0, w2-1)];
|
||||
tmp[x] = COMPOSE_FIDELITYiH0(v[0], v[1], v[2], v[3], b[x+w2], v[4], v[5], v[6], v[7]);
|
||||
}
|
||||
|
||||
for (x = 0; x < w2; x++) {
|
||||
for (i = 0; i < 8; i++)
|
||||
v[i] = tmp[av_clip(x-4+i, 0, w2-1)];
|
||||
tmp[x+w2] = COMPOSE_FIDELITYiL0(v[0], v[1], v[2], v[3], b[x], v[4], v[5], v[6], v[7]);
|
||||
}
|
||||
|
||||
interleave(b, tmp+w2, tmp, w2, 0, 0);
|
||||
}
|
||||
|
||||
static void horizontal_compose_daub97i(IDWTELEM *b, IDWTELEM *temp, int w)
|
||||
{
|
||||
const int w2 = w >> 1;
|
||||
int x, b0, b1, b2;
|
||||
|
||||
temp[0] = COMPOSE_DAUB97iL1(b[w2], b[0], b[w2]);
|
||||
for (x = 1; x < w2; x++) {
|
||||
temp[x ] = COMPOSE_DAUB97iL1(b[x+w2-1], b[x ], b[x+w2]);
|
||||
temp[x+w2-1] = COMPOSE_DAUB97iH1(temp[x-1], b[x+w2-1], temp[x]);
|
||||
}
|
||||
temp[w-1] = COMPOSE_DAUB97iH1(temp[w2-1], b[w-1], temp[w2-1]);
|
||||
|
||||
// second stage combined with interleave and shift
|
||||
b0 = b2 = COMPOSE_DAUB97iL0(temp[w2], temp[0], temp[w2]);
|
||||
b[0] = (b0 + 1) >> 1;
|
||||
for (x = 1; x < w2; x++) {
|
||||
b2 = COMPOSE_DAUB97iL0(temp[x+w2-1], temp[x ], temp[x+w2]);
|
||||
b1 = COMPOSE_DAUB97iH0( b0, temp[x+w2-1], b2 );
|
||||
b[2*x-1] = (b1 + 1) >> 1;
|
||||
b[2*x ] = (b2 + 1) >> 1;
|
||||
b0 = b2;
|
||||
}
|
||||
b[w-1] = (COMPOSE_DAUB97iH0(b2, temp[w-1], b2) + 1) >> 1;
|
||||
}
|
||||
|
||||
static void vertical_compose_dirac53iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<width; i++){
|
||||
b1[i] = COMPOSE_DIRAC53iH0(b0[i], b1[i], b2[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void vertical_compose_dd97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
|
||||
IDWTELEM *b3, IDWTELEM *b4, int width)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<width; i++){
|
||||
b2[i] = COMPOSE_DD97iH0(b0[i], b1[i], b2[i], b3[i], b4[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void vertical_compose_dd137iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
|
||||
IDWTELEM *b3, IDWTELEM *b4, int width)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<width; i++){
|
||||
b2[i] = COMPOSE_DD137iL0(b0[i], b1[i], b2[i], b3[i], b4[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void vertical_compose_haar(IDWTELEM *b0, IDWTELEM *b1, int width)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < width; i++) {
|
||||
b0[i] = COMPOSE_HAARiL0(b0[i], b1[i]);
|
||||
b1[i] = COMPOSE_HAARiH0(b1[i], b0[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void vertical_compose_fidelityiH0(IDWTELEM *dst, IDWTELEM *b[8], int width)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<width; i++){
|
||||
dst[i] = COMPOSE_FIDELITYiH0(b[0][i], b[1][i], b[2][i], b[3][i], dst[i], b[4][i], b[5][i], b[6][i], b[7][i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void vertical_compose_fidelityiL0(IDWTELEM *dst, IDWTELEM *b[8], int width)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<width; i++){
|
||||
dst[i] = COMPOSE_FIDELITYiL0(b[0][i], b[1][i], b[2][i], b[3][i], dst[i], b[4][i], b[5][i], b[6][i], b[7][i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void vertical_compose_daub97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<width; i++){
|
||||
b1[i] = COMPOSE_DAUB97iH0(b0[i], b1[i], b2[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void vertical_compose_daub97iH1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<width; i++){
|
||||
b1[i] = COMPOSE_DAUB97iH1(b0[i], b1[i], b2[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void vertical_compose_daub97iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<width; i++){
|
||||
b1[i] = COMPOSE_DAUB97iL0(b0[i], b1[i], b2[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void vertical_compose_daub97iL1(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<width; i++){
|
||||
b1[i] = COMPOSE_DAUB97iL1(b0[i], b1[i], b2[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void spatial_compose_dd97i_dy(DWTContext *d, int level, int width, int height, int stride)
|
||||
{
|
||||
vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
|
||||
vertical_compose_5tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
|
||||
DWTCompose *cs = d->cs + level;
|
||||
|
||||
int i, y = cs->y;
|
||||
IDWTELEM *b[8];
|
||||
for (i = 0; i < 6; i++)
|
||||
b[i] = cs->b[i];
|
||||
b[6] = d->buffer + av_clip(y+5, 0, height-2)*stride;
|
||||
b[7] = d->buffer + av_clip(y+6, 1, height-1)*stride;
|
||||
|
||||
if(y+5<(unsigned)height) vertical_compose_l0( b[5], b[6], b[7], width);
|
||||
if(y+1<(unsigned)height) vertical_compose_h0(b[0], b[2], b[3], b[4], b[6], width);
|
||||
|
||||
if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
|
||||
if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
cs->b[i] = b[i+2];
|
||||
cs->y += 2;
|
||||
}
|
||||
|
||||
static void spatial_compose_dirac53i_dy(DWTContext *d, int level, int width, int height, int stride)
|
||||
{
|
||||
vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
|
||||
vertical_compose_3tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
|
||||
DWTCompose *cs = d->cs + level;
|
||||
|
||||
int y= cs->y;
|
||||
IDWTELEM *b[4] = { cs->b[0], cs->b[1] };
|
||||
b[2] = d->buffer + mirror(y+1, height-1)*stride;
|
||||
b[3] = d->buffer + mirror(y+2, height-1)*stride;
|
||||
|
||||
if(y+1<(unsigned)height) vertical_compose_l0(b[1], b[2], b[3], width);
|
||||
if(y+0<(unsigned)height) vertical_compose_h0(b[0], b[1], b[2], width);
|
||||
|
||||
if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
|
||||
if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
|
||||
|
||||
cs->b[0] = b[2];
|
||||
cs->b[1] = b[3];
|
||||
cs->y += 2;
|
||||
}
|
||||
|
||||
|
||||
static void spatial_compose_dd137i_dy(DWTContext *d, int level, int width, int height, int stride)
|
||||
{
|
||||
vertical_compose_5tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
|
||||
vertical_compose_5tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
|
||||
DWTCompose *cs = d->cs + level;
|
||||
|
||||
int i, y = cs->y;
|
||||
IDWTELEM *b[10];
|
||||
for (i = 0; i < 8; i++)
|
||||
b[i] = cs->b[i];
|
||||
b[8] = d->buffer + av_clip(y+7, 0, height-2)*stride;
|
||||
b[9] = d->buffer + av_clip(y+8, 1, height-1)*stride;
|
||||
|
||||
if(y+5<(unsigned)height) vertical_compose_l0(b[3], b[5], b[6], b[7], b[9], width);
|
||||
if(y+1<(unsigned)height) vertical_compose_h0(b[0], b[2], b[3], b[4], b[6], width);
|
||||
|
||||
if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
|
||||
if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
cs->b[i] = b[i+2];
|
||||
cs->y += 2;
|
||||
}
|
||||
|
||||
// haar makes the assumption that height is even (always true for dirac)
|
||||
static void spatial_compose_haari_dy(DWTContext *d, int level, int width, int height, int stride)
|
||||
{
|
||||
vertical_compose_2tap vertical_compose = (void*)d->vertical_compose;
|
||||
int y = d->cs[level].y;
|
||||
IDWTELEM *b0 = d->buffer + (y-1)*stride;
|
||||
IDWTELEM *b1 = d->buffer + (y )*stride;
|
||||
|
||||
vertical_compose(b0, b1, width);
|
||||
d->horizontal_compose(b0, d->temp, width);
|
||||
d->horizontal_compose(b1, d->temp, width);
|
||||
|
||||
d->cs[level].y += 2;
|
||||
}
|
||||
|
||||
// Don't do sliced idwt for fidelity; the 9 tap filter makes it a bit annoying
|
||||
// Fortunately, this filter isn't used in practice.
|
||||
static void spatial_compose_fidelity(DWTContext *d, int level, int width, int height, int stride)
|
||||
{
|
||||
vertical_compose_9tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
|
||||
vertical_compose_9tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
|
||||
int i, y;
|
||||
IDWTELEM *b[8];
|
||||
|
||||
for (y = 1; y < height; y += 2) {
|
||||
for (i = 0; i < 8; i++)
|
||||
b[i] = d->buffer + av_clip((y-7 + 2*i), 0, height-2)*stride;
|
||||
vertical_compose_h0(d->buffer + y*stride, b, width);
|
||||
}
|
||||
|
||||
for (y = 0; y < height; y += 2) {
|
||||
for (i = 0; i < 8; i++)
|
||||
b[i] = d->buffer + av_clip((y-7 + 2*i), 1, height-1)*stride;
|
||||
vertical_compose_l0(d->buffer + y*stride, b, width);
|
||||
}
|
||||
|
||||
for (y = 0; y < height; y++)
|
||||
d->horizontal_compose(d->buffer + y*stride, d->temp, width);
|
||||
|
||||
d->cs[level].y = height+1;
|
||||
}
|
||||
|
||||
static void spatial_compose_daub97i_dy(DWTContext *d, int level, int width, int height, int stride)
|
||||
{
|
||||
vertical_compose_3tap vertical_compose_l0 = (void*)d->vertical_compose_l0;
|
||||
vertical_compose_3tap vertical_compose_h0 = (void*)d->vertical_compose_h0;
|
||||
vertical_compose_3tap vertical_compose_l1 = (void*)d->vertical_compose_l1;
|
||||
vertical_compose_3tap vertical_compose_h1 = (void*)d->vertical_compose_h1;
|
||||
DWTCompose *cs = d->cs + level;
|
||||
|
||||
int i, y = cs->y;
|
||||
IDWTELEM *b[6];
|
||||
for (i = 0; i < 4; i++)
|
||||
b[i] = cs->b[i];
|
||||
b[4] = d->buffer + mirror(y+3, height-1)*stride;
|
||||
b[5] = d->buffer + mirror(y+4, height-1)*stride;
|
||||
|
||||
if(y+3<(unsigned)height) vertical_compose_l1(b[3], b[4], b[5], width);
|
||||
if(y+2<(unsigned)height) vertical_compose_h1(b[2], b[3], b[4], width);
|
||||
if(y+1<(unsigned)height) vertical_compose_l0(b[1], b[2], b[3], width);
|
||||
if(y+0<(unsigned)height) vertical_compose_h0(b[0], b[1], b[2], width);
|
||||
|
||||
if(y-1<(unsigned)height) d->horizontal_compose(b[0], d->temp, width);
|
||||
if(y+0<(unsigned)height) d->horizontal_compose(b[1], d->temp, width);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
cs->b[i] = b[i+2];
|
||||
cs->y += 2;
|
||||
}
|
||||
|
||||
|
||||
static void spatial_compose97i_init2(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
|
||||
{
|
||||
cs->b[0] = buffer + mirror(-3-1, height-1)*stride;
|
||||
cs->b[1] = buffer + mirror(-3 , height-1)*stride;
|
||||
cs->b[2] = buffer + mirror(-3+1, height-1)*stride;
|
||||
cs->b[3] = buffer + mirror(-3+2, height-1)*stride;
|
||||
cs->y = -3;
|
||||
}
|
||||
|
||||
static void spatial_compose53i_init2(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
|
||||
{
|
||||
cs->b[0] = buffer + mirror(-1-1, height-1)*stride;
|
||||
cs->b[1] = buffer + mirror(-1 , height-1)*stride;
|
||||
cs->y = -1;
|
||||
}
|
||||
|
||||
static void spatial_compose_dd97i_init(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
|
||||
{
|
||||
cs->b[0] = buffer + av_clip(-5-1, 0, height-2)*stride;
|
||||
cs->b[1] = buffer + av_clip(-5 , 1, height-1)*stride;
|
||||
cs->b[2] = buffer + av_clip(-5+1, 0, height-2)*stride;
|
||||
cs->b[3] = buffer + av_clip(-5+2, 1, height-1)*stride;
|
||||
cs->b[4] = buffer + av_clip(-5+3, 0, height-2)*stride;
|
||||
cs->b[5] = buffer + av_clip(-5+4, 1, height-1)*stride;
|
||||
cs->y = -5;
|
||||
}
|
||||
|
||||
static void spatial_compose_dd137i_init(DWTCompose *cs, IDWTELEM *buffer, int height, int stride)
|
||||
{
|
||||
cs->b[0] = buffer + av_clip(-5-1, 0, height-2)*stride;
|
||||
cs->b[1] = buffer + av_clip(-5 , 1, height-1)*stride;
|
||||
cs->b[2] = buffer + av_clip(-5+1, 0, height-2)*stride;
|
||||
cs->b[3] = buffer + av_clip(-5+2, 1, height-1)*stride;
|
||||
cs->b[4] = buffer + av_clip(-5+3, 0, height-2)*stride;
|
||||
cs->b[5] = buffer + av_clip(-5+4, 1, height-1)*stride;
|
||||
cs->b[6] = buffer + av_clip(-5+5, 0, height-2)*stride;
|
||||
cs->b[7] = buffer + av_clip(-5+6, 1, height-1)*stride;
|
||||
cs->y = -5;
|
||||
}
|
||||
|
||||
int ff_spatial_idwt_init2(DWTContext *d, IDWTELEM *buffer, int width, int height,
|
||||
int stride, enum dwt_type type, int decomposition_count,
|
||||
IDWTELEM *temp)
|
||||
{
|
||||
int level;
|
||||
|
||||
d->buffer = buffer;
|
||||
d->width = width;
|
||||
d->height = height;
|
||||
d->stride = stride;
|
||||
d->decomposition_count = decomposition_count;
|
||||
d->temp = temp + 8;
|
||||
|
||||
for(level=decomposition_count-1; level>=0; level--){
|
||||
int hl = height >> level;
|
||||
int stride_l = stride << level;
|
||||
|
||||
switch(type){
|
||||
case DWT_DIRAC_DD9_7:
|
||||
spatial_compose_dd97i_init(d->cs+level, buffer, hl, stride_l);
|
||||
break;
|
||||
case DWT_DIRAC_LEGALL5_3:
|
||||
spatial_compose53i_init2(d->cs+level, buffer, hl, stride_l);
|
||||
break;
|
||||
case DWT_DIRAC_DD13_7:
|
||||
spatial_compose_dd137i_init(d->cs+level, buffer, hl, stride_l);
|
||||
break;
|
||||
case DWT_DIRAC_HAAR0:
|
||||
case DWT_DIRAC_HAAR1:
|
||||
d->cs[level].y = 1;
|
||||
break;
|
||||
case DWT_DIRAC_DAUB9_7:
|
||||
spatial_compose97i_init2(d->cs+level, buffer, hl, stride_l);
|
||||
break;
|
||||
default:
|
||||
d->cs[level].y = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case DWT_DIRAC_DD9_7:
|
||||
d->spatial_compose = spatial_compose_dd97i_dy;
|
||||
d->vertical_compose_l0 = (void*)vertical_compose53iL0;
|
||||
d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0;
|
||||
d->horizontal_compose = horizontal_compose_dd97i;
|
||||
d->support = 7;
|
||||
break;
|
||||
case DWT_DIRAC_LEGALL5_3:
|
||||
d->spatial_compose = spatial_compose_dirac53i_dy;
|
||||
d->vertical_compose_l0 = (void*)vertical_compose53iL0;
|
||||
d->vertical_compose_h0 = (void*)vertical_compose_dirac53iH0;
|
||||
d->horizontal_compose = horizontal_compose_dirac53i;
|
||||
d->support = 3;
|
||||
break;
|
||||
case DWT_DIRAC_DD13_7:
|
||||
d->spatial_compose = spatial_compose_dd137i_dy;
|
||||
d->vertical_compose_l0 = (void*)vertical_compose_dd137iL0;
|
||||
d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0;
|
||||
d->horizontal_compose = horizontal_compose_dd137i;
|
||||
d->support = 7;
|
||||
break;
|
||||
case DWT_DIRAC_HAAR0:
|
||||
case DWT_DIRAC_HAAR1:
|
||||
d->spatial_compose = spatial_compose_haari_dy;
|
||||
d->vertical_compose = (void*)vertical_compose_haar;
|
||||
if (type == DWT_DIRAC_HAAR0)
|
||||
d->horizontal_compose = horizontal_compose_haar0i;
|
||||
else
|
||||
d->horizontal_compose = horizontal_compose_haar1i;
|
||||
d->support = 1;
|
||||
break;
|
||||
case DWT_DIRAC_FIDELITY:
|
||||
d->spatial_compose = spatial_compose_fidelity;
|
||||
d->vertical_compose_l0 = (void*)vertical_compose_fidelityiL0;
|
||||
d->vertical_compose_h0 = (void*)vertical_compose_fidelityiH0;
|
||||
d->horizontal_compose = horizontal_compose_fidelityi;
|
||||
break;
|
||||
case DWT_DIRAC_DAUB9_7:
|
||||
d->spatial_compose = spatial_compose_daub97i_dy;
|
||||
d->vertical_compose_l0 = (void*)vertical_compose_daub97iL0;
|
||||
d->vertical_compose_h0 = (void*)vertical_compose_daub97iH0;
|
||||
d->vertical_compose_l1 = (void*)vertical_compose_daub97iL1;
|
||||
d->vertical_compose_h1 = (void*)vertical_compose_daub97iH1;
|
||||
d->horizontal_compose = horizontal_compose_daub97i;
|
||||
d->support = 5;
|
||||
break;
|
||||
default:
|
||||
av_log(NULL, AV_LOG_ERROR, "Unknown wavelet type %d\n", type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (HAVE_MMX) ff_spatial_idwt_init_mmx(d, type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ff_spatial_idwt_slice2(DWTContext *d, int y)
|
||||
{
|
||||
int level, support = d->support;
|
||||
|
||||
for (level = d->decomposition_count-1; level >= 0; level--) {
|
||||
int wl = d->width >> level;
|
||||
int hl = d->height >> level;
|
||||
int stride_l = d->stride << level;
|
||||
|
||||
while (d->cs[level].y <= FFMIN((y>>level)+support, hl))
|
||||
d->spatial_compose(d, level, wl, hl, stride_l);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Copyright (C) 2004-2010 Michael Niedermayer <michaelni@gmx.at>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_DIRAC_DWT_H
|
||||
#define AVCODEC_DIRAC_DWT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef int DWTELEM;
|
||||
typedef short IDWTELEM;
|
||||
|
||||
#define MAX_DWT_SUPPORT 8
|
||||
#define MAX_DECOMPOSITIONS 8
|
||||
|
||||
typedef struct DWTCompose {
|
||||
IDWTELEM *b[MAX_DWT_SUPPORT];
|
||||
int y;
|
||||
} DWTCompose;
|
||||
|
||||
struct DWTContext;
|
||||
|
||||
// Possible prototypes for vertical_compose functions
|
||||
typedef void (*vertical_compose_2tap)(IDWTELEM *b0, IDWTELEM *b1, int width);
|
||||
typedef void (*vertical_compose_3tap)(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width);
|
||||
typedef void (*vertical_compose_5tap)(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, int width);
|
||||
typedef void (*vertical_compose_9tap)(IDWTELEM *dst, IDWTELEM *b[8], int width);
|
||||
|
||||
typedef struct DWTContext {
|
||||
IDWTELEM *buffer;
|
||||
IDWTELEM *temp;
|
||||
int width;
|
||||
int height;
|
||||
int stride;
|
||||
int decomposition_count;
|
||||
int support;
|
||||
|
||||
void (*spatial_compose)(struct DWTContext *cs, int level, int width, int height, int stride);
|
||||
void (*vertical_compose_l0)(void);
|
||||
void (*vertical_compose_h0)(void);
|
||||
void (*vertical_compose_l1)(void);
|
||||
void (*vertical_compose_h1)(void);
|
||||
void (*vertical_compose)(void); ///< one set of lowpass and highpass combined
|
||||
void (*horizontal_compose)(IDWTELEM *b, IDWTELEM *tmp, int width);
|
||||
|
||||
DWTCompose cs[MAX_DECOMPOSITIONS];
|
||||
} DWTContext;
|
||||
|
||||
enum dwt_type {
|
||||
DWT_SNOW_DAUB9_7,
|
||||
DWT_SNOW_LEGALL5_3,
|
||||
DWT_DIRAC_DD9_7,
|
||||
DWT_DIRAC_LEGALL5_3,
|
||||
DWT_DIRAC_DD13_7,
|
||||
DWT_DIRAC_HAAR0,
|
||||
DWT_DIRAC_HAAR1,
|
||||
DWT_DIRAC_FIDELITY,
|
||||
DWT_DIRAC_DAUB9_7,
|
||||
DWT_NUM_TYPES
|
||||
};
|
||||
|
||||
// -1 if an error occurred, e.g. the dwt_type isn't recognized
|
||||
int ff_spatial_idwt_init2(DWTContext *d, IDWTELEM *buffer, int width, int height,
|
||||
int stride, enum dwt_type type, int decomposition_count,
|
||||
IDWTELEM *temp);
|
||||
|
||||
void ff_spatial_idwt_slice2(DWTContext *d, int y);
|
||||
|
||||
// shared stuff for simd optimiztions
|
||||
#define COMPOSE_53iL0(b0, b1, b2)\
|
||||
(b1 - ((b0 + b2 + 2) >> 2))
|
||||
|
||||
#define COMPOSE_DIRAC53iH0(b0, b1, b2)\
|
||||
(b1 + ((b0 + b2 + 1) >> 1))
|
||||
|
||||
#define COMPOSE_DD97iH0(b0, b1, b2, b3, b4)\
|
||||
(b2 + ((-b0 + 9*b1 + 9*b3 - b4 + 8) >> 4))
|
||||
|
||||
#define COMPOSE_DD137iL0(b0, b1, b2, b3, b4)\
|
||||
(b2 - ((-b0 + 9*b1 + 9*b3 - b4 + 16) >> 5))
|
||||
|
||||
#define COMPOSE_HAARiL0(b0, b1)\
|
||||
(b0 - ((b1 + 1) >> 1))
|
||||
|
||||
#define COMPOSE_HAARiH0(b0, b1)\
|
||||
(b0 + b1)
|
||||
|
||||
#define COMPOSE_FIDELITYiL0(b0, b1, b2, b3, b4, b5, b6, b7, b8)\
|
||||
(b4 - ((-8*(b0+b8) + 21*(b1+b7) - 46*(b2+b6) + 161*(b3+b5) + 128) >> 8))
|
||||
|
||||
#define COMPOSE_FIDELITYiH0(b0, b1, b2, b3, b4, b5, b6, b7, b8)\
|
||||
(b4 + ((-2*(b0+b8) + 10*(b1+b7) - 25*(b2+b6) + 81*(b3+b5) + 128) >> 8))
|
||||
|
||||
#define COMPOSE_DAUB97iL1(b0, b1, b2)\
|
||||
(b1 - ((1817*(b0 + b2) + 2048) >> 12))
|
||||
|
||||
#define COMPOSE_DAUB97iH1(b0, b1, b2)\
|
||||
(b1 - (( 113*(b0 + b2) + 64) >> 7))
|
||||
|
||||
#define COMPOSE_DAUB97iL0(b0, b1, b2)\
|
||||
(b1 + (( 217*(b0 + b2) + 2048) >> 12))
|
||||
|
||||
#define COMPOSE_DAUB97iH0(b0, b1, b2)\
|
||||
(b1 + ((6497*(b0 + b2) + 2048) >> 12))
|
||||
|
||||
|
||||
#endif /* AVCODEC_DWT_H */
|
|
@ -0,0 +1,260 @@
|
|||
/*
|
||||
* Dirac parser
|
||||
*
|
||||
* Copyright (c) 2007-2008 Marco Gerards <marco@gnu.org>
|
||||
* Copyright (c) 2008 BBC, Anuradha Suraparaju <asuraparaju@gmail.com>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Dirac Parser
|
||||
* @author Marco Gerards <marco@gnu.org>
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "libavutil/intreadwrite.h"
|
||||
#include "libavutil/mem.h"
|
||||
#include "parser.h"
|
||||
|
||||
#define DIRAC_PARSE_INFO_PREFIX 0x42424344
|
||||
|
||||
/**
|
||||
* Find the end of the current frame in the bitstream.
|
||||
* @return the position of the first byte of the next frame or -1
|
||||
*/
|
||||
typedef struct DiracParseContext {
|
||||
int state;
|
||||
int is_synced;
|
||||
int sync_offset;
|
||||
int header_bytes_needed;
|
||||
int overread_index;
|
||||
int buffer_size;
|
||||
int index;
|
||||
uint8_t *buffer;
|
||||
int dirac_unit_size;
|
||||
uint8_t *dirac_unit;
|
||||
} DiracParseContext;
|
||||
|
||||
static int find_frame_end(DiracParseContext *pc,
|
||||
const uint8_t *buf, int buf_size)
|
||||
{
|
||||
uint32_t state = pc->state;
|
||||
int i = 0;
|
||||
|
||||
if (!pc->is_synced) {
|
||||
for (i = 0; i < buf_size; i++) {
|
||||
state = (state << 8) | buf[i];
|
||||
if (state == DIRAC_PARSE_INFO_PREFIX) {
|
||||
state = -1;
|
||||
pc->is_synced = 1;
|
||||
pc->header_bytes_needed = 9;
|
||||
pc->sync_offset = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pc->is_synced) {
|
||||
pc->sync_offset = 0;
|
||||
for (; i < buf_size; i++) {
|
||||
if (state == DIRAC_PARSE_INFO_PREFIX) {
|
||||
if ((buf_size-i) >= pc->header_bytes_needed) {
|
||||
pc->state = -1;
|
||||
return i + pc->header_bytes_needed;
|
||||
} else {
|
||||
pc->header_bytes_needed = 9-(buf_size-i);
|
||||
break;
|
||||
}
|
||||
} else
|
||||
state = (state << 8) | buf[i];
|
||||
}
|
||||
}
|
||||
pc->state = state;
|
||||
return -1;
|
||||
}
|
||||
|
||||
typedef struct DiracParseUnit
|
||||
{
|
||||
int next_pu_offset;
|
||||
int prev_pu_offset;
|
||||
uint8_t pu_type;
|
||||
} DiracParseUnit;
|
||||
|
||||
static int unpack_parse_unit(DiracParseUnit *pu, DiracParseContext *pc,
|
||||
int offset)
|
||||
{
|
||||
uint8_t *start = pc->buffer + offset;
|
||||
uint8_t *end = pc->buffer + pc->index;
|
||||
if (start < pc->buffer || (start+13 > end))
|
||||
return 0;
|
||||
pu->pu_type = start[4];
|
||||
|
||||
pu->next_pu_offset = AV_RB32(start+5);
|
||||
pu->prev_pu_offset = AV_RB32(start+9);
|
||||
|
||||
if (pu->pu_type == 0x10 && pu->next_pu_offset == 0)
|
||||
pu->next_pu_offset = 13;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dirac_combine_frame(AVCodecParserContext *s, AVCodecContext *avctx,
|
||||
int next, const uint8_t **buf, int *buf_size)
|
||||
{
|
||||
int parse_timing_info = (s->pts == AV_NOPTS_VALUE &&
|
||||
s->dts == AV_NOPTS_VALUE);
|
||||
DiracParseContext *pc = s->priv_data;
|
||||
|
||||
if (pc->overread_index) {
|
||||
memcpy(pc->buffer, pc->buffer + pc->overread_index,
|
||||
pc->index - pc->overread_index);
|
||||
pc->index -= pc->overread_index;
|
||||
pc->overread_index = 0;
|
||||
if (*buf_size == 0 && pc->buffer[4] == 0x10) {
|
||||
*buf = pc->buffer;
|
||||
*buf_size = pc->index;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( next == -1) {
|
||||
/* Found a possible frame start but not a frame end */
|
||||
void *new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size,
|
||||
pc->index + (*buf_size -
|
||||
pc->sync_offset));
|
||||
pc->buffer = new_buffer;
|
||||
memcpy(pc->buffer+pc->index, (*buf + pc->sync_offset),
|
||||
*buf_size - pc->sync_offset);
|
||||
pc->index += *buf_size - pc->sync_offset;
|
||||
return -1;
|
||||
} else {
|
||||
/* Found a possible frame start and a possible frame end */
|
||||
DiracParseUnit pu1, pu;
|
||||
void *new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size,
|
||||
pc->index + next);
|
||||
pc->buffer = new_buffer;
|
||||
memcpy(pc->buffer + pc->index, *buf, next);
|
||||
pc->index += next;
|
||||
|
||||
/* Need to check if we have a valid Parse Unit. We can't go by the
|
||||
* sync pattern 'BBCD' alone because arithmetic coding of the residual
|
||||
* and motion data can cause the pattern triggering a false start of
|
||||
* frame. So check if the previous parse offset of the next parse unit
|
||||
* is equal to the next parse offset of the current parse unit then
|
||||
* we can be pretty sure that we have a valid parse unit */
|
||||
if (!unpack_parse_unit(&pu1, pc, pc->index - 13) ||
|
||||
!unpack_parse_unit(&pu, pc, pc->index - 13 - pu1.prev_pu_offset) ||
|
||||
pu.next_pu_offset != pu1.prev_pu_offset ||
|
||||
pc->index < pc->dirac_unit_size + 13LL + pu1.prev_pu_offset
|
||||
) {
|
||||
pc->index -= 9;
|
||||
*buf_size = next-9;
|
||||
pc->header_bytes_needed = 9;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* All non-frame data must be accompanied by frame data. This is to
|
||||
* ensure that pts is set correctly. So if the current parse unit is
|
||||
* not frame data, wait for frame data to come along */
|
||||
|
||||
pc->dirac_unit = pc->buffer + pc->index - 13 -
|
||||
pu1.prev_pu_offset - pc->dirac_unit_size;
|
||||
|
||||
pc->dirac_unit_size += pu.next_pu_offset;
|
||||
|
||||
if ((pu.pu_type&0x08) != 0x08) {
|
||||
pc->header_bytes_needed = 9;
|
||||
*buf_size = next;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get the picture number to set the pts and dts*/
|
||||
if (parse_timing_info) {
|
||||
uint8_t *cur_pu = pc->buffer +
|
||||
pc->index - 13 - pu1.prev_pu_offset;
|
||||
int pts = AV_RB32(cur_pu + 13);
|
||||
if (s->last_pts == 0 && s->last_dts == 0)
|
||||
s->dts = pts - 1;
|
||||
else
|
||||
s->dts = s->last_dts+1;
|
||||
s->pts = pts;
|
||||
if (!avctx->has_b_frames && (cur_pu[4] & 0x03))
|
||||
avctx->has_b_frames = 1;
|
||||
}
|
||||
if (avctx->has_b_frames && s->pts == s->dts)
|
||||
s->pict_type = AV_PICTURE_TYPE_B;
|
||||
|
||||
/* Finally have a complete Dirac data unit */
|
||||
*buf = pc->dirac_unit;
|
||||
*buf_size = pc->dirac_unit_size;
|
||||
|
||||
pc->dirac_unit_size = 0;
|
||||
pc->overread_index = pc->index-13;
|
||||
pc->header_bytes_needed = 9;
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
static int dirac_parse(AVCodecParserContext *s, AVCodecContext *avctx,
|
||||
const uint8_t **poutbuf, int *poutbuf_size,
|
||||
const uint8_t *buf, int buf_size)
|
||||
{
|
||||
DiracParseContext *pc = s->priv_data;
|
||||
int next;
|
||||
|
||||
*poutbuf = NULL;
|
||||
*poutbuf_size = 0;
|
||||
|
||||
if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
|
||||
next = buf_size;
|
||||
*poutbuf = buf;
|
||||
*poutbuf_size = buf_size;
|
||||
/* Assume that data has been packetized into an encapsulation unit. */
|
||||
} else {
|
||||
next = find_frame_end(pc, buf, buf_size);
|
||||
if (!pc->is_synced && next == -1) {
|
||||
/* No frame start found yet. So throw away the entire buffer. */
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
if (dirac_combine_frame(s, avctx, next, &buf, &buf_size) < 0) {
|
||||
return buf_size;
|
||||
}
|
||||
}
|
||||
|
||||
*poutbuf = buf;
|
||||
*poutbuf_size = buf_size;
|
||||
return next;
|
||||
}
|
||||
|
||||
static void dirac_parse_close(AVCodecParserContext *s)
|
||||
{
|
||||
DiracParseContext *pc = s->priv_data;
|
||||
|
||||
if (pc->buffer_size > 0)
|
||||
av_free(pc->buffer);
|
||||
}
|
||||
|
||||
AVCodecParser ff_dirac_parser = {
|
||||
.codec_ids = { AV_CODEC_ID_DIRAC },
|
||||
.priv_data_size = sizeof(DiracParseContext),
|
||||
.parser_parse = dirac_parse,
|
||||
.parser_close = dirac_parse_close,
|
||||
};
|
File diff suppressed because it is too large
Load Diff
|
@ -19,7 +19,6 @@
|
|||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "dsputil.h"
|
||||
#include "diracdsp.h"
|
||||
#include "libavcodec/x86/diracdsp_mmx.h"
|
||||
|
|
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
* exp golomb vlc stuff
|
||||
* Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief
|
||||
* exp golomb vlc stuff
|
||||
* @author Michael Niedermayer <michaelni@gmx.at>
|
||||
*/
|
||||
|
||||
#include "libavutil/common.h"
|
||||
|
||||
const uint8_t ff_golomb_vlc_len[512]={
|
||||
19,17,15,15,13,13,13,13,11,11,11,11,11,11,11,11,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
|
||||
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
|
||||
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
||||
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
||||
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
||||
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
|
||||
};
|
||||
|
||||
const uint8_t ff_ue_golomb_vlc_code[512]={
|
||||
32,32,32,32,32,32,32,32,31,32,32,32,32,32,32,32,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,
|
||||
7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9,10,10,10,10,11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,14,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
const int8_t ff_se_golomb_vlc_code[512]={
|
||||
17, 17, 17, 17, 17, 17, 17, 17, 16, 17, 17, 17, 17, 17, 17, 17, 8, -8, 9, -9, 10,-10, 11,-11, 12,-12, 13,-13, 14,-14, 15,-15,
|
||||
4, 4, 4, 4, -4, -4, -4, -4, 5, 5, 5, 5, -5, -5, -5, -5, 6, 6, 6, 6, -6, -6, -6, -6, 7, 7, 7, 7, -7, -7, -7, -7,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
|
||||
const uint8_t ff_ue_golomb_len[256]={
|
||||
1, 3, 3, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,11,
|
||||
11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,13,
|
||||
13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
|
||||
13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,15,
|
||||
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
|
||||
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
|
||||
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
|
||||
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,17,
|
||||
};
|
||||
|
||||
const uint8_t ff_interleaved_golomb_vlc_len[256]={
|
||||
9,9,7,7,9,9,7,7,5,5,5,5,5,5,5,5,
|
||||
9,9,7,7,9,9,7,7,5,5,5,5,5,5,5,5,
|
||||
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
||||
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
||||
9,9,7,7,9,9,7,7,5,5,5,5,5,5,5,5,
|
||||
9,9,7,7,9,9,7,7,5,5,5,5,5,5,5,5,
|
||||
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
||||
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
};
|
||||
|
||||
const uint8_t ff_interleaved_ue_golomb_vlc_code[256]={
|
||||
15,16,7, 7, 17,18,8, 8, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
19,20,9, 9, 21,22,10,10,4, 4, 4, 4, 4, 4, 4, 4,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
23,24,11,11,25,26,12,12,5, 5, 5, 5, 5, 5, 5, 5,
|
||||
27,28,13,13,29,30,14,14,6, 6, 6, 6, 6, 6, 6, 6,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
const int8_t ff_interleaved_se_golomb_vlc_code[256]={
|
||||
8, -8, 4, 4, 9, -9, -4, -4, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
10,-10, 5, 5, 11,-11, -5, -5, -2, -2, -2, -2, -2, -2, -2, -2,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
12,-12, 6, 6, 13,-13, -6, -6, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
14,-14, 7, 7, 15,-15, -7, -7, -3, -3, -3, -3, -3, -3, -3, -3,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
const uint8_t ff_interleaved_dirac_golomb_vlc_code[256]={
|
||||
0, 1, 0, 0, 2, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
4, 5, 2, 2, 6, 7, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
8, 9, 4, 4, 10,11,5, 5, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
12,13,6, 6, 14,15,7, 7, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,};
|
|
@ -0,0 +1,557 @@
|
|||
/*
|
||||
* exp golomb vlc stuff
|
||||
* Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
|
||||
* Copyright (c) 2004 Alex Beregszaszi
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief
|
||||
* exp golomb vlc stuff
|
||||
* @author Michael Niedermayer <michaelni@gmx.at> and Alex Beregszaszi
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_GOLOMB_H
|
||||
#define AVCODEC_GOLOMB_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "get_bits.h"
|
||||
#include "put_bits.h"
|
||||
|
||||
#define INVALID_VLC 0x80000000
|
||||
|
||||
extern const uint8_t ff_golomb_vlc_len[512];
|
||||
extern const uint8_t ff_ue_golomb_vlc_code[512];
|
||||
extern const int8_t ff_se_golomb_vlc_code[512];
|
||||
extern const uint8_t ff_ue_golomb_len[256];
|
||||
|
||||
extern const uint8_t ff_interleaved_golomb_vlc_len[256];
|
||||
extern const uint8_t ff_interleaved_ue_golomb_vlc_code[256];
|
||||
extern const int8_t ff_interleaved_se_golomb_vlc_code[256];
|
||||
extern const uint8_t ff_interleaved_dirac_golomb_vlc_code[256];
|
||||
|
||||
|
||||
/**
|
||||
* read unsigned exp golomb code.
|
||||
*/
|
||||
static inline int get_ue_golomb(GetBitContext *gb){
|
||||
unsigned int buf;
|
||||
int log;
|
||||
|
||||
OPEN_READER(re, gb);
|
||||
UPDATE_CACHE(re, gb);
|
||||
buf=GET_CACHE(re, gb);
|
||||
|
||||
if(buf >= (1<<27)){
|
||||
buf >>= 32 - 9;
|
||||
LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]);
|
||||
CLOSE_READER(re, gb);
|
||||
|
||||
return ff_ue_golomb_vlc_code[buf];
|
||||
}else{
|
||||
log= 2*av_log2(buf) - 31;
|
||||
LAST_SKIP_BITS(re, gb, 32 - log);
|
||||
CLOSE_READER(re, gb);
|
||||
if (CONFIG_FTRAPV && log < 0) {
|
||||
av_log(0, AV_LOG_ERROR, "Invalid UE golomb code\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
buf>>= log;
|
||||
buf--;
|
||||
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read an unsigned Exp-Golomb code in the range 0 to UINT32_MAX-1.
|
||||
*/
|
||||
static inline unsigned get_ue_golomb_long(GetBitContext *gb)
|
||||
{
|
||||
unsigned buf, log;
|
||||
|
||||
buf = show_bits_long(gb, 32);
|
||||
log = 31 - av_log2(buf);
|
||||
skip_bits_long(gb, log);
|
||||
|
||||
return get_bits_long(gb, log + 1) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* read unsigned exp golomb code, constraint to a max of 31.
|
||||
* the return value is undefined if the stored value exceeds 31.
|
||||
*/
|
||||
static inline int get_ue_golomb_31(GetBitContext *gb){
|
||||
unsigned int buf;
|
||||
|
||||
OPEN_READER(re, gb);
|
||||
UPDATE_CACHE(re, gb);
|
||||
buf=GET_CACHE(re, gb);
|
||||
|
||||
buf >>= 32 - 9;
|
||||
LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]);
|
||||
CLOSE_READER(re, gb);
|
||||
|
||||
return ff_ue_golomb_vlc_code[buf];
|
||||
}
|
||||
|
||||
static inline unsigned svq3_get_ue_golomb(GetBitContext *gb)
|
||||
{
|
||||
uint32_t buf;
|
||||
|
||||
OPEN_READER(re, gb);
|
||||
UPDATE_CACHE(re, gb);
|
||||
buf=GET_CACHE(re, gb);
|
||||
|
||||
if(buf&0xAA800000){
|
||||
buf >>= 32 - 8;
|
||||
LAST_SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]);
|
||||
CLOSE_READER(re, gb);
|
||||
|
||||
return ff_interleaved_ue_golomb_vlc_code[buf];
|
||||
}else{
|
||||
unsigned ret = 1;
|
||||
|
||||
do {
|
||||
buf >>= 32 - 8;
|
||||
LAST_SKIP_BITS(re, gb, FFMIN(ff_interleaved_golomb_vlc_len[buf], 8));
|
||||
|
||||
if (ff_interleaved_golomb_vlc_len[buf] != 9){
|
||||
ret <<= (ff_interleaved_golomb_vlc_len[buf] - 1) >> 1;
|
||||
ret |= ff_interleaved_dirac_golomb_vlc_code[buf];
|
||||
break;
|
||||
}
|
||||
ret = (ret << 4) | ff_interleaved_dirac_golomb_vlc_code[buf];
|
||||
UPDATE_CACHE(re, gb);
|
||||
buf = GET_CACHE(re, gb);
|
||||
} while (ret<0x8000000U && HAVE_BITS_REMAINING(re, gb));
|
||||
|
||||
CLOSE_READER(re, gb);
|
||||
return ret - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* read unsigned truncated exp golomb code.
|
||||
*/
|
||||
static inline int get_te0_golomb(GetBitContext *gb, int range){
|
||||
av_assert2(range >= 1);
|
||||
|
||||
if(range==1) return 0;
|
||||
else if(range==2) return get_bits1(gb)^1;
|
||||
else return get_ue_golomb(gb);
|
||||
}
|
||||
|
||||
/**
|
||||
* read unsigned truncated exp golomb code.
|
||||
*/
|
||||
static inline int get_te_golomb(GetBitContext *gb, int range){
|
||||
av_assert2(range >= 1);
|
||||
|
||||
if(range==2) return get_bits1(gb)^1;
|
||||
else return get_ue_golomb(gb);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* read signed exp golomb code.
|
||||
*/
|
||||
static inline int get_se_golomb(GetBitContext *gb){
|
||||
unsigned int buf;
|
||||
int log;
|
||||
|
||||
OPEN_READER(re, gb);
|
||||
UPDATE_CACHE(re, gb);
|
||||
buf=GET_CACHE(re, gb);
|
||||
|
||||
if(buf >= (1<<27)){
|
||||
buf >>= 32 - 9;
|
||||
LAST_SKIP_BITS(re, gb, ff_golomb_vlc_len[buf]);
|
||||
CLOSE_READER(re, gb);
|
||||
|
||||
return ff_se_golomb_vlc_code[buf];
|
||||
}else{
|
||||
log = av_log2(buf);
|
||||
LAST_SKIP_BITS(re, gb, 31 - log);
|
||||
UPDATE_CACHE(re, gb);
|
||||
buf = GET_CACHE(re, gb);
|
||||
|
||||
buf>>= log;
|
||||
|
||||
LAST_SKIP_BITS(re, gb, 32 - log);
|
||||
CLOSE_READER(re, gb);
|
||||
|
||||
if(buf&1) buf= -(buf>>1);
|
||||
else buf= (buf>>1);
|
||||
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int svq3_get_se_golomb(GetBitContext *gb){
|
||||
unsigned int buf;
|
||||
int log;
|
||||
|
||||
OPEN_READER(re, gb);
|
||||
UPDATE_CACHE(re, gb);
|
||||
buf=GET_CACHE(re, gb);
|
||||
|
||||
if(buf&0xAA800000){
|
||||
buf >>= 32 - 8;
|
||||
LAST_SKIP_BITS(re, gb, ff_interleaved_golomb_vlc_len[buf]);
|
||||
CLOSE_READER(re, gb);
|
||||
|
||||
return ff_interleaved_se_golomb_vlc_code[buf];
|
||||
}else{
|
||||
LAST_SKIP_BITS(re, gb, 8);
|
||||
UPDATE_CACHE(re, gb);
|
||||
buf |= 1 | (GET_CACHE(re, gb) >> 8);
|
||||
|
||||
if((buf & 0xAAAAAAAA) == 0)
|
||||
return INVALID_VLC;
|
||||
|
||||
for(log=31; (buf & 0x80000000) == 0; log--){
|
||||
buf = (buf << 2) - ((buf << log) >> (log - 1)) + (buf >> 30);
|
||||
}
|
||||
|
||||
LAST_SKIP_BITS(re, gb, 63 - 2*log - 8);
|
||||
CLOSE_READER(re, gb);
|
||||
|
||||
return (signed) (((((buf << log) >> log) - 1) ^ -(buf & 0x1)) + 1) >> 1;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int dirac_get_se_golomb(GetBitContext *gb){
|
||||
uint32_t buf;
|
||||
uint32_t ret;
|
||||
|
||||
ret = svq3_get_ue_golomb(gb);
|
||||
|
||||
if (ret) {
|
||||
OPEN_READER(re, gb);
|
||||
UPDATE_CACHE(re, gb);
|
||||
buf = SHOW_SBITS(re, gb, 1);
|
||||
LAST_SKIP_BITS(re, gb, 1);
|
||||
ret = (ret ^ buf) - buf;
|
||||
CLOSE_READER(re, gb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* read unsigned golomb rice code (ffv1).
|
||||
*/
|
||||
static inline int get_ur_golomb(GetBitContext *gb, int k, int limit, int esc_len){
|
||||
unsigned int buf;
|
||||
int log;
|
||||
|
||||
OPEN_READER(re, gb);
|
||||
UPDATE_CACHE(re, gb);
|
||||
buf=GET_CACHE(re, gb);
|
||||
|
||||
log= av_log2(buf);
|
||||
|
||||
if(log > 31-limit){
|
||||
buf >>= log - k;
|
||||
buf += (30-log)<<k;
|
||||
LAST_SKIP_BITS(re, gb, 32 + k - log);
|
||||
CLOSE_READER(re, gb);
|
||||
|
||||
return buf;
|
||||
}else{
|
||||
LAST_SKIP_BITS(re, gb, limit);
|
||||
UPDATE_CACHE(re, gb);
|
||||
|
||||
buf = SHOW_UBITS(re, gb, esc_len);
|
||||
|
||||
LAST_SKIP_BITS(re, gb, esc_len);
|
||||
CLOSE_READER(re, gb);
|
||||
|
||||
return buf + limit - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* read unsigned golomb rice code (jpegls).
|
||||
*/
|
||||
static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, int esc_len){
|
||||
unsigned int buf;
|
||||
int log;
|
||||
|
||||
OPEN_READER(re, gb);
|
||||
UPDATE_CACHE(re, gb);
|
||||
buf=GET_CACHE(re, gb);
|
||||
|
||||
log= av_log2(buf);
|
||||
|
||||
if(log - k >= 32-MIN_CACHE_BITS+(MIN_CACHE_BITS==32) && 32-log < limit){
|
||||
buf >>= log - k;
|
||||
buf += (30-log)<<k;
|
||||
LAST_SKIP_BITS(re, gb, 32 + k - log);
|
||||
CLOSE_READER(re, gb);
|
||||
|
||||
return buf;
|
||||
}else{
|
||||
int i;
|
||||
for (i = 0; i < limit && SHOW_UBITS(re, gb, 1) == 0; i++) {
|
||||
if (gb->size_in_bits <= re_index)
|
||||
return -1;
|
||||
LAST_SKIP_BITS(re, gb, 1);
|
||||
UPDATE_CACHE(re, gb);
|
||||
}
|
||||
SKIP_BITS(re, gb, 1);
|
||||
|
||||
if(i < limit - 1){
|
||||
if(k){
|
||||
buf = SHOW_UBITS(re, gb, k);
|
||||
LAST_SKIP_BITS(re, gb, k);
|
||||
}else{
|
||||
buf=0;
|
||||
}
|
||||
|
||||
CLOSE_READER(re, gb);
|
||||
return buf + (i<<k);
|
||||
}else if(i == limit - 1){
|
||||
buf = SHOW_UBITS(re, gb, esc_len);
|
||||
LAST_SKIP_BITS(re, gb, esc_len);
|
||||
CLOSE_READER(re, gb);
|
||||
|
||||
return buf + 1;
|
||||
}else
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* read signed golomb rice code (ffv1).
|
||||
*/
|
||||
static inline int get_sr_golomb(GetBitContext *gb, int k, int limit, int esc_len){
|
||||
int v= get_ur_golomb(gb, k, limit, esc_len);
|
||||
|
||||
v++;
|
||||
if (v&1) return v>>1;
|
||||
else return -(v>>1);
|
||||
|
||||
// return (v>>1) ^ -(v&1);
|
||||
}
|
||||
|
||||
/**
|
||||
* read signed golomb rice code (flac).
|
||||
*/
|
||||
static inline int get_sr_golomb_flac(GetBitContext *gb, int k, int limit, int esc_len){
|
||||
int v= get_ur_golomb_jpegls(gb, k, limit, esc_len);
|
||||
return (v>>1) ^ -(v&1);
|
||||
}
|
||||
|
||||
/**
|
||||
* read unsigned golomb rice code (shorten).
|
||||
*/
|
||||
static inline unsigned int get_ur_golomb_shorten(GetBitContext *gb, int k){
|
||||
return get_ur_golomb_jpegls(gb, k, INT_MAX, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* read signed golomb rice code (shorten).
|
||||
*/
|
||||
static inline int get_sr_golomb_shorten(GetBitContext* gb, int k)
|
||||
{
|
||||
int uvar = get_ur_golomb_jpegls(gb, k + 1, INT_MAX, 0);
|
||||
if (uvar & 1)
|
||||
return ~(uvar >> 1);
|
||||
else
|
||||
return uvar >> 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef TRACE
|
||||
|
||||
static inline int get_ue(GetBitContext *s, const char *file, const char *func,
|
||||
int line)
|
||||
{
|
||||
int show= show_bits(s, 24);
|
||||
int pos= get_bits_count(s);
|
||||
int i= get_ue_golomb(s);
|
||||
int len= get_bits_count(s) - pos;
|
||||
int bits= show>>(24-len);
|
||||
|
||||
print_bin(bits, len);
|
||||
|
||||
av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d ue @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static inline int get_se(GetBitContext *s, const char *file, const char *func,
|
||||
int line)
|
||||
{
|
||||
int show= show_bits(s, 24);
|
||||
int pos= get_bits_count(s);
|
||||
int i= get_se_golomb(s);
|
||||
int len= get_bits_count(s) - pos;
|
||||
int bits= show>>(24-len);
|
||||
|
||||
print_bin(bits, len);
|
||||
|
||||
av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d se @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static inline int get_te(GetBitContext *s, int r, char *file, const char *func, int line){
|
||||
int show= show_bits(s, 24);
|
||||
int pos= get_bits_count(s);
|
||||
int i= get_te0_golomb(s, r);
|
||||
int len= get_bits_count(s) - pos;
|
||||
int bits= show>>(24-len);
|
||||
|
||||
print_bin(bits, len);
|
||||
|
||||
av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d te @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
#define get_ue_golomb(a) get_ue(a, __FILE__, __PRETTY_FUNCTION__, __LINE__)
|
||||
#define get_se_golomb(a) get_se(a, __FILE__, __PRETTY_FUNCTION__, __LINE__)
|
||||
#define get_te_golomb(a, r) get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__)
|
||||
#define get_te0_golomb(a, r) get_te(a, r, __FILE__, __PRETTY_FUNCTION__, __LINE__)
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* write unsigned exp golomb code.
|
||||
*/
|
||||
static inline void set_ue_golomb(PutBitContext *pb, int i){
|
||||
int e;
|
||||
|
||||
av_assert2(i>=0);
|
||||
|
||||
#if 0
|
||||
if(i=0){
|
||||
put_bits(pb, 1, 1);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if(i<256)
|
||||
put_bits(pb, ff_ue_golomb_len[i], i+1);
|
||||
else{
|
||||
e= av_log2(i+1);
|
||||
|
||||
put_bits(pb, 2*e+1, i+1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* write truncated unsigned exp golomb code.
|
||||
*/
|
||||
static inline void set_te_golomb(PutBitContext *pb, int i, int range){
|
||||
av_assert2(range >= 1);
|
||||
av_assert2(i<=range);
|
||||
|
||||
if(range==2) put_bits(pb, 1, i^1);
|
||||
else set_ue_golomb(pb, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* write signed exp golomb code. 16 bits at most.
|
||||
*/
|
||||
static inline void set_se_golomb(PutBitContext *pb, int i){
|
||||
#if 0
|
||||
if(i<=0) i= -2*i;
|
||||
else i= 2*i-1;
|
||||
#elif 1
|
||||
i= 2*i-1;
|
||||
if(i<0) i^= -1; //FIXME check if gcc does the right thing
|
||||
#else
|
||||
i= 2*i-1;
|
||||
i^= (i>>31);
|
||||
#endif
|
||||
set_ue_golomb(pb, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* write unsigned golomb rice code (ffv1).
|
||||
*/
|
||||
static inline void set_ur_golomb(PutBitContext *pb, int i, int k, int limit, int esc_len){
|
||||
int e;
|
||||
|
||||
av_assert2(i>=0);
|
||||
|
||||
e= i>>k;
|
||||
if(e<limit){
|
||||
put_bits(pb, e + k + 1, (1<<k) + (i&((1<<k)-1)));
|
||||
}else{
|
||||
put_bits(pb, limit + esc_len, i - limit + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* write unsigned golomb rice code (jpegls).
|
||||
*/
|
||||
static inline void set_ur_golomb_jpegls(PutBitContext *pb, int i, int k, int limit, int esc_len){
|
||||
int e;
|
||||
|
||||
av_assert2(i>=0);
|
||||
|
||||
e= (i>>k) + 1;
|
||||
if(e<limit){
|
||||
while(e > 31) {
|
||||
put_bits(pb, 31, 0);
|
||||
e -= 31;
|
||||
}
|
||||
put_bits(pb, e, 1);
|
||||
if(k)
|
||||
put_sbits(pb, k, i);
|
||||
}else{
|
||||
while(limit > 31) {
|
||||
put_bits(pb, 31, 0);
|
||||
limit -= 31;
|
||||
}
|
||||
put_bits(pb, limit , 1);
|
||||
put_bits(pb, esc_len, i - 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* write signed golomb rice code (ffv1).
|
||||
*/
|
||||
static inline void set_sr_golomb(PutBitContext *pb, int i, int k, int limit, int esc_len){
|
||||
int v;
|
||||
|
||||
v = -2*i-1;
|
||||
v ^= (v>>31);
|
||||
|
||||
set_ur_golomb(pb, v, k, limit, esc_len);
|
||||
}
|
||||
|
||||
/**
|
||||
* write signed golomb rice code (flac).
|
||||
*/
|
||||
static inline void set_sr_golomb_flac(PutBitContext *pb, int i, int k, int limit, int esc_len){
|
||||
int v;
|
||||
|
||||
v = -2*i-1;
|
||||
v ^= (v>>31);
|
||||
|
||||
set_ur_golomb_jpegls(pb, v, k, limit, esc_len);
|
||||
}
|
||||
|
||||
#endif /* AVCODEC_GOLOMB_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* TAK common code
|
||||
* Copyright (c) 2012 Paul B Mahol
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "libavutil/crc.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
#include "tak.h"
|
||||
|
||||
static const int64_t tak_channel_layouts[] = {
|
||||
0,
|
||||
AV_CH_FRONT_LEFT,
|
||||
AV_CH_FRONT_RIGHT,
|
||||
AV_CH_FRONT_CENTER,
|
||||
AV_CH_LOW_FREQUENCY,
|
||||
AV_CH_BACK_LEFT,
|
||||
AV_CH_BACK_RIGHT,
|
||||
AV_CH_FRONT_LEFT_OF_CENTER,
|
||||
AV_CH_FRONT_RIGHT_OF_CENTER,
|
||||
AV_CH_BACK_CENTER,
|
||||
AV_CH_SIDE_LEFT,
|
||||
AV_CH_SIDE_RIGHT,
|
||||
AV_CH_TOP_CENTER,
|
||||
AV_CH_TOP_FRONT_LEFT,
|
||||
AV_CH_TOP_FRONT_CENTER,
|
||||
AV_CH_TOP_FRONT_RIGHT,
|
||||
AV_CH_TOP_BACK_LEFT,
|
||||
AV_CH_TOP_BACK_CENTER,
|
||||
AV_CH_TOP_BACK_RIGHT,
|
||||
};
|
||||
|
||||
static const uint16_t frame_duration_type_quants[] = {
|
||||
3, 4, 6, 8, 4096, 8192, 16384, 512, 1024, 2048,
|
||||
};
|
||||
|
||||
static int tak_get_nb_samples(int sample_rate, enum TAKFrameSizeType type)
|
||||
{
|
||||
int nb_samples, max_nb_samples;
|
||||
|
||||
if (type <= TAK_FST_250ms) {
|
||||
nb_samples = sample_rate * frame_duration_type_quants[type] >>
|
||||
TAK_FRAME_DURATION_QUANT_SHIFT;
|
||||
max_nb_samples = 16384;
|
||||
} else if (type < FF_ARRAY_ELEMS(frame_duration_type_quants)) {
|
||||
nb_samples = frame_duration_type_quants[type];
|
||||
max_nb_samples = sample_rate *
|
||||
frame_duration_type_quants[TAK_FST_250ms] >>
|
||||
TAK_FRAME_DURATION_QUANT_SHIFT;
|
||||
} else {
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
if (nb_samples <= 0 || nb_samples > max_nb_samples)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
return nb_samples;
|
||||
}
|
||||
|
||||
int ff_tak_check_crc(const uint8_t *buf, unsigned int buf_size)
|
||||
{
|
||||
uint32_t crc, CRC;
|
||||
|
||||
if (buf_size < 4)
|
||||
return AVERROR_INVALIDDATA;
|
||||
buf_size -= 3;
|
||||
|
||||
CRC = AV_RB24(buf + buf_size);
|
||||
crc = av_crc(av_crc_get_table(AV_CRC_24_IEEE), 0xCE04B7U, buf, buf_size);
|
||||
if (CRC != crc)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void avpriv_tak_parse_streaminfo(GetBitContext *gb, TAKStreamInfo *s)
|
||||
{
|
||||
uint64_t channel_mask = 0;
|
||||
int frame_type, i;
|
||||
|
||||
s->codec = get_bits(gb, TAK_ENCODER_CODEC_BITS);
|
||||
skip_bits(gb, TAK_ENCODER_PROFILE_BITS);
|
||||
|
||||
frame_type = get_bits(gb, TAK_SIZE_FRAME_DURATION_BITS);
|
||||
s->samples = get_bits64(gb, TAK_SIZE_SAMPLES_NUM_BITS);
|
||||
|
||||
s->data_type = get_bits(gb, TAK_FORMAT_DATA_TYPE_BITS);
|
||||
s->sample_rate = get_bits(gb, TAK_FORMAT_SAMPLE_RATE_BITS) +
|
||||
TAK_SAMPLE_RATE_MIN;
|
||||
s->bps = get_bits(gb, TAK_FORMAT_BPS_BITS) +
|
||||
TAK_BPS_MIN;
|
||||
s->channels = get_bits(gb, TAK_FORMAT_CHANNEL_BITS) +
|
||||
TAK_CHANNELS_MIN;
|
||||
|
||||
if (get_bits1(gb)) {
|
||||
skip_bits(gb, TAK_FORMAT_VALID_BITS);
|
||||
if (get_bits1(gb)) {
|
||||
for (i = 0; i < s->channels; i++) {
|
||||
int value = get_bits(gb, TAK_FORMAT_CH_LAYOUT_BITS);
|
||||
|
||||
if (value < FF_ARRAY_ELEMS(tak_channel_layouts))
|
||||
channel_mask |= tak_channel_layouts[value];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s->ch_layout = channel_mask;
|
||||
s->frame_samples = tak_get_nb_samples(s->sample_rate, frame_type);
|
||||
}
|
||||
|
||||
int ff_tak_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,
|
||||
TAKStreamInfo *ti, int log_level_offset)
|
||||
{
|
||||
if (get_bits(gb, TAK_FRAME_HEADER_SYNC_ID_BITS) != TAK_FRAME_HEADER_SYNC_ID) {
|
||||
av_log(avctx, AV_LOG_ERROR + log_level_offset, "missing sync id\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
ti->flags = get_bits(gb, TAK_FRAME_HEADER_FLAGS_BITS);
|
||||
ti->frame_num = get_bits(gb, TAK_FRAME_HEADER_NO_BITS);
|
||||
|
||||
if (ti->flags & TAK_FRAME_FLAG_IS_LAST) {
|
||||
ti->last_frame_samples = get_bits(gb, TAK_FRAME_HEADER_SAMPLE_COUNT_BITS) + 1;
|
||||
skip_bits(gb, 2);
|
||||
} else {
|
||||
ti->last_frame_samples = 0;
|
||||
}
|
||||
|
||||
if (ti->flags & TAK_FRAME_FLAG_HAS_INFO) {
|
||||
avpriv_tak_parse_streaminfo(gb, ti);
|
||||
|
||||
if (get_bits(gb, 6))
|
||||
skip_bits(gb, 25);
|
||||
align_get_bits(gb);
|
||||
}
|
||||
|
||||
if (ti->flags & TAK_FRAME_FLAG_HAS_METADATA)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
skip_bits(gb, 24);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* TAK decoder/demuxer common code
|
||||
* Copyright (c) 2012 Paul B Mahol
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* TAK (Tom's lossless Audio Kompressor) decoder/demuxer common functions
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_TAK_H
|
||||
#define AVCODEC_TAK_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define BITSTREAM_READER_LE
|
||||
#include "get_bits.h"
|
||||
#include "avcodec.h"
|
||||
|
||||
#define TAK_FORMAT_DATA_TYPE_BITS 3
|
||||
#define TAK_FORMAT_SAMPLE_RATE_BITS 18
|
||||
#define TAK_FORMAT_BPS_BITS 5
|
||||
#define TAK_FORMAT_CHANNEL_BITS 4
|
||||
#define TAK_FORMAT_VALID_BITS 5
|
||||
#define TAK_FORMAT_CH_LAYOUT_BITS 6
|
||||
#define TAK_SIZE_FRAME_DURATION_BITS 4
|
||||
#define TAK_SIZE_SAMPLES_NUM_BITS 35
|
||||
#define TAK_LAST_FRAME_POS_BITS 40
|
||||
#define TAK_LAST_FRAME_SIZE_BITS 24
|
||||
#define TAK_ENCODER_CODEC_BITS 6
|
||||
#define TAK_ENCODER_PROFILE_BITS 4
|
||||
#define TAK_ENCODER_VERSION_BITS 24
|
||||
#define TAK_SAMPLE_RATE_MIN 6000
|
||||
#define TAK_CHANNELS_MIN 1
|
||||
#define TAK_BPS_MIN 8
|
||||
#define TAK_FRAME_HEADER_FLAGS_BITS 3
|
||||
#define TAK_FRAME_HEADER_SYNC_ID 0xA0FF
|
||||
#define TAK_FRAME_HEADER_SYNC_ID_BITS 16
|
||||
#define TAK_FRAME_HEADER_SAMPLE_COUNT_BITS 14
|
||||
#define TAK_FRAME_HEADER_NO_BITS 21
|
||||
#define TAK_FRAME_DURATION_QUANT_SHIFT 5
|
||||
#define TAK_CRC24_BITS 24
|
||||
|
||||
|
||||
#define TAK_FRAME_FLAG_IS_LAST 0x1
|
||||
#define TAK_FRAME_FLAG_HAS_INFO 0x2
|
||||
#define TAK_FRAME_FLAG_HAS_METADATA 0x4
|
||||
|
||||
#define TAK_MAX_CHANNELS (1 << TAK_FORMAT_CHANNEL_BITS)
|
||||
|
||||
#define TAK_MIN_FRAME_HEADER_BITS (TAK_FRAME_HEADER_SYNC_ID_BITS + \
|
||||
TAK_FRAME_HEADER_FLAGS_BITS + \
|
||||
TAK_FRAME_HEADER_NO_BITS + \
|
||||
TAK_CRC24_BITS)
|
||||
|
||||
#define TAK_MIN_FRAME_HEADER_LAST_BITS (TAK_MIN_FRAME_HEADER_BITS + 2 + \
|
||||
TAK_FRAME_HEADER_SAMPLE_COUNT_BITS)
|
||||
|
||||
#define TAK_ENCODER_BITS (TAK_ENCODER_CODEC_BITS + \
|
||||
TAK_ENCODER_PROFILE_BITS)
|
||||
|
||||
#define TAK_SIZE_BITS (TAK_SIZE_SAMPLES_NUM_BITS + \
|
||||
TAK_SIZE_FRAME_DURATION_BITS)
|
||||
|
||||
#define TAK_FORMAT_BITS (TAK_FORMAT_DATA_TYPE_BITS + \
|
||||
TAK_FORMAT_SAMPLE_RATE_BITS + \
|
||||
TAK_FORMAT_BPS_BITS + \
|
||||
TAK_FORMAT_CHANNEL_BITS + 1 + \
|
||||
TAK_FORMAT_VALID_BITS + 1 + \
|
||||
TAK_FORMAT_CH_LAYOUT_BITS * \
|
||||
TAK_MAX_CHANNELS)
|
||||
|
||||
#define TAK_STREAMINFO_BITS (TAK_ENCODER_BITS + \
|
||||
TAK_SIZE_BITS + \
|
||||
TAK_FORMAT_BITS)
|
||||
|
||||
#define TAK_MAX_FRAME_HEADER_BITS (TAK_MIN_FRAME_HEADER_LAST_BITS + \
|
||||
TAK_STREAMINFO_BITS + 31)
|
||||
|
||||
#define TAK_STREAMINFO_BYTES ((TAK_STREAMINFO_BITS + 7) / 8)
|
||||
#define TAK_MAX_FRAME_HEADER_BYTES ((TAK_MAX_FRAME_HEADER_BITS + 7) / 8)
|
||||
#define TAK_MIN_FRAME_HEADER_BYTES ((TAK_MIN_FRAME_HEADER_BITS + 7) / 8)
|
||||
|
||||
enum TAKCodecType {
|
||||
TAK_CODEC_MONO_STEREO = 2,
|
||||
TAK_CODEC_MULTICHANNEL = 4,
|
||||
};
|
||||
|
||||
enum TAKMetaDataType {
|
||||
TAK_METADATA_END = 0,
|
||||
TAK_METADATA_STREAMINFO,
|
||||
TAK_METADATA_SEEKTABLE,
|
||||
TAK_METADATA_SIMPLE_WAVE_DATA,
|
||||
TAK_METADATA_ENCODER,
|
||||
TAK_METADATA_PADDING,
|
||||
TAK_METADATA_MD5,
|
||||
TAK_METADATA_LAST_FRAME,
|
||||
};
|
||||
|
||||
enum TAKFrameSizeType {
|
||||
TAK_FST_94ms = 0,
|
||||
TAK_FST_125ms,
|
||||
TAK_FST_188ms,
|
||||
TAK_FST_250ms,
|
||||
TAK_FST_4096,
|
||||
TAK_FST_8192,
|
||||
TAK_FST_16384,
|
||||
TAK_FST_512,
|
||||
TAK_FST_1024,
|
||||
TAK_FST_2048,
|
||||
};
|
||||
|
||||
typedef struct TAKStreamInfo {
|
||||
int flags;
|
||||
enum TAKCodecType codec;
|
||||
int data_type;
|
||||
int sample_rate;
|
||||
int channels;
|
||||
int bps;
|
||||
int frame_num;
|
||||
int frame_samples;
|
||||
int last_frame_samples;
|
||||
uint64_t ch_layout;
|
||||
int64_t samples;
|
||||
} TAKStreamInfo;
|
||||
|
||||
int ff_tak_check_crc(const uint8_t *buf, unsigned int buf_size);
|
||||
|
||||
/**
|
||||
* Parse the Streaminfo metadata block.
|
||||
* @param[in] gb pointer to GetBitContext
|
||||
* @param[out] s storage for parsed information
|
||||
*/
|
||||
void avpriv_tak_parse_streaminfo(GetBitContext *gb, TAKStreamInfo *s);
|
||||
|
||||
/**
|
||||
* Validate and decode a frame header.
|
||||
* @param avctx AVCodecContext to use as av_log() context
|
||||
* @param[in] gb GetBitContext from which to read frame header
|
||||
* @param[out] s frame information
|
||||
* @param log_level_offset log level offset, can be used to silence
|
||||
* error messages.
|
||||
* @return non-zero on error, 0 if OK
|
||||
*/
|
||||
int ff_tak_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb,
|
||||
TAKStreamInfo *s, int log_level_offset);
|
||||
#endif /* AVCODEC_TAK_H */
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* TAK parser
|
||||
* Copyright (c) 2012 Michael Niedermayer
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* TAK parser
|
||||
**/
|
||||
|
||||
#include "tak.h"
|
||||
#include "parser.h"
|
||||
|
||||
typedef struct TAKParseContext {
|
||||
ParseContext pc;
|
||||
TAKStreamInfo ti;
|
||||
int index;
|
||||
} TAKParseContext;
|
||||
|
||||
static int tak_parse(AVCodecParserContext *s, AVCodecContext *avctx,
|
||||
const uint8_t **poutbuf, int *poutbuf_size,
|
||||
const uint8_t *buf, int buf_size)
|
||||
{
|
||||
TAKParseContext *t = s->priv_data;
|
||||
ParseContext *pc = &t->pc;
|
||||
int next = END_NOT_FOUND;
|
||||
GetBitContext gb;
|
||||
int consumed = 0;
|
||||
int needed = buf_size ? TAK_MAX_FRAME_HEADER_BYTES : 8;
|
||||
|
||||
if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
|
||||
TAKStreamInfo ti;
|
||||
init_get_bits(&gb, buf, buf_size);
|
||||
if (!ff_tak_decode_frame_header(avctx, &gb, &ti, 127))
|
||||
s->duration = t->ti.last_frame_samples ? t->ti.last_frame_samples
|
||||
: t->ti.frame_samples;
|
||||
*poutbuf = buf;
|
||||
*poutbuf_size = buf_size;
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
while (buf_size || t->index + needed <= pc->index) {
|
||||
if (buf_size && t->index + TAK_MAX_FRAME_HEADER_BYTES > pc->index) {
|
||||
int tmp_buf_size = FFMIN(2 * TAK_MAX_FRAME_HEADER_BYTES,
|
||||
buf_size);
|
||||
const uint8_t *tmp_buf = buf;
|
||||
|
||||
if (ff_combine_frame(pc, END_NOT_FOUND, &tmp_buf, &tmp_buf_size) != -1)
|
||||
return AVERROR(ENOMEM);
|
||||
consumed += tmp_buf_size;
|
||||
buf += tmp_buf_size;
|
||||
buf_size -= tmp_buf_size;
|
||||
}
|
||||
|
||||
for (; t->index + needed <= pc->index; t->index++) {
|
||||
if (pc->buffer[ t->index ] == 0xFF &&
|
||||
pc->buffer[ t->index + 1 ] == 0xA0) {
|
||||
TAKStreamInfo ti;
|
||||
|
||||
init_get_bits(&gb, pc->buffer + t->index,
|
||||
8 * (pc->index - t->index));
|
||||
if (!ff_tak_decode_frame_header(avctx, &gb,
|
||||
pc->frame_start_found ? &ti : &t->ti, 127) &&
|
||||
!ff_tak_check_crc(pc->buffer + t->index,
|
||||
get_bits_count(&gb) / 8)) {
|
||||
if (!pc->frame_start_found) {
|
||||
pc->frame_start_found = 1;
|
||||
s->duration = t->ti.last_frame_samples ?
|
||||
t->ti.last_frame_samples :
|
||||
t->ti.frame_samples;
|
||||
s->key_frame = !!(t->ti.flags & TAK_FRAME_FLAG_HAS_INFO);
|
||||
} else {
|
||||
pc->frame_start_found = 0;
|
||||
next = t->index - pc->index;
|
||||
t->index = 0;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
found:
|
||||
|
||||
if (consumed && !buf_size && next == END_NOT_FOUND ||
|
||||
ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
|
||||
*poutbuf = NULL;
|
||||
*poutbuf_size = 0;
|
||||
return buf_size + consumed;
|
||||
}
|
||||
|
||||
if (next != END_NOT_FOUND) {
|
||||
next += consumed;
|
||||
pc->overread = FFMAX(0, -next);
|
||||
}
|
||||
|
||||
*poutbuf = buf;
|
||||
*poutbuf_size = buf_size;
|
||||
return next;
|
||||
}
|
||||
|
||||
AVCodecParser ff_tak_parser = {
|
||||
.codec_ids = { AV_CODEC_ID_TAK },
|
||||
.priv_data_size = sizeof(TAKParseContext),
|
||||
.parser_parse = tak_parse,
|
||||
.parser_close = ff_parse_close,
|
||||
};
|
|
@ -0,0 +1,948 @@
|
|||
/*
|
||||
* TAK decoder
|
||||
* Copyright (c) 2012 Paul B Mahol
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* TAK (Tom's lossless Audio Kompressor) decoder
|
||||
* @author Paul B Mahol
|
||||
*/
|
||||
|
||||
#include "libavutil/internal.h"
|
||||
#include "libavutil/samplefmt.h"
|
||||
#include "tak.h"
|
||||
#include "thread.h"
|
||||
#include "avcodec.h"
|
||||
#include "dsputil.h"
|
||||
#include "internal.h"
|
||||
#include "unary.h"
|
||||
|
||||
#define MAX_SUBFRAMES 8 ///< max number of subframes per channel
|
||||
#define MAX_PREDICTORS 256
|
||||
|
||||
typedef struct MCDParam {
|
||||
int8_t present; ///< decorrelation parameter availability for this channel
|
||||
int8_t index; ///< index into array of decorrelation types
|
||||
int8_t chan1;
|
||||
int8_t chan2;
|
||||
} MCDParam;
|
||||
|
||||
typedef struct TAKDecContext {
|
||||
AVCodecContext *avctx; ///< parent AVCodecContext
|
||||
DSPContext dsp;
|
||||
TAKStreamInfo ti;
|
||||
GetBitContext gb; ///< bitstream reader initialized to start at the current frame
|
||||
|
||||
int uval;
|
||||
int nb_samples; ///< number of samples in the current frame
|
||||
uint8_t *decode_buffer;
|
||||
unsigned int decode_buffer_size;
|
||||
int32_t *decoded[TAK_MAX_CHANNELS]; ///< decoded samples for each channel
|
||||
|
||||
int8_t lpc_mode[TAK_MAX_CHANNELS];
|
||||
int8_t sample_shift[TAK_MAX_CHANNELS]; ///< shift applied to every sample in the channel
|
||||
int16_t predictors[MAX_PREDICTORS];
|
||||
int nb_subframes; ///< number of subframes in the current frame
|
||||
int16_t subframe_len[MAX_SUBFRAMES]; ///< subframe length in samples
|
||||
int subframe_scale;
|
||||
|
||||
int8_t dmode; ///< channel decorrelation type in the current frame
|
||||
|
||||
MCDParam mcdparams[TAK_MAX_CHANNELS]; ///< multichannel decorrelation parameters
|
||||
|
||||
int8_t coding_mode[128];
|
||||
DECLARE_ALIGNED(16, int16_t, filter)[MAX_PREDICTORS];
|
||||
DECLARE_ALIGNED(16, int16_t, residues)[544];
|
||||
} TAKDecContext;
|
||||
|
||||
static const int8_t mc_dmodes[] = { 1, 3, 4, 6, };
|
||||
|
||||
static const uint16_t predictor_sizes[] = {
|
||||
4, 8, 12, 16, 24, 32, 48, 64, 80, 96, 128, 160, 192, 224, 256, 0,
|
||||
};
|
||||
|
||||
static const struct CParam {
|
||||
int init;
|
||||
int escape;
|
||||
int scale;
|
||||
int aescape;
|
||||
int bias;
|
||||
} xcodes[50] = {
|
||||
{ 0x01, 0x0000001, 0x0000001, 0x0000003, 0x0000008 },
|
||||
{ 0x02, 0x0000003, 0x0000001, 0x0000007, 0x0000006 },
|
||||
{ 0x03, 0x0000005, 0x0000002, 0x000000E, 0x000000D },
|
||||
{ 0x03, 0x0000003, 0x0000003, 0x000000D, 0x0000018 },
|
||||
{ 0x04, 0x000000B, 0x0000004, 0x000001C, 0x0000019 },
|
||||
{ 0x04, 0x0000006, 0x0000006, 0x000001A, 0x0000030 },
|
||||
{ 0x05, 0x0000016, 0x0000008, 0x0000038, 0x0000032 },
|
||||
{ 0x05, 0x000000C, 0x000000C, 0x0000034, 0x0000060 },
|
||||
{ 0x06, 0x000002C, 0x0000010, 0x0000070, 0x0000064 },
|
||||
{ 0x06, 0x0000018, 0x0000018, 0x0000068, 0x00000C0 },
|
||||
{ 0x07, 0x0000058, 0x0000020, 0x00000E0, 0x00000C8 },
|
||||
{ 0x07, 0x0000030, 0x0000030, 0x00000D0, 0x0000180 },
|
||||
{ 0x08, 0x00000B0, 0x0000040, 0x00001C0, 0x0000190 },
|
||||
{ 0x08, 0x0000060, 0x0000060, 0x00001A0, 0x0000300 },
|
||||
{ 0x09, 0x0000160, 0x0000080, 0x0000380, 0x0000320 },
|
||||
{ 0x09, 0x00000C0, 0x00000C0, 0x0000340, 0x0000600 },
|
||||
{ 0x0A, 0x00002C0, 0x0000100, 0x0000700, 0x0000640 },
|
||||
{ 0x0A, 0x0000180, 0x0000180, 0x0000680, 0x0000C00 },
|
||||
{ 0x0B, 0x0000580, 0x0000200, 0x0000E00, 0x0000C80 },
|
||||
{ 0x0B, 0x0000300, 0x0000300, 0x0000D00, 0x0001800 },
|
||||
{ 0x0C, 0x0000B00, 0x0000400, 0x0001C00, 0x0001900 },
|
||||
{ 0x0C, 0x0000600, 0x0000600, 0x0001A00, 0x0003000 },
|
||||
{ 0x0D, 0x0001600, 0x0000800, 0x0003800, 0x0003200 },
|
||||
{ 0x0D, 0x0000C00, 0x0000C00, 0x0003400, 0x0006000 },
|
||||
{ 0x0E, 0x0002C00, 0x0001000, 0x0007000, 0x0006400 },
|
||||
{ 0x0E, 0x0001800, 0x0001800, 0x0006800, 0x000C000 },
|
||||
{ 0x0F, 0x0005800, 0x0002000, 0x000E000, 0x000C800 },
|
||||
{ 0x0F, 0x0003000, 0x0003000, 0x000D000, 0x0018000 },
|
||||
{ 0x10, 0x000B000, 0x0004000, 0x001C000, 0x0019000 },
|
||||
{ 0x10, 0x0006000, 0x0006000, 0x001A000, 0x0030000 },
|
||||
{ 0x11, 0x0016000, 0x0008000, 0x0038000, 0x0032000 },
|
||||
{ 0x11, 0x000C000, 0x000C000, 0x0034000, 0x0060000 },
|
||||
{ 0x12, 0x002C000, 0x0010000, 0x0070000, 0x0064000 },
|
||||
{ 0x12, 0x0018000, 0x0018000, 0x0068000, 0x00C0000 },
|
||||
{ 0x13, 0x0058000, 0x0020000, 0x00E0000, 0x00C8000 },
|
||||
{ 0x13, 0x0030000, 0x0030000, 0x00D0000, 0x0180000 },
|
||||
{ 0x14, 0x00B0000, 0x0040000, 0x01C0000, 0x0190000 },
|
||||
{ 0x14, 0x0060000, 0x0060000, 0x01A0000, 0x0300000 },
|
||||
{ 0x15, 0x0160000, 0x0080000, 0x0380000, 0x0320000 },
|
||||
{ 0x15, 0x00C0000, 0x00C0000, 0x0340000, 0x0600000 },
|
||||
{ 0x16, 0x02C0000, 0x0100000, 0x0700000, 0x0640000 },
|
||||
{ 0x16, 0x0180000, 0x0180000, 0x0680000, 0x0C00000 },
|
||||
{ 0x17, 0x0580000, 0x0200000, 0x0E00000, 0x0C80000 },
|
||||
{ 0x17, 0x0300000, 0x0300000, 0x0D00000, 0x1800000 },
|
||||
{ 0x18, 0x0B00000, 0x0400000, 0x1C00000, 0x1900000 },
|
||||
{ 0x18, 0x0600000, 0x0600000, 0x1A00000, 0x3000000 },
|
||||
{ 0x19, 0x1600000, 0x0800000, 0x3800000, 0x3200000 },
|
||||
{ 0x19, 0x0C00000, 0x0C00000, 0x3400000, 0x6000000 },
|
||||
{ 0x1A, 0x2C00000, 0x1000000, 0x7000000, 0x6400000 },
|
||||
{ 0x1A, 0x1800000, 0x1800000, 0x6800000, 0xC000000 },
|
||||
};
|
||||
|
||||
static int set_bps_params(AVCodecContext *avctx)
|
||||
{
|
||||
switch (avctx->bits_per_raw_sample) {
|
||||
case 8:
|
||||
avctx->sample_fmt = AV_SAMPLE_FMT_U8P;
|
||||
break;
|
||||
case 16:
|
||||
avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
|
||||
break;
|
||||
case 24:
|
||||
avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
|
||||
break;
|
||||
default:
|
||||
av_log(avctx, AV_LOG_ERROR, "invalid/unsupported bits per sample: %d\n",
|
||||
avctx->bits_per_raw_sample);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_sample_rate_params(AVCodecContext *avctx)
|
||||
{
|
||||
TAKDecContext *s = avctx->priv_data;
|
||||
int shift = 3 - (avctx->sample_rate / 11025);
|
||||
shift = FFMAX(0, shift);
|
||||
s->uval = FFALIGN(avctx->sample_rate + 511 >> 9, 4) << shift;
|
||||
s->subframe_scale = FFALIGN(avctx->sample_rate + 511 >> 9, 4) << 1;
|
||||
}
|
||||
|
||||
static av_cold int tak_decode_init(AVCodecContext *avctx)
|
||||
{
|
||||
TAKDecContext *s = avctx->priv_data;
|
||||
|
||||
ff_dsputil_init(&s->dsp, avctx);
|
||||
|
||||
s->avctx = avctx;
|
||||
avctx->bits_per_raw_sample = avctx->bits_per_coded_sample;
|
||||
|
||||
set_sample_rate_params(avctx);
|
||||
|
||||
return set_bps_params(avctx);
|
||||
}
|
||||
|
||||
static void decode_lpc(int32_t *coeffs, int mode, int length)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (length < 2)
|
||||
return;
|
||||
|
||||
if (mode == 1) {
|
||||
int a1 = *coeffs++;
|
||||
for (i = 0; i < length - 1 >> 1; i++) {
|
||||
*coeffs += a1;
|
||||
coeffs[1] += *coeffs;
|
||||
a1 = coeffs[1];
|
||||
coeffs += 2;
|
||||
}
|
||||
if (length - 1 & 1)
|
||||
*coeffs += a1;
|
||||
} else if (mode == 2) {
|
||||
int a1 = coeffs[1];
|
||||
int a2 = a1 + *coeffs;
|
||||
coeffs[1] = a2;
|
||||
if (length > 2) {
|
||||
coeffs += 2;
|
||||
for (i = 0; i < length - 2 >> 1; i++) {
|
||||
int a3 = *coeffs + a1;
|
||||
int a4 = a3 + a2;
|
||||
*coeffs = a4;
|
||||
a1 = coeffs[1] + a3;
|
||||
a2 = a1 + a4;
|
||||
coeffs[1] = a2;
|
||||
coeffs += 2;
|
||||
}
|
||||
if (length & 1)
|
||||
*coeffs += a1 + a2;
|
||||
}
|
||||
} else if (mode == 3) {
|
||||
int a1 = coeffs[1];
|
||||
int a2 = a1 + *coeffs;
|
||||
coeffs[1] = a2;
|
||||
if (length > 2) {
|
||||
int a3 = coeffs[2];
|
||||
int a4 = a3 + a1;
|
||||
int a5 = a4 + a2;
|
||||
coeffs += 3;
|
||||
for (i = 0; i < length - 3; i++) {
|
||||
a3 += *coeffs;
|
||||
a4 += a3;
|
||||
a5 += a4;
|
||||
*coeffs = a5;
|
||||
coeffs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int decode_segment(TAKDecContext *s, int8_t mode, int32_t *decoded, int len)
|
||||
{
|
||||
struct CParam code;
|
||||
GetBitContext *gb = &s->gb;
|
||||
int i;
|
||||
|
||||
if (!mode) {
|
||||
memset(decoded, 0, len * sizeof(*decoded));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mode > FF_ARRAY_ELEMS(xcodes))
|
||||
return AVERROR_INVALIDDATA;
|
||||
code = xcodes[mode - 1];
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
int x = get_bits_long(gb, code.init);
|
||||
if (x >= code.escape && get_bits1(gb)) {
|
||||
x |= 1 << code.init;
|
||||
if (x >= code.aescape) {
|
||||
int scale = get_unary(gb, 1, 9);
|
||||
if (scale == 9) {
|
||||
int scale_bits = get_bits(gb, 3);
|
||||
if (scale_bits > 0) {
|
||||
if (scale_bits == 7) {
|
||||
scale_bits += get_bits(gb, 5);
|
||||
if (scale_bits > 29)
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
scale = get_bits_long(gb, scale_bits) + 1;
|
||||
x += code.scale * scale;
|
||||
}
|
||||
x += code.bias;
|
||||
} else
|
||||
x += code.scale * scale - code.escape;
|
||||
} else
|
||||
x -= code.escape;
|
||||
}
|
||||
decoded[i] = (x >> 1) ^ -(x & 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decode_residues(TAKDecContext *s, int32_t *decoded, int length)
|
||||
{
|
||||
GetBitContext *gb = &s->gb;
|
||||
int i, mode, ret;
|
||||
|
||||
if (length > s->nb_samples)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
if (get_bits1(gb)) {
|
||||
int wlength, rval;
|
||||
|
||||
wlength = length / s->uval;
|
||||
|
||||
rval = length - (wlength * s->uval);
|
||||
|
||||
if (rval < s->uval / 2)
|
||||
rval += s->uval;
|
||||
else
|
||||
wlength++;
|
||||
|
||||
if (wlength <= 1 || wlength > 128)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
s->coding_mode[0] = mode = get_bits(gb, 6);
|
||||
|
||||
for (i = 1; i < wlength; i++) {
|
||||
int c = get_unary(gb, 1, 6);
|
||||
|
||||
switch (c) {
|
||||
case 6:
|
||||
mode = get_bits(gb, 6);
|
||||
break;
|
||||
case 5:
|
||||
case 4:
|
||||
case 3: {
|
||||
/* mode += sign ? (1 - c) : (c - 1) */
|
||||
int sign = get_bits1(gb);
|
||||
mode += (-sign ^ (c - 1)) + sign;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
mode++;
|
||||
break;
|
||||
case 1:
|
||||
mode--;
|
||||
break;
|
||||
}
|
||||
s->coding_mode[i] = mode;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (i < wlength) {
|
||||
int len = 0;
|
||||
|
||||
mode = s->coding_mode[i];
|
||||
do {
|
||||
if (i >= wlength - 1)
|
||||
len += rval;
|
||||
else
|
||||
len += s->uval;
|
||||
i++;
|
||||
|
||||
if (i == wlength)
|
||||
break;
|
||||
} while (s->coding_mode[i] == mode);
|
||||
|
||||
if ((ret = decode_segment(s, mode, decoded, len)) < 0)
|
||||
return ret;
|
||||
decoded += len;
|
||||
}
|
||||
} else {
|
||||
mode = get_bits(gb, 6);
|
||||
if ((ret = decode_segment(s, mode, decoded, length)) < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_bits_esc4(GetBitContext *gb)
|
||||
{
|
||||
if (get_bits1(gb))
|
||||
return get_bits(gb, 4) + 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decode_subframe(TAKDecContext *s, int32_t *decoded,
|
||||
int subframe_size, int prev_subframe_size)
|
||||
{
|
||||
GetBitContext *gb = &s->gb;
|
||||
int tmp, x, y, i, j, ret = 0;
|
||||
int dshift, size, filter_quant, filter_order;
|
||||
int tfilter[MAX_PREDICTORS];
|
||||
|
||||
if (!get_bits1(gb))
|
||||
return decode_residues(s, decoded, subframe_size);
|
||||
|
||||
filter_order = predictor_sizes[get_bits(gb, 4)];
|
||||
|
||||
if (prev_subframe_size > 0 && get_bits1(gb)) {
|
||||
if (filter_order > prev_subframe_size)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
decoded -= filter_order;
|
||||
subframe_size += filter_order;
|
||||
|
||||
if (filter_order > subframe_size)
|
||||
return AVERROR_INVALIDDATA;
|
||||
} else {
|
||||
int lpc_mode;
|
||||
|
||||
if (filter_order > subframe_size)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
lpc_mode = get_bits(gb, 2);
|
||||
if (lpc_mode > 2)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
if ((ret = decode_residues(s, decoded, filter_order)) < 0)
|
||||
return ret;
|
||||
|
||||
if (lpc_mode)
|
||||
decode_lpc(decoded, lpc_mode, filter_order);
|
||||
}
|
||||
|
||||
dshift = get_bits_esc4(gb);
|
||||
size = get_bits1(gb) + 6;
|
||||
|
||||
filter_quant = 10;
|
||||
if (get_bits1(gb)) {
|
||||
filter_quant -= get_bits(gb, 3) + 1;
|
||||
if (filter_quant < 3)
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
s->predictors[0] = get_sbits(gb, 10);
|
||||
s->predictors[1] = get_sbits(gb, 10);
|
||||
s->predictors[2] = get_sbits(gb, size) << (10 - size);
|
||||
s->predictors[3] = get_sbits(gb, size) << (10 - size);
|
||||
if (filter_order > 4) {
|
||||
tmp = size - get_bits1(gb);
|
||||
|
||||
for (i = 4; i < filter_order; i++) {
|
||||
if (!(i & 3))
|
||||
x = tmp - get_bits(gb, 2);
|
||||
s->predictors[i] = get_sbits(gb, x) << (10 - size);
|
||||
}
|
||||
}
|
||||
|
||||
tfilter[0] = s->predictors[0] << 6;
|
||||
for (i = 1; i < filter_order; i++) {
|
||||
int32_t *p1 = &tfilter[0];
|
||||
int32_t *p2 = &tfilter[i - 1];
|
||||
|
||||
for (j = 0; j < (i + 1) / 2; j++) {
|
||||
x = *p1 + (s->predictors[i] * *p2 + 256 >> 9);
|
||||
*p2 += s->predictors[i] * *p1 + 256 >> 9;
|
||||
*p1++ = x;
|
||||
p2--;
|
||||
}
|
||||
|
||||
tfilter[i] = s->predictors[i] << 6;
|
||||
}
|
||||
|
||||
x = 1 << (32 - (15 - filter_quant));
|
||||
y = 1 << ((15 - filter_quant) - 1);
|
||||
for (i = 0, j = filter_order - 1; i < filter_order / 2; i++, j--) {
|
||||
tmp = y + tfilter[j];
|
||||
s->filter[j] = x - ((tfilter[i] + y) >> (15 - filter_quant));
|
||||
s->filter[i] = x - ((tfilter[j] + y) >> (15 - filter_quant));
|
||||
}
|
||||
|
||||
if ((ret = decode_residues(s, &decoded[filter_order],
|
||||
subframe_size - filter_order)) < 0)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < filter_order; i++)
|
||||
s->residues[i] = *decoded++ >> dshift;
|
||||
|
||||
y = FF_ARRAY_ELEMS(s->residues) - filter_order;
|
||||
x = subframe_size - filter_order;
|
||||
while (x > 0) {
|
||||
tmp = FFMIN(y, x);
|
||||
|
||||
for (i = 0; i < tmp; i++) {
|
||||
int v = 1 << (filter_quant - 1);
|
||||
|
||||
if (filter_order & -16)
|
||||
v += s->dsp.scalarproduct_int16(&s->residues[i], s->filter,
|
||||
filter_order & -16);
|
||||
for (j = filter_order & -16; j < filter_order; j += 4) {
|
||||
v += s->residues[i + j + 3] * s->filter[j + 3] +
|
||||
s->residues[i + j + 2] * s->filter[j + 2] +
|
||||
s->residues[i + j + 1] * s->filter[j + 1] +
|
||||
s->residues[i + j ] * s->filter[j ];
|
||||
}
|
||||
v = (av_clip(v >> filter_quant, -8192, 8191) << dshift) - *decoded;
|
||||
*decoded++ = v;
|
||||
s->residues[filter_order + i] = v >> dshift;
|
||||
}
|
||||
|
||||
x -= tmp;
|
||||
if (x > 0)
|
||||
memcpy(s->residues, &s->residues[y], 2 * filter_order);
|
||||
}
|
||||
|
||||
emms_c();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decode_channel(TAKDecContext *s, int chan)
|
||||
{
|
||||
AVCodecContext *avctx = s->avctx;
|
||||
GetBitContext *gb = &s->gb;
|
||||
int32_t *decoded = s->decoded[chan];
|
||||
int left = s->nb_samples - 1;
|
||||
int i = 0, ret, prev = 0;
|
||||
|
||||
s->sample_shift[chan] = get_bits_esc4(gb);
|
||||
if (s->sample_shift[chan] >= avctx->bits_per_raw_sample)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
*decoded++ = get_sbits(gb, avctx->bits_per_raw_sample - s->sample_shift[chan]);
|
||||
s->lpc_mode[chan] = get_bits(gb, 2);
|
||||
s->nb_subframes = get_bits(gb, 3) + 1;
|
||||
|
||||
if (s->nb_subframes > 1) {
|
||||
if (get_bits_left(gb) < (s->nb_subframes - 1) * 6)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
for (; i < s->nb_subframes - 1; i++) {
|
||||
int v = get_bits(gb, 6);
|
||||
|
||||
s->subframe_len[i] = (v - prev) * s->subframe_scale;
|
||||
if (s->subframe_len[i] <= 0)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
left -= s->subframe_len[i];
|
||||
prev = v;
|
||||
}
|
||||
|
||||
if (left <= 0)
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
s->subframe_len[i] = left;
|
||||
|
||||
prev = 0;
|
||||
for (i = 0; i < s->nb_subframes; i++) {
|
||||
if ((ret = decode_subframe(s, decoded, s->subframe_len[i], prev)) < 0)
|
||||
return ret;
|
||||
decoded += s->subframe_len[i];
|
||||
prev = s->subframe_len[i];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decorrelate(TAKDecContext *s, int c1, int c2, int length)
|
||||
{
|
||||
GetBitContext *gb = &s->gb;
|
||||
int32_t *p1 = s->decoded[c1] + 1;
|
||||
int32_t *p2 = s->decoded[c2] + 1;
|
||||
int i;
|
||||
int dshift, dfactor;
|
||||
|
||||
switch (s->dmode) {
|
||||
case 1: /* left/side */
|
||||
for (i = 0; i < length; i++) {
|
||||
int32_t a = p1[i];
|
||||
int32_t b = p2[i];
|
||||
p2[i] = a + b;
|
||||
}
|
||||
break;
|
||||
case 2: /* side/right */
|
||||
for (i = 0; i < length; i++) {
|
||||
int32_t a = p1[i];
|
||||
int32_t b = p2[i];
|
||||
p1[i] = b - a;
|
||||
}
|
||||
break;
|
||||
case 3: /* side/mid */
|
||||
for (i = 0; i < length; i++) {
|
||||
int32_t a = p1[i];
|
||||
int32_t b = p2[i];
|
||||
a -= b >> 1;
|
||||
p1[i] = a;
|
||||
p2[i] = a + b;
|
||||
}
|
||||
break;
|
||||
case 4: /* side/left with scale factor */
|
||||
FFSWAP(int32_t*, p1, p2);
|
||||
case 5: /* side/right with scale factor */
|
||||
dshift = get_bits_esc4(gb);
|
||||
dfactor = get_sbits(gb, 10);
|
||||
for (i = 0; i < length; i++) {
|
||||
int32_t a = p1[i];
|
||||
int32_t b = p2[i];
|
||||
b = dfactor * (b >> dshift) + 128 >> 8 << dshift;
|
||||
p1[i] = b - a;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
FFSWAP(int32_t*, p1, p2);
|
||||
case 7: {
|
||||
int length2, order_half, filter_order, dval1, dval2;
|
||||
int tmp, x, code_size;
|
||||
|
||||
if (length < 256)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
dshift = get_bits_esc4(gb);
|
||||
filter_order = 8 << get_bits1(gb);
|
||||
dval1 = get_bits1(gb);
|
||||
dval2 = get_bits1(gb);
|
||||
|
||||
for (i = 0; i < filter_order; i++) {
|
||||
if (!(i & 3))
|
||||
code_size = 14 - get_bits(gb, 3);
|
||||
s->filter[i] = get_sbits(gb, code_size);
|
||||
}
|
||||
|
||||
order_half = filter_order / 2;
|
||||
length2 = length - (filter_order - 1);
|
||||
|
||||
/* decorrelate beginning samples */
|
||||
if (dval1) {
|
||||
for (i = 0; i < order_half; i++) {
|
||||
int32_t a = p1[i];
|
||||
int32_t b = p2[i];
|
||||
p1[i] = a + b;
|
||||
}
|
||||
}
|
||||
|
||||
/* decorrelate ending samples */
|
||||
if (dval2) {
|
||||
for (i = length2 + order_half; i < length; i++) {
|
||||
int32_t a = p1[i];
|
||||
int32_t b = p2[i];
|
||||
p1[i] = a + b;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < filter_order; i++)
|
||||
s->residues[i] = *p2++ >> dshift;
|
||||
|
||||
p1 += order_half;
|
||||
x = FF_ARRAY_ELEMS(s->residues) - filter_order;
|
||||
for (; length2 > 0; length2 -= tmp) {
|
||||
tmp = FFMIN(length2, x);
|
||||
|
||||
for (i = 0; i < tmp; i++)
|
||||
s->residues[filter_order + i] = *p2++ >> dshift;
|
||||
|
||||
for (i = 0; i < tmp; i++) {
|
||||
int v = 1 << 9;
|
||||
|
||||
if (filter_order == 16) {
|
||||
v += s->dsp.scalarproduct_int16(&s->residues[i], s->filter,
|
||||
filter_order);
|
||||
} else {
|
||||
v += s->residues[i + 7] * s->filter[7] +
|
||||
s->residues[i + 6] * s->filter[6] +
|
||||
s->residues[i + 5] * s->filter[5] +
|
||||
s->residues[i + 4] * s->filter[4] +
|
||||
s->residues[i + 3] * s->filter[3] +
|
||||
s->residues[i + 2] * s->filter[2] +
|
||||
s->residues[i + 1] * s->filter[1] +
|
||||
s->residues[i ] * s->filter[0];
|
||||
}
|
||||
|
||||
v = (av_clip(v >> 10, -8192, 8191) << dshift) - *p1;
|
||||
*p1++ = v;
|
||||
}
|
||||
|
||||
memcpy(s->residues, &s->residues[tmp], 2 * filter_order);
|
||||
}
|
||||
|
||||
emms_c();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tak_decode_frame(AVCodecContext *avctx, void *data,
|
||||
int *got_frame_ptr, AVPacket *pkt)
|
||||
{
|
||||
TAKDecContext *s = avctx->priv_data;
|
||||
AVFrame *frame = data;
|
||||
ThreadFrame tframe = { .f = data };
|
||||
GetBitContext *gb = &s->gb;
|
||||
int chan, i, ret, hsize;
|
||||
|
||||
if (pkt->size < TAK_MIN_FRAME_HEADER_BYTES)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
if ((ret = init_get_bits8(gb, pkt->data, pkt->size)) < 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = ff_tak_decode_frame_header(avctx, gb, &s->ti, 0)) < 0)
|
||||
return ret;
|
||||
|
||||
if (avctx->err_recognition & AV_EF_CRCCHECK) {
|
||||
hsize = get_bits_count(gb) / 8;
|
||||
if (ff_tak_check_crc(pkt->data, hsize)) {
|
||||
av_log(avctx, AV_LOG_ERROR, "CRC error\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
}
|
||||
|
||||
if (s->ti.codec != TAK_CODEC_MONO_STEREO &&
|
||||
s->ti.codec != TAK_CODEC_MULTICHANNEL) {
|
||||
av_log(avctx, AV_LOG_ERROR, "unsupported codec: %d\n", s->ti.codec);
|
||||
return AVERROR_PATCHWELCOME;
|
||||
}
|
||||
if (s->ti.data_type) {
|
||||
av_log(avctx, AV_LOG_ERROR,
|
||||
"unsupported data type: %d\n", s->ti.data_type);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
if (s->ti.codec == TAK_CODEC_MONO_STEREO && s->ti.channels > 2) {
|
||||
av_log(avctx, AV_LOG_ERROR,
|
||||
"invalid number of channels: %d\n", s->ti.channels);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
if (s->ti.channels > 6) {
|
||||
av_log(avctx, AV_LOG_ERROR,
|
||||
"unsupported number of channels: %d\n", s->ti.channels);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
if (s->ti.frame_samples <= 0) {
|
||||
av_log(avctx, AV_LOG_ERROR, "unsupported/invalid number of samples\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
if (s->ti.bps != avctx->bits_per_raw_sample) {
|
||||
avctx->bits_per_raw_sample = s->ti.bps;
|
||||
if ((ret = set_bps_params(avctx)) < 0)
|
||||
return ret;
|
||||
}
|
||||
if (s->ti.sample_rate != avctx->sample_rate) {
|
||||
avctx->sample_rate = s->ti.sample_rate;
|
||||
set_sample_rate_params(avctx);
|
||||
}
|
||||
if (s->ti.ch_layout)
|
||||
avctx->channel_layout = s->ti.ch_layout;
|
||||
avctx->channels = s->ti.channels;
|
||||
|
||||
s->nb_samples = s->ti.last_frame_samples ? s->ti.last_frame_samples
|
||||
: s->ti.frame_samples;
|
||||
|
||||
frame->nb_samples = s->nb_samples;
|
||||
if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)
|
||||
return ret;
|
||||
ff_thread_finish_setup(avctx);
|
||||
|
||||
if (avctx->bits_per_raw_sample <= 16) {
|
||||
int buf_size = av_samples_get_buffer_size(NULL, avctx->channels,
|
||||
s->nb_samples,
|
||||
AV_SAMPLE_FMT_S32P, 0);
|
||||
av_fast_malloc(&s->decode_buffer, &s->decode_buffer_size, buf_size);
|
||||
if (!s->decode_buffer)
|
||||
return AVERROR(ENOMEM);
|
||||
ret = av_samples_fill_arrays((uint8_t **)s->decoded, NULL,
|
||||
s->decode_buffer, avctx->channels,
|
||||
s->nb_samples, AV_SAMPLE_FMT_S32P, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
} else {
|
||||
for (chan = 0; chan < avctx->channels; chan++)
|
||||
s->decoded[chan] = (int32_t *)frame->extended_data[chan];
|
||||
}
|
||||
|
||||
if (s->nb_samples < 16) {
|
||||
for (chan = 0; chan < avctx->channels; chan++) {
|
||||
int32_t *decoded = s->decoded[chan];
|
||||
for (i = 0; i < s->nb_samples; i++)
|
||||
decoded[i] = get_sbits(gb, avctx->bits_per_raw_sample);
|
||||
}
|
||||
} else {
|
||||
if (s->ti.codec == TAK_CODEC_MONO_STEREO) {
|
||||
for (chan = 0; chan < avctx->channels; chan++)
|
||||
if (ret = decode_channel(s, chan))
|
||||
return ret;
|
||||
|
||||
if (avctx->channels == 2) {
|
||||
s->nb_subframes = get_bits(gb, 1) + 1;
|
||||
if (s->nb_subframes > 1) {
|
||||
s->subframe_len[1] = get_bits(gb, 6);
|
||||
}
|
||||
|
||||
s->dmode = get_bits(gb, 3);
|
||||
if (ret = decorrelate(s, 0, 1, s->nb_samples - 1))
|
||||
return ret;
|
||||
}
|
||||
} else if (s->ti.codec == TAK_CODEC_MULTICHANNEL) {
|
||||
if (get_bits1(gb)) {
|
||||
int ch_mask = 0;
|
||||
|
||||
chan = get_bits(gb, 4) + 1;
|
||||
if (chan > avctx->channels)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
for (i = 0; i < chan; i++) {
|
||||
int nbit = get_bits(gb, 4);
|
||||
|
||||
if (nbit >= avctx->channels)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
if (ch_mask & 1 << nbit)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
s->mcdparams[i].present = get_bits1(gb);
|
||||
if (s->mcdparams[i].present) {
|
||||
s->mcdparams[i].index = get_bits(gb, 2);
|
||||
s->mcdparams[i].chan2 = get_bits(gb, 4);
|
||||
if (s->mcdparams[i].index == 1) {
|
||||
if ((nbit == s->mcdparams[i].chan2) ||
|
||||
(ch_mask & 1 << s->mcdparams[i].chan2))
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
ch_mask |= 1 << s->mcdparams[i].chan2;
|
||||
} else if (!(ch_mask & 1 << s->mcdparams[i].chan2)) {
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
}
|
||||
s->mcdparams[i].chan1 = nbit;
|
||||
|
||||
ch_mask |= 1 << nbit;
|
||||
}
|
||||
} else {
|
||||
chan = avctx->channels;
|
||||
for (i = 0; i < chan; i++) {
|
||||
s->mcdparams[i].present = 0;
|
||||
s->mcdparams[i].chan1 = i;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < chan; i++) {
|
||||
if (s->mcdparams[i].present && s->mcdparams[i].index == 1)
|
||||
if (ret = decode_channel(s, s->mcdparams[i].chan2))
|
||||
return ret;
|
||||
|
||||
if (ret = decode_channel(s, s->mcdparams[i].chan1))
|
||||
return ret;
|
||||
|
||||
if (s->mcdparams[i].present) {
|
||||
s->dmode = mc_dmodes[s->mcdparams[i].index];
|
||||
if (ret = decorrelate(s,
|
||||
s->mcdparams[i].chan2,
|
||||
s->mcdparams[i].chan1,
|
||||
s->nb_samples - 1))
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (chan = 0; chan < avctx->channels; chan++) {
|
||||
int32_t *decoded = s->decoded[chan];
|
||||
|
||||
if (s->lpc_mode[chan])
|
||||
decode_lpc(decoded, s->lpc_mode[chan], s->nb_samples);
|
||||
|
||||
if (s->sample_shift[chan] > 0)
|
||||
for (i = 0; i < s->nb_samples; i++)
|
||||
decoded[i] <<= s->sample_shift[chan];
|
||||
}
|
||||
}
|
||||
|
||||
align_get_bits(gb);
|
||||
skip_bits(gb, 24);
|
||||
if (get_bits_left(gb) < 0)
|
||||
av_log(avctx, AV_LOG_DEBUG, "overread\n");
|
||||
else if (get_bits_left(gb) > 0)
|
||||
av_log(avctx, AV_LOG_DEBUG, "underread\n");
|
||||
|
||||
if (avctx->err_recognition & AV_EF_CRCCHECK) {
|
||||
if (ff_tak_check_crc(pkt->data + hsize,
|
||||
get_bits_count(gb) / 8 - hsize)) {
|
||||
av_log(avctx, AV_LOG_ERROR, "CRC error\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
}
|
||||
|
||||
/* convert to output buffer */
|
||||
switch (avctx->sample_fmt) {
|
||||
case AV_SAMPLE_FMT_U8P:
|
||||
for (chan = 0; chan < avctx->channels; chan++) {
|
||||
uint8_t *samples = (uint8_t *)frame->extended_data[chan];
|
||||
int32_t *decoded = s->decoded[chan];
|
||||
for (i = 0; i < s->nb_samples; i++)
|
||||
samples[i] = decoded[i] + 0x80;
|
||||
}
|
||||
break;
|
||||
case AV_SAMPLE_FMT_S16P:
|
||||
for (chan = 0; chan < avctx->channels; chan++) {
|
||||
int16_t *samples = (int16_t *)frame->extended_data[chan];
|
||||
int32_t *decoded = s->decoded[chan];
|
||||
for (i = 0; i < s->nb_samples; i++)
|
||||
samples[i] = decoded[i];
|
||||
}
|
||||
break;
|
||||
case AV_SAMPLE_FMT_S32P:
|
||||
for (chan = 0; chan < avctx->channels; chan++) {
|
||||
int32_t *samples = (int32_t *)frame->extended_data[chan];
|
||||
for (i = 0; i < s->nb_samples; i++)
|
||||
samples[i] <<= 8;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
*got_frame_ptr = 1;
|
||||
|
||||
return pkt->size;
|
||||
}
|
||||
|
||||
static int init_thread_copy(AVCodecContext *avctx)
|
||||
{
|
||||
TAKDecContext *s = avctx->priv_data;
|
||||
s->avctx = avctx;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int update_thread_context(AVCodecContext *dst,
|
||||
const AVCodecContext *src)
|
||||
{
|
||||
TAKDecContext *tsrc = src->priv_data;
|
||||
TAKDecContext *tdst = dst->priv_data;
|
||||
|
||||
if (dst == src)
|
||||
return 0;
|
||||
memcpy(&tdst->ti, &tsrc->ti, sizeof(TAKStreamInfo));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_cold int tak_decode_close(AVCodecContext *avctx)
|
||||
{
|
||||
TAKDecContext *s = avctx->priv_data;
|
||||
|
||||
av_freep(&s->decode_buffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVCodec ff_tak_decoder = {
|
||||
.name = "tak",
|
||||
.type = AVMEDIA_TYPE_AUDIO,
|
||||
.id = AV_CODEC_ID_TAK,
|
||||
.priv_data_size = sizeof(TAKDecContext),
|
||||
.init = tak_decode_init,
|
||||
.close = tak_decode_close,
|
||||
.decode = tak_decode_frame,
|
||||
.init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
|
||||
.update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context),
|
||||
.capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS,
|
||||
.long_name = NULL_IF_CONFIG_SMALL("TAK (Tom's lossless Audio Kompressor)"),
|
||||
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
|
||||
AV_SAMPLE_FMT_S16P,
|
||||
AV_SAMPLE_FMT_S32P,
|
||||
AV_SAMPLE_FMT_NONE },
|
||||
};
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_UNARY_H
|
||||
#define AVCODEC_UNARY_H
|
||||
|
||||
#include "get_bits.h"
|
||||
|
||||
/**
|
||||
* Get unary code of limited length
|
||||
* @param gb GetBitContext
|
||||
* @param[in] stop The bitstop value (unary code of 1's or 0's)
|
||||
* @param[in] len Maximum length
|
||||
* @return Unary length/index
|
||||
*/
|
||||
static inline int get_unary(GetBitContext *gb, int stop, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < len && get_bits1(gb) != stop; i++);
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get unary code terminated by a 0 with a maximum length of 33
|
||||
* @param gb GetBitContext
|
||||
* @return Unary length/index
|
||||
*/
|
||||
static inline int get_unary_0_33(GetBitContext *gb)
|
||||
{
|
||||
return get_unary(gb, 0, 33);
|
||||
}
|
||||
|
||||
static inline int get_unary_0_9(GetBitContext *gb)
|
||||
{
|
||||
return get_unary(gb, 0, 9);
|
||||
}
|
||||
|
||||
#endif /* AVCODEC_UNARY_H */
|
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
* MMX optimized discrete wavelet transform
|
||||
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
|
||||
* Copyright (c) 2010 David Conrad
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "libavutil/x86/asm.h"
|
||||
#include "dsputil_x86.h"
|
||||
#include "dirac_dwt.h"
|
||||
|
||||
#define COMPOSE_VERTICAL(ext, align) \
|
||||
void ff_vertical_compose53iL0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width); \
|
||||
void ff_vertical_compose_dirac53iH0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width); \
|
||||
void ff_vertical_compose_dd137iL0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, int width); \
|
||||
void ff_vertical_compose_dd97iH0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, IDWTELEM *b3, IDWTELEM *b4, int width); \
|
||||
void ff_vertical_compose_haar##ext(IDWTELEM *b0, IDWTELEM *b1, int width); \
|
||||
void ff_horizontal_compose_haar0i##ext(IDWTELEM *b, IDWTELEM *tmp, int w);\
|
||||
void ff_horizontal_compose_haar1i##ext(IDWTELEM *b, IDWTELEM *tmp, int w);\
|
||||
\
|
||||
static void vertical_compose53iL0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width) \
|
||||
{ \
|
||||
int i, width_align = width&~(align-1); \
|
||||
\
|
||||
for(i=width_align; i<width; i++) \
|
||||
b1[i] = COMPOSE_53iL0(b0[i], b1[i], b2[i]); \
|
||||
\
|
||||
ff_vertical_compose53iL0##ext(b0, b1, b2, width_align); \
|
||||
} \
|
||||
\
|
||||
static void vertical_compose_dirac53iH0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, int width) \
|
||||
{ \
|
||||
int i, width_align = width&~(align-1); \
|
||||
\
|
||||
for(i=width_align; i<width; i++) \
|
||||
b1[i] = COMPOSE_DIRAC53iH0(b0[i], b1[i], b2[i]); \
|
||||
\
|
||||
ff_vertical_compose_dirac53iH0##ext(b0, b1, b2, width_align); \
|
||||
} \
|
||||
\
|
||||
static void vertical_compose_dd137iL0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, \
|
||||
IDWTELEM *b3, IDWTELEM *b4, int width) \
|
||||
{ \
|
||||
int i, width_align = width&~(align-1); \
|
||||
\
|
||||
for(i=width_align; i<width; i++) \
|
||||
b2[i] = COMPOSE_DD137iL0(b0[i], b1[i], b2[i], b3[i], b4[i]); \
|
||||
\
|
||||
ff_vertical_compose_dd137iL0##ext(b0, b1, b2, b3, b4, width_align); \
|
||||
} \
|
||||
\
|
||||
static void vertical_compose_dd97iH0##ext(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2, \
|
||||
IDWTELEM *b3, IDWTELEM *b4, int width) \
|
||||
{ \
|
||||
int i, width_align = width&~(align-1); \
|
||||
\
|
||||
for(i=width_align; i<width; i++) \
|
||||
b2[i] = COMPOSE_DD97iH0(b0[i], b1[i], b2[i], b3[i], b4[i]); \
|
||||
\
|
||||
ff_vertical_compose_dd97iH0##ext(b0, b1, b2, b3, b4, width_align); \
|
||||
} \
|
||||
static void vertical_compose_haar##ext(IDWTELEM *b0, IDWTELEM *b1, int width) \
|
||||
{ \
|
||||
int i, width_align = width&~(align-1); \
|
||||
\
|
||||
for(i=width_align; i<width; i++) { \
|
||||
b0[i] = COMPOSE_HAARiL0(b0[i], b1[i]); \
|
||||
b1[i] = COMPOSE_HAARiH0(b1[i], b0[i]); \
|
||||
} \
|
||||
\
|
||||
ff_vertical_compose_haar##ext(b0, b1, width_align); \
|
||||
} \
|
||||
static void horizontal_compose_haar0i##ext(IDWTELEM *b, IDWTELEM *tmp, int w)\
|
||||
{\
|
||||
int w2= w>>1;\
|
||||
int x= w2 - (w2&(align-1));\
|
||||
ff_horizontal_compose_haar0i##ext(b, tmp, w);\
|
||||
\
|
||||
for (; x < w2; x++) {\
|
||||
b[2*x ] = tmp[x];\
|
||||
b[2*x+1] = COMPOSE_HAARiH0(b[x+w2], tmp[x]);\
|
||||
}\
|
||||
}\
|
||||
static void horizontal_compose_haar1i##ext(IDWTELEM *b, IDWTELEM *tmp, int w)\
|
||||
{\
|
||||
int w2= w>>1;\
|
||||
int x= w2 - (w2&(align-1));\
|
||||
ff_horizontal_compose_haar1i##ext(b, tmp, w);\
|
||||
\
|
||||
for (; x < w2; x++) {\
|
||||
b[2*x ] = (tmp[x] + 1)>>1;\
|
||||
b[2*x+1] = (COMPOSE_HAARiH0(b[x+w2], tmp[x]) + 1)>>1;\
|
||||
}\
|
||||
}\
|
||||
\
|
||||
|
||||
#if HAVE_YASM
|
||||
#if !ARCH_X86_64
|
||||
COMPOSE_VERTICAL(_mmx, 4)
|
||||
#endif
|
||||
COMPOSE_VERTICAL(_sse2, 8)
|
||||
|
||||
|
||||
void ff_horizontal_compose_dd97i_ssse3(IDWTELEM *b, IDWTELEM *tmp, int w);
|
||||
|
||||
static void horizontal_compose_dd97i_ssse3(IDWTELEM *b, IDWTELEM *tmp, int w)
|
||||
{
|
||||
int w2= w>>1;
|
||||
int x= w2 - (w2&7);
|
||||
ff_horizontal_compose_dd97i_ssse3(b, tmp, w);
|
||||
|
||||
for (; x < w2; x++) {
|
||||
b[2*x ] = (tmp[x] + 1)>>1;
|
||||
b[2*x+1] = (COMPOSE_DD97iH0(tmp[x-1], tmp[x], b[x+w2], tmp[x+1], tmp[x+2]) + 1)>>1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void ff_spatial_idwt_init_mmx(DWTContext *d, enum dwt_type type)
|
||||
{
|
||||
#if HAVE_YASM
|
||||
int mm_flags = av_get_cpu_flags();
|
||||
|
||||
#if !ARCH_X86_64
|
||||
if (!(mm_flags & AV_CPU_FLAG_MMX))
|
||||
return;
|
||||
|
||||
switch (type) {
|
||||
case DWT_DIRAC_DD9_7:
|
||||
d->vertical_compose_l0 = (void*)vertical_compose53iL0_mmx;
|
||||
d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0_mmx;
|
||||
break;
|
||||
case DWT_DIRAC_LEGALL5_3:
|
||||
d->vertical_compose_l0 = (void*)vertical_compose53iL0_mmx;
|
||||
d->vertical_compose_h0 = (void*)vertical_compose_dirac53iH0_mmx;
|
||||
break;
|
||||
case DWT_DIRAC_DD13_7:
|
||||
d->vertical_compose_l0 = (void*)vertical_compose_dd137iL0_mmx;
|
||||
d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0_mmx;
|
||||
break;
|
||||
case DWT_DIRAC_HAAR0:
|
||||
d->vertical_compose = (void*)vertical_compose_haar_mmx;
|
||||
d->horizontal_compose = horizontal_compose_haar0i_mmx;
|
||||
break;
|
||||
case DWT_DIRAC_HAAR1:
|
||||
d->vertical_compose = (void*)vertical_compose_haar_mmx;
|
||||
d->horizontal_compose = horizontal_compose_haar1i_mmx;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!(mm_flags & AV_CPU_FLAG_SSE2))
|
||||
return;
|
||||
|
||||
switch (type) {
|
||||
case DWT_DIRAC_DD9_7:
|
||||
d->vertical_compose_l0 = (void*)vertical_compose53iL0_sse2;
|
||||
d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0_sse2;
|
||||
break;
|
||||
case DWT_DIRAC_LEGALL5_3:
|
||||
d->vertical_compose_l0 = (void*)vertical_compose53iL0_sse2;
|
||||
d->vertical_compose_h0 = (void*)vertical_compose_dirac53iH0_sse2;
|
||||
break;
|
||||
case DWT_DIRAC_DD13_7:
|
||||
d->vertical_compose_l0 = (void*)vertical_compose_dd137iL0_sse2;
|
||||
d->vertical_compose_h0 = (void*)vertical_compose_dd97iH0_sse2;
|
||||
break;
|
||||
case DWT_DIRAC_HAAR0:
|
||||
d->vertical_compose = (void*)vertical_compose_haar_sse2;
|
||||
d->horizontal_compose = horizontal_compose_haar0i_sse2;
|
||||
break;
|
||||
case DWT_DIRAC_HAAR1:
|
||||
d->vertical_compose = (void*)vertical_compose_haar_sse2;
|
||||
d->horizontal_compose = horizontal_compose_haar1i_sse2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(mm_flags & AV_CPU_FLAG_SSSE3))
|
||||
return;
|
||||
|
||||
switch (type) {
|
||||
case DWT_DIRAC_DD9_7:
|
||||
d->horizontal_compose = horizontal_compose_dd97i_ssse3;
|
||||
break;
|
||||
}
|
||||
#endif // HAVE_YASM
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_X86_DIRAC_DWT_H
|
||||
#define AVCODEC_X86_DIRAC_DWT_H
|
||||
|
||||
#include "libavcodec/dirac_dwt.h"
|
||||
|
||||
void ff_horizontal_compose_dd97i_end_c(IDWTELEM *b, IDWTELEM *tmp, int w2, int x);
|
||||
void ff_horizontal_compose_haar1i_end_c(IDWTELEM *b, IDWTELEM *tmp, int w2, int x);
|
||||
void ff_horizontal_compose_haar0i_end_c(IDWTELEM *b, IDWTELEM *tmp, int w2, int x);
|
||||
|
||||
void ff_spatial_idwt_init_mmx(DWTContext *d, enum dwt_type type);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,264 @@
|
|||
;******************************************************************************
|
||||
;* Copyright (c) 2010 David Conrad
|
||||
;*
|
||||
;* This file is part of FFmpeg.
|
||||
;*
|
||||
;* FFmpeg is free software; you can redistribute it and/or
|
||||
;* modify it under the terms of the GNU Lesser General Public
|
||||
;* License as published by the Free Software Foundation; either
|
||||
;* version 2.1 of the License, or (at your option) any later version.
|
||||
;*
|
||||
;* FFmpeg is distributed in the hope that it will be useful,
|
||||
;* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
;* Lesser General Public License for more details.
|
||||
;*
|
||||
;* You should have received a copy of the GNU Lesser General Public
|
||||
;* License along with FFmpeg; if not, write to the Free Software
|
||||
;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
;******************************************************************************
|
||||
|
||||
%include "libavutil/x86/x86util.asm"
|
||||
|
||||
SECTION_RODATA
|
||||
pw_3: times 8 dw 3
|
||||
pw_7: times 8 dw 7
|
||||
pw_16: times 8 dw 16
|
||||
pw_32: times 8 dw 32
|
||||
pb_128: times 16 db 128
|
||||
|
||||
section .text
|
||||
|
||||
%macro UNPACK_ADD 6
|
||||
mov%5 %1, %3
|
||||
mov%6 m5, %4
|
||||
mova m4, %1
|
||||
mova %2, m5
|
||||
punpcklbw %1, m7
|
||||
punpcklbw m5, m7
|
||||
punpckhbw m4, m7
|
||||
punpckhbw %2, m7
|
||||
paddw %1, m5
|
||||
paddw %2, m4
|
||||
%endmacro
|
||||
|
||||
%macro HPEL_FILTER 1
|
||||
; dirac_hpel_filter_v_sse2(uint8_t *dst, uint8_t *src, int stride, int width);
|
||||
cglobal dirac_hpel_filter_v_%1, 4,6,8, dst, src, stride, width, src0, stridex3
|
||||
mov src0q, srcq
|
||||
lea stridex3q, [3*strideq]
|
||||
sub src0q, stridex3q
|
||||
pxor m7, m7
|
||||
.loop:
|
||||
; 7*(src[0] + src[1])
|
||||
UNPACK_ADD m0, m1, [srcq], [srcq + strideq], a,a
|
||||
pmullw m0, [pw_7]
|
||||
pmullw m1, [pw_7]
|
||||
|
||||
; 3*( ... + src[-2] + src[3])
|
||||
UNPACK_ADD m2, m3, [src0q + strideq], [srcq + stridex3q], a,a
|
||||
paddw m0, m2
|
||||
paddw m1, m3
|
||||
pmullw m0, [pw_3]
|
||||
pmullw m1, [pw_3]
|
||||
|
||||
; ... - 7*(src[-1] + src[2])
|
||||
UNPACK_ADD m2, m3, [src0q + strideq*2], [srcq + strideq*2], a,a
|
||||
pmullw m2, [pw_7]
|
||||
pmullw m3, [pw_7]
|
||||
psubw m0, m2
|
||||
psubw m1, m3
|
||||
|
||||
; ... - (src[-3] + src[4])
|
||||
UNPACK_ADD m2, m3, [src0q], [srcq + strideq*4], a,a
|
||||
psubw m0, m2
|
||||
psubw m1, m3
|
||||
|
||||
paddw m0, [pw_16]
|
||||
paddw m1, [pw_16]
|
||||
psraw m0, 5
|
||||
psraw m1, 5
|
||||
packuswb m0, m1
|
||||
mova [dstq], m0
|
||||
add dstq, mmsize
|
||||
add srcq, mmsize
|
||||
add src0q, mmsize
|
||||
sub widthd, mmsize
|
||||
jg .loop
|
||||
RET
|
||||
|
||||
; dirac_hpel_filter_h_sse2(uint8_t *dst, uint8_t *src, int width);
|
||||
cglobal dirac_hpel_filter_h_%1, 3,3,8, dst, src, width
|
||||
dec widthd
|
||||
pxor m7, m7
|
||||
and widthd, ~(mmsize-1)
|
||||
.loop:
|
||||
; 7*(src[0] + src[1])
|
||||
UNPACK_ADD m0, m1, [srcq + widthq], [srcq + widthq + 1], u,u
|
||||
pmullw m0, [pw_7]
|
||||
pmullw m1, [pw_7]
|
||||
|
||||
; 3*( ... + src[-2] + src[3])
|
||||
UNPACK_ADD m2, m3, [srcq + widthq - 2], [srcq + widthq + 3], u,u
|
||||
paddw m0, m2
|
||||
paddw m1, m3
|
||||
pmullw m0, [pw_3]
|
||||
pmullw m1, [pw_3]
|
||||
|
||||
; ... - 7*(src[-1] + src[2])
|
||||
UNPACK_ADD m2, m3, [srcq + widthq - 1], [srcq + widthq + 2], u,u
|
||||
pmullw m2, [pw_7]
|
||||
pmullw m3, [pw_7]
|
||||
psubw m0, m2
|
||||
psubw m1, m3
|
||||
|
||||
; ... - (src[-3] + src[4])
|
||||
UNPACK_ADD m2, m3, [srcq + widthq - 3], [srcq + widthq + 4], u,u
|
||||
psubw m0, m2
|
||||
psubw m1, m3
|
||||
|
||||
paddw m0, [pw_16]
|
||||
paddw m1, [pw_16]
|
||||
psraw m0, 5
|
||||
psraw m1, 5
|
||||
packuswb m0, m1
|
||||
mova [dstq + widthq], m0
|
||||
sub widthd, mmsize
|
||||
jge .loop
|
||||
RET
|
||||
%endmacro
|
||||
|
||||
%macro PUT_RECT 1
|
||||
; void put_rect_clamped(uint8_t *dst, int dst_stride, int16_t *src, int src_stride, int width, int height)
|
||||
cglobal put_signed_rect_clamped_%1, 5,9,3, dst, dst_stride, src, src_stride, w, dst2, src2
|
||||
mova m0, [pb_128]
|
||||
add wd, (mmsize-1)
|
||||
and wd, ~(mmsize-1)
|
||||
|
||||
%if ARCH_X86_64
|
||||
movsxd dst_strideq, dst_strided
|
||||
movsxd src_strideq, src_strided
|
||||
mov r7d, r5m
|
||||
mov r8d, wd
|
||||
%define wspill r8d
|
||||
%define hd r7d
|
||||
%else
|
||||
mov r4m, wd
|
||||
%define wspill r4m
|
||||
%define hd r5mp
|
||||
%endif
|
||||
|
||||
.loopy
|
||||
lea src2q, [srcq+src_strideq*2]
|
||||
lea dst2q, [dstq+dst_strideq]
|
||||
.loopx:
|
||||
sub wd, mmsize
|
||||
mova m1, [srcq +2*wq]
|
||||
mova m2, [src2q+2*wq]
|
||||
packsswb m1, [srcq +2*wq+mmsize]
|
||||
packsswb m2, [src2q+2*wq+mmsize]
|
||||
paddb m1, m0
|
||||
paddb m2, m0
|
||||
mova [dstq +wq], m1
|
||||
mova [dst2q+wq], m2
|
||||
jg .loopx
|
||||
|
||||
lea srcq, [srcq+src_strideq*4]
|
||||
lea dstq, [dstq+dst_strideq*2]
|
||||
sub hd, 2
|
||||
mov wd, wspill
|
||||
jg .loopy
|
||||
RET
|
||||
%endm
|
||||
|
||||
%macro ADD_RECT 1
|
||||
; void add_rect_clamped(uint8_t *dst, uint16_t *src, int stride, int16_t *idwt, int idwt_stride, int width, int height)
|
||||
cglobal add_rect_clamped_%1, 7,9,3, dst, src, stride, idwt, idwt_stride, w, h
|
||||
mova m0, [pw_32]
|
||||
add wd, (mmsize-1)
|
||||
and wd, ~(mmsize-1)
|
||||
|
||||
%if ARCH_X86_64
|
||||
movsxd strideq, strided
|
||||
movsxd idwt_strideq, idwt_strided
|
||||
mov r8d, wd
|
||||
%define wspill r8d
|
||||
%else
|
||||
mov r5m, wd
|
||||
%define wspill r5m
|
||||
%endif
|
||||
|
||||
.loop:
|
||||
sub wd, mmsize
|
||||
movu m1, [srcq +2*wq] ; FIXME: ensure alignment
|
||||
paddw m1, m0
|
||||
psraw m1, 6
|
||||
movu m2, [srcq +2*wq+mmsize] ; FIXME: ensure alignment
|
||||
paddw m2, m0
|
||||
psraw m2, 6
|
||||
paddw m1, [idwtq+2*wq]
|
||||
paddw m2, [idwtq+2*wq+mmsize]
|
||||
packuswb m1, m2
|
||||
mova [dstq +wq], m1
|
||||
jg .loop
|
||||
|
||||
lea srcq, [srcq + 2*strideq]
|
||||
add dstq, strideq
|
||||
lea idwtq, [idwtq+ 2*idwt_strideq]
|
||||
sub hd, 1
|
||||
mov wd, wspill
|
||||
jg .loop
|
||||
RET
|
||||
%endm
|
||||
|
||||
%macro ADD_OBMC 2
|
||||
; void add_obmc(uint16_t *dst, uint8_t *src, int stride, uint8_t *obmc_weight, int yblen)
|
||||
cglobal add_dirac_obmc%1_%2, 6,6,5, dst, src, stride, obmc, yblen
|
||||
pxor m4, m4
|
||||
.loop:
|
||||
%assign i 0
|
||||
%rep %1 / mmsize
|
||||
mova m0, [srcq+i]
|
||||
mova m1, m0
|
||||
punpcklbw m0, m4
|
||||
punpckhbw m1, m4
|
||||
mova m2, [obmcq+i]
|
||||
mova m3, m2
|
||||
punpcklbw m2, m4
|
||||
punpckhbw m3, m4
|
||||
pmullw m0, m2
|
||||
pmullw m1, m3
|
||||
movu m2, [dstq+2*i]
|
||||
movu m3, [dstq+2*i+mmsize]
|
||||
paddw m0, m2
|
||||
paddw m1, m3
|
||||
movu [dstq+2*i], m0
|
||||
movu [dstq+2*i+mmsize], m1
|
||||
%assign i i+mmsize
|
||||
%endrep
|
||||
lea srcq, [srcq+strideq]
|
||||
lea dstq, [dstq+2*strideq]
|
||||
add obmcq, 32
|
||||
sub yblend, 1
|
||||
jg .loop
|
||||
RET
|
||||
%endm
|
||||
|
||||
INIT_MMX
|
||||
%if ARCH_X86_64 == 0
|
||||
PUT_RECT mmx
|
||||
ADD_RECT mmx
|
||||
|
||||
HPEL_FILTER mmx
|
||||
ADD_OBMC 32, mmx
|
||||
ADD_OBMC 16, mmx
|
||||
%endif
|
||||
ADD_OBMC 8, mmx
|
||||
|
||||
INIT_XMM
|
||||
PUT_RECT sse2
|
||||
ADD_RECT sse2
|
||||
|
||||
HPEL_FILTER sse2
|
||||
ADD_OBMC 32, sse2
|
||||
ADD_OBMC 16, sse2
|
|
@ -0,0 +1,734 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2001 Fabrice Bellard
|
||||
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libavutil/attributes.h"
|
||||
#include "libavutil/cpu.h"
|
||||
#include "libavutil/x86/asm.h"
|
||||
#include "libavutil/x86/cpu.h"
|
||||
#include "libavcodec/dsputil.h"
|
||||
#include "libavcodec/simple_idct.h"
|
||||
#include "dsputil_x86.h"
|
||||
#include "idct_xvid.h"
|
||||
|
||||
void ff_put_pixels8_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
|
||||
int dstStride, int src1Stride, int h);
|
||||
void ff_put_no_rnd_pixels8_l2_mmxext(uint8_t *dst, uint8_t *src1,
|
||||
uint8_t *src2, int dstStride,
|
||||
int src1Stride, int h);
|
||||
void ff_avg_pixels8_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
|
||||
int dstStride, int src1Stride, int h);
|
||||
void ff_put_pixels16_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
|
||||
int dstStride, int src1Stride, int h);
|
||||
void ff_avg_pixels16_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
|
||||
int dstStride, int src1Stride, int h);
|
||||
void ff_put_no_rnd_pixels16_l2_mmxext(uint8_t *dst, uint8_t *src1, uint8_t *src2,
|
||||
int dstStride, int src1Stride, int h);
|
||||
void ff_put_mpeg4_qpel16_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
|
||||
int dstStride, int srcStride, int h);
|
||||
void ff_avg_mpeg4_qpel16_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
|
||||
int dstStride, int srcStride, int h);
|
||||
void ff_put_no_rnd_mpeg4_qpel16_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
|
||||
int dstStride, int srcStride,
|
||||
int h);
|
||||
void ff_put_mpeg4_qpel8_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
|
||||
int dstStride, int srcStride, int h);
|
||||
void ff_avg_mpeg4_qpel8_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
|
||||
int dstStride, int srcStride, int h);
|
||||
void ff_put_no_rnd_mpeg4_qpel8_h_lowpass_mmxext(uint8_t *dst, uint8_t *src,
|
||||
int dstStride, int srcStride,
|
||||
int h);
|
||||
void ff_put_mpeg4_qpel16_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
|
||||
int dstStride, int srcStride);
|
||||
void ff_avg_mpeg4_qpel16_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
|
||||
int dstStride, int srcStride);
|
||||
void ff_put_no_rnd_mpeg4_qpel16_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
|
||||
int dstStride, int srcStride);
|
||||
void ff_put_mpeg4_qpel8_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
|
||||
int dstStride, int srcStride);
|
||||
void ff_avg_mpeg4_qpel8_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
|
||||
int dstStride, int srcStride);
|
||||
void ff_put_no_rnd_mpeg4_qpel8_v_lowpass_mmxext(uint8_t *dst, uint8_t *src,
|
||||
int dstStride, int srcStride);
|
||||
#define ff_put_no_rnd_pixels16_mmxext ff_put_pixels16_mmxext
|
||||
#define ff_put_no_rnd_pixels8_mmxext ff_put_pixels8_mmxext
|
||||
|
||||
void ff_h263_v_loop_filter_mmx(uint8_t *src, int stride, int qscale);
|
||||
void ff_h263_h_loop_filter_mmx(uint8_t *src, int stride, int qscale);
|
||||
|
||||
int32_t ff_scalarproduct_int16_mmxext(const int16_t *v1, const int16_t *v2,
|
||||
int order);
|
||||
int32_t ff_scalarproduct_int16_sse2(const int16_t *v1, const int16_t *v2,
|
||||
int order);
|
||||
int32_t ff_scalarproduct_and_madd_int16_mmxext(int16_t *v1, const int16_t *v2,
|
||||
const int16_t *v3,
|
||||
int order, int mul);
|
||||
int32_t ff_scalarproduct_and_madd_int16_sse2(int16_t *v1, const int16_t *v2,
|
||||
const int16_t *v3,
|
||||
int order, int mul);
|
||||
int32_t ff_scalarproduct_and_madd_int16_ssse3(int16_t *v1, const int16_t *v2,
|
||||
const int16_t *v3,
|
||||
int order, int mul);
|
||||
|
||||
void ff_apply_window_int16_round_mmxext(int16_t *output, const int16_t *input,
|
||||
const int16_t *window, unsigned int len);
|
||||
void ff_apply_window_int16_round_sse2(int16_t *output, const int16_t *input,
|
||||
const int16_t *window, unsigned int len);
|
||||
void ff_apply_window_int16_mmxext(int16_t *output, const int16_t *input,
|
||||
const int16_t *window, unsigned int len);
|
||||
void ff_apply_window_int16_sse2(int16_t *output, const int16_t *input,
|
||||
const int16_t *window, unsigned int len);
|
||||
void ff_apply_window_int16_ssse3(int16_t *output, const int16_t *input,
|
||||
const int16_t *window, unsigned int len);
|
||||
void ff_apply_window_int16_ssse3_atom(int16_t *output, const int16_t *input,
|
||||
const int16_t *window, unsigned int len);
|
||||
|
||||
void ff_bswap32_buf_ssse3(uint32_t *dst, const uint32_t *src, int w);
|
||||
void ff_bswap32_buf_sse2(uint32_t *dst, const uint32_t *src, int w);
|
||||
|
||||
void ff_add_hfyu_median_prediction_mmxext(uint8_t *dst, const uint8_t *top,
|
||||
const uint8_t *diff, int w,
|
||||
int *left, int *left_top);
|
||||
int ff_add_hfyu_left_prediction_ssse3(uint8_t *dst, const uint8_t *src,
|
||||
int w, int left);
|
||||
int ff_add_hfyu_left_prediction_sse4(uint8_t *dst, const uint8_t *src,
|
||||
int w, int left);
|
||||
|
||||
void ff_vector_clip_int32_mmx (int32_t *dst, const int32_t *src,
|
||||
int32_t min, int32_t max, unsigned int len);
|
||||
void ff_vector_clip_int32_sse2 (int32_t *dst, const int32_t *src,
|
||||
int32_t min, int32_t max, unsigned int len);
|
||||
void ff_vector_clip_int32_int_sse2(int32_t *dst, const int32_t *src,
|
||||
int32_t min, int32_t max, unsigned int len);
|
||||
void ff_vector_clip_int32_sse4 (int32_t *dst, const int32_t *src,
|
||||
int32_t min, int32_t max, unsigned int len);
|
||||
|
||||
#if HAVE_YASM
|
||||
|
||||
PIXELS16(static, ff_avg, , , _mmxext)
|
||||
PIXELS16(static, ff_put, , , _mmxext)
|
||||
|
||||
#define QPEL_OP(OPNAME, RND, MMX) \
|
||||
static void OPNAME ## qpel8_mc00_ ## MMX (uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
ff_ ## OPNAME ## pixels8_ ## MMX(dst, src, stride, 8); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel8_mc10_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
uint64_t temp[8]; \
|
||||
uint8_t * const half = (uint8_t*)temp; \
|
||||
ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(half, src, 8, \
|
||||
stride, 8); \
|
||||
ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src, half, \
|
||||
stride, stride, 8); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel8_mc20_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
ff_ ## OPNAME ## mpeg4_qpel8_h_lowpass_ ## MMX(dst, src, stride, \
|
||||
stride, 8); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel8_mc30_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
uint64_t temp[8]; \
|
||||
uint8_t * const half = (uint8_t*)temp; \
|
||||
ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(half, src, 8, \
|
||||
stride, 8); \
|
||||
ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src + 1, half, stride, \
|
||||
stride, 8); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel8_mc01_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
uint64_t temp[8]; \
|
||||
uint8_t * const half = (uint8_t*)temp; \
|
||||
ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(half, src, \
|
||||
8, stride); \
|
||||
ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src, half, \
|
||||
stride, stride, 8); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel8_mc02_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, src, \
|
||||
stride, stride); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel8_mc03_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
uint64_t temp[8]; \
|
||||
uint8_t * const half = (uint8_t*)temp; \
|
||||
ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(half, src, \
|
||||
8, stride); \
|
||||
ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, src + stride, half, stride,\
|
||||
stride, 8); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel8_mc11_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
uint64_t half[8 + 9]; \
|
||||
uint8_t * const halfH = ((uint8_t*)half) + 64; \
|
||||
uint8_t * const halfHV = ((uint8_t*)half); \
|
||||
ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \
|
||||
stride, 9); \
|
||||
ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH, 8, \
|
||||
stride, 9); \
|
||||
ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
|
||||
ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV, \
|
||||
stride, 8, 8); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel8_mc31_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
uint64_t half[8 + 9]; \
|
||||
uint8_t * const halfH = ((uint8_t*)half) + 64; \
|
||||
uint8_t * const halfHV = ((uint8_t*)half); \
|
||||
ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \
|
||||
stride, 9); \
|
||||
ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8, \
|
||||
stride, 9); \
|
||||
ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
|
||||
ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV, \
|
||||
stride, 8, 8); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel8_mc13_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
uint64_t half[8 + 9]; \
|
||||
uint8_t * const halfH = ((uint8_t*)half) + 64; \
|
||||
uint8_t * const halfHV = ((uint8_t*)half); \
|
||||
ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \
|
||||
stride, 9); \
|
||||
ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH, 8, \
|
||||
stride, 9); \
|
||||
ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
|
||||
ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV, \
|
||||
stride, 8, 8); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel8_mc33_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
uint64_t half[8 + 9]; \
|
||||
uint8_t * const halfH = ((uint8_t*)half) + 64; \
|
||||
uint8_t * const halfHV = ((uint8_t*)half); \
|
||||
ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \
|
||||
stride, 9); \
|
||||
ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8, \
|
||||
stride, 9); \
|
||||
ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
|
||||
ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV, \
|
||||
stride, 8, 8); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel8_mc21_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
uint64_t half[8 + 9]; \
|
||||
uint8_t * const halfH = ((uint8_t*)half) + 64; \
|
||||
uint8_t * const halfHV = ((uint8_t*)half); \
|
||||
ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \
|
||||
stride, 9); \
|
||||
ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
|
||||
ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH, halfHV, \
|
||||
stride, 8, 8); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel8_mc23_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
uint64_t half[8 + 9]; \
|
||||
uint8_t * const halfH = ((uint8_t*)half) + 64; \
|
||||
uint8_t * const halfHV = ((uint8_t*)half); \
|
||||
ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \
|
||||
stride, 9); \
|
||||
ff_put ## RND ## mpeg4_qpel8_v_lowpass_ ## MMX(halfHV, halfH, 8, 8);\
|
||||
ff_ ## OPNAME ## pixels8_l2_ ## MMX(dst, halfH + 8, halfHV, \
|
||||
stride, 8, 8); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel8_mc12_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
uint64_t half[8 + 9]; \
|
||||
uint8_t * const halfH = ((uint8_t*)half); \
|
||||
ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \
|
||||
stride, 9); \
|
||||
ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src, halfH, \
|
||||
8, stride, 9); \
|
||||
ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH, \
|
||||
stride, 8); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel8_mc32_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
uint64_t half[8 + 9]; \
|
||||
uint8_t * const halfH = ((uint8_t*)half); \
|
||||
ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \
|
||||
stride, 9); \
|
||||
ff_put ## RND ## pixels8_l2_ ## MMX(halfH, src + 1, halfH, 8, \
|
||||
stride, 9); \
|
||||
ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH, \
|
||||
stride, 8); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel8_mc22_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
uint64_t half[9]; \
|
||||
uint8_t * const halfH = ((uint8_t*)half); \
|
||||
ff_put ## RND ## mpeg4_qpel8_h_lowpass_ ## MMX(halfH, src, 8, \
|
||||
stride, 9); \
|
||||
ff_ ## OPNAME ## mpeg4_qpel8_v_lowpass_ ## MMX(dst, halfH, \
|
||||
stride, 8); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel16_mc00_ ## MMX (uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
ff_ ## OPNAME ## pixels16_ ## MMX(dst, src, stride, 16); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel16_mc10_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
uint64_t temp[32]; \
|
||||
uint8_t * const half = (uint8_t*)temp; \
|
||||
ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(half, src, 16, \
|
||||
stride, 16); \
|
||||
ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src, half, stride, \
|
||||
stride, 16); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel16_mc20_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
ff_ ## OPNAME ## mpeg4_qpel16_h_lowpass_ ## MMX(dst, src, \
|
||||
stride, stride, 16);\
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel16_mc30_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
uint64_t temp[32]; \
|
||||
uint8_t * const half = (uint8_t*)temp; \
|
||||
ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(half, src, 16, \
|
||||
stride, 16); \
|
||||
ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src + 1, half, \
|
||||
stride, stride, 16); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel16_mc01_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
uint64_t temp[32]; \
|
||||
uint8_t * const half = (uint8_t*)temp; \
|
||||
ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(half, src, 16, \
|
||||
stride); \
|
||||
ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src, half, stride, \
|
||||
stride, 16); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel16_mc02_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, src, \
|
||||
stride, stride); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel16_mc03_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
uint64_t temp[32]; \
|
||||
uint8_t * const half = (uint8_t*)temp; \
|
||||
ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(half, src, 16, \
|
||||
stride); \
|
||||
ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, src+stride, half, \
|
||||
stride, stride, 16); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel16_mc11_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
uint64_t half[16 * 2 + 17 * 2]; \
|
||||
uint8_t * const halfH = ((uint8_t*)half) + 256; \
|
||||
uint8_t * const halfHV = ((uint8_t*)half); \
|
||||
ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \
|
||||
stride, 17); \
|
||||
ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16, \
|
||||
stride, 17); \
|
||||
ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH, \
|
||||
16, 16); \
|
||||
ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV, \
|
||||
stride, 16, 16); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel16_mc31_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
uint64_t half[16 * 2 + 17 * 2]; \
|
||||
uint8_t * const halfH = ((uint8_t*)half) + 256; \
|
||||
uint8_t * const halfHV = ((uint8_t*)half); \
|
||||
ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \
|
||||
stride, 17); \
|
||||
ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16, \
|
||||
stride, 17); \
|
||||
ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH, \
|
||||
16, 16); \
|
||||
ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV, \
|
||||
stride, 16, 16); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel16_mc13_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
uint64_t half[16 * 2 + 17 * 2]; \
|
||||
uint8_t * const halfH = ((uint8_t*)half) + 256; \
|
||||
uint8_t * const halfHV = ((uint8_t*)half); \
|
||||
ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \
|
||||
stride, 17); \
|
||||
ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16, \
|
||||
stride, 17); \
|
||||
ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH, \
|
||||
16, 16); \
|
||||
ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV, \
|
||||
stride, 16, 16); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel16_mc33_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
uint64_t half[16 * 2 + 17 * 2]; \
|
||||
uint8_t * const halfH = ((uint8_t*)half) + 256; \
|
||||
uint8_t * const halfHV = ((uint8_t*)half); \
|
||||
ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \
|
||||
stride, 17); \
|
||||
ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16, \
|
||||
stride, 17); \
|
||||
ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH, \
|
||||
16, 16); \
|
||||
ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV, \
|
||||
stride, 16, 16); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel16_mc21_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
uint64_t half[16 * 2 + 17 * 2]; \
|
||||
uint8_t * const halfH = ((uint8_t*)half) + 256; \
|
||||
uint8_t * const halfHV = ((uint8_t*)half); \
|
||||
ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \
|
||||
stride, 17); \
|
||||
ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH, \
|
||||
16, 16); \
|
||||
ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH, halfHV, \
|
||||
stride, 16, 16); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel16_mc23_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
uint64_t half[16 * 2 + 17 * 2]; \
|
||||
uint8_t * const halfH = ((uint8_t*)half) + 256; \
|
||||
uint8_t * const halfHV = ((uint8_t*)half); \
|
||||
ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \
|
||||
stride, 17); \
|
||||
ff_put ## RND ## mpeg4_qpel16_v_lowpass_ ## MMX(halfHV, halfH, \
|
||||
16, 16); \
|
||||
ff_ ## OPNAME ## pixels16_l2_ ## MMX(dst, halfH + 16, halfHV, \
|
||||
stride, 16, 16); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel16_mc12_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
uint64_t half[17 * 2]; \
|
||||
uint8_t * const halfH = ((uint8_t*)half); \
|
||||
ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \
|
||||
stride, 17); \
|
||||
ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src, halfH, 16, \
|
||||
stride, 17); \
|
||||
ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH, \
|
||||
stride, 16); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel16_mc32_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
uint64_t half[17 * 2]; \
|
||||
uint8_t * const halfH = ((uint8_t*)half); \
|
||||
ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \
|
||||
stride, 17); \
|
||||
ff_put ## RND ## pixels16_l2_ ## MMX(halfH, src + 1, halfH, 16, \
|
||||
stride, 17); \
|
||||
ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH, \
|
||||
stride, 16); \
|
||||
} \
|
||||
\
|
||||
static void OPNAME ## qpel16_mc22_ ## MMX(uint8_t *dst, uint8_t *src, \
|
||||
ptrdiff_t stride) \
|
||||
{ \
|
||||
uint64_t half[17 * 2]; \
|
||||
uint8_t * const halfH = ((uint8_t*)half); \
|
||||
ff_put ## RND ## mpeg4_qpel16_h_lowpass_ ## MMX(halfH, src, 16, \
|
||||
stride, 17); \
|
||||
ff_ ## OPNAME ## mpeg4_qpel16_v_lowpass_ ## MMX(dst, halfH, \
|
||||
stride, 16); \
|
||||
}
|
||||
|
||||
QPEL_OP(put_, _, mmxext)
|
||||
QPEL_OP(avg_, _, mmxext)
|
||||
QPEL_OP(put_no_rnd_, _no_rnd_, mmxext)
|
||||
#endif /* HAVE_YASM */
|
||||
|
||||
#define SET_QPEL_FUNCS(PFX, IDX, SIZE, CPU, PREFIX) \
|
||||
do { \
|
||||
c->PFX ## _pixels_tab[IDX][ 0] = PREFIX ## PFX ## SIZE ## _mc00_ ## CPU; \
|
||||
c->PFX ## _pixels_tab[IDX][ 1] = PREFIX ## PFX ## SIZE ## _mc10_ ## CPU; \
|
||||
c->PFX ## _pixels_tab[IDX][ 2] = PREFIX ## PFX ## SIZE ## _mc20_ ## CPU; \
|
||||
c->PFX ## _pixels_tab[IDX][ 3] = PREFIX ## PFX ## SIZE ## _mc30_ ## CPU; \
|
||||
c->PFX ## _pixels_tab[IDX][ 4] = PREFIX ## PFX ## SIZE ## _mc01_ ## CPU; \
|
||||
c->PFX ## _pixels_tab[IDX][ 5] = PREFIX ## PFX ## SIZE ## _mc11_ ## CPU; \
|
||||
c->PFX ## _pixels_tab[IDX][ 6] = PREFIX ## PFX ## SIZE ## _mc21_ ## CPU; \
|
||||
c->PFX ## _pixels_tab[IDX][ 7] = PREFIX ## PFX ## SIZE ## _mc31_ ## CPU; \
|
||||
c->PFX ## _pixels_tab[IDX][ 8] = PREFIX ## PFX ## SIZE ## _mc02_ ## CPU; \
|
||||
c->PFX ## _pixels_tab[IDX][ 9] = PREFIX ## PFX ## SIZE ## _mc12_ ## CPU; \
|
||||
c->PFX ## _pixels_tab[IDX][10] = PREFIX ## PFX ## SIZE ## _mc22_ ## CPU; \
|
||||
c->PFX ## _pixels_tab[IDX][11] = PREFIX ## PFX ## SIZE ## _mc32_ ## CPU; \
|
||||
c->PFX ## _pixels_tab[IDX][12] = PREFIX ## PFX ## SIZE ## _mc03_ ## CPU; \
|
||||
c->PFX ## _pixels_tab[IDX][13] = PREFIX ## PFX ## SIZE ## _mc13_ ## CPU; \
|
||||
c->PFX ## _pixels_tab[IDX][14] = PREFIX ## PFX ## SIZE ## _mc23_ ## CPU; \
|
||||
c->PFX ## _pixels_tab[IDX][15] = PREFIX ## PFX ## SIZE ## _mc33_ ## CPU; \
|
||||
} while (0)
|
||||
|
||||
static av_cold void dsputil_init_mmx(DSPContext *c, AVCodecContext *avctx,
|
||||
int cpu_flags)
|
||||
{
|
||||
#if HAVE_MMX_INLINE
|
||||
const int high_bit_depth = avctx->bits_per_raw_sample > 8;
|
||||
|
||||
c->put_pixels_clamped = ff_put_pixels_clamped_mmx;
|
||||
c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_mmx;
|
||||
c->add_pixels_clamped = ff_add_pixels_clamped_mmx;
|
||||
|
||||
if (!high_bit_depth) {
|
||||
c->clear_block = ff_clear_block_mmx;
|
||||
c->clear_blocks = ff_clear_blocks_mmx;
|
||||
c->draw_edges = ff_draw_edges_mmx;
|
||||
}
|
||||
|
||||
#if CONFIG_VIDEODSP && (ARCH_X86_32 || !HAVE_YASM)
|
||||
c->gmc = ff_gmc_mmx;
|
||||
#endif
|
||||
|
||||
c->add_bytes = ff_add_bytes_mmx;
|
||||
#endif /* HAVE_MMX_INLINE */
|
||||
|
||||
#if HAVE_MMX_EXTERNAL
|
||||
if (CONFIG_H263_DECODER || CONFIG_H263_ENCODER) {
|
||||
c->h263_v_loop_filter = ff_h263_v_loop_filter_mmx;
|
||||
c->h263_h_loop_filter = ff_h263_h_loop_filter_mmx;
|
||||
}
|
||||
|
||||
c->vector_clip_int32 = ff_vector_clip_int32_mmx;
|
||||
#endif /* HAVE_MMX_EXTERNAL */
|
||||
}
|
||||
|
||||
static av_cold void dsputil_init_mmxext(DSPContext *c, AVCodecContext *avctx,
|
||||
int cpu_flags)
|
||||
{
|
||||
#if HAVE_MMXEXT_EXTERNAL
|
||||
SET_QPEL_FUNCS(avg_qpel, 0, 16, mmxext, );
|
||||
SET_QPEL_FUNCS(avg_qpel, 1, 8, mmxext, );
|
||||
|
||||
SET_QPEL_FUNCS(put_qpel, 0, 16, mmxext, );
|
||||
SET_QPEL_FUNCS(put_qpel, 1, 8, mmxext, );
|
||||
SET_QPEL_FUNCS(put_no_rnd_qpel, 0, 16, mmxext, );
|
||||
SET_QPEL_FUNCS(put_no_rnd_qpel, 1, 8, mmxext, );
|
||||
|
||||
/* slower than cmov version on AMD */
|
||||
if (!(cpu_flags & AV_CPU_FLAG_3DNOW))
|
||||
c->add_hfyu_median_prediction = ff_add_hfyu_median_prediction_mmxext;
|
||||
|
||||
c->scalarproduct_int16 = ff_scalarproduct_int16_mmxext;
|
||||
c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_mmxext;
|
||||
|
||||
if (avctx->flags & CODEC_FLAG_BITEXACT) {
|
||||
c->apply_window_int16 = ff_apply_window_int16_mmxext;
|
||||
} else {
|
||||
c->apply_window_int16 = ff_apply_window_int16_round_mmxext;
|
||||
}
|
||||
#endif /* HAVE_MMXEXT_EXTERNAL */
|
||||
}
|
||||
|
||||
static av_cold void dsputil_init_sse(DSPContext *c, AVCodecContext *avctx,
|
||||
int cpu_flags)
|
||||
{
|
||||
#if HAVE_SSE_INLINE
|
||||
const int high_bit_depth = avctx->bits_per_raw_sample > 8;
|
||||
|
||||
if (!high_bit_depth) {
|
||||
if (!(CONFIG_MPEG_XVMC_DECODER && avctx->xvmc_acceleration > 1)) {
|
||||
/* XvMCCreateBlocks() may not allocate 16-byte aligned blocks */
|
||||
c->clear_block = ff_clear_block_sse;
|
||||
c->clear_blocks = ff_clear_blocks_sse;
|
||||
}
|
||||
}
|
||||
|
||||
c->vector_clipf = ff_vector_clipf_sse;
|
||||
#endif /* HAVE_SSE_INLINE */
|
||||
|
||||
#if HAVE_YASM
|
||||
#if HAVE_INLINE_ASM && CONFIG_VIDEODSP
|
||||
c->gmc = ff_gmc_sse;
|
||||
#endif
|
||||
#endif /* HAVE_YASM */
|
||||
}
|
||||
|
||||
static av_cold void dsputil_init_sse2(DSPContext *c, AVCodecContext *avctx,
|
||||
int cpu_flags)
|
||||
{
|
||||
#if HAVE_SSE2_INLINE
|
||||
const int high_bit_depth = avctx->bits_per_raw_sample > 8;
|
||||
|
||||
if (!high_bit_depth && avctx->idct_algo == FF_IDCT_XVIDMMX && avctx->lowres == 0) {
|
||||
c->idct_put = ff_idct_xvid_sse2_put;
|
||||
c->idct_add = ff_idct_xvid_sse2_add;
|
||||
c->idct = ff_idct_xvid_sse2;
|
||||
c->idct_permutation_type = FF_SSE2_IDCT_PERM;
|
||||
}
|
||||
#endif /* HAVE_SSE2_INLINE */
|
||||
|
||||
#if HAVE_SSE2_EXTERNAL
|
||||
c->scalarproduct_int16 = ff_scalarproduct_int16_sse2;
|
||||
c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_sse2;
|
||||
if (cpu_flags & AV_CPU_FLAG_ATOM) {
|
||||
c->vector_clip_int32 = ff_vector_clip_int32_int_sse2;
|
||||
} else {
|
||||
c->vector_clip_int32 = ff_vector_clip_int32_sse2;
|
||||
}
|
||||
if (avctx->flags & CODEC_FLAG_BITEXACT) {
|
||||
c->apply_window_int16 = ff_apply_window_int16_sse2;
|
||||
} else if (!(cpu_flags & AV_CPU_FLAG_SSE2SLOW)) {
|
||||
c->apply_window_int16 = ff_apply_window_int16_round_sse2;
|
||||
}
|
||||
c->bswap_buf = ff_bswap32_buf_sse2;
|
||||
#endif /* HAVE_SSE2_EXTERNAL */
|
||||
}
|
||||
|
||||
static av_cold void dsputil_init_ssse3(DSPContext *c, AVCodecContext *avctx,
|
||||
int cpu_flags)
|
||||
{
|
||||
#if HAVE_SSSE3_EXTERNAL
|
||||
c->add_hfyu_left_prediction = ff_add_hfyu_left_prediction_ssse3;
|
||||
if (cpu_flags & AV_CPU_FLAG_SSE4) // not really SSE4, just slow on Conroe
|
||||
c->add_hfyu_left_prediction = ff_add_hfyu_left_prediction_sse4;
|
||||
|
||||
if (cpu_flags & AV_CPU_FLAG_ATOM)
|
||||
c->apply_window_int16 = ff_apply_window_int16_ssse3_atom;
|
||||
else
|
||||
c->apply_window_int16 = ff_apply_window_int16_ssse3;
|
||||
if (!(cpu_flags & (AV_CPU_FLAG_SSE42 | AV_CPU_FLAG_3DNOW))) // cachesplit
|
||||
c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_ssse3;
|
||||
c->bswap_buf = ff_bswap32_buf_ssse3;
|
||||
#endif /* HAVE_SSSE3_EXTERNAL */
|
||||
}
|
||||
|
||||
static av_cold void dsputil_init_sse4(DSPContext *c, AVCodecContext *avctx,
|
||||
int cpu_flags)
|
||||
{
|
||||
#if HAVE_SSE4_EXTERNAL
|
||||
c->vector_clip_int32 = ff_vector_clip_int32_sse4;
|
||||
#endif /* HAVE_SSE4_EXTERNAL */
|
||||
}
|
||||
|
||||
av_cold void ff_dsputil_init_x86(DSPContext *c, AVCodecContext *avctx)
|
||||
{
|
||||
int cpu_flags = av_get_cpu_flags();
|
||||
|
||||
#if HAVE_7REGS && HAVE_INLINE_ASM
|
||||
if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_CMOV)
|
||||
c->add_hfyu_median_prediction = ff_add_hfyu_median_prediction_cmov;
|
||||
#endif
|
||||
|
||||
if (X86_MMX(cpu_flags)) {
|
||||
#if HAVE_INLINE_ASM
|
||||
const int idct_algo = avctx->idct_algo;
|
||||
|
||||
if (avctx->lowres == 0 && avctx->bits_per_raw_sample <= 8) {
|
||||
if (idct_algo == FF_IDCT_AUTO || idct_algo == FF_IDCT_SIMPLEMMX) {
|
||||
c->idct_put = ff_simple_idct_put_mmx;
|
||||
c->idct_add = ff_simple_idct_add_mmx;
|
||||
c->idct = ff_simple_idct_mmx;
|
||||
c->idct_permutation_type = FF_SIMPLE_IDCT_PERM;
|
||||
} else if (idct_algo == FF_IDCT_XVIDMMX) {
|
||||
if (cpu_flags & AV_CPU_FLAG_SSE2) {
|
||||
c->idct_put = ff_idct_xvid_sse2_put;
|
||||
c->idct_add = ff_idct_xvid_sse2_add;
|
||||
c->idct = ff_idct_xvid_sse2;
|
||||
c->idct_permutation_type = FF_SSE2_IDCT_PERM;
|
||||
} else if (cpu_flags & AV_CPU_FLAG_MMXEXT) {
|
||||
c->idct_put = ff_idct_xvid_mmxext_put;
|
||||
c->idct_add = ff_idct_xvid_mmxext_add;
|
||||
c->idct = ff_idct_xvid_mmxext;
|
||||
} else {
|
||||
c->idct_put = ff_idct_xvid_mmx_put;
|
||||
c->idct_add = ff_idct_xvid_mmx_add;
|
||||
c->idct = ff_idct_xvid_mmx;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_INLINE_ASM */
|
||||
|
||||
dsputil_init_mmx(c, avctx, cpu_flags);
|
||||
}
|
||||
|
||||
if (X86_MMXEXT(cpu_flags))
|
||||
dsputil_init_mmxext(c, avctx, cpu_flags);
|
||||
|
||||
if (X86_SSE(cpu_flags))
|
||||
dsputil_init_sse(c, avctx, cpu_flags);
|
||||
|
||||
if (X86_SSE2(cpu_flags))
|
||||
dsputil_init_sse2(c, avctx, cpu_flags);
|
||||
|
||||
if (EXTERNAL_SSSE3(cpu_flags))
|
||||
dsputil_init_ssse3(c, avctx, cpu_flags);
|
||||
|
||||
if (EXTERNAL_SSE4(cpu_flags))
|
||||
dsputil_init_sse4(c, avctx, cpu_flags);
|
||||
|
||||
if (CONFIG_ENCODERS)
|
||||
ff_dsputilenc_init_mmx(c, avctx);
|
||||
}
|
|
@ -0,0 +1,637 @@
|
|||
/*
|
||||
* MMX optimized DSP utils
|
||||
* Copyright (c) 2000, 2001 Fabrice Bellard
|
||||
* Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* MMX optimization by Nick Kurshev <nickols_k@mail.ru>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/cpu.h"
|
||||
#include "libavutil/x86/asm.h"
|
||||
#include "libavcodec/videodsp.h"
|
||||
#include "constants.h"
|
||||
#include "dsputil_x86.h"
|
||||
#include "diracdsp_mmx.h"
|
||||
|
||||
#if HAVE_INLINE_ASM
|
||||
|
||||
void ff_put_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels,
|
||||
int line_size)
|
||||
{
|
||||
const int16_t *p;
|
||||
uint8_t *pix;
|
||||
|
||||
/* read the pixels */
|
||||
p = block;
|
||||
pix = pixels;
|
||||
/* unrolled loop */
|
||||
__asm__ volatile (
|
||||
"movq (%3), %%mm0 \n\t"
|
||||
"movq 8(%3), %%mm1 \n\t"
|
||||
"movq 16(%3), %%mm2 \n\t"
|
||||
"movq 24(%3), %%mm3 \n\t"
|
||||
"movq 32(%3), %%mm4 \n\t"
|
||||
"movq 40(%3), %%mm5 \n\t"
|
||||
"movq 48(%3), %%mm6 \n\t"
|
||||
"movq 56(%3), %%mm7 \n\t"
|
||||
"packuswb %%mm1, %%mm0 \n\t"
|
||||
"packuswb %%mm3, %%mm2 \n\t"
|
||||
"packuswb %%mm5, %%mm4 \n\t"
|
||||
"packuswb %%mm7, %%mm6 \n\t"
|
||||
"movq %%mm0, (%0) \n\t"
|
||||
"movq %%mm2, (%0, %1) \n\t"
|
||||
"movq %%mm4, (%0, %1, 2) \n\t"
|
||||
"movq %%mm6, (%0, %2) \n\t"
|
||||
:: "r"(pix), "r"((x86_reg)line_size), "r"((x86_reg)line_size * 3),
|
||||
"r"(p)
|
||||
: "memory");
|
||||
pix += line_size * 4;
|
||||
p += 32;
|
||||
|
||||
// if here would be an exact copy of the code above
|
||||
// compiler would generate some very strange code
|
||||
// thus using "r"
|
||||
__asm__ volatile (
|
||||
"movq (%3), %%mm0 \n\t"
|
||||
"movq 8(%3), %%mm1 \n\t"
|
||||
"movq 16(%3), %%mm2 \n\t"
|
||||
"movq 24(%3), %%mm3 \n\t"
|
||||
"movq 32(%3), %%mm4 \n\t"
|
||||
"movq 40(%3), %%mm5 \n\t"
|
||||
"movq 48(%3), %%mm6 \n\t"
|
||||
"movq 56(%3), %%mm7 \n\t"
|
||||
"packuswb %%mm1, %%mm0 \n\t"
|
||||
"packuswb %%mm3, %%mm2 \n\t"
|
||||
"packuswb %%mm5, %%mm4 \n\t"
|
||||
"packuswb %%mm7, %%mm6 \n\t"
|
||||
"movq %%mm0, (%0) \n\t"
|
||||
"movq %%mm2, (%0, %1) \n\t"
|
||||
"movq %%mm4, (%0, %1, 2) \n\t"
|
||||
"movq %%mm6, (%0, %2) \n\t"
|
||||
:: "r"(pix), "r"((x86_reg)line_size), "r"((x86_reg)line_size * 3), "r"(p)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
#define put_signed_pixels_clamped_mmx_half(off) \
|
||||
"movq "#off"(%2), %%mm1 \n\t" \
|
||||
"movq 16 + "#off"(%2), %%mm2 \n\t" \
|
||||
"movq 32 + "#off"(%2), %%mm3 \n\t" \
|
||||
"movq 48 + "#off"(%2), %%mm4 \n\t" \
|
||||
"packsswb 8 + "#off"(%2), %%mm1 \n\t" \
|
||||
"packsswb 24 + "#off"(%2), %%mm2 \n\t" \
|
||||
"packsswb 40 + "#off"(%2), %%mm3 \n\t" \
|
||||
"packsswb 56 + "#off"(%2), %%mm4 \n\t" \
|
||||
"paddb %%mm0, %%mm1 \n\t" \
|
||||
"paddb %%mm0, %%mm2 \n\t" \
|
||||
"paddb %%mm0, %%mm3 \n\t" \
|
||||
"paddb %%mm0, %%mm4 \n\t" \
|
||||
"movq %%mm1, (%0) \n\t" \
|
||||
"movq %%mm2, (%0, %3) \n\t" \
|
||||
"movq %%mm3, (%0, %3, 2) \n\t" \
|
||||
"movq %%mm4, (%0, %1) \n\t"
|
||||
|
||||
void ff_put_signed_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels,
|
||||
int line_size)
|
||||
{
|
||||
x86_reg line_skip = line_size;
|
||||
x86_reg line_skip3;
|
||||
|
||||
__asm__ volatile (
|
||||
"movq "MANGLE(ff_pb_80)", %%mm0 \n\t"
|
||||
"lea (%3, %3, 2), %1 \n\t"
|
||||
put_signed_pixels_clamped_mmx_half(0)
|
||||
"lea (%0, %3, 4), %0 \n\t"
|
||||
put_signed_pixels_clamped_mmx_half(64)
|
||||
: "+&r"(pixels), "=&r"(line_skip3)
|
||||
: "r"(block), "r"(line_skip)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
void ff_add_pixels_clamped_mmx(const int16_t *block, uint8_t *pixels,
|
||||
int line_size)
|
||||
{
|
||||
const int16_t *p;
|
||||
uint8_t *pix;
|
||||
int i;
|
||||
|
||||
/* read the pixels */
|
||||
p = block;
|
||||
pix = pixels;
|
||||
MOVQ_ZERO(mm7);
|
||||
i = 4;
|
||||
do {
|
||||
__asm__ volatile (
|
||||
"movq (%2), %%mm0 \n\t"
|
||||
"movq 8(%2), %%mm1 \n\t"
|
||||
"movq 16(%2), %%mm2 \n\t"
|
||||
"movq 24(%2), %%mm3 \n\t"
|
||||
"movq %0, %%mm4 \n\t"
|
||||
"movq %1, %%mm6 \n\t"
|
||||
"movq %%mm4, %%mm5 \n\t"
|
||||
"punpcklbw %%mm7, %%mm4 \n\t"
|
||||
"punpckhbw %%mm7, %%mm5 \n\t"
|
||||
"paddsw %%mm4, %%mm0 \n\t"
|
||||
"paddsw %%mm5, %%mm1 \n\t"
|
||||
"movq %%mm6, %%mm5 \n\t"
|
||||
"punpcklbw %%mm7, %%mm6 \n\t"
|
||||
"punpckhbw %%mm7, %%mm5 \n\t"
|
||||
"paddsw %%mm6, %%mm2 \n\t"
|
||||
"paddsw %%mm5, %%mm3 \n\t"
|
||||
"packuswb %%mm1, %%mm0 \n\t"
|
||||
"packuswb %%mm3, %%mm2 \n\t"
|
||||
"movq %%mm0, %0 \n\t"
|
||||
"movq %%mm2, %1 \n\t"
|
||||
: "+m"(*pix), "+m"(*(pix + line_size))
|
||||
: "r"(p)
|
||||
: "memory");
|
||||
pix += line_size * 2;
|
||||
p += 16;
|
||||
} while (--i);
|
||||
}
|
||||
|
||||
#define CLEAR_BLOCKS(name, n) \
|
||||
void name(int16_t *blocks) \
|
||||
{ \
|
||||
__asm__ volatile ( \
|
||||
"pxor %%mm7, %%mm7 \n\t" \
|
||||
"mov %1, %%"REG_a" \n\t" \
|
||||
"1: \n\t" \
|
||||
"movq %%mm7, (%0, %%"REG_a") \n\t" \
|
||||
"movq %%mm7, 8(%0, %%"REG_a") \n\t" \
|
||||
"movq %%mm7, 16(%0, %%"REG_a") \n\t" \
|
||||
"movq %%mm7, 24(%0, %%"REG_a") \n\t" \
|
||||
"add $32, %%"REG_a" \n\t" \
|
||||
"js 1b \n\t" \
|
||||
:: "r"(((uint8_t *)blocks) + 128 * n), \
|
||||
"i"(-128 * n) \
|
||||
: "%"REG_a \
|
||||
); \
|
||||
}
|
||||
CLEAR_BLOCKS(ff_clear_blocks_mmx, 6)
|
||||
CLEAR_BLOCKS(ff_clear_block_mmx, 1)
|
||||
|
||||
void ff_clear_block_sse(int16_t *block)
|
||||
{
|
||||
__asm__ volatile (
|
||||
"xorps %%xmm0, %%xmm0 \n"
|
||||
"movaps %%xmm0, (%0) \n"
|
||||
"movaps %%xmm0, 16(%0) \n"
|
||||
"movaps %%xmm0, 32(%0) \n"
|
||||
"movaps %%xmm0, 48(%0) \n"
|
||||
"movaps %%xmm0, 64(%0) \n"
|
||||
"movaps %%xmm0, 80(%0) \n"
|
||||
"movaps %%xmm0, 96(%0) \n"
|
||||
"movaps %%xmm0, 112(%0) \n"
|
||||
:: "r"(block)
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
void ff_clear_blocks_sse(int16_t *blocks)
|
||||
{
|
||||
__asm__ volatile (
|
||||
"xorps %%xmm0, %%xmm0 \n"
|
||||
"mov %1, %%"REG_a" \n"
|
||||
"1: \n"
|
||||
"movaps %%xmm0, (%0, %%"REG_a") \n"
|
||||
"movaps %%xmm0, 16(%0, %%"REG_a") \n"
|
||||
"movaps %%xmm0, 32(%0, %%"REG_a") \n"
|
||||
"movaps %%xmm0, 48(%0, %%"REG_a") \n"
|
||||
"movaps %%xmm0, 64(%0, %%"REG_a") \n"
|
||||
"movaps %%xmm0, 80(%0, %%"REG_a") \n"
|
||||
"movaps %%xmm0, 96(%0, %%"REG_a") \n"
|
||||
"movaps %%xmm0, 112(%0, %%"REG_a") \n"
|
||||
"add $128, %%"REG_a" \n"
|
||||
"js 1b \n"
|
||||
:: "r"(((uint8_t *)blocks) + 128 * 6),
|
||||
"i"(-128 * 6)
|
||||
: "%"REG_a
|
||||
);
|
||||
}
|
||||
|
||||
void ff_add_bytes_mmx(uint8_t *dst, uint8_t *src, int w)
|
||||
{
|
||||
x86_reg i = 0;
|
||||
__asm__ volatile (
|
||||
"jmp 2f \n\t"
|
||||
"1: \n\t"
|
||||
"movq (%1, %0), %%mm0 \n\t"
|
||||
"movq (%2, %0), %%mm1 \n\t"
|
||||
"paddb %%mm0, %%mm1 \n\t"
|
||||
"movq %%mm1, (%2, %0) \n\t"
|
||||
"movq 8(%1, %0), %%mm0 \n\t"
|
||||
"movq 8(%2, %0), %%mm1 \n\t"
|
||||
"paddb %%mm0, %%mm1 \n\t"
|
||||
"movq %%mm1, 8(%2, %0) \n\t"
|
||||
"add $16, %0 \n\t"
|
||||
"2: \n\t"
|
||||
"cmp %3, %0 \n\t"
|
||||
"js 1b \n\t"
|
||||
: "+r"(i)
|
||||
: "r"(src), "r"(dst), "r"((x86_reg)w - 15)
|
||||
);
|
||||
for ( ; i < w; i++)
|
||||
dst[i + 0] += src[i + 0];
|
||||
}
|
||||
|
||||
/* Draw the edges of width 'w' of an image of size width, height
|
||||
* this MMX version can only handle w == 8 || w == 16. */
|
||||
void ff_draw_edges_mmx(uint8_t *buf, int wrap, int width, int height,
|
||||
int w, int h, int sides)
|
||||
{
|
||||
uint8_t *ptr, *last_line;
|
||||
int i;
|
||||
|
||||
last_line = buf + (height - 1) * wrap;
|
||||
/* left and right */
|
||||
ptr = buf;
|
||||
if (w == 8) {
|
||||
__asm__ volatile (
|
||||
"1: \n\t"
|
||||
"movd (%0), %%mm0 \n\t"
|
||||
"punpcklbw %%mm0, %%mm0 \n\t"
|
||||
"punpcklwd %%mm0, %%mm0 \n\t"
|
||||
"punpckldq %%mm0, %%mm0 \n\t"
|
||||
"movq %%mm0, -8(%0) \n\t"
|
||||
"movq -8(%0, %2), %%mm1 \n\t"
|
||||
"punpckhbw %%mm1, %%mm1 \n\t"
|
||||
"punpckhwd %%mm1, %%mm1 \n\t"
|
||||
"punpckhdq %%mm1, %%mm1 \n\t"
|
||||
"movq %%mm1, (%0, %2) \n\t"
|
||||
"add %1, %0 \n\t"
|
||||
"cmp %3, %0 \n\t"
|
||||
"jb 1b \n\t"
|
||||
: "+r"(ptr)
|
||||
: "r"((x86_reg)wrap), "r"((x86_reg)width), "r"(ptr + wrap * height)
|
||||
);
|
||||
} else if(w==16){
|
||||
__asm__ volatile (
|
||||
"1: \n\t"
|
||||
"movd (%0), %%mm0 \n\t"
|
||||
"punpcklbw %%mm0, %%mm0 \n\t"
|
||||
"punpcklwd %%mm0, %%mm0 \n\t"
|
||||
"punpckldq %%mm0, %%mm0 \n\t"
|
||||
"movq %%mm0, -8(%0) \n\t"
|
||||
"movq %%mm0, -16(%0) \n\t"
|
||||
"movq -8(%0, %2), %%mm1 \n\t"
|
||||
"punpckhbw %%mm1, %%mm1 \n\t"
|
||||
"punpckhwd %%mm1, %%mm1 \n\t"
|
||||
"punpckhdq %%mm1, %%mm1 \n\t"
|
||||
"movq %%mm1, (%0, %2) \n\t"
|
||||
"movq %%mm1, 8(%0, %2) \n\t"
|
||||
"add %1, %0 \n\t"
|
||||
"cmp %3, %0 \n\t"
|
||||
"jb 1b \n\t"
|
||||
: "+r"(ptr)
|
||||
: "r"((x86_reg)wrap), "r"((x86_reg)width), "r"(ptr + wrap * height)
|
||||
);
|
||||
} else {
|
||||
av_assert1(w == 4);
|
||||
__asm__ volatile (
|
||||
"1: \n\t"
|
||||
"movd (%0), %%mm0 \n\t"
|
||||
"punpcklbw %%mm0, %%mm0 \n\t"
|
||||
"punpcklwd %%mm0, %%mm0 \n\t"
|
||||
"movd %%mm0, -4(%0) \n\t"
|
||||
"movd -4(%0, %2), %%mm1 \n\t"
|
||||
"punpcklbw %%mm1, %%mm1 \n\t"
|
||||
"punpckhwd %%mm1, %%mm1 \n\t"
|
||||
"punpckhdq %%mm1, %%mm1 \n\t"
|
||||
"movd %%mm1, (%0, %2) \n\t"
|
||||
"add %1, %0 \n\t"
|
||||
"cmp %3, %0 \n\t"
|
||||
"jb 1b \n\t"
|
||||
: "+r"(ptr)
|
||||
: "r"((x86_reg)wrap), "r"((x86_reg)width), "r"(ptr + wrap * height)
|
||||
);
|
||||
}
|
||||
|
||||
/* top and bottom (and hopefully also the corners) */
|
||||
if (sides & EDGE_TOP) {
|
||||
for (i = 0; i < h; i += 4) {
|
||||
ptr = buf - (i + 1) * wrap - w;
|
||||
__asm__ volatile (
|
||||
"1: \n\t"
|
||||
"movq (%1, %0), %%mm0 \n\t"
|
||||
"movq %%mm0, (%0) \n\t"
|
||||
"movq %%mm0, (%0, %2) \n\t"
|
||||
"movq %%mm0, (%0, %2, 2) \n\t"
|
||||
"movq %%mm0, (%0, %3) \n\t"
|
||||
"add $8, %0 \n\t"
|
||||
"cmp %4, %0 \n\t"
|
||||
"jb 1b \n\t"
|
||||
: "+r"(ptr)
|
||||
: "r"((x86_reg)buf - (x86_reg)ptr - w), "r"((x86_reg) -wrap),
|
||||
"r"((x86_reg) -wrap * 3), "r"(ptr + width + 2 * w)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (sides & EDGE_BOTTOM) {
|
||||
for (i = 0; i < h; i += 4) {
|
||||
ptr = last_line + (i + 1) * wrap - w;
|
||||
__asm__ volatile (
|
||||
"1: \n\t"
|
||||
"movq (%1, %0), %%mm0 \n\t"
|
||||
"movq %%mm0, (%0) \n\t"
|
||||
"movq %%mm0, (%0, %2) \n\t"
|
||||
"movq %%mm0, (%0, %2, 2) \n\t"
|
||||
"movq %%mm0, (%0, %3) \n\t"
|
||||
"add $8, %0 \n\t"
|
||||
"cmp %4, %0 \n\t"
|
||||
"jb 1b \n\t"
|
||||
: "+r"(ptr)
|
||||
: "r"((x86_reg)last_line - (x86_reg)ptr - w),
|
||||
"r"((x86_reg)wrap), "r"((x86_reg)wrap * 3),
|
||||
"r"(ptr + width + 2 * w)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef void emulated_edge_mc_func(uint8_t *dst, ptrdiff_t dst_stride,
|
||||
const uint8_t *src, ptrdiff_t src_linesize,
|
||||
int block_w, int block_h,
|
||||
int src_x, int src_y, int w, int h);
|
||||
|
||||
static av_always_inline void gmc(uint8_t *dst, uint8_t *src,
|
||||
int stride, int h, int ox, int oy,
|
||||
int dxx, int dxy, int dyx, int dyy,
|
||||
int shift, int r, int width, int height,
|
||||
emulated_edge_mc_func *emu_edge_fn)
|
||||
{
|
||||
const int w = 8;
|
||||
const int ix = ox >> (16 + shift);
|
||||
const int iy = oy >> (16 + shift);
|
||||
const int oxs = ox >> 4;
|
||||
const int oys = oy >> 4;
|
||||
const int dxxs = dxx >> 4;
|
||||
const int dxys = dxy >> 4;
|
||||
const int dyxs = dyx >> 4;
|
||||
const int dyys = dyy >> 4;
|
||||
const uint16_t r4[4] = { r, r, r, r };
|
||||
const uint16_t dxy4[4] = { dxys, dxys, dxys, dxys };
|
||||
const uint16_t dyy4[4] = { dyys, dyys, dyys, dyys };
|
||||
const uint64_t shift2 = 2 * shift;
|
||||
#define MAX_STRIDE 4096U
|
||||
#define MAX_H 8U
|
||||
uint8_t edge_buf[(MAX_H + 1) * MAX_STRIDE];
|
||||
int x, y;
|
||||
|
||||
const int dxw = (dxx - (1 << (16 + shift))) * (w - 1);
|
||||
const int dyh = (dyy - (1 << (16 + shift))) * (h - 1);
|
||||
const int dxh = dxy * (h - 1);
|
||||
const int dyw = dyx * (w - 1);
|
||||
int need_emu = (unsigned)ix >= width - w ||
|
||||
(unsigned)iy >= height - h;
|
||||
|
||||
if ( // non-constant fullpel offset (3% of blocks)
|
||||
((ox ^ (ox + dxw)) | (ox ^ (ox + dxh)) | (ox ^ (ox + dxw + dxh)) |
|
||||
(oy ^ (oy + dyw)) | (oy ^ (oy + dyh)) | (oy ^ (oy + dyw + dyh))) >> (16 + shift)
|
||||
// uses more than 16 bits of subpel mv (only at huge resolution)
|
||||
|| (dxx | dxy | dyx | dyy) & 15
|
||||
|| (need_emu && (h > MAX_H || stride > MAX_STRIDE))) {
|
||||
// FIXME could still use mmx for some of the rows
|
||||
ff_gmc_c(dst, src, stride, h, ox, oy, dxx, dxy, dyx, dyy,
|
||||
shift, r, width, height);
|
||||
return;
|
||||
}
|
||||
|
||||
src += ix + iy * stride;
|
||||
if (need_emu) {
|
||||
emu_edge_fn(edge_buf, stride, src, stride, w + 1, h + 1, ix, iy, width, height);
|
||||
src = edge_buf;
|
||||
}
|
||||
|
||||
__asm__ volatile (
|
||||
"movd %0, %%mm6 \n\t"
|
||||
"pxor %%mm7, %%mm7 \n\t"
|
||||
"punpcklwd %%mm6, %%mm6 \n\t"
|
||||
"punpcklwd %%mm6, %%mm6 \n\t"
|
||||
:: "r"(1<<shift)
|
||||
);
|
||||
|
||||
for (x = 0; x < w; x += 4) {
|
||||
uint16_t dx4[4] = { oxs - dxys + dxxs * (x + 0),
|
||||
oxs - dxys + dxxs * (x + 1),
|
||||
oxs - dxys + dxxs * (x + 2),
|
||||
oxs - dxys + dxxs * (x + 3) };
|
||||
uint16_t dy4[4] = { oys - dyys + dyxs * (x + 0),
|
||||
oys - dyys + dyxs * (x + 1),
|
||||
oys - dyys + dyxs * (x + 2),
|
||||
oys - dyys + dyxs * (x + 3) };
|
||||
|
||||
for (y = 0; y < h; y++) {
|
||||
__asm__ volatile (
|
||||
"movq %0, %%mm4 \n\t"
|
||||
"movq %1, %%mm5 \n\t"
|
||||
"paddw %2, %%mm4 \n\t"
|
||||
"paddw %3, %%mm5 \n\t"
|
||||
"movq %%mm4, %0 \n\t"
|
||||
"movq %%mm5, %1 \n\t"
|
||||
"psrlw $12, %%mm4 \n\t"
|
||||
"psrlw $12, %%mm5 \n\t"
|
||||
: "+m"(*dx4), "+m"(*dy4)
|
||||
: "m"(*dxy4), "m"(*dyy4)
|
||||
);
|
||||
|
||||
__asm__ volatile (
|
||||
"movq %%mm6, %%mm2 \n\t"
|
||||
"movq %%mm6, %%mm1 \n\t"
|
||||
"psubw %%mm4, %%mm2 \n\t"
|
||||
"psubw %%mm5, %%mm1 \n\t"
|
||||
"movq %%mm2, %%mm0 \n\t"
|
||||
"movq %%mm4, %%mm3 \n\t"
|
||||
"pmullw %%mm1, %%mm0 \n\t" // (s - dx) * (s - dy)
|
||||
"pmullw %%mm5, %%mm3 \n\t" // dx * dy
|
||||
"pmullw %%mm5, %%mm2 \n\t" // (s - dx) * dy
|
||||
"pmullw %%mm4, %%mm1 \n\t" // dx * (s - dy)
|
||||
|
||||
"movd %4, %%mm5 \n\t"
|
||||
"movd %3, %%mm4 \n\t"
|
||||
"punpcklbw %%mm7, %%mm5 \n\t"
|
||||
"punpcklbw %%mm7, %%mm4 \n\t"
|
||||
"pmullw %%mm5, %%mm3 \n\t" // src[1, 1] * dx * dy
|
||||
"pmullw %%mm4, %%mm2 \n\t" // src[0, 1] * (s - dx) * dy
|
||||
|
||||
"movd %2, %%mm5 \n\t"
|
||||
"movd %1, %%mm4 \n\t"
|
||||
"punpcklbw %%mm7, %%mm5 \n\t"
|
||||
"punpcklbw %%mm7, %%mm4 \n\t"
|
||||
"pmullw %%mm5, %%mm1 \n\t" // src[1, 0] * dx * (s - dy)
|
||||
"pmullw %%mm4, %%mm0 \n\t" // src[0, 0] * (s - dx) * (s - dy)
|
||||
"paddw %5, %%mm1 \n\t"
|
||||
"paddw %%mm3, %%mm2 \n\t"
|
||||
"paddw %%mm1, %%mm0 \n\t"
|
||||
"paddw %%mm2, %%mm0 \n\t"
|
||||
|
||||
"psrlw %6, %%mm0 \n\t"
|
||||
"packuswb %%mm0, %%mm0 \n\t"
|
||||
"movd %%mm0, %0 \n\t"
|
||||
|
||||
: "=m"(dst[x + y * stride])
|
||||
: "m"(src[0]), "m"(src[1]),
|
||||
"m"(src[stride]), "m"(src[stride + 1]),
|
||||
"m"(*r4), "m"(shift2)
|
||||
);
|
||||
src += stride;
|
||||
}
|
||||
src += 4 - h * stride;
|
||||
}
|
||||
}
|
||||
|
||||
#if CONFIG_VIDEODSP
|
||||
#if HAVE_YASM
|
||||
#if ARCH_X86_32
|
||||
void ff_gmc_mmx(uint8_t *dst, uint8_t *src,
|
||||
int stride, int h, int ox, int oy,
|
||||
int dxx, int dxy, int dyx, int dyy,
|
||||
int shift, int r, int width, int height)
|
||||
{
|
||||
gmc(dst, src, stride, h, ox, oy, dxx, dxy, dyx, dyy, shift, r,
|
||||
width, height, &ff_emulated_edge_mc_8);
|
||||
}
|
||||
#endif
|
||||
void ff_gmc_sse(uint8_t *dst, uint8_t *src,
|
||||
int stride, int h, int ox, int oy,
|
||||
int dxx, int dxy, int dyx, int dyy,
|
||||
int shift, int r, int width, int height)
|
||||
{
|
||||
gmc(dst, src, stride, h, ox, oy, dxx, dxy, dyx, dyy, shift, r,
|
||||
width, height, &ff_emulated_edge_mc_8);
|
||||
}
|
||||
#else
|
||||
void ff_gmc_mmx(uint8_t *dst, uint8_t *src,
|
||||
int stride, int h, int ox, int oy,
|
||||
int dxx, int dxy, int dyx, int dyy,
|
||||
int shift, int r, int width, int height)
|
||||
{
|
||||
gmc(dst, src, stride, h, ox, oy, dxx, dxy, dyx, dyy, shift, r,
|
||||
width, height, &ff_emulated_edge_mc_8);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if CONFIG_DIRAC_DECODER
|
||||
#define DIRAC_PIXOP(OPNAME2, OPNAME, EXT)\
|
||||
void ff_ ## OPNAME2 ## _dirac_pixels8_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h)\
|
||||
{\
|
||||
if (h&3)\
|
||||
ff_ ## OPNAME2 ## _dirac_pixels8_c(dst, src, stride, h);\
|
||||
else\
|
||||
OPNAME ## _pixels8_ ## EXT(dst, src[0], stride, h);\
|
||||
}\
|
||||
void ff_ ## OPNAME2 ## _dirac_pixels16_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h)\
|
||||
{\
|
||||
if (h&3)\
|
||||
ff_ ## OPNAME2 ## _dirac_pixels16_c(dst, src, stride, h);\
|
||||
else\
|
||||
OPNAME ## _pixels16_ ## EXT(dst, src[0], stride, h);\
|
||||
}\
|
||||
void ff_ ## OPNAME2 ## _dirac_pixels32_ ## EXT(uint8_t *dst, const uint8_t *src[5], int stride, int h)\
|
||||
{\
|
||||
if (h&3) {\
|
||||
ff_ ## OPNAME2 ## _dirac_pixels32_c(dst, src, stride, h);\
|
||||
} else {\
|
||||
OPNAME ## _pixels16_ ## EXT(dst , src[0] , stride, h);\
|
||||
OPNAME ## _pixels16_ ## EXT(dst+16, src[0]+16, stride, h);\
|
||||
}\
|
||||
}
|
||||
|
||||
#if HAVE_MMX_INLINE
|
||||
PIXELS16(static, ff_avg, , , _mmxext)
|
||||
DIRAC_PIXOP(put, ff_put, mmx)
|
||||
DIRAC_PIXOP(avg, ff_avg, mmx)
|
||||
#endif
|
||||
|
||||
#if HAVE_YASM
|
||||
DIRAC_PIXOP(avg, ff_avg, mmxext)
|
||||
|
||||
void ff_put_dirac_pixels16_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h)
|
||||
{
|
||||
if (h&3)
|
||||
ff_put_dirac_pixels16_c(dst, src, stride, h);
|
||||
else
|
||||
ff_put_pixels16_sse2(dst, src[0], stride, h);
|
||||
}
|
||||
void ff_avg_dirac_pixels16_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h)
|
||||
{
|
||||
if (h&3)
|
||||
ff_avg_dirac_pixels16_c(dst, src, stride, h);
|
||||
else
|
||||
ff_avg_pixels16_sse2(dst, src[0], stride, h);
|
||||
}
|
||||
void ff_put_dirac_pixels32_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h)
|
||||
{
|
||||
if (h&3) {
|
||||
ff_put_dirac_pixels32_c(dst, src, stride, h);
|
||||
} else {
|
||||
ff_put_pixels16_sse2(dst , src[0] , stride, h);
|
||||
ff_put_pixels16_sse2(dst+16, src[0]+16, stride, h);
|
||||
}
|
||||
}
|
||||
void ff_avg_dirac_pixels32_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h)
|
||||
{
|
||||
if (h&3) {
|
||||
ff_avg_dirac_pixels32_c(dst, src, stride, h);
|
||||
} else {
|
||||
ff_avg_pixels16_sse2(dst , src[0] , stride, h);
|
||||
ff_avg_pixels16_sse2(dst+16, src[0]+16, stride, h);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void ff_vector_clipf_sse(float *dst, const float *src,
|
||||
float min, float max, int len)
|
||||
{
|
||||
x86_reg i = (len - 16) * 4;
|
||||
__asm__ volatile (
|
||||
"movss %3, %%xmm4 \n\t"
|
||||
"movss %4, %%xmm5 \n\t"
|
||||
"shufps $0, %%xmm4, %%xmm4 \n\t"
|
||||
"shufps $0, %%xmm5, %%xmm5 \n\t"
|
||||
"1: \n\t"
|
||||
"movaps (%2, %0), %%xmm0 \n\t" // 3/1 on intel
|
||||
"movaps 16(%2, %0), %%xmm1 \n\t"
|
||||
"movaps 32(%2, %0), %%xmm2 \n\t"
|
||||
"movaps 48(%2, %0), %%xmm3 \n\t"
|
||||
"maxps %%xmm4, %%xmm0 \n\t"
|
||||
"maxps %%xmm4, %%xmm1 \n\t"
|
||||
"maxps %%xmm4, %%xmm2 \n\t"
|
||||
"maxps %%xmm4, %%xmm3 \n\t"
|
||||
"minps %%xmm5, %%xmm0 \n\t"
|
||||
"minps %%xmm5, %%xmm1 \n\t"
|
||||
"minps %%xmm5, %%xmm2 \n\t"
|
||||
"minps %%xmm5, %%xmm3 \n\t"
|
||||
"movaps %%xmm0, (%1, %0) \n\t"
|
||||
"movaps %%xmm1, 16(%1, %0) \n\t"
|
||||
"movaps %%xmm2, 32(%1, %0) \n\t"
|
||||
"movaps %%xmm3, 48(%1, %0) \n\t"
|
||||
"sub $64, %0 \n\t"
|
||||
"jge 1b \n\t"
|
||||
: "+&r"(i)
|
||||
: "r"(dst), "r"(src), "m"(min), "m"(max)
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* HAVE_INLINE_ASM */
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* XVID MPEG-4 VIDEO CODEC
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* header for Xvid IDCT functions
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_X86_IDCT_XVID_H
|
||||
#define AVCODEC_X86_IDCT_XVID_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void ff_idct_xvid_mmx(short *block);
|
||||
void ff_idct_xvid_mmx_put(uint8_t *dest, int line_size, int16_t *block);
|
||||
void ff_idct_xvid_mmx_add(uint8_t *dest, int line_size, int16_t *block);
|
||||
|
||||
void ff_idct_xvid_mmxext(short *block);
|
||||
void ff_idct_xvid_mmxext_put(uint8_t *dest, int line_size, int16_t *block);
|
||||
void ff_idct_xvid_mmxext_add(uint8_t *dest, int line_size, int16_t *block);
|
||||
|
||||
void ff_idct_xvid_sse2(short *block);
|
||||
void ff_idct_xvid_sse2_put(uint8_t *dest, int line_size, short *block);
|
||||
void ff_idct_xvid_sse2_add(uint8_t *dest, int line_size, short *block);
|
||||
|
||||
#endif /* AVCODEC_X86_IDCT_XVID_H */
|
|
@ -0,0 +1,241 @@
|
|||
/*
|
||||
* APE tag handling
|
||||
* Copyright (c) 2007 Benjamin Zores <ben@geexbox.org>
|
||||
* based upon libdemac from Dave Chapman.
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "libavutil/intreadwrite.h"
|
||||
#include "libavutil/dict.h"
|
||||
#include "avformat.h"
|
||||
#include "avio_internal.h"
|
||||
#include "apetag.h"
|
||||
#include "internal.h"
|
||||
|
||||
#define APE_TAG_FLAG_CONTAINS_HEADER (1 << 31)
|
||||
#define APE_TAG_FLAG_CONTAINS_FOOTER (1 << 30)
|
||||
#define APE_TAG_FLAG_IS_HEADER (1 << 29)
|
||||
#define APE_TAG_FLAG_IS_BINARY (1 << 1)
|
||||
|
||||
static int ape_tag_read_field(AVFormatContext *s)
|
||||
{
|
||||
AVIOContext *pb = s->pb;
|
||||
uint8_t key[1024], *value;
|
||||
uint32_t size, flags;
|
||||
int i, c;
|
||||
|
||||
size = avio_rl32(pb); /* field size */
|
||||
flags = avio_rl32(pb); /* field flags */
|
||||
for (i = 0; i < sizeof(key) - 1; i++) {
|
||||
c = avio_r8(pb);
|
||||
if (c < 0x20 || c > 0x7E)
|
||||
break;
|
||||
else
|
||||
key[i] = c;
|
||||
}
|
||||
key[i] = 0;
|
||||
if (c != 0) {
|
||||
av_log(s, AV_LOG_WARNING, "Invalid APE tag key '%s'.\n", key);
|
||||
return -1;
|
||||
}
|
||||
if (size >= UINT_MAX)
|
||||
return -1;
|
||||
if (flags & APE_TAG_FLAG_IS_BINARY) {
|
||||
uint8_t filename[1024];
|
||||
enum AVCodecID id;
|
||||
AVStream *st = avformat_new_stream(s, NULL);
|
||||
if (!st)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
size -= avio_get_str(pb, size, filename, sizeof(filename));
|
||||
if (size <= 0) {
|
||||
av_log(s, AV_LOG_WARNING, "Skipping binary tag '%s'.\n", key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
av_dict_set(&st->metadata, key, filename, 0);
|
||||
|
||||
if ((id = ff_guess_image2_codec(filename)) != AV_CODEC_ID_NONE) {
|
||||
AVPacket pkt;
|
||||
int ret;
|
||||
|
||||
ret = av_get_packet(s->pb, &pkt, size);
|
||||
if (ret < 0) {
|
||||
av_log(s, AV_LOG_ERROR, "Error reading cover art.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
|
||||
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
|
||||
st->codec->codec_id = id;
|
||||
|
||||
st->attached_pic = pkt;
|
||||
st->attached_pic.stream_index = st->index;
|
||||
st->attached_pic.flags |= AV_PKT_FLAG_KEY;
|
||||
} else {
|
||||
st->codec->extradata = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!st->codec->extradata)
|
||||
return AVERROR(ENOMEM);
|
||||
if (avio_read(pb, st->codec->extradata, size) != size) {
|
||||
av_freep(&st->codec->extradata);
|
||||
return AVERROR(EIO);
|
||||
}
|
||||
st->codec->extradata_size = size;
|
||||
st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT;
|
||||
}
|
||||
} else {
|
||||
value = av_malloc(size+1);
|
||||
if (!value)
|
||||
return AVERROR(ENOMEM);
|
||||
c = avio_read(pb, value, size);
|
||||
if (c < 0) {
|
||||
av_free(value);
|
||||
return c;
|
||||
}
|
||||
value[c] = 0;
|
||||
av_dict_set(&s->metadata, key, value, AV_DICT_DONT_STRDUP_VAL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t ff_ape_parse_tag(AVFormatContext *s)
|
||||
{
|
||||
AVIOContext *pb = s->pb;
|
||||
int64_t file_size = avio_size(pb);
|
||||
uint32_t val, fields, tag_bytes;
|
||||
uint8_t buf[8];
|
||||
int64_t tag_start;
|
||||
int i;
|
||||
|
||||
if (file_size < APE_TAG_FOOTER_BYTES)
|
||||
return 0;
|
||||
|
||||
avio_seek(pb, file_size - APE_TAG_FOOTER_BYTES, SEEK_SET);
|
||||
|
||||
avio_read(pb, buf, 8); /* APETAGEX */
|
||||
if (strncmp(buf, APE_TAG_PREAMBLE, 8)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
val = avio_rl32(pb); /* APE tag version */
|
||||
if (val > APE_TAG_VERSION) {
|
||||
av_log(s, AV_LOG_ERROR, "Unsupported tag version. (>=%d)\n", APE_TAG_VERSION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
tag_bytes = avio_rl32(pb); /* tag size */
|
||||
if (tag_bytes - APE_TAG_FOOTER_BYTES > (1024 * 1024 * 16)) {
|
||||
av_log(s, AV_LOG_ERROR, "Tag size is way too big\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (tag_bytes > file_size - APE_TAG_FOOTER_BYTES) {
|
||||
av_log(s, AV_LOG_ERROR, "Invalid tag size %u.\n", tag_bytes);
|
||||
return 0;
|
||||
}
|
||||
tag_start = file_size - tag_bytes - APE_TAG_FOOTER_BYTES;
|
||||
|
||||
fields = avio_rl32(pb); /* number of fields */
|
||||
if (fields > 65536) {
|
||||
av_log(s, AV_LOG_ERROR, "Too many tag fields (%d)\n", fields);
|
||||
return 0;
|
||||
}
|
||||
|
||||
val = avio_rl32(pb); /* flags */
|
||||
if (val & APE_TAG_FLAG_IS_HEADER) {
|
||||
av_log(s, AV_LOG_ERROR, "APE Tag is a header\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
avio_seek(pb, file_size - tag_bytes, SEEK_SET);
|
||||
|
||||
for (i=0; i<fields; i++)
|
||||
if (ape_tag_read_field(s) < 0) break;
|
||||
|
||||
return tag_start;
|
||||
}
|
||||
|
||||
static int string_is_ascii(const uint8_t *str)
|
||||
{
|
||||
while (*str && *str >= 0x20 && *str <= 0x7e ) str++;
|
||||
return !*str;
|
||||
}
|
||||
|
||||
int ff_ape_write_tag(AVFormatContext *s)
|
||||
{
|
||||
AVDictionaryEntry *e = NULL;
|
||||
int size, ret, count = 0;
|
||||
AVIOContext *dyn_bc = NULL;
|
||||
uint8_t *dyn_buf = NULL;
|
||||
|
||||
if ((ret = avio_open_dyn_buf(&dyn_bc)) < 0)
|
||||
goto end;
|
||||
|
||||
// flags
|
||||
avio_wl32(dyn_bc, APE_TAG_FLAG_CONTAINS_HEADER | APE_TAG_FLAG_CONTAINS_FOOTER |
|
||||
APE_TAG_FLAG_IS_HEADER);
|
||||
ffio_fill(dyn_bc, 0, 8); // reserved
|
||||
|
||||
while ((e = av_dict_get(s->metadata, "", e, AV_DICT_IGNORE_SUFFIX))) {
|
||||
int val_len;
|
||||
|
||||
if (!string_is_ascii(e->key)) {
|
||||
av_log(s, AV_LOG_WARNING, "Non ASCII keys are not allowed\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
val_len = strlen(e->value);
|
||||
avio_wl32(dyn_bc, val_len); // value length
|
||||
avio_wl32(dyn_bc, 0); // item flags
|
||||
avio_put_str(dyn_bc, e->key); // key
|
||||
avio_write(dyn_bc, e->value, val_len); // value
|
||||
count++;
|
||||
}
|
||||
if (!count)
|
||||
goto end;
|
||||
|
||||
size = avio_close_dyn_buf(dyn_bc, &dyn_buf);
|
||||
if (size <= 0)
|
||||
goto end;
|
||||
size += 20;
|
||||
|
||||
// header
|
||||
avio_write(s->pb, "APETAGEX", 8); // id
|
||||
avio_wl32(s->pb, APE_TAG_VERSION); // version
|
||||
avio_wl32(s->pb, size);
|
||||
avio_wl32(s->pb, count);
|
||||
|
||||
avio_write(s->pb, dyn_buf, size - 20);
|
||||
|
||||
// footer
|
||||
avio_write(s->pb, "APETAGEX", 8); // id
|
||||
avio_wl32(s->pb, APE_TAG_VERSION); // version
|
||||
avio_wl32(s->pb, size); // size
|
||||
avio_wl32(s->pb, count); // tag count
|
||||
|
||||
// flags
|
||||
avio_wl32(s->pb, APE_TAG_FLAG_CONTAINS_HEADER | APE_TAG_FLAG_CONTAINS_FOOTER);
|
||||
ffio_fill(s->pb, 0, 8); // reserved
|
||||
|
||||
end:
|
||||
if (dyn_bc && !dyn_buf)
|
||||
avio_close_dyn_buf(dyn_bc, &dyn_buf);
|
||||
av_freep(&dyn_buf);
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* APE tag handling
|
||||
* Copyright (c) 2007 Benjamin Zores <ben@geexbox.org>
|
||||
* based upon libdemac from Dave Chapman.
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVFORMAT_APETAG_H
|
||||
#define AVFORMAT_APETAG_H
|
||||
|
||||
#include "avformat.h"
|
||||
|
||||
#define APE_TAG_PREAMBLE "APETAGEX"
|
||||
#define APE_TAG_VERSION 2000
|
||||
#define APE_TAG_FOOTER_BYTES 32
|
||||
|
||||
/**
|
||||
* Read and parse an APE tag
|
||||
*
|
||||
* @return offset of the tag start in the file
|
||||
*/
|
||||
int64_t ff_ape_parse_tag(AVFormatContext *s);
|
||||
|
||||
/**
|
||||
* Write an APE tag into a file.
|
||||
*/
|
||||
int ff_ape_write_tag(AVFormatContext *s);
|
||||
|
||||
#endif /* AVFORMAT_APETAG_H */
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Image format
|
||||
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
|
||||
* Copyright (c) 2004 Michael Niedermayer
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "libavutil/avstring.h"
|
||||
#include "internal.h"
|
||||
|
||||
typedef struct {
|
||||
enum AVCodecID id;
|
||||
const char *str;
|
||||
} IdStrMap;
|
||||
|
||||
static const IdStrMap img_tags[] = {
|
||||
{ AV_CODEC_ID_MJPEG, "jpeg" },
|
||||
{ AV_CODEC_ID_MJPEG, "jpg" },
|
||||
{ AV_CODEC_ID_MJPEG, "jps" },
|
||||
{ AV_CODEC_ID_LJPEG, "ljpg" },
|
||||
{ AV_CODEC_ID_JPEGLS, "jls" },
|
||||
{ AV_CODEC_ID_PNG, "png" },
|
||||
{ AV_CODEC_ID_PNG, "pns" },
|
||||
{ AV_CODEC_ID_PNG, "mng" },
|
||||
{ AV_CODEC_ID_PPM, "ppm" },
|
||||
{ AV_CODEC_ID_PPM, "pnm" },
|
||||
{ AV_CODEC_ID_PGM, "pgm" },
|
||||
{ AV_CODEC_ID_PGMYUV, "pgmyuv" },
|
||||
{ AV_CODEC_ID_PBM, "pbm" },
|
||||
{ AV_CODEC_ID_PAM, "pam" },
|
||||
{ AV_CODEC_ID_MPEG1VIDEO, "mpg1-img" },
|
||||
{ AV_CODEC_ID_MPEG2VIDEO, "mpg2-img" },
|
||||
{ AV_CODEC_ID_MPEG4, "mpg4-img" },
|
||||
{ AV_CODEC_ID_FFV1, "ffv1-img" },
|
||||
{ AV_CODEC_ID_RAWVIDEO, "y" },
|
||||
{ AV_CODEC_ID_RAWVIDEO, "raw" },
|
||||
{ AV_CODEC_ID_BMP, "bmp" },
|
||||
{ AV_CODEC_ID_TARGA, "tga" },
|
||||
{ AV_CODEC_ID_TIFF, "tiff" },
|
||||
{ AV_CODEC_ID_TIFF, "tif" },
|
||||
{ AV_CODEC_ID_SGI, "sgi" },
|
||||
{ AV_CODEC_ID_PTX, "ptx" },
|
||||
{ AV_CODEC_ID_PCX, "pcx" },
|
||||
{ AV_CODEC_ID_BRENDER_PIX, "pix" },
|
||||
{ AV_CODEC_ID_SUNRAST, "sun" },
|
||||
{ AV_CODEC_ID_SUNRAST, "ras" },
|
||||
{ AV_CODEC_ID_SUNRAST, "rs" },
|
||||
{ AV_CODEC_ID_SUNRAST, "im1" },
|
||||
{ AV_CODEC_ID_SUNRAST, "im8" },
|
||||
{ AV_CODEC_ID_SUNRAST, "im24" },
|
||||
{ AV_CODEC_ID_SUNRAST, "im32" },
|
||||
{ AV_CODEC_ID_SUNRAST, "sunras" },
|
||||
{ AV_CODEC_ID_JPEG2000, "j2c" },
|
||||
{ AV_CODEC_ID_JPEG2000, "jp2" },
|
||||
{ AV_CODEC_ID_JPEG2000, "jpc" },
|
||||
{ AV_CODEC_ID_JPEG2000, "j2k" },
|
||||
{ AV_CODEC_ID_DPX, "dpx" },
|
||||
{ AV_CODEC_ID_EXR, "exr" },
|
||||
{ AV_CODEC_ID_PICTOR, "pic" },
|
||||
{ AV_CODEC_ID_V210X, "yuv10" },
|
||||
{ AV_CODEC_ID_WEBP, "webp" },
|
||||
{ AV_CODEC_ID_XBM, "xbm" },
|
||||
{ AV_CODEC_ID_XFACE, "xface" },
|
||||
{ AV_CODEC_ID_XWD, "xwd" },
|
||||
{ AV_CODEC_ID_NONE, NULL }
|
||||
};
|
||||
|
||||
static enum AVCodecID av_str2id(const IdStrMap *tags, const char *str)
|
||||
{
|
||||
str = strrchr(str, '.');
|
||||
if (!str)
|
||||
return AV_CODEC_ID_NONE;
|
||||
str++;
|
||||
|
||||
while (tags->id) {
|
||||
if (!av_strcasecmp(str, tags->str))
|
||||
return tags->id;
|
||||
|
||||
tags++;
|
||||
}
|
||||
return AV_CODEC_ID_NONE;
|
||||
}
|
||||
|
||||
enum AVCodecID ff_guess_image2_codec(const char *filename)
|
||||
{
|
||||
return av_str2id(img_tags, filename);
|
||||
}
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* RAW demuxers
|
||||
* Copyright (c) 2001 Fabrice Bellard
|
||||
* Copyright (c) 2005 Alex Beregszaszi
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "avformat.h"
|
||||
#include "internal.h"
|
||||
#include "avio_internal.h"
|
||||
#include "rawdec.h"
|
||||
#include "libavutil/opt.h"
|
||||
#include "libavutil/parseutils.h"
|
||||
#include "libavutil/pixdesc.h"
|
||||
#include "libavutil/avassert.h"
|
||||
|
||||
#define RAW_PACKET_SIZE 1024
|
||||
|
||||
int ff_raw_read_partial_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
{
|
||||
int ret, size;
|
||||
|
||||
size = RAW_PACKET_SIZE;
|
||||
|
||||
if (av_new_packet(pkt, size) < 0)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
pkt->pos= avio_tell(s->pb);
|
||||
pkt->stream_index = 0;
|
||||
ret = ffio_read_partial(s->pb, pkt->data, size);
|
||||
if (ret < 0) {
|
||||
av_free_packet(pkt);
|
||||
return ret;
|
||||
}
|
||||
av_shrink_packet(pkt, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ff_raw_audio_read_header(AVFormatContext *s)
|
||||
{
|
||||
AVStream *st = avformat_new_stream(s, NULL);
|
||||
if (!st)
|
||||
return AVERROR(ENOMEM);
|
||||
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
|
||||
st->codec->codec_id = s->iformat->raw_codec_id;
|
||||
st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
|
||||
st->start_time = 0;
|
||||
/* the parameters will be extracted from the compressed bitstream */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* MPEG-1/H.263 input */
|
||||
int ff_raw_video_read_header(AVFormatContext *s)
|
||||
{
|
||||
AVStream *st;
|
||||
FFRawVideoDemuxerContext *s1 = s->priv_data;
|
||||
int ret = 0;
|
||||
|
||||
|
||||
st = avformat_new_stream(s, NULL);
|
||||
if (!st) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
|
||||
st->codec->codec_id = s->iformat->raw_codec_id;
|
||||
st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
|
||||
|
||||
st->codec->time_base = av_inv_q(s1->framerate);
|
||||
avpriv_set_pts_info(st, 64, 1, 1200000);
|
||||
|
||||
fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ff_raw_data_read_header(AVFormatContext *s)
|
||||
{
|
||||
AVStream *st = avformat_new_stream(s, NULL);
|
||||
if (!st)
|
||||
return AVERROR(ENOMEM);
|
||||
st->codec->codec_type = AVMEDIA_TYPE_DATA;
|
||||
st->codec->codec_id = s->iformat->raw_codec_id;
|
||||
st->start_time = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Note: Do not forget to add new entries to the Makefile as well. */
|
||||
|
||||
#define OFFSET(x) offsetof(FFRawVideoDemuxerContext, x)
|
||||
#define DEC AV_OPT_FLAG_DECODING_PARAM
|
||||
const AVOption ff_rawvideo_options[] = {
|
||||
{ "framerate", "", OFFSET(framerate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0, DEC},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
#if CONFIG_DATA_DEMUXER
|
||||
AVInputFormat ff_data_demuxer = {
|
||||
.name = "data",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("raw data"),
|
||||
.read_header = ff_raw_data_read_header,
|
||||
.read_packet = ff_raw_read_partial_packet,
|
||||
.raw_codec_id = AV_CODEC_ID_NONE,
|
||||
};
|
||||
#endif
|
||||
|
||||
#if CONFIG_LATM_DEMUXER
|
||||
AVInputFormat ff_latm_demuxer = {
|
||||
.name = "latm",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("raw LOAS/LATM"),
|
||||
.read_header = ff_raw_audio_read_header,
|
||||
.read_packet = ff_raw_read_partial_packet,
|
||||
.flags = AVFMT_GENERIC_INDEX,
|
||||
.extensions = "latm",
|
||||
.raw_codec_id = AV_CODEC_ID_AAC_LATM,
|
||||
};
|
||||
#endif
|
||||
|
||||
#if CONFIG_MJPEG_DEMUXER
|
||||
FF_DEF_RAWVIDEO_DEMUXER(mjpeg, "raw MJPEG video", NULL, "mjpg,mjpeg,mpo", AV_CODEC_ID_MJPEG)
|
||||
#endif
|
||||
|
||||
#if CONFIG_MLP_DEMUXER
|
||||
AVInputFormat ff_mlp_demuxer = {
|
||||
.name = "mlp",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("raw MLP"),
|
||||
.read_header = ff_raw_audio_read_header,
|
||||
.read_packet = ff_raw_read_partial_packet,
|
||||
.flags = AVFMT_GENERIC_INDEX,
|
||||
.extensions = "mlp",
|
||||
.raw_codec_id = AV_CODEC_ID_MLP,
|
||||
};
|
||||
#endif
|
||||
|
||||
#if CONFIG_TRUEHD_DEMUXER
|
||||
AVInputFormat ff_truehd_demuxer = {
|
||||
.name = "truehd",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("raw TrueHD"),
|
||||
.read_header = ff_raw_audio_read_header,
|
||||
.read_packet = ff_raw_read_partial_packet,
|
||||
.flags = AVFMT_GENERIC_INDEX,
|
||||
.extensions = "thd",
|
||||
.raw_codec_id = AV_CODEC_ID_TRUEHD,
|
||||
};
|
||||
#endif
|
||||
|
||||
#if CONFIG_SHORTEN_DEMUXER
|
||||
AVInputFormat ff_shorten_demuxer = {
|
||||
.name = "shn",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("raw Shorten"),
|
||||
.read_header = ff_raw_audio_read_header,
|
||||
.read_packet = ff_raw_read_partial_packet,
|
||||
.flags = AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK,
|
||||
.extensions = "shn",
|
||||
.raw_codec_id = AV_CODEC_ID_SHORTEN,
|
||||
};
|
||||
#endif
|
||||
|
||||
#if CONFIG_VC1_DEMUXER
|
||||
FF_DEF_RAWVIDEO_DEMUXER(vc1, "raw VC-1", NULL, "vc1", AV_CODEC_ID_VC1)
|
||||
#endif
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* RAW demuxers
|
||||
* Copyright (C) 2007 Aurelien Jacobs <aurel@gnuage.org>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVFORMAT_RAWDEC_H
|
||||
#define AVFORMAT_RAWDEC_H
|
||||
|
||||
#include "avformat.h"
|
||||
#include "libavutil/log.h"
|
||||
#include "libavutil/opt.h"
|
||||
|
||||
typedef struct FFRawVideoDemuxerContext {
|
||||
const AVClass *class; /**< Class for private options. */
|
||||
char *video_size; /**< String describing video size, set by a private option. */
|
||||
char *pixel_format; /**< Set by a private option. */
|
||||
AVRational framerate; /**< AVRational describing framerate, set by a private option. */
|
||||
} FFRawVideoDemuxerContext;
|
||||
|
||||
extern const AVOption ff_rawvideo_options[];
|
||||
|
||||
int ff_raw_read_partial_packet(AVFormatContext *s, AVPacket *pkt);
|
||||
|
||||
int ff_raw_audio_read_header(AVFormatContext *s);
|
||||
|
||||
int ff_raw_video_read_header(AVFormatContext *s);
|
||||
|
||||
#define FF_RAWVIDEO_DEMUXER_CLASS(name)\
|
||||
static const AVClass name ## _demuxer_class = {\
|
||||
.class_name = #name " demuxer",\
|
||||
.item_name = av_default_item_name,\
|
||||
.option = ff_rawvideo_options,\
|
||||
.version = LIBAVUTIL_VERSION_INT,\
|
||||
};
|
||||
|
||||
#define FF_DEF_RAWVIDEO_DEMUXER(shortname, longname, probe, ext, id)\
|
||||
FF_RAWVIDEO_DEMUXER_CLASS(shortname)\
|
||||
AVInputFormat ff_ ## shortname ## _demuxer = {\
|
||||
.name = #shortname,\
|
||||
.long_name = NULL_IF_CONFIG_SMALL(longname),\
|
||||
.read_probe = probe,\
|
||||
.read_header = ff_raw_video_read_header,\
|
||||
.read_packet = ff_raw_read_partial_packet,\
|
||||
.extensions = ext,\
|
||||
.flags = AVFMT_GENERIC_INDEX,\
|
||||
.raw_codec_id = id,\
|
||||
.priv_data_size = sizeof(FFRawVideoDemuxerContext),\
|
||||
.priv_class = &shortname ## _demuxer_class,\
|
||||
};
|
||||
|
||||
#endif /* AVFORMAT_RAWDEC_H */
|
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* Raw TAK demuxer
|
||||
* Copyright (c) 2012 Paul B Mahol
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "libavutil/crc.h"
|
||||
#include "libavcodec/tak.h"
|
||||
#include "avformat.h"
|
||||
#include "avio_internal.h"
|
||||
#include "internal.h"
|
||||
#include "rawdec.h"
|
||||
#include "apetag.h"
|
||||
|
||||
typedef struct TAKDemuxContext {
|
||||
int mlast_frame;
|
||||
int64_t data_end;
|
||||
} TAKDemuxContext;
|
||||
|
||||
static int tak_probe(AVProbeData *p)
|
||||
{
|
||||
if (!memcmp(p->buf, "tBaK", 4))
|
||||
return AVPROBE_SCORE_EXTENSION;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long tak_check_crc(unsigned long checksum, const uint8_t *buf,
|
||||
unsigned int len)
|
||||
{
|
||||
return av_crc(av_crc_get_table(AV_CRC_24_IEEE), checksum, buf, len);
|
||||
}
|
||||
|
||||
static int tak_read_header(AVFormatContext *s)
|
||||
{
|
||||
TAKDemuxContext *tc = s->priv_data;
|
||||
AVIOContext *pb = s->pb;
|
||||
GetBitContext gb;
|
||||
AVStream *st;
|
||||
uint8_t *buffer = NULL;
|
||||
int ret;
|
||||
|
||||
st = avformat_new_stream(s, 0);
|
||||
if (!st)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
|
||||
st->codec->codec_id = AV_CODEC_ID_TAK;
|
||||
st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
|
||||
|
||||
tc->mlast_frame = 0;
|
||||
if (avio_rl32(pb) != MKTAG('t', 'B', 'a', 'K')) {
|
||||
avio_seek(pb, -4, SEEK_CUR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (!url_feof(pb)) {
|
||||
enum TAKMetaDataType type;
|
||||
int size;
|
||||
|
||||
type = avio_r8(pb) & 0x7f;
|
||||
size = avio_rl24(pb);
|
||||
|
||||
switch (type) {
|
||||
case TAK_METADATA_STREAMINFO:
|
||||
case TAK_METADATA_LAST_FRAME:
|
||||
case TAK_METADATA_ENCODER:
|
||||
if (size <= 3)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
buffer = av_malloc(size - 3 + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!buffer)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
ffio_init_checksum(pb, tak_check_crc, 0xCE04B7U);
|
||||
if (avio_read(pb, buffer, size - 3) != size - 3) {
|
||||
av_freep(&buffer);
|
||||
return AVERROR(EIO);
|
||||
}
|
||||
if (ffio_get_checksum(s->pb) != avio_rb24(pb)) {
|
||||
av_log(s, AV_LOG_ERROR, "%d metadata block CRC error.\n", type);
|
||||
if (s->error_recognition & AV_EF_EXPLODE) {
|
||||
av_freep(&buffer);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
}
|
||||
|
||||
init_get_bits8(&gb, buffer, size - 3);
|
||||
break;
|
||||
case TAK_METADATA_MD5: {
|
||||
uint8_t md5[16];
|
||||
int i;
|
||||
|
||||
if (size != 19)
|
||||
return AVERROR_INVALIDDATA;
|
||||
ffio_init_checksum(pb, tak_check_crc, 0xCE04B7U);
|
||||
avio_read(pb, md5, 16);
|
||||
if (ffio_get_checksum(s->pb) != avio_rb24(pb)) {
|
||||
av_log(s, AV_LOG_ERROR, "MD5 metadata block CRC error.\n");
|
||||
if (s->error_recognition & AV_EF_EXPLODE)
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
av_log(s, AV_LOG_VERBOSE, "MD5=");
|
||||
for (i = 0; i < 16; i++)
|
||||
av_log(s, AV_LOG_VERBOSE, "%02x", md5[i]);
|
||||
av_log(s, AV_LOG_VERBOSE, "\n");
|
||||
break;
|
||||
}
|
||||
case TAK_METADATA_END: {
|
||||
int64_t curpos = avio_tell(pb);
|
||||
|
||||
if (pb->seekable) {
|
||||
ff_ape_parse_tag(s);
|
||||
avio_seek(pb, curpos, SEEK_SET);
|
||||
}
|
||||
|
||||
tc->data_end += curpos;
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
ret = avio_skip(pb, size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (type == TAK_METADATA_STREAMINFO) {
|
||||
TAKStreamInfo ti;
|
||||
|
||||
avpriv_tak_parse_streaminfo(&gb, &ti);
|
||||
if (ti.samples > 0)
|
||||
st->duration = ti.samples;
|
||||
st->codec->bits_per_coded_sample = ti.bps;
|
||||
if (ti.ch_layout)
|
||||
st->codec->channel_layout = ti.ch_layout;
|
||||
st->codec->sample_rate = ti.sample_rate;
|
||||
st->codec->channels = ti.channels;
|
||||
st->start_time = 0;
|
||||
avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
|
||||
st->codec->extradata = buffer;
|
||||
st->codec->extradata_size = size - 3;
|
||||
buffer = NULL;
|
||||
} else if (type == TAK_METADATA_LAST_FRAME) {
|
||||
if (size != 11)
|
||||
return AVERROR_INVALIDDATA;
|
||||
tc->mlast_frame = 1;
|
||||
tc->data_end = get_bits64(&gb, TAK_LAST_FRAME_POS_BITS) +
|
||||
get_bits(&gb, TAK_LAST_FRAME_SIZE_BITS);
|
||||
av_freep(&buffer);
|
||||
} else if (type == TAK_METADATA_ENCODER) {
|
||||
av_log(s, AV_LOG_VERBOSE, "encoder version: %0X\n",
|
||||
get_bits_long(&gb, TAK_ENCODER_VERSION_BITS));
|
||||
av_freep(&buffer);
|
||||
}
|
||||
}
|
||||
|
||||
return AVERROR_EOF;
|
||||
}
|
||||
|
||||
static int raw_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
{
|
||||
TAKDemuxContext *tc = s->priv_data;
|
||||
int ret;
|
||||
|
||||
if (tc->mlast_frame) {
|
||||
AVIOContext *pb = s->pb;
|
||||
int64_t size, left;
|
||||
|
||||
left = tc->data_end - avio_tell(pb);
|
||||
size = FFMIN(left, 1024);
|
||||
if (size <= 0)
|
||||
return AVERROR_EOF;
|
||||
|
||||
ret = av_get_packet(pb, pkt, size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
pkt->stream_index = 0;
|
||||
} else {
|
||||
ret = ff_raw_read_partial_packet(s, pkt);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AVInputFormat ff_tak_demuxer = {
|
||||
.name = "tak",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("raw TAK"),
|
||||
.priv_data_size = sizeof(TAKDemuxContext),
|
||||
.read_probe = tak_probe,
|
||||
.read_header = tak_read_header,
|
||||
.read_packet = raw_read_packet,
|
||||
.flags = AVFMT_GENERIC_INDEX,
|
||||
.extensions = "tak",
|
||||
.raw_codec_id = AV_CODEC_ID_TAK,
|
||||
};
|
|
@ -138,6 +138,7 @@ StringList FileRef::defaultFileExtensions()
|
|||
l.append("asf");
|
||||
l.append("ape");
|
||||
l.append("opus");
|
||||
l.append("tak");
|
||||
|
||||
return l;
|
||||
}
|
||||
|
@ -233,6 +234,8 @@ File *FileRef::create(FileName fileName, bool readAudioProperties,
|
|||
return new ASF::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "APE")
|
||||
return new APE::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "TAK")
|
||||
return new APE::File(fileName, false, audioPropertiesStyle);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -293,12 +293,12 @@ int lockmgr_callback(void ** mutex, enum AVLockOp op)
|
|||
|
||||
+ (NSArray *)fileTypes
|
||||
{
|
||||
return [NSArray arrayWithObjects:@"wma", @"asf", @"xwma", nil];
|
||||
return [NSArray arrayWithObjects:@"wma", @"asf", @"xwma", @"tak", nil];
|
||||
}
|
||||
|
||||
+ (NSArray *)mimeTypes
|
||||
{
|
||||
return [NSArray arrayWithObjects:@"application/wma", @"application/x-wma", @"audio/x-wma", @"audio/x-ms-wma", nil];
|
||||
return [NSArray arrayWithObjects:@"application/wma", @"application/x-wma", @"audio/x-wma", @"audio/x-ms-wma", @"audio/x-tak", nil];
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -174,12 +174,12 @@
|
|||
+ (NSArray *)fileTypes
|
||||
{
|
||||
//May be a way to get a list of supported formats
|
||||
return [NSArray arrayWithObjects:@"ape", @"asf", @"wma", @"ogg", @"opus", @"mpc", @"flac", @"m4a", @"mp3", nil];
|
||||
return [NSArray arrayWithObjects:@"ape", @"asf", @"wma", @"ogg", @"opus", @"mpc", @"flac", @"m4a", @"mp3", @"tak", nil];
|
||||
}
|
||||
|
||||
+ (NSArray *)mimeTypes
|
||||
{
|
||||
return [NSArray arrayWithObjects:@"audio/x-ape", @"audio/x-ms-wma", @"application/ogg", @"application/x-ogg", @"audio/x-vorbis+ogg", @"audio/x-musepack", @"audio/x-flac", @"audio/x-m4a", @"audio/mpeg", @"audio/x-mp3", nil];
|
||||
return [NSArray arrayWithObjects:@"audio/x-ape", @"audio/x-ms-wma", @"application/ogg", @"application/x-ogg", @"audio/x-vorbis+ogg", @"audio/x-musepack", @"audio/x-flac", @"audio/x-m4a", @"audio/mpeg", @"audio/x-mp3", @"audio/x-tak", nil];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
Loading…
Reference in New Issue