diff --git a/Frameworks/FFMPEG/FFMPEG.xcodeproj/project.pbxproj b/Frameworks/FFMPEG/FFMPEG.xcodeproj/project.pbxproj index 71b614d0e..ebbeedcdb 100644 --- a/Frameworks/FFMPEG/FFMPEG.xcodeproj/project.pbxproj +++ b/Frameworks/FFMPEG/FFMPEG.xcodeproj/project.pbxproj @@ -222,7 +222,6 @@ 830F0D4917FC85ED00042E8F /* intmath.h in Headers */ = {isa = PBXBuildFile; fileRef = 830F0D4517FC85ED00042E8F /* intmath.h */; }; 830F0D4D17FC862400042E8F /* time.c in Sources */ = {isa = PBXBuildFile; fileRef = 830F0D4A17FC862300042E8F /* time.c */; }; 830F0D4F17FC862400042E8F /* utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 830F0D4C17FC862400042E8F /* utils.c */; }; - 830F0D5117FC880E00042E8F /* time_.h in Headers */ = {isa = PBXBuildFile; fileRef = 830F0D5017FC880E00042E8F /* time_.h */; }; 830F0D5317FC891800042E8F /* file_open.c in Sources */ = {isa = PBXBuildFile; fileRef = 830F0D5217FC891800042E8F /* file_open.c */; }; 830F0D5817FC893E00042E8F /* bitstream.c in Sources */ = {isa = PBXBuildFile; fileRef = 830F0D5417FC893E00042E8F /* bitstream.c */; }; 830F0D5917FC893E00042E8F /* codec_desc.c in Sources */ = {isa = PBXBuildFile; fileRef = 830F0D5517FC893E00042E8F /* codec_desc.c */; }; @@ -278,6 +277,22 @@ 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 */; }; + 832F4BA618CD4F47003E940E /* lls2.c in Sources */ = {isa = PBXBuildFile; fileRef = 832F4BA418CD4F47003E940E /* lls2.c */; }; + 832F4BA718CD4F47003E940E /* lls2.h in Headers */ = {isa = PBXBuildFile; fileRef = 832F4BA518CD4F47003E940E /* lls2.h */; }; + 832F4BAF18CD4F6B003E940E /* atrac3plus_data.h in Headers */ = {isa = PBXBuildFile; fileRef = 832F4BA918CD4F6B003E940E /* atrac3plus_data.h */; }; + 832F4BB018CD4F6B003E940E /* atrac3plus.c in Sources */ = {isa = PBXBuildFile; fileRef = 832F4BAA18CD4F6B003E940E /* atrac3plus.c */; }; + 832F4BB118CD4F6B003E940E /* atrac3plus.h in Headers */ = {isa = PBXBuildFile; fileRef = 832F4BAB18CD4F6B003E940E /* atrac3plus.h */; }; + 832F4BB218CD4F6B003E940E /* atrac3plusdec.c in Sources */ = {isa = PBXBuildFile; fileRef = 832F4BAC18CD4F6B003E940E /* atrac3plusdec.c */; }; + 832F4BB318CD4F6B003E940E /* atrac3plusdsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 832F4BAD18CD4F6B003E940E /* atrac3plusdsp.c */; }; + 832F4BB618CD4FEA003E940E /* macros.h in Headers */ = {isa = PBXBuildFile; fileRef = 832F4BB418CD4FEA003E940E /* macros.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 832F4BB718CD4FEA003E940E /* timestamp.h in Headers */ = {isa = PBXBuildFile; fileRef = 832F4BB518CD4FEA003E940E /* timestamp.h */; }; + 832F4BBA18CD53E9003E940E /* ttadsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 832F4BB818CD53E9003E940E /* ttadsp.c */; }; + 832F4BBB18CD53E9003E940E /* ttadsp.h in Headers */ = {isa = PBXBuildFile; fileRef = 832F4BB918CD53E9003E940E /* ttadsp.h */; }; + 832F4BC018CD5DD9003E940E /* downmix_info.c in Sources */ = {isa = PBXBuildFile; fileRef = 832F4BBE18CD5DD9003E940E /* downmix_info.c */; }; + 832F4BC118CD5DD9003E940E /* downmix_info.h in Headers */ = {isa = PBXBuildFile; fileRef = 832F4BBF18CD5DD9003E940E /* downmix_info.h */; }; + 832F4BC318CD5DE2003E940E /* time_.h in Headers */ = {isa = PBXBuildFile; fileRef = 832F4BC218CD5DE2003E940E /* time_.h */; }; + 832F4BC518CD601B003E940E /* ttadsp_init.c in Sources */ = {isa = PBXBuildFile; fileRef = 832F4BC418CD601B003E940E /* ttadsp_init.c */; }; + 832F4BC718CD6052003E940E /* dcadsp_init.c in Sources */ = {isa = PBXBuildFile; fileRef = 832F4BC618CD6052003E940E /* dcadsp_init.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 */; }; @@ -401,8 +416,6 @@ 838491021807CDC000E7332D /* lpc.c in Sources */ = {isa = PBXBuildFile; fileRef = 838491001807CDC000E7332D /* lpc.c */; }; 838491031807CDC000E7332D /* lpc.h in Headers */ = {isa = PBXBuildFile; fileRef = 838491011807CDC000E7332D /* lpc.h */; }; 838491051807CDEC00E7332D /* cbrt_tablegen.h in Headers */ = {isa = PBXBuildFile; fileRef = 838491041807CDEC00E7332D /* cbrt_tablegen.h */; }; - 838491081807CDF400E7332D /* lls.c in Sources */ = {isa = PBXBuildFile; fileRef = 838491061807CDF400E7332D /* lls.c */; }; - 838491091807CDF400E7332D /* lls.h in Headers */ = {isa = PBXBuildFile; fileRef = 838491071807CDF400E7332D /* lls.h */; }; 8384910B1807CE2A00E7332D /* lls_init.c in Sources */ = {isa = PBXBuildFile; fileRef = 8384910A1807CE2A00E7332D /* lls_init.c */; }; 8384910D1807CEB600E7332D /* sbrdsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 8384910C1807CEB600E7332D /* sbrdsp.c */; }; 8384910F1807CEC400E7332D /* lpc.c in Sources */ = {isa = PBXBuildFile; fileRef = 8384910E1807CEC400E7332D /* lpc.c */; }; @@ -430,7 +443,6 @@ 8393B80518052BC200913C76 /* mpegaudiodsp_data.c in Sources */ = {isa = PBXBuildFile; fileRef = 8393B7F118052BC200913C76 /* mpegaudiodsp_data.c */; }; 8393B80718052BC200913C76 /* mpegaudiodsp_float.c in Sources */ = {isa = PBXBuildFile; fileRef = 8393B7F318052BC200913C76 /* mpegaudiodsp_float.c */; }; 8393B80A18052BC200913C76 /* mpegaudiodsp.h in Headers */ = {isa = PBXBuildFile; fileRef = 8393B7F618052BC200913C76 /* mpegaudiodsp.h */; }; - 8393B80B18052BC200913C76 /* mpegaudioenc.c in Sources */ = {isa = PBXBuildFile; fileRef = 8393B7F718052BC200913C76 /* mpegaudioenc.c */; }; 8393B80C18052BC200913C76 /* mpegaudiotab.h in Headers */ = {isa = PBXBuildFile; fileRef = 8393B7F818052BC200913C76 /* mpegaudiotab.h */; }; 8393B80E18052BD500913C76 /* mpegaudiodsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 8393B80D18052BD500913C76 /* mpegaudiodsp.c */; }; 8393B81118052DB700913C76 /* bitstream_filter.c in Sources */ = {isa = PBXBuildFile; fileRef = 8393B80F18052DB700913C76 /* bitstream_filter.c */; }; @@ -665,7 +677,6 @@ 830F0D4517FC85ED00042E8F /* intmath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = intmath.h; sourceTree = ""; }; 830F0D4A17FC862300042E8F /* time.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = time.c; sourceTree = ""; }; 830F0D4C17FC862400042E8F /* utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = utils.c; sourceTree = ""; }; - 830F0D5017FC880E00042E8F /* time_.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = time_.h; sourceTree = ""; }; 830F0D5217FC891800042E8F /* file_open.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = file_open.c; sourceTree = ""; }; 830F0D5417FC893E00042E8F /* bitstream.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bitstream.c; sourceTree = ""; }; 830F0D5517FC893E00042E8F /* codec_desc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = codec_desc.c; sourceTree = ""; }; @@ -721,6 +732,22 @@ 830F0DCF17FC934D00042E8F /* spdif.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = spdif.c; sourceTree = ""; }; 830F0DD017FC934D00042E8F /* spdif.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = spdif.h; sourceTree = ""; }; 830F0DD417FC93E400042E8F /* xwma.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xwma.c; sourceTree = ""; }; + 832F4BA418CD4F47003E940E /* lls2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lls2.c; sourceTree = ""; }; + 832F4BA518CD4F47003E940E /* lls2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lls2.h; sourceTree = ""; }; + 832F4BA918CD4F6B003E940E /* atrac3plus_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = atrac3plus_data.h; sourceTree = ""; }; + 832F4BAA18CD4F6B003E940E /* atrac3plus.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = atrac3plus.c; sourceTree = ""; }; + 832F4BAB18CD4F6B003E940E /* atrac3plus.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = atrac3plus.h; sourceTree = ""; }; + 832F4BAC18CD4F6B003E940E /* atrac3plusdec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = atrac3plusdec.c; sourceTree = ""; }; + 832F4BAD18CD4F6B003E940E /* atrac3plusdsp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = atrac3plusdsp.c; sourceTree = ""; }; + 832F4BB418CD4FEA003E940E /* macros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = macros.h; sourceTree = ""; }; + 832F4BB518CD4FEA003E940E /* timestamp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = timestamp.h; sourceTree = ""; }; + 832F4BB818CD53E9003E940E /* ttadsp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttadsp.c; sourceTree = ""; }; + 832F4BB918CD53E9003E940E /* ttadsp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ttadsp.h; sourceTree = ""; }; + 832F4BBE18CD5DD9003E940E /* downmix_info.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = downmix_info.c; sourceTree = ""; }; + 832F4BBF18CD5DD9003E940E /* downmix_info.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = downmix_info.h; sourceTree = ""; }; + 832F4BC218CD5DE2003E940E /* time_.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = time_.h; sourceTree = ""; }; + 832F4BC418CD601B003E940E /* ttadsp_init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ttadsp_init.c; sourceTree = ""; }; + 832F4BC618CD6052003E940E /* dcadsp_init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dcadsp_init.c; sourceTree = ""; }; 833C3794180328A300CBA602 /* takdec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = takdec.c; sourceTree = ""; }; 833C3796180328B300CBA602 /* tak_parser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tak_parser.c; sourceTree = ""; }; 833C3797180328B300CBA602 /* tak.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tak.c; sourceTree = ""; }; @@ -844,8 +871,6 @@ 838491001807CDC000E7332D /* lpc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lpc.c; sourceTree = ""; }; 838491011807CDC000E7332D /* lpc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lpc.h; sourceTree = ""; }; 838491041807CDEC00E7332D /* cbrt_tablegen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cbrt_tablegen.h; sourceTree = ""; }; - 838491061807CDF400E7332D /* lls.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lls.c; sourceTree = ""; }; - 838491071807CDF400E7332D /* lls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lls.h; sourceTree = ""; }; 8384910A1807CE2A00E7332D /* lls_init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lls_init.c; sourceTree = ""; }; 8384910C1807CEB600E7332D /* sbrdsp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sbrdsp.c; sourceTree = ""; }; 8384910E1807CEC400E7332D /* lpc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lpc.c; sourceTree = ""; }; @@ -873,7 +898,6 @@ 8393B7F118052BC200913C76 /* mpegaudiodsp_data.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpegaudiodsp_data.c; sourceTree = ""; }; 8393B7F318052BC200913C76 /* mpegaudiodsp_float.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpegaudiodsp_float.c; sourceTree = ""; }; 8393B7F618052BC200913C76 /* mpegaudiodsp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mpegaudiodsp.h; sourceTree = ""; }; - 8393B7F718052BC200913C76 /* mpegaudioenc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpegaudioenc.c; sourceTree = ""; }; 8393B7F818052BC200913C76 /* mpegaudiotab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mpegaudiotab.h; sourceTree = ""; }; 8393B80D18052BD500913C76 /* mpegaudiodsp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpegaudiodsp.c; sourceTree = ""; }; 8393B80F18052DB700913C76 /* bitstream_filter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bitstream_filter.c; sourceTree = ""; }; @@ -967,6 +991,13 @@ 830F0B8E17FC4FB900042E8F /* libavcodec */ = { isa = PBXGroup; children = ( + 832F4BB818CD53E9003E940E /* ttadsp.c */, + 832F4BB918CD53E9003E940E /* ttadsp.h */, + 832F4BA918CD4F6B003E940E /* atrac3plus_data.h */, + 832F4BAA18CD4F6B003E940E /* atrac3plus.c */, + 832F4BAB18CD4F6B003E940E /* atrac3plus.h */, + 832F4BAC18CD4F6B003E940E /* atrac3plusdec.c */, + 832F4BAD18CD4F6B003E940E /* atrac3plusdsp.c */, 833E5F9D18A31EC4006A85F9 /* twinvq_data.h */, 833E5F9E18A31EC4006A85F9 /* twinvq.c */, 833E5F9F18A31EC4006A85F9 /* twinvq.h */, @@ -1074,7 +1105,6 @@ 8393B7F118052BC200913C76 /* mpegaudiodsp_data.c */, 8393B7F318052BC200913C76 /* mpegaudiodsp_float.c */, 8393B7F618052BC200913C76 /* mpegaudiodsp.h */, - 8393B7F718052BC200913C76 /* mpegaudioenc.c */, 8393B7F818052BC200913C76 /* mpegaudiotab.h */, 833C37D418032E7000CBA602 /* jrevdct.c */, 833C37CA18032D4800CBA602 /* golomb.c */, @@ -1308,8 +1338,13 @@ 830F0BBA17FC4FB900042E8F /* libavutil */ = { isa = PBXGroup; children = ( - 838491061807CDF400E7332D /* lls.c */, - 838491071807CDF400E7332D /* lls.h */, + 832F4BC218CD5DE2003E940E /* time_.h */, + 832F4BBE18CD5DD9003E940E /* downmix_info.c */, + 832F4BBF18CD5DD9003E940E /* downmix_info.h */, + 832F4BB418CD4FEA003E940E /* macros.h */, + 832F4BB518CD4FEA003E940E /* timestamp.h */, + 832F4BA418CD4F47003E940E /* lls2.c */, + 832F4BA518CD4F47003E940E /* lls2.h */, 838490721807B07000E7332D /* md5.c */, 838490731807B07000E7332D /* md5.h */, 8384906E1807B04200E7332D /* lfg.c */, @@ -1319,7 +1354,6 @@ 83BCB8E117FCA64400760340 /* timecode.h */, 830F0DB117FC8FCE00042E8F /* log2_tab.c */, 830F0D5217FC891800042E8F /* file_open.c */, - 830F0D5017FC880E00042E8F /* time_.h */, 830F0D4A17FC862300042E8F /* time.c */, 830F0D4C17FC862400042E8F /* utils.c */, 830F0D4217FC85ED00042E8F /* integer.c */, @@ -1438,6 +1472,8 @@ 830F0D0717FC80B400042E8F /* x86 */ = { isa = PBXGroup; children = ( + 832F4BC618CD6052003E940E /* dcadsp_init.c */, + 832F4BC418CD601B003E940E /* ttadsp_init.c */, 838491101807CEF400E7332D /* sbrdsp_init.c */, 8384910E1807CEC400E7332D /* lpc.c */, 838490841807B17C00E7332D /* ac3dsp_init.c */, @@ -1477,12 +1513,13 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 83BCB8E217FCA64400760340 /* avconfig.h in Headers */, 830F0D3417FC841B00042E8F /* opt.h in Headers */, 830F0C1C17FC523000042E8F /* url.h in Headers */, - 83BCB8E217FCA64400760340 /* avconfig.h in Headers */, 830F0BDC17FC4FB900042E8F /* old_codec_ids.h in Headers */, 830F0C0B17FC4FB900042E8F /* pixfmt.h in Headers */, 830F0C0517FC4FB900042E8F /* intfloat_readwrite.h in Headers */, + 832F4BBB18CD53E9003E940E /* ttadsp.h in Headers */, 830F0C0417FC4FB900042E8F /* intfloat.h in Headers */, 830F0C0717FC4FB900042E8F /* mathematics.h in Headers */, 838491031807CDC000E7332D /* lpc.h in Headers */, @@ -1502,6 +1539,7 @@ 830F0BE317FC4FB900042E8F /* version.h in Headers */, 830F0BFA17FC4FB900042E8F /* attributes.h in Headers */, 830F0BFF17FC4FB900042E8F /* common.h in Headers */, + 832F4BB618CD4FEA003E940E /* macros.h in Headers */, 830F0BFB17FC4FB900042E8F /* avutil.h in Headers */, 830F0C0D17FC4FB900042E8F /* samplefmt.h in Headers */, 830F0BFD17FC4FB900042E8F /* buffer.h in Headers */, @@ -1598,11 +1636,12 @@ 830F0DCA17FC931700042E8F /* pcm.h in Headers */, 830F0CCC17FC7F1E00042E8F /* celp_filters.h in Headers */, 830C4B5C180C3434007674D6 /* amrnbdata.h in Headers */, - 830F0D5117FC880E00042E8F /* time_.h in Headers */, 830F0BD717FC4FB900042E8F /* get_bits.h in Headers */, 830F0C2417FC527400042E8F /* atomic.h in Headers */, + 832F4BC318CD5DE2003E940E /* time_.h in Headers */, 833E5FA118A31EC4006A85F9 /* twinvq_data.h in Headers */, 830F0C5D17FC7CEA00042E8F /* id3v1.h in Headers */, + 832F4BAF18CD4F6B003E940E /* atrac3plus_data.h in Headers */, 838490631807AF0100E7332D /* ac3dec.h in Headers */, 838490C31807C37300E7332D /* atrac.h in Headers */, 830F0C6A17FC7DB100042E8F /* avassert.h in Headers */, @@ -1620,7 +1659,6 @@ 830F0C6D17FC7DB100042E8F /* buffer_internal.h in Headers */, 830F0DBB17FC921D00042E8F /* emms.h in Headers */, 830F0C2217FC527400042E8F /* atomic_gcc.h in Headers */, - 838491091807CDF400E7332D /* lls.h in Headers */, 838490F21807C57B00E7332D /* aacadtsdec.h in Headers */, 830F0CD117FC7F1E00042E8F /* dct.h in Headers */, 830F0DBC17FC921D00042E8F /* timer.h in Headers */, @@ -1628,6 +1666,7 @@ 830F0BD817FC4FB900042E8F /* internal.h in Headers */, 830F0BE517FC4FB900042E8F /* wma_common.h in Headers */, 830F0CDB17FC7F1E00042E8F /* error_resilience.h in Headers */, + 832F4BB718CD4FEA003E940E /* timestamp.h in Headers */, 830F0C4A17FC7CA300042E8F /* avio_internal.h in Headers */, 830F0C7017FC7DB100042E8F /* pixdesc.h in Headers */, 833C37C318032CF600CBA602 /* dirac_arith.h in Headers */, @@ -1638,6 +1677,7 @@ 830F0CE817FC7F1E00042E8F /* hpeldsp.h in Headers */, 830F0D8B17FC8E8B00042E8F /* aacpsdsp.h in Headers */, 830F0CD617FC7F1E00042E8F /* dctref.h in Headers */, + 832F4BA718CD4F47003E940E /* lls2.h in Headers */, 838490F61807C57B00E7332D /* aacps_tablegen.h in Headers */, 830F0C1917FC523000042E8F /* rdt.h in Headers */, 838490941807BC9400E7332D /* dcadsp.h in Headers */, @@ -1680,8 +1720,10 @@ 830F0C8117FC7ED100042E8F /* crc.h in Headers */, 833C379C180328B300CBA602 /* tak.h in Headers */, 830F0DB817FC921D00042E8F /* asm.h in Headers */, + 832F4BC118CD5DD9003E940E /* downmix_info.h in Headers */, 830F0CC517FC7F1E00042E8F /* acelp_pitch_delay.h in Headers */, 838490D91807C47E00E7332D /* g729postfilter.h in Headers */, + 832F4BB118CD4F6B003E940E /* atrac3plus.h in Headers */, 830F0D8F17FC8E8B00042E8F /* sbrdsp.h in Headers */, 830F0CCE17FC7F1E00042E8F /* celp_math.h in Headers */, 8384905D1807AF0100E7332D /* ac3_parser.h in Headers */, @@ -1755,7 +1797,6 @@ buildActionMask = 2147483647; files = ( 838490DA1807C47E00E7332D /* g726.c in Sources */, - 838491081807CDF400E7332D /* lls.c in Sources */, 833C37A918032AAD00CBA602 /* img2.c in Sources */, 838490701807B04200E7332D /* lfg.c in Sources */, 838490981807BC9C00E7332D /* dtshddec.c in Sources */, @@ -1768,6 +1809,7 @@ 830F0CF417FC7F1E00042E8F /* rdft.c in Sources */, 830F0DB217FC8FCE00042E8F /* log2_tab.c in Sources */, 830F0BEE17FC4FB900042E8F /* allformats.c in Sources */, + 832F4BB218CD4F6B003E940E /* atrac3plusdec.c in Sources */, 830F0D4817FC85ED00042E8F /* intmath.c in Sources */, 8384904F1807898A00E7332D /* ape.c in Sources */, 830F0CF017FC7F1E00042E8F /* ratecontrol.c in Sources */, @@ -1804,6 +1846,7 @@ 830F0BF217FC4FB900042E8F /* avio.c in Sources */, 830C4B5F180C3434007674D6 /* amrwbdec.c in Sources */, 838490DC1807C47E00E7332D /* g723_1.c in Sources */, + 832F4BC518CD601B003E940E /* ttadsp_init.c in Sources */, 830F0CE217FC7F1E00042E8F /* frame_thread_encoder.c in Sources */, 830C4B61180C343C007674D6 /* amr.c in Sources */, 838491151807D1D200E7332D /* tta.c in Sources */, @@ -1881,6 +1924,7 @@ 830F0CDE17FC7F1E00042E8F /* faanidct.c in Sources */, 833C379B180328B300CBA602 /* tak.c in Sources */, 830F0CC917FC7F1E00042E8F /* bit_depth_template.c in Sources */, + 832F4BC718CD6052003E940E /* dcadsp_init.c in Sources */, 8384906C1807AFB800E7332D /* aac_ac3_parser.c in Sources */, 8393B7E318052BB000913C76 /* mpeg.c in Sources */, 838491111807CEF400E7332D /* sbrdsp_init.c in Sources */, @@ -1911,11 +1955,13 @@ 830F0D5F17FC89BD00042E8F /* options.c in Sources */, 8393B7FE18052BC200913C76 /* mpegaudiodata.c in Sources */, 833C37D318032E4800CBA602 /* dsputil_init.c in Sources */, + 832F4BA618CD4F47003E940E /* lls2.c in Sources */, 830F0DB917FC921D00042E8F /* cpu.c in Sources */, 830F0C7D17FC7E4E00042E8F /* mathematics.c in Sources */, 830F0BDD17FC4FB900042E8F /* parser.c in Sources */, 830F0C5C17FC7CEA00042E8F /* id3v1.c in Sources */, 8393B7F918052BC200913C76 /* mpegaudio_parser.c in Sources */, + 832F4BBA18CD53E9003E940E /* ttadsp.c in Sources */, 830F0CFC17FC7F1E00042E8F /* videodsp.c in Sources */, 830F0D8C17FC8E8B00042E8F /* dv_profile.c in Sources */, 833C37B118032AEF00CBA602 /* diracdsp.c in Sources */, @@ -1929,7 +1975,9 @@ 8384904D1807898200E7332D /* apedec.c in Sources */, 830F0D2E17FC841B00042E8F /* channel_layout.c in Sources */, 830F0CE517FC7F1E00042E8F /* h264chroma.c in Sources */, + 832F4BB318CD4F6B003E940E /* atrac3plusdsp.c in Sources */, 830F0BE717FC4FB900042E8F /* wmadec.c in Sources */, + 832F4BC018CD5DD9003E940E /* downmix_info.c in Sources */, 838490931807BC9400E7332D /* dcadsp.c in Sources */, 838490FF1807C58500E7332D /* aacdec.c in Sources */, 830F0CC617FC7F1E00042E8F /* acelp_vectors.c in Sources */, @@ -1944,6 +1992,7 @@ 830F0D3817FC844E00042E8F /* parseutils.c in Sources */, 830F0D2017FC82AB00042E8F /* cpu.c in Sources */, 8393B7FC18052BC200913C76 /* mpegaudio.c in Sources */, + 832F4BB018CD4F6B003E940E /* atrac3plus.c in Sources */, 838490D81807C47E00E7332D /* g729postfilter.c in Sources */, 833C37C618032CF600CBA602 /* dirac_parser.c in Sources */, 830F0CED17FC7F1E00042E8F /* mpeg12data.c in Sources */, @@ -1954,7 +2003,6 @@ 830F0BE817FC4FB900042E8F /* wmalosslessdec.c in Sources */, 838490621807AF0100E7332D /* ac3dec.c in Sources */, 83BCB8E317FCA64400760340 /* timecode.c in Sources */, - 8393B80B18052BC200913C76 /* mpegaudioenc.c in Sources */, 8384910D1807CEB600E7332D /* sbrdsp.c in Sources */, 8384911A1807D1D900E7332D /* ttadata.c in Sources */, 838490B91807C1C300E7332D /* truespeech.c in Sources */, @@ -2009,7 +2057,6 @@ GCC_PREFIX_HEADER = FFMPEG_Prefix.pch; HEADER_SEARCH_PATHS = ( "$(inherited)", - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, "ffmpeg-minimal", ); INFOPLIST_FILE = Info.plist; @@ -2034,7 +2081,6 @@ GCC_PREFIX_HEADER = FFMPEG_Prefix.pch; HEADER_SEARCH_PATHS = ( "$(inherited)", - /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, "ffmpeg-minimal", ); INFOPLIST_FILE = Info.plist; @@ -2049,6 +2095,7 @@ 1DEB91B208733DA50010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; CODE_SIGN_IDENTITY = "Christopher Snowhill"; GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1"; GCC_WARN_ABOUT_RETURN_TYPE = YES; @@ -2063,6 +2110,7 @@ 1DEB91B308733DA50010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; CODE_SIGN_IDENTITY = "Christopher Snowhill"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; GCC_WARN_ABOUT_RETURN_TYPE = YES; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/config.h b/Frameworks/FFMPEG/ffmpeg-minimal/config.h index 10c34d802..fc40dfbbc 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/config.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/config.h @@ -5,6 +5,7 @@ #define ARCH_X86 1 #define ARCH_ARM 0 #define ARCH_PPC 0 +#define ARCH_AARCH64 0 #define ARCH_ALPHA 0 #define ARCH_BFIN 0 #define ARCH_SH4 0 @@ -79,6 +80,7 @@ #define CONFIG_RISKY 1 #define CONFIG_FTRAPV 0 #define CONFIG_SMALL 0 +#define CONFIG_XVMC 0 #define NULL_IF_CONFIG_SMALL(a) a @@ -88,8 +90,9 @@ #define CONFIG_H264_VAAPI_HWACCEL 0 #define CONFIG_H264_VDA_HWACCEL 0 #define CONFIG_H264_VDPAU_HWACCEL 0 +#define CONFIG_MPEG1_XVMC_HWACCEL 0 #define CONFIG_MPEG1_VDPAU_HWACCEL 0 -#define CONFIG_MPEG1_DXVA2_HWACCEL 0 +#define CONFIG_MPEG2_XVMC_HWACCEL 0 #define CONFIG_MPEG2_DXVA2_HWACCEL 0 #define CONFIG_MPEG2_VAAPI_HWACCEL 0 #define CONFIG_MPEG2_VDPAU_HWACCEL 0 @@ -135,6 +138,7 @@ #define CONFIG_CAVS_DECODER 0 #define CONFIG_CDGRAPHICS_DECODER 0 #define CONFIG_CDXL_DECODER 0 +#define CONFIG_CINEPAK_ENCODER 0 #define CONFIG_CINEPAK_DECODER 0 #define CONFIG_CLJR_ENCODER 0 #define CONFIG_CLJR_DECODER 0 @@ -170,6 +174,7 @@ #define CONFIG_FFV1_DECODER 0 #define CONFIG_FFVHUFF_ENCODER 0 #define CONFIG_FFVHUFF_DECODER 0 +#define CONFIG_FIC_DECODER 0 #define CONFIG_FLASHSV_ENCODER 0 #define CONFIG_FLASHSV_DECODER 0 #define CONFIG_FLASHSV2_ENCODER 0 @@ -194,6 +199,8 @@ #define CONFIG_H264_CRYSTALHD_DECODER 0 #define CONFIG_H264_VDA_DECODER 0 #define CONFIG_H264_VDPAU_DECODER 0 +#define CONFIG_HEVC_DECODER 0 +#define CONFIG_HNM4_VIDEO_DECODER 0 #define CONFIG_HUFFYUV_ENCODER 0 #define CONFIG_HUFFYUV_DECODER 0 #define CONFIG_IDCIN_DECODER 0 @@ -398,6 +405,7 @@ #define CONFIG_APE_DECODER 1 #define CONFIG_ATRAC1_DECODER 0 #define CONFIG_ATRAC3_DECODER 1 +#define CONFIG_ATRAC3P_DECODER 1 #define CONFIG_BINKAUDIO_DCT_DECODER 0 #define CONFIG_BINKAUDIO_RDFT_DECODER 0 #define CONFIG_BMV_AUDIO_DECODER 0 @@ -427,6 +435,7 @@ #define CONFIG_MP2_ENCODER 0 #define CONFIG_MP2_DECODER 0 #define CONFIG_MP2FLOAT_DECODER 1 +#define CONFIG_MP2FIXED_ENCODER 0 #define CONFIG_MP3_DECODER 0 #define CONFIG_MP3FLOAT_DECODER 1 #define CONFIG_MP3ADU_DECODER 0 @@ -550,6 +559,7 @@ #define CONFIG_ADPCM_G722_DECODER 1 #define CONFIG_ADPCM_G726_ENCODER 0 #define CONFIG_ADPCM_G726_DECODER 1 +#define CONFIG_ADPCM_G726LE_DECODER 1 #define CONFIG_ADPCM_IMA_AMV_DECODER 0 #define CONFIG_ADPCM_IMA_APC_DECODER 0 #define CONFIG_ADPCM_IMA_DK3_DECODER 1 @@ -644,8 +654,10 @@ #define CONFIG_LIBVPX_VP9_ENCODER 0 #define CONFIG_LIBVPX_VP9_DECODER 0 #define CONFIG_LIBWAVPACK_ENCODER 0 +#define CONFIG_LIBWEBP_ENCODER 0 #define CONFIG_LIBX264_ENCODER 0 #define CONFIG_LIBX264RGB_ENCODER 0 +#define CONFIG_LIBX265_ENCODER 0 #define CONFIG_LIBXAVS_ENCODER 0 #define CONFIG_LIBXVID_ENCODER 0 #define CONFIG_LIBZVBI_TELETEXT_DECODER 0 @@ -673,6 +685,7 @@ #define CONFIG_H261_PARSER 0 #define CONFIG_H263_PARSER 0 #define CONFIG_H264_PARSER 0 +#define CONFIG_HEVC_PARSER 0 #define CONFIG_MJPEG_PARSER 0 #define CONFIG_MLP_PARSER 0 #define CONFIG_MPEG4VIDEO_PARSER 0 @@ -687,6 +700,7 @@ #define CONFIG_VORBIS_PARSER 0 #define CONFIG_VP3_PARSER 0 #define CONFIG_VP8_PARSER 0 +#define CONFIG_VP9_PARSER 0 #define CONFIG_AAC_ADTSTOASC_BSF 1 #define CONFIG_CHOMP_BSF 0 @@ -809,9 +823,12 @@ #define CONFIG_H263_DEMUXER 0 #define CONFIG_H264_MUXER 0 #define CONFIG_H264_DEMUXER 0 -#define CONFIG_H265_DEMUXER 0 +#define CONFIG_HDS_MUXER 0 +#define CONFIG_HEVC_MUXER 0 +#define CONFIG_HEVC_DEMUXER 0 #define CONFIG_HLS_MUXER 0 #define CONFIG_HLS_DEMUXER 0 +#define CONFIG_HNM_DEMUXER 0 #define CONFIG_ICO_MUXER 0 #define CONFIG_ICO_DEMUXER 0 #define CONFIG_IDCIN_DEMUXER 0 @@ -900,6 +917,7 @@ #define CONFIG_OGG_DEMUXER 0 #define CONFIG_OMA_MUXER 0 #define CONFIG_OMA_DEMUXER 0 +#define CONFIG_OPUS_MUXER 0 #define CONFIG_PAF_DEMUXER 0 #define CONFIG_PCM_ALAW_MUXER 0 #define CONFIG_PCM_ALAW_DEMUXER 0 @@ -970,6 +988,7 @@ #define CONFIG_SAP_DEMUXER 0 #define CONFIG_SBG_DEMUXER 0 #define CONFIG_SDP_DEMUXER 0 +#define CONFIG_SDR2_DEMUXER 0 #define CONFIG_SEGAFILM_DEMUXER 0 #define CONFIG_SEGMENT_MUXER 0 #define CONFIG_SHORTEN_DEMUXER 0 @@ -984,6 +1003,7 @@ #define CONFIG_SOX_DEMUXER 0 #define CONFIG_SPDIF_MUXER 0 #define CONFIG_SPDIF_DEMUXER 1 +#define CONFIG_SPEEX_MUXER 0 #define CONFIG_SRT_MUXER 0 #define CONFIG_SRT_DEMUXER 0 #define CONFIG_STR_DEMUXER 0 @@ -1005,6 +1025,7 @@ #define CONFIG_TTA_DEMUXER 1 #define CONFIG_TXD_DEMUXER 0 #define CONFIG_TTY_DEMUXER 0 +#define CONFIG_UNCODEDFRAMECRC_MUXER 0 #define CONFIG_VC1_MUXER 0 #define CONFIG_VC1_DEMUXER 0 #define CONFIG_VC1T_MUXER 0 @@ -1066,6 +1087,7 @@ #define CONFIG_RTP_PROTOCOL 0 #define CONFIG_SCTP_PROTOCOL 0 #define CONFIG_SRTP_PROTOCOL 0 +#define CONFIG_SUBFILE_PROTOCOL 0 #define CONFIG_TCP_PROTOCOL 0 #define CONFIG_TLS_PROTOCOL 0 #define CONFIG_UDP_PROTOCOL 0 diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aac.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aac.h index cda14777c..89f463e34 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aac.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aac.h @@ -234,7 +234,7 @@ typedef struct SingleChannelElement { int sf_idx[128]; ///< scalefactor indices (used by encoder) uint8_t zeroes[128]; ///< band is not coded (used by encoder) DECLARE_ALIGNED(32, float, coeffs)[1024]; ///< coefficients for IMDCT - DECLARE_ALIGNED(32, float, saved)[1024]; ///< overlap + DECLARE_ALIGNED(32, float, saved)[1536]; ///< overlap DECLARE_ALIGNED(32, float, ret_buf)[2048]; ///< PCM output buffer DECLARE_ALIGNED(16, float, ltp_state)[3072]; ///< time signal for LTP PredictorState predictor_state[MAX_PREDICTORS]; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aac_ac3_parser.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aac_ac3_parser.c index 618463fa0..c82a21024 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aac_ac3_parser.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aac_ac3_parser.c @@ -20,7 +20,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/channel_layout.h" #include "libavutil/common.h" +#include "libavutil/internal.h" #include "parser.h" #include "aac_ac3_parser.h" @@ -82,20 +84,27 @@ get_next: if (avctx->codec_id != AV_CODEC_ID_AAC) { avctx->sample_rate = s->sample_rate; - /* allow downmixing to stereo (or mono for AC-3) */ - AV_NOWARN_DEPRECATED( - if(avctx->request_channels > 0 && - avctx->request_channels < s->channels && - (avctx->request_channels <= 2 || - (avctx->request_channels == 1 && - (avctx->codec_id == AV_CODEC_ID_AC3 || - avctx->codec_id == AV_CODEC_ID_EAC3)))) { - avctx->channels = avctx->request_channels; + /* (E-)AC-3: allow downmixing to stereo or mono */ +#if FF_API_REQUEST_CHANNELS +FF_DISABLE_DEPRECATION_WARNINGS + if (avctx->request_channels == 1) + avctx->request_channel_layout = AV_CH_LAYOUT_MONO; + else if (avctx->request_channels == 2) + avctx->request_channel_layout = AV_CH_LAYOUT_STEREO; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + if (s->channels > 1 && + avctx->request_channel_layout == AV_CH_LAYOUT_MONO) { + avctx->channels = 1; + avctx->channel_layout = AV_CH_LAYOUT_MONO; + } else if (s->channels > 2 && + avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) { + avctx->channels = 2; + avctx->channel_layout = AV_CH_LAYOUT_STEREO; } else { avctx->channels = s->channels; avctx->channel_layout = s->channel_layout; } - ); s1->duration = s->samples; avctx->audio_service_type = s->service_type; } diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aac_adtstoasc_bsf.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aac_adtstoasc_bsf.c index 54cd68706..d5ea20f19 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aac_adtstoasc_bsf.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aac_adtstoasc_bsf.c @@ -88,6 +88,7 @@ static int aac_adtstoasc_filter(AVBitStreamFilterContext *bsfc, buf_size -= get_bits_count(&gb)/8; buf += get_bits_count(&gb)/8; } + av_free(avctx->extradata); avctx->extradata_size = 2 + pce_size; avctx->extradata = av_mallocz(avctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacdec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacdec.c index b65d16826..2affceb00 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacdec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacdec.c @@ -2,6 +2,7 @@ * AAC decoder * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org ) * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com ) + * Copyright (c) 2008-2013 Alex Converse * * AAC LATM decoder * Copyright (c) 2008-2010 Paul Kendall @@ -73,6 +74,7 @@ * N SinuSoidal Coding (Transient, Sinusoid, Noise) * Y Parametric Stereo * N Direct Stream Transfer + * Y Enhanced AAC Low Delay (ER AAC ELD) * * Note: - HE AAC v1 comprises LC AAC with Spectral Band Replication. * - HE AAC v2 comprises LC AAC with Spectral Band Replication and @@ -104,6 +106,7 @@ #include #include #include +#include #include #if ARCH_ARM @@ -194,6 +197,9 @@ static int frame_configure_elements(AVCodecContext *avctx) /* get output buffer */ av_frame_unref(ac->frame); + if (!avctx->channels) + return 1; + ac->frame->nb_samples = 2048; if ((ret = ff_get_buffer(avctx, ac->frame, 0)) < 0) return ret; @@ -532,6 +538,25 @@ static int set_default_channel_config(AVCodecContext *avctx, *tags = tags_per_config[channel_config]; memcpy(layout_map, aac_channel_layout_map[channel_config - 1], *tags * sizeof(*layout_map)); + + /* + * AAC specification has 7.1(wide) as a default layout for 8-channel streams. + * However, at least Nero AAC encoder encodes 7.1 streams using the default + * channel config 7, mapping the side channels of the original audio stream + * to the second AAC_CHANNEL_FRONT pair in the AAC stream. Similarly, e.g. FAAD + * decodes the second AAC_CHANNEL_FRONT pair as side channels, therefore decoding + * the incorrect streams as if they were correct (and as the encoder intended). + * + * As actual intended 7.1(wide) streams are very rare, default to assuming a + * 7.1 layout was intended. + */ + if (channel_config == 7 && avctx->strict_std_compliance < FF_COMPLIANCE_STRICT) { + av_log(avctx, AV_LOG_INFO, "Assuming an incorrectly encoded 7.1 channel layout" + " instead of a spec-compliant 7.1(wide) layout, use -strict %d to decode" + " according to the specification instead.\n", FF_COMPLIANCE_STRICT); + layout_map[2][2] = AAC_CHANNEL_SIDE; + } + return 0; } @@ -794,9 +819,9 @@ static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx, case AOT_ER_AAC_LD: res_flags = get_bits(gb, 3); if (res_flags) { - av_log(avctx, AV_LOG_ERROR, - "AAC data resilience not supported (flags %x)\n", - res_flags); + avpriv_report_missing_feature(avctx, + "AAC data resilience (flags %x)", + res_flags); return AVERROR_PATCHWELCOME; } break; @@ -810,15 +835,75 @@ static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx, case AOT_ER_AAC_LD: ep_config = get_bits(gb, 2); if (ep_config) { - av_log(avctx, AV_LOG_ERROR, - "epConfig %d is not supported.\n", - ep_config); + avpriv_report_missing_feature(avctx, + "epConfig %d", ep_config); return AVERROR_PATCHWELCOME; } } return 0; } +static int decode_eld_specific_config(AACContext *ac, AVCodecContext *avctx, + GetBitContext *gb, + MPEG4AudioConfig *m4ac, + int channel_config) +{ + int ret, ep_config, res_flags; + uint8_t layout_map[MAX_ELEM_ID*4][3]; + int tags = 0; + const int ELDEXT_TERM = 0; + + m4ac->ps = 0; + m4ac->sbr = 0; + + if (get_bits1(gb)) { // frameLengthFlag + avpriv_request_sample(avctx, "960/120 MDCT window"); + return AVERROR_PATCHWELCOME; + } + + res_flags = get_bits(gb, 3); + if (res_flags) { + avpriv_report_missing_feature(avctx, + "AAC data resilience (flags %x)", + res_flags); + return AVERROR_PATCHWELCOME; + } + + if (get_bits1(gb)) { // ldSbrPresentFlag + avpriv_report_missing_feature(avctx, + "Low Delay SBR"); + return AVERROR_PATCHWELCOME; + } + + while (get_bits(gb, 4) != ELDEXT_TERM) { + int len = get_bits(gb, 4); + if (len == 15) + len += get_bits(gb, 8); + if (len == 15 + 255) + len += get_bits(gb, 16); + if (get_bits_left(gb) < len * 8 + 4) { + av_log(ac->avctx, AV_LOG_ERROR, overread_err); + return AVERROR_INVALIDDATA; + } + skip_bits_long(gb, 8 * len); + } + + if ((ret = set_default_channel_config(avctx, layout_map, + &tags, channel_config))) + return ret; + + if (ac && (ret = output_configure(ac, layout_map, tags, OC_GLOBAL_HDR, 0))) + return ret; + + ep_config = get_bits(gb, 2); + if (ep_config) { + avpriv_report_missing_feature(avctx, + "epConfig %d", ep_config); + return AVERROR_PATCHWELCOME; + } + return 0; +} + /** * Decode audio specific configuration; reference: table 1.13. * @@ -877,11 +962,16 @@ static int decode_audio_specific_config(AACContext *ac, m4ac, m4ac->chan_config)) < 0) return ret; break; + case AOT_ER_AAC_ELD: + if ((ret = decode_eld_specific_config(ac, avctx, &gb, + m4ac, m4ac->chan_config)) < 0) + return ret; + break; default: - av_log(avctx, AV_LOG_ERROR, - "Audio object type %s%d is not supported.\n", - m4ac->sbr == 1 ? "SBR+" : "", - m4ac->object_type); + avpriv_report_missing_feature(avctx, + "Audio object type %s%d", + m4ac->sbr == 1 ? "SBR+" : "", + m4ac->object_type); return AVERROR(ENOSYS); } @@ -1047,7 +1137,6 @@ static av_cold int aac_decode_init(AVCodecContext *avctx) ff_mdct_init(&ac->mdct_ltp, 11, 0, -2.0 * 32768.0); // window initialization ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024); - ff_kbd_window_init(ff_aac_kbd_long_512, 4.0, 512); ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128); ff_init_ff_sine_windows(10); ff_init_ff_sine_windows( 9); @@ -1117,22 +1206,25 @@ static void decode_ltp(LongTermPrediction *ltp, static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics, GetBitContext *gb) { - if (get_bits1(gb)) { - av_log(ac->avctx, AV_LOG_ERROR, "Reserved bit set.\n"); - return AVERROR_INVALIDDATA; + int aot = ac->oc[1].m4ac.object_type; + if (aot != AOT_ER_AAC_ELD) { + if (get_bits1(gb)) { + av_log(ac->avctx, AV_LOG_ERROR, "Reserved bit set.\n"); + return AVERROR_INVALIDDATA; + } + ics->window_sequence[1] = ics->window_sequence[0]; + ics->window_sequence[0] = get_bits(gb, 2); + if (aot == AOT_ER_AAC_LD && + ics->window_sequence[0] != ONLY_LONG_SEQUENCE) { + av_log(ac->avctx, AV_LOG_ERROR, + "AAC LD is only defined for ONLY_LONG_SEQUENCE but " + "window sequence %d found.\n", ics->window_sequence[0]); + ics->window_sequence[0] = ONLY_LONG_SEQUENCE; + return AVERROR_INVALIDDATA; + } + ics->use_kb_window[1] = ics->use_kb_window[0]; + ics->use_kb_window[0] = get_bits1(gb); } - ics->window_sequence[1] = ics->window_sequence[0]; - ics->window_sequence[0] = get_bits(gb, 2); - if (ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD && - ics->window_sequence[0] != ONLY_LONG_SEQUENCE) { - av_log(ac->avctx, AV_LOG_ERROR, - "AAC LD is only defined for ONLY_LONG_SEQUENCE but " - "window sequence %d found.\n", ics->window_sequence[0]); - ics->window_sequence[0] = ONLY_LONG_SEQUENCE; - return AVERROR_INVALIDDATA; - } - ics->use_kb_window[1] = ics->use_kb_window[0]; - ics->use_kb_window[0] = get_bits1(gb); ics->num_window_groups = 1; ics->group_len[0] = 1; if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { @@ -1154,30 +1246,33 @@ static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics, } else { ics->max_sfb = get_bits(gb, 6); ics->num_windows = 1; - if (ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD) { + if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD) { ics->swb_offset = ff_swb_offset_512[ac->oc[1].m4ac.sampling_index]; ics->num_swb = ff_aac_num_swb_512[ac->oc[1].m4ac.sampling_index]; + ics->tns_max_bands = ff_tns_max_bands_512[ac->oc[1].m4ac.sampling_index]; if (!ics->num_swb || !ics->swb_offset) return AVERROR_BUG; } else { ics->swb_offset = ff_swb_offset_1024[ac->oc[1].m4ac.sampling_index]; ics->num_swb = ff_aac_num_swb_1024[ac->oc[1].m4ac.sampling_index]; + ics->tns_max_bands = ff_tns_max_bands_1024[ac->oc[1].m4ac.sampling_index]; + } + if (aot != AOT_ER_AAC_ELD) { + ics->predictor_present = get_bits1(gb); + ics->predictor_reset_group = 0; } - ics->tns_max_bands = ff_tns_max_bands_1024[ac->oc[1].m4ac.sampling_index]; - ics->predictor_present = get_bits1(gb); - ics->predictor_reset_group = 0; if (ics->predictor_present) { - if (ac->oc[1].m4ac.object_type == AOT_AAC_MAIN) { + if (aot == AOT_AAC_MAIN) { if (decode_prediction(ac, ics, gb)) { goto fail; } - } else if (ac->oc[1].m4ac.object_type == AOT_AAC_LC || - ac->oc[1].m4ac.object_type == AOT_ER_AAC_LC) { + } else if (aot == AOT_AAC_LC || + aot == AOT_ER_AAC_LC) { av_log(ac->avctx, AV_LOG_ERROR, "Prediction is not allowed in AAC-LC.\n"); goto fail; } else { - if (ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD) { + if (aot == AOT_ER_AAC_LD) { av_log(ac->avctx, AV_LOG_ERROR, "LTP in ER AAC LD not yet implemented.\n"); return AVERROR_PATCHWELCOME; @@ -1332,12 +1427,12 @@ static int decode_pulses(Pulse *pulse, GetBitContext *gb, return -1; pulse->pos[0] = swb_offset[pulse_swb]; pulse->pos[0] += get_bits(gb, 5); - if (pulse->pos[0] > 1023) + if (pulse->pos[0] >= swb_offset[num_swb]) return -1; pulse->amp[0] = get_bits(gb, 4); for (i = 1; i < pulse->num_pulse; i++) { pulse->pos[i] = get_bits(gb, 5) + pulse->pos[i - 1]; - if (pulse->pos[i] > 1023) + if (pulse->pos[i] >= swb_offset[num_swb]) return -1; pulse->amp[i] = get_bits(gb, 4); } @@ -1802,9 +1897,15 @@ static int decode_ics(AACContext *ac, SingleChannelElement *sce, TemporalNoiseShaping *tns = &sce->tns; IndividualChannelStream *ics = &sce->ics; float *out = sce->coeffs; - int global_gain, er_syntax, pulse_present = 0; + int global_gain, eld_syntax, er_syntax, pulse_present = 0; int ret; + eld_syntax = ac->oc[1].m4ac.object_type == AOT_ER_AAC_ELD; + er_syntax = ac->oc[1].m4ac.object_type == AOT_ER_AAC_LC || + ac->oc[1].m4ac.object_type == AOT_ER_AAC_LTP || + ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD || + ac->oc[1].m4ac.object_type == AOT_ER_AAC_ELD; + /* This assignment is to silence a GCC warning about the variable being used * uninitialized when in fact it always is. */ @@ -1825,11 +1926,8 @@ static int decode_ics(AACContext *ac, SingleChannelElement *sce, return ret; pulse_present = 0; - er_syntax = ac->oc[1].m4ac.object_type == AOT_ER_AAC_LC || - ac->oc[1].m4ac.object_type == AOT_ER_AAC_LTP || - ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD; if (!scale_flag) { - if ((pulse_present = get_bits1(gb))) { + if (!eld_syntax && (pulse_present = get_bits1(gb))) { if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { av_log(ac->avctx, AV_LOG_ERROR, "Pulse tool not allowed in eight short sequence.\n"); @@ -1845,7 +1943,7 @@ static int decode_ics(AACContext *ac, SingleChannelElement *sce, if (tns->present && !er_syntax) if (decode_tns(ac, tns, gb, ics) < 0) return AVERROR_INVALIDDATA; - if (get_bits1(gb)) { + if (!eld_syntax && get_bits1(gb)) { avpriv_request_sample(ac->avctx, "SSR"); return AVERROR_PATCHWELCOME; } @@ -1945,8 +2043,9 @@ static void apply_intensity_stereo(AACContext *ac, static int decode_cpe(AACContext *ac, GetBitContext *gb, ChannelElement *cpe) { int i, ret, common_window, ms_present = 0; + int eld_syntax = ac->oc[1].m4ac.object_type == AOT_ER_AAC_ELD; - common_window = get_bits1(gb); + common_window = eld_syntax || get_bits1(gb); if (common_window) { if (decode_ics_info(ac, &cpe->ch[0].ics, gb)) return AVERROR_INVALIDDATA; @@ -2188,10 +2287,12 @@ static int decode_extension_payload(AACContext *ac, GetBitContext *gb, int cnt, } else if (ac->oc[1].m4ac.ps == -1 && ac->oc[1].status < OC_LOCKED && ac->avctx->channels == 1) { ac->oc[1].m4ac.sbr = 1; ac->oc[1].m4ac.ps = 1; + ac->avctx->profile = FF_PROFILE_AAC_HE_V2; output_configure(ac, ac->oc[1].layout_map, ac->oc[1].layout_map_tags, ac->oc[1].status, 1); } else { ac->oc[1].m4ac.sbr = 1; + ac->avctx->profile = FF_PROFILE_AAC_HE; } res = ff_decode_sbr_extension(ac, &che->sbr, gb, crc_flag, cnt, elem_type); break; @@ -2431,19 +2532,81 @@ static void imdct_and_windowing_ld(AACContext *ac, SingleChannelElement *sce) float *in = sce->coeffs; float *out = sce->ret; float *saved = sce->saved; - const float *lwindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_long_512 : ff_sine_512; float *buf = ac->buf_mdct; // imdct ac->mdct.imdct_half(&ac->mdct_ld, buf, in); // window overlapping - ac->fdsp.vector_fmul_window(out, saved, buf, lwindow_prev, 256); + if (ics->use_kb_window[1]) { + // AAC LD uses a low overlap sine window instead of a KBD window + memcpy(out, saved, 192 * sizeof(float)); + ac->fdsp.vector_fmul_window(out + 192, saved + 192, buf, ff_sine_128, 64); + memcpy( out + 320, buf + 64, 192 * sizeof(float)); + } else { + ac->fdsp.vector_fmul_window(out, saved, buf, ff_sine_512, 256); + } // buffer update memcpy(saved, buf + 256, 256 * sizeof(float)); } +static void imdct_and_windowing_eld(AACContext *ac, SingleChannelElement *sce) +{ + float *in = sce->coeffs; + float *out = sce->ret; + float *saved = sce->saved; + const float *const window = ff_aac_eld_window; + float *buf = ac->buf_mdct; + int i; + const int n = 512; + const int n2 = n >> 1; + const int n4 = n >> 2; + + // Inverse transform, mapped to the conventional IMDCT by + // Chivukula, R.K.; Reznik, Y.A.; Devarajan, V., + // "Efficient algorithms for MPEG-4 AAC-ELD, AAC-LD and AAC-LC filterbanks," + // International Conference on Audio, Language and Image Processing, ICALIP 2008. + // URL: http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=4590245&isnumber=4589950 + for (i = 0; i < n2; i+=2) { + float temp; + temp = in[i ]; in[i ] = -in[n - 1 - i]; in[n - 1 - i] = temp; + temp = -in[i + 1]; in[i + 1] = in[n - 2 - i]; in[n - 2 - i] = temp; + } + ac->mdct.imdct_half(&ac->mdct_ld, buf, in); + for (i = 0; i < n; i+=2) { + buf[i] = -buf[i]; + } + // Like with the regular IMDCT at this point we still have the middle half + // of a transform but with even symmetry on the left and odd symmetry on + // the right + + // window overlapping + // The spec says to use samples [0..511] but the reference decoder uses + // samples [128..639]. + for (i = n4; i < n2; i ++) { + out[i - n4] = buf[n2 - 1 - i] * window[i - n4] + + saved[ i + n2] * window[i + n - n4] + + -saved[ n + n2 - 1 - i] * window[i + 2*n - n4] + + -saved[2*n + n2 + i] * window[i + 3*n - n4]; + } + for (i = 0; i < n2; i ++) { + out[n4 + i] = buf[i] * window[i + n2 - n4] + + -saved[ n - 1 - i] * window[i + n2 + n - n4] + + -saved[ n + i] * window[i + n2 + 2*n - n4] + + saved[2*n + n - 1 - i] * window[i + n2 + 3*n - n4]; + } + for (i = 0; i < n4; i ++) { + out[n2 + n4 + i] = buf[ i + n2] * window[i + n - n4] + + -saved[ n2 - 1 - i] * window[i + 2*n - n4] + + -saved[ n + n2 + i] * window[i + 3*n - n4]; + } + + // buffer update + memmove(saved + n, saved, 2 * n * sizeof(float)); + memcpy( saved, buf, n * sizeof(float)); +} + /** * Apply dependent channel coupling (applied before IMDCT). * @@ -2541,10 +2704,16 @@ static void spectral_to_sample(AACContext *ac) { int i, type; void (*imdct_and_window)(AACContext *ac, SingleChannelElement *sce); - if (ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD) + switch (ac->oc[1].m4ac.object_type) { + case AOT_ER_AAC_LD: imdct_and_window = imdct_and_windowing_ld; - else + break; + case AOT_ER_AAC_ELD: + imdct_and_window = imdct_and_windowing_eld; + break; + default: imdct_and_window = ac->imdct_and_windowing; + } for (type = 3; type >= 0; type--) { for (i = 0; i < MAX_ELEM_ID; i++) { ChannelElement *che = ac->che[type][i]; @@ -2654,8 +2823,9 @@ static int aac_decode_er_frame(AVCodecContext *avctx, void *data, int err, i; int samples = 1024; int chan_config = ac->oc[1].m4ac.chan_config; + int aot = ac->oc[1].m4ac.object_type; - if (ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD) + if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD) samples >>= 1; ac->frame = data; @@ -2663,6 +2833,10 @@ static int aac_decode_er_frame(AVCodecContext *avctx, void *data, if ((err = frame_configure_elements(avctx)) < 0) return err; + // The FF_PROFILE_AAC_* defines are all object_type - 1 + // This may lead to an undefined profile being signaled + ac->avctx->profile = ac->oc[1].m4ac.object_type - 1; + ac->tags_mapped = 0; if (chan_config < 0 || chan_config >= 8) { @@ -2679,7 +2853,8 @@ static int aac_decode_er_frame(AVCodecContext *avctx, void *data, elem_type, elem_id); return AVERROR_INVALIDDATA; } - skip_bits(gb, 4); + if (aot != AOT_ER_AAC_ELD) + skip_bits(gb, 4); switch (elem_type) { case TYPE_SCE: err = decode_ics(ac, &che->ch[0], gb, 0, 0); @@ -2698,6 +2873,7 @@ static int aac_decode_er_frame(AVCodecContext *avctx, void *data, spectral_to_sample(ac); ac->frame->nb_samples = samples; + ac->frame->sample_rate = avctx->sample_rate; *got_frame_ptr = 1; skip_bits_long(gb, get_bits_left(gb)); @@ -2731,6 +2907,10 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, if ((err = frame_configure_elements(avctx)) < 0) goto fail; + // The FF_PROFILE_AAC_* defines are all object_type - 1 + // This may lead to an undefined profile being signaled + ac->avctx->profile = ac->oc[1].m4ac.object_type - 1; + ac->tags_mapped = 0; // parse while ((elem_type = get_bits(gb, 3)) != TYPE_END) { @@ -2828,22 +3008,6 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, multiplier = (ac->oc[1].m4ac.sbr == 1) ? ac->oc[1].m4ac.ext_sample_rate > ac->oc[1].m4ac.sample_rate : 0; samples <<= multiplier; - /* for dual-mono audio (SCE + SCE) */ - is_dmono = ac->dmono_mode && sce_count == 2 && - ac->oc[1].channel_layout == (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT); - - if (samples) - ac->frame->nb_samples = samples; - else - av_frame_unref(ac->frame); - *got_frame_ptr = !!samples; - - if (is_dmono) { - if (ac->dmono_mode == 1) - ((AVFrame *)data)->data[1] =((AVFrame *)data)->data[0]; - else if (ac->dmono_mode == 2) - ((AVFrame *)data)->data[0] =((AVFrame *)data)->data[1]; - } if (ac->oc[1].status && audio_found) { avctx->sample_rate = ac->oc[1].m4ac.sample_rate << multiplier; @@ -2857,6 +3021,25 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, if (side && side_size>=4) AV_WL32(side, 2*AV_RL32(side)); } + + *got_frame_ptr = !!samples; + if (samples) { + ac->frame->nb_samples = samples; + ac->frame->sample_rate = avctx->sample_rate; + } else + av_frame_unref(ac->frame); + *got_frame_ptr = !!samples; + + /* for dual-mono audio (SCE + SCE) */ + is_dmono = ac->dmono_mode && sce_count == 2 && + ac->oc[1].channel_layout == (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT); + if (is_dmono) { + if (ac->dmono_mode == 1) + ((AVFrame *)data)->data[1] =((AVFrame *)data)->data[0]; + else if (ac->dmono_mode == 2) + ((AVFrame *)data)->data[0] =((AVFrame *)data)->data[1]; + } + return 0; fail: pop_output_configuration(ac); @@ -2915,6 +3098,7 @@ static int aac_decode_frame(AVCodecContext *avctx, void *data, case AOT_ER_AAC_LC: case AOT_ER_AAC_LTP: case AOT_ER_AAC_LD: + case AOT_ER_AAC_ELD: err = aac_decode_er_frame(avctx, data, got_frame_ptr, &gb); break; default: diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacps.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacps.c index c541a6997..d11c4e1b1 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacps.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacps.c @@ -323,14 +323,15 @@ static void hybrid2_re(float (*in)[2], float (*out)[32][2], const float filter[8 } /** Split one subband into 6 subsubbands with a complex filter */ -static void hybrid6_cx(PSDSPContext *dsp, float (*in)[2], float (*out)[32][2], const float (*filter)[8][2], int len) +static void hybrid6_cx(PSDSPContext *dsp, float (*in)[2], float (*out)[32][2], + TABLE_CONST float (*filter)[8][2], int len) { int i; int N = 8; LOCAL_ALIGNED_16(float, temp, [8], [2]); for (i = 0; i < len; i++, in++) { - dsp->hybrid_analysis(temp, in, filter, 1, N); + dsp->hybrid_analysis(temp, in, (const float (*)[8][2]) filter, 1, N); out[0][i][0] = temp[6][0]; out[0][i][1] = temp[6][1]; out[1][i][0] = temp[7][0]; @@ -346,12 +347,14 @@ static void hybrid6_cx(PSDSPContext *dsp, float (*in)[2], float (*out)[32][2], c } } -static void hybrid4_8_12_cx(PSDSPContext *dsp, float (*in)[2], float (*out)[32][2], const float (*filter)[8][2], int N, int len) +static void hybrid4_8_12_cx(PSDSPContext *dsp, + float (*in)[2], float (*out)[32][2], + TABLE_CONST float (*filter)[8][2], int N, int len) { int i; for (i = 0; i < len; i++, in++) { - dsp->hybrid_analysis(out[0] + i, in, filter, 32, N); + dsp->hybrid_analysis(out[0] + i, in, (const float (*)[8][2]) filter, 32, N); } } @@ -430,6 +433,7 @@ static void hybrid_synthesis(PSDSPContext *dsp, float out[2][38][64], #define DECAY_SLOPE 0.05f /// Number of frequency bands that can be addressed by the parameter index, b(k) static const int NR_PAR_BANDS[] = { 20, 34 }; +static const int NR_IPDOPD_BANDS[] = { 11, 17 }; /// Number of frequency bands that can be addressed by the sub subband index, k static const int NR_BANDS[] = { 71, 91 }; /// Start frequency band for the all-pass filter decay slope @@ -686,7 +690,8 @@ static void decorrelation(PSContext *ps, float (*out)[32][2], const float (*s)[3 memcpy(ap_delay[k][m], ap_delay[k][m]+numQMFSlots, 5*sizeof(ap_delay[k][m][0])); } ps->dsp.decorrelate(out[k], delay[k] + PS_MAX_DELAY - 2, ap_delay[k], - phi_fract[is34][k], Q_fract_allpass[is34][k], + phi_fract[is34][k], + (const float (*)[2]) Q_fract_allpass[is34][k], transient_gain[b], g_decay_slope, nL - n0); } for (; k < SHORT_DELAY_BAND[is34]; k++) { @@ -764,7 +769,7 @@ static void stereo_processing(PSContext *ps, float (*l)[32][2], float (*r)[32][2 int8_t (*ipd_mapped)[PS_MAX_NR_IIDICC] = ipd_mapped_buf; int8_t (*opd_mapped)[PS_MAX_NR_IIDICC] = opd_mapped_buf; const int8_t *k_to_i = is34 ? k_to_i_34 : k_to_i_20; - const float (*H_LUT)[8][4] = (PS_BASELINE || ps->icc_mode < 3) ? HA : HB; + TABLE_CONST float (*H_LUT)[8][4] = (PS_BASELINE || ps->icc_mode < 3) ? HA : HB; //Remapping if (ps->num_env_old) { @@ -825,7 +830,7 @@ static void stereo_processing(PSContext *ps, float (*l)[32][2], float (*r)[32][2 h21 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps->iid_quant][icc_mapped[e][b]][2]; h22 = H_LUT[iid_mapped[e][b] + 7 + 23 * ps->iid_quant][icc_mapped[e][b]][3]; - if (!PS_BASELINE && ps->enable_ipdopd && 2*b <= NR_PAR_BANDS[is34]) { + if (!PS_BASELINE && ps->enable_ipdopd && b < NR_IPDOPD_BANDS[is34]) { //The spec say says to only run this smoother when enable_ipdopd //is set but the reference decoder appears to run it constantly float h11i, h12i, h21i, h22i; @@ -915,7 +920,7 @@ int ff_ps_apply(AVCodecContext *avctx, PSContext *ps, float L[2][38][64], float memset(ps->ap_delay + top, 0, (NR_ALLPASS_BANDS[is34] - top)*sizeof(ps->ap_delay[0])); hybrid_analysis(&ps->dsp, Lbuf, ps->in_buf, L, is34, len); - decorrelation(ps, Rbuf, Lbuf, is34); + decorrelation(ps, Rbuf, (const float (*)[32][2]) Lbuf, is34); stereo_processing(ps, Lbuf, Rbuf, is34); hybrid_synthesis(&ps->dsp, L, Lbuf, is34, len); hybrid_synthesis(&ps->dsp, R, Rbuf, is34, len); diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacps_tablegen.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacps_tablegen.c new file mode 100644 index 000000000..47d4205f4 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacps_tablegen.c @@ -0,0 +1,93 @@ +/* + * Generate a header file for hardcoded Parametric Stereo tables + * + * Copyright (c) 2010 Alex Converse + * + * 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 +#define CONFIG_HARDCODED_TABLES 0 +#include "aacps_tablegen.h" +#include "tableprint.h" + +void write_float_3d_array (const void *p, int b, int c, int d) +{ + int i; + const float *f = p; + for (i = 0; i < b; i++) { + printf("{\n"); + write_float_2d_array(f, c, d); + printf("},\n"); + f += c * d; + } +} + +void write_float_4d_array (const void *p, int a, int b, int c, int d) +{ + int i; + const float *f = p; + for (i = 0; i < a; i++) { + printf("{\n"); + write_float_3d_array(f, b, c, d); + printf("},\n"); + f += b * c * d; + } +} + +int main(void) +{ + ps_tableinit(); + + write_fileheader(); + + printf("static const float pd_re_smooth[8*8*8] = {\n"); + write_float_array(pd_re_smooth, 8*8*8); + printf("};\n"); + printf("static const float pd_im_smooth[8*8*8] = {\n"); + write_float_array(pd_im_smooth, 8*8*8); + printf("};\n"); + + printf("static const float HA[46][8][4] = {\n"); + write_float_3d_array(HA, 46, 8, 4); + printf("};\n"); + printf("static const float HB[46][8][4] = {\n"); + write_float_3d_array(HB, 46, 8, 4); + printf("};\n"); + + printf("static const DECLARE_ALIGNED(16, float, f20_0_8)[8][8][2] = {\n"); + write_float_3d_array(f20_0_8, 8, 8, 2); + printf("};\n"); + printf("static const DECLARE_ALIGNED(16, float, f34_0_12)[12][8][2] = {\n"); + write_float_3d_array(f34_0_12, 12, 8, 2); + printf("};\n"); + printf("static const DECLARE_ALIGNED(16, float, f34_1_8)[8][8][2] = {\n"); + write_float_3d_array(f34_1_8, 8, 8, 2); + printf("};\n"); + printf("static const DECLARE_ALIGNED(16, float, f34_2_4)[4][8][2] = {\n"); + write_float_3d_array(f34_2_4, 4, 8, 2); + printf("};\n"); + + printf("static TABLE_CONST DECLARE_ALIGNED(16, float, Q_fract_allpass)[2][50][3][2] = {\n"); + write_float_4d_array(Q_fract_allpass, 2, 50, 3, 2); + printf("};\n"); + printf("static const DECLARE_ALIGNED(16, float, phi_fract)[2][50][2] = {\n"); + write_float_3d_array(phi_fract, 2, 50, 2); + printf("};\n"); + + return 0; +} diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacps_tablegen.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacps_tablegen.h index 05a2af652..9df38ffd8 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacps_tablegen.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacps_tablegen.h @@ -28,6 +28,7 @@ #if CONFIG_HARDCODED_TABLES #define ps_tableinit() +#define TABLE_CONST const #include "libavcodec/aacps_tables.h" #else #include "libavutil/common.h" @@ -37,6 +38,7 @@ #define NR_ALLPASS_BANDS20 30 #define NR_ALLPASS_BANDS34 50 #define PS_AP_LINKS 3 +#define TABLE_CONST static float pd_re_smooth[8*8*8]; static float pd_im_smooth[8*8*8]; static float HA[46][8][4]; @@ -45,7 +47,7 @@ static DECLARE_ALIGNED(16, float, f20_0_8) [ 8][8][2]; static DECLARE_ALIGNED(16, float, f34_0_12)[12][8][2]; static DECLARE_ALIGNED(16, float, f34_1_8) [ 8][8][2]; static DECLARE_ALIGNED(16, float, f34_2_4) [ 4][8][2]; -static DECLARE_ALIGNED(16, float, Q_fract_allpass)[2][50][3][2]; +static TABLE_CONST DECLARE_ALIGNED(16, float, Q_fract_allpass)[2][50][3][2]; static DECLARE_ALIGNED(16, float, phi_fract)[2][50][2]; static const float g0_Q8[] = { diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacpsdsp.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacpsdsp.c index 9f6284413..5dc1a6aba 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacpsdsp.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacpsdsp.c @@ -93,7 +93,7 @@ static void ps_hybrid_synthesis_deint_c(float out[2][38][64], static void ps_decorrelate_c(float (*out)[2], float (*delay)[2], float (*ap_delay)[PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2], - const float phi_fract[2], float (*Q_fract)[2], + const float phi_fract[2], const float (*Q_fract)[2], const float *transient_gain, float g_decay_slope, int len) diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacpsdsp.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacpsdsp.h index 74a8af61e..0ef30236e 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacpsdsp.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacpsdsp.h @@ -38,7 +38,7 @@ typedef struct PSDSPContext { int i, int len); void (*decorrelate)(float (*out)[2], float (*delay)[2], float (*ap_delay)[PS_QMF_TIME_SLOTS+PS_MAX_AP_DELAY][2], - const float phi_fract[2], float (*Q_fract)[2], + const float phi_fract[2], const float (*Q_fract)[2], const float *transient_gain, float g_decay_slope, int len); diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacpsy.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacpsy.c new file mode 100644 index 000000000..d2a782e8d --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aacpsy.c @@ -0,0 +1,965 @@ +/* + * AAC encoder psychoacoustic model + * Copyright (C) 2008 Konstantin Shishkov + * + * 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 + * AAC encoder psychoacoustic model + */ + +#include "libavutil/attributes.h" +#include "libavutil/libm.h" + +#include "avcodec.h" +#include "aactab.h" +#include "psymodel.h" + +/*********************************** + * TODOs: + * try other bitrate controlling mechanism (maybe use ratecontrol.c?) + * control quality for quality-based output + **********************************/ + +/** + * constants for 3GPP AAC psychoacoustic model + * @{ + */ +#define PSY_3GPP_THR_SPREAD_HI 1.5f // spreading factor for low-to-hi threshold spreading (15 dB/Bark) +#define PSY_3GPP_THR_SPREAD_LOW 3.0f // spreading factor for hi-to-low threshold spreading (30 dB/Bark) +/* spreading factor for low-to-hi energy spreading, long block, > 22kbps/channel (20dB/Bark) */ +#define PSY_3GPP_EN_SPREAD_HI_L1 2.0f +/* spreading factor for low-to-hi energy spreading, long block, <= 22kbps/channel (15dB/Bark) */ +#define PSY_3GPP_EN_SPREAD_HI_L2 1.5f +/* spreading factor for low-to-hi energy spreading, short block (15 dB/Bark) */ +#define PSY_3GPP_EN_SPREAD_HI_S 1.5f +/* spreading factor for hi-to-low energy spreading, long block (30dB/Bark) */ +#define PSY_3GPP_EN_SPREAD_LOW_L 3.0f +/* spreading factor for hi-to-low energy spreading, short block (20dB/Bark) */ +#define PSY_3GPP_EN_SPREAD_LOW_S 2.0f + +#define PSY_3GPP_RPEMIN 0.01f +#define PSY_3GPP_RPELEV 2.0f + +#define PSY_3GPP_C1 3.0f /* log2(8) */ +#define PSY_3GPP_C2 1.3219281f /* log2(2.5) */ +#define PSY_3GPP_C3 0.55935729f /* 1 - C2 / C1 */ + +#define PSY_SNR_1DB 7.9432821e-1f /* -1dB */ +#define PSY_SNR_25DB 3.1622776e-3f /* -25dB */ + +#define PSY_3GPP_SAVE_SLOPE_L -0.46666667f +#define PSY_3GPP_SAVE_SLOPE_S -0.36363637f +#define PSY_3GPP_SAVE_ADD_L -0.84285712f +#define PSY_3GPP_SAVE_ADD_S -0.75f +#define PSY_3GPP_SPEND_SLOPE_L 0.66666669f +#define PSY_3GPP_SPEND_SLOPE_S 0.81818181f +#define PSY_3GPP_SPEND_ADD_L -0.35f +#define PSY_3GPP_SPEND_ADD_S -0.26111111f +#define PSY_3GPP_CLIP_LO_L 0.2f +#define PSY_3GPP_CLIP_LO_S 0.2f +#define PSY_3GPP_CLIP_HI_L 0.95f +#define PSY_3GPP_CLIP_HI_S 0.75f + +#define PSY_3GPP_AH_THR_LONG 0.5f +#define PSY_3GPP_AH_THR_SHORT 0.63f + +enum { + PSY_3GPP_AH_NONE, + PSY_3GPP_AH_INACTIVE, + PSY_3GPP_AH_ACTIVE +}; + +#define PSY_3GPP_BITS_TO_PE(bits) ((bits) * 1.18f) + +/* LAME psy model constants */ +#define PSY_LAME_FIR_LEN 21 ///< LAME psy model FIR order +#define AAC_BLOCK_SIZE_LONG 1024 ///< long block size +#define AAC_BLOCK_SIZE_SHORT 128 ///< short block size +#define AAC_NUM_BLOCKS_SHORT 8 ///< number of blocks in a short sequence +#define PSY_LAME_NUM_SUBBLOCKS 3 ///< Number of sub-blocks in each short block + +/** + * @} + */ + +/** + * information for single band used by 3GPP TS26.403-inspired psychoacoustic model + */ +typedef struct AacPsyBand{ + float energy; ///< band energy + float thr; ///< energy threshold + float thr_quiet; ///< threshold in quiet + float nz_lines; ///< number of non-zero spectral lines + float active_lines; ///< number of active spectral lines + float pe; ///< perceptual entropy + float pe_const; ///< constant part of the PE calculation + float norm_fac; ///< normalization factor for linearization + int avoid_holes; ///< hole avoidance flag +}AacPsyBand; + +/** + * single/pair channel context for psychoacoustic model + */ +typedef struct AacPsyChannel{ + AacPsyBand band[128]; ///< bands information + AacPsyBand prev_band[128]; ///< bands information from the previous frame + + float win_energy; ///< sliding average of channel energy + float iir_state[2]; ///< hi-pass IIR filter state + uint8_t next_grouping; ///< stored grouping scheme for the next frame (in case of 8 short window sequence) + enum WindowSequence next_window_seq; ///< window sequence to be used in the next frame + /* LAME psy model specific members */ + float attack_threshold; ///< attack threshold for this channel + float prev_energy_subshort[AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS]; + int prev_attack; ///< attack value for the last short block in the previous sequence +}AacPsyChannel; + +/** + * psychoacoustic model frame type-dependent coefficients + */ +typedef struct AacPsyCoeffs{ + float ath; ///< absolute threshold of hearing per bands + float barks; ///< Bark value for each spectral band in long frame + float spread_low[2]; ///< spreading factor for low-to-high threshold spreading in long frame + float spread_hi [2]; ///< spreading factor for high-to-low threshold spreading in long frame + float min_snr; ///< minimal SNR +}AacPsyCoeffs; + +/** + * 3GPP TS26.403-inspired psychoacoustic model specific data + */ +typedef struct AacPsyContext{ + int chan_bitrate; ///< bitrate per channel + int frame_bits; ///< average bits per frame + int fill_level; ///< bit reservoir fill level + struct { + float min; ///< minimum allowed PE for bit factor calculation + float max; ///< maximum allowed PE for bit factor calculation + float previous; ///< allowed PE of the previous frame + float correction; ///< PE correction factor + } pe; + AacPsyCoeffs psy_coef[2][64]; + AacPsyChannel *ch; +}AacPsyContext; + +/** + * LAME psy model preset struct + */ +typedef struct { + int quality; ///< Quality to map the rest of the vaules to. + /* This is overloaded to be both kbps per channel in ABR mode, and + * requested quality in constant quality mode. + */ + float st_lrm; ///< short threshold for L, R, and M channels +} PsyLamePreset; + +/** + * LAME psy model preset table for ABR + */ +static const PsyLamePreset psy_abr_map[] = { +/* TODO: Tuning. These were taken from LAME. */ +/* kbps/ch st_lrm */ + { 8, 6.60}, + { 16, 6.60}, + { 24, 6.60}, + { 32, 6.60}, + { 40, 6.60}, + { 48, 6.60}, + { 56, 6.60}, + { 64, 6.40}, + { 80, 6.00}, + { 96, 5.60}, + {112, 5.20}, + {128, 5.20}, + {160, 5.20} +}; + +/** +* LAME psy model preset table for constant quality +*/ +static const PsyLamePreset psy_vbr_map[] = { +/* vbr_q st_lrm */ + { 0, 4.20}, + { 1, 4.20}, + { 2, 4.20}, + { 3, 4.20}, + { 4, 4.20}, + { 5, 4.20}, + { 6, 4.20}, + { 7, 4.20}, + { 8, 4.20}, + { 9, 4.20}, + {10, 4.20} +}; + +/** + * LAME psy model FIR coefficient table + */ +static const float psy_fir_coeffs[] = { + -8.65163e-18 * 2, -0.00851586 * 2, -6.74764e-18 * 2, 0.0209036 * 2, + -3.36639e-17 * 2, -0.0438162 * 2, -1.54175e-17 * 2, 0.0931738 * 2, + -5.52212e-17 * 2, -0.313819 * 2 +}; + +#if ARCH_MIPS +# include "mips/aacpsy_mips.h" +#endif /* ARCH_MIPS */ + +/** + * Calculate the ABR attack threshold from the above LAME psymodel table. + */ +static float lame_calc_attack_threshold(int bitrate) +{ + /* Assume max bitrate to start with */ + int lower_range = 12, upper_range = 12; + int lower_range_kbps = psy_abr_map[12].quality; + int upper_range_kbps = psy_abr_map[12].quality; + int i; + + /* Determine which bitrates the value specified falls between. + * If the loop ends without breaking our above assumption of 320kbps was correct. + */ + for (i = 1; i < 13; i++) { + if (FFMAX(bitrate, psy_abr_map[i].quality) != bitrate) { + upper_range = i; + upper_range_kbps = psy_abr_map[i ].quality; + lower_range = i - 1; + lower_range_kbps = psy_abr_map[i - 1].quality; + break; /* Upper range found */ + } + } + + /* Determine which range the value specified is closer to */ + if ((upper_range_kbps - bitrate) > (bitrate - lower_range_kbps)) + return psy_abr_map[lower_range].st_lrm; + return psy_abr_map[upper_range].st_lrm; +} + +/** + * LAME psy model specific initialization + */ +static av_cold void lame_window_init(AacPsyContext *ctx, AVCodecContext *avctx) +{ + int i, j; + + for (i = 0; i < avctx->channels; i++) { + AacPsyChannel *pch = &ctx->ch[i]; + + if (avctx->flags & CODEC_FLAG_QSCALE) + pch->attack_threshold = psy_vbr_map[avctx->global_quality / FF_QP2LAMBDA].st_lrm; + else + pch->attack_threshold = lame_calc_attack_threshold(avctx->bit_rate / avctx->channels / 1000); + + for (j = 0; j < AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS; j++) + pch->prev_energy_subshort[j] = 10.0f; + } +} + +/** + * Calculate Bark value for given line. + */ +static av_cold float calc_bark(float f) +{ + return 13.3f * atanf(0.00076f * f) + 3.5f * atanf((f / 7500.0f) * (f / 7500.0f)); +} + +#define ATH_ADD 4 +/** + * Calculate ATH value for given frequency. + * Borrowed from Lame. + */ +static av_cold float ath(float f, float add) +{ + f /= 1000.0f; + return 3.64 * pow(f, -0.8) + - 6.8 * exp(-0.6 * (f - 3.4) * (f - 3.4)) + + 6.0 * exp(-0.15 * (f - 8.7) * (f - 8.7)) + + (0.6 + 0.04 * add) * 0.001 * f * f * f * f; +} + +static av_cold int psy_3gpp_init(FFPsyContext *ctx) { + AacPsyContext *pctx; + float bark; + int i, j, g, start; + float prev, minscale, minath, minsnr, pe_min; + const int chan_bitrate = ctx->avctx->bit_rate / ctx->avctx->channels; + const int bandwidth = ctx->avctx->cutoff ? ctx->avctx->cutoff : AAC_CUTOFF(ctx->avctx); + const float num_bark = calc_bark((float)bandwidth); + + ctx->model_priv_data = av_mallocz(sizeof(AacPsyContext)); + pctx = (AacPsyContext*) ctx->model_priv_data; + + pctx->chan_bitrate = chan_bitrate; + pctx->frame_bits = chan_bitrate * AAC_BLOCK_SIZE_LONG / ctx->avctx->sample_rate; + pctx->pe.min = 8.0f * AAC_BLOCK_SIZE_LONG * bandwidth / (ctx->avctx->sample_rate * 2.0f); + pctx->pe.max = 12.0f * AAC_BLOCK_SIZE_LONG * bandwidth / (ctx->avctx->sample_rate * 2.0f); + ctx->bitres.size = 6144 - pctx->frame_bits; + ctx->bitres.size -= ctx->bitres.size % 8; + pctx->fill_level = ctx->bitres.size; + minath = ath(3410, ATH_ADD); + for (j = 0; j < 2; j++) { + AacPsyCoeffs *coeffs = pctx->psy_coef[j]; + const uint8_t *band_sizes = ctx->bands[j]; + float line_to_frequency = ctx->avctx->sample_rate / (j ? 256.f : 2048.0f); + float avg_chan_bits = chan_bitrate * (j ? 128.0f : 1024.0f) / ctx->avctx->sample_rate; + /* reference encoder uses 2.4% here instead of 60% like the spec says */ + float bark_pe = 0.024f * PSY_3GPP_BITS_TO_PE(avg_chan_bits) / num_bark; + float en_spread_low = j ? PSY_3GPP_EN_SPREAD_LOW_S : PSY_3GPP_EN_SPREAD_LOW_L; + /* High energy spreading for long blocks <= 22kbps/channel and short blocks are the same. */ + float en_spread_hi = (j || (chan_bitrate <= 22.0f)) ? PSY_3GPP_EN_SPREAD_HI_S : PSY_3GPP_EN_SPREAD_HI_L1; + + i = 0; + prev = 0.0; + for (g = 0; g < ctx->num_bands[j]; g++) { + i += band_sizes[g]; + bark = calc_bark((i-1) * line_to_frequency); + coeffs[g].barks = (bark + prev) / 2.0; + prev = bark; + } + for (g = 0; g < ctx->num_bands[j] - 1; g++) { + AacPsyCoeffs *coeff = &coeffs[g]; + float bark_width = coeffs[g+1].barks - coeffs->barks; + coeff->spread_low[0] = pow(10.0, -bark_width * PSY_3GPP_THR_SPREAD_LOW); + coeff->spread_hi [0] = pow(10.0, -bark_width * PSY_3GPP_THR_SPREAD_HI); + coeff->spread_low[1] = pow(10.0, -bark_width * en_spread_low); + coeff->spread_hi [1] = pow(10.0, -bark_width * en_spread_hi); + pe_min = bark_pe * bark_width; + minsnr = exp2(pe_min / band_sizes[g]) - 1.5f; + coeff->min_snr = av_clipf(1.0f / minsnr, PSY_SNR_25DB, PSY_SNR_1DB); + } + start = 0; + for (g = 0; g < ctx->num_bands[j]; g++) { + minscale = ath(start * line_to_frequency, ATH_ADD); + for (i = 1; i < band_sizes[g]; i++) + minscale = FFMIN(minscale, ath((start + i) * line_to_frequency, ATH_ADD)); + coeffs[g].ath = minscale - minath; + start += band_sizes[g]; + } + } + + pctx->ch = av_mallocz(sizeof(AacPsyChannel) * ctx->avctx->channels); + + lame_window_init(pctx, ctx->avctx); + + return 0; +} + +/** + * IIR filter used in block switching decision + */ +static float iir_filter(int in, float state[2]) +{ + float ret; + + ret = 0.7548f * (in - state[0]) + 0.5095f * state[1]; + state[0] = in; + state[1] = ret; + return ret; +} + +/** + * window grouping information stored as bits (0 - new group, 1 - group continues) + */ +static const uint8_t window_grouping[9] = { + 0xB6, 0x6C, 0xD8, 0xB2, 0x66, 0xC6, 0x96, 0x36, 0x36 +}; + +/** + * Tell encoder which window types to use. + * @see 3GPP TS26.403 5.4.1 "Blockswitching" + */ +static av_unused FFPsyWindowInfo psy_3gpp_window(FFPsyContext *ctx, + const int16_t *audio, + const int16_t *la, + int channel, int prev_type) +{ + int i, j; + int br = ctx->avctx->bit_rate / ctx->avctx->channels; + int attack_ratio = br <= 16000 ? 18 : 10; + AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data; + AacPsyChannel *pch = &pctx->ch[channel]; + uint8_t grouping = 0; + int next_type = pch->next_window_seq; + FFPsyWindowInfo wi = { { 0 } }; + + if (la) { + float s[8], v; + int switch_to_eight = 0; + float sum = 0.0, sum2 = 0.0; + int attack_n = 0; + int stay_short = 0; + for (i = 0; i < 8; i++) { + for (j = 0; j < 128; j++) { + v = iir_filter(la[i*128+j], pch->iir_state); + sum += v*v; + } + s[i] = sum; + sum2 += sum; + } + for (i = 0; i < 8; i++) { + if (s[i] > pch->win_energy * attack_ratio) { + attack_n = i + 1; + switch_to_eight = 1; + break; + } + } + pch->win_energy = pch->win_energy*7/8 + sum2/64; + + wi.window_type[1] = prev_type; + switch (prev_type) { + case ONLY_LONG_SEQUENCE: + wi.window_type[0] = switch_to_eight ? LONG_START_SEQUENCE : ONLY_LONG_SEQUENCE; + next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : ONLY_LONG_SEQUENCE; + break; + case LONG_START_SEQUENCE: + wi.window_type[0] = EIGHT_SHORT_SEQUENCE; + grouping = pch->next_grouping; + next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE; + break; + case LONG_STOP_SEQUENCE: + wi.window_type[0] = switch_to_eight ? LONG_START_SEQUENCE : ONLY_LONG_SEQUENCE; + next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : ONLY_LONG_SEQUENCE; + break; + case EIGHT_SHORT_SEQUENCE: + stay_short = next_type == EIGHT_SHORT_SEQUENCE || switch_to_eight; + wi.window_type[0] = stay_short ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE; + grouping = next_type == EIGHT_SHORT_SEQUENCE ? pch->next_grouping : 0; + next_type = switch_to_eight ? EIGHT_SHORT_SEQUENCE : LONG_STOP_SEQUENCE; + break; + } + + pch->next_grouping = window_grouping[attack_n]; + pch->next_window_seq = next_type; + } else { + for (i = 0; i < 3; i++) + wi.window_type[i] = prev_type; + grouping = (prev_type == EIGHT_SHORT_SEQUENCE) ? window_grouping[0] : 0; + } + + wi.window_shape = 1; + if (wi.window_type[0] != EIGHT_SHORT_SEQUENCE) { + wi.num_windows = 1; + wi.grouping[0] = 1; + } else { + int lastgrp = 0; + wi.num_windows = 8; + for (i = 0; i < 8; i++) { + if (!((grouping >> i) & 1)) + lastgrp = i; + wi.grouping[lastgrp]++; + } + } + + return wi; +} + +/* 5.6.1.2 "Calculation of Bit Demand" */ +static int calc_bit_demand(AacPsyContext *ctx, float pe, int bits, int size, + int short_window) +{ + const float bitsave_slope = short_window ? PSY_3GPP_SAVE_SLOPE_S : PSY_3GPP_SAVE_SLOPE_L; + const float bitsave_add = short_window ? PSY_3GPP_SAVE_ADD_S : PSY_3GPP_SAVE_ADD_L; + const float bitspend_slope = short_window ? PSY_3GPP_SPEND_SLOPE_S : PSY_3GPP_SPEND_SLOPE_L; + const float bitspend_add = short_window ? PSY_3GPP_SPEND_ADD_S : PSY_3GPP_SPEND_ADD_L; + const float clip_low = short_window ? PSY_3GPP_CLIP_LO_S : PSY_3GPP_CLIP_LO_L; + const float clip_high = short_window ? PSY_3GPP_CLIP_HI_S : PSY_3GPP_CLIP_HI_L; + float clipped_pe, bit_save, bit_spend, bit_factor, fill_level; + + ctx->fill_level += ctx->frame_bits - bits; + ctx->fill_level = av_clip(ctx->fill_level, 0, size); + fill_level = av_clipf((float)ctx->fill_level / size, clip_low, clip_high); + clipped_pe = av_clipf(pe, ctx->pe.min, ctx->pe.max); + bit_save = (fill_level + bitsave_add) * bitsave_slope; + assert(bit_save <= 0.3f && bit_save >= -0.05000001f); + bit_spend = (fill_level + bitspend_add) * bitspend_slope; + assert(bit_spend <= 0.5f && bit_spend >= -0.1f); + /* The bit factor graph in the spec is obviously incorrect. + * bit_spend + ((bit_spend - bit_spend))... + * The reference encoder subtracts everything from 1, but also seems incorrect. + * 1 - bit_save + ((bit_spend + bit_save))... + * Hopefully below is correct. + */ + bit_factor = 1.0f - bit_save + ((bit_spend - bit_save) / (ctx->pe.max - ctx->pe.min)) * (clipped_pe - ctx->pe.min); + /* NOTE: The reference encoder attempts to center pe max/min around the current pe. */ + ctx->pe.max = FFMAX(pe, ctx->pe.max); + ctx->pe.min = FFMIN(pe, ctx->pe.min); + + return FFMIN(ctx->frame_bits * bit_factor, ctx->frame_bits + size - bits); +} + +static float calc_pe_3gpp(AacPsyBand *band) +{ + float pe, a; + + band->pe = 0.0f; + band->pe_const = 0.0f; + band->active_lines = 0.0f; + if (band->energy > band->thr) { + a = log2f(band->energy); + pe = a - log2f(band->thr); + band->active_lines = band->nz_lines; + if (pe < PSY_3GPP_C1) { + pe = pe * PSY_3GPP_C3 + PSY_3GPP_C2; + a = a * PSY_3GPP_C3 + PSY_3GPP_C2; + band->active_lines *= PSY_3GPP_C3; + } + band->pe = pe * band->nz_lines; + band->pe_const = a * band->nz_lines; + } + + return band->pe; +} + +static float calc_reduction_3gpp(float a, float desired_pe, float pe, + float active_lines) +{ + float thr_avg, reduction; + + if(active_lines == 0.0) + return 0; + + thr_avg = exp2f((a - pe) / (4.0f * active_lines)); + reduction = exp2f((a - desired_pe) / (4.0f * active_lines)) - thr_avg; + + return FFMAX(reduction, 0.0f); +} + +static float calc_reduced_thr_3gpp(AacPsyBand *band, float min_snr, + float reduction) +{ + float thr = band->thr; + + if (band->energy > thr) { + thr = sqrtf(thr); + thr = sqrtf(thr) + reduction; + thr *= thr; + thr *= thr; + + /* This deviates from the 3GPP spec to match the reference encoder. + * It performs min(thr_reduced, max(thr, energy/min_snr)) only for bands + * that have hole avoidance on (active or inactive). It always reduces the + * threshold of bands with hole avoidance off. + */ + if (thr > band->energy * min_snr && band->avoid_holes != PSY_3GPP_AH_NONE) { + thr = FFMAX(band->thr, band->energy * min_snr); + band->avoid_holes = PSY_3GPP_AH_ACTIVE; + } + } + + return thr; +} + +#ifndef calc_thr_3gpp +static void calc_thr_3gpp(const FFPsyWindowInfo *wi, const int num_bands, AacPsyChannel *pch, + const uint8_t *band_sizes, const float *coefs) +{ + int i, w, g; + int start = 0; + for (w = 0; w < wi->num_windows*16; w += 16) { + for (g = 0; g < num_bands; g++) { + AacPsyBand *band = &pch->band[w+g]; + + float form_factor = 0.0f; + float Temp; + band->energy = 0.0f; + for (i = 0; i < band_sizes[g]; i++) { + band->energy += coefs[start+i] * coefs[start+i]; + form_factor += sqrtf(fabs(coefs[start+i])); + } + Temp = band->energy > 0 ? sqrtf((float)band_sizes[g] / band->energy) : 0; + band->thr = band->energy * 0.001258925f; + band->nz_lines = form_factor * sqrtf(Temp); + + start += band_sizes[g]; + } + } +} +#endif /* calc_thr_3gpp */ + +#ifndef psy_hp_filter +static void psy_hp_filter(const float *firbuf, float *hpfsmpl, const float *psy_fir_coeffs) +{ + int i, j; + for (i = 0; i < AAC_BLOCK_SIZE_LONG; i++) { + float sum1, sum2; + sum1 = firbuf[i + (PSY_LAME_FIR_LEN - 1) / 2]; + sum2 = 0.0; + for (j = 0; j < ((PSY_LAME_FIR_LEN - 1) / 2) - 1; j += 2) { + sum1 += psy_fir_coeffs[j] * (firbuf[i + j] + firbuf[i + PSY_LAME_FIR_LEN - j]); + sum2 += psy_fir_coeffs[j + 1] * (firbuf[i + j + 1] + firbuf[i + PSY_LAME_FIR_LEN - j - 1]); + } + /* NOTE: The LAME psymodel expects it's input in the range -32768 to 32768. + * Tuning this for normalized floats would be difficult. */ + hpfsmpl[i] = (sum1 + sum2) * 32768.0f; + } +} +#endif /* psy_hp_filter */ + +/** + * Calculate band thresholds as suggested in 3GPP TS26.403 + */ +static void psy_3gpp_analyze_channel(FFPsyContext *ctx, int channel, + const float *coefs, const FFPsyWindowInfo *wi) +{ + AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data; + AacPsyChannel *pch = &pctx->ch[channel]; + int i, w, g; + float desired_bits, desired_pe, delta_pe, reduction= NAN, spread_en[128] = {0}; + float a = 0.0f, active_lines = 0.0f, norm_fac = 0.0f; + float pe = pctx->chan_bitrate > 32000 ? 0.0f : FFMAX(50.0f, 100.0f - pctx->chan_bitrate * 100.0f / 32000.0f); + const int num_bands = ctx->num_bands[wi->num_windows == 8]; + const uint8_t *band_sizes = ctx->bands[wi->num_windows == 8]; + AacPsyCoeffs *coeffs = pctx->psy_coef[wi->num_windows == 8]; + const float avoid_hole_thr = wi->num_windows == 8 ? PSY_3GPP_AH_THR_SHORT : PSY_3GPP_AH_THR_LONG; + + //calculate energies, initial thresholds and related values - 5.4.2 "Threshold Calculation" + calc_thr_3gpp(wi, num_bands, pch, band_sizes, coefs); + + //modify thresholds and energies - spread, threshold in quiet, pre-echo control + for (w = 0; w < wi->num_windows*16; w += 16) { + AacPsyBand *bands = &pch->band[w]; + + /* 5.4.2.3 "Spreading" & 5.4.3 "Spread Energy Calculation" */ + spread_en[0] = bands[0].energy; + for (g = 1; g < num_bands; g++) { + bands[g].thr = FFMAX(bands[g].thr, bands[g-1].thr * coeffs[g].spread_hi[0]); + spread_en[w+g] = FFMAX(bands[g].energy, spread_en[w+g-1] * coeffs[g].spread_hi[1]); + } + for (g = num_bands - 2; g >= 0; g--) { + bands[g].thr = FFMAX(bands[g].thr, bands[g+1].thr * coeffs[g].spread_low[0]); + spread_en[w+g] = FFMAX(spread_en[w+g], spread_en[w+g+1] * coeffs[g].spread_low[1]); + } + //5.4.2.4 "Threshold in quiet" + for (g = 0; g < num_bands; g++) { + AacPsyBand *band = &bands[g]; + + band->thr_quiet = band->thr = FFMAX(band->thr, coeffs[g].ath); + //5.4.2.5 "Pre-echo control" + if (!(wi->window_type[0] == LONG_STOP_SEQUENCE || (wi->window_type[1] == LONG_START_SEQUENCE && !w))) + band->thr = FFMAX(PSY_3GPP_RPEMIN*band->thr, FFMIN(band->thr, + PSY_3GPP_RPELEV*pch->prev_band[w+g].thr_quiet)); + + /* 5.6.1.3.1 "Preparatory steps of the perceptual entropy calculation" */ + pe += calc_pe_3gpp(band); + a += band->pe_const; + active_lines += band->active_lines; + + /* 5.6.1.3.3 "Selection of the bands for avoidance of holes" */ + if (spread_en[w+g] * avoid_hole_thr > band->energy || coeffs[g].min_snr > 1.0f) + band->avoid_holes = PSY_3GPP_AH_NONE; + else + band->avoid_holes = PSY_3GPP_AH_INACTIVE; + } + } + + /* 5.6.1.3.2 "Calculation of the desired perceptual entropy" */ + ctx->ch[channel].entropy = pe; + desired_bits = calc_bit_demand(pctx, pe, ctx->bitres.bits, ctx->bitres.size, wi->num_windows == 8); + desired_pe = PSY_3GPP_BITS_TO_PE(desired_bits); + /* NOTE: PE correction is kept simple. During initial testing it had very + * little effect on the final bitrate. Probably a good idea to come + * back and do more testing later. + */ + if (ctx->bitres.bits > 0) + desired_pe *= av_clipf(pctx->pe.previous / PSY_3GPP_BITS_TO_PE(ctx->bitres.bits), + 0.85f, 1.15f); + pctx->pe.previous = PSY_3GPP_BITS_TO_PE(desired_bits); + + if (desired_pe < pe) { + /* 5.6.1.3.4 "First Estimation of the reduction value" */ + for (w = 0; w < wi->num_windows*16; w += 16) { + reduction = calc_reduction_3gpp(a, desired_pe, pe, active_lines); + pe = 0.0f; + a = 0.0f; + active_lines = 0.0f; + for (g = 0; g < num_bands; g++) { + AacPsyBand *band = &pch->band[w+g]; + + band->thr = calc_reduced_thr_3gpp(band, coeffs[g].min_snr, reduction); + /* recalculate PE */ + pe += calc_pe_3gpp(band); + a += band->pe_const; + active_lines += band->active_lines; + } + } + + /* 5.6.1.3.5 "Second Estimation of the reduction value" */ + for (i = 0; i < 2; i++) { + float pe_no_ah = 0.0f, desired_pe_no_ah; + active_lines = a = 0.0f; + for (w = 0; w < wi->num_windows*16; w += 16) { + for (g = 0; g < num_bands; g++) { + AacPsyBand *band = &pch->band[w+g]; + + if (band->avoid_holes != PSY_3GPP_AH_ACTIVE) { + pe_no_ah += band->pe; + a += band->pe_const; + active_lines += band->active_lines; + } + } + } + desired_pe_no_ah = FFMAX(desired_pe - (pe - pe_no_ah), 0.0f); + if (active_lines > 0.0f) + reduction += calc_reduction_3gpp(a, desired_pe_no_ah, pe_no_ah, active_lines); + + pe = 0.0f; + for (w = 0; w < wi->num_windows*16; w += 16) { + for (g = 0; g < num_bands; g++) { + AacPsyBand *band = &pch->band[w+g]; + + if (active_lines > 0.0f) + band->thr = calc_reduced_thr_3gpp(band, coeffs[g].min_snr, reduction); + pe += calc_pe_3gpp(band); + band->norm_fac = band->active_lines / band->thr; + norm_fac += band->norm_fac; + } + } + delta_pe = desired_pe - pe; + if (fabs(delta_pe) > 0.05f * desired_pe) + break; + } + + if (pe < 1.15f * desired_pe) { + /* 6.6.1.3.6 "Final threshold modification by linearization" */ + norm_fac = 1.0f / norm_fac; + for (w = 0; w < wi->num_windows*16; w += 16) { + for (g = 0; g < num_bands; g++) { + AacPsyBand *band = &pch->band[w+g]; + + if (band->active_lines > 0.5f) { + float delta_sfb_pe = band->norm_fac * norm_fac * delta_pe; + float thr = band->thr; + + thr *= exp2f(delta_sfb_pe / band->active_lines); + if (thr > coeffs[g].min_snr * band->energy && band->avoid_holes == PSY_3GPP_AH_INACTIVE) + thr = FFMAX(band->thr, coeffs[g].min_snr * band->energy); + band->thr = thr; + } + } + } + } else { + /* 5.6.1.3.7 "Further perceptual entropy reduction" */ + g = num_bands; + while (pe > desired_pe && g--) { + for (w = 0; w < wi->num_windows*16; w+= 16) { + AacPsyBand *band = &pch->band[w+g]; + if (band->avoid_holes != PSY_3GPP_AH_NONE && coeffs[g].min_snr < PSY_SNR_1DB) { + coeffs[g].min_snr = PSY_SNR_1DB; + band->thr = band->energy * PSY_SNR_1DB; + pe += band->active_lines * 1.5f - band->pe; + } + } + } + /* TODO: allow more holes (unused without mid/side) */ + } + } + + for (w = 0; w < wi->num_windows*16; w += 16) { + for (g = 0; g < num_bands; g++) { + AacPsyBand *band = &pch->band[w+g]; + FFPsyBand *psy_band = &ctx->ch[channel].psy_bands[w+g]; + + psy_band->threshold = band->thr; + psy_band->energy = band->energy; + } + } + + memcpy(pch->prev_band, pch->band, sizeof(pch->band)); +} + +static void psy_3gpp_analyze(FFPsyContext *ctx, int channel, + const float **coeffs, const FFPsyWindowInfo *wi) +{ + int ch; + FFPsyChannelGroup *group = ff_psy_find_group(ctx, channel); + + for (ch = 0; ch < group->num_ch; ch++) + psy_3gpp_analyze_channel(ctx, channel + ch, coeffs[ch], &wi[ch]); +} + +static av_cold void psy_3gpp_end(FFPsyContext *apc) +{ + AacPsyContext *pctx = (AacPsyContext*) apc->model_priv_data; + av_freep(&pctx->ch); + av_freep(&apc->model_priv_data); +} + +static void lame_apply_block_type(AacPsyChannel *ctx, FFPsyWindowInfo *wi, int uselongblock) +{ + int blocktype = ONLY_LONG_SEQUENCE; + if (uselongblock) { + if (ctx->next_window_seq == EIGHT_SHORT_SEQUENCE) + blocktype = LONG_STOP_SEQUENCE; + } else { + blocktype = EIGHT_SHORT_SEQUENCE; + if (ctx->next_window_seq == ONLY_LONG_SEQUENCE) + ctx->next_window_seq = LONG_START_SEQUENCE; + if (ctx->next_window_seq == LONG_STOP_SEQUENCE) + ctx->next_window_seq = EIGHT_SHORT_SEQUENCE; + } + + wi->window_type[0] = ctx->next_window_seq; + ctx->next_window_seq = blocktype; +} + +static FFPsyWindowInfo psy_lame_window(FFPsyContext *ctx, const float *audio, + const float *la, int channel, int prev_type) +{ + AacPsyContext *pctx = (AacPsyContext*) ctx->model_priv_data; + AacPsyChannel *pch = &pctx->ch[channel]; + int grouping = 0; + int uselongblock = 1; + int attacks[AAC_NUM_BLOCKS_SHORT + 1] = { 0 }; + int i; + FFPsyWindowInfo wi = { { 0 } }; + + if (la) { + float hpfsmpl[AAC_BLOCK_SIZE_LONG]; + float const *pf = hpfsmpl; + float attack_intensity[(AAC_NUM_BLOCKS_SHORT + 1) * PSY_LAME_NUM_SUBBLOCKS]; + float energy_subshort[(AAC_NUM_BLOCKS_SHORT + 1) * PSY_LAME_NUM_SUBBLOCKS]; + float energy_short[AAC_NUM_BLOCKS_SHORT + 1] = { 0 }; + const float *firbuf = la + (AAC_BLOCK_SIZE_SHORT/4 - PSY_LAME_FIR_LEN); + int att_sum = 0; + + /* LAME comment: apply high pass filter of fs/4 */ + psy_hp_filter(firbuf, hpfsmpl, psy_fir_coeffs); + + /* Calculate the energies of each sub-shortblock */ + for (i = 0; i < PSY_LAME_NUM_SUBBLOCKS; i++) { + energy_subshort[i] = pch->prev_energy_subshort[i + ((AAC_NUM_BLOCKS_SHORT - 1) * PSY_LAME_NUM_SUBBLOCKS)]; + assert(pch->prev_energy_subshort[i + ((AAC_NUM_BLOCKS_SHORT - 2) * PSY_LAME_NUM_SUBBLOCKS + 1)] > 0); + attack_intensity[i] = energy_subshort[i] / pch->prev_energy_subshort[i + ((AAC_NUM_BLOCKS_SHORT - 2) * PSY_LAME_NUM_SUBBLOCKS + 1)]; + energy_short[0] += energy_subshort[i]; + } + + for (i = 0; i < AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS; i++) { + float const *const pfe = pf + AAC_BLOCK_SIZE_LONG / (AAC_NUM_BLOCKS_SHORT * PSY_LAME_NUM_SUBBLOCKS); + float p = 1.0f; + for (; pf < pfe; pf++) + p = FFMAX(p, fabsf(*pf)); + pch->prev_energy_subshort[i] = energy_subshort[i + PSY_LAME_NUM_SUBBLOCKS] = p; + energy_short[1 + i / PSY_LAME_NUM_SUBBLOCKS] += p; + /* NOTE: The indexes below are [i + 3 - 2] in the LAME source. + * Obviously the 3 and 2 have some significance, or this would be just [i + 1] + * (which is what we use here). What the 3 stands for is ambiguous, as it is both + * number of short blocks, and the number of sub-short blocks. + * It seems that LAME is comparing each sub-block to sub-block + 1 in the + * previous block. + */ + if (p > energy_subshort[i + 1]) + p = p / energy_subshort[i + 1]; + else if (energy_subshort[i + 1] > p * 10.0f) + p = energy_subshort[i + 1] / (p * 10.0f); + else + p = 0.0; + attack_intensity[i + PSY_LAME_NUM_SUBBLOCKS] = p; + } + + /* compare energy between sub-short blocks */ + for (i = 0; i < (AAC_NUM_BLOCKS_SHORT + 1) * PSY_LAME_NUM_SUBBLOCKS; i++) + if (!attacks[i / PSY_LAME_NUM_SUBBLOCKS]) + if (attack_intensity[i] > pch->attack_threshold) + attacks[i / PSY_LAME_NUM_SUBBLOCKS] = (i % PSY_LAME_NUM_SUBBLOCKS) + 1; + + /* should have energy change between short blocks, in order to avoid periodic signals */ + /* Good samples to show the effect are Trumpet test songs */ + /* GB: tuned (1) to avoid too many short blocks for test sample TRUMPET */ + /* RH: tuned (2) to let enough short blocks through for test sample FSOL and SNAPS */ + for (i = 1; i < AAC_NUM_BLOCKS_SHORT + 1; i++) { + float const u = energy_short[i - 1]; + float const v = energy_short[i]; + float const m = FFMAX(u, v); + if (m < 40000) { /* (2) */ + if (u < 1.7f * v && v < 1.7f * u) { /* (1) */ + if (i == 1 && attacks[0] < attacks[i]) + attacks[0] = 0; + attacks[i] = 0; + } + } + att_sum += attacks[i]; + } + + if (attacks[0] <= pch->prev_attack) + attacks[0] = 0; + + att_sum += attacks[0]; + /* 3 below indicates the previous attack happened in the last sub-block of the previous sequence */ + if (pch->prev_attack == 3 || att_sum) { + uselongblock = 0; + + for (i = 1; i < AAC_NUM_BLOCKS_SHORT + 1; i++) + if (attacks[i] && attacks[i-1]) + attacks[i] = 0; + } + } else { + /* We have no lookahead info, so just use same type as the previous sequence. */ + uselongblock = !(prev_type == EIGHT_SHORT_SEQUENCE); + } + + lame_apply_block_type(pch, &wi, uselongblock); + + wi.window_type[1] = prev_type; + if (wi.window_type[0] != EIGHT_SHORT_SEQUENCE) { + wi.num_windows = 1; + wi.grouping[0] = 1; + if (wi.window_type[0] == LONG_START_SEQUENCE) + wi.window_shape = 0; + else + wi.window_shape = 1; + } else { + int lastgrp = 0; + + wi.num_windows = 8; + wi.window_shape = 0; + for (i = 0; i < 8; i++) { + if (!((pch->next_grouping >> i) & 1)) + lastgrp = i; + wi.grouping[lastgrp]++; + } + } + + /* Determine grouping, based on the location of the first attack, and save for + * the next frame. + * FIXME: Move this to analysis. + * TODO: Tune groupings depending on attack location + * TODO: Handle more than one attack in a group + */ + for (i = 0; i < 9; i++) { + if (attacks[i]) { + grouping = i; + break; + } + } + pch->next_grouping = window_grouping[grouping]; + + pch->prev_attack = attacks[8]; + + return wi; +} + +const FFPsyModel ff_aac_psy_model = +{ + .name = "3GPP TS 26.403-inspired model", + .init = psy_3gpp_init, + .window = psy_lame_window, + .analyze = psy_3gpp_analyze, + .end = psy_3gpp_end, +}; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aactab.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aactab.c index 08c44e5d3..eb882e897 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aactab.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aactab.c @@ -34,7 +34,6 @@ #include DECLARE_ALIGNED(32, float, ff_aac_kbd_long_1024)[1024]; -DECLARE_ALIGNED(32, float, ff_aac_kbd_long_512 )[512]; DECLARE_ALIGNED(32, float, ff_aac_kbd_short_128)[128]; const uint8_t ff_aac_num_swb_1024[] = { @@ -1237,7 +1236,494 @@ const uint8_t ff_tns_max_bands_1024[] = { 31, 31, 34, 40, 42, 51, 46, 46, 42, 42, 42, 39, 39 }; +const uint8_t ff_tns_max_bands_512[] = { + 0, 0, 0, 31, 32, 37, 31, 31, 0, 0, 0, 0, 0 +}; + const uint8_t ff_tns_max_bands_128[] = { 9, 9, 10, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14 }; // @} + +const DECLARE_ALIGNED(32, float, ff_aac_eld_window)[1920] = { + 0.00338834, 0.00567745, 0.00847677, 0.01172641, + 0.01532555, 0.01917664, 0.02318809, 0.02729259, + 0.03144503, 0.03560261, 0.03972499, 0.04379783, + 0.04783094, 0.05183357, 0.05581342, 0.05977723, + 0.06373173, 0.06768364, 0.07163937, 0.07559976, + 0.07956096, 0.08352024, 0.08747623, 0.09143035, + 0.09538618, 0.09934771, 0.10331917, 0.10730456, + 0.11130697, 0.11532867, 0.11937133, 0.12343922, + 0.12753911, 0.13167705, 0.13585812, 0.14008529, + 0.14435986, 0.14868291, 0.15305531, 0.15747594, + 0.16194193, 0.16645070, 0.17099991, 0.17558633, + 0.18020600, 0.18485548, 0.18953191, 0.19423322, + 0.19895800, 0.20370512, 0.20847374, 0.21326312, + 0.21807244, 0.22290083, 0.22774742, 0.23261210, + 0.23749542, 0.24239767, 0.24731889, 0.25225887, + 0.25721719, 0.26219330, 0.26718648, 0.27219630, + 0.27722262, 0.28226514, 0.28732336, 0.29239628, + 0.29748247, 0.30258055, 0.30768914, 0.31280508, + 0.31792385, 0.32304172, 0.32815579, 0.33326397, + 0.33836470, 0.34345661, 0.34853868, 0.35361188, + 0.35867865, 0.36374072, 0.36879900, 0.37385347, + 0.37890349, 0.38394836, 0.38898730, 0.39401912, + 0.39904236, 0.40405575, 0.40905820, 0.41404819, + 0.41902398, 0.42398423, 0.42892805, 0.43385441, + 0.43876210, 0.44365014, 0.44851786, 0.45336632, + 0.45819759, 0.46301302, 0.46781309, 0.47259722, + 0.47736435, 0.48211365, 0.48684450, 0.49155594, + 0.49624679, 0.50091636, 0.50556440, 0.51019132, + 0.51479771, 0.51938391, 0.52394998, 0.52849587, + 0.53302151, 0.53752680, 0.54201160, 0.54647575, + 0.55091916, 0.55534181, 0.55974376, 0.56412513, + 0.56848615, 0.57282710, 0.57714834, 0.58145030, + 0.58492489, 0.58918511, 0.59342326, 0.59763936, + 0.60183347, 0.60600561, 0.61015581, 0.61428412, + 0.61839056, 0.62247517, 0.62653799, 0.63057912, + 0.63459872, 0.63859697, 0.64257403, 0.64653001, + 0.65046495, 0.65437887, 0.65827181, 0.66214383, + 0.66599499, 0.66982535, 0.67363499, 0.67742394, + 0.68119219, 0.68493972, 0.68866653, 0.69237258, + 0.69605778, 0.69972207, 0.70336537, 0.70698758, + 0.71058862, 0.71416837, 0.71772674, 0.72126361, + 0.72477889, 0.72827246, 0.73174419, 0.73519392, + 0.73862141, 0.74202643, 0.74540874, 0.74876817, + 0.75210458, 0.75541785, 0.75870785, 0.76197437, + 0.76521709, 0.76843570, 0.77162988, 0.77479939, + 0.77794403, 0.78106359, 0.78415789, 0.78722670, + 0.79026979, 0.79328694, 0.79627791, 0.79924244, + 0.80218027, 0.80509112, 0.80797472, 0.81083081, + 0.81365915, 0.81645949, 0.81923160, 0.82197528, + 0.82469037, 0.82737673, 0.83003419, 0.83266262, + 0.83526186, 0.83783176, 0.84037217, 0.84288297, + 0.84536401, 0.84781517, 0.85023632, 0.85262739, + 0.85498836, 0.85731921, 0.85961993, 0.86189052, + 0.86413101, 0.86634140, 0.86852173, 0.87067211, + 0.87279275, 0.87488384, 0.87694559, 0.87897824, + 0.88098206, 0.88295729, 0.88490423, 0.88682332, + 0.88871519, 0.89058048, 0.89241983, 0.89423391, + 0.89602338, 0.89778893, 0.89953126, 0.90125142, + 0.90295086, 0.90463104, 0.90629341, 0.90793946, + 0.90957067, 0.91118856, 0.91279464, 0.91439073, + 0.91597898, 0.91756153, 0.91914049, 0.92071690, + 0.92229070, 0.92386182, 0.92542993, 0.92698946, + 0.92852960, 0.93003929, 0.93150727, 0.93291739, + 0.93424863, 0.93547974, 0.93658982, 0.93756587, + 0.93894072, 0.93922780, 0.93955477, 0.93991290, + 0.94029104, 0.94067794, 0.94106258, 0.94144084, + 0.94181549, 0.94218963, 0.94256628, 0.94294662, + 0.94332998, 0.94371562, 0.94410280, 0.94449122, + 0.94488106, 0.94527249, 0.94566568, 0.94606074, + 0.94645772, 0.94685665, 0.94725759, 0.94766054, + 0.94806547, 0.94847234, 0.94888115, 0.94929190, + 0.94970469, 0.95011960, 0.95053672, 0.95095604, + 0.95137751, 0.95180105, 0.95222658, 0.95265413, + 0.95308380, 0.95351571, 0.95394994, 0.95438653, + 0.95482538, 0.95526643, 0.95570958, 0.95615486, + 0.95660234, 0.95705214, 0.95750433, 0.95795892, + 0.95841582, 0.95887493, 0.95933616, 0.95979949, + 0.96026500, 0.96073277, 0.96120286, 0.96167526, + 0.96214986, 0.96262655, 0.96310522, 0.96358586, + 0.96406853, 0.96455330, 0.96504026, 0.96552936, + 0.96602051, 0.96651360, 0.96700850, 0.96750520, + 0.96800376, 0.96850424, 0.96900670, 0.96951112, + 0.97001738, 0.97052533, 0.97103488, 0.97154597, + 0.97205867, 0.97257304, 0.97308915, 0.97360694, + 0.97412631, 0.97464711, 0.97516923, 0.97569262, + 0.97621735, 0.97674350, 0.97727111, 0.97780016, + 0.97833051, 0.97886205, 0.97939463, 0.97992823, + 0.98046291, 0.98099875, 0.98153580, 0.98207405, + 0.98261337, 0.98315364, 0.98369474, 0.98423664, + 0.98477941, 0.98532311, 0.98586780, 0.98641348, + 0.98696003, 0.98750734, 0.98805530, 0.98860389, + 0.98915320, 0.98970328, 0.99025423, 0.99080602, + 0.99135855, 0.99191171, 0.99246541, 0.99301962, + 0.99357443, 0.99412992, 0.99468617, 0.99524320, + 0.99580092, 0.99635926, 0.99691814, 0.99747748, + 0.99803721, 0.99859725, 0.99915752, 0.99971793, + 1.00028215, 1.00084319, 1.00140472, 1.00196665, + 1.00252889, 1.00309139, 1.00365404, 1.00421679, + 1.00477954, 1.00534221, 1.00590474, 1.00646713, + 1.00702945, 1.00759179, 1.00815424, 1.00871678, + 1.00927930, 1.00984169, 1.01040384, 1.01096575, + 1.01152747, 1.01208910, 1.01265070, 1.01321226, + 1.01377365, 1.01433478, 1.01489551, 1.01545584, + 1.01601582, 1.01657553, 1.01713502, 1.01769427, + 1.01825316, 1.01881154, 1.01936929, 1.01992639, + 1.02048289, 1.02103888, 1.02159441, 1.02214945, + 1.02270387, 1.02325751, 1.02381025, 1.02436204, + 1.02491295, 1.02546304, 1.02601238, 1.02656092, + 1.02710853, 1.02765508, 1.02820041, 1.02874449, + 1.02928737, 1.02982913, 1.03036981, 1.03090937, + 1.03144768, 1.03198460, 1.03252000, 1.03305384, + 1.03358617, 1.03411707, 1.03464659, 1.03517470, + 1.03570128, 1.03622620, 1.03674934, 1.03727066, + 1.03779024, 1.03830815, 1.03882446, 1.03933914, + 1.03985206, 1.04036312, 1.04087217, 1.04137920, + 1.04188428, 1.04238748, 1.04288888, 1.04338845, + 1.04388610, 1.04438170, 1.04487515, 1.04536645, + 1.04585569, 1.04634297, 1.04682838, 1.04731192, + 1.04779350, 1.04827303, 1.04875042, 1.04922568, + 1.04969891, 1.05017022, 1.05063974, 1.05110746, + 1.05157332, 1.05203721, 1.05249907, 1.05295889, + 1.05341676, 1.05387277, 1.05432700, 1.05477948, + 1.05523018, 1.05567906, 1.05612608, 1.05657124, + 1.05701459, 1.05745616, 1.05789601, 1.05833426, + 1.05877109, 1.05920669, 1.05964125, 1.06007444, + 1.06050542, 1.06093335, 1.06135746, 1.06177909, + 1.06220164, 1.06262858, 1.06306309, 1.06350050, + 1.06392837, 1.06433391, 1.06470443, 1.06502996, + 1.06481076, 1.06469765, 1.06445004, 1.06408002, + 1.06361382, 1.06307719, 1.06249453, 1.06188365, + 1.06125612, 1.06062291, 1.05999418, 1.05937132, + 1.05874726, 1.05811486, 1.05746728, 1.05680000, + 1.05611070, 1.05539715, 1.05465735, 1.05389329, + 1.05311083, 1.05231578, 1.05151372, 1.05070811, + 1.04990044, 1.04909210, 1.04828434, 1.04747647, + 1.04666590, 1.04585003, 1.04502628, 1.04419009, + 1.04333499, 1.04245452, 1.04154244, 1.04059452, + 1.03960846, 1.03858207, 1.03751326, 1.03640189, + 1.03524976, 1.03405868, 1.03283047, 1.03156812, + 1.03027574, 1.02895743, 1.02761717, 1.02625804, + 1.02488222, 1.02349184, 1.02208892, 1.02067450, + 1.01924861, 1.01781123, 1.01636229, 1.01490045, + 1.01342315, 1.01192778, 1.01041175, 1.00887284, + 1.00730915, 1.00571882, 1.00409996, 1.00245032, + 1.00076734, 0.99904842, 0.99729101, 0.99549380, + 0.99365664, 0.99177946, 0.98986234, 0.98791024, + 0.98593294, 0.98394037, 0.98194226, 0.97994532, + 0.97795324, 0.97596955, 0.97399748, 0.97203326, + 0.97006624, 0.96808546, 0.96608018, 0.96404416, + 0.96197556, 0.95987276, 0.95773420, 0.95556018, + 0.95335291, 0.95111462, 0.94884764, 0.94655663, + 0.94424858, 0.94193055, 0.93960953, 0.93729154, + 0.93498157, 0.93268456, 0.93040503, 0.92813771, + 0.92586755, 0.92357910, 0.92125731, 0.91889642, + 0.91649998, 0.91407191, 0.91161623, 0.90913975, + 0.90665202, 0.90416271, 0.90168115, 0.89920934, + 0.89674189, 0.89427312, 0.89179743, 0.88931147, + 0.88681415, 0.88430445, 0.88178141, 0.87924528, + 0.87669753, 0.87413966, 0.87157318, 0.86899958, + 0.86642037, 0.86383703, 0.86125106, 0.85866393, + 0.85604236, 0.85344385, 0.85083093, 0.84820550, + 0.84556943, 0.84292458, 0.84027278, 0.83761586, + 0.83495565, 0.83229393, 0.82963243, 0.82697135, + 0.82430933, 0.82164496, 0.81897669, 0.81630017, + 0.81360822, 0.81089355, 0.80814924, 0.80537741, + 0.80258920, 0.79979611, 0.79700954, 0.79423813, + 0.79148780, 0.78876432, 0.78607290, 0.78340590, + 0.78074288, 0.77806279, 0.77534514, 0.77258187, + 0.76977737, 0.76693654, 0.76406441, 0.76116851, + 0.75825892, 0.75534582, 0.75243924, 0.74954634, + 0.74667135, 0.74381840, 0.74099145, 0.73819147, + 0.73541641, 0.73266408, 0.72993193, 0.72720913, + 0.72447661, 0.72171494, 0.71890515, 0.71603932, + 0.71312056, 0.71015250, 0.70713900, 0.70409084, + 0.70102565, 0.69796137, 0.69491556, 0.69189772, + 0.68890931, 0.68595141, 0.68302498, 0.68012852, + 0.67725801, 0.67440936, 0.67157841, 0.66876081, + 0.66595195, 0.66314722, 0.66034194, 0.65753027, + 0.65470525, 0.65185984, 0.64898709, 0.64608214, + 0.64314221, 0.64016460, 0.63714680, 0.63409034, + 0.63100082, 0.62788400, 0.62474577, 0.62159473, + 0.61844225, 0.61529977, 0.61217866, 0.60908811, + 0.60603510, 0.60302654, 0.60006916, 0.59716588, + 0.59431580, 0.59151787, 0.58877068, 0.58606495, + 0.58338353, 0.58070891, 0.57802356, 0.57530864, + 0.57254404, 0.56970958, 0.56678577, 0.56376860, + 0.56066951, 0.55750064, 0.55427451, 0.55101301, + 0.54774732, 0.54450907, 0.54132936, 0.53822744, + 0.53521072, 0.53228613, 0.52945979, 0.52671997, + 0.52403708, 0.52138072, 0.51872085, 0.51603570, + 0.51331170, 0.51053560, 0.50769466, 0.50478931, + 0.50183308, 0.49884001, 0.49582406, 0.49279905, + 0.48985748, 0.48679641, 0.48379429, 0.48085363, + 0.47796576, 0.47512151, 0.47231151, 0.46952402, + 0.46674486, 0.46395978, 0.46115496, 0.45832607, + 0.45547830, 0.45261727, 0.44974866, 0.44688011, + 0.44402125, 0.44118178, 0.43837094, 0.43558772, + 0.43282082, 0.43005847, 0.42728913, 0.42450572, + 0.42170567, 0.41888658, 0.41604633, 0.41318897, + 0.41032472, 0.40746405, 0.40461724, 0.40178943, + 0.39898066, 0.39619073, 0.39341940, 0.39066519, + 0.38792536, 0.38519713, 0.38247773, 0.37976476, + 0.37705620, 0.37435006, 0.37164438, 0.36893869, + 0.36623396, 0.36353124, 0.36083153, 0.35813533, + 0.35544262, 0.35275338, 0.35006755, 0.34738530, + 0.34470699, 0.34203296, 0.33936359, 0.33669922, + 0.33404027, 0.33138711, 0.32874013, 0.32609944, + 0.32346493, 0.32083645, 0.31821388, 0.31559703, + 0.31298573, 0.31037987, 0.30777941, 0.30518446, + 0.30259525, 0.30001202, 0.29743499, 0.29486428, + 0.29229989, 0.28974179, 0.28718997, 0.28464452, + 0.28210562, 0.27957346, 0.27704820, 0.27452992, + 0.27201854, 0.26951399, 0.26701622, 0.26452533, + 0.26204158, 0.25956526, 0.25709662, 0.25463583, + 0.25218294, 0.24973798, 0.24730100, 0.24487207, + 0.24245133, 0.24003893, 0.23763500, 0.23523959, + 0.23285262, 0.23047401, 0.22810369, 0.22574170, + 0.22338818, 0.22104329, 0.21870719, 0.21637986, + 0.21406117, 0.21175095, 0.20944904, 0.20715535, + 0.20486987, 0.20259261, 0.20032356, 0.19806259, + 0.19580944, 0.19356385, 0.19132556, 0.18909442, + 0.18687040, 0.18465350, 0.18244372, 0.18024164, + 0.17804841, 0.17586521, 0.17369322, 0.17153360, + 0.16938755, 0.16725622, 0.16514081, 0.16304247, + 0.16098974, 0.15896561, 0.15696026, 0.15497259, + 0.15300151, 0.15104590, 0.14910466, 0.14717666, + 0.14526081, 0.14335599, 0.14146111, 0.13957570, + 0.13769993, 0.13583399, 0.13397806, 0.13213229, + 0.13029682, 0.12847178, 0.12665729, 0.12485353, + 0.12306074, 0.12127916, 0.11950900, 0.11775043, + 0.11600347, 0.11426820, 0.11254464, 0.11083292, + 0.10913318, 0.10744559, 0.10577028, 0.10410733, + 0.10245672, 0.10081842, 0.09919240, 0.09757872, + 0.09597750, 0.09438884, 0.09281288, 0.09124964, + 0.08969907, 0.08816111, 0.08663570, 0.08512288, + 0.08362274, 0.08213540, 0.08066096, 0.07919944, + 0.07775076, 0.07631484, 0.07489161, 0.07348108, + 0.07208335, 0.07069851, 0.06932666, 0.06796781, + 0.06662187, 0.06528874, 0.06396833, 0.06266065, + 0.06136578, 0.06008380, 0.05881480, 0.05755876, + 0.05631557, 0.05508511, 0.05386728, 0.05266206, + 0.05146951, 0.05028971, 0.04912272, 0.04796855, + 0.04682709, 0.04569825, 0.04458194, 0.04347817, + 0.04238704, 0.04130868, 0.04024318, 0.03919056, + 0.03815071, 0.03712352, 0.03610890, 0.03510679, + 0.03411720, 0.03314013, 0.03217560, 0.03122343, + 0.03028332, 0.02935494, 0.02843799, 0.02753230, + 0.02663788, 0.02575472, 0.02488283, 0.02402232, + 0.02317341, 0.02233631, 0.02151124, 0.02069866, + 0.01989922, 0.01911359, 0.01834241, 0.01758563, + 0.01684248, 0.01611219, 0.01539397, 0.01468726, + 0.01399167, 0.01330687, 0.01263250, 0.01196871, + 0.01131609, 0.01067527, 0.01004684, 0.00943077, + 0.00882641, 0.00823307, 0.00765011, 0.00707735, + 0.00651513, 0.00596377, 0.00542364, 0.00489514, + 0.00437884, 0.00387530, 0.00338509, 0.00290795, + 0.00244282, 0.00198860, 0.00154417, 0.00110825, + 0.00067934, 0.00025589, -0.00016357, -0.00057897, + -0.00098865, -0.00139089, -0.00178397, -0.00216547, + -0.00253230, -0.00288133, -0.00320955, -0.00351626, + -0.00380315, -0.00407198, -0.00432457, -0.00456373, + -0.00479326, -0.00501699, -0.00523871, -0.00546066, + -0.00568360, -0.00590821, -0.00613508, -0.00636311, + -0.00658944, -0.00681117, -0.00702540, -0.00722982, + -0.00742268, -0.00760226, -0.00776687, -0.00791580, + -0.00804933, -0.00816774, -0.00827139, -0.00836122, + -0.00843882, -0.00850583, -0.00856383, -0.00861430, + -0.00865853, -0.00869781, -0.00873344, -0.00876633, + -0.00879707, -0.00882622, -0.00885433, -0.00888132, + -0.00890652, -0.00892925, -0.00894881, -0.00896446, + -0.00897541, -0.00898088, -0.00898010, -0.00897234, + -0.00895696, -0.00893330, -0.00890076, -0.00885914, + -0.00880875, -0.00874987, -0.00868282, -0.00860825, + -0.00852716, -0.00844055, -0.00834941, -0.00825485, + -0.00815807, -0.00806025, -0.00796253, -0.00786519, + -0.00776767, -0.00766937, -0.00756971, -0.00746790, + -0.00736305, -0.00725422, -0.00714055, -0.00702161, + -0.00689746, -0.00676816, -0.00663381, -0.00649489, + -0.00635230, -0.00620694, -0.00605969, -0.00591116, + -0.00576167, -0.00561155, -0.00546110, -0.00531037, + -0.00515917, -0.00500732, -0.00485462, -0.00470075, + -0.00454530, -0.00438786, -0.00422805, -0.00406594, + -0.00390204, -0.00373686, -0.00357091, -0.00340448, + -0.00323770, -0.00307066, -0.00290344, -0.00273610, + -0.00256867, -0.00240117, -0.00223365, -0.00206614, + -0.00189866, -0.00173123, -0.00156390, -0.00139674, + -0.00122989, -0.00106351, -0.00089772, -0.00073267, + -0.00056849, -0.00040530, -0.00024324, -0.00008241, + 0.00008214, 0.00024102, 0.00039922, 0.00055660, + 0.00071299, 0.00086826, 0.00102224, 0.00117480, + 0.00132579, 0.00147507, 0.00162252, 0.00176804, + 0.00191161, 0.00205319, 0.00219277, 0.00233029, + 0.00246567, 0.00259886, 0.00272975, 0.00285832, + 0.00298453, 0.00310839, 0.00322990, 0.00334886, + 0.00346494, 0.00357778, 0.00368706, 0.00379273, + 0.00389501, 0.00399411, 0.00409020, 0.00418350, + 0.00427419, 0.00436249, 0.00444858, 0.00453250, + 0.00461411, 0.00469328, 0.00476988, 0.00484356, + 0.00491375, 0.00497987, 0.00504139, 0.00509806, + 0.00514990, 0.00519693, 0.00523920, 0.00527700, + 0.00531083, 0.00534122, 0.00536864, 0.00539357, + 0.00541649, 0.00543785, 0.00545809, 0.00547713, + 0.00549441, 0.00550936, 0.00552146, 0.00553017, + 0.00553494, 0.00553524, 0.00553058, 0.00552065, + 0.00550536, 0.00548459, 0.00545828, 0.00542662, + 0.00539007, 0.00534910, 0.00530415, 0.00525568, + 0.00520417, 0.00515009, 0.00509387, 0.00503595, + 0.00497674, 0.00491665, 0.00485605, 0.00479503, + 0.00473336, 0.00467082, 0.00460721, 0.00454216, + 0.00447517, 0.00440575, 0.00433344, 0.00425768, + 0.00417786, 0.00409336, 0.00400363, 0.00390837, + 0.00380759, 0.00370130, 0.00358952, 0.00347268, + 0.00335157, 0.00322699, 0.00309975, 0.00297088, + 0.00284164, 0.00271328, 0.00258700, 0.00246328, + 0.00234195, 0.00222281, 0.00210562, 0.00198958, + 0.00187331, 0.00175546, 0.00163474, 0.00151020, + 0.00138130, 0.00124750, 0.00110831, 0.00096411, + 0.00081611, 0.00066554, 0.00051363, 0.00036134, + 0.00020940, 0.00005853, -0.00009058, -0.00023783, + -0.00038368, -0.00052861, -0.00067310, -0.00081757, + -0.00096237, -0.00110786, -0.00125442, -0.00140210, + -0.00155065, -0.00169984, -0.00184940, -0.00199910, + -0.00214872, -0.00229798, -0.00244664, -0.00259462, + -0.00274205, -0.00288912, -0.00303596, -0.00318259, + -0.00332890, -0.00347480, -0.00362024, -0.00376519, + -0.00390962, -0.00405345, -0.00419658, -0.00433902, + -0.00448085, -0.00462219, -0.00476309, -0.00490357, + -0.00504361, -0.00518321, -0.00532243, -0.00546132, + -0.00559988, -0.00573811, -0.00587602, -0.00601363, + -0.00615094, -0.00628795, -0.00642466, -0.00656111, + -0.00669737, -0.00683352, -0.00696963, -0.00710578, + -0.00724208, -0.00737862, -0.00751554, -0.00765295, + -0.00779098, -0.00792976, -0.00806941, -0.00821006, + -0.00835183, -0.00849485, -0.00863926, -0.00878522, + -0.00893293, -0.00908260, -0.00923444, -0.00938864, + -0.00954537, -0.00970482, -0.00986715, -0.01003173, + -0.01019711, -0.01036164, -0.01052357, -0.01068184, + -0.01083622, -0.01098652, -0.01113252, -0.01127409, + -0.01141114, -0.01154358, -0.01167135, -0.01179439, + -0.01191268, -0.01202619, -0.01213493, -0.01223891, + -0.01233817, -0.01243275, -0.01252272, -0.01260815, + -0.01268915, -0.01276583, -0.01283832, -0.01290685, + -0.01297171, -0.01303320, -0.01309168, -0.01314722, + -0.01319969, -0.01324889, -0.01329466, -0.01333693, + -0.01337577, -0.01341125, -0.01344345, -0.01347243, + -0.01349823, -0.01352089, -0.01354045, -0.01355700, + -0.01357068, -0.01358164, -0.01359003, -0.01359587, + -0.01359901, -0.01359931, -0.01359661, -0.01359087, + -0.01358219, -0.01357065, -0.01355637, -0.01353935, + -0.01351949, -0.01349670, -0.01347088, -0.01344214, + -0.01341078, -0.01337715, -0.01334158, -0.01330442, + -0.01326601, -0.01322671, -0.01318689, -0.01314692, + -0.01310123, -0.01306470, -0.01302556, -0.01298381, + -0.01293948, -0.01289255, -0.01284305, -0.01279095, + -0.01273625, -0.01267893, -0.01261897, -0.01255632, + -0.01249096, -0.01242283, -0.01235190, -0.01227827, + -0.01220213, -0.01212366, -0.01204304, -0.01196032, + -0.01187543, -0.01178829, -0.01169884, -0.01160718, + -0.01151352, -0.01141809, -0.01132111, -0.01122272, + -0.01112304, -0.01102217, -0.01092022, -0.01081730, + -0.01071355, -0.01060912, -0.01050411, -0.01039854, + -0.01029227, -0.01018521, -0.01007727, -0.00996859, + -0.00985959, -0.00975063, -0.00964208, -0.00953420, + -0.00942723, -0.00932135, -0.00921677, -0.00911364, + -0.00901208, -0.00891220, -0.00881412, -0.00871792, + -0.00862369, -0.00853153, -0.00844149, -0.00835360, + -0.00826785, -0.00818422, -0.00810267, -0.00802312, + -0.00794547, -0.00786959, -0.00779533, -0.00772165, + -0.00764673, -0.00756886, -0.00748649, -0.00739905, + -0.00730681, -0.00721006, -0.00710910, -0.00700419, + -0.00689559, -0.00678354, -0.00666829, -0.00655007, + -0.00642916, -0.00630579, -0.00618022, -0.00605267, + -0.00592333, -0.00579240, -0.00566006, -0.00552651, + -0.00539194, -0.00525653, -0.00512047, -0.00498390, + -0.00484693, -0.00470969, -0.00457228, -0.00443482, + -0.00429746, -0.00416034, -0.00402359, -0.00388738, + -0.00375185, -0.00361718, -0.00348350, -0.00335100, + -0.00321991, -0.00309043, -0.00296276, -0.00283698, + -0.00271307, -0.00259098, -0.00247066, -0.00235210, + -0.00223531, -0.00212030, -0.00200709, -0.00189576, + -0.00178647, -0.00167936, -0.00157457, -0.00147216, + -0.00137205, -0.00127418, -0.00117849, -0.00108498, + -0.00099375, -0.00090486, -0.00081840, -0.00073444, + -0.00065309, -0.00057445, -0.00049860, -0.00042551, + -0.00035503, -0.00028700, -0.00022125, -0.00015761, + -0.00009588, -0.00003583, 0.00002272, 0.00007975, + 0.00013501, 0.00018828, 0.00023933, 0.00028784, + 0.00033342, 0.00037572, 0.00041438, 0.00044939, + 0.00048103, 0.00050958, 0.00053533, 0.00055869, + 0.00058015, 0.00060022, 0.00061935, 0.00063781, + 0.00065568, 0.00067303, 0.00068991, 0.00070619, + 0.00072155, 0.00073567, 0.00074826, 0.00075912, + 0.00076811, 0.00077509, 0.00077997, 0.00078275, + 0.00078351, 0.00078237, 0.00077943, 0.00077484, + 0.00076884, 0.00076160, 0.00075335, 0.00074423, + 0.00073442, 0.00072404, 0.00071323, 0.00070209, + 0.00069068, 0.00067906, 0.00066728, 0.00065534, + 0.00064321, 0.00063086, 0.00061824, 0.00060534, + 0.00059211, 0.00057855, 0.00056462, 0.00055033, + 0.00053566, 0.00052063, 0.00050522, 0.00048949, + 0.00047349, 0.00045728, 0.00044092, 0.00042447, + 0.00040803, 0.00039166, 0.00037544, 0.00035943, + 0.00034371, 0.00032833, 0.00031333, 0.00029874, + 0.00028452, 0.00027067, 0.00025715, 0.00024395, + 0.00023104, 0.00021842, 0.00020606, 0.00019398, + 0.00018218, 0.00017069, 0.00015953, 0.00014871, + 0.00013827, 0.00012823, 0.00011861, 0.00010942, + 0.00010067, 0.00009236, 0.00008448, 0.00007703, + 0.00006999, 0.00006337, 0.00005714, 0.00005129, + 0.00004583, 0.00004072, 0.00003597, 0.00003157, + 0.00002752, 0.00002380, 0.00002042, 0.00001736, + 0.00001461, 0.00001215, 0.00000998, 0.00000807, + 0.00000641, 0.00000499, 0.00000378, 0.00000278, + 0.00000196, 0.00000132, 0.00000082, 0.00000046, + 0.00000020, 0.00000005, -0.00000003, -0.00000006, + -0.00000004, -0.00000001, 0.00000001, 0.00000001, + 0.00000001, 0.00000001, -0.00000001, -0.00000004, + -0.00000005, -0.00000003, 0.00000005, 0.00000020, + 0.00000043, 0.00000077, 0.00000123, 0.00000183, + 0.00000257, 0.00000348, 0.00000455, 0.00000581, + 0.00000727, 0.00000893, 0.00001080, 0.00001290, + 0.00001522, 0.00001778, 0.00002057, 0.00002362, + 0.00002691, 0.00003044, 0.00003422, 0.00003824, + 0.00004250, 0.00004701, 0.00005176, 0.00005676, + 0.00006200, 0.00006749, 0.00007322, 0.00007920, + 0.00008541, 0.00009186, 0.00009854, 0.00010543, + 0.00011251, 0.00011975, 0.00012714, 0.00013465, + 0.00014227, 0.00014997, 0.00015775, 0.00016558, + 0.00017348, 0.00018144, 0.00018947, 0.00019756, + 0.00020573, 0.00021399, 0.00022233, 0.00023076, + 0.00023924, 0.00024773, 0.00025621, 0.00026462, + 0.00027293, 0.00028108, 0.00028904, 0.00029675, + 0.00030419, 0.00031132, 0.00031810, 0.00032453, + 0.00033061, 0.00033632, 0.00034169, 0.00034672, + 0.00035142, 0.00035580, 0.00035988, 0.00036369, + 0.00036723, 0.00037053, 0.00037361, 0.00037647, + 0.00037909, 0.00038145, 0.00038352, 0.00038527, + 0.00038663, 0.00038757, 0.00038801, 0.00038790, + 0.00038717, 0.00038572, 0.00038350, 0.00038044, + 0.00037651, 0.00037170, 0.00036597, 0.00035936, + 0.00035191, 0.00034370, 0.00033480, 0.00032531, + 0.00031537, 0.00030512, 0.00029470, 0.00028417, + 0.00027354, 0.00026279, 0.00025191, 0.00024081, + 0.00022933, 0.00021731, 0.00020458, 0.00019101, + 0.00017654, 0.00016106, 0.00014452, 0.00012694, + 0.00010848, 0.00008929, 0.00006953, 0.00004935, + 0.00002884, 0.00000813, -0.00001268, -0.00003357, + -0.00005457, -0.00007574, -0.00009714, -0.00011882, + -0.00014082, -0.00016318, -0.00018595, -0.00020912, + -0.00023265, -0.00025650, -0.00028060, -0.00030492, + -0.00032941, -0.00035400, -0.00037865, -0.00040333, + -0.00042804, -0.00045279, -0.00047759, -0.00050243, + -0.00052728, -0.00055209, -0.00057685, -0.00060153, + -0.00062611, -0.00065056, -0.00067485, -0.00069895, + -0.00072287, -0.00074660, -0.00077013, -0.00079345, + -0.00081653, -0.00083936, -0.00086192, -0.00088421, + -0.00090619, -0.00092786, -0.00094919, -0.00097017, + -0.00099077, -0.00101098, -0.00103077, -0.00105012, + -0.00106904, -0.00108750, -0.00110549, -0.00112301, + -0.00114005, -0.00115660, -0.00117265, -0.00118821, + -0.00120325, -0.00121779, -0.00123180, -0.00124528, + -0.00125822, -0.00127061, -0.00128243, -0.00129368, + -0.00130435, -0.00131445, -0.00132395, -0.00133285, + -0.00134113, -0.00134878, -0.00135577, -0.00136215, + -0.00136797, -0.00137333, -0.00137834, -0.00138305, + -0.00138748, -0.00139163, -0.00139551, -0.00139913, + -0.00140249, -0.00140559, -0.00140844, -0.00141102, + -0.00141334, -0.00141538, -0.00141714, -0.00141861, + -0.00141978, -0.00142064, -0.00142117, -0.00142138, + -0.00142125, -0.00142077, -0.00141992, -0.00141870, + -0.00141710, -0.00141510, -0.00141268, -0.00140986, + -0.00140663, -0.00140301, -0.00139900, -0.00139460, + -0.00138981, -0.00138464, -0.00137908, -0.00137313, + -0.00136680, -0.00136010, -0.00135301, -0.00134555, + -0.00133772, -0.00132952, -0.00132095, -0.00131201, + -0.00130272, -0.00129307, -0.00128309, -0.00127277, + -0.00126211, -0.00125113, -0.00123981, -0.00122817, + -0.00121622, -0.00120397, -0.00119141, -0.00117859, + -0.00116552, -0.00115223, -0.00113877, -0.00112517, + -0.00111144, -0.00109764, -0.00108377, -0.00106989, +}; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aactab.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aactab.h index e06f6824a..5ed850888 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aactab.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/aactab.h @@ -45,8 +45,8 @@ * @{ */ DECLARE_ALIGNED(32, extern float, ff_aac_kbd_long_1024)[1024]; -DECLARE_ALIGNED(32, extern float, ff_aac_kbd_long_512 )[512]; DECLARE_ALIGNED(32, extern float, ff_aac_kbd_short_128)[128]; +const DECLARE_ALIGNED(32, extern float, ff_aac_eld_window)[1920]; // @} /* @name number of scalefactor window bands for long and short transform windows respectively @@ -75,6 +75,7 @@ extern const uint16_t * const ff_swb_offset_512 [13]; extern const uint16_t * const ff_swb_offset_128 [13]; extern const uint8_t ff_tns_max_bands_1024[13]; +extern const uint8_t ff_tns_max_bands_512 [13]; extern const uint8_t ff_tns_max_bands_128 [13]; #endif /* AVCODEC_AACTAB_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3.h index e609bb51c..0cc9e2c98 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3.h @@ -82,6 +82,38 @@ typedef enum { AC3_CHMODE_3F2R } AC3ChannelMode; +/** Dolby Surround mode */ +typedef enum AC3DolbySurroundMode { + AC3_DSURMOD_NOTINDICATED = 0, + AC3_DSURMOD_OFF, + AC3_DSURMOD_ON, + AC3_DSURMOD_RESERVED +} AC3DolbySurroundMode; + +/** Dolby Surround EX mode */ +typedef enum AC3DolbySurroundEXMode { + AC3_DSUREXMOD_NOTINDICATED = 0, + AC3_DSUREXMOD_OFF, + AC3_DSUREXMOD_ON, + AC3_DSUREXMOD_PLIIZ +} AC3DolbySurroundEXMode; + +/** Dolby Headphone mode */ +typedef enum AC3DolbyHeadphoneMode { + AC3_DHEADPHONMOD_NOTINDICATED = 0, + AC3_DHEADPHONMOD_OFF, + AC3_DHEADPHONMOD_ON, + AC3_DHEADPHONMOD_RESERVED +} AC3DolbyHeadphoneMode; + +/** Preferred Stereo Downmix mode */ +typedef enum AC3PreferredStereoDownmixMode { + AC3_DMIXMOD_NOTINDICATED = 0, + AC3_DMIXMOD_LTRT, + AC3_DMIXMOD_LORO, + AC3_DMIXMOD_DPLII // reserved value in A/52, but used by encoders to indicate DPL2 +} AC3PreferredStereoDownmixMode; + typedef struct AC3BitAllocParameters { int sr_code; int sr_shift; @@ -110,6 +142,9 @@ typedef struct AC3HeaderInfo { int surround_mix_level; ///< Surround mix level index uint16_t channel_map; int num_blocks; ///< number of audio blocks +#if AV_HAVE_INCOMPATIBLE_LIBAV_ABI + int dolby_surround_mode; +#endif /** @} */ /** @name Derived values @@ -122,6 +157,9 @@ typedef struct AC3HeaderInfo { uint16_t frame_size; uint64_t channel_layout; /** @} */ +#if !AV_HAVE_INCOMPATIBLE_LIBAV_ABI + int dolby_surround_mode; +#endif } AC3HeaderInfo; typedef enum { diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3_parser.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3_parser.c index 8dc4c0d48..dd6d77c9a 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3_parser.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3_parser.c @@ -47,9 +47,16 @@ static const uint8_t center_levels[4] = { 4, 5, 6, 5 }; static const uint8_t surround_levels[4] = { 4, 6, 7, 6 }; -int avpriv_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) +int avpriv_ac3_parse_header2(GetBitContext *gbc, AC3HeaderInfo **phdr) { int frame_size_code; + AC3HeaderInfo *hdr; + + if (!*phdr) + *phdr = av_mallocz(sizeof(AC3HeaderInfo)); + if (!*phdr) + return AVERROR(ENOMEM); + hdr = *phdr; memset(hdr, 0, sizeof(*hdr)); @@ -68,6 +75,9 @@ int avpriv_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) hdr->center_mix_level = 5; // -4.5dB hdr->surround_mix_level = 6; // -6.0dB + /* set default dolby surround mode */ + hdr->dolby_surround_mode = AC3_DSURMOD_NOTINDICATED; + if(hdr->bitstream_id <= 10) { /* Normal AC-3 */ hdr->crc1 = get_bits(gbc, 16); @@ -85,7 +95,7 @@ int avpriv_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) hdr->channel_mode = get_bits(gbc, 3); if(hdr->channel_mode == AC3_CHMODE_STEREO) { - skip_bits(gbc, 2); // skip dsurmod + hdr->dolby_surround_mode = get_bits(gbc, 2); } else { if((hdr->channel_mode & 1) && hdr->channel_mode != AC3_CHMODE_MONO) hdr-> center_mix_level = center_levels[get_bits(gbc, 2)]; @@ -141,6 +151,15 @@ int avpriv_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) return 0; } +int avpriv_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) +{ + AC3HeaderInfo tmp, *ptmp = &tmp; + int ret = avpriv_ac3_parse_header2(gbc, &ptmp); + + memcpy(hdr, ptmp, ((intptr_t)&tmp.channel_layout) - ((intptr_t)&tmp) + sizeof(uint64_t)); + return ret; +} + static int ac3_sync(uint64_t state, AACAC3ParseContext *hdr_info, int *need_next_header, int *new_frame_start) { @@ -149,11 +168,11 @@ static int ac3_sync(uint64_t state, AACAC3ParseContext *hdr_info, uint64_t u64; uint8_t u8[8]; } tmp = { av_be2ne64(state) }; - AC3HeaderInfo hdr; + AC3HeaderInfo hdr, *phdr = &hdr; GetBitContext gbc; init_get_bits(&gbc, tmp.u8+8-AC3_HEADER_SIZE, 54); - err = avpriv_ac3_parse_header(&gbc, &hdr); + err = avpriv_ac3_parse_header2(&gbc, &phdr); if(err < 0) return 0; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3_parser.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3_parser.h index b5022de2d..f37387d76 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3_parser.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3_parser.h @@ -31,11 +31,14 @@ * Parse the header up to the lfeon element, which is the first 52 or 54 bits * depending on the audio coding mode. * @param[in] gbc BitContext containing the first 54 bits of the frame. - * @param[out] hdr Pointer to struct where header info is written. + * @param[out] hdr Pointer to Pointer to struct where header info is written. + * will be allocated if NULL * @return Returns 0 on success, -1 if there is a sync word mismatch, * -2 if the bsid (version) element is invalid, -3 if the fscod (sample rate) * element is invalid, or -4 if the frmsizecod (bit rate) element is invalid. */ +int avpriv_ac3_parse_header2(GetBitContext *gbc, AC3HeaderInfo **hdr); + int avpriv_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr); #endif /* AVCODEC_AC3_PARSER_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3dec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3dec.c index 48b82e1c8..7d5e4b5db 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3dec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3dec.c @@ -29,7 +29,9 @@ #include #include +#include "libavutil/channel_layout.h" #include "libavutil/crc.h" +#include "libavutil/downmix_info.h" #include "libavutil/opt.h" #include "libavutil/internal.h" #include "internal.h" @@ -77,6 +79,15 @@ static const float gain_levels[9] = { LEVEL_MINUS_9DB }; +/** Adjustments in dB gain (LFE, +10 to -21 dB) */ +static const float gain_levels_lfe[32] = { + 3.162275, 2.818382, 2.511886, 2.238719, 1.995261, 1.778278, 1.584893, + 1.412536, 1.258924, 1.122018, 1.000000, 0.891251, 0.794328, 0.707946, + 0.630957, 0.562341, 0.501187, 0.446683, 0.398107, 0.354813, 0.316227, + 0.281838, 0.251188, 0.223872, 0.199526, 0.177828, 0.158489, 0.141253, + 0.125892, 0.112201, 0.100000, 0.089125 +}; + /** * Table for default stereo downmixing coefficients * reference: Section 7.8.2 Downmixing Into Two Channels @@ -179,13 +190,20 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx) avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; /* allow downmixing to stereo or mono */ - AV_NOWARN_DEPRECATED( - if (avctx->channels > 0 && avctx->request_channels > 0 && - avctx->request_channels < avctx->channels && - avctx->request_channels <= 2) { - avctx->channels = avctx->request_channels; - } - ); +#if FF_API_REQUEST_CHANNELS +FF_DISABLE_DEPRECATION_WARNINGS + if (avctx->request_channels == 1) + avctx->request_channel_layout = AV_CH_LAYOUT_MONO; + else if (avctx->request_channels == 2) + avctx->request_channel_layout = AV_CH_LAYOUT_STEREO; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + if (avctx->channels > 1 && + avctx->request_channel_layout == AV_CH_LAYOUT_MONO) + avctx->channels = 1; + else if (avctx->channels > 2 && + avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) + avctx->channels = 2; s->downmixed = 1; for (i = 0; i < AC3_MAX_CHANNELS; i++) { @@ -220,12 +238,26 @@ static int ac3_parse_header(AC3DecodeContext *s) skip_bits(gbc, 2); //skip copyright bit and original bitstream bit - /* skip the timecodes (or extra bitstream information for Alternate Syntax) - TODO: read & use the xbsi1 downmix levels */ - if (get_bits1(gbc)) - skip_bits(gbc, 14); //skip timecode1 / xbsi1 - if (get_bits1(gbc)) - skip_bits(gbc, 14); //skip timecode2 / xbsi2 + /* skip the timecodes or parse the Alternate Bit Stream Syntax */ + if (s->bitstream_id != 6) { + if (get_bits1(gbc)) + skip_bits(gbc, 14); //skip timecode1 + if (get_bits1(gbc)) + skip_bits(gbc, 14); //skip timecode2 + } else { + if (get_bits1(gbc)) { + s->preferred_downmix = get_bits(gbc, 2); + s->center_mix_level_ltrt = get_bits(gbc, 3); + s->surround_mix_level_ltrt = av_clip(get_bits(gbc, 3), 3, 7); + s->center_mix_level = get_bits(gbc, 3); + s->surround_mix_level = av_clip(get_bits(gbc, 3), 3, 7); + } + if (get_bits1(gbc)) { + s->dolby_surround_ex_mode = get_bits(gbc, 2); + s->dolby_headphone_mode = get_bits(gbc, 2); + skip_bits(gbc, 10); // skip adconvtyp (1), xbsi2 (8), encinfo (1) + } + } /* skip additional bitstream info */ if (get_bits1(gbc)) { @@ -243,18 +275,18 @@ static int ac3_parse_header(AC3DecodeContext *s) */ static int parse_frame_header(AC3DecodeContext *s) { - AC3HeaderInfo hdr; + AC3HeaderInfo hdr, *phdr=&hdr; int err; - err = avpriv_ac3_parse_header(&s->gbc, &hdr); + err = avpriv_ac3_parse_header2(&s->gbc, &phdr); if (err) return err; /* get decoding parameters from header info */ s->bit_alloc_params.sr_code = hdr.sr_code; + s->bitstream_id = hdr.bitstream_id; s->bitstream_mode = hdr.bitstream_mode; s->channel_mode = hdr.channel_mode; - s->channel_layout = hdr.channel_layout; s->lfe_on = hdr.lfe_on; s->bit_alloc_params.sr_shift = hdr.sr_shift; s->sample_rate = hdr.sample_rate; @@ -263,11 +295,18 @@ static int parse_frame_header(AC3DecodeContext *s) s->fbw_channels = s->channels - s->lfe_on; s->lfe_ch = s->fbw_channels + 1; s->frame_size = hdr.frame_size; + s->preferred_downmix = AC3_DMIXMOD_NOTINDICATED; s->center_mix_level = hdr.center_mix_level; + s->center_mix_level_ltrt = 4; // -3.0dB s->surround_mix_level = hdr.surround_mix_level; + s->surround_mix_level_ltrt = 4; // -3.0dB + s->lfe_mix_level_exists = 0; s->num_blocks = hdr.num_blocks; s->frame_type = hdr.frame_type; s->substreamid = hdr.substreamid; + s->dolby_surround_mode = hdr.dolby_surround_mode; + s->dolby_surround_ex_mode = AC3_DSUREXMOD_NOTINDICATED; + s->dolby_headphone_mode = AC3_DHEADPHONMOD_NOTINDICATED; if (s->lfe_on) { s->start_freq[s->lfe_ch] = 0; @@ -276,7 +315,7 @@ static int parse_frame_header(AC3DecodeContext *s) s->channel_in_cpl[s->lfe_ch] = 0; } - if (hdr.bitstream_id <= 10) { + if (s->bitstream_id <= 10) { s->eac3 = 0; s->snr_offset_strategy = 2; s->block_switch_syntax = 1; @@ -491,6 +530,10 @@ static void ac3_decode_transform_coeffs_ch(AC3DecodeContext *s, int ch_index, ma break; default: /* 6 to 15 */ /* Shift mantissa and sign-extend it. */ + if (bap > 15) { + av_log(s->avctx, AV_LOG_ERROR, "bap %d is invalid in plain AC-3\n", bap); + bap = 15; + } mantissa = get_sbits(gbc, quantization_tab[bap]); mantissa <<= 24 - quantization_tab[bap]; break; @@ -750,8 +793,13 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) i = !s->channel_mode; do { if (get_bits1(gbc)) { - s->dynamic_range[i] = ((dynamic_range_tab[get_bits(gbc, 8)] - 1.0) * - s->drc_scale) + 1.0; + /* Allow asymmetric application of DRC when drc_scale > 1. + Amplification of quiet sounds is enhanced */ + float range = dynamic_range_tab[get_bits(gbc, 8)]; + if (range > 1.0 || s->drc_scale <= 1.0) + s->dynamic_range[i] = powf(range, s->drc_scale); + else + s->dynamic_range[i] = range; } else if (blk == 0) { s->dynamic_range[i] = 1.0f; } @@ -1274,6 +1322,8 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int blk, ch, err, ret; const uint8_t *channel_map; const float *output[AC3_MAX_CHANNELS]; + enum AVMatrixEncoding matrix_encoding; + AVDownmixInfo *downmix_info; /* copy input buffer to decoder context to avoid reading past the end of the buffer, which can be caused by a damaged input stream. */ @@ -1333,6 +1383,8 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, if (av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, &buf[2], s->frame_size - 2)) { av_log(avctx, AV_LOG_ERROR, "frame CRC mismatch\n"); + if (avctx->err_recognition & AV_EF_EXPLODE) + return AVERROR_INVALIDDATA; err = AAC_AC3_PARSE_ERROR_CRC; } } @@ -1350,16 +1402,15 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, s->output_mode = s->channel_mode; if (s->lfe_on) s->output_mode |= AC3_OUTPUT_LFEON; - AV_NOWARN_DEPRECATED( - if (avctx->request_channels > 0 && avctx->request_channels <= 2 && - avctx->request_channels < s->channels) { - s->out_channels = avctx->request_channels; - s->output_mode = avctx->request_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO; - s->channel_layout = avpriv_ac3_channel_layout_tab[s->output_mode]; + if (s->channels > 1 && + avctx->request_channel_layout == AV_CH_LAYOUT_MONO) { + s->out_channels = 1; + s->output_mode = AC3_CHMODE_MONO; + } else if (s->channels > 2 && + avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) { + s->out_channels = 2; + s->output_mode = AC3_CHMODE_STEREO; } - ); - avctx->channels = s->out_channels; - avctx->channel_layout = s->channel_layout; s->loro_center_mix_level = gain_levels[s-> center_mix_level]; s->loro_surround_mix_level = gain_levels[s->surround_mix_level]; @@ -1375,6 +1426,9 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, return AVERROR_INVALIDDATA; } avctx->channels = s->out_channels; + avctx->channel_layout = avpriv_ac3_channel_layout_tab[s->output_mode & ~AC3_OUTPUT_LFEON]; + if (s->output_mode & AC3_OUTPUT_LFEON) + avctx->channel_layout |= AV_CH_LOW_FREQUENCY; /* set audio service type based on bitstream mode for AC-3 */ avctx->audio_service_type = s->bitstream_mode; @@ -1418,6 +1472,62 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, for (ch = 0; ch < s->out_channels; ch++) memcpy(s->output[ch], output[ch], sizeof(**output) * AC3_BLOCK_SIZE); + /* + * AVMatrixEncoding + * + * Check whether the input layout is compatible, and make sure we're not + * downmixing (else the matrix encoding is no longer applicable). + */ + matrix_encoding = AV_MATRIX_ENCODING_NONE; + if (s->channel_mode == AC3_CHMODE_STEREO && + s->channel_mode == (s->output_mode & ~AC3_OUTPUT_LFEON)) { + if (s->dolby_surround_mode == AC3_DSURMOD_ON) + matrix_encoding = AV_MATRIX_ENCODING_DOLBY; + else if (s->dolby_headphone_mode == AC3_DHEADPHONMOD_ON) + matrix_encoding = AV_MATRIX_ENCODING_DOLBYHEADPHONE; + } else if (s->channel_mode >= AC3_CHMODE_2F2R && + s->channel_mode == (s->output_mode & ~AC3_OUTPUT_LFEON)) { + switch (s->dolby_surround_ex_mode) { + case AC3_DSUREXMOD_ON: // EX or PLIIx + matrix_encoding = AV_MATRIX_ENCODING_DOLBYEX; + break; + case AC3_DSUREXMOD_PLIIZ: + matrix_encoding = AV_MATRIX_ENCODING_DPLIIZ; + break; + default: // not indicated or off + break; + } + } + if ((ret = ff_side_data_update_matrix_encoding(frame, matrix_encoding)) < 0) + return ret; + + /* AVDownmixInfo */ + if ((downmix_info = av_downmix_info_update_side_data(frame))) { + switch (s->preferred_downmix) { + case AC3_DMIXMOD_LTRT: + downmix_info->preferred_downmix_type = AV_DOWNMIX_TYPE_LTRT; + break; + case AC3_DMIXMOD_LORO: + downmix_info->preferred_downmix_type = AV_DOWNMIX_TYPE_LORO; + break; + case AC3_DMIXMOD_DPLII: + downmix_info->preferred_downmix_type = AV_DOWNMIX_TYPE_DPLII; + break; + default: + downmix_info->preferred_downmix_type = AV_DOWNMIX_TYPE_UNKNOWN; + break; + } + downmix_info->center_mix_level = gain_levels[s-> center_mix_level]; + downmix_info->center_mix_level_ltrt = gain_levels[s-> center_mix_level_ltrt]; + downmix_info->surround_mix_level = gain_levels[s-> surround_mix_level]; + downmix_info->surround_mix_level_ltrt = gain_levels[s->surround_mix_level_ltrt]; + if (s->lfe_mix_level_exists) + downmix_info->lfe_mix_level = gain_levels_lfe[s->lfe_mix_level]; + else + downmix_info->lfe_mix_level = 0.0; // -inf dB + } else + return AVERROR(ENOMEM); + *got_frame_ptr = 1; return FFMIN(buf_size, s->frame_size); @@ -1438,7 +1548,7 @@ static av_cold int ac3_decode_end(AVCodecContext *avctx) #define OFFSET(x) offsetof(AC3DecodeContext, x) #define PAR (AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM) static const AVOption options[] = { - { "drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), AV_OPT_TYPE_FLOAT, {.dbl = 1.0}, 0.0, 1.0, PAR }, + { "drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), AV_OPT_TYPE_FLOAT, {.dbl = 1.0}, 0.0, 6.0, PAR }, {"dmix_mode", "Preferred Stereo Downmix Mode", OFFSET(preferred_stereo_downmix), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 2, 0, "dmix_mode"}, {"ltrt_cmixlev", "Lt/Rt Center Mix Level", OFFSET(ltrt_center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0}, diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3dec.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3dec.h index ae72d80c8..58d8ee69b 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3dec.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3dec.h @@ -79,14 +79,22 @@ typedef struct AC3DecodeContext { int bit_rate; ///< stream bit rate, in bits-per-second int sample_rate; ///< sample frequency, in Hz int num_blocks; ///< number of audio blocks + int bitstream_id; ///< bitstream id (bsid) int bitstream_mode; ///< bitstream mode (bsmod) int channel_mode; ///< channel mode (acmod) - int channel_layout; ///< channel layout int lfe_on; ///< lfe channel in use int channel_map; ///< custom channel map + int preferred_downmix; ///< Preferred 2-channel downmix mode (dmixmod) int center_mix_level; ///< Center mix level index + int center_mix_level_ltrt; ///< Center mix level index for Lt/Rt (ltrtcmixlev) int surround_mix_level; ///< Surround mix level index + int surround_mix_level_ltrt; ///< Surround mix level index for Lt/Rt (ltrtsurmixlev) + int lfe_mix_level_exists; ///< indicates if lfemixlevcod is specified (lfemixlevcode) + int lfe_mix_level; ///< LFE mix level index (lfemixlevcod) int eac3; ///< indicates if current frame is E-AC-3 + int dolby_surround_mode; ///< dolby surround mode (dsurmod) + int dolby_surround_ex_mode; ///< dolby surround ex mode (dsurexmod) + int dolby_headphone_mode; ///< dolby headphone mode (dheadphonmod) ///@} int preferred_stereo_downmix; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3dsp.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3dsp.c index 6df3a68a4..feda6ddc6 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3dsp.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3dsp.c @@ -239,6 +239,19 @@ static void ac3_downmix_c(float **samples, float (*matrix)[2], } } +static void apply_window_int16_c(int16_t *output, const int16_t *input, + const int16_t *window, unsigned int len) +{ + int i; + int len2 = len >> 1; + + for (i = 0; i < len2; i++) { + int16_t w = window[i]; + output[i] = (MUL16(input[i], w) + (1 << 14)) >> 15; + output[len-i-1] = (MUL16(input[len-i-1], w) + (1 << 14)) >> 15; + } +} + av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact) { c->ac3_exponent_min = ac3_exponent_min_c; @@ -253,6 +266,7 @@ av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact) c->sum_square_butterfly_int32 = ac3_sum_square_butterfly_int32_c; c->sum_square_butterfly_float = ac3_sum_square_butterfly_float_c; c->downmix = ac3_downmix_c; + c->apply_window_int16 = apply_window_int16_c; if (ARCH_ARM) ff_ac3dsp_init_arm(c, bit_exact); diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3dsp.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3dsp.h index bafbc8995..bced5974e 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3dsp.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3dsp.h @@ -134,6 +134,20 @@ typedef struct AC3DSPContext { void (*downmix)(float **samples, float (*matrix)[2], int out_ch, int in_ch, int len); + + /** + * Apply symmetric window in 16-bit fixed-point. + * @param output destination array + * constraints: 16-byte aligned + * @param input source array + * constraints: 16-byte aligned + * @param window window array + * constraints: 16-byte aligned, at least len/2 elements + * @param len full window length + * constraints: multiple of ? greater than zero + */ + void (*apply_window_int16)(int16_t *output, const int16_t *input, + const int16_t *window, unsigned int len); } AC3DSPContext; void ff_ac3dsp_init (AC3DSPContext *c, int bit_exact); diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3tab.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3tab.h index a71d093e7..74cbd9ed6 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3tab.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ac3tab.h @@ -22,8 +22,9 @@ #ifndef AVCODEC_AC3TAB_H #define AVCODEC_AC3TAB_H -#include "config.h" -#include "libavutil/common.h" +#include + +#include "libavutil/internal.h" #include "ac3.h" #if CONFIG_HARDCODED_TABLES diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/adpcm.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/adpcm.c index 44f481ddb..f8663a7f6 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/adpcm.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/adpcm.c @@ -1317,7 +1317,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, byte & 0x0F, 4, 0); } } else if (avctx->codec->id == AV_CODEC_ID_ADPCM_SBPRO_3) { - for (n = nb_samples / 3; n > 0; n--) { + for (n = (nb_samples< 0; n--) { int byte = bytestream2_get_byteu(&gb); *samples++ = adpcm_sbpro_expand_nibble(&c->status[0], byte >> 5 , 3, 0); diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/adpcm_data.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/adpcm_data.c index 022836207..210928553 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/adpcm_data.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/adpcm_data.c @@ -47,7 +47,7 @@ static const int8_t adpcm_index_table5[32] = { -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16, }; -const int8_t *ff_adpcm_index_tables[4] = { +const int8_t * const ff_adpcm_index_tables[4] = { &adpcm_index_table2[0], &adpcm_index_table3[0], &ff_adpcm_index_table[0], diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/adpcm_data.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/adpcm_data.h index 1e32436fc..6589bc56c 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/adpcm_data.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/adpcm_data.h @@ -31,7 +31,7 @@ static const uint8_t ff_adpcm_ima_block_sizes[4] = { 4, 12, 4, 20 }; static const uint8_t ff_adpcm_ima_block_samples[4] = { 16, 32, 8, 32 }; -extern const int8_t *ff_adpcm_index_tables[4]; +extern const int8_t * const ff_adpcm_index_tables[4]; extern const int8_t ff_adpcm_index_table[16]; extern const int16_t ff_adpcm_step_table[89]; extern const int16_t ff_adpcm_oki_step_table[49]; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/allcodecs.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/allcodecs.c index 12f334e34..f4a4848a7 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/allcodecs.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/allcodecs.c @@ -24,8 +24,9 @@ * Provide registration of all codecs, parsers and bitstream filters for libavcodec. */ -#include "avcodec.h" #include "config.h" +#include "avcodec.h" +#include "version.h" #define REGISTER_HWACCEL(X, x) \ { \ @@ -79,7 +80,9 @@ void avcodec_register_all(void) REGISTER_HWACCEL(H264_VAAPI, h264_vaapi); REGISTER_HWACCEL(H264_VDA, h264_vda); REGISTER_HWACCEL(H264_VDPAU, h264_vdpau); + REGISTER_HWACCEL(MPEG1_XVMC, mpeg1_xvmc); REGISTER_HWACCEL(MPEG1_VDPAU, mpeg1_vdpau); + REGISTER_HWACCEL(MPEG2_XVMC, mpeg2_xvmc); REGISTER_HWACCEL(MPEG2_DXVA2, mpeg2_dxva2); REGISTER_HWACCEL(MPEG2_VAAPI, mpeg2_vaapi); REGISTER_HWACCEL(MPEG2_VDPAU, mpeg2_vdpau); @@ -119,7 +122,7 @@ void avcodec_register_all(void) REGISTER_DECODER(CAVS, cavs); REGISTER_DECODER(CDGRAPHICS, cdgraphics); REGISTER_DECODER(CDXL, cdxl); - REGISTER_DECODER(CINEPAK, cinepak); + REGISTER_ENCDEC (CINEPAK, cinepak); REGISTER_ENCDEC (CLJR, cljr); REGISTER_DECODER(CLLC, cllc); REGISTER_ENCDEC (COMFORTNOISE, comfortnoise); @@ -147,6 +150,7 @@ void avcodec_register_all(void) REGISTER_DECODER(EXR, exr); REGISTER_ENCDEC (FFV1, ffv1); REGISTER_ENCDEC (FFVHUFF, ffvhuff); + REGISTER_DECODER(FIC, fic); REGISTER_ENCDEC (FLASHSV, flashsv); REGISTER_ENCDEC (FLASHSV2, flashsv2); REGISTER_DECODER(FLIC, flic); @@ -164,6 +168,8 @@ void avcodec_register_all(void) REGISTER_DECODER(H264_CRYSTALHD, h264_crystalhd); REGISTER_DECODER(H264_VDA, h264_vda); REGISTER_DECODER(H264_VDPAU, h264_vdpau); + REGISTER_DECODER(HEVC, hevc); + REGISTER_DECODER(HNM4_VIDEO, hnm4_video); REGISTER_ENCDEC (HUFFYUV, huffyuv); REGISTER_DECODER(IDCIN, idcin); REGISTER_DECODER(IFF_BYTERUN1, iff_byterun1); @@ -187,7 +193,9 @@ void avcodec_register_all(void) REGISTER_DECODER(MJPEGB, mjpegb); REGISTER_DECODER(MMVIDEO, mmvideo); REGISTER_DECODER(MOTIONPIXELS, motionpixels); +#if FF_API_XVMC REGISTER_DECODER(MPEG_XVMC, mpeg_xvmc); +#endif /* FF_API_XVMC */ REGISTER_ENCDEC (MPEG1VIDEO, mpeg1video); REGISTER_ENCDEC (MPEG2VIDEO, mpeg2video); REGISTER_ENCDEC (MPEG4, mpeg4); @@ -320,6 +328,7 @@ void avcodec_register_all(void) REGISTER_DECODER(APE, ape); REGISTER_DECODER(ATRAC1, atrac1); REGISTER_DECODER(ATRAC3, atrac3); + REGISTER_DECODER(ATRAC3P, atrac3p); REGISTER_DECODER(BINKAUDIO_DCT, binkaudio_dct); REGISTER_DECODER(BINKAUDIO_RDFT, binkaudio_rdft); REGISTER_DECODER(BMV_AUDIO, bmv_audio); @@ -344,6 +353,7 @@ void avcodec_register_all(void) REGISTER_DECODER(MP1FLOAT, mp1float); REGISTER_ENCDEC (MP2, mp2); REGISTER_DECODER(MP2FLOAT, mp2float); + REGISTER_ENCODER(MP2FIXED, mp2fixed); REGISTER_DECODER(MP3, mp3); REGISTER_DECODER(MP3FLOAT, mp3float); REGISTER_DECODER(MP3ADU, mp3adu); @@ -431,6 +441,7 @@ void avcodec_register_all(void) REGISTER_DECODER(ADPCM_EA_XAS, adpcm_ea_xas); REGISTER_ENCDEC (ADPCM_G722, adpcm_g722); REGISTER_ENCDEC (ADPCM_G726, adpcm_g726); + REGISTER_DECODER(ADPCM_G726LE, adpcm_g726le); REGISTER_DECODER(ADPCM_IMA_AMV, adpcm_ima_amv); REGISTER_DECODER(ADPCM_IMA_APC, adpcm_ima_apc); REGISTER_DECODER(ADPCM_IMA_DK3, adpcm_ima_dk3); @@ -501,8 +512,10 @@ void avcodec_register_all(void) REGISTER_ENCDEC (LIBVPX_VP8, libvpx_vp8); REGISTER_ENCDEC (LIBVPX_VP9, libvpx_vp9); REGISTER_ENCODER(LIBWAVPACK, libwavpack); + REGISTER_ENCODER(LIBWEBP, libwebp); REGISTER_ENCODER(LIBX264, libx264); REGISTER_ENCODER(LIBX264RGB, libx264rgb); + REGISTER_ENCODER(LIBX265, libx265); REGISTER_ENCODER(LIBXAVS, libxavs); REGISTER_ENCODER(LIBXVID, libxvid); REGISTER_DECODER(LIBZVBI_TELETEXT, libzvbi_teletext); @@ -532,6 +545,7 @@ void avcodec_register_all(void) REGISTER_PARSER(H261, h261); REGISTER_PARSER(H263, h263); REGISTER_PARSER(H264, h264); + REGISTER_PARSER(HEVC, hevc); REGISTER_PARSER(MJPEG, mjpeg); REGISTER_PARSER(MLP, mlp); REGISTER_PARSER(MPEG4VIDEO, mpeg4video); @@ -546,6 +560,7 @@ void avcodec_register_all(void) REGISTER_PARSER(VORBIS, vorbis); REGISTER_PARSER(VP3, vp3); REGISTER_PARSER(VP8, vp8); + REGISTER_PARSER(VP9, vp9); /* bitstream filters */ REGISTER_BSF(AAC_ADTSTOASC, aac_adtstoasc); @@ -555,7 +570,6 @@ void avcodec_register_all(void) REGISTER_BSF(IMX_DUMP_HEADER, imx_dump_header); REGISTER_BSF(MJPEG2JPEG, mjpeg2jpeg); REGISTER_BSF(MJPEGA_DUMP_HEADER, mjpega_dump_header); - REGISTER_BSF(MP3_HEADER_COMPRESS, mp3_header_compress); REGISTER_BSF(MP3_HEADER_DECOMPRESS, mp3_header_decompress); REGISTER_BSF(MOV2TEXTSUB, mov2textsub); REGISTER_BSF(NOISE, noise); diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/apedec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/apedec.c index 7108a6750..68c7f9fab 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/apedec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/apedec.c @@ -605,10 +605,14 @@ static void decode_array_0000(APEContext *ctx, GetBitContext *gb, rice->ksum += out[i]; } rice->k = av_log2(rice->ksum / 10) + 1; + if (rice->k >= 24) + return; for (; i < 64; i++) { out[i] = get_rice_ook(&ctx->gb, rice->k); rice->ksum += out[i]; rice->k = av_log2(rice->ksum / ((i + 1) * 2)) + 1; + if (rice->k >= 24) + return; } ksummax = 1 << (rice->k + 7); ksummin = rice->k ? (1 << (rice->k + 6)) : 0; @@ -1436,7 +1440,7 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data, } if (s->fileversion < 3950) // previous versions overread two bytes buf_size += 2; - av_fast_malloc(&s->data, (unsigned int *) &s->data_size, buf_size); + av_fast_padded_malloc(&s->data, &s->data_size, buf_size); if (!s->data) return AVERROR(ENOMEM); s->dsp.bswap_buf((uint32_t*)s->data, (const uint32_t*)buf, buf_size >> 2); @@ -1458,7 +1462,8 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data, } s->ptr += offset; } else { - init_get_bits(&s->gb, s->ptr, (s->data_end - s->ptr) * 8); + if ((ret = init_get_bits8(&s->gb, s->ptr, s->data_end - s->ptr)) < 0) + return ret; if (s->fileversion > 3800) skip_bits_long(&s->gb, offset * 8); else diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/atrac3.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/atrac3.c index 793f446eb..cb42c0370 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/atrac3.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/atrac3.c @@ -116,9 +116,6 @@ typedef struct ATRAC3Context { static DECLARE_ALIGNED(32, float, mdct_window)[MDCT_SIZE]; static VLC_TYPE atrac3_vlc_table[4096][2]; static VLC spectral_coeff_tab[7]; -static float gain_tab1[16]; -static float gain_tab2[31]; - /** * Regular 512 points IMDCT without overlapping, with the exception of the @@ -175,7 +172,7 @@ static int decode_bytes(const uint8_t *input, uint8_t *out, int bytes) return off; } -static av_cold void init_atrac3_window(void) +static av_cold void init_imdct_window(void) { int i, j; @@ -780,7 +777,7 @@ static av_cold void atrac3_init_static_data(void) { int i; - init_atrac3_window(); + init_imdct_window(); ff_atrac_generate_tables(); /* Initialize the VLC tables. */ @@ -792,13 +789,6 @@ static av_cold void atrac3_init_static_data(void) huff_bits[i], 1, 1, huff_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); } - - /* Generate gain tables */ - for (i = 0; i < 16; i++) - gain_tab1[i] = exp2f (4 - i); - - for (i = -15; i < 16; i++) - gain_tab2[i + 15] = exp2f (i * -0.125); } static av_cold int atrac3_decode_init(AVCodecContext *avctx) diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/atrac3plus.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/atrac3plus.c new file mode 100644 index 000000000..08c90cde9 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/atrac3plus.c @@ -0,0 +1,1818 @@ +/* + * ATRAC3+ compatible decoder + * + * Copyright (c) 2010-2013 Maxim Poliakovski + * + * 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 + * Bitstream parser for ATRAC3+ decoder. + */ + +#include "libavutil/avassert.h" +#include "avcodec.h" +#include "get_bits.h" +#include "atrac3plus.h" +#include "atrac3plus_data.h" + +static VLC_TYPE tables_data[154276][2]; +static VLC wl_vlc_tabs[4]; +static VLC sf_vlc_tabs[8]; +static VLC ct_vlc_tabs[4]; +static VLC spec_vlc_tabs[112]; +static VLC gain_vlc_tabs[11]; +static VLC tone_vlc_tabs[7]; + +#define GET_DELTA(gb, delta_bits) \ + ((delta_bits) ? get_bits((gb), (delta_bits)) : 0) + +/** + * Generate canonical VLC table from given descriptor. + * + * @param[in] cb ptr to codebook descriptor + * @param[in] xlat ptr to translation table or NULL + * @param[in,out] tab_offset starting offset to the generated vlc table + * @param[out] out_vlc ptr to vlc table to be generated + */ +static av_cold void build_canonical_huff(const uint8_t *cb, const uint8_t *xlat, + int *tab_offset, VLC *out_vlc) +{ + int i, b; + uint16_t codes[256]; + uint8_t bits[256]; + unsigned code = 0; + int index = 0; + int min_len = *cb++; // get shortest codeword length + int max_len = *cb++; // get longest codeword length + + for (b = min_len; b <= max_len; b++) { + for (i = *cb++; i > 0; i--) { + av_assert0(index < 256); + bits[index] = b; + codes[index] = code++; + index++; + } + code <<= 1; + } + + out_vlc->table = &tables_data[*tab_offset]; + out_vlc->table_allocated = 1 << max_len; + + ff_init_vlc_sparse(out_vlc, max_len, index, bits, 1, 1, codes, 2, 2, + xlat, 1, 1, INIT_VLC_USE_NEW_STATIC); + + *tab_offset += 1 << max_len; +} + +av_cold void ff_atrac3p_init_vlcs(void) +{ + int i, wl_vlc_offs, ct_vlc_offs, sf_vlc_offs, tab_offset; + + static int wl_nb_bits[4] = { 2, 3, 5, 5 }; + static int wl_nb_codes[4] = { 3, 5, 8, 8 }; + static const uint8_t *wl_bits[4] = { + atrac3p_wl_huff_bits1, atrac3p_wl_huff_bits2, + atrac3p_wl_huff_bits3, atrac3p_wl_huff_bits4 + }; + static const uint8_t *wl_codes[4] = { + atrac3p_wl_huff_code1, atrac3p_wl_huff_code2, + atrac3p_wl_huff_code3, atrac3p_wl_huff_code4 + }; + static const uint8_t *wl_xlats[4] = { + atrac3p_wl_huff_xlat1, atrac3p_wl_huff_xlat2, NULL, NULL + }; + + static int ct_nb_bits[4] = { 3, 4, 4, 4 }; + static int ct_nb_codes[4] = { 4, 8, 8, 8 }; + static const uint8_t *ct_bits[4] = { + atrac3p_ct_huff_bits1, atrac3p_ct_huff_bits2, + atrac3p_ct_huff_bits2, atrac3p_ct_huff_bits3 + }; + static const uint8_t *ct_codes[4] = { + atrac3p_ct_huff_code1, atrac3p_ct_huff_code2, + atrac3p_ct_huff_code2, atrac3p_ct_huff_code3 + }; + static const uint8_t *ct_xlats[4] = { + NULL, NULL, atrac3p_ct_huff_xlat1, NULL + }; + + static int sf_nb_bits[8] = { 9, 9, 9, 9, 6, 6, 7, 7 }; + static int sf_nb_codes[8] = { 64, 64, 64, 64, 16, 16, 16, 16 }; + static const uint8_t *sf_bits[8] = { + atrac3p_sf_huff_bits1, atrac3p_sf_huff_bits1, atrac3p_sf_huff_bits2, + atrac3p_sf_huff_bits3, atrac3p_sf_huff_bits4, atrac3p_sf_huff_bits4, + atrac3p_sf_huff_bits5, atrac3p_sf_huff_bits6 + }; + static const uint16_t *sf_codes[8] = { + atrac3p_sf_huff_code1, atrac3p_sf_huff_code1, atrac3p_sf_huff_code2, + atrac3p_sf_huff_code3, atrac3p_sf_huff_code4, atrac3p_sf_huff_code4, + atrac3p_sf_huff_code5, atrac3p_sf_huff_code6 + }; + static const uint8_t *sf_xlats[8] = { + atrac3p_sf_huff_xlat1, atrac3p_sf_huff_xlat2, NULL, NULL, + atrac3p_sf_huff_xlat4, atrac3p_sf_huff_xlat5, NULL, NULL + }; + + static const uint8_t *gain_cbs[11] = { + atrac3p_huff_gain_npoints1_cb, atrac3p_huff_gain_npoints1_cb, + atrac3p_huff_gain_lev1_cb, atrac3p_huff_gain_lev2_cb, + atrac3p_huff_gain_lev3_cb, atrac3p_huff_gain_lev4_cb, + atrac3p_huff_gain_loc3_cb, atrac3p_huff_gain_loc1_cb, + atrac3p_huff_gain_loc4_cb, atrac3p_huff_gain_loc2_cb, + atrac3p_huff_gain_loc5_cb + }; + static const uint8_t *gain_xlats[11] = { + NULL, atrac3p_huff_gain_npoints2_xlat, atrac3p_huff_gain_lev1_xlat, + atrac3p_huff_gain_lev2_xlat, atrac3p_huff_gain_lev3_xlat, + atrac3p_huff_gain_lev4_xlat, atrac3p_huff_gain_loc3_xlat, + atrac3p_huff_gain_loc1_xlat, atrac3p_huff_gain_loc4_xlat, + atrac3p_huff_gain_loc2_xlat, atrac3p_huff_gain_loc5_xlat + }; + + static const uint8_t *tone_cbs[7] = { + atrac3p_huff_tonebands_cb, atrac3p_huff_numwavs1_cb, + atrac3p_huff_numwavs2_cb, atrac3p_huff_wav_ampsf1_cb, + atrac3p_huff_wav_ampsf2_cb, atrac3p_huff_wav_ampsf3_cb, + atrac3p_huff_freq_cb + }; + static const uint8_t *tone_xlats[7] = { + NULL, NULL, atrac3p_huff_numwavs2_xlat, atrac3p_huff_wav_ampsf1_xlat, + atrac3p_huff_wav_ampsf2_xlat, atrac3p_huff_wav_ampsf3_xlat, + atrac3p_huff_freq_xlat + }; + + for (i = 0, wl_vlc_offs = 0, ct_vlc_offs = 2508; i < 4; i++) { + wl_vlc_tabs[i].table = &tables_data[wl_vlc_offs]; + wl_vlc_tabs[i].table_allocated = 1 << wl_nb_bits[i]; + ct_vlc_tabs[i].table = &tables_data[ct_vlc_offs]; + ct_vlc_tabs[i].table_allocated = 1 << ct_nb_bits[i]; + + ff_init_vlc_sparse(&wl_vlc_tabs[i], wl_nb_bits[i], wl_nb_codes[i], + wl_bits[i], 1, 1, + wl_codes[i], 1, 1, + wl_xlats[i], 1, 1, + INIT_VLC_USE_NEW_STATIC); + + ff_init_vlc_sparse(&ct_vlc_tabs[i], ct_nb_bits[i], ct_nb_codes[i], + ct_bits[i], 1, 1, + ct_codes[i], 1, 1, + ct_xlats[i], 1, 1, + INIT_VLC_USE_NEW_STATIC); + + wl_vlc_offs += wl_vlc_tabs[i].table_allocated; + ct_vlc_offs += ct_vlc_tabs[i].table_allocated; + } + + for (i = 0, sf_vlc_offs = 76; i < 8; i++) { + sf_vlc_tabs[i].table = &tables_data[sf_vlc_offs]; + sf_vlc_tabs[i].table_allocated = 1 << sf_nb_bits[i]; + + ff_init_vlc_sparse(&sf_vlc_tabs[i], sf_nb_bits[i], sf_nb_codes[i], + sf_bits[i], 1, 1, + sf_codes[i], 2, 2, + sf_xlats[i], 1, 1, + INIT_VLC_USE_NEW_STATIC); + sf_vlc_offs += sf_vlc_tabs[i].table_allocated; + } + + tab_offset = 2564; + + /* build huffman tables for spectrum decoding */ + for (i = 0; i < 112; i++) { + if (atrac3p_spectra_tabs[i].cb) + build_canonical_huff(atrac3p_spectra_tabs[i].cb, + atrac3p_spectra_tabs[i].xlat, + &tab_offset, &spec_vlc_tabs[i]); + else + spec_vlc_tabs[i].table = 0; + } + + /* build huffman tables for gain data decoding */ + for (i = 0; i < 11; i++) + build_canonical_huff(gain_cbs[i], gain_xlats[i], &tab_offset, &gain_vlc_tabs[i]); + + /* build huffman tables for tone decoding */ + for (i = 0; i < 7; i++) + build_canonical_huff(tone_cbs[i], tone_xlats[i], &tab_offset, &tone_vlc_tabs[i]); +} + +/** + * Decode number of coded quantization units. + * + * @param[in] gb the GetBit context + * @param[in,out] chan ptr to the channel parameters + * @param[in,out] ctx ptr to the channel unit context + * @param[in] avctx ptr to the AVCodecContext + * @return result code: 0 = OK, otherwise - error code + */ +static int num_coded_units(GetBitContext *gb, Atrac3pChanParams *chan, + Atrac3pChanUnitCtx *ctx, AVCodecContext *avctx) +{ + chan->fill_mode = get_bits(gb, 2); + if (!chan->fill_mode) { + chan->num_coded_vals = ctx->num_quant_units; + } else { + chan->num_coded_vals = get_bits(gb, 5); + if (chan->num_coded_vals > ctx->num_quant_units) { + av_log(avctx, AV_LOG_ERROR, + "Invalid number of transmitted units!\n"); + return AVERROR_INVALIDDATA; + } + + if (chan->fill_mode == 3) + chan->split_point = get_bits(gb, 2) + (chan->ch_num << 1) + 1; + } + + return 0; +} + +/** + * Add weighting coefficients to the decoded word-length information. + * + * @param[in,out] ctx ptr to the channel unit context + * @param[in,out] chan ptr to the channel parameters + * @param[in] wtab_idx index of the table of weights + * @param[in] avctx ptr to the AVCodecContext + * @return result code: 0 = OK, otherwise - error code + */ +static int add_wordlen_weights(Atrac3pChanUnitCtx *ctx, + Atrac3pChanParams *chan, int wtab_idx, + AVCodecContext *avctx) +{ + int i; + const int8_t *weights_tab = + &atrac3p_wl_weights[chan->ch_num * 3 + wtab_idx - 1][0]; + + for (i = 0; i < ctx->num_quant_units; i++) { + chan->qu_wordlen[i] += weights_tab[i]; + if (chan->qu_wordlen[i] < 0 || chan->qu_wordlen[i] > 7) { + av_log(avctx, AV_LOG_ERROR, + "WL index out of range: pos=%d, val=%d!\n", + i, chan->qu_wordlen[i]); + return AVERROR_INVALIDDATA; + } + } + + return 0; +} + +/** + * Subtract weighting coefficients from decoded scalefactors. + * + * @param[in,out] ctx ptr to the channel unit context + * @param[in,out] chan ptr to the channel parameters + * @param[in] wtab_idx index of table of weights + * @param[in] avctx ptr to the AVCodecContext + * @return result code: 0 = OK, otherwise - error code + */ +static int subtract_sf_weights(Atrac3pChanUnitCtx *ctx, + Atrac3pChanParams *chan, int wtab_idx, + AVCodecContext *avctx) +{ + int i; + const int8_t *weights_tab = &atrac3p_sf_weights[wtab_idx - 1][0]; + + for (i = 0; i < ctx->used_quant_units; i++) { + chan->qu_sf_idx[i] -= weights_tab[i]; + if (chan->qu_sf_idx[i] < 0 || chan->qu_sf_idx[i] > 63) { + av_log(avctx, AV_LOG_ERROR, + "SF index out of range: pos=%d, val=%d!\n", + i, chan->qu_sf_idx[i]); + return AVERROR_INVALIDDATA; + } + } + + return 0; +} + +/** + * Unpack vector quantization tables. + * + * @param[in] start_val start value for the unpacked table + * @param[in] shape_vec ptr to table to unpack + * @param[out] dst ptr to output array + * @param[in] num_values number of values to unpack + */ +static inline void unpack_vq_shape(int start_val, const int8_t *shape_vec, + int *dst, int num_values) +{ + int i; + + if (num_values) { + dst[0] = dst[1] = dst[2] = start_val; + for (i = 3; i < num_values; i++) + dst[i] = start_val - shape_vec[atrac3p_qu_num_to_seg[i] - 1]; + } +} + +#define UNPACK_SF_VQ_SHAPE(gb, dst, num_vals) \ + start_val = get_bits((gb), 6); \ + unpack_vq_shape(start_val, &atrac3p_sf_shapes[get_bits((gb), 6)][0], \ + (dst), (num_vals)) + +/** + * Decode word length for each quantization unit of a channel. + * + * @param[in] gb the GetBit context + * @param[in,out] ctx ptr to the channel unit context + * @param[in] ch_num channel to process + * @param[in] avctx ptr to the AVCodecContext + * @return result code: 0 = OK, otherwise - error code + */ +static int decode_channel_wordlen(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, + int ch_num, AVCodecContext *avctx) +{ + int i, weight_idx = 0, delta, diff, pos, delta_bits, min_val, flag, + ret, start_val; + VLC *vlc_tab; + Atrac3pChanParams *chan = &ctx->channels[ch_num]; + Atrac3pChanParams *ref_chan = &ctx->channels[0]; + + chan->fill_mode = 0; + + switch (get_bits(gb, 2)) { /* switch according to coding mode */ + case 0: /* coded using constant number of bits */ + for (i = 0; i < ctx->num_quant_units; i++) + chan->qu_wordlen[i] = get_bits(gb, 3); + break; + case 1: + if (ch_num) { + if ((ret = num_coded_units(gb, chan, ctx, avctx)) < 0) + return ret; + + if (chan->num_coded_vals) { + vlc_tab = &wl_vlc_tabs[get_bits(gb, 2)]; + + for (i = 0; i < chan->num_coded_vals; i++) { + delta = get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1); + chan->qu_wordlen[i] = (ref_chan->qu_wordlen[i] + delta) & 7; + } + } + } else { + weight_idx = get_bits(gb, 2); + if ((ret = num_coded_units(gb, chan, ctx, avctx)) < 0) + return ret; + + if (chan->num_coded_vals) { + pos = get_bits(gb, 5); + if (pos > chan->num_coded_vals) { + av_log(avctx, AV_LOG_ERROR, + "WL mode 1: invalid position!\n"); + return AVERROR_INVALIDDATA; + } + + delta_bits = get_bits(gb, 2); + min_val = get_bits(gb, 3); + + for (i = 0; i < pos; i++) + chan->qu_wordlen[i] = get_bits(gb, 3); + + for (i = pos; i < chan->num_coded_vals; i++) + chan->qu_wordlen[i] = (min_val + GET_DELTA(gb, delta_bits)) & 7; + } + } + break; + case 2: + if ((ret = num_coded_units(gb, chan, ctx, avctx)) < 0) + return ret; + + if (ch_num && chan->num_coded_vals) { + vlc_tab = &wl_vlc_tabs[get_bits(gb, 2)]; + delta = get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1); + chan->qu_wordlen[0] = (ref_chan->qu_wordlen[0] + delta) & 7; + + for (i = 1; i < chan->num_coded_vals; i++) { + diff = ref_chan->qu_wordlen[i] - ref_chan->qu_wordlen[i - 1]; + delta = get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1); + chan->qu_wordlen[i] = (chan->qu_wordlen[i - 1] + diff + delta) & 7; + } + } else if (chan->num_coded_vals) { + flag = get_bits(gb, 1); + vlc_tab = &wl_vlc_tabs[get_bits(gb, 1)]; + + start_val = get_bits(gb, 3); + unpack_vq_shape(start_val, + &atrac3p_wl_shapes[start_val][get_bits(gb, 4)][0], + chan->qu_wordlen, chan->num_coded_vals); + + if (!flag) { + for (i = 0; i < chan->num_coded_vals; i++) { + delta = get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1); + chan->qu_wordlen[i] = (chan->qu_wordlen[i] + delta) & 7; + } + } else { + for (i = 0; i < (chan->num_coded_vals & - 2); i += 2) + if (!get_bits1(gb)) { + chan->qu_wordlen[i] = (chan->qu_wordlen[i] + + get_vlc2(gb, vlc_tab->table, + vlc_tab->bits, 1)) & 7; + chan->qu_wordlen[i + 1] = (chan->qu_wordlen[i + 1] + + get_vlc2(gb, vlc_tab->table, + vlc_tab->bits, 1)) & 7; + } + + if (chan->num_coded_vals & 1) + chan->qu_wordlen[i] = (chan->qu_wordlen[i] + + get_vlc2(gb, vlc_tab->table, + vlc_tab->bits, 1)) & 7; + } + } + break; + case 3: + weight_idx = get_bits(gb, 2); + if ((ret = num_coded_units(gb, chan, ctx, avctx)) < 0) + return ret; + + if (chan->num_coded_vals) { + vlc_tab = &wl_vlc_tabs[get_bits(gb, 2)]; + + /* first coefficient is coded directly */ + chan->qu_wordlen[0] = get_bits(gb, 3); + + for (i = 1; i < chan->num_coded_vals; i++) { + delta = get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1); + chan->qu_wordlen[i] = (chan->qu_wordlen[i - 1] + delta) & 7; + } + } + break; + } + + if (chan->fill_mode == 2) { + for (i = chan->num_coded_vals; i < ctx->num_quant_units; i++) + chan->qu_wordlen[i] = ch_num ? get_bits1(gb) : 1; + } else if (chan->fill_mode == 3) { + pos = ch_num ? chan->num_coded_vals + chan->split_point + : ctx->num_quant_units - chan->split_point; + for (i = chan->num_coded_vals; i < pos; i++) + chan->qu_wordlen[i] = 1; + } + + if (weight_idx) + return add_wordlen_weights(ctx, chan, weight_idx, avctx); + + return 0; +} + +/** + * Decode scale factor indexes for each quant unit of a channel. + * + * @param[in] gb the GetBit context + * @param[in,out] ctx ptr to the channel unit context + * @param[in] ch_num channel to process + * @param[in] avctx ptr to the AVCodecContext + * @return result code: 0 = OK, otherwise - error code + */ +static int decode_channel_sf_idx(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, + int ch_num, AVCodecContext *avctx) +{ + int i, weight_idx = 0, delta, diff, num_long_vals, + delta_bits, min_val, vlc_sel, start_val; + VLC *vlc_tab; + Atrac3pChanParams *chan = &ctx->channels[ch_num]; + Atrac3pChanParams *ref_chan = &ctx->channels[0]; + + switch (get_bits(gb, 2)) { /* switch according to coding mode */ + case 0: /* coded using constant number of bits */ + for (i = 0; i < ctx->used_quant_units; i++) + chan->qu_sf_idx[i] = get_bits(gb, 6); + break; + case 1: + if (ch_num) { + vlc_tab = &sf_vlc_tabs[get_bits(gb, 2)]; + + for (i = 0; i < ctx->used_quant_units; i++) { + delta = get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1); + chan->qu_sf_idx[i] = (ref_chan->qu_sf_idx[i] + delta) & 0x3F; + } + } else { + weight_idx = get_bits(gb, 2); + if (weight_idx == 3) { + UNPACK_SF_VQ_SHAPE(gb, chan->qu_sf_idx, ctx->used_quant_units); + + num_long_vals = get_bits(gb, 5); + delta_bits = get_bits(gb, 2); + min_val = get_bits(gb, 4) - 7; + + for (i = 0; i < num_long_vals; i++) + chan->qu_sf_idx[i] = (chan->qu_sf_idx[i] + + get_bits(gb, 4) - 7) & 0x3F; + + /* all others are: min_val + delta */ + for (i = num_long_vals; i < ctx->used_quant_units; i++) + chan->qu_sf_idx[i] = (chan->qu_sf_idx[i] + min_val + + GET_DELTA(gb, delta_bits)) & 0x3F; + } else { + num_long_vals = get_bits(gb, 5); + delta_bits = get_bits(gb, 3); + min_val = get_bits(gb, 6); + if (num_long_vals > ctx->used_quant_units || delta_bits == 7) { + av_log(avctx, AV_LOG_ERROR, + "SF mode 1: invalid parameters!\n"); + return AVERROR_INVALIDDATA; + } + + /* read full-precision SF indexes */ + for (i = 0; i < num_long_vals; i++) + chan->qu_sf_idx[i] = get_bits(gb, 6); + + /* all others are: min_val + delta */ + for (i = num_long_vals; i < ctx->used_quant_units; i++) + chan->qu_sf_idx[i] = (min_val + + GET_DELTA(gb, delta_bits)) & 0x3F; + } + } + break; + case 2: + if (ch_num) { + vlc_tab = &sf_vlc_tabs[get_bits(gb, 2)]; + + delta = get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1); + chan->qu_sf_idx[0] = (ref_chan->qu_sf_idx[0] + delta) & 0x3F; + + for (i = 1; i < ctx->used_quant_units; i++) { + diff = ref_chan->qu_sf_idx[i] - ref_chan->qu_sf_idx[i - 1]; + delta = get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1); + chan->qu_sf_idx[i] = (chan->qu_sf_idx[i - 1] + diff + delta) & 0x3F; + } + } else { + vlc_tab = &sf_vlc_tabs[get_bits(gb, 2) + 4]; + + UNPACK_SF_VQ_SHAPE(gb, chan->qu_sf_idx, ctx->used_quant_units); + + for (i = 0; i < ctx->used_quant_units; i++) { + delta = get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1); + chan->qu_sf_idx[i] = (chan->qu_sf_idx[i] + + sign_extend(delta, 4)) & 0x3F; + } + } + break; + case 3: + if (ch_num) { + /* copy coefficients from reference channel */ + for (i = 0; i < ctx->used_quant_units; i++) + chan->qu_sf_idx[i] = ref_chan->qu_sf_idx[i]; + } else { + weight_idx = get_bits(gb, 2); + vlc_sel = get_bits(gb, 2); + vlc_tab = &sf_vlc_tabs[vlc_sel]; + + if (weight_idx == 3) { + vlc_tab = &sf_vlc_tabs[vlc_sel + 4]; + + UNPACK_SF_VQ_SHAPE(gb, chan->qu_sf_idx, ctx->used_quant_units); + + diff = (get_bits(gb, 4) + 56) & 0x3F; + chan->qu_sf_idx[0] = (chan->qu_sf_idx[0] + diff) & 0x3F; + + for (i = 1; i < ctx->used_quant_units; i++) { + delta = get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1); + diff = (diff + sign_extend(delta, 4)) & 0x3F; + chan->qu_sf_idx[i] = (diff + chan->qu_sf_idx[i]) & 0x3F; + } + } else { + /* 1st coefficient is coded directly */ + chan->qu_sf_idx[0] = get_bits(gb, 6); + + for (i = 1; i < ctx->used_quant_units; i++) { + delta = get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1); + chan->qu_sf_idx[i] = (chan->qu_sf_idx[i - 1] + delta) & 0x3F; + } + } + } + break; + } + + if (weight_idx && weight_idx < 3) + return subtract_sf_weights(ctx, chan, weight_idx, avctx); + + return 0; +} + +/** + * Decode word length information for each channel. + * + * @param[in] gb the GetBit context + * @param[in,out] ctx ptr to the channel unit context + * @param[in] num_channels number of channels to process + * @param[in] avctx ptr to the AVCodecContext + * @return result code: 0 = OK, otherwise - error code + */ +static int decode_quant_wordlen(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, + int num_channels, AVCodecContext *avctx) +{ + int ch_num, i, ret; + + for (ch_num = 0; ch_num < num_channels; ch_num++) { + memset(ctx->channels[ch_num].qu_wordlen, 0, + sizeof(ctx->channels[ch_num].qu_wordlen)); + + if ((ret = decode_channel_wordlen(gb, ctx, ch_num, avctx)) < 0) + return ret; + } + + /* scan for last non-zero coeff in both channels and + * set number of quant units having coded spectrum */ + for (i = ctx->num_quant_units - 1; i >= 0; i--) + if (ctx->channels[0].qu_wordlen[i] || + (num_channels == 2 && ctx->channels[1].qu_wordlen[i])) + break; + ctx->used_quant_units = i + 1; + + return 0; +} + +/** + * Decode scale factor indexes for each channel. + * + * @param[in] gb the GetBit context + * @param[in,out] ctx ptr to the channel unit context + * @param[in] num_channels number of channels to process + * @param[in] avctx ptr to the AVCodecContext + * @return result code: 0 = OK, otherwise - error code + */ +static int decode_scale_factors(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, + int num_channels, AVCodecContext *avctx) +{ + int ch_num, ret; + + if (!ctx->used_quant_units) + return 0; + + for (ch_num = 0; ch_num < num_channels; ch_num++) { + memset(ctx->channels[ch_num].qu_sf_idx, 0, + sizeof(ctx->channels[ch_num].qu_sf_idx)); + + if ((ret = decode_channel_sf_idx(gb, ctx, ch_num, avctx)) < 0) + return ret; + } + + return 0; +} + +/** + * Decode number of code table values. + * + * @param[in] gb the GetBit context + * @param[in,out] ctx ptr to the channel unit context + * @param[in] avctx ptr to the AVCodecContext + * @return result code: 0 = OK, otherwise - error code + */ +static int get_num_ct_values(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, + AVCodecContext *avctx) +{ + int num_coded_vals; + + if (get_bits1(gb)) { + num_coded_vals = get_bits(gb, 5); + if (num_coded_vals > ctx->used_quant_units) { + av_log(avctx, AV_LOG_ERROR, + "Invalid number of code table indexes: %d!\n", num_coded_vals); + return AVERROR_INVALIDDATA; + } + return num_coded_vals; + } else + return ctx->used_quant_units; +} + +#define DEC_CT_IDX_COMMON(OP) \ + num_vals = get_num_ct_values(gb, ctx, avctx); \ + if (num_vals < 0) \ + return num_vals; \ + \ + for (i = 0; i < num_vals; i++) { \ + if (chan->qu_wordlen[i]) { \ + chan->qu_tab_idx[i] = OP; \ + } else if (ch_num && ref_chan->qu_wordlen[i]) \ + /* get clone master flag */ \ + chan->qu_tab_idx[i] = get_bits1(gb); \ + } + +#define CODING_DIRECT get_bits(gb, num_bits) + +#define CODING_VLC get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1) + +#define CODING_VLC_DELTA \ + (!i) ? CODING_VLC \ + : (pred + get_vlc2(gb, delta_vlc->table, \ + delta_vlc->bits, 1)) & mask; \ + pred = chan->qu_tab_idx[i] + +#define CODING_VLC_DIFF \ + (ref_chan->qu_tab_idx[i] + \ + get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1)) & mask + +/** + * Decode code table indexes for each quant unit of a channel. + * + * @param[in] gb the GetBit context + * @param[in,out] ctx ptr to the channel unit context + * @param[in] ch_num channel to process + * @param[in] avctx ptr to the AVCodecContext + * @return result code: 0 = OK, otherwise - error code + */ +static int decode_channel_code_tab(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, + int ch_num, AVCodecContext *avctx) +{ + int i, num_vals, num_bits, pred; + int mask = ctx->use_full_table ? 7 : 3; /* mask for modular arithmetic */ + VLC *vlc_tab, *delta_vlc; + Atrac3pChanParams *chan = &ctx->channels[ch_num]; + Atrac3pChanParams *ref_chan = &ctx->channels[0]; + + chan->table_type = get_bits1(gb); + + switch (get_bits(gb, 2)) { /* switch according to coding mode */ + case 0: /* directly coded */ + num_bits = ctx->use_full_table + 2; + DEC_CT_IDX_COMMON(CODING_DIRECT); + break; + case 1: /* entropy-coded */ + vlc_tab = ctx->use_full_table ? &ct_vlc_tabs[1] + : ct_vlc_tabs; + DEC_CT_IDX_COMMON(CODING_VLC); + break; + case 2: /* entropy-coded delta */ + if (ctx->use_full_table) { + vlc_tab = &ct_vlc_tabs[1]; + delta_vlc = &ct_vlc_tabs[2]; + } else { + vlc_tab = ct_vlc_tabs; + delta_vlc = ct_vlc_tabs; + } + pred = 0; + DEC_CT_IDX_COMMON(CODING_VLC_DELTA); + break; + case 3: /* entropy-coded difference to master */ + if (ch_num) { + vlc_tab = ctx->use_full_table ? &ct_vlc_tabs[3] + : ct_vlc_tabs; + DEC_CT_IDX_COMMON(CODING_VLC_DIFF); + } + break; + } + + return 0; +} + +/** + * Decode code table indexes for each channel. + * + * @param[in] gb the GetBit context + * @param[in,out] ctx ptr to the channel unit context + * @param[in] num_channels number of channels to process + * @param[in] avctx ptr to the AVCodecContext + * @return result code: 0 = OK, otherwise - error code + */ +static int decode_code_table_indexes(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, + int num_channels, AVCodecContext *avctx) +{ + int ch_num, ret; + + if (!ctx->used_quant_units) + return 0; + + ctx->use_full_table = get_bits1(gb); + + for (ch_num = 0; ch_num < num_channels; ch_num++) { + memset(ctx->channels[ch_num].qu_tab_idx, 0, + sizeof(ctx->channels[ch_num].qu_tab_idx)); + + if ((ret = decode_channel_code_tab(gb, ctx, ch_num, avctx)) < 0) + return ret; + } + + return 0; +} + +/** + * Decode huffman-coded spectral lines for a given quant unit. + * + * This is a generalized version for all known coding modes. + * Its speed can be improved by creating separate functions for each mode. + * + * @param[in] gb the GetBit context + * @param[in] tab code table telling how to decode spectral lines + * @param[in] vlc_tab ptr to the huffman table associated with the code table + * @param[out] out pointer to buffer where decoded data should be stored + * @param[in] num_specs number of spectral lines to decode + */ +static void decode_qu_spectra(GetBitContext *gb, const Atrac3pSpecCodeTab *tab, + VLC *vlc_tab, int16_t *out, const int num_specs) +{ + int i, j, pos, cf; + int group_size = tab->group_size; + int num_coeffs = tab->num_coeffs; + int bits = tab->bits; + int is_signed = tab->is_signed; + unsigned val, mask = (1 << bits) - 1; + + for (pos = 0; pos < num_specs;) { + if (group_size == 1 || get_bits1(gb)) { + for (j = 0; j < group_size; j++) { + val = get_vlc2(gb, vlc_tab->table, vlc_tab->bits, 1); + + for (i = 0; i < num_coeffs; i++) { + cf = val & mask; + if (is_signed) + cf = sign_extend(cf, bits); + else if (cf && get_bits1(gb)) + cf = -cf; + + out[pos++] = cf; + val >>= bits; + } + } + } else /* group skipped */ + pos += group_size * num_coeffs; + } +} + +/** + * Decode huffman-coded IMDCT spectrum for all channels. + * + * @param[in] gb the GetBit context + * @param[in,out] ctx ptr to the channel unit context + * @param[in] num_channels number of channels to process + * @param[in] avctx ptr to the AVCodecContext + */ +static void decode_spectrum(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, + int num_channels, AVCodecContext *avctx) +{ + int i, ch_num, qu, wordlen, codetab, tab_index, num_specs; + const Atrac3pSpecCodeTab *tab; + Atrac3pChanParams *chan; + + for (ch_num = 0; ch_num < num_channels; ch_num++) { + chan = &ctx->channels[ch_num]; + + memset(chan->spectrum, 0, sizeof(chan->spectrum)); + + /* set power compensation level to disabled */ + memset(chan->power_levs, ATRAC3P_POWER_COMP_OFF, sizeof(chan->power_levs)); + + for (qu = 0; qu < ctx->used_quant_units; qu++) { + num_specs = ff_atrac3p_qu_to_spec_pos[qu + 1] - + ff_atrac3p_qu_to_spec_pos[qu]; + + wordlen = chan->qu_wordlen[qu]; + codetab = chan->qu_tab_idx[qu]; + if (wordlen) { + if (!ctx->use_full_table) + codetab = atrac3p_ct_restricted_to_full[chan->table_type][wordlen - 1][codetab]; + + tab_index = (chan->table_type * 8 + codetab) * 7 + wordlen - 1; + tab = &atrac3p_spectra_tabs[tab_index]; + + /* this allows reusing VLC tables */ + if (tab->redirect >= 0) + tab_index = tab->redirect; + + decode_qu_spectra(gb, tab, &spec_vlc_tabs[tab_index], + &chan->spectrum[ff_atrac3p_qu_to_spec_pos[qu]], + num_specs); + } else if (ch_num && ctx->channels[0].qu_wordlen[qu] && !codetab) { + /* copy coefficients from master */ + memcpy(&chan->spectrum[ff_atrac3p_qu_to_spec_pos[qu]], + &ctx->channels[0].spectrum[ff_atrac3p_qu_to_spec_pos[qu]], + num_specs * + sizeof(chan->spectrum[ff_atrac3p_qu_to_spec_pos[qu]])); + chan->qu_wordlen[qu] = ctx->channels[0].qu_wordlen[qu]; + } + } + + /* Power compensation levels only present in the bitstream + * if there are more than 2 quant units. The lowest two units + * correspond to the frequencies 0...351 Hz, whose shouldn't + * be affected by the power compensation. */ + if (ctx->used_quant_units > 2) { + num_specs = atrac3p_subband_to_num_powgrps[ctx->num_coded_subbands - 1]; + for (i = 0; i < num_specs; i++) + chan->power_levs[i] = get_bits(gb, 4); + } + } +} + +/** + * Retrieve specified amount of flag bits from the input bitstream. + * The data can be shortened in the case of the following two common conditions: + * if all bits are zero then only one signal bit = 0 will be stored, + * if all bits are ones then two signal bits = 1,0 will be stored. + * Otherwise, all necessary bits will be directly stored + * prefixed by two signal bits = 1,1. + * + * @param[in] gb ptr to the GetBitContext + * @param[out] out where to place decoded flags + * @param[in] num_flags number of flags to process + * @return: 0 = all flag bits are zero, 1 = there is at least one non-zero flag bit + */ +static int get_subband_flags(GetBitContext *gb, uint8_t *out, int num_flags) +{ + int i, result; + + memset(out, 0, num_flags); + + result = get_bits1(gb); + if (result) { + if (get_bits1(gb)) + for (i = 0; i < num_flags; i++) + out[i] = get_bits1(gb); + else + memset(out, 1, num_flags); + } + + return result; +} + +/** + * Decode mdct window shape flags for all channels. + * + * @param[in] gb the GetBit context + * @param[in,out] ctx ptr to the channel unit context + * @param[in] num_channels number of channels to process + */ +static void decode_window_shape(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, + int num_channels) +{ + int ch_num; + + for (ch_num = 0; ch_num < num_channels; ch_num++) + get_subband_flags(gb, ctx->channels[ch_num].wnd_shape, + ctx->num_subbands); +} + +/** + * Decode number of gain control points. + * + * @param[in] gb the GetBit context + * @param[in,out] ctx ptr to the channel unit context + * @param[in] ch_num channel to process + * @param[in] coded_subbands number of subbands to process + * @return result code: 0 = OK, otherwise - error code + */ +static int decode_gainc_npoints(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, + int ch_num, int coded_subbands) +{ + int i, delta, delta_bits, min_val; + Atrac3pChanParams *chan = &ctx->channels[ch_num]; + Atrac3pChanParams *ref_chan = &ctx->channels[0]; + + switch (get_bits(gb, 2)) { /* switch according to coding mode */ + case 0: /* fixed-length coding */ + for (i = 0; i < coded_subbands; i++) + chan->gain_data[i].num_points = get_bits(gb, 3); + break; + case 1: /* variable-length coding */ + for (i = 0; i < coded_subbands; i++) + chan->gain_data[i].num_points = + get_vlc2(gb, gain_vlc_tabs[0].table, + gain_vlc_tabs[0].bits, 1); + break; + case 2: + if (ch_num) { /* VLC modulo delta to master channel */ + for (i = 0; i < coded_subbands; i++) { + delta = get_vlc2(gb, gain_vlc_tabs[1].table, + gain_vlc_tabs[1].bits, 1); + chan->gain_data[i].num_points = + (ref_chan->gain_data[i].num_points + delta) & 7; + } + } else { /* VLC modulo delta to previous */ + chan->gain_data[0].num_points = + get_vlc2(gb, gain_vlc_tabs[0].table, + gain_vlc_tabs[0].bits, 1); + + for (i = 1; i < coded_subbands; i++) { + delta = get_vlc2(gb, gain_vlc_tabs[1].table, + gain_vlc_tabs[1].bits, 1); + chan->gain_data[i].num_points = + (chan->gain_data[i - 1].num_points + delta) & 7; + } + } + break; + case 3: + if (ch_num) { /* copy data from master channel */ + for (i = 0; i < coded_subbands; i++) + chan->gain_data[i].num_points = + ref_chan->gain_data[i].num_points; + } else { /* shorter delta to min */ + delta_bits = get_bits(gb, 2); + min_val = get_bits(gb, 3); + + for (i = 0; i < coded_subbands; i++) { + chan->gain_data[i].num_points = min_val + GET_DELTA(gb, delta_bits); + if (chan->gain_data[i].num_points > 7) + return AVERROR_INVALIDDATA; + } + } + } + + return 0; +} + +/** + * Implements coding mode 3 (slave) for gain compensation levels. + * + * @param[out] dst ptr to the output array + * @param[in] ref ptr to the reference channel + */ +static inline void gainc_level_mode3s(AtracGainInfo *dst, AtracGainInfo *ref) +{ + int i; + + for (i = 0; i < dst->num_points; i++) + dst->lev_code[i] = (i >= ref->num_points) ? 7 : ref->lev_code[i]; +} + +/** + * Implements coding mode 1 (master) for gain compensation levels. + * + * @param[in] gb the GetBit context + * @param[in] ctx ptr to the channel unit context + * @param[out] dst ptr to the output array + */ +static inline void gainc_level_mode1m(GetBitContext *gb, + Atrac3pChanUnitCtx *ctx, + AtracGainInfo *dst) +{ + int i, delta; + + if (dst->num_points > 0) + dst->lev_code[0] = get_vlc2(gb, gain_vlc_tabs[2].table, + gain_vlc_tabs[2].bits, 1); + + for (i = 1; i < dst->num_points; i++) { + delta = get_vlc2(gb, gain_vlc_tabs[3].table, + gain_vlc_tabs[3].bits, 1); + dst->lev_code[i] = (dst->lev_code[i - 1] + delta) & 0xF; + } +} + +/** + * Decode level code for each gain control point. + * + * @param[in] gb the GetBit context + * @param[in,out] ctx ptr to the channel unit context + * @param[in] ch_num channel to process + * @param[in] coded_subbands number of subbands to process + * @return result code: 0 = OK, otherwise - error code + */ +static int decode_gainc_levels(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, + int ch_num, int coded_subbands) +{ + int sb, i, delta, delta_bits, min_val, pred; + Atrac3pChanParams *chan = &ctx->channels[ch_num]; + Atrac3pChanParams *ref_chan = &ctx->channels[0]; + + switch (get_bits(gb, 2)) { /* switch according to coding mode */ + case 0: /* fixed-length coding */ + for (sb = 0; sb < coded_subbands; sb++) + for (i = 0; i < chan->gain_data[sb].num_points; i++) + chan->gain_data[sb].lev_code[i] = get_bits(gb, 4); + break; + case 1: + if (ch_num) { /* VLC modulo delta to master channel */ + for (sb = 0; sb < coded_subbands; sb++) + for (i = 0; i < chan->gain_data[sb].num_points; i++) { + delta = get_vlc2(gb, gain_vlc_tabs[5].table, + gain_vlc_tabs[5].bits, 1); + pred = (i >= ref_chan->gain_data[sb].num_points) + ? 7 : ref_chan->gain_data[sb].lev_code[i]; + chan->gain_data[sb].lev_code[i] = (pred + delta) & 0xF; + } + } else { /* VLC modulo delta to previous */ + for (sb = 0; sb < coded_subbands; sb++) + gainc_level_mode1m(gb, ctx, &chan->gain_data[sb]); + } + break; + case 2: + if (ch_num) { /* VLC modulo delta to previous or clone master */ + for (sb = 0; sb < coded_subbands; sb++) + if (chan->gain_data[sb].num_points > 0) { + if (get_bits1(gb)) + gainc_level_mode1m(gb, ctx, &chan->gain_data[sb]); + else + gainc_level_mode3s(&chan->gain_data[sb], + &ref_chan->gain_data[sb]); + } + } else { /* VLC modulo delta to lev_codes of previous subband */ + if (chan->gain_data[0].num_points > 0) + gainc_level_mode1m(gb, ctx, &chan->gain_data[0]); + + for (sb = 1; sb < coded_subbands; sb++) + for (i = 0; i < chan->gain_data[sb].num_points; i++) { + delta = get_vlc2(gb, gain_vlc_tabs[4].table, + gain_vlc_tabs[4].bits, 1); + pred = (i >= chan->gain_data[sb - 1].num_points) + ? 7 : chan->gain_data[sb - 1].lev_code[i]; + chan->gain_data[sb].lev_code[i] = (pred + delta) & 0xF; + } + } + break; + case 3: + if (ch_num) { /* clone master */ + for (sb = 0; sb < coded_subbands; sb++) + gainc_level_mode3s(&chan->gain_data[sb], + &ref_chan->gain_data[sb]); + } else { /* shorter delta to min */ + delta_bits = get_bits(gb, 2); + min_val = get_bits(gb, 4); + + for (sb = 0; sb < coded_subbands; sb++) + for (i = 0; i < chan->gain_data[sb].num_points; i++) { + chan->gain_data[sb].lev_code[i] = min_val + GET_DELTA(gb, delta_bits); + if (chan->gain_data[sb].lev_code[i] > 15) + return AVERROR_INVALIDDATA; + } + } + break; + } + + return 0; +} + +/** + * Implements coding mode 0 for gain compensation locations. + * + * @param[in] gb the GetBit context + * @param[in] ctx ptr to the channel unit context + * @param[out] dst ptr to the output array + * @param[in] pos position of the value to be processed + */ +static inline void gainc_loc_mode0(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, + AtracGainInfo *dst, int pos) +{ + int delta_bits; + + if (!pos || dst->loc_code[pos - 1] < 15) + dst->loc_code[pos] = get_bits(gb, 5); + else if (dst->loc_code[pos - 1] >= 30) + dst->loc_code[pos] = 31; + else { + delta_bits = av_log2(30 - dst->loc_code[pos - 1]) + 1; + dst->loc_code[pos] = dst->loc_code[pos - 1] + + get_bits(gb, delta_bits) + 1; + } +} + +/** + * Implements coding mode 1 for gain compensation locations. + * + * @param[in] gb the GetBit context + * @param[in] ctx ptr to the channel unit context + * @param[out] dst ptr to the output array + */ +static inline void gainc_loc_mode1(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, + AtracGainInfo *dst) +{ + int i; + VLC *tab; + + if (dst->num_points > 0) { + /* 1st coefficient is stored directly */ + dst->loc_code[0] = get_bits(gb, 5); + + for (i = 1; i < dst->num_points; i++) { + /* switch VLC according to the curve direction + * (ascending/descending) */ + tab = (dst->lev_code[i] <= dst->lev_code[i - 1]) + ? &gain_vlc_tabs[7] + : &gain_vlc_tabs[9]; + dst->loc_code[i] = dst->loc_code[i - 1] + + get_vlc2(gb, tab->table, tab->bits, 1); + } + } +} + +/** + * Decode location code for each gain control point. + * + * @param[in] gb the GetBit context + * @param[in,out] ctx ptr to the channel unit context + * @param[in] ch_num channel to process + * @param[in] coded_subbands number of subbands to process + * @param[in] avctx ptr to the AVCodecContext + * @return result code: 0 = OK, otherwise - error code + */ +static int decode_gainc_loc_codes(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, + int ch_num, int coded_subbands, + AVCodecContext *avctx) +{ + int sb, i, delta, delta_bits, min_val, pred, more_than_ref; + AtracGainInfo *dst, *ref; + VLC *tab; + Atrac3pChanParams *chan = &ctx->channels[ch_num]; + Atrac3pChanParams *ref_chan = &ctx->channels[0]; + + switch (get_bits(gb, 2)) { /* switch according to coding mode */ + case 0: /* sequence of numbers in ascending order */ + for (sb = 0; sb < coded_subbands; sb++) + for (i = 0; i < chan->gain_data[sb].num_points; i++) + gainc_loc_mode0(gb, ctx, &chan->gain_data[sb], i); + break; + case 1: + if (ch_num) { + for (sb = 0; sb < coded_subbands; sb++) { + if (chan->gain_data[sb].num_points <= 0) + continue; + dst = &chan->gain_data[sb]; + ref = &ref_chan->gain_data[sb]; + + /* 1st value is vlc-coded modulo delta to master */ + delta = get_vlc2(gb, gain_vlc_tabs[10].table, + gain_vlc_tabs[10].bits, 1); + pred = ref->num_points > 0 ? ref->loc_code[0] : 0; + dst->loc_code[0] = (pred + delta) & 0x1F; + + for (i = 1; i < dst->num_points; i++) { + more_than_ref = i >= ref->num_points; + if (dst->lev_code[i] > dst->lev_code[i - 1]) { + /* ascending curve */ + if (more_than_ref) { + delta = + get_vlc2(gb, gain_vlc_tabs[9].table, + gain_vlc_tabs[9].bits, 1); + dst->loc_code[i] = dst->loc_code[i - 1] + delta; + } else { + if (get_bits1(gb)) + gainc_loc_mode0(gb, ctx, dst, i); // direct coding + else + dst->loc_code[i] = ref->loc_code[i]; // clone master + } + } else { /* descending curve */ + tab = more_than_ref ? &gain_vlc_tabs[7] + : &gain_vlc_tabs[10]; + delta = get_vlc2(gb, tab->table, tab->bits, 1); + if (more_than_ref) + dst->loc_code[i] = dst->loc_code[i - 1] + delta; + else + dst->loc_code[i] = (ref->loc_code[i] + delta) & 0x1F; + } + } + } + } else /* VLC delta to previous */ + for (sb = 0; sb < coded_subbands; sb++) + gainc_loc_mode1(gb, ctx, &chan->gain_data[sb]); + break; + case 2: + if (ch_num) { + for (sb = 0; sb < coded_subbands; sb++) { + if (chan->gain_data[sb].num_points <= 0) + continue; + dst = &chan->gain_data[sb]; + ref = &ref_chan->gain_data[sb]; + if (dst->num_points > ref->num_points || get_bits1(gb)) + gainc_loc_mode1(gb, ctx, dst); + else /* clone master for the whole subband */ + for (i = 0; i < chan->gain_data[sb].num_points; i++) + dst->loc_code[i] = ref->loc_code[i]; + } + } else { + /* data for the first subband is coded directly */ + for (i = 0; i < chan->gain_data[0].num_points; i++) + gainc_loc_mode0(gb, ctx, &chan->gain_data[0], i); + + for (sb = 1; sb < coded_subbands; sb++) { + if (chan->gain_data[sb].num_points <= 0) + continue; + dst = &chan->gain_data[sb]; + + /* 1st value is vlc-coded modulo delta to the corresponding + * value of the previous subband if any or zero */ + delta = get_vlc2(gb, gain_vlc_tabs[6].table, + gain_vlc_tabs[6].bits, 1); + pred = dst[-1].num_points > 0 + ? dst[-1].loc_code[0] : 0; + dst->loc_code[0] = (pred + delta) & 0x1F; + + for (i = 1; i < dst->num_points; i++) { + more_than_ref = i >= dst[-1].num_points; + /* Select VLC table according to curve direction and + * presence of prediction. */ + tab = &gain_vlc_tabs[(dst->lev_code[i] > dst->lev_code[i - 1]) * + 2 + more_than_ref + 6]; + delta = get_vlc2(gb, tab->table, tab->bits, 1); + if (more_than_ref) + dst->loc_code[i] = dst->loc_code[i - 1] + delta; + else + dst->loc_code[i] = (dst[-1].loc_code[i] + delta) & 0x1F; + } + } + } + break; + case 3: + if (ch_num) { /* clone master or direct or direct coding */ + for (sb = 0; sb < coded_subbands; sb++) + for (i = 0; i < chan->gain_data[sb].num_points; i++) { + if (i >= ref_chan->gain_data[sb].num_points) + gainc_loc_mode0(gb, ctx, &chan->gain_data[sb], i); + else + chan->gain_data[sb].loc_code[i] = + ref_chan->gain_data[sb].loc_code[i]; + } + } else { /* shorter delta to min */ + delta_bits = get_bits(gb, 2) + 1; + min_val = get_bits(gb, 5); + + for (sb = 0; sb < coded_subbands; sb++) + for (i = 0; i < chan->gain_data[sb].num_points; i++) + chan->gain_data[sb].loc_code[i] = min_val + i + + get_bits(gb, delta_bits); + } + break; + } + + /* Validate decoded information */ + for (sb = 0; sb < coded_subbands; sb++) { + dst = &chan->gain_data[sb]; + for (i = 0; i < chan->gain_data[sb].num_points; i++) { + if (dst->loc_code[i] < 0 || dst->loc_code[i] > 31 || + (i && dst->loc_code[i] <= dst->loc_code[i - 1])) { + av_log(avctx, AV_LOG_ERROR, + "Invalid gain location: ch=%d, sb=%d, pos=%d, val=%d\n", + ch_num, sb, i, dst->loc_code[i]); + return AVERROR_INVALIDDATA; + } + } + } + + return 0; +} + +/** + * Decode gain control data for all channels. + * + * @param[in] gb the GetBit context + * @param[in,out] ctx ptr to the channel unit context + * @param[in] num_channels number of channels to process + * @param[in] avctx ptr to the AVCodecContext + * @return result code: 0 = OK, otherwise - error code + */ +static int decode_gainc_data(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, + int num_channels, AVCodecContext *avctx) +{ + int ch_num, coded_subbands, sb, ret; + + for (ch_num = 0; ch_num < num_channels; ch_num++) { + memset(ctx->channels[ch_num].gain_data, 0, + sizeof(*ctx->channels[ch_num].gain_data) * ATRAC3P_SUBBANDS); + + if (get_bits1(gb)) { /* gain control data present? */ + coded_subbands = get_bits(gb, 4) + 1; + if (get_bits1(gb)) /* is high band gain data replication on? */ + ctx->channels[ch_num].num_gain_subbands = get_bits(gb, 4) + 1; + else + ctx->channels[ch_num].num_gain_subbands = coded_subbands; + + if ((ret = decode_gainc_npoints(gb, ctx, ch_num, coded_subbands)) < 0 || + (ret = decode_gainc_levels(gb, ctx, ch_num, coded_subbands)) < 0 || + (ret = decode_gainc_loc_codes(gb, ctx, ch_num, coded_subbands, avctx)) < 0) + return ret; + + if (coded_subbands > 0) { /* propagate gain data if requested */ + for (sb = coded_subbands; sb < ctx->channels[ch_num].num_gain_subbands; sb++) + ctx->channels[ch_num].gain_data[sb] = + ctx->channels[ch_num].gain_data[sb - 1]; + } + } else { + ctx->channels[ch_num].num_gain_subbands = 0; + } + } + + return 0; +} + +/** + * Decode envelope for all tones of a channel. + * + * @param[in] gb the GetBit context + * @param[in,out] ctx ptr to the channel unit context + * @param[in] ch_num channel to process + * @param[in] band_has_tones ptr to an array of per-band-flags: + * 1 - tone data present + */ +static void decode_tones_envelope(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, + int ch_num, int band_has_tones[]) +{ + int sb; + Atrac3pWavesData *dst = ctx->channels[ch_num].tones_info; + Atrac3pWavesData *ref = ctx->channels[0].tones_info; + + if (!ch_num || !get_bits1(gb)) { /* mode 0: fixed-length coding */ + for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) { + if (!band_has_tones[sb]) + continue; + dst[sb].pend_env.has_start_point = get_bits1(gb); + dst[sb].pend_env.start_pos = dst[sb].pend_env.has_start_point + ? get_bits(gb, 5) : -1; + dst[sb].pend_env.has_stop_point = get_bits1(gb); + dst[sb].pend_env.stop_pos = dst[sb].pend_env.has_stop_point + ? get_bits(gb, 5) : 32; + } + } else { /* mode 1(slave only): copy master */ + for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) { + if (!band_has_tones[sb]) + continue; + dst[sb].pend_env.has_start_point = ref[sb].pend_env.has_start_point; + dst[sb].pend_env.has_stop_point = ref[sb].pend_env.has_stop_point; + dst[sb].pend_env.start_pos = ref[sb].pend_env.start_pos; + dst[sb].pend_env.stop_pos = ref[sb].pend_env.stop_pos; + } + } +} + +/** + * Decode number of tones for each subband of a channel. + * + * @param[in] gb the GetBit context + * @param[in,out] ctx ptr to the channel unit context + * @param[in] ch_num channel to process + * @param[in] band_has_tones ptr to an array of per-band-flags: + * 1 - tone data present + * @param[in] avctx ptr to the AVCodecContext + * @return result code: 0 = OK, otherwise - error code + */ +static int decode_band_numwavs(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, + int ch_num, int band_has_tones[], + AVCodecContext *avctx) +{ + int mode, sb, delta; + Atrac3pWavesData *dst = ctx->channels[ch_num].tones_info; + Atrac3pWavesData *ref = ctx->channels[0].tones_info; + + mode = get_bits(gb, ch_num + 1); + switch (mode) { + case 0: /** fixed-length coding */ + for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) + if (band_has_tones[sb]) + dst[sb].num_wavs = get_bits(gb, 4); + break; + case 1: /** variable-length coding */ + for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) + if (band_has_tones[sb]) + dst[sb].num_wavs = + get_vlc2(gb, tone_vlc_tabs[1].table, + tone_vlc_tabs[1].bits, 1); + break; + case 2: /** VLC modulo delta to master (slave only) */ + for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) + if (band_has_tones[sb]) { + delta = get_vlc2(gb, tone_vlc_tabs[2].table, + tone_vlc_tabs[2].bits, 1); + delta = sign_extend(delta, 3); + dst[sb].num_wavs = (ref[sb].num_wavs + delta) & 0xF; + } + break; + case 3: /** copy master (slave only) */ + for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) + if (band_has_tones[sb]) + dst[sb].num_wavs = ref[sb].num_wavs; + break; + } + + /** initialize start tone index for each subband */ + for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) + if (band_has_tones[sb]) { + if (ctx->waves_info->tones_index + dst[sb].num_wavs > 48) { + av_log(avctx, AV_LOG_ERROR, + "Too many tones: %d (max. 48), frame: %d!\n", + ctx->waves_info->tones_index + dst[sb].num_wavs, + avctx->frame_number); + return AVERROR_INVALIDDATA; + } + dst[sb].start_index = ctx->waves_info->tones_index; + ctx->waves_info->tones_index += dst[sb].num_wavs; + } + + return 0; +} + +/** + * Decode frequency information for each subband of a channel. + * + * @param[in] gb the GetBit context + * @param[in,out] ctx ptr to the channel unit context + * @param[in] ch_num channel to process + * @param[in] band_has_tones ptr to an array of per-band-flags: + * 1 - tone data present + */ +static void decode_tones_frequency(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, + int ch_num, int band_has_tones[]) +{ + int sb, i, direction, nbits, pred, delta; + Atrac3pWaveParam *iwav, *owav; + Atrac3pWavesData *dst = ctx->channels[ch_num].tones_info; + Atrac3pWavesData *ref = ctx->channels[0].tones_info; + + if (!ch_num || !get_bits1(gb)) { /* mode 0: fixed-length coding */ + for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) { + if (!band_has_tones[sb] || !dst[sb].num_wavs) + continue; + iwav = &ctx->waves_info->waves[dst[sb].start_index]; + direction = (dst[sb].num_wavs > 1) ? get_bits1(gb) : 0; + if (direction) { /** packed numbers in descending order */ + if (dst[sb].num_wavs) + iwav[dst[sb].num_wavs - 1].freq_index = get_bits(gb, 10); + for (i = dst[sb].num_wavs - 2; i >= 0 ; i--) { + nbits = av_log2(iwav[i+1].freq_index) + 1; + iwav[i].freq_index = get_bits(gb, nbits); + } + } else { /** packed numbers in ascending order */ + for (i = 0; i < dst[sb].num_wavs; i++) { + if (!i || iwav[i - 1].freq_index < 512) + iwav[i].freq_index = get_bits(gb, 10); + else { + nbits = av_log2(1023 - iwav[i - 1].freq_index) + 1; + iwav[i].freq_index = get_bits(gb, nbits) + + 1024 - (1 << nbits); + } + } + } + } + } else { /* mode 1: VLC modulo delta to master (slave only) */ + for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) { + if (!band_has_tones[sb] || !dst[sb].num_wavs) + continue; + iwav = &ctx->waves_info->waves[ref[sb].start_index]; + owav = &ctx->waves_info->waves[dst[sb].start_index]; + for (i = 0; i < dst[sb].num_wavs; i++) { + delta = get_vlc2(gb, tone_vlc_tabs[6].table, + tone_vlc_tabs[6].bits, 1); + delta = sign_extend(delta, 8); + pred = (i < ref[sb].num_wavs) ? iwav[i].freq_index : + (ref[sb].num_wavs ? iwav[ref[sb].num_wavs - 1].freq_index : 0); + owav[i].freq_index = (pred + delta) & 0x3FF; + } + } + } +} + +/** + * Decode amplitude information for each subband of a channel. + * + * @param[in] gb the GetBit context + * @param[in,out] ctx ptr to the channel unit context + * @param[in] ch_num channel to process + * @param[in] band_has_tones ptr to an array of per-band-flags: + * 1 - tone data present + */ +static void decode_tones_amplitude(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, + int ch_num, int band_has_tones[]) +{ + int mode, sb, j, i, diff, maxdiff, fi, delta, pred; + Atrac3pWaveParam *wsrc, *wref; + int refwaves[48]; + Atrac3pWavesData *dst = ctx->channels[ch_num].tones_info; + Atrac3pWavesData *ref = ctx->channels[0].tones_info; + + if (ch_num) { + for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) { + if (!band_has_tones[sb] || !dst[sb].num_wavs) + continue; + wsrc = &ctx->waves_info->waves[dst[sb].start_index]; + wref = &ctx->waves_info->waves[ref[sb].start_index]; + for (j = 0; j < dst[sb].num_wavs; j++) { + for (i = 0, fi = 0, maxdiff = 1024; i < ref[sb].num_wavs; i++) { + diff = FFABS(wsrc[j].freq_index - wref[i].freq_index); + if (diff < maxdiff) { + maxdiff = diff; + fi = i; + } + } + + if (maxdiff < 8) + refwaves[dst[sb].start_index + j] = fi + ref[sb].start_index; + else if (j < ref[sb].num_wavs) + refwaves[dst[sb].start_index + j] = j + ref[sb].start_index; + else + refwaves[dst[sb].start_index + j] = -1; + } + } + } + + mode = get_bits(gb, ch_num + 1); + + switch (mode) { + case 0: /** fixed-length coding */ + for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) { + if (!band_has_tones[sb] || !dst[sb].num_wavs) + continue; + if (ctx->waves_info->amplitude_mode) + for (i = 0; i < dst[sb].num_wavs; i++) + ctx->waves_info->waves[dst[sb].start_index + i].amp_sf = get_bits(gb, 6); + else + ctx->waves_info->waves[dst[sb].start_index].amp_sf = get_bits(gb, 6); + } + break; + case 1: /** min + VLC delta */ + for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) { + if (!band_has_tones[sb] || !dst[sb].num_wavs) + continue; + if (ctx->waves_info->amplitude_mode) + for (i = 0; i < dst[sb].num_wavs; i++) + ctx->waves_info->waves[dst[sb].start_index + i].amp_sf = + get_vlc2(gb, tone_vlc_tabs[3].table, + tone_vlc_tabs[3].bits, 1) + 20; + else + ctx->waves_info->waves[dst[sb].start_index].amp_sf = + get_vlc2(gb, tone_vlc_tabs[4].table, + tone_vlc_tabs[4].bits, 1) + 24; + } + break; + case 2: /** VLC modulo delta to master (slave only) */ + for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) { + if (!band_has_tones[sb] || !dst[sb].num_wavs) + continue; + for (i = 0; i < dst[sb].num_wavs; i++) { + delta = get_vlc2(gb, tone_vlc_tabs[5].table, + tone_vlc_tabs[5].bits, 1); + delta = sign_extend(delta, 5); + pred = refwaves[dst[sb].start_index + i] >= 0 ? + ctx->waves_info->waves[refwaves[dst[sb].start_index + i]].amp_sf : 34; + ctx->waves_info->waves[dst[sb].start_index + i].amp_sf = (pred + delta) & 0x3F; + } + } + break; + case 3: /** clone master (slave only) */ + for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) { + if (!band_has_tones[sb]) + continue; + for (i = 0; i < dst[sb].num_wavs; i++) + ctx->waves_info->waves[dst[sb].start_index + i].amp_sf = + refwaves[dst[sb].start_index + i] >= 0 + ? ctx->waves_info->waves[refwaves[dst[sb].start_index + i]].amp_sf + : 32; + } + break; + } +} + +/** + * Decode phase information for each subband of a channel. + * + * @param[in] gb the GetBit context + * @param[in,out] ctx ptr to the channel unit context + * @param[in] ch_num channel to process + * @param[in] band_has_tones ptr to an array of per-band-flags: + * 1 - tone data present + */ +static void decode_tones_phase(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, + int ch_num, int band_has_tones[]) +{ + int sb, i; + Atrac3pWaveParam *wparam; + Atrac3pWavesData *dst = ctx->channels[ch_num].tones_info; + + for (sb = 0; sb < ctx->waves_info->num_tone_bands; sb++) { + if (!band_has_tones[sb]) + continue; + wparam = &ctx->waves_info->waves[dst[sb].start_index]; + for (i = 0; i < dst[sb].num_wavs; i++) + wparam[i].phase_index = get_bits(gb, 5); + } +} + +/** + * Decode tones info for all channels. + * + * @param[in] gb the GetBit context + * @param[in,out] ctx ptr to the channel unit context + * @param[in] num_channels number of channels to process + * @param[in] avctx ptr to the AVCodecContext + * @return result code: 0 = OK, otherwise - error code + */ +static int decode_tones_info(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, + int num_channels, AVCodecContext *avctx) +{ + int ch_num, i, ret; + int band_has_tones[16]; + + for (ch_num = 0; ch_num < num_channels; ch_num++) + memset(ctx->channels[ch_num].tones_info, 0, + sizeof(*ctx->channels[ch_num].tones_info) * ATRAC3P_SUBBANDS); + + ctx->waves_info->tones_present = get_bits1(gb); + if (!ctx->waves_info->tones_present) + return 0; + + memset(ctx->waves_info->waves, 0, sizeof(ctx->waves_info->waves)); + + ctx->waves_info->amplitude_mode = get_bits1(gb); + if (!ctx->waves_info->amplitude_mode) { + avpriv_report_missing_feature(avctx, "GHA amplitude mode 0"); + return AVERROR_PATCHWELCOME; + } + + ctx->waves_info->num_tone_bands = + get_vlc2(gb, tone_vlc_tabs[0].table, + tone_vlc_tabs[0].bits, 1) + 1; + + if (num_channels == 2) { + get_subband_flags(gb, ctx->waves_info->tone_sharing, ctx->waves_info->num_tone_bands); + get_subband_flags(gb, ctx->waves_info->tone_master, ctx->waves_info->num_tone_bands); + if (get_subband_flags(gb, ctx->waves_info->phase_shift, + ctx->waves_info->num_tone_bands)) { + avpriv_report_missing_feature(avctx, "GHA Phase shifting"); + return AVERROR_PATCHWELCOME; + } + } + + ctx->waves_info->tones_index = 0; + + for (ch_num = 0; ch_num < num_channels; ch_num++) { + for (i = 0; i < ctx->waves_info->num_tone_bands; i++) + band_has_tones[i] = !ch_num ? 1 : !ctx->waves_info->tone_sharing[i]; + + decode_tones_envelope(gb, ctx, ch_num, band_has_tones); + if ((ret = decode_band_numwavs(gb, ctx, ch_num, band_has_tones, + avctx)) < 0) + return ret; + + decode_tones_frequency(gb, ctx, ch_num, band_has_tones); + decode_tones_amplitude(gb, ctx, ch_num, band_has_tones); + decode_tones_phase(gb, ctx, ch_num, band_has_tones); + } + + if (num_channels == 2) { + for (i = 0; i < ctx->waves_info->num_tone_bands; i++) { + if (ctx->waves_info->tone_sharing[i]) + ctx->channels[1].tones_info[i] = ctx->channels[0].tones_info[i]; + + if (ctx->waves_info->tone_master[i]) + FFSWAP(Atrac3pWavesData, ctx->channels[0].tones_info[i], + ctx->channels[1].tones_info[i]); + } + } + + return 0; +} + +int ff_atrac3p_decode_channel_unit(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, + int num_channels, AVCodecContext *avctx) +{ + int ret; + + /* parse sound header */ + ctx->num_quant_units = get_bits(gb, 5) + 1; + if (ctx->num_quant_units > 28 && ctx->num_quant_units < 32) { + av_log(avctx, AV_LOG_ERROR, + "Invalid number of quantization units: %d!\n", + ctx->num_quant_units); + return AVERROR_INVALIDDATA; + } + + ctx->mute_flag = get_bits1(gb); + + /* decode various sound parameters */ + if ((ret = decode_quant_wordlen(gb, ctx, num_channels, avctx)) < 0) + return ret; + + ctx->num_subbands = atrac3p_qu_to_subband[ctx->num_quant_units - 1] + 1; + ctx->num_coded_subbands = ctx->used_quant_units + ? atrac3p_qu_to_subband[ctx->used_quant_units - 1] + 1 + : 0; + + if ((ret = decode_scale_factors(gb, ctx, num_channels, avctx)) < 0) + return ret; + + if ((ret = decode_code_table_indexes(gb, ctx, num_channels, avctx)) < 0) + return ret; + + decode_spectrum(gb, ctx, num_channels, avctx); + + if (num_channels == 2) { + get_subband_flags(gb, ctx->swap_channels, ctx->num_coded_subbands); + get_subband_flags(gb, ctx->negate_coeffs, ctx->num_coded_subbands); + } + + decode_window_shape(gb, ctx, num_channels); + + if ((ret = decode_gainc_data(gb, ctx, num_channels, avctx)) < 0) + return ret; + + if ((ret = decode_tones_info(gb, ctx, num_channels, avctx)) < 0) + return ret; + + /* decode global noise info */ + ctx->noise_present = get_bits1(gb); + if (ctx->noise_present) { + ctx->noise_level_index = get_bits(gb, 4); + ctx->noise_table_index = get_bits(gb, 4); + } + + return 0; +} diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/atrac3plus.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/atrac3plus.h new file mode 100644 index 000000000..1b001fae6 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/atrac3plus.h @@ -0,0 +1,240 @@ +/* + * ATRAC3+ compatible decoder + * + * Copyright (c) 2010-2013 Maxim Poliakovski + * + * 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 + * Global structures, constants and data for ATRAC3+ decoder. + */ + +#ifndef AVCODEC_ATRAC3PLUS_H +#define AVCODEC_ATRAC3PLUS_H + +#include + +#include "libavutil/float_dsp.h" +#include "atrac.h" +#include "avcodec.h" +#include "fft.h" +#include "get_bits.h" + +/** Global unit sizes */ +#define ATRAC3P_SUBBANDS 16 ///< number of PQF subbands +#define ATRAC3P_SUBBAND_SAMPLES 128 ///< number of samples per subband +#define ATRAC3P_FRAME_SAMPLES (ATRAC3P_SUBBAND_SAMPLES * ATRAC3P_SUBBANDS) + +#define ATRAC3P_PQF_FIR_LEN 12 ///< length of the prototype FIR of the PQF + +/** Global constants */ +#define ATRAC3P_POWER_COMP_OFF 15 ///< disable power compensation + +/** ATRAC3+ channel unit types */ +enum Atrac3pChannelUnitTypes { + CH_UNIT_MONO = 0, ///< unit containing one coded channel + CH_UNIT_STEREO = 1, ///< unit containing two jointly-coded channels + CH_UNIT_EXTENSION = 2, ///< unit containing extension information + CH_UNIT_TERMINATOR = 3 ///< unit sequence terminator +}; + +/** Per-channel IPQF history */ +typedef struct Atrac3pIPQFChannelCtx { + DECLARE_ALIGNED(32, float, buf1)[ATRAC3P_PQF_FIR_LEN * 2][8]; + DECLARE_ALIGNED(32, float, buf2)[ATRAC3P_PQF_FIR_LEN * 2][8]; + int pos; +} Atrac3pIPQFChannelCtx; + +/** Amplitude envelope of a group of sine waves */ +typedef struct Atrac3pWaveEnvelope { + int has_start_point; ///< indicates start point within the GHA window + int has_stop_point; ///< indicates stop point within the GHA window + int start_pos; ///< start position expressed in n*4 samples + int stop_pos; ///< stop position expressed in n*4 samples +} Atrac3pWaveEnvelope; + +/** Parameters of a group of sine waves */ +typedef struct Atrac3pWavesData { + Atrac3pWaveEnvelope pend_env; ///< pending envelope from the previous frame + Atrac3pWaveEnvelope curr_env; ///< group envelope from the current frame + int num_wavs; ///< number of sine waves in the group + int start_index; ///< start index into global tones table for that subband +} Atrac3pWavesData; + +/** Parameters of a single sine wave */ +typedef struct Atrac3pWaveParam { + int freq_index; ///< wave frequency index + int amp_sf; ///< quantized amplitude scale factor + int amp_index; ///< quantized amplitude index + int phase_index; ///< quantized phase index +} Atrac3pWaveParam; + +/** Sound channel parameters */ +typedef struct Atrac3pChanParams { + int ch_num; + int num_coded_vals; ///< number of transmitted quant unit values + int fill_mode; + int split_point; + int table_type; ///< table type: 0 - tone?, 1- noise? + int qu_wordlen[32]; ///< array of word lengths for each quant unit + int qu_sf_idx[32]; ///< array of scale factor indexes for each quant unit + int qu_tab_idx[32]; ///< array of code table indexes for each quant unit + int16_t spectrum[2048]; ///< decoded IMDCT spectrum + uint8_t power_levs[5]; ///< power compensation levels + + /* imdct window shape history (2 frames) for overlapping. */ + uint8_t wnd_shape_hist[2][ATRAC3P_SUBBANDS]; ///< IMDCT window shape, 0=sine/1=steep + uint8_t *wnd_shape; ///< IMDCT window shape for current frame + uint8_t *wnd_shape_prev; ///< IMDCT window shape for previous frame + + /* gain control data history (2 frames) for overlapping. */ + AtracGainInfo gain_data_hist[2][ATRAC3P_SUBBANDS]; ///< gain control data for all subbands + AtracGainInfo *gain_data; ///< gain control data for next frame + AtracGainInfo *gain_data_prev; ///< gain control data for previous frame + int num_gain_subbands; ///< number of subbands with gain control data + + /* tones data history (2 frames) for overlapping. */ + Atrac3pWavesData tones_info_hist[2][ATRAC3P_SUBBANDS]; + Atrac3pWavesData *tones_info; + Atrac3pWavesData *tones_info_prev; +} Atrac3pChanParams; + +/* Per-unit sine wave parameters */ +typedef struct Atrac3pWaveSynthParams { + int tones_present; ///< 1 - tones info present + int amplitude_mode; ///< 1 - low range, 0 - high range + int num_tone_bands; ///< number of PQF bands with tones + uint8_t tone_sharing[ATRAC3P_SUBBANDS]; ///< 1 - subband-wise tone sharing flags + uint8_t tone_master[ATRAC3P_SUBBANDS]; ///< 1 - subband-wise tone channel swapping + uint8_t phase_shift[ATRAC3P_SUBBANDS]; ///< 1 - subband-wise 180° phase shifting + int tones_index; ///< total sum of tones in this unit + Atrac3pWaveParam waves[48]; +} Atrac3pWaveSynthParams; + +/** Channel unit parameters */ +typedef struct Atrac3pChanUnitCtx { + /* channel unit variables */ + int unit_type; ///< unit type (mono/stereo) + int num_quant_units; + int num_subbands; + int used_quant_units; ///< number of quant units with coded spectrum + int num_coded_subbands; ///< number of subbands with coded spectrum + int mute_flag; ///< mute flag + int use_full_table; ///< 1 - full table list, 0 - restricted one + int noise_present; ///< 1 - global noise info present + int noise_level_index; ///< global noise level index + int noise_table_index; ///< global noise RNG table index + uint8_t swap_channels[ATRAC3P_SUBBANDS]; ///< 1 - perform subband-wise channel swapping + uint8_t negate_coeffs[ATRAC3P_SUBBANDS]; ///< 1 - subband-wise IMDCT coefficients negation + Atrac3pChanParams channels[2]; + + /* Variables related to GHA tones */ + Atrac3pWaveSynthParams wave_synth_hist[2]; ///< waves synth history for two frames + Atrac3pWaveSynthParams *waves_info; + Atrac3pWaveSynthParams *waves_info_prev; + + Atrac3pIPQFChannelCtx ipqf_ctx[2]; + DECLARE_ALIGNED(32, float, prev_buf)[2][ATRAC3P_FRAME_SAMPLES]; ///< overlapping buffer +} Atrac3pChanUnitCtx; + +/** + * Initialize VLC tables for bitstream parsing. + */ +void ff_atrac3p_init_vlcs(void); + +/** + * Decode bitstream data of a channel unit. + * + * @param[in] gb the GetBit context + * @param[in,out] ctx ptr to the channel unit context + * @param[in] num_channels number of channels to process + * @param[in] avctx ptr to the AVCodecContext + * @return result code: 0 = OK, otherwise - error code + */ +int ff_atrac3p_decode_channel_unit(GetBitContext *gb, Atrac3pChanUnitCtx *ctx, + int num_channels, AVCodecContext *avctx); + +/** + * Initialize IMDCT transform. + * + * @param[in] avctx ptr to the AVCodecContext + * @param[in] mdct_ctx pointer to MDCT transform context + */ +void ff_atrac3p_init_imdct(AVCodecContext *avctx, FFTContext *mdct_ctx); + +/** + * Initialize sine waves synthesizer. + */ +void ff_atrac3p_init_wave_synth(void); + +/** + * Synthesize sine waves for a particular subband. + * + * @param[in] ch_unit pointer to the channel unit context + * @param[in] fdsp pointer to float DSP context + * @param[in] ch_num which channel to process + * @param[in] sb which subband to process + * @param[out] out receives processed data + */ +void ff_atrac3p_generate_tones(Atrac3pChanUnitCtx *ch_unit, AVFloatDSPContext *fdsp, + int ch_num, int sb, float *out); + +/** + * Perform power compensation aka noise dithering. + * + * @param[in] ctx ptr to the channel context + * @param[in] ch_index which channel to process + * @param[in,out] sp ptr to channel spectrum to process + * @param[in] rng_index indicates which RNG table to use + * @param[in] sb_num which subband to process + */ +void ff_atrac3p_power_compensation(Atrac3pChanUnitCtx *ctx, int ch_index, + float *sp, int rng_index, int sb_num); + +/** + * Regular IMDCT and windowing without overlapping, + * with spectrum reversal in the odd subbands. + * + * @param[in] fdsp pointer to float DSP context + * @param[in] mdct_ctx pointer to MDCT transform context + * @param[in] pIn float input + * @param[out] pOut float output + * @param[in] wind_id which MDCT window to apply + * @param[in] sb subband number + */ +void ff_atrac3p_imdct(AVFloatDSPContext *fdsp, FFTContext *mdct_ctx, float *pIn, + float *pOut, int wind_id, int sb); + +/** + * Subband synthesis filter based on the polyphase quadrature (pseudo-QMF) + * filter bank. + * + * @param[in] dct_ctx ptr to the pre-initialized IDCT context + * @param[in,out] hist ptr to the filter history + * @param[in] in input data to process + * @param[out] out receives processed data + */ +void ff_atrac3p_ipqf(FFTContext *dct_ctx, Atrac3pIPQFChannelCtx *hist, + const float *in, float *out); + +extern const uint16_t ff_atrac3p_qu_to_spec_pos[33]; +extern const float ff_atrac3p_sf_tab[64]; +extern const float ff_atrac3p_mant_tab[8]; + +#endif /* AVCODEC_ATRAC3PLUS_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/atrac3plus_data.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/atrac3plus_data.h new file mode 100644 index 000000000..2a107eef1 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/atrac3plus_data.h @@ -0,0 +1,1914 @@ +/* + * ATRAC3+ compatible decoder + * + * Copyright (c) 2010-2013 Maxim Poliakovski + * + * 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_ATRAC3PLUS_DATA_H +#define AVCODEC_ATRAC3PLUS_DATA_H + +#include +#include + +/** VLC tables for wordlen */ +static const uint8_t atrac3p_wl_huff_code1[3] = { 0, 2, 3 }; + +static const uint8_t atrac3p_wl_huff_bits1[3] = { 1, 2, 2 }; + +static const uint8_t atrac3p_wl_huff_xlat1[3] = { 0, 1, 7 }; + +static const uint8_t atrac3p_wl_huff_code2[5] = { 0, 4, 5, 6, 7 }; + +static const uint8_t atrac3p_wl_huff_bits2[5] = { 1, 3, 3, 3, 3 }; + +static const uint8_t atrac3p_wl_huff_xlat2[5] = { 0, 1, 2, 6, 7 }; + +static const uint8_t atrac3p_wl_huff_code3[8] = { + 0, 4, 0xC, 0x1E, 0x1F, 0xD, 0xE, 5 +}; + +static const uint8_t atrac3p_wl_huff_bits3[8] = { 1, 3, 4, 5, 5, 4, 4, 3 }; + +static const uint8_t atrac3p_wl_huff_code4[8] = { + 0, 4, 0xC, 0xD, 0x1E, 0x1F, 0xE, 5 +}; + +static const uint8_t atrac3p_wl_huff_bits4[8] = { 1, 3, 4, 4, 5, 5, 4, 3 }; + +/** VLC tables for scale factor indexes */ +static const uint16_t atrac3p_sf_huff_code1[64] = { + 0, 2, 3, 4, 5, 0xC, 0xD, 0xE0, + 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0x1CE, 0x1CF, + 0x1D0, 0x1D1, 0x1D2, 0x1D3, 0x1D4, 0x1D5, 0x1D6, 0x1D7, + 0x1D8, 0x1D9, 0x1DA, 0x1DB, 0x1DC, 0x1DD, 0x1DE, 0x1DF, + 0x1E0, 0x1E1, 0x1E2, 0x1E3, 0x1E4, 0x1E5, 0x1E6, 0x1E7, + 0x1E8, 0x1E9, 0x1EA, 0x1EB, 0x1EC, 0x1ED, 0x1EE, 0x1EF, + 0x1F0, 0x1F1, 0x1F2, 0x1F3, 0x1F4, 0x1F5, 0x1F6, 0x1F7, + 0x1F8, 0x1F9, 0x1FA, 0x1FB, 0x1FC, 0x1FD, 0x1FE, 0x1FF +}; + +static const uint8_t atrac3p_sf_huff_bits1[64] = { + 2, 3, 3, 3, 3, 4, 4, 8, 8, 8, 8, 8, 8, 8, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 +}; + +static const uint8_t atrac3p_sf_huff_xlat1[64] = { + 0, 1, 61, 62, 63, 2, 60, 3, 4, 5, 6, 57, 58, 59, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56 +}; + +static const uint8_t atrac3p_sf_huff_xlat2[64] = { + 0, 1, 2, 62, 63, 3, 61, 4, 5, 6, 57, 58, 59, 60, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56 +}; + +static const uint16_t atrac3p_sf_huff_code2[64] = { + 0, 4, 0x18, 0x19, 0x70, 0x1CA, 0x1CB, 0x1CC, + 0x1CD, 0x1CE, 0x1CF, 0x1D0, 0x1D1, 0x1D2, 0x1D3, 0x1D4, + 0x1D5, 0x1D6, 0x1D7, 0x1D8, 0x1D9, 0x1DA, 0x1DB, 0x1DC, + 0x1DD, 0x1DE, 0x1DF, 0x1E0, 0x1E1, 0x1E2, 0x1E3, 0x1E4, + 0x1E5, 0x1E6, 0x1E7, 0x1E8, 0x1E9, 0x1EA, 0x1EB, 0x1EC, + 0x1ED, 0x1EE, 0x1EF, 0x1F0, 0x1F1, 0x1F2, 0x1F3, 0x1F4, + 0x1F5, 0x1F6, 0x1F7, 0x1F8, 0x1F9, 0x1FA, 0x1FB, 0x1FC, + 0x1FD, 0x1FE, 0x1FF, 0xE4, 0x71, 0x1A, 0x1B, 5 +}; + +static const uint8_t atrac3p_sf_huff_bits2[64] = { + 1, 3, 5, 5, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 7, 5, 5, 3 +}; + +static const uint16_t atrac3p_sf_huff_code3[64] = { + 0, 2, 3, 0x18, 0x19, 0x70, 0x1CC, 0x1CD, + 0x1CE, 0x1CF, 0x1D0, 0x1D1, 0x1D2, 0x1D3, 0x1D4, 0x1D5, + 0x1D6, 0x1D7, 0x1D8, 0x1D9, 0x1DA, 0x1DB, 0x1DC, 0x1DD, + 0x1DE, 0x1DF, 0x1E0, 0x1E1, 0x1E2, 0x1E3, 0x1E4, 0x1E5, + 0x1E6, 0x1E7, 0x1E8, 0x1E9, 0x1EA, 0x1EB, 0x1EC, 0x1ED, + 0x1EE, 0x1EF, 0x1F0, 0x1F1, 0x1F2, 0x1F3, 0x1F4, 0x1F5, + 0x1F6, 0x1F7, 0x1F8, 0x1F9, 0x1FA, 0x1FB, 0x1FC, 0x1FD, + 0x1FE, 0x1FF, 0x71, 0x72, 0x1A, 0x1B, 4, 5 +}; + +static const uint8_t atrac3p_sf_huff_bits3[64] = { + 2, 3, 3, 5, 5, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 5, 5, 3, 3 +}; + +static const uint16_t atrac3p_sf_huff_code4[16] = { + 0, 2, 3, 4, 5, 0xC, 0xD, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0, 0x3D, 0x3E, 0x3F +}; + +static const uint8_t atrac3p_sf_huff_bits4[16] = { + 2, 3, 3, 3, 3, 4, 4, 6, 6, 6, 6, 6, 0, 6, 6, 6 +}; + +static const uint8_t atrac3p_sf_huff_xlat4[16] = { + 0, 1, 13, 14, 15, 2, 12, 3, 4, 5, 6, 7, 8, 9, 10, 11 +}; + +static const uint8_t atrac3p_sf_huff_xlat5[16] = { + 0, 1, 2, 14, 15, 3, 13, 4, 5, 6, 7, 9, 8, 10, 11, 12 +}; + +static const uint16_t atrac3p_sf_huff_code5[16] = { + 0, 4, 0xC, 0x1C, 0x78, 0x79, 0x7A, 0x7B, + 0, 0x7C, 0x7D, 0x7E, 0x7F, 0x1D, 0xD, 5 +}; + +static const uint8_t atrac3p_sf_huff_bits5[16] = { + 1, 3, 4, 5, 7, 7, 7, 7, 0, 7, 7, 7, 7, 5, 4, 3 +}; + +static const uint16_t atrac3p_sf_huff_code6[16] = { + 0, 2, 3, 0xC, 0x1C, 0x3C, 0x7C, 0x7D, 0, 0x7E, 0x7F, 0x3D, 0x1D, 0xD, 4, 5 +}; + +static const uint8_t atrac3p_sf_huff_bits6[16] = { + 2, 3, 3, 4, 5, 6, 7, 7, 0, 7, 7, 6, 5, 4, 3, 3 +}; + +/** VLC tables for code table indexes */ +static const uint8_t atrac3p_ct_huff_code1[4] = { 0, 2, 6, 7 }; + +static const uint8_t atrac3p_ct_huff_bits1[4] = { 1, 2, 3, 3 }; + +static const uint8_t atrac3p_ct_huff_code2[8] = { 0, 2, 3, 4, 5, 6, 0xE, 0xF }; + +static const uint8_t atrac3p_ct_huff_bits2[8] = { 2, 3, 3, 3, 3, 3, 4, 4 }; + +static const uint8_t atrac3p_ct_huff_xlat1[8] = { 0, 1, 2, 3, 6, 7, 4, 5 }; + +static const uint8_t atrac3p_ct_huff_code3[8] = { + 0, 4, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF +}; + +static const uint8_t atrac3p_ct_huff_bits3[8] = { 1, 3, 4, 4, 4, 4, 4, 4 }; + +/* weights for quantized word lengths */ +static const int8_t atrac3p_wl_weights[6][32] = { + { 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 5, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 6, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 2, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }, + { 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 5, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 6, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 2, 2, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } +}; + +/* weights for quantized scale factors + * sf_weights[i] = i / (tab_idx + 1) + * where tab_idx = [1,2] */ +static const int8_t atrac3p_sf_weights[2][32] = { + { 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, + 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15 }, + { 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, + 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10 } +}; + +/** Ungroup table for word length segments. + * Numbers in this table tell which coeff belongs to which segment. */ +static const uint8_t atrac3p_qu_num_to_seg[32] = { + 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, + 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9 +}; + +/** Map quant unit number to subband number */ +static const uint8_t atrac3p_qu_to_subband[32] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 +}; + +/** Map subband number to number of power compensation groups */ +static const int atrac3p_subband_to_num_powgrps[16] = { + 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5 +}; + +/** 3D base shape tables. The values are grouped together as follows: + * [num_start_values = 8][num_shape_tables = 16][num_seg_coeffs = 9] + * For each of the 8 start values there are 16 different shapes each + * 9 coefficients long. */ +static const int8_t atrac3p_wl_shapes[8][16][9] = { + { { 0, 0, 0, 0, 0, 0, 0, -2, -1 }, + { 0, 0, 0, 0, 0, 0, 0, -5, -1 }, + { 0, 0, 0, -7, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, -7, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, -5, 0, 0 }, + { 0, 0, 0, 0, -5, 0, 0, 0, 0 }, + { -7, -7, 0, 0, 0, 0, 0, 0, 0 }, + { 0, -7, 0, 0, 0, 0, 0, 0, 0 }, + { -2, -2, -5, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, -2, -5, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, -2, -5, 0, 0 }, + { 0, 0, 0, -5, 0, 0, 0, 0, 0 }, + { 0, -2, -7, -2, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, -2, -5, 0, 0, 0 }, + { 0, 0, 0, -5, -5, 0, 0, 0, 0 }, + { 0, 0, 0, -5, -2, 0, 0, 0, 0 } }, + { { -1, -5, -3, -2, -1, -1, 0, 0, 0 }, + { -2, -5, -3, -3, -2, -1, -1, 0, 0 }, + { 0, -1, -1, -1, 0, 0, 0, 0, 0 }, + { -1, -3, 0, 0, 0, 0, 0, 0, 0 }, + { -1, -2, 0, 0, 0, 0, 0, 0, 0 }, + { -1, -3, -1, 0, 0, 0, 0, 1, 1 }, + { -1, -5, -3, -3, -2, -1, 0, 0, 0 }, + { -1, -1, -4, -2, -2, -1, -1, 0, 0 }, + { -1, -1, -3, -2, -3, -1, -1, -1, 0 }, + { -1, -4, -2, -3, -1, 0, 0, 0, 0 }, + { 0, -1, -2, -2, -1, -1, 0, 0, 0 }, + { 0, -2, -1, 0, 0, 0, 0, 0, 0 }, + { -1, -1, 0, 0, 0, 0, 0, 0, 0 }, + { -1, -1, -3, -2, -2, -1, -1, -1, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, -1, -3, -2, -2, -1, -1, -1, 0 }, }, + { { -1, -2, 0, 1, 1, 1, 1, 1, 1 }, + { 0, -1, 1, 1, 1, 1, 1, 1, 1 }, + { 0, -2, 1, 1, 1, 1, 1, 1, 1 }, + { 0, -2, 0, 1, 1, 1, 1, 1, 1 }, + { -1, -1, 0, 1, 1, 1, 1, 1, 1 }, + { 0, 0, -1, 0, 1, 1, 1, 1, 1 }, + { -1, -1, 1, 1, 1, 1, 1, 1, 1 }, + { 0, 0, -1, 1, 1, 1, 1, 1, 1 }, + { 0, -1, 0, 1, 1, 1, 1, 1, 1 }, + { -1, -1, -1, 1, 1, 1, 1, 1, 1 }, + { 0, 0, 0, 0, 1, 1, 1, 1, 1 }, + { 0, 0, 0, 1, 1, 1, 1, 1, 1 }, + { 0, -1, -1, 1, 1, 1, 1, 1, 1 }, + { 0, 1, 0, 1, 1, 1, 1, 1, 1 }, + { 0, -3, -2, 1, 1, 1, 1, 2, 2 }, + { -3, -5, -3, 2, 2, 2, 2, 2, 2 }, }, + { { -1, -2, 0, 2, 2, 2, 2, 2, 2 }, + { -1, -2, 0, 1, 2, 2, 2, 2, 2 }, + { 0, -2, 0, 2, 2, 2, 2, 2, 2 }, + { -1, 0, 1, 2, 2, 2, 2, 2, 2 }, + { 0, 0, 1, 2, 2, 2, 2, 2, 2 }, + { 0, -2, 0, 1, 2, 2, 2, 2, 2 }, + { 0, -1, 1, 2, 2, 2, 2, 2, 2 }, + { -1, -1, 0, 2, 2, 2, 2, 2, 2 }, + { -1, -1, 0, 1, 2, 2, 2, 2, 2 }, + { -1, -2, -1, 2, 2, 2, 2, 2, 2 }, + { 0, -1, 0, 2, 2, 2, 2, 2, 2 }, + { 1, 1, 0, 1, 2, 2, 2, 2, 2 }, + { 0, 1, 2, 2, 2, 2, 2, 2, 2 }, + { 1, 0, 0, 1, 2, 2, 2, 2, 2 }, + { 0, 0, 0, 1, 2, 2, 2, 2, 2 }, + { -1, -1, -1, 1, 2, 2, 2, 2, 2 }, }, + { { 0, 1, 2, 3, 3, 3, 3, 3, 3 }, + { 1, 1, 2, 3, 3, 3, 3, 3, 3 }, + { -1, 0, 1, 2, 3, 3, 3, 3, 3 }, + { 0, 0, 2, 3, 3, 3, 3, 3, 3 }, + { -1, 0, 1, 3, 3, 3, 3, 3, 3 }, + { 0, 0, 1, 3, 3, 3, 3, 3, 3 }, + { 1, 2, 3, 3, 3, 3, 3, 3, 3 }, + { 1, 2, 2, 3, 3, 3, 3, 3, 3 }, + { 0, 1, 1, 3, 3, 3, 3, 3, 3 }, + { 0, 0, 1, 2, 3, 3, 3, 3, 3 }, + { -1, 1, 2, 3, 3, 3, 3, 3, 3 }, + { -1, 0, 2, 3, 3, 3, 3, 3, 3 }, + { 2, 2, 3, 3, 3, 3, 3, 3, 3 }, + { 1, 1, 3, 3, 3, 3, 3, 3, 3 }, + { 0, 2, 3, 3, 3, 3, 3, 3, 3 }, + { 0, 1, 1, 2, 3, 3, 3, 3, 3 }, }, + { { 0, 1, 2, 3, 4, 4, 4, 4, 4 }, + { 1, 2, 3, 4, 4, 4, 4, 4, 4 }, + { 0, 0, 2, 3, 4, 4, 4, 4, 4 }, + { 1, 1, 2, 4, 4, 4, 4, 4, 4 }, + { 0, 1, 2, 4, 4, 4, 4, 4, 4 }, + { -1, 0, 1, 3, 4, 4, 4, 4, 4 }, + { 0, 0, 1, 3, 4, 4, 4, 4, 4 }, + { 1, 1, 2, 3, 4, 4, 4, 4, 4 }, + { 0, 1, 1, 3, 4, 4, 4, 4, 4 }, + { 2, 2, 3, 4, 4, 4, 4, 4, 4 }, + { 1, 1, 3, 4, 4, 4, 4, 4, 4 }, + { 1, 2, 2, 4, 4, 4, 4, 4, 4 }, + { -1, 0, 2, 3, 4, 4, 4, 4, 4 }, + { 0, 1, 3, 4, 4, 4, 4, 4, 4 }, + { 1, 2, 2, 3, 4, 4, 4, 4, 4 }, + { 0, 2, 3, 4, 4, 4, 4, 4, 4 }, }, + { { 1, 2, 3, 4, 5, 5, 5, 5, 5 }, + { 0, 1, 2, 3, 4, 5, 5, 5, 5 }, + { 0, 1, 2, 3, 5, 5, 5, 5, 5 }, + { 1, 1, 3, 4, 5, 5, 5, 5, 5 }, + { 1, 1, 2, 4, 5, 5, 5, 5, 5 }, + { 1, 2, 2, 4, 5, 5, 5, 5, 5 }, + { 1, 1, 2, 3, 5, 5, 5, 5, 5 }, + { 2, 2, 3, 4, 5, 5, 5, 5, 5 }, + { 0, 1, 2, 4, 5, 5, 5, 5, 5 }, + { 2, 2, 3, 5, 5, 5, 5, 5, 5 }, + { 1, 2, 3, 5, 5, 5, 5, 5, 5 }, + { 0, 1, 3, 4, 5, 5, 5, 5, 5 }, + { 1, 2, 2, 3, 5, 5, 5, 5, 5 }, + { 2, 3, 4, 5, 5, 5, 5, 5, 5 }, + { 0, 2, 3, 4, 5, 5, 5, 5, 5 }, + { 1, 1, 1, 3, 4, 5, 5, 5, 5 }, }, + { { 1, 2, 3, 4, 5, 5, 5, 6, 6 }, + { 1, 2, 3, 4, 5, 6, 6, 6, 6 }, + { 2, 3, 4, 5, 6, 6, 6, 6, 6 }, + { 1, 2, 3, 4, 6, 6, 6, 6, 6 }, + { 2, 2, 3, 4, 5, 5, 5, 6, 6 }, + { 1, 2, 3, 4, 5, 5, 6, 6, 6 }, + { 2, 2, 3, 4, 6, 6, 6, 6, 6 }, + { 2, 2, 3, 4, 5, 6, 6, 6, 6 }, + { 2, 2, 4, 5, 6, 6, 6, 6, 6 }, + { 2, 2, 3, 5, 6, 6, 6, 6, 6 }, + { 1, 2, 3, 5, 6, 6, 6, 6, 6 }, + { 2, 3, 3, 5, 6, 6, 6, 6, 6 }, + { 1, 2, 4, 5, 6, 6, 6, 6, 6 }, + { 2, 2, 3, 4, 5, 5, 6, 6, 6 }, + { 2, 3, 3, 4, 6, 6, 6, 6, 6 }, + { 1, 3, 4, 5, 6, 6, 6, 6, 6 } } +}; + +/** 2D base shape tables for scale factor coding. + * The values are grouped together as follows: + * [num_shape_tables = 64][num_seg_coeffs = 9] */ +static const int8_t atrac3p_sf_shapes[64][9] = { + { -3, -2, -1, 0, 3, 5, 6, 8, 40 }, + { -3, -2, 0, 1, 7, 9, 11, 13, 20 }, + { -1, 0, 0, 1, 6, 8, 10, 13, 41 }, + { 0, 0, 0, 2, 5, 5, 6, 8, 14 }, + { 0, 0, 0, 2, 6, 7, 8, 11, 47 }, + { 0, 0, 1, 2, 5, 7, 8, 10, 32 }, + { 0, 0, 1, 3, 8, 10, 12, 14, 47 }, + { 0, 0, 2, 4, 9, 10, 12, 14, 40 }, + { 0, 0, 3, 5, 9, 10, 12, 14, 22 }, + { 0, 1, 3, 5, 10, 14, 18, 22, 31 }, + { 0, 2, 5, 6, 10, 10, 10, 12, 46 }, + { 0, 2, 5, 7, 12, 14, 15, 18, 44 }, + { 1, 1, 4, 5, 7, 7, 8, 9, 15 }, + { 1, 2, 2, 2, 4, 5, 7, 9, 26 }, + { 1, 2, 2, 3, 6, 7, 7, 8, 47 }, + { 1, 2, 2, 3, 6, 8, 10, 13, 22 }, + { 1, 3, 4, 7, 13, 17, 21, 24, 41 }, + { 1, 4, 0, 4, 10, 12, 13, 14, 17 }, + { 2, 3, 3, 3, 6, 8, 10, 13, 48 }, + { 2, 3, 3, 4, 9, 12, 14, 17, 47 }, + { 2, 3, 3, 5, 10, 12, 14, 17, 25 }, + { 2, 3, 5, 7, 8, 9, 9, 9, 13 }, + { 2, 3, 5, 9, 16, 21, 25, 28, 33 }, + { 2, 4, 5, 8, 12, 14, 17, 19, 26 }, + { 2, 4, 6, 8, 12, 13, 13, 15, 20 }, + { 2, 4, 7, 12, 20, 26, 30, 32, 35 }, + { 3, 3, 5, 6, 12, 14, 16, 19, 34 }, + { 3, 4, 4, 5, 7, 9, 10, 11, 48 }, + { 3, 4, 5, 6, 8, 9, 10, 11, 16 }, + { 3, 5, 5, 5, 7, 9, 10, 13, 35 }, + { 3, 5, 5, 7, 10, 12, 13, 15, 49 }, + { 3, 5, 7, 7, 8, 7, 9, 12, 21 }, + { 3, 5, 7, 8, 12, 14, 15, 15, 24 }, + { 3, 5, 7, 10, 16, 21, 24, 27, 44 }, + { 3, 5, 8, 14, 21, 26, 28, 29, 42 }, + { 3, 6, 10, 13, 18, 19, 20, 22, 27 }, + { 3, 6, 11, 16, 24, 27, 28, 29, 31 }, + { 4, 5, 4, 3, 4, 6, 8, 11, 18 }, + { 4, 6, 5, 6, 9, 10, 12, 14, 20 }, + { 4, 6, 7, 6, 6, 6, 7, 8, 46 }, + { 4, 6, 7, 9, 13, 16, 18, 20, 48 }, + { 4, 6, 7, 9, 14, 17, 20, 23, 31 }, + { 4, 6, 9, 11, 14, 15, 15, 17, 21 }, + { 4, 8, 13, 20, 27, 32, 35, 36, 38 }, + { 5, 6, 6, 4, 5, 6, 7, 6, 6 }, + { 5, 7, 7, 8, 9, 9, 10, 12, 49 }, + { 5, 8, 9, 9, 10, 11, 12, 13, 42 }, + { 5, 8, 10, 12, 15, 16, 17, 19, 42 }, + { 5, 8, 12, 17, 26, 31, 32, 33, 44 }, + { 5, 9, 13, 16, 20, 22, 23, 23, 35 }, + { 6, 8, 8, 7, 6, 5, 6, 8, 15 }, + { 6, 8, 8, 8, 9, 10, 12, 16, 24 }, + { 6, 8, 8, 9, 10, 10, 11, 11, 13 }, + { 6, 8, 10, 13, 19, 21, 24, 26, 32 }, + { 6, 9, 10, 11, 13, 13, 14, 16, 49 }, + { 7, 9, 9, 10, 13, 14, 16, 19, 27 }, + { 7, 10, 12, 13, 16, 16, 17, 17, 27 }, + { 7, 10, 12, 14, 17, 19, 20, 22, 48 }, + { 8, 9, 10, 9, 10, 11, 11, 11, 19 }, + { 8, 11, 12, 12, 13, 13, 13, 13, 17 }, + { 8, 11, 13, 14, 16, 17, 19, 20, 27 }, + { 8, 12, 17, 22, 26, 28, 29, 30, 33 }, + { 10, 14, 16, 19, 21, 22, 22, 24, 28 }, + { 10, 15, 17, 18, 21, 22, 23, 25, 43 } +}; + +static const uint8_t atrac3p_ct_restricted_to_full[2][7][4] = { + { { 0, 5, 4, 1 }, + { 0, 1, 2, 3 }, + { 3, 0, 4, 2 }, + { 4, 0, 1, 2 }, + { 1, 0, 4, 3 }, + { 3, 0, 2, 1 }, + { 0, 3, 1, 2 } }, + { { 4, 0, 1, 2 }, + { 0, 3, 2, 1 }, + { 0, 1, 2, 3 }, + { 0, 1, 2, 4 }, + { 0, 1, 2, 3 }, + { 1, 4, 2, 0 }, + { 0, 1, 2, 3 } } +}; + +/** Tables for spectrum coding */ +static const uint8_t huff_a01_cb[14] = { + 1, 12, 1, 0, 0, 1, 7, 0, 19, 5, 13, 21, 6, 8 +}; + +static const uint8_t huff_a01_xlat[81] = { + 0x00, 0x03, 0x40, 0xC0, 0x10, 0x30, 0x04, 0x0C, 0x01, 0x50, 0xD0, 0x70, + 0xF0, 0xC4, 0x14, 0x34, 0x4C, 0x1C, 0x3C, 0x41, 0xC1, 0x31, 0x05, 0x0D, + 0xC3, 0x13, 0x07, 0x0F, 0x44, 0xCC, 0x11, 0x43, 0x33, 0x54, 0x74, 0xDC, + 0xFC, 0x71, 0x15, 0x4D, 0xCD, 0x1D, 0xD3, 0xC7, 0x37, 0x3F, 0xD4, 0xF4, + 0x5C, 0x7C, 0x51, 0xD1, 0xF1, 0x45, 0xC5, 0x35, 0xDD, 0x3D, 0x53, 0x73, + 0xF3, 0x47, 0x17, 0x77, 0x4F, 0xCF, 0x1F, 0x55, 0xF5, 0x7D, 0xD7, 0x5F, + 0xFF, 0xD5, 0x75, 0x5D, 0xFD, 0x57, 0xF7, 0xDF, 0x7F +}; + +static const uint8_t huff_a02_cb[13] = { + 2, 12, 1, 0, 4, 11, 0, 1, 29, 6, 20, 7, 2 +}; + +static const uint8_t huff_a02_xlat[81] = { + 0x00, 0x40, 0x10, 0x04, 0x01, 0x50, 0x44, 0x14, 0x54, 0x41, 0x11, 0x51, + 0x05, 0x45, 0x15, 0x55, 0x90, 0x80, 0x20, 0x60, 0x84, 0x94, 0x24, 0x64, + 0x08, 0x48, 0x18, 0x58, 0x81, 0x91, 0x21, 0x85, 0x95, 0x65, 0x09, 0x49, + 0x19, 0x59, 0x02, 0x42, 0x12, 0x52, 0x06, 0x46, 0x16, 0x56, 0x88, 0x61, + 0x25, 0x29, 0x69, 0x5A, 0xA0, 0xA4, 0x98, 0x28, 0x68, 0xA1, 0xA5, 0x89, + 0x99, 0xA9, 0x82, 0x92, 0x22, 0x62, 0x96, 0x26, 0x66, 0x0A, 0x4A, 0x1A, + 0xA8, 0x86, 0xA6, 0x8A, 0x9A, 0x2A, 0x6A, 0xA2, 0xAA +}; + +static const uint8_t huff_a03_cb[9] = { 3, 9, 1, 8, 0, 13, 18, 7, 2 }; + +static const uint8_t huff_a03_xlat[49] = { + 0x00, 0x08, 0x38, 0x01, 0x09, 0x39, 0x07, 0x0F, 0x3F, 0x10, 0x30, 0x11, + 0x31, 0x02, 0x0A, 0x3A, 0x05, 0x06, 0x0E, 0x3E, 0x17, 0x37, 0x18, 0x28, + 0x19, 0x29, 0x2A, 0x32, 0x03, 0x0B, 0x33, 0x3B, 0x0D, 0x15, 0x3D, 0x16, + 0x1E, 0x36, 0x1F, 0x2F, 0x12, 0x1A, 0x13, 0x2B, 0x1D, 0x35, 0x2E, 0x1B, + 0x2D +}; + +static const uint8_t huff_a04_cb[4] = { 2, 3, 2, 4 }; +static const uint8_t huff_a04_xlat[6] = { 1, 2, 0, 3, 4, 5 }; + +static const uint8_t huff_a05_cb[12] = { + 3, 12, 1, 3, 5, 8, 12, 23, 72, 68, 31, 2 +}; + +static const uint8_t huff_a05_xlat[225] = { + 0x00, 0x10, 0xF0, 0x01, 0x11, 0xF1, 0x0F, 0x1F, 0xFF, 0x20, 0xE0, 0xE1, + 0x02, 0xF2, 0x0E, 0x1E, 0x2F, 0x30, 0xD0, 0x21, 0x12, 0x22, 0xE2, 0x03, + 0x0D, 0x2E, 0xEE, 0xFE, 0xEF, 0x40, 0xC0, 0x31, 0xC1, 0xD1, 0x32, 0xD2, + 0x13, 0x23, 0xE3, 0xF3, 0x04, 0xF4, 0x0C, 0x1C, 0x1D, 0x2D, 0xED, 0xFD, + 0x3E, 0xDE, 0x3F, 0xDF, 0x50, 0x60, 0x70, 0x90, 0xA0, 0xB0, 0x41, 0x51, + 0x61, 0x71, 0x91, 0xA1, 0xB1, 0x42, 0x62, 0x92, 0xA2, 0xC2, 0x33, 0xC3, + 0xD3, 0x14, 0x24, 0x34, 0xD4, 0xE4, 0x05, 0x15, 0xF5, 0x06, 0x16, 0x26, + 0xE6, 0xF6, 0x07, 0x17, 0xE7, 0xF7, 0x09, 0x19, 0x29, 0xF9, 0x0A, 0x1A, + 0x2A, 0xEA, 0xFA, 0x0B, 0x1B, 0xFB, 0x2C, 0x3C, 0xDC, 0xEC, 0xFC, 0x3D, + 0x4D, 0xCD, 0xDD, 0x4E, 0x6E, 0x7E, 0xAE, 0xCE, 0x4F, 0x5F, 0x6F, 0x7F, + 0x9F, 0xAF, 0xBF, 0xCF, 0x52, 0x72, 0xB2, 0x43, 0x53, 0x63, 0x73, 0x93, + 0xA3, 0xB3, 0x44, 0x64, 0x74, 0x94, 0xA4, 0xB4, 0xC4, 0x25, 0x35, 0xA5, + 0xC5, 0xD5, 0xE5, 0x36, 0x46, 0xB6, 0xC6, 0xD6, 0x27, 0x37, 0x47, 0xB7, + 0xC7, 0xD7, 0x39, 0x49, 0x59, 0xC9, 0xD9, 0xE9, 0x3A, 0x4A, 0x5A, 0xCA, + 0xDA, 0x2B, 0x3B, 0x4B, 0x6B, 0x7B, 0xDB, 0xEB, 0x4C, 0x5C, 0x6C, 0x7C, + 0x9C, 0xAC, 0xCC, 0x5D, 0x6D, 0x7D, 0x9D, 0xAD, 0xBD, 0x5E, 0x9E, 0xBE, + 0x54, 0x45, 0x55, 0x65, 0x75, 0x95, 0xB5, 0x56, 0x66, 0x76, 0x96, 0xA6, + 0x57, 0x67, 0x97, 0xA7, 0x69, 0x79, 0xA9, 0xB9, 0x6A, 0x7A, 0x9A, 0xAA, + 0xBA, 0x5B, 0x9B, 0xAB, 0xBB, 0xCB, 0xBC, 0x77, 0x99 +}; + +static const uint8_t huff_a06_cb[7] = { + 2, 6, 1, 3, 2, 6, 4 +}; + +static const uint8_t huff_a06_xlat[16] = { + 1, 0, 2, 3, 4, 5, 6, 7, 8, 9, 13, 14, 10, 11, 12, 15 +}; + +static const uint8_t huff_a07_cb[11] = { + 2, 10, 1, 2, 2, 2, 6, 14, 21, 13, 2 +}; + +static const uint8_t huff_a07_xlat[63] = { + 0, 1, 63, 2, 62, 3, 61, 4, 5, 6, 58, 59, 60, 7, 8, 9, + 10, 26, 27, 28, 36, 37, 38, 54, 55, 56, 57, 11, 12, 13, 14, 15, + 16, 25, 29, 30, 31, 33, 34, 35, 39, 47, 48, 49, 50, 51, 52, 53, + 17, 18, 19, 20, 21, 22, 23, 41, 42, 43, 44, 45, 46, 24, 40 +}; + +static const uint8_t huff_a11_cb[13] = { + 1, 11, 1, 0, 0, 0, 8, 1, 18, 9, 22, 10, 12 +}; + +static const uint8_t huff_a11_xlat[81] = { + 0x00, 0x40, 0xC0, 0x10, 0x30, 0x04, 0x0C, 0x01, 0x03, 0xD0, 0x50, 0x70, + 0xF0, 0xC4, 0x34, 0x4C, 0xCC, 0x1C, 0x41, 0xC1, 0x31, 0x05, 0x0D, 0x43, + 0xC3, 0x13, 0x07, 0x0F, 0x44, 0x14, 0x74, 0xDC, 0x3C, 0x11, 0x1D, 0x33, + 0x37, 0x54, 0xD4, 0xF4, 0x5C, 0x7C, 0xFC, 0xD1, 0x71, 0xF1, 0x15, 0x35, + 0x4D, 0xCD, 0xDD, 0x3D, 0xD3, 0x73, 0x47, 0xC7, 0x17, 0x77, 0x3F, 0x51, + 0x45, 0xC5, 0x55, 0x53, 0xF3, 0x4F, 0xCF, 0x1F, 0xFF, 0xD5, 0x75, 0xF5, + 0x5D, 0x7D, 0xFD, 0x57, 0xD7, 0xF7, 0x5F, 0xDF, 0x7F +}; + +static const uint8_t huff_a12_cb[8] = { 5, 10, 16, 11, 32, 19, 1, 2 }; + +static const uint8_t huff_a12_xlat[81] = { + 0x00, 0x40, 0x10, 0x50, 0x04, 0x44, 0x14, 0x54, 0x01, 0x41, 0x11, 0x51, + 0x05, 0x45, 0x15, 0x55, 0x90, 0x94, 0x58, 0x91, 0x95, 0x19, 0x59, 0x06, + 0x46, 0x16, 0x56, 0x80, 0x60, 0x84, 0x24, 0x64, 0xA4, 0x08, 0x48, 0x18, + 0x68, 0x81, 0x21, 0x61, 0xA1, 0x85, 0x25, 0x65, 0xA5, 0x09, 0x49, 0x99, + 0x69, 0xA9, 0x02, 0x42, 0x12, 0x52, 0x96, 0x26, 0x66, 0x1A, 0x5A, 0x20, + 0xA0, 0x88, 0x98, 0x28, 0xA8, 0x89, 0x29, 0x82, 0x92, 0x22, 0x62, 0x86, + 0xA6, 0x0A, 0x4A, 0x9A, 0x6A, 0xAA, 0xA2, 0x8A, 0x2A +}; + +static const uint8_t huff_a13_cb[12] = { + 1, 10, 1, 0, 0, 4, 2, 2, 9, 15, 12, 4 +}; + +static const uint8_t huff_a13_xlat[49] = { + 0x00, 0x08, 0x38, 0x01, 0x07, 0x39, 0x0F, 0x09, 0x3F, 0x10, 0x30, 0x31, + 0x02, 0x3A, 0x06, 0x0E, 0x3E, 0x17, 0x18, 0x28, 0x11, 0x29, 0x0A, 0x32, + 0x03, 0x0B, 0x3B, 0x05, 0x0D, 0x3D, 0x16, 0x1F, 0x37, 0x19, 0x12, 0x1A, + 0x2A, 0x13, 0x33, 0x15, 0x35, 0x1E, 0x2E, 0x36, 0x2F, 0x1B, 0x2B, 0x1D, + 0x2D +}; + +static const uint8_t huff_a14_cb[12] = { + 2, 11, 1, 0, 4, 3, 5, 16, 28, 34, 26, 4 +}; + +static const uint8_t huff_a14_xlat[121] = { + 0x00, 0x10, 0xF0, 0x01, 0x0F, 0xF1, 0x1F, 0xFF, 0x20, 0xE0, 0x11, 0x02, + 0x0E, 0x30, 0x50, 0xB0, 0xD0, 0x21, 0xE1, 0x12, 0xF2, 0x03, 0x05, 0x0B, + 0x0D, 0x1E, 0xFE, 0x2F, 0xEF, 0x40, 0xC0, 0x31, 0x51, 0xB1, 0xC1, 0xD1, + 0x22, 0x52, 0xE2, 0x13, 0xF3, 0x04, 0x15, 0xF5, 0x1B, 0xEB, 0xFB, 0x0C, + 0x1D, 0xFD, 0x2E, 0x5E, 0xEE, 0x3F, 0x5F, 0xBF, 0xDF, 0x41, 0x32, 0x42, + 0xB2, 0xD2, 0x23, 0x53, 0xB3, 0xE3, 0x14, 0x24, 0xE4, 0xF4, 0x25, 0x35, + 0xD5, 0xE5, 0x2B, 0x3B, 0xDB, 0x1C, 0x2C, 0xBC, 0xEC, 0xFC, 0x2D, 0xBD, + 0xED, 0x3E, 0x4E, 0xBE, 0xDE, 0x4F, 0xCF, 0xC2, 0x33, 0x43, 0xC3, 0xD3, + 0x34, 0x44, 0x54, 0xB4, 0xD4, 0x45, 0x55, 0xC5, 0x4B, 0xCB, 0x3C, 0x4C, + 0x5C, 0xCC, 0xDC, 0x3D, 0x4D, 0x5D, 0xCD, 0xDD, 0xCE, 0xC4, 0xB5, 0x5B, + 0xBB +}; + +static const uint8_t huff_a15_cb[9] = { 5, 11, 9, 12, 16, 44, 98, 42, 4 }; + +static const uint8_t huff_a15_xlat[225] = { + 0x00, 0x10, 0xF0, 0x01, 0x11, 0xF1, 0x0F, 0x1F, 0xFF, 0x20, 0xE0, 0x21, + 0xE1, 0x02, 0x12, 0xF2, 0x0E, 0x1E, 0xFE, 0x2F, 0xEF, 0x30, 0xD0, 0x31, + 0xD1, 0x22, 0xE2, 0x03, 0x13, 0xF3, 0x0D, 0x1D, 0xFD, 0x2E, 0xEE, 0x3F, + 0xDF, 0x40, 0x60, 0x70, 0x90, 0xA0, 0xC0, 0x41, 0xC1, 0x32, 0x42, 0xC2, + 0xD2, 0x23, 0x33, 0xD3, 0xE3, 0x04, 0x14, 0x24, 0xE4, 0xF4, 0x06, 0x16, + 0xF6, 0x07, 0x09, 0x0A, 0x1A, 0xFA, 0x0C, 0x1C, 0x2C, 0xEC, 0xFC, 0x2D, + 0x3D, 0xDD, 0xED, 0x3E, 0x4E, 0xCE, 0xDE, 0x4F, 0xCF, 0x50, 0xB0, 0x51, + 0x61, 0x71, 0x91, 0xA1, 0xB1, 0x52, 0x62, 0x72, 0x92, 0xA2, 0xB2, 0x43, + 0x53, 0x63, 0x73, 0x93, 0xA3, 0xC3, 0x34, 0x44, 0x64, 0xA4, 0xC4, 0xD4, + 0x05, 0x15, 0x25, 0x35, 0xD5, 0xE5, 0xF5, 0x26, 0x36, 0x46, 0xC6, 0xD6, + 0xE6, 0x17, 0x27, 0x37, 0xC7, 0xD7, 0xE7, 0xF7, 0x19, 0x29, 0x39, 0xC9, + 0xD9, 0xE9, 0xF9, 0x2A, 0x3A, 0x4A, 0x5A, 0xCA, 0xDA, 0xEA, 0x0B, 0x1B, + 0x2B, 0x3B, 0xCB, 0xDB, 0xEB, 0xFB, 0x3C, 0x4C, 0x6C, 0x7C, 0x9C, 0xAC, + 0xBC, 0xCC, 0xDC, 0x4D, 0x5D, 0x6D, 0x7D, 0x9D, 0xAD, 0xBD, 0xCD, 0x5E, + 0x6E, 0x7E, 0x9E, 0xAE, 0xBE, 0x5F, 0x6F, 0x7F, 0x9F, 0xAF, 0xBF, 0xB3, + 0x54, 0x74, 0x94, 0xB4, 0x45, 0x55, 0x65, 0x75, 0x95, 0xA5, 0xB5, 0xC5, + 0x56, 0x66, 0x76, 0x96, 0xA6, 0xB6, 0x47, 0x57, 0x67, 0xA7, 0xB7, 0x49, + 0x59, 0x69, 0xA9, 0xB9, 0x6A, 0x7A, 0x9A, 0xAA, 0xBA, 0x4B, 0x5B, 0x6B, + 0x7B, 0x9B, 0xAB, 0xBB, 0x5C, 0x77, 0x97, 0x79, 0x99 +}; + +static const uint8_t huff_a16_cb[13] = { + 2, 12, 1, 1, 2, 2, 5, 7, 21, 54, 85, 62, 16 +}; + +static const uint8_t huff_a16_xlat[256] = { + 0x00, 0x01, 0x10, 0x11, 0x21, 0x12, 0x20, 0x31, 0x02, 0x22, 0x13, 0x30, + 0x41, 0x32, 0x03, 0x23, 0x14, 0x24, 0x40, 0x51, 0x61, 0xD1, 0xE1, 0x42, + 0x52, 0xD2, 0x33, 0x43, 0xD3, 0x04, 0x34, 0x05, 0x15, 0x25, 0x16, 0x1D, + 0x2D, 0x1E, 0x2E, 0x50, 0x60, 0xD0, 0xE0, 0xF0, 0x71, 0x81, 0xF1, 0x62, + 0x72, 0xE2, 0xF2, 0x53, 0x63, 0xE3, 0xF3, 0x44, 0x54, 0xD4, 0xE4, 0xF4, + 0x35, 0x45, 0x55, 0xD5, 0xE5, 0xF5, 0x06, 0x26, 0x36, 0xD6, 0x07, 0x17, + 0x27, 0x37, 0xD7, 0x18, 0x28, 0x1C, 0x0D, 0x3D, 0x4D, 0x5D, 0x6D, 0x8D, + 0x0E, 0x3E, 0x4E, 0x5E, 0x0F, 0x1F, 0x2F, 0x3F, 0x5F, 0x70, 0x80, 0x90, + 0xC0, 0x91, 0xA1, 0xB1, 0xC1, 0x82, 0x92, 0xA2, 0xC2, 0x73, 0x83, 0x93, + 0xA3, 0xC3, 0x64, 0x74, 0x84, 0x94, 0xA4, 0xC4, 0x65, 0x75, 0x85, 0x46, + 0x56, 0x66, 0xC6, 0xE6, 0xF6, 0x47, 0x57, 0xE7, 0xF7, 0x08, 0x38, 0x48, + 0x58, 0x68, 0xD8, 0xE8, 0xF8, 0x09, 0x19, 0x29, 0x39, 0x59, 0xD9, 0xE9, + 0xF9, 0x1A, 0x2A, 0x3A, 0xDA, 0xEA, 0xFA, 0x1B, 0x2B, 0xDB, 0xEB, 0xFB, + 0x0C, 0x2C, 0x3C, 0xDC, 0xEC, 0x7D, 0x9D, 0xAD, 0xBD, 0xCD, 0x6E, 0x7E, + 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0x4F, 0x6F, 0x7F, 0x8F, 0xAF, 0xA0, 0xB2, + 0xB3, 0xB4, 0x95, 0xA5, 0xB5, 0xC5, 0x76, 0x86, 0x96, 0xA6, 0xB6, 0x67, + 0x77, 0x87, 0x97, 0xC7, 0x78, 0x88, 0x98, 0xC8, 0x49, 0x69, 0x79, 0x89, + 0x99, 0xC9, 0x0A, 0x4A, 0x5A, 0x6A, 0x7A, 0xCA, 0x0B, 0x3B, 0x4B, 0x5B, + 0x6B, 0xCB, 0x4C, 0x5C, 0x6C, 0x7C, 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xFC, + 0xDD, 0xED, 0xFD, 0xDE, 0xEE, 0xFE, 0x9F, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF, + 0xB0, 0xA7, 0xB7, 0xA8, 0xB8, 0xA9, 0xB9, 0x8A, 0x9A, 0xAA, 0xBA, 0x7B, + 0x8B, 0x9B, 0xAB, 0xBB +}; + +static const uint8_t huff_a17_cb[9] = { 3, 9, 3, 2, 5, 7, 17, 23, 6 }; + +static const uint8_t huff_a17_xlat[63] = { + 0, 1, 63, 2, 62, 3, 4, 59, 60, 61, 5, 6, 7, 8, 56, 57, + 58, 9, 10, 11, 12, 13, 14, 26, 27, 36, 37, 38, 50, 51, 52, 53, + 54, 55, 15, 16, 17, 18, 19, 20, 21, 25, 28, 29, 30, 31, 33, 34, + 35, 39, 43, 44, 45, 46, 47, 48, 49, 22, 23, 24, 40, 41, 42 +}; + +static const uint8_t huff_a21_cb[14] = { + 1, 12, 1, 0, 0, 2, 6, 0, 7, 21, 15, 17, 8, 4 +}; + +static const uint8_t huff_a21_xlat[81] = { + 0x00, 0x40, 0xC0, 0x10, 0x30, 0x04, 0x0C, 0x01, 0x03, 0xD0, 0x70, 0x34, + 0x1C, 0x0D, 0x13, 0x07, 0x50, 0xF0, 0x44, 0xC4, 0x14, 0x74, 0x4C, 0xCC, + 0xDC, 0x3C, 0x41, 0xC1, 0x11, 0x31, 0x05, 0x1D, 0x43, 0xC3, 0x33, 0x37, + 0x0F, 0x54, 0xF4, 0xFC, 0xD1, 0x71, 0x15, 0x4D, 0xCD, 0xDD, 0xD3, 0x73, + 0x47, 0xC7, 0x77, 0x3F, 0xD4, 0x5C, 0x7C, 0x51, 0xF1, 0x45, 0xC5, 0x55, + 0x35, 0x3D, 0x53, 0xF3, 0x17, 0x4F, 0xCF, 0x1F, 0xFF, 0x75, 0xF5, 0x5D, + 0x7D, 0xD7, 0xF7, 0x5F, 0xDF, 0xD5, 0xFD, 0x57, 0x7F +}; + +static const uint8_t huff_a22_cb[10] = { 2, 9, 1, 4, 0, 4, 3, 8, 3, 2 }; + +static const uint8_t huff_a22_xlat[25] = { + 0x00, 0x08, 0x38, 0x01, 0x07, 0x09, 0x39, 0x0F, 0x3F, 0x10, 0x02, 0x06, + 0x30, 0x11, 0x31, 0x0A, 0x3A, 0x0E, 0x17, 0x37, 0x32, 0x16, 0x3E, 0x12, + 0x36 +}; + +static const uint8_t huff_a23_cb[9] = { 3, 9, 5, 0, 4, 6, 10, 16, 8 }; + +static const uint8_t huff_a23_xlat[49] = { + 0x00, 0x08, 0x38, 0x01, 0x07, 0x09, 0x39, 0x0F, 0x3F, 0x10, 0x30, 0x02, + 0x3A, 0x06, 0x0E, 0x18, 0x28, 0x11, 0x31, 0x0A, 0x03, 0x05, 0x3E, 0x17, + 0x37, 0x19, 0x29, 0x12, 0x2A, 0x32, 0x0B, 0x33, 0x3B, 0x0D, 0x15, 0x3D, + 0x16, 0x1E, 0x36, 0x1F, 0x2F, 0x1A, 0x13, 0x1B, 0x2B, 0x1D, 0x2D, 0x35, + 0x2E +}; + +static const uint8_t huff_a24_cb[5] = { 2, 4, 3, 1, 2 }; + +static const uint8_t huff_a25_cb[5] = { 2, 4, 1, 5, 2 }; + +static const uint8_t huff_a25_xlat[8] = { 1, 0, 2, 3, 4, 5, 6, 7 }; + +static const uint8_t huff_a26_cb[10] = { 4, 11, 3, 4, 12, 15, 34, 83, 75, 30 }; + +static const uint8_t huff_a26_xlat[256] = { + 0x00, 0x01, 0x11, 0x10, 0x21, 0x12, 0x22, 0x20, 0x30, 0x31, 0x41, 0x02, + 0x32, 0x03, 0x13, 0x23, 0x33, 0x14, 0x24, 0x40, 0x51, 0x61, 0x42, 0x52, + 0x43, 0x53, 0x04, 0x34, 0x44, 0x15, 0x25, 0x35, 0x16, 0x26, 0x50, 0x60, + 0x71, 0x81, 0xD1, 0x62, 0x72, 0x82, 0xD2, 0x63, 0x73, 0xD3, 0x54, 0x64, + 0x05, 0x45, 0x55, 0x65, 0x06, 0x36, 0x46, 0x56, 0x17, 0x27, 0x37, 0x47, + 0x18, 0x28, 0x38, 0x19, 0x1D, 0x2D, 0x3D, 0x1E, 0x70, 0x80, 0x90, 0xD0, + 0xE0, 0x91, 0xA1, 0xB1, 0xC1, 0xE1, 0xF1, 0x92, 0xA2, 0xC2, 0xE2, 0xF2, + 0x83, 0x93, 0xA3, 0xC3, 0xE3, 0xF3, 0x74, 0x84, 0x94, 0xA4, 0xC4, 0xD4, + 0xE4, 0xF4, 0x75, 0x85, 0x95, 0xD5, 0xE5, 0x66, 0x76, 0x86, 0xD6, 0xE6, + 0x07, 0x57, 0x67, 0x77, 0xD7, 0x08, 0x48, 0x58, 0x68, 0xD8, 0x09, 0x29, + 0x39, 0x49, 0x59, 0x69, 0x1A, 0x2A, 0x3A, 0x4A, 0x1B, 0x2B, 0x1C, 0x2C, + 0x3C, 0x4C, 0x0D, 0x4D, 0x5D, 0x6D, 0x7D, 0x8D, 0x0E, 0x2E, 0x3E, 0x4E, + 0x5E, 0x6E, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0xA0, 0xB0, 0xC0, 0xF0, 0xB2, + 0xB3, 0xB4, 0xA5, 0xB5, 0xC5, 0xF5, 0x96, 0xA6, 0xB6, 0xC6, 0xF6, 0x87, + 0x97, 0xA7, 0xB7, 0xC7, 0xE7, 0xF7, 0x78, 0x88, 0x98, 0xA8, 0xC8, 0xE8, + 0xF8, 0x79, 0x89, 0x99, 0xC9, 0xD9, 0xE9, 0xF9, 0x0A, 0x5A, 0x6A, 0x7A, + 0x8A, 0xDA, 0xEA, 0xFA, 0x0B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B, 0x8B, 0xDB, + 0x0C, 0x5C, 0x6C, 0x7C, 0x8C, 0x9C, 0xDC, 0x9D, 0xAD, 0xBD, 0xCD, 0x7E, + 0x8E, 0x9E, 0xAE, 0xBE, 0x0F, 0x6F, 0x7F, 0x8F, 0x9F, 0xAF, 0xB8, 0xA9, + 0xB9, 0x9A, 0xAA, 0xBA, 0xCA, 0x9B, 0xAB, 0xBB, 0xCB, 0xEB, 0xFB, 0xAC, + 0xBC, 0xCC, 0xEC, 0xFC, 0xDD, 0xED, 0xFD, 0xCE, 0xDE, 0xEE, 0xFE, 0xBF, + 0xCF, 0xDF, 0xEF, 0xFF +}; + +static const uint8_t huff_a27_cb[7] = { 4, 8, 3, 14, 10, 20, 16 }; + +static const uint8_t huff_a27_xlat[63] = { + 0, 2, 3, 1, 5, 6, 7, 9, 54, 55, 56, 58, 59, 60, 61, 62, + 63, 4, 8, 10, 11, 12, 14, 49, 52, 53, 57, 13, 15, 16, 17, 18, + 19, 22, 23, 25, 26, 30, 39, 43, 44, 45, 46, 47, 48, 50, 51, 20, + 21, 24, 27, 28, 29, 31, 33, 34, 35, 36, 37, 38, 40, 41, 42 +}; + +static const uint8_t huff_a31_cb[8] = { 1, 6, 1, 0, 3, 1, 0, 4 }; + +static const uint8_t huff_a31_xlat[9] = { + 0x00, 0x04, 0x0C, 0x01, 0x03, 0x05, 0x0D, 0x07, 0x0F +}; + +static const uint8_t huff_a32_cb[13] = { + 1, 11, 1, 0, 0, 2, 2, 6, 12, 18, 19, 15, 6 +}; + +static const uint8_t huff_a32_xlat[81] = { + 0x00, 0x40, 0x01, 0x10, 0x04, 0x80, 0x50, 0x20, 0x14, 0x05, 0x02, 0x90, + 0x60, 0x44, 0x54, 0x24, 0x08, 0x18, 0x41, 0x11, 0x15, 0x09, 0x06, 0xA0, + 0x84, 0x94, 0x64, 0xA4, 0x48, 0x58, 0x28, 0x51, 0x21, 0x45, 0x55, 0x25, + 0x19, 0x12, 0x16, 0x0A, 0x1A, 0x68, 0xA8, 0x81, 0x91, 0x61, 0xA1, 0x85, + 0x95, 0x65, 0xA5, 0x49, 0x59, 0x29, 0x69, 0x42, 0x52, 0x46, 0x56, 0x2A, + 0x88, 0x98, 0x89, 0x99, 0xA9, 0x82, 0x92, 0x22, 0x62, 0x86, 0x26, 0x66, + 0x4A, 0x5A, 0x6A, 0xA2, 0x96, 0xA6, 0x8A, 0x9A, 0xAA +}; + +static const uint8_t huff_a33_cb[12] = { + 3, 12, 1, 1, 13, 1, 14, 28, 33, 81, 32, 52 +}; + +static const uint8_t huff_a33_xlat[256] = { + 0x00, 0x10, 0x40, 0x50, 0x04, 0x44, 0x14, 0x54, 0x01, 0x41, 0x11, 0x51, + 0x05, 0x45, 0x15, 0x55, 0x90, 0x20, 0x94, 0x64, 0x18, 0x21, 0x95, 0x19, + 0x69, 0x02, 0x52, 0x06, 0x46, 0x16, 0x80, 0x60, 0x84, 0xD4, 0x24, 0x08, + 0x48, 0x58, 0x68, 0x81, 0x91, 0x61, 0x85, 0x25, 0x65, 0xA5, 0x09, 0x49, + 0x59, 0x29, 0x42, 0x12, 0x56, 0x96, 0xA6, 0x0A, 0x17, 0x1B, 0xD0, 0xC4, + 0x74, 0xF4, 0x88, 0xC8, 0x28, 0xA1, 0x71, 0xC5, 0xD5, 0x75, 0x99, 0xB9, + 0x4D, 0x1D, 0x2D, 0x6D, 0x22, 0x62, 0x66, 0x4A, 0x1A, 0x9A, 0x6A, 0x8E, + 0x5E, 0x43, 0x23, 0x07, 0x47, 0x57, 0x6B, 0xC0, 0xA0, 0xE0, 0x70, 0xB0, + 0xA4, 0xE4, 0x34, 0xB4, 0x98, 0xD8, 0xA8, 0x38, 0x78, 0x0C, 0x4C, 0x1C, + 0x5C, 0x9C, 0x6C, 0x7C, 0xC1, 0xD1, 0xE1, 0x31, 0xE5, 0x35, 0xB5, 0xF5, + 0x89, 0xA9, 0x79, 0xF9, 0x0D, 0xCD, 0x9D, 0xDD, 0xAD, 0x3D, 0x7D, 0x82, + 0xC2, 0x92, 0xD2, 0xE2, 0x72, 0xF2, 0x86, 0xD6, 0xE6, 0x76, 0xB6, 0x8A, + 0x5A, 0xDA, 0xEA, 0xFA, 0x4E, 0x1E, 0x9E, 0xEE, 0x03, 0x13, 0x53, 0x97, + 0xB7, 0x0B, 0x4B, 0x8B, 0x5B, 0x9B, 0xEB, 0x7B, 0x0F, 0x4F, 0x1F, 0x5F, + 0x9F, 0x2F, 0x3F, 0xBF, 0xE8, 0xB8, 0xF8, 0x8C, 0x2C, 0x3C, 0xFC, 0xB1, + 0xC9, 0xD9, 0xE9, 0x39, 0x5D, 0xED, 0xBD, 0xA2, 0x32, 0x26, 0x36, 0x2A, + 0xAA, 0xBA, 0x0E, 0x2E, 0x6E, 0x83, 0xC3, 0x93, 0x63, 0xB3, 0xA7, 0x37, + 0x30, 0xF0, 0xCC, 0xDC, 0xAC, 0xEC, 0xBC, 0xF1, 0x8D, 0xFD, 0xB2, 0xC6, + 0xF6, 0xCA, 0x3A, 0x7A, 0xCE, 0xDE, 0xAE, 0x3E, 0x7E, 0xBE, 0xFE, 0xD3, + 0xA3, 0xE3, 0x33, 0x73, 0xF3, 0x87, 0xC7, 0xD7, 0x27, 0x67, 0xE7, 0x77, + 0xF7, 0xCB, 0xDB, 0x2B, 0xAB, 0x3B, 0xBB, 0xFB, 0x8F, 0xCF, 0xDF, 0x6F, + 0xAF, 0xEF, 0x7F, 0xFF +}; + +static const uint8_t huff_a34_cb[7] = { 1, 5, 1, 1, 1, 1, 2 }; + +static const uint8_t huff_a34_xlat[6] = { 1, 0, 2, 3, 4, 5 }; + +static const uint8_t huff_a35_cb[11] = { 2, 10, 1, 0, 2, 3, 6, 19, 9, 75, 110 }; + +static const uint8_t huff_a35_xlat[225] = { + 0x00, 0xF0, 0x0F, 0x10, 0x01, 0xFF, 0x20, 0xE0, 0x11, 0xF1, 0x0E, 0x1F, + 0x30, 0x40, 0xD0, 0x21, 0xE1, 0x02, 0x12, 0x22, 0xE2, 0xF2, 0x03, 0x13, + 0x1E, 0x2E, 0x3E, 0xEE, 0xFE, 0x2F, 0xEF, 0xD2, 0x43, 0xF3, 0x04, 0x0D, + 0x2D, 0x3D, 0x3F, 0xDF, 0x50, 0x60, 0x70, 0x90, 0xB0, 0x31, 0x41, 0x91, + 0xA1, 0xC1, 0xD1, 0x42, 0xA2, 0xC2, 0x23, 0x33, 0xE3, 0x24, 0x34, 0xB4, + 0xD4, 0xF4, 0x05, 0x15, 0x45, 0xE5, 0x16, 0x36, 0x56, 0xA6, 0xC6, 0xD6, + 0xF6, 0x57, 0xC7, 0xF7, 0x09, 0x29, 0x49, 0x59, 0x69, 0xF9, 0x0A, 0x2A, + 0x3A, 0x4A, 0xDA, 0xEA, 0xFA, 0x0B, 0x2B, 0xAB, 0xEB, 0xFB, 0x0C, 0x1C, + 0x2C, 0x3C, 0x4C, 0x5C, 0xCC, 0xDC, 0xFC, 0x1D, 0x4D, 0x6D, 0xBD, 0xCD, + 0xED, 0xFD, 0x4E, 0x6E, 0xCE, 0xDE, 0x7F, 0xA0, 0xC0, 0x51, 0x61, 0x71, + 0xB1, 0x32, 0x52, 0x62, 0x72, 0x92, 0xB2, 0x53, 0x63, 0x73, 0x93, 0xA3, + 0xB3, 0xC3, 0xD3, 0x14, 0x44, 0x54, 0x64, 0x74, 0x94, 0xA4, 0xC4, 0xE4, + 0x25, 0x35, 0x55, 0x65, 0x75, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xF5, 0x06, + 0x26, 0x46, 0x66, 0x76, 0x96, 0xB6, 0xE6, 0x07, 0x17, 0x27, 0x37, 0x47, + 0x67, 0x77, 0x97, 0xA7, 0xB7, 0xD7, 0xE7, 0x19, 0x39, 0x79, 0x99, 0xA9, + 0xB9, 0xC9, 0xD9, 0xE9, 0x1A, 0x5A, 0x6A, 0x7A, 0x9A, 0xAA, 0xBA, 0xCA, + 0x1B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B, 0x9B, 0xBB, 0xCB, 0xDB, 0x6C, 0x7C, + 0x9C, 0xAC, 0xBC, 0xEC, 0x5D, 0x7D, 0x9D, 0xAD, 0xDD, 0x5E, 0x7E, 0x9E, + 0xAE, 0xBE, 0x4F, 0x5F, 0x6F, 0x9F, 0xAF, 0xBF, 0xCF +}; + +static const uint8_t huff_a36_cb[12] = { + 3, 12, 1, 3, 5, 5, 13, 27, 69, 96, 35, 2 +}; + +static const uint8_t huff_a36_xlat[256] = { + 0x00, 0x10, 0x01, 0x11, 0x20, 0x21, 0x02, 0x12, 0x22, 0x31, 0x41, 0x32, + 0x13, 0x23, 0x30, 0x40, 0x51, 0x42, 0x03, 0x33, 0x43, 0x04, 0x14, 0x24, + 0x34, 0x15, 0x25, 0x50, 0x61, 0x71, 0xD1, 0x52, 0x62, 0x72, 0xD2, 0x53, + 0x63, 0xD3, 0x44, 0x54, 0x64, 0x05, 0x35, 0x45, 0x55, 0x16, 0x26, 0x36, + 0x46, 0x17, 0x27, 0x1D, 0x2D, 0x3D, 0x60, 0x70, 0xD0, 0x81, 0x91, 0xA1, + 0xC1, 0xE1, 0xF1, 0x82, 0x92, 0xC2, 0xE2, 0xF2, 0x73, 0x83, 0xE3, 0xF3, + 0x74, 0x84, 0xC4, 0xD4, 0xE4, 0xF4, 0x65, 0x75, 0x85, 0xD5, 0xE5, 0x06, + 0x56, 0x66, 0xD6, 0xE6, 0x07, 0x37, 0x47, 0x57, 0x67, 0xD7, 0xE7, 0x18, + 0x28, 0x38, 0x48, 0x58, 0xD8, 0x19, 0x29, 0x2A, 0x1C, 0x2C, 0x0D, 0x4D, + 0x5D, 0x6D, 0x7D, 0x8D, 0x9D, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E, + 0x1F, 0x2F, 0x3F, 0x80, 0x90, 0xA0, 0xC0, 0xE0, 0xF0, 0xB1, 0xA2, 0xB2, + 0x93, 0xA3, 0xB3, 0xC3, 0x94, 0xA4, 0xB4, 0x95, 0xA5, 0xB5, 0xC5, 0xF5, + 0x76, 0x86, 0x96, 0xA6, 0xC6, 0xF6, 0x77, 0x87, 0x97, 0xA7, 0xC7, 0xF7, + 0x08, 0x68, 0x78, 0x88, 0x98, 0xC8, 0xE8, 0xF8, 0x09, 0x39, 0x49, 0x59, + 0x69, 0x79, 0x89, 0xD9, 0xE9, 0xF9, 0x0A, 0x1A, 0x3A, 0x4A, 0x5A, 0x6A, + 0xDA, 0xEA, 0xFA, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0xDB, 0xEB, 0xFB, 0x0C, + 0x3C, 0x4C, 0x5C, 0x6C, 0x7C, 0x8C, 0x9C, 0xDC, 0xEC, 0xAD, 0xBD, 0xCD, + 0xDD, 0xED, 0x0E, 0x8E, 0x9E, 0xAE, 0xBE, 0x0F, 0x4F, 0x5F, 0x6F, 0x7F, + 0x8F, 0x9F, 0xAF, 0xB0, 0xB6, 0xB7, 0xA8, 0xB8, 0x99, 0xA9, 0xB9, 0xC9, + 0x7A, 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0x0B, 0x6B, 0x7B, 0x8B, 0x9B, 0xCB, + 0xAC, 0xBC, 0xCC, 0xFC, 0xFD, 0xCE, 0xDE, 0xEE, 0xFE, 0xBF, 0xCF, 0xDF, + 0xEF, 0xFF, 0xAB, 0xBB +}; + +static const uint8_t huff_a37_cb[7] = { 4, 8, 7, 6, 8, 22, 20 }; + +static const uint8_t huff_a37_xlat[63] = { + 0, 1, 2, 3, 61, 62, 63, 4, 5, 6, 58, 59, 60, 7, 8, 9, + 10, 54, 55, 56, 57, 11, 12, 13, 14, 15, 16, 25, 26, 27, 28, 29, + 30, 35, 36, 37, 38, 48, 49, 50, 51, 52, 53, 17, 18, 19, 20, 21, + 22, 23, 24, 31, 33, 34, 39, 40, 41, 42, 43, 44, 45, 46, 47 +}; + +static const uint8_t huff_a41_cb[14] = { + 1, 12, 1, 0, 0, 6, 2, 0, 0, 0, 19, 9, 24, 20 +}; + +static const uint8_t huff_a41_xlat[81] = { + 0x00, 0x40, 0xC0, 0x10, 0x30, 0x04, 0x0C, 0x01, 0x03, 0x50, 0xD0, 0x70, + 0xF0, 0xC4, 0x34, 0x4C, 0xCC, 0x1C, 0x41, 0xC1, 0x31, 0x05, 0x0D, 0x43, + 0xC3, 0x13, 0x07, 0x0F, 0x44, 0x14, 0x74, 0xDC, 0x3C, 0x11, 0x1D, 0x33, + 0x37, 0x54, 0xD4, 0xF4, 0x5C, 0x7C, 0xFC, 0xD1, 0x71, 0xF1, 0xC5, 0x15, + 0x35, 0x4D, 0xCD, 0xDD, 0x3D, 0xD3, 0x73, 0x47, 0xC7, 0x17, 0x77, 0x1F, + 0x3F, 0x51, 0x45, 0x55, 0xD5, 0x75, 0xF5, 0x5D, 0x7D, 0xFD, 0x53, 0xF3, + 0x57, 0xD7, 0xF7, 0x4F, 0xCF, 0x5F, 0xDF, 0x7F, 0xFF +}; + +static const uint8_t huff_a42_cb[10] = { 3, 10, 1, 2, 13, 1, 31, 13, 16, 4 }; + +static const uint8_t huff_a42_xlat[81] = { + 0x00, 0x40, 0x01, 0x10, 0x50, 0x04, 0x44, 0x14, 0x54, 0x41, 0x11, 0x51, + 0x05, 0x45, 0x15, 0x55, 0x59, 0x80, 0x90, 0x20, 0x60, 0x84, 0x94, 0x24, + 0x64, 0x08, 0x48, 0x18, 0x58, 0x81, 0x91, 0x21, 0x61, 0x85, 0x95, 0x25, + 0x65, 0x09, 0x49, 0x19, 0x02, 0x42, 0x12, 0x52, 0x06, 0x46, 0x16, 0x56, + 0xA0, 0xA4, 0x68, 0xA1, 0xA5, 0x99, 0x29, 0x69, 0x96, 0x66, 0x4A, 0x1A, + 0x5A, 0x88, 0x98, 0x28, 0x89, 0xA9, 0x82, 0x92, 0x22, 0x62, 0x86, 0x26, + 0xA6, 0x0A, 0x9A, 0x2A, 0x6A, 0xA8, 0xA2, 0x8A, 0xAA +}; + +static const uint8_t huff_a43_cb[5] = { 2, 4, 2, 3, 2 }; + +static const uint8_t huff_a43_xlat[7] = { 0, 7, 1, 2, 6, 3, 5 }; + +static const uint8_t huff_a44_cb[9] = { 4, 10, 5, 4, 12, 17, 47, 24, 12 }; + +static const uint8_t huff_a44_xlat[121] = { + 0x00, 0x10, 0xF0, 0x01, 0x0F, 0x11, 0xF1, 0x1F, 0xFF, 0x20, 0xE0, 0x21, + 0xE1, 0x02, 0x12, 0xF2, 0x0E, 0x1E, 0xFE, 0x2F, 0xEF, 0x30, 0x50, 0xD0, + 0xD1, 0x22, 0xE2, 0x03, 0x13, 0xF3, 0x0D, 0x1D, 0x2D, 0xFD, 0x2E, 0xEE, + 0x3F, 0xDF, 0x40, 0xB0, 0xC0, 0x31, 0x41, 0x51, 0xB1, 0xC1, 0x32, 0xB2, + 0xC2, 0xD2, 0x23, 0xB3, 0xD3, 0xE3, 0x04, 0x14, 0xE4, 0xF4, 0x05, 0x15, + 0xD5, 0xE5, 0xF5, 0x0B, 0x1B, 0x2B, 0x3B, 0xEB, 0xFB, 0x0C, 0x1C, 0x2C, + 0xFC, 0x3D, 0x5D, 0xED, 0x3E, 0x4E, 0x5E, 0xBE, 0xDE, 0x4F, 0x5F, 0xBF, + 0xCF, 0x42, 0x52, 0x33, 0x53, 0xC3, 0x24, 0xB4, 0xD4, 0x25, 0x35, 0xC5, + 0x4B, 0xCB, 0xDB, 0x3C, 0x4C, 0x5C, 0xDC, 0xEC, 0x4D, 0xBD, 0xCD, 0xDD, + 0xCE, 0x43, 0x34, 0x44, 0x54, 0xC4, 0x45, 0x55, 0xB5, 0x5B, 0xBB, 0xBC, + 0xCC +}; + +static const uint8_t huff_a45_cb[5] = { 2, 4, 2, 2, 4 }; + +static const uint8_t huff_a45_xlat[8] = { 1, 2, 0, 3, 4, 5, 6, 7 }; + +static const uint8_t huff_a46_cb[7] = { 5, 9, 1, 16, 31, 36, 172 }; + +static const uint8_t huff_a46_xlat[256] = { + 0x02, 0x00, 0x30, 0x21, 0x31, 0x41, 0x61, 0x12, 0x22, 0x42, 0x62, 0x43, + 0x53, 0x24, 0x45, 0x26, 0x27, 0x10, 0x40, 0xB0, 0x01, 0x11, 0x81, 0x32, + 0x52, 0x72, 0x92, 0x03, 0x13, 0x33, 0x63, 0x14, 0x34, 0x54, 0x64, 0x74, + 0x05, 0x15, 0x25, 0x35, 0x55, 0x65, 0x06, 0x46, 0x56, 0x57, 0x67, 0x88, + 0x20, 0x51, 0x91, 0xD1, 0xF2, 0x23, 0x83, 0x93, 0x04, 0x44, 0x84, 0x94, + 0x75, 0x85, 0xC5, 0x36, 0x66, 0x96, 0xB6, 0x07, 0x37, 0x97, 0x08, 0x28, + 0x38, 0x48, 0x68, 0x09, 0x69, 0x79, 0x0A, 0x2A, 0x1B, 0x9B, 0x2C, 0x4D, + 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0, 0xC0, 0xD0, 0xE0, 0xF0, 0x71, 0xA1, + 0xB1, 0xC1, 0xE1, 0xF1, 0x82, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0x73, 0xA3, + 0xB3, 0xC3, 0xD3, 0xE3, 0xF3, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4, 0x95, + 0xA5, 0xB5, 0xD5, 0xE5, 0xF5, 0x16, 0x76, 0x86, 0xA6, 0xC6, 0xD6, 0xE6, + 0xF6, 0x17, 0x47, 0x77, 0x87, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7, 0x18, + 0x58, 0x78, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8, 0x19, 0x29, 0x39, + 0x49, 0x59, 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9, 0x1A, 0x3A, + 0x4A, 0x5A, 0x6A, 0x7A, 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA, + 0x0B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B, 0x8B, 0xAB, 0xBB, 0xCB, 0xDB, + 0xEB, 0xFB, 0x0C, 0x1C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C, 0x8C, 0x9C, 0xAC, + 0xBC, 0xCC, 0xDC, 0xEC, 0xFC, 0x0D, 0x1D, 0x2D, 0x3D, 0x5D, 0x6D, 0x7D, + 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD, 0x0E, 0x1E, 0x2E, 0x3E, + 0x4E, 0x5E, 0x6E, 0x7E, 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE, + 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F, 0x8F, 0x9F, 0xAF, 0xBF, + 0xCF, 0xDF, 0xEF, 0xFF +}; + +static const uint8_t huff_a47_cb[8] = { 4, 9, 5, 12, 9, 12, 15, 10 }; + +static const uint8_t huff_a47_xlat[63] = { + 0, 1, 2, 62, 63, 3, 4, 5, 6, 8, 54, 56, 57, 58, 59, 60, + 61, 7, 9, 10, 11, 12, 13, 14, 53, 55, 15, 16, 17, 18, 19, 20, + 21, 36, 37, 39, 42, 52, 22, 25, 28, 35, 38, 40, 41, 43, 45, 46, + 47, 48, 49, 50, 51, 23, 24, 26, 27, 29, 30, 31, 33, 34, 44 +}; + +static const uint8_t huff_a51_cb[12] = { + 2, 11, 1, 0, 6, 2, 6, 18, 4, 26, 6, 12 +}; + +static const uint8_t huff_a51_xlat[81] = { + 0x00, 0x40, 0xC0, 0x30, 0x04, 0x01, 0x03, 0x10, 0x0C, 0xD0, 0x70, 0x34, + 0x1C, 0x0D, 0x07, 0x50, 0xF0, 0x44, 0xC4, 0x14, 0x4C, 0xCC, 0x3C, 0x41, + 0xC1, 0x11, 0x31, 0x05, 0x43, 0xC3, 0x13, 0x33, 0x0F, 0x74, 0xDC, 0x1D, + 0x37, 0x54, 0xD4, 0xF4, 0x5C, 0x7C, 0xFC, 0xD1, 0x71, 0xF1, 0xC5, 0x15, + 0x35, 0x4D, 0xCD, 0xDD, 0x3D, 0x53, 0xD3, 0x73, 0x47, 0xC7, 0x17, 0x77, + 0x4F, 0x1F, 0x3F, 0x51, 0x45, 0x55, 0xF3, 0xCF, 0xFF, 0xD5, 0x75, 0xF5, + 0x5D, 0x7D, 0xFD, 0x57, 0xD7, 0xF7, 0x5F, 0xDF, 0x7F +}; + +static const uint8_t huff_a52_cb[12] = { 1, 10, 1, 0, 2, 2, 0, 4, 3, 8, 3, 2 }; + +static const uint8_t huff_a52_xlat[25] = { + 0x00, 0x08, 0x38, 0x01, 0x07, 0x09, 0x39, 0x0F, 0x3F, 0x10, 0x02, 0x06, + 0x30, 0x11, 0x31, 0x0A, 0x3A, 0x0E, 0x17, 0x37, 0x32, 0x16, 0x3E, 0x12, + 0x36 +}; + +static const uint8_t huff_a53_xlat[7] = { 0, 1, 2, 6, 7, 3, 5 }; + +static const uint8_t huff_a54_cb[8] = { 4, 9, 4, 7, 12, 19, 21, 58 }; + +static const uint8_t huff_a54_xlat[121] = { + 0x00, 0x01, 0x0F, 0x1F, 0x10, 0xE0, 0xF0, 0x11, 0xF1, 0x2F, 0xFF, 0x20, + 0x21, 0xE1, 0x02, 0x12, 0xF2, 0x03, 0xF3, 0x0E, 0x2E, 0xFE, 0x3F, 0x30, + 0x40, 0xD0, 0xC1, 0xD1, 0x22, 0xC2, 0x33, 0xE3, 0x0C, 0xCC, 0x0D, 0x1D, + 0x2D, 0xFD, 0x1E, 0x3E, 0x5E, 0xEF, 0xC0, 0x52, 0xB2, 0xD2, 0x43, 0xC3, + 0xD3, 0x24, 0x45, 0xF5, 0x4B, 0x5B, 0xFB, 0x1C, 0x3D, 0xBD, 0xDD, 0xEE, + 0xBF, 0xCF, 0xDF, 0x50, 0xB0, 0x31, 0x41, 0x51, 0xB1, 0x32, 0x42, 0xE2, + 0x13, 0x23, 0x53, 0xB3, 0x04, 0x14, 0x34, 0x44, 0x54, 0xB4, 0xC4, 0xD4, + 0xE4, 0xF4, 0x05, 0x15, 0x25, 0x35, 0x55, 0xB5, 0xC5, 0xD5, 0xE5, 0x0B, + 0x1B, 0x2B, 0x3B, 0xBB, 0xCB, 0xDB, 0xEB, 0x2C, 0x3C, 0x4C, 0x5C, 0xBC, + 0xDC, 0xEC, 0xFC, 0x4D, 0x5D, 0xCD, 0xED, 0x4E, 0xBE, 0xCE, 0xDE, 0x4F, + 0x5F +}; + +static const uint8_t huff_a55_cb[8] = { 1, 6, 1, 1, 1, 0, 3, 2 }; + +static const uint8_t huff_a55_xlat[8] = { 0, 1, 2, 3, 6, 7, 4, 5 }; + +static const uint8_t huff_a56_cb[7] = { 3, 7, 1, 8, 6, 8, 8 }; + +static const uint8_t huff_a56_xlat[31] = { + 4, 0, 1, 2, 3, 28, 29, 30, 31, 5, 6, 7, 24, 25, 27, 8, + 9, 14, 19, 21, 22, 23, 26, 10, 11, 12, 13, 15, 17, 18, 20 +}; + +static const uint8_t huff_a57_cb[9] = { 3, 9, 1, 5, 7, 8, 16, 22, 4 }; + +static const uint8_t huff_a57_xlat[63] = { + 0, 1, 2, 61, 62, 63, 3, 4, 5, 6, 58, 59, + 60, 7, 8, 9, 10, 54, 55, 56, 57, 11, 12, 13, + 14, 15, 26, 27, 28, 36, 37, 38, 49, 50, 51, 52, + 53, 16, 17, 18, 19, 20, 21, 23, 24, 25, 29, 30, + 31, 33, 34, 35, 39, 43, 44, 45, 46, 47, 48, 22, + 40, 41, 42 +}; + +static const uint8_t huff_a61_cb[12] = { + 2, 11, 1, 0, 8, 0, 1, 16, 10, 29, 12, 4 +}; + +static const uint8_t huff_a61_xlat[81] = { + 0x00, 0x40, 0xC0, 0x10, 0x30, 0x04, 0x0C, 0x01, 0x03, 0x70, 0x50, 0xD0, + 0xF0, 0x44, 0xC4, 0x14, 0x34, 0x4C, 0x1C, 0x3C, 0x31, 0x05, 0x0D, 0x13, + 0x07, 0x0F, 0x74, 0xCC, 0xDC, 0xFC, 0x41, 0xC1, 0x11, 0x43, 0xC3, 0x33, + 0x54, 0xD4, 0xF4, 0x5C, 0x7C, 0x51, 0xD1, 0x71, 0xF1, 0x45, 0xC5, 0x15, + 0x35, 0x4D, 0xCD, 0x1D, 0x3D, 0x53, 0xD3, 0x73, 0xF3, 0x47, 0xC7, 0x17, + 0x37, 0x4F, 0xCF, 0x1F, 0x3F, 0x55, 0xD5, 0x75, 0xF5, 0x5D, 0xDD, 0xFD, + 0x57, 0xD7, 0x77, 0xF7, 0xFF, 0x7D, 0x5F, 0xDF, 0x7F +}; + +static const uint8_t huff_a62_cb[8] = { 3, 8, 5, 2, 2, 9, 5, 2 }; + +static const uint8_t huff_a62_xlat[25] = { + 0x00, 0x08, 0x38, 0x01, 0x07, 0x39, 0x0F, 0x09, 0x3F, 0x10, 0x30, 0x31, + 0x02, 0x3A, 0x06, 0x0E, 0x17, 0x37, 0x11, 0x0A, 0x32, 0x16, 0x3E, 0x12, + 0x36 +}; + +static const uint8_t huff_a63_cb[11] = { + 3, 11, 1, 1, 10, 4, 16, 29, 46, 75, 74 +}; + +static const uint8_t huff_a63_xlat[256] = { + 0x00, 0x40, 0x10, 0x50, 0x04, 0x44, 0x14, 0x01, 0x41, 0x05, 0x45, 0x55, + 0x54, 0x11, 0x51, 0x15, 0x80, 0x90, 0x60, 0x24, 0x64, 0xA4, 0x48, 0x61, + 0x95, 0x25, 0xA5, 0x02, 0x42, 0x52, 0x16, 0x56, 0x20, 0x84, 0x94, 0x18, + 0x58, 0x81, 0x91, 0x85, 0x65, 0x09, 0x49, 0x19, 0x59, 0x99, 0x29, 0x69, + 0x79, 0x5D, 0x12, 0x62, 0x06, 0x46, 0x86, 0x66, 0x1A, 0x5A, 0x6A, 0x47, + 0x17, 0xC0, 0xA0, 0xE0, 0xC4, 0xD4, 0x74, 0x08, 0x78, 0x0C, 0x4C, 0x1C, + 0x5C, 0xD1, 0x21, 0xE1, 0x71, 0xC5, 0xE5, 0x75, 0xB5, 0x89, 0xBD, 0x92, + 0x22, 0x96, 0xA6, 0x36, 0x0A, 0x4A, 0x8A, 0x9A, 0x2A, 0x7A, 0xDE, 0x6E, + 0x43, 0x13, 0x53, 0x23, 0x07, 0x77, 0x4B, 0x1B, 0x9B, 0x6B, 0x2F, 0xD0, + 0x30, 0x70, 0xE4, 0x34, 0xF4, 0xC8, 0x98, 0x28, 0x68, 0xA8, 0xE8, 0x38, + 0xB8, 0xF8, 0x9C, 0x2C, 0x6C, 0x7C, 0xA1, 0xB1, 0xD5, 0x35, 0xC9, 0xD9, + 0xA9, 0xE9, 0x39, 0xB9, 0xF9, 0xCD, 0x1D, 0x2D, 0xAD, 0x7D, 0xC2, 0xD2, + 0xA2, 0xB2, 0xF2, 0xC6, 0x26, 0x76, 0xB6, 0xDA, 0xAA, 0xEA, 0x3A, 0xFA, + 0x0E, 0x4E, 0x2E, 0x7E, 0xBE, 0xFE, 0x03, 0x83, 0x63, 0xA3, 0xB3, 0x87, + 0x57, 0x97, 0xD7, 0x27, 0x0B, 0x8B, 0x5B, 0x2B, 0xAB, 0xCF, 0x1F, 0x9F, + 0x7F, 0xBF, 0xB0, 0xF0, 0xB4, 0x88, 0xD8, 0x8C, 0xCC, 0xDC, 0xAC, 0xEC, + 0x3C, 0xBC, 0xFC, 0xC1, 0x31, 0xF1, 0xF5, 0x0D, 0x4D, 0x8D, 0x9D, 0xDD, + 0x6D, 0xED, 0x3D, 0xFD, 0x82, 0xE2, 0x32, 0x72, 0xD6, 0xE6, 0xF6, 0xCA, + 0xBA, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xAE, 0xEE, 0x3E, 0xC3, 0x93, 0xD3, + 0xE3, 0x33, 0x73, 0xF3, 0xC7, 0x67, 0xA7, 0xE7, 0x37, 0xB7, 0xF7, 0xCB, + 0xDB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB, 0x0F, 0x4F, 0x8F, 0x5F, 0xDF, 0x6F, + 0xAF, 0xEF, 0x3F, 0xFF +}; + +static const uint8_t huff_a64_cb[8] = { 4, 9, 1, 7, 12, 36, 63, 2 }; + +static const uint8_t huff_a64_xlat[121] = { + 0x00, 0x10, 0x20, 0xE0, 0xF0, 0x02, 0x0E, 0xEF, 0x30, 0x01, 0x11, 0x21, + 0x31, 0xF1, 0x12, 0xF2, 0x1E, 0xEE, 0xDF, 0xFF, 0x40, 0xC0, 0xD0, 0xD1, + 0xE1, 0x22, 0x32, 0x42, 0xD2, 0xE2, 0x03, 0x13, 0x23, 0xB3, 0xC3, 0xE3, + 0xF3, 0xE4, 0x05, 0xF5, 0x2B, 0x0C, 0xFC, 0x1D, 0x2D, 0xBD, 0xDD, 0xFD, + 0x2E, 0x4E, 0xDE, 0xFE, 0x0F, 0x1F, 0x2F, 0x3F, 0x50, 0xB0, 0x41, 0x51, + 0xB1, 0xC1, 0x52, 0xB2, 0xC2, 0x33, 0x43, 0x53, 0xD3, 0x04, 0x14, 0x24, + 0x34, 0x44, 0x54, 0xB4, 0xC4, 0xD4, 0xF4, 0x15, 0x25, 0x35, 0x45, 0x55, + 0xB5, 0xC5, 0xD5, 0xE5, 0x0B, 0x1B, 0x3B, 0x4B, 0x5B, 0xBB, 0xCB, 0xDB, + 0xEB, 0xFB, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0xBC, 0xCC, 0xDC, 0xEC, 0x0D, + 0x3D, 0x4D, 0x5D, 0xCD, 0xED, 0x3E, 0x5E, 0xBE, 0xCE, 0x4F, 0xCF, 0x5F, + 0xBF +}; + +static const uint8_t huff_a65_cb[8] = { 2, 7, 3, 0, 1, 3, 4, 4 }; + +static const uint8_t huff_a65_xlat[15] = { + 0, 1, 15, 14, 2, 3, 13, 4, 6, 10, 12, 5, 7, 9, 11 +}; + +static const uint8_t huff_a66_cb[11] = { 2, 10, 1, 2, 2, 6, 8, 6, 3, 1, 2 }; + +static const uint8_t huff_a66_xlat[31] = { + 0, 1, 31, 2, 30, 3, 4, 15, 17, 28, 29, 5, 6, 7, 8, 24, + 25, 26, 27, 9, 10, 11, 21, 22, 23, 12, 19, 20, 13, 14, 18 +}; + +static const uint8_t huff_a67_cb[10] = { 2, 9, 1, 1, 3, 4, 6, 13, 25, 10 }; + +static const uint8_t huff_a67_xlat[63] = { + 0, 1, 2, 62, 63, 3, 4, 60, 61, 5, 6, 7, 57, 58, 59, 8, + 9, 10, 11, 12, 13, 26, 38, 52, 53, 54, 55, 56, 14, 15, 16, 17, + 18, 19, 25, 27, 28, 29, 30, 31, 33, 34, 35, 36, 37, 39, 45, 46, + 47, 48, 49, 50, 51, 20, 21, 22, 23, 24, 40, 41, 42, 43, 44 +}; + +static const uint8_t huff_a71_cb[5] = { 1, 3, 1, 1, 2 }; + +static const uint8_t huff_a72_cb[12] = { + 2, 11, 1, 0, 4, 8, 3, 8, 24, 17, 12, 4 +}; + +static const uint8_t huff_a72_xlat[81] = { + 0x00, 0x40, 0x10, 0x04, 0x01, 0x50, 0x44, 0x14, 0x54, 0x41, 0x11, 0x05, + 0x15, 0x51, 0x45, 0x55, 0x80, 0x90, 0x20, 0x64, 0x08, 0x19, 0x02, 0x06, + 0x60, 0x84, 0x94, 0x24, 0x48, 0x18, 0x58, 0x81, 0x91, 0x21, 0x61, 0x85, + 0x95, 0x25, 0x65, 0x09, 0x49, 0x59, 0x42, 0x12, 0x52, 0x46, 0x16, 0x56, + 0xA0, 0xA4, 0x98, 0x28, 0x68, 0xA1, 0xA5, 0x99, 0x29, 0x69, 0x96, 0x26, + 0x66, 0x0A, 0x4A, 0x1A, 0x5A, 0x88, 0xA8, 0x89, 0xA9, 0x82, 0x92, 0x22, + 0x62, 0x86, 0xA6, 0x2A, 0x6A, 0xA2, 0x8A, 0x9A, 0xAA +}; + +static const uint8_t huff_a73_cb[11] = { 2, 10, 1, 1, 5, 2, 8, 7, 13, 8, 4 }; + +static const uint8_t huff_a73_xlat[49] = { + 0x00, 0x08, 0x38, 0x01, 0x39, 0x07, 0x0F, 0x09, 0x3F, 0x10, 0x30, 0x31, + 0x02, 0x3A, 0x06, 0x0E, 0x17, 0x11, 0x0A, 0x32, 0x0D, 0x16, 0x3E, 0x37, + 0x18, 0x28, 0x19, 0x29, 0x12, 0x2A, 0x03, 0x3B, 0x05, 0x15, 0x1E, 0x1F, + 0x2F, 0x1A, 0x0B, 0x2B, 0x33, 0x35, 0x3D, 0x2E, 0x36, 0x13, 0x1B, 0x1D, + 0x2D +}; + +static const uint8_t huff_a74_cb[14] = { + 1, 12, 1, 0, 0, 4, 0, 4, 5, 9, 30, 45, 21, 2 +}; + +static const uint8_t huff_a74_xlat[121] = { + 0x00, 0x10, 0xF0, 0x01, 0x0F, 0x11, 0xF1, 0x1F, 0xFF, 0x20, 0xE0, 0x02, + 0xF2, 0x0E, 0x21, 0xE1, 0x12, 0xE2, 0x1E, 0x2E, 0xFE, 0x2F, 0xEF, 0x30, + 0x50, 0xB0, 0xC0, 0xD0, 0x31, 0xB1, 0xD1, 0x22, 0xD2, 0x03, 0x13, 0xE3, + 0xF3, 0xF4, 0x05, 0xE5, 0xF5, 0x0B, 0x1B, 0x0C, 0x0D, 0x1D, 0x2D, 0xFD, + 0x3E, 0xEE, 0x3F, 0x5F, 0xDF, 0x40, 0x41, 0x51, 0xC1, 0x32, 0x42, 0x52, + 0xB2, 0xC2, 0x23, 0x33, 0xB3, 0xC3, 0xD3, 0x04, 0x14, 0x24, 0xD4, 0xE4, + 0x15, 0x25, 0xC5, 0xD5, 0x2B, 0x3B, 0xEB, 0xFB, 0x1C, 0x2C, 0x3C, 0x5C, + 0xEC, 0xFC, 0x3D, 0x5D, 0xDD, 0xED, 0x4E, 0x5E, 0xBE, 0xCE, 0xDE, 0x4F, + 0xBF, 0xCF, 0x43, 0x53, 0x34, 0x54, 0xB4, 0xC4, 0x35, 0x45, 0x55, 0xB5, + 0x4B, 0x5B, 0xCB, 0xDB, 0x4C, 0xBC, 0xCC, 0xDC, 0x4D, 0xBD, 0xCD, 0x44, + 0xBB +}; + +static const uint8_t huff_a75_cb[7] = { 2, 6, 1, 3, 3, 4, 4 }; + +static const uint8_t huff_a75_xlat[15] = { + 0, 1, 14, 15, 2, 3, 13, 4, 6, 10, 12, 5, 7, 9, 11 +}; + +static const uint8_t huff_a76_cb[12] = { + 3, 12, 1, 3, 4, 8, 10, 36, 60, 78, 48, 8 +}; + +static const uint8_t huff_a76_xlat[256] = { + 0x00, 0x10, 0x01, 0x11, 0x20, 0x21, 0x02, 0x12, 0x30, 0x31, 0x41, 0x22, + 0x03, 0x13, 0x23, 0x14, 0x40, 0x51, 0x61, 0x32, 0x42, 0x33, 0x04, 0x24, + 0x15, 0x16, 0x50, 0x60, 0xD0, 0x71, 0x81, 0xD1, 0xE1, 0xF1, 0x52, 0x62, + 0x72, 0xD2, 0x43, 0x53, 0x63, 0xD3, 0x34, 0x44, 0x54, 0x05, 0x25, 0x35, + 0x45, 0x06, 0x26, 0x36, 0x17, 0x27, 0x18, 0x0D, 0x1D, 0x2D, 0x3D, 0x1E, + 0x2E, 0x1F, 0x70, 0x80, 0xE0, 0xF0, 0x91, 0xA1, 0xC1, 0x82, 0x92, 0xC2, + 0xE2, 0xF2, 0x73, 0x83, 0x93, 0xE3, 0xF3, 0x64, 0x74, 0x84, 0xD4, 0xE4, + 0xF4, 0x55, 0x65, 0xD5, 0xE5, 0xF5, 0x46, 0x56, 0x66, 0xD6, 0x07, 0x37, + 0x47, 0x57, 0x08, 0x28, 0x38, 0x48, 0x19, 0x29, 0x39, 0x1A, 0x2A, 0x1B, + 0x1C, 0x2C, 0x3C, 0x4D, 0x5D, 0x6D, 0x0E, 0x3E, 0x4E, 0x5E, 0x0F, 0x2F, + 0x3F, 0x4F, 0x90, 0xA0, 0xB0, 0xC0, 0xB1, 0xA2, 0xB2, 0xA3, 0xB3, 0xC3, + 0x94, 0xA4, 0xB4, 0xC4, 0x75, 0x85, 0x95, 0xA5, 0xC5, 0x76, 0x86, 0x96, + 0xE6, 0xF6, 0x67, 0x77, 0x87, 0xD7, 0xE7, 0xF7, 0x58, 0x68, 0x78, 0x88, + 0xD8, 0xE8, 0xF8, 0x09, 0x49, 0x59, 0x69, 0xD9, 0xE9, 0xF9, 0x0A, 0x3A, + 0x4A, 0x5A, 0xDA, 0xEA, 0x0B, 0x2B, 0x3B, 0x4B, 0xDB, 0x0C, 0x4C, 0x5C, + 0x6C, 0xDC, 0x7D, 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0x6E, 0x7E, 0x8E, 0x9E, + 0xAE, 0xBE, 0x5F, 0x6F, 0x7F, 0x8F, 0x9F, 0xAF, 0xB5, 0xA6, 0xB6, 0xC6, + 0x97, 0xA7, 0xC7, 0x98, 0xA8, 0xB8, 0xC8, 0x79, 0x89, 0x99, 0xA9, 0xB9, + 0xC9, 0x6A, 0x7A, 0x8A, 0x9A, 0xAA, 0xCA, 0xFA, 0x5B, 0x6B, 0x7B, 0x8B, + 0xCB, 0xEB, 0xFB, 0x7C, 0x8C, 0x9C, 0xAC, 0xBC, 0xEC, 0xFC, 0xDD, 0xED, + 0xFD, 0xCE, 0xDE, 0xEE, 0xFE, 0xBF, 0xCF, 0xDF, 0xB7, 0xBA, 0x9B, 0xAB, + 0xBB, 0xCC, 0xEF, 0xFF +}; + +static const uint8_t huff_b01_cb[14] = { + 1, 12, 1, 0, 0, 2, 6, 0, 11, 13, 12, 24, 4, 8 +}; + +static const uint8_t huff_b01_xlat[81] = { + 0x00, 0x01, 0x03, 0x40, 0xC0, 0x10, 0x30, 0x04, 0x0C, 0x50, 0xD0, 0x70, + 0xF0, 0x34, 0x1C, 0x05, 0x0D, 0x13, 0x07, 0x0F, 0x44, 0xC4, 0x14, 0x4C, + 0xCC, 0x3C, 0x41, 0xC1, 0x11, 0x31, 0x43, 0xC3, 0x33, 0x54, 0x74, 0xDC, + 0xFC, 0x71, 0x15, 0x4D, 0x1D, 0xD3, 0xC7, 0x37, 0x3F, 0xD4, 0xF4, 0x5C, + 0x7C, 0x51, 0xD1, 0xF1, 0x45, 0xC5, 0x55, 0x35, 0xCD, 0xDD, 0x3D, 0x53, + 0x73, 0xF3, 0x47, 0x17, 0x77, 0x4F, 0xCF, 0x1F, 0xFF, 0xF5, 0x7D, 0xD7, + 0x5F, 0xD5, 0x75, 0x5D, 0xFD, 0x57, 0xF7, 0xDF, 0x7F +}; + +static const uint8_t huff_b02_cb[14] = { + 1, 12, 1, 0, 0, 4, 0, 8, 4, 9, 19, 13, 13, 10 +}; + +static const uint8_t huff_b02_xlat[81] = { + 0x00, 0x40, 0x10, 0x04, 0x01, 0x50, 0x44, 0x14, 0x54, 0x41, 0x11, 0x05, + 0x15, 0x80, 0x51, 0x45, 0x55, 0x90, 0x20, 0x60, 0x24, 0x08, 0x18, 0x09, + 0x02, 0x06, 0x84, 0x94, 0x64, 0x48, 0x58, 0x81, 0x91, 0x21, 0x61, 0x95, + 0x25, 0x65, 0x19, 0x59, 0x42, 0x12, 0x46, 0x16, 0x56, 0xA0, 0xA4, 0x28, + 0x68, 0x85, 0xA5, 0x49, 0x29, 0x69, 0x52, 0x0A, 0x1A, 0x5A, 0x88, 0x98, + 0xA1, 0x89, 0x99, 0xA9, 0x22, 0x62, 0x96, 0x26, 0x66, 0x4A, 0x6A, 0xA8, + 0x82, 0x92, 0xA2, 0x86, 0xA6, 0x8A, 0x9A, 0x2A, 0xAA +}; + +static const uint8_t huff_b03_cb[11] = { 1, 9, 1, 0, 0, 4, 0, 5, 12, 13, 14 }; + +static const uint8_t huff_b03_xlat[49] = { + 0x00, 0x08, 0x38, 0x01, 0x07, 0x30, 0x09, 0x39, 0x0F, 0x3F, 0x10, 0x18, + 0x28, 0x31, 0x02, 0x3A, 0x03, 0x05, 0x06, 0x0E, 0x17, 0x37, 0x11, 0x19, + 0x29, 0x0A, 0x32, 0x0B, 0x3B, 0x0D, 0x15, 0x3D, 0x3E, 0x1F, 0x2F, 0x12, + 0x1A, 0x2A, 0x13, 0x1B, 0x2B, 0x33, 0x1D, 0x2D, 0x35, 0x16, 0x1E, 0x2E, + 0x36 +}; + +static const uint8_t huff_b04_cb[12] = { + 2, 11, 1, 0, 4, 4, 5, 9, 30, 45, 21, 2 +}; + +static const uint8_t huff_b04_xlat[121] = { + 0x00, 0x10, 0xF0, 0x01, 0x0F, 0x11, 0xF1, 0x1F, 0xFF, 0x20, 0xE0, 0x02, + 0xF2, 0x0E, 0x21, 0xE1, 0x12, 0xE2, 0x1E, 0x2E, 0xFE, 0x2F, 0xEF, 0x30, + 0x50, 0xB0, 0xC0, 0xD0, 0x31, 0xB1, 0xD1, 0x22, 0xD2, 0x03, 0x13, 0xE3, + 0xF3, 0xF4, 0x05, 0xE5, 0xF5, 0x0B, 0x1B, 0x0C, 0x0D, 0x1D, 0x2D, 0xFD, + 0x3E, 0xEE, 0x3F, 0x5F, 0xDF, 0x40, 0x41, 0x51, 0xC1, 0x32, 0x42, 0x52, + 0xB2, 0xC2, 0x23, 0x33, 0xB3, 0xC3, 0xD3, 0x04, 0x14, 0x24, 0xD4, 0xE4, + 0x15, 0x25, 0xC5, 0xD5, 0x2B, 0x3B, 0xEB, 0xFB, 0x1C, 0x2C, 0x3C, 0x5C, + 0xEC, 0xFC, 0x3D, 0x5D, 0xDD, 0xED, 0x4E, 0x5E, 0xBE, 0xCE, 0xDE, 0x4F, + 0xBF, 0xCF, 0x43, 0x53, 0x34, 0x54, 0xB4, 0xC4, 0x35, 0x45, 0x55, 0xB5, + 0x4B, 0x5B, 0xCB, 0xDB, 0x4C, 0xBC, 0xCC, 0xDC, 0x4D, 0xBD, 0xCD, 0x44, + 0xBB +}; + +static const uint8_t huff_b05_cb[11] = { + 3, 11, 1, 4, 4, 4, 12, 30, 73, 75, 22 +}; + +static const uint8_t huff_b05_xlat[225] = { + 0x00, 0x10, 0xF0, 0x01, 0x0F, 0x11, 0xF1, 0x1F, 0xFF, 0x20, 0xE0, 0x02, + 0x0E, 0x30, 0xD0, 0x21, 0xE1, 0x12, 0xF2, 0x03, 0x0D, 0x1E, 0xFE, 0x2F, + 0xEF, 0x40, 0x60, 0x70, 0x90, 0xA0, 0xC0, 0x31, 0xD1, 0x22, 0x32, 0xD2, + 0xE2, 0x13, 0x23, 0xE3, 0xF3, 0x04, 0x06, 0x07, 0x09, 0x0A, 0x0C, 0x1D, + 0x2D, 0xFD, 0x2E, 0x3E, 0xEE, 0x3F, 0xDF, 0x50, 0xB0, 0x41, 0x51, 0x61, + 0x71, 0x91, 0xA1, 0xB1, 0xC1, 0x42, 0x62, 0x72, 0x92, 0xA2, 0xC2, 0x33, + 0x93, 0xA3, 0xD3, 0x14, 0x24, 0xE4, 0xF4, 0x05, 0x15, 0xF5, 0x16, 0x26, + 0xD6, 0xE6, 0xF6, 0x17, 0x27, 0xD7, 0xE7, 0xF7, 0x19, 0x29, 0x39, 0xE9, + 0xF9, 0x1A, 0x2A, 0xEA, 0xFA, 0x0B, 0x1B, 0xFB, 0x1C, 0x2C, 0xEC, 0xFC, + 0x3D, 0x7D, 0x9D, 0xDD, 0xED, 0x4E, 0x6E, 0x7E, 0x9E, 0xAE, 0xCE, 0xDE, + 0x4F, 0x5F, 0x6F, 0x7F, 0x9F, 0xAF, 0xBF, 0xCF, 0x52, 0xB2, 0x43, 0x53, + 0x63, 0x73, 0xB3, 0xC3, 0x34, 0x44, 0x64, 0x74, 0x94, 0xA4, 0xB4, 0xC4, + 0xD4, 0x25, 0x35, 0x65, 0x75, 0x95, 0xA5, 0xD5, 0xE5, 0x36, 0x46, 0x56, + 0x66, 0xA6, 0xB6, 0xC6, 0x37, 0x47, 0x57, 0xB7, 0xC7, 0x49, 0x59, 0x69, + 0xB9, 0xC9, 0xD9, 0x3A, 0x4A, 0x5A, 0x6A, 0xAA, 0xBA, 0xCA, 0xDA, 0x2B, + 0x3B, 0x6B, 0x7B, 0x9B, 0xAB, 0xDB, 0xEB, 0x3C, 0x4C, 0x6C, 0x7C, 0x9C, + 0xAC, 0xCC, 0xDC, 0x4D, 0x5D, 0x6D, 0xAD, 0xBD, 0xCD, 0x5E, 0xBE, 0x54, + 0x45, 0x55, 0xB5, 0xC5, 0x76, 0x96, 0x67, 0x77, 0x97, 0xA7, 0x79, 0x99, + 0xA9, 0x7A, 0x9A, 0x4B, 0x5B, 0xBB, 0xCB, 0x5C, 0xBC +}; + +static const uint8_t huff_b07_cb[9] = { 3, 9, 3, 2, 4, 8, 23, 13, 10 }; + +static const uint8_t huff_b07_xlat[63] = { + 0, 1, 63, 2, 62, 3, 4, 60, 61, 5, 6, 7, 8, 56, 57, 58, + 59, 9, 10, 11, 12, 25, 26, 27, 28, 29, 30, 31, 33, 34, 35, 36, + 37, 38, 39, 51, 52, 53, 54, 55, 13, 14, 15, 16, 17, 18, 19, 45, + 46, 47, 48, 49, 50, 20, 21, 22, 23, 24, 40, 41, 42, 43, 44 +}; + +static const uint8_t huff_b12_cb[10] = { 3, 10, 1, 3, 12, 0, 30, 9, 18, 8 }; + +static const uint8_t huff_b12_xlat[81] = { + 0x00, 0x40, 0x04, 0x01, 0x10, 0x50, 0x44, 0x14, 0x54, 0x41, 0x11, 0x51, + 0x05, 0x45, 0x15, 0x55, 0x80, 0x90, 0x20, 0x60, 0x84, 0x94, 0x24, 0x64, + 0x08, 0x48, 0x18, 0x81, 0x91, 0x61, 0x85, 0x95, 0x25, 0x65, 0x09, 0x49, + 0x19, 0x59, 0x02, 0x42, 0x12, 0x52, 0x06, 0x46, 0x16, 0x56, 0xA4, 0x58, + 0x68, 0x21, 0xA5, 0x29, 0x69, 0x1A, 0x5A, 0xA0, 0x88, 0x98, 0x28, 0xA1, + 0x89, 0x99, 0xA9, 0x92, 0x22, 0x62, 0x86, 0x96, 0x26, 0x66, 0x0A, 0x4A, + 0x6A, 0xA8, 0x82, 0xA2, 0xA6, 0x8A, 0x9A, 0x2A, 0xAA +}; + +static const uint8_t huff_b14_cb[14] = { + 1, 12, 1, 0, 0, 4, 0, 3, 5, 16, 28, 34, 26, 4 +}; + +static const uint8_t huff_b14_xlat[121] = { + 0x00, 0x10, 0xF0, 0x01, 0x0F, 0xF1, 0x1F, 0xFF, 0x20, 0xE0, 0x11, 0x02, + 0x0E, 0x30, 0x50, 0xB0, 0xD0, 0x21, 0xE1, 0x12, 0xF2, 0x03, 0x05, 0x0B, + 0x0D, 0x1E, 0xFE, 0x2F, 0xEF, 0x40, 0xC0, 0x31, 0x51, 0xB1, 0xC1, 0xD1, + 0x22, 0x52, 0xE2, 0x13, 0xF3, 0x04, 0x15, 0xF5, 0x1B, 0xEB, 0xFB, 0x0C, + 0x1D, 0xFD, 0x2E, 0x5E, 0xEE, 0x3F, 0x5F, 0xBF, 0xDF, 0x41, 0x32, 0x42, + 0xB2, 0xD2, 0x23, 0x53, 0xB3, 0xE3, 0x14, 0x24, 0xE4, 0xF4, 0x25, 0x35, + 0xD5, 0xE5, 0x2B, 0x3B, 0xDB, 0x1C, 0x2C, 0xBC, 0xEC, 0xFC, 0x2D, 0xBD, + 0xED, 0x3E, 0x4E, 0xBE, 0xDE, 0x4F, 0xCF, 0xC2, 0x33, 0x43, 0xC3, 0xD3, + 0x34, 0x44, 0x54, 0xB4, 0xD4, 0x45, 0x55, 0xC5, 0x4B, 0xCB, 0x3C, 0x4C, + 0x5C, 0xCC, 0xDC, 0x3D, 0x4D, 0x5D, 0xCD, 0xDD, 0xCE, 0xC4, 0xB5, 0x5B, + 0xBB +}; + +static const uint8_t huff_b16_cb[11] = { + 4, 12, 4, 4, 9, 13, 37, 76, 72, 39, 2 +}; + +static const uint8_t huff_b16_xlat[256] = { + 0x00, 0x10, 0x01, 0x11, 0x20, 0x21, 0x02, 0x12, 0x30, 0x31, 0x41, 0x22, + 0x32, 0x03, 0x13, 0x23, 0x14, 0x40, 0x51, 0x61, 0x42, 0x52, 0x33, 0x43, + 0x04, 0x24, 0x34, 0x15, 0x25, 0x16, 0x50, 0x60, 0x70, 0x71, 0x81, 0xD1, + 0xE1, 0x62, 0x72, 0x82, 0xD2, 0x53, 0x63, 0x73, 0xD3, 0x44, 0x54, 0x05, + 0x35, 0x45, 0x55, 0x06, 0x26, 0x36, 0x07, 0x17, 0x27, 0x37, 0x18, 0x28, + 0x19, 0x1D, 0x2D, 0x3D, 0x1E, 0x2E, 0x1F, 0x80, 0x90, 0xD0, 0xE0, 0xF0, + 0x91, 0xA1, 0xB1, 0xC1, 0xF1, 0x92, 0xA2, 0xB2, 0xC2, 0xE2, 0xF2, 0x83, + 0x93, 0xA3, 0xC3, 0xE3, 0xF3, 0x64, 0x74, 0x84, 0x94, 0xD4, 0xE4, 0xF4, + 0x65, 0x75, 0x85, 0xD5, 0xE5, 0x46, 0x56, 0x66, 0x76, 0xD6, 0xE6, 0x47, + 0x57, 0x67, 0xD7, 0x08, 0x38, 0x48, 0x58, 0x09, 0x29, 0x39, 0x49, 0x0A, + 0x1A, 0x2A, 0x3A, 0x1B, 0x2B, 0x0C, 0x1C, 0x2C, 0x3C, 0x0D, 0x4D, 0x5D, + 0x6D, 0x7D, 0x0E, 0x3E, 0x4E, 0x5E, 0x6E, 0x0F, 0x2F, 0x3F, 0x4F, 0xA0, + 0xB0, 0xC0, 0xB3, 0xA4, 0xB4, 0xC4, 0x95, 0xA5, 0xB5, 0xC5, 0xF5, 0x86, + 0x96, 0xA6, 0xB6, 0xC6, 0xF6, 0x77, 0x87, 0x97, 0xA7, 0xC7, 0xE7, 0xF7, + 0x68, 0x78, 0x88, 0x98, 0xD8, 0xE8, 0xF8, 0x59, 0x69, 0x79, 0x89, 0xD9, + 0xE9, 0xF9, 0x4A, 0x5A, 0x6A, 0x7A, 0xDA, 0xEA, 0x0B, 0x3B, 0x4B, 0x5B, + 0xDB, 0xEB, 0x4C, 0x5C, 0x6C, 0x7C, 0x8C, 0xDC, 0x8D, 0x9D, 0xAD, 0xBD, + 0xCD, 0x7E, 0x8E, 0x9E, 0xAE, 0xBE, 0x5F, 0x6F, 0x7F, 0x8F, 0x9F, 0xB7, + 0xA8, 0xB8, 0xC8, 0x99, 0xA9, 0xB9, 0xC9, 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, + 0xFA, 0x6B, 0x7B, 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xFB, 0x9C, 0xAC, 0xBC, + 0xCC, 0xEC, 0xFC, 0xDD, 0xED, 0xFD, 0xCE, 0xDE, 0xEE, 0xFE, 0xAF, 0xBF, + 0xCF, 0xDF, 0xEF, 0xFF +}; + +static const uint8_t huff_b26_cb[12] = { + 3, 12, 2, 2, 4, 5, 11, 26, 67, 78, 51, 10 +}; + +static const uint8_t huff_b26_xlat[256] = { + 0x00, 0x01, 0x10, 0x11, 0x20, 0x21, 0x02, 0x12, 0x30, 0x31, 0x22, 0x03, + 0x13, 0x40, 0x41, 0x51, 0x32, 0x42, 0x23, 0x33, 0x04, 0x14, 0x24, 0x15, + 0x50, 0x61, 0x71, 0xD1, 0xE1, 0x52, 0x62, 0xD2, 0x43, 0x53, 0xD3, 0x34, + 0x44, 0x05, 0x25, 0x35, 0x06, 0x16, 0x26, 0x17, 0x18, 0x1D, 0x2D, 0x3D, + 0x1E, 0x2E, 0x60, 0x70, 0x80, 0xD0, 0xE0, 0xF0, 0x81, 0x91, 0xA1, 0xC1, + 0xF1, 0x72, 0x82, 0x92, 0xC2, 0xE2, 0xF2, 0x63, 0x73, 0xE3, 0xF3, 0x54, + 0x64, 0x74, 0xD4, 0xE4, 0xF4, 0x45, 0x55, 0x65, 0xD5, 0xE5, 0xF5, 0x36, + 0x46, 0x56, 0xD6, 0xE6, 0x07, 0x27, 0x37, 0x47, 0xD7, 0x08, 0x28, 0x38, + 0x19, 0x29, 0x1A, 0x1B, 0x1C, 0x2C, 0x0D, 0x4D, 0x5D, 0x6D, 0x7D, 0x0E, + 0x3E, 0x4E, 0x5E, 0x6E, 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x90, 0xA0, 0xC0, + 0xB1, 0xA2, 0xB2, 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0x84, 0x94, 0xA4, 0xC4, + 0x75, 0x85, 0x95, 0xC5, 0x66, 0x76, 0x86, 0x96, 0xC6, 0xF6, 0x57, 0x67, + 0x77, 0xE7, 0xF7, 0x48, 0x58, 0x68, 0x78, 0xD8, 0xE8, 0xF8, 0x09, 0x39, + 0x49, 0x59, 0xD9, 0xE9, 0xF9, 0x0A, 0x2A, 0x3A, 0x4A, 0xDA, 0xEA, 0x0B, + 0x2B, 0x3B, 0xDB, 0xEB, 0x0C, 0x3C, 0x4C, 0x5C, 0x6C, 0xDC, 0x8D, 0x9D, + 0xAD, 0xBD, 0xCD, 0x7E, 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0x5F, 0x6F, 0x7F, + 0x8F, 0x9F, 0xAF, 0xB0, 0xB4, 0xA5, 0xB5, 0xA6, 0xB6, 0x87, 0x97, 0xA7, + 0xB7, 0xC7, 0x88, 0x98, 0xA8, 0xC8, 0x69, 0x79, 0x89, 0x99, 0xA9, 0xC9, + 0x5A, 0x6A, 0x7A, 0x9A, 0xCA, 0xFA, 0x4B, 0x5B, 0x6B, 0x7B, 0xCB, 0xFB, + 0x7C, 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xEC, 0xFC, 0xDD, 0xED, 0xFD, 0xDE, + 0xEE, 0xFE, 0xBF, 0xCF, 0xDF, 0xEF, 0xB8, 0xB9, 0x8A, 0xAA, 0xBA, 0x8B, + 0x9B, 0xAB, 0xBB, 0xFF +}; + +static const uint8_t huff_b32_cb[12] = { + 2, 11, 1, 0, 4, 6, 7, 10, 22, 11, 16, 4 +}; + +static const uint8_t huff_b32_xlat[81] = { + 0x00, 0x40, 0x10, 0x04, 0x01, 0x50, 0x44, 0x14, 0x41, 0x11, 0x05, 0x80, + 0x54, 0x51, 0x45, 0x15, 0x55, 0x02, 0x90, 0x20, 0x60, 0x84, 0x24, 0x08, + 0x18, 0x09, 0x12, 0x06, 0xA0, 0x94, 0x64, 0x48, 0x58, 0x81, 0x91, 0x21, + 0x61, 0x85, 0x95, 0x25, 0x65, 0x49, 0x19, 0x59, 0x42, 0x52, 0x46, 0x16, + 0x56, 0x0A, 0xA4, 0x28, 0x68, 0xA1, 0xA5, 0x29, 0x69, 0x26, 0x4A, 0x1A, + 0x5A, 0x88, 0x98, 0xA8, 0x89, 0x99, 0xA9, 0x82, 0x92, 0x22, 0x62, 0x86, + 0x96, 0x66, 0x9A, 0x2A, 0x6A, 0xA2, 0xA6, 0x8A, 0xAA +}; + +static const uint8_t huff_b33_cb[13] = { + 2, 12, 1, 0, 0, 4, 11, 8, 28, 92, 97, 13, 2 +}; + +static const uint8_t huff_b33_xlat[256] = { + 0x00, 0x40, 0x10, 0x04, 0x01, 0x50, 0x44, 0x14, 0x54, 0x41, 0x11, 0x51, + 0x05, 0x45, 0x15, 0x55, 0x20, 0x95, 0x65, 0x49, 0x59, 0x52, 0x46, 0x16, + 0x80, 0x90, 0x60, 0x84, 0x94, 0x24, 0x64, 0xA4, 0x08, 0x48, 0x18, 0x58, + 0x81, 0x91, 0x21, 0x61, 0x85, 0x25, 0x09, 0x19, 0x69, 0x02, 0x42, 0x12, + 0x06, 0x56, 0x5A, 0x57, 0xD0, 0x74, 0x68, 0x5C, 0xC1, 0xD5, 0xA5, 0xE5, + 0x75, 0xB5, 0xF5, 0x99, 0xD9, 0xA9, 0xE9, 0x79, 0xB9, 0xF9, 0x1D, 0x5D, + 0x9D, 0xDD, 0x6D, 0xAD, 0xED, 0x7D, 0xBD, 0xFD, 0x82, 0x92, 0xD2, 0x62, + 0x96, 0xD6, 0x26, 0x66, 0xA6, 0xE6, 0x76, 0xB6, 0xF6, 0x0A, 0x4A, 0x1A, + 0x9A, 0xDA, 0x2A, 0x6A, 0xAA, 0xEA, 0x7A, 0xBA, 0xFA, 0x5E, 0x9E, 0xDE, + 0x6E, 0xAE, 0xEE, 0x7E, 0xBE, 0xFE, 0x03, 0x13, 0x53, 0x17, 0x97, 0xD7, + 0x67, 0xA7, 0xE7, 0x77, 0xB7, 0xF7, 0x5B, 0x9B, 0xDB, 0x6B, 0xAB, 0xEB, + 0x7B, 0xBB, 0xFB, 0x5F, 0x9F, 0xDF, 0x6F, 0xAF, 0xEF, 0x7F, 0xBF, 0xFF, + 0xC0, 0xA0, 0xE0, 0x30, 0xC4, 0xD4, 0xE4, 0x34, 0xB4, 0xF4, 0x88, 0xC8, + 0x98, 0xD8, 0x28, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8, 0x0C, 0x4C, 0x1C, + 0x9C, 0xDC, 0x6C, 0xAC, 0xEC, 0x7C, 0xBC, 0xFC, 0xD1, 0xA1, 0xE1, 0x31, + 0x71, 0xB1, 0xF1, 0xC5, 0x35, 0x89, 0xC9, 0x29, 0x39, 0x0D, 0x4D, 0x8D, + 0xCD, 0x2D, 0x3D, 0x22, 0xA2, 0xE2, 0x72, 0xB2, 0xF2, 0x86, 0xC6, 0x36, + 0x8A, 0xCA, 0x3A, 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x2E, 0x3E, 0x43, 0x83, + 0x93, 0xD3, 0x23, 0x63, 0xA3, 0xE3, 0x73, 0xB3, 0xF3, 0x07, 0x47, 0x87, + 0xC7, 0x27, 0x37, 0x4B, 0x8B, 0xCB, 0x1B, 0x2B, 0x3B, 0x4F, 0x8F, 0xCF, + 0x1F, 0x70, 0xB0, 0xF0, 0x8C, 0xCC, 0x2C, 0x3C, 0xC2, 0x32, 0xC3, 0x0F, + 0x2F, 0x3F, 0x33, 0x0B +}; + +static const uint8_t huff_b35_cb[14] = { + 1, 12, 1, 0, 0, 0, 4, 6, 6, 14, 42, 63, 59, 30 +}; + +static const uint8_t huff_b35_xlat[225] = { + 0x00, 0x10, 0xF0, 0x01, 0x0F, 0x11, 0xF1, 0x02, 0x0E, 0x1F, 0xFF, 0x20, + 0xE0, 0x21, 0xF2, 0xFE, 0xEF, 0x30, 0xD0, 0xE1, 0x12, 0x22, 0xE2, 0x03, + 0x0D, 0x1D, 0x1E, 0x2E, 0xEE, 0x2F, 0xDF, 0x40, 0x60, 0x70, 0x90, 0xA0, + 0xB0, 0xC0, 0x31, 0x71, 0x91, 0xC1, 0xD1, 0x32, 0xD2, 0x13, 0xE3, 0xF3, + 0x04, 0x05, 0x06, 0x07, 0x17, 0xF7, 0x09, 0x19, 0x0A, 0x1A, 0xFA, 0x0C, + 0x1C, 0x2D, 0xED, 0xFD, 0x3E, 0x7E, 0xDE, 0x3F, 0x6F, 0x7F, 0x9F, 0xAF, + 0xCF, 0x50, 0x41, 0x51, 0x61, 0xA1, 0xB1, 0x62, 0x72, 0x92, 0xA2, 0xC2, + 0x23, 0x33, 0x63, 0x73, 0x93, 0xA3, 0xD3, 0x14, 0x24, 0x34, 0xD4, 0xE4, + 0xF4, 0x15, 0xF5, 0x16, 0x26, 0xD6, 0xE6, 0xF6, 0x27, 0x37, 0x47, 0xE7, + 0x29, 0x39, 0xC9, 0xD9, 0xE9, 0xF9, 0x2A, 0xEA, 0x0B, 0x1B, 0xFB, 0x2C, + 0x7C, 0xEC, 0xFC, 0x3D, 0x4D, 0x6D, 0x7D, 0xDD, 0x4E, 0x5E, 0x6E, 0x9E, + 0xAE, 0xCE, 0x4F, 0x5F, 0x42, 0x52, 0xB2, 0x43, 0xB3, 0xC3, 0x44, 0x64, + 0x74, 0x94, 0xA4, 0x25, 0x35, 0x65, 0x75, 0x95, 0xA5, 0xE5, 0x36, 0x46, + 0x66, 0x76, 0x96, 0xA6, 0xB6, 0xC6, 0x57, 0xA7, 0xB7, 0xC7, 0xD7, 0x59, + 0xA9, 0xB9, 0x3A, 0x4A, 0x6A, 0xCA, 0xDA, 0x2B, 0x3B, 0x6B, 0x9B, 0xAB, + 0xDB, 0xEB, 0x3C, 0x6C, 0x9C, 0xAC, 0xCC, 0xDC, 0x5D, 0x9D, 0xAD, 0xBD, + 0xCD, 0xBE, 0xBF, 0x53, 0x54, 0xB4, 0xC4, 0x45, 0x55, 0xB5, 0xC5, 0xD5, + 0x56, 0x67, 0x77, 0x97, 0x49, 0x69, 0x79, 0x99, 0x5A, 0x7A, 0x9A, 0xAA, + 0xBA, 0x4B, 0x5B, 0x7B, 0xBB, 0xCB, 0x4C, 0x5C, 0xBC +}; + +static const uint8_t huff_b37_cb[13] = { + 1, 11, 1, 0, 2, 0, 2, 2, 6, 17, 14, 13, 6 +}; + +static const uint8_t huff_b37_xlat[63] = { + 0, 1, 63, 2, 62, 3, 61, 4, 5, 6, 58, 59, 60, 7, 8, 9, + 10, 25, 26, 27, 28, 29, 34, 35, 37, 38, 39, 55, 56, 57, 11, 13, + 14, 15, 30, 31, 33, 36, 49, 50, 51, 52, 53, 54, 12, 16, 17, 18, + 19, 21, 41, 43, 44, 45, 46, 47, 48, 20, 22, 23, 24, 40, 42 +}; + +static const uint8_t huff_b41_cb[14] = { + 1, 12, 1, 0, 0, 1, 7, 0, 20, 4, 10, 24, 2, 12 +}; + +static const uint8_t huff_b41_xlat[81] = { + 0x00, 0x01, 0x40, 0xC0, 0x10, 0x30, 0x04, 0x0C, 0x03, 0x50, 0xD0, 0x70, + 0xF0, 0xC4, 0x14, 0x34, 0x4C, 0x1C, 0x3C, 0xC1, 0x11, 0x31, 0x05, 0x0D, + 0xC3, 0x13, 0x33, 0x07, 0x0F, 0x44, 0xCC, 0x41, 0x43, 0x54, 0x74, 0xDC, + 0xFC, 0x71, 0x15, 0x4D, 0x1D, 0x37, 0x3F, 0xD4, 0xF4, 0x5C, 0x7C, 0x51, + 0xD1, 0xF1, 0x45, 0xC5, 0x35, 0xCD, 0xDD, 0x3D, 0x53, 0xD3, 0x73, 0xF3, + 0x47, 0xC7, 0x17, 0x77, 0x4F, 0xCF, 0x1F, 0x55, 0xFF, 0xD5, 0x75, 0xF5, + 0x5D, 0x7D, 0xFD, 0x57, 0xD7, 0xF7, 0x5F, 0xDF, 0x7F +}; + +static const uint8_t huff_b42_cb[11] = { 1, 9, 1, 0, 1, 3, 2, 3, 7, 4, 4 }; + +static const uint8_t huff_b42_xlat[25] = { + 0x00, 0x07, 0x08, 0x38, 0x01, 0x39, 0x0F, 0x10, 0x09, 0x3F, 0x30, 0x31, + 0x02, 0x3A, 0x06, 0x0E, 0x17, 0x11, 0x0A, 0x3E, 0x37, 0x12, 0x32, 0x16, + 0x36 +}; + +static const uint8_t huff_b43_cb[10] = { 2, 9, 1, 1, 3, 4, 9, 15, 12, 4 }; + +static const uint8_t huff_b43_xlat[49] = { + 0x00, 0x07, 0x08, 0x38, 0x01, 0x09, 0x39, 0x0F, 0x3F, 0x10, 0x30, 0x31, + 0x02, 0x3A, 0x06, 0x0E, 0x17, 0x37, 0x18, 0x28, 0x11, 0x19, 0x29, 0x0A, + 0x03, 0x0B, 0x3B, 0x05, 0x0D, 0x3D, 0x3E, 0x1F, 0x2F, 0x12, 0x1A, 0x2A, + 0x32, 0x13, 0x33, 0x15, 0x35, 0x16, 0x1E, 0x2E, 0x36, 0x1B, 0x2B, 0x1D, + 0x2D +}; + +static const uint8_t huff_b47_cb[10] = { 2, 9, 1, 1, 3, 4, 6, 14, 22, 12 }; + +static const uint8_t huff_b47_xlat[63] = { + 0, 1, 2, 62, 63, 3, 4, 60, 61, 5, 6, 7, 57, 58, 59, 8, + 9, 10, 11, 12, 26, 27, 37, 38, 52, 53, 54, 55, 56, 13, 14, 15, + 16, 17, 18, 25, 28, 29, 30, 31, 33, 34, 35, 36, 39, 46, 47, 48, + 49, 50, 51, 19, 20, 21, 22, 23, 24, 40, 41, 42, 43, 44, 45 +}; + +static const uint8_t huff_b52_cb[11] = { 1, 9, 1, 0, 1, 3, 2, 3, 7, 4, 4 }; + +static const uint8_t huff_b52_xlat[25] = { + 0x00, 0x01, 0x08, 0x38, 0x07, 0x39, 0x0F, 0x30, 0x09, 0x3F, 0x10, 0x31, + 0x02, 0x3A, 0x06, 0x0E, 0x17, 0x11, 0x0A, 0x3E, 0x37, 0x12, 0x32, 0x16, + 0x36 +}; + +static const uint8_t huff_b53_cb[7] = { 1, 5, 1, 1, 1, 0, 4 }; // same as b63!!! + +static const uint8_t huff_b53_xlat[7] = { 0, 7, 1, 2, 3, 5, 6 }; + +static const uint8_t huff_b56_cb[11] = { 1, 9, 1, 0, 2, 0, 2, 4, 11, 9, 2 }; + +static const uint8_t huff_b56_xlat[31] = { + 0, 1, 31, 2, 30, 3, 4, 13, 29, 5, 6, 7, 14, 15, 17, 18, + 19, 26, 27, 28, 8, 9, 12, 20, 21, 22, 23, 24, 25, 10, 11 +}; + +static const uint8_t huff_b62_cb[14] = { + 1, 12, 1, 0, 0, 2, 3, 5, 12, 14, 18, 15, 9, 2 +}; + +static const uint8_t huff_b62_xlat[81] = { + 0x00, 0x40, 0x01, 0x10, 0x04, 0x02, 0x80, 0x50, 0x90, 0x05, 0x06, 0x20, + 0x60, 0x44, 0x14, 0x54, 0x24, 0x08, 0x18, 0x41, 0x11, 0x15, 0x09, 0xA0, + 0x84, 0x94, 0x64, 0xA4, 0x28, 0x51, 0x45, 0x55, 0x19, 0x12, 0x16, 0x0A, + 0x1A, 0x48, 0x58, 0x68, 0x81, 0x91, 0x21, 0x61, 0x85, 0x95, 0x25, 0x65, + 0x49, 0x59, 0x29, 0x69, 0x42, 0x46, 0x56, 0x88, 0x98, 0xA8, 0xA1, 0xA5, + 0x99, 0xA9, 0x52, 0x22, 0x26, 0x66, 0x4A, 0x5A, 0x2A, 0x6A, 0x89, 0x82, + 0x92, 0x62, 0x86, 0x96, 0xA6, 0x8A, 0xAA, 0xA2, 0x9A +}; + +static const uint8_t huff_b63_cb[7] = { 1, 5, 1, 1, 1, 0, 4 }; + +static const uint8_t huff_b63_xlat[7] = { 0, 1, 7, 2, 3, 5, 6 }; + +static const uint8_t huff_b64_cb[7] = { 1, 5, 1, 1, 1, 1, 2 }; + +static const uint8_t huff_b64_xlat[6] = { 1, 0, 2, 5, 3, 4 }; + +static const uint8_t huff_b65_cb[14] = { + 1, 12, 1, 0, 0, 2, 2, 2, 6, 12, 34, 92, 54, 20 +}; + +static const uint8_t huff_b65_xlat[225] = { + 0x00, 0xF0, 0x01, 0x10, 0x0F, 0x11, 0xF1, 0x20, 0xE0, 0x02, 0x0E, 0x1F, + 0xFF, 0xD0, 0x21, 0xE1, 0x12, 0xF2, 0x07, 0x0A, 0x0D, 0x1E, 0xFE, 0x2F, + 0xEF, 0x30, 0x70, 0x90, 0xA0, 0xC0, 0x71, 0x91, 0xC1, 0xD1, 0x32, 0x92, + 0xE2, 0x03, 0x13, 0x63, 0x04, 0x06, 0xE6, 0xE7, 0xF7, 0x09, 0x19, 0x39, + 0xFA, 0x0C, 0x1C, 0xDD, 0xED, 0xFD, 0x2E, 0x7E, 0x9E, 0x3F, 0x9F, 0x40, + 0x50, 0x60, 0xB0, 0x31, 0x41, 0x61, 0xA1, 0xB1, 0x22, 0x42, 0x72, 0xA2, + 0xB2, 0xC2, 0xD2, 0x23, 0x33, 0x73, 0xA3, 0xC3, 0xD3, 0xE3, 0xF3, 0x14, + 0x24, 0x34, 0x44, 0x74, 0xD4, 0xE4, 0x05, 0x25, 0x45, 0x65, 0x95, 0xA5, + 0x16, 0x26, 0x46, 0x76, 0xA6, 0xB6, 0xC6, 0xD6, 0xF6, 0x17, 0x27, 0x37, + 0x47, 0x67, 0xA7, 0xD7, 0x29, 0x69, 0xB9, 0xD9, 0xE9, 0xF9, 0x1A, 0x2A, + 0x3A, 0x9A, 0xCA, 0xDA, 0xEA, 0x0B, 0x1B, 0x3B, 0x6B, 0xEB, 0xFB, 0x2C, + 0x6C, 0xEC, 0xFC, 0x1D, 0x2D, 0x4D, 0x6D, 0x9D, 0xAD, 0x3E, 0x4E, 0x6E, + 0xAE, 0xCE, 0xEE, 0x4F, 0x5F, 0x6F, 0xDF, 0x51, 0x52, 0x62, 0x43, 0x93, + 0xB3, 0x54, 0x94, 0xA4, 0xF4, 0x15, 0x75, 0xB5, 0xE5, 0xF5, 0x36, 0x56, + 0x66, 0x96, 0x57, 0x77, 0x49, 0x59, 0xA9, 0xC9, 0x4A, 0x5A, 0x6A, 0x7A, + 0xAA, 0xBA, 0x2B, 0x4B, 0x7B, 0x9B, 0xAB, 0xDB, 0x3C, 0x4C, 0x7C, 0x9C, + 0xAC, 0xBC, 0xCC, 0x3D, 0x5D, 0x7D, 0xBD, 0xCD, 0x5E, 0xBE, 0xDE, 0xBF, + 0xCF, 0x53, 0x64, 0xB4, 0xC4, 0x35, 0x55, 0xC5, 0xD5, 0x97, 0xB7, 0xC7, + 0x79, 0x99, 0x5B, 0xBB, 0xCB, 0x5C, 0xDC, 0x7F, 0xAF +}; + +static const uint8_t huff_b66_cb[14] = { + 1, 12, 1, 0, 0, 3, 0, 3, 3, 10, 40, 85, 61, 50 +}; + +static const uint8_t huff_b66_xlat[256] = { + 0x00, 0x10, 0x01, 0x11, 0x21, 0x02, 0x12, 0x20, 0x22, 0x13, 0x30, 0x31, + 0x41, 0xD1, 0xE1, 0x32, 0x52, 0x03, 0x23, 0x2D, 0x40, 0x50, 0x60, 0x80, + 0xD0, 0xE0, 0x51, 0x61, 0xF1, 0x42, 0x62, 0xD2, 0xE2, 0xF2, 0x33, 0x43, + 0xC3, 0xD3, 0xE3, 0x04, 0x14, 0xD4, 0xF4, 0x25, 0x35, 0x16, 0x17, 0xF7, + 0xD8, 0x1C, 0x3C, 0x0D, 0x1D, 0x3D, 0x5D, 0x0E, 0x1E, 0x2E, 0x7E, 0x2F, + 0xC0, 0xF0, 0x71, 0x81, 0x91, 0xC1, 0x72, 0x82, 0x92, 0xB2, 0xC2, 0x53, + 0x63, 0x73, 0x93, 0xA3, 0xF3, 0x24, 0x44, 0x64, 0x84, 0xA4, 0xB4, 0x05, + 0x15, 0x95, 0xD5, 0x06, 0x26, 0x36, 0x46, 0x96, 0xD6, 0xE6, 0xF6, 0x07, + 0x27, 0x37, 0xD7, 0xE7, 0x08, 0x18, 0x28, 0x38, 0xE8, 0xF8, 0x09, 0x19, + 0x29, 0xE9, 0xF9, 0x0A, 0x1A, 0xCA, 0xDA, 0xEA, 0x0B, 0x1B, 0xDB, 0xEB, + 0xFB, 0x2C, 0x4C, 0x5C, 0x7C, 0x8C, 0x4D, 0x6D, 0x8D, 0x9D, 0xFD, 0x3E, + 0x5E, 0x6E, 0x8E, 0x9E, 0xEE, 0x0F, 0x1F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F, + 0xCF, 0x70, 0xA1, 0xA2, 0x83, 0xB3, 0x34, 0x74, 0xC4, 0xE4, 0x55, 0x65, + 0x85, 0xA5, 0xC5, 0xE5, 0xF5, 0x56, 0x66, 0x76, 0x86, 0xA6, 0xC6, 0x57, + 0x67, 0x77, 0x97, 0xA7, 0x48, 0x88, 0x98, 0x49, 0x59, 0x79, 0x99, 0x3A, + 0x4A, 0x8A, 0xBA, 0xFA, 0x2B, 0x7B, 0x0C, 0xAC, 0xBC, 0xCC, 0xEC, 0x7D, + 0xAD, 0xBD, 0xDD, 0x4E, 0xBE, 0xCE, 0xFE, 0x8F, 0x9F, 0xAF, 0xBF, 0xDF, + 0xEF, 0xFF, 0x90, 0xA0, 0xB0, 0xB1, 0x54, 0x94, 0x45, 0x75, 0xB5, 0xB6, + 0x47, 0x87, 0xB7, 0xC7, 0x58, 0x68, 0x78, 0xA8, 0xB8, 0xC8, 0x39, 0x69, + 0x89, 0xA9, 0xB9, 0xC9, 0xD9, 0x2A, 0x5A, 0x6A, 0x7A, 0x9A, 0xAA, 0x3B, + 0x4B, 0x5B, 0x6B, 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0x6C, 0x9C, 0xDC, 0xFC, + 0xCD, 0xED, 0xAE, 0xDE +}; + +static const uint8_t huff_b67_cb[10] = { 2, 9, 1, 2, 1, 4, 7, 10, 26, 12 }; + +static const uint8_t huff_b67_xlat[63] = { + 0, 1, 63, 62, 2, 3, 60, 61, 4, 5, 6, 7, 57, 58, 59, 8, + 9, 10, 11, 12, 52, 53, 54, 55, 56, 13, 14, 15, 16, 17, 18, 25, + 26, 27, 28, 29, 30, 31, 33, 34, 35, 36, 37, 38, 39, 46, 47, 48, + 49, 50, 51, 19, 20, 21, 22, 23, 24, 40, 41, 42, 43, 44, 45 +}; + +static const uint8_t huff_b71_cb[14] = { + 1, 12, 1, 0, 0, 1, 7, 0, 19, 5, 13, 23, 0, 12 +}; + +static const uint8_t huff_b71_xlat[81] = { + 0x00, 0x03, 0x40, 0xC0, 0x10, 0x30, 0x04, 0x0C, 0x01, 0x50, 0xD0, 0x70, + 0xF0, 0xC4, 0x14, 0x34, 0x4C, 0x1C, 0x3C, 0xC1, 0x11, 0x31, 0x05, 0x0D, + 0x13, 0x33, 0x07, 0x0F, 0x44, 0xCC, 0x41, 0x43, 0xC3, 0x54, 0x74, 0xDC, + 0xFC, 0xF1, 0xC5, 0x15, 0x1D, 0x53, 0xC7, 0x37, 0x4F, 0x3F, 0xD4, 0xF4, + 0x5C, 0x7C, 0x51, 0xD1, 0x71, 0x45, 0x55, 0x35, 0x4D, 0xCD, 0xDD, 0x3D, + 0xD3, 0x73, 0xF3, 0x47, 0x17, 0x77, 0xCF, 0x1F, 0xFF, 0xD5, 0x75, 0xF5, + 0x5D, 0x7D, 0xFD, 0x57, 0xD7, 0xF7, 0x5F, 0xDF, 0x7F +}; + +static const uint8_t huff_b73_cb[13] = { + 1, 11, 1, 0, 0, 0, 1, 4, 9, 4, 103, 110, 24 +}; + +static const uint8_t huff_b73_xlat[256] = { + 0x00, 0x40, 0x10, 0x04, 0x01, 0x05, 0x50, 0x14, 0x54, 0x41, 0x11, 0x51, + 0x45, 0x15, 0x55, 0x44, 0x95, 0x6A, 0x03, 0x80, 0xC0, 0x90, 0xD0, 0x94, + 0xD4, 0x24, 0x64, 0x58, 0x91, 0xA1, 0x85, 0xD5, 0x25, 0x65, 0xA5, 0xE5, + 0x75, 0xB5, 0xF5, 0x19, 0x59, 0x99, 0xD9, 0x69, 0xA9, 0xE9, 0x79, 0xB9, + 0xF9, 0x4D, 0x5D, 0x9D, 0xDD, 0x6D, 0xAD, 0xED, 0x7D, 0xBD, 0xFD, 0x02, + 0x42, 0x52, 0x06, 0x46, 0x16, 0x56, 0x96, 0xD6, 0x26, 0x66, 0xA6, 0xE6, + 0x76, 0xB6, 0xF6, 0x1A, 0x5A, 0x9A, 0xDA, 0xAA, 0xEA, 0x7A, 0xBA, 0xFA, + 0x5E, 0x9E, 0xDE, 0x6E, 0xAE, 0xEE, 0x7E, 0xBE, 0xFE, 0x07, 0x47, 0x57, + 0x97, 0xD7, 0x67, 0xA7, 0xE7, 0x77, 0xB7, 0xF7, 0x5B, 0x9B, 0xDB, 0x6B, + 0xAB, 0xEB, 0x7B, 0xBB, 0xFB, 0x5F, 0x9F, 0xDF, 0x6F, 0xAF, 0xEF, 0x7F, + 0xBF, 0xFF, 0x20, 0x60, 0x70, 0xB0, 0xF0, 0x84, 0xC4, 0xA4, 0xE4, 0x74, + 0xB4, 0xF4, 0x08, 0x88, 0x18, 0x98, 0xD8, 0x68, 0xA8, 0xE8, 0x78, 0xB8, + 0xF8, 0x1C, 0x5C, 0x9C, 0xDC, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC, + 0x81, 0xD1, 0x21, 0x61, 0xE1, 0x71, 0xB1, 0xF1, 0xC5, 0x35, 0x09, 0x49, + 0x89, 0xC9, 0x29, 0x39, 0x0D, 0x8D, 0xCD, 0x1D, 0x2D, 0x3D, 0x92, 0xD2, + 0x22, 0x62, 0xA2, 0xE2, 0x72, 0xB2, 0xF2, 0x86, 0xC6, 0x36, 0x0A, 0x4A, + 0x8A, 0xCA, 0x2A, 0x3A, 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x2E, 0x3E, 0x13, + 0x53, 0x93, 0xD3, 0x63, 0xA3, 0xE3, 0x73, 0xB3, 0xF3, 0x87, 0xC7, 0x17, + 0x27, 0x37, 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x2B, 0x3B, 0x0F, 0x4F, 0x8F, + 0xCF, 0x1F, 0x2F, 0x3F, 0xA0, 0xE0, 0x30, 0x34, 0x48, 0xC8, 0x28, 0x38, + 0x0C, 0x4C, 0x8C, 0xCC, 0x2C, 0xC1, 0x31, 0x82, 0xC2, 0x12, 0x32, 0x43, + 0x83, 0xC3, 0x23, 0x33 +}; + +static const uint8_t huff_b74_cb[8] = { 1, 6, 1, 0, 2, 2, 2, 4 }; + +static const uint8_t huff_b74_xlat[11] = { + 0, 1, 15, 2, 14, 5, 13, 3, 4, 11, 12 +}; + +static const uint8_t huff_b75_cb[13] = { + 2, 12, 1, 4, 0, 0, 0, 8, 11, 24, 53, 64, 60 +}; + +static const uint8_t huff_b75_xlat[225] = { + 0x00, 0x10, 0xF0, 0x01, 0x0F, 0x20, 0xE0, 0x11, 0xF1, 0x02, 0x0E, 0x1F, + 0xFF, 0xD0, 0x21, 0xE1, 0x12, 0xF2, 0x03, 0x0D, 0x1E, 0xFE, 0x2F, 0xEF, + 0x30, 0x40, 0x60, 0x70, 0x90, 0xA0, 0xC0, 0x31, 0xD1, 0x22, 0xE2, 0x13, + 0xF3, 0x04, 0x06, 0x07, 0x09, 0x0C, 0x1D, 0xFD, 0x2E, 0xEE, 0x3F, 0xDF, + 0x50, 0xB0, 0x41, 0x61, 0x71, 0x91, 0xA1, 0xC1, 0x32, 0x62, 0x72, 0x92, + 0xA2, 0xD2, 0x23, 0xD3, 0xE3, 0x14, 0xF4, 0x05, 0x16, 0x26, 0xE6, 0xF6, + 0x17, 0x27, 0xE7, 0xF7, 0x19, 0x29, 0xF9, 0x0A, 0x1A, 0x2A, 0xFA, 0x0B, + 0x1C, 0x2C, 0xFC, 0x2D, 0x3D, 0xED, 0x3E, 0x4E, 0x7E, 0x9E, 0xDE, 0x4F, + 0x6F, 0x7F, 0x9F, 0xAF, 0xCF, 0x51, 0xB1, 0x42, 0x52, 0xB2, 0xC2, 0x33, + 0x63, 0x73, 0x93, 0xA3, 0xB3, 0xC3, 0x24, 0x34, 0x74, 0xA4, 0xD4, 0xE4, + 0x15, 0x25, 0x65, 0x95, 0xE5, 0xF5, 0x36, 0xD6, 0x37, 0x47, 0xC7, 0xD7, + 0x39, 0x59, 0xB9, 0xC9, 0xD9, 0xE9, 0x3A, 0x6A, 0xDA, 0xEA, 0x1B, 0x2B, + 0x9B, 0xAB, 0xEB, 0xFB, 0x6C, 0x7C, 0x9C, 0xAC, 0xEC, 0x4D, 0x6D, 0x7D, + 0x9D, 0xAD, 0xBD, 0xDD, 0x5E, 0x6E, 0xAE, 0xCE, 0x5F, 0x43, 0x53, 0x44, + 0x54, 0x64, 0x94, 0xB4, 0xC4, 0x35, 0x45, 0x55, 0x75, 0xA5, 0xB5, 0xC5, + 0xD5, 0x46, 0x56, 0x66, 0x76, 0x96, 0xA6, 0xB6, 0xC6, 0x57, 0x67, 0x77, + 0x97, 0xA7, 0xB7, 0x49, 0x69, 0x79, 0x99, 0xA9, 0x4A, 0x5A, 0x7A, 0x9A, + 0xAA, 0xBA, 0xCA, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B, 0xBB, 0xCB, 0xDB, 0x3C, + 0x4C, 0x5C, 0xBC, 0xCC, 0xDC, 0x5D, 0xCD, 0xBE, 0xBF +}; + +static const uint8_t huff_b77_cb[12] = { + 2, 11, 1, 0, 4, 6, 10, 12, 7, 15, 4, 4 +}; + +static const uint8_t huff_b77_xlat[63] = { + 0, 1, 2, 62, 63, 3, 4, 5, 59, 60, 61, 6, 7, 8, 9, 10, + 54, 55, 56, 57, 58, 11, 12, 13, 14, 15, 16, 47, 49, 50, 51, 52, + 53, 17, 18, 19, 20, 45, 46, 48, 21, 22, 23, 24, 25, 26, 27, 37, + 38, 39, 40, 41, 42, 43, 44, 28, 29, 30, 35, 31, 33, 34, 36 +}; + +/** Tables for spectrum coding. */ +typedef struct Atrac3pSpecCodeTab { + uint8_t group_size; ///< number of coefficients grouped together + uint8_t num_coeffs; ///< 1 - map index to a single value, > 1 - map index to a vector of values + uint8_t bits; ///< number of bits a single coefficient occupy + uint8_t is_signed; ///< 1 - values in that table are signed ones, otherwise - absolute ones + + int redirect; ///< if >= 0: tells which huffman table must be reused + const uint8_t *cb; ///< pointer to the codebook descriptor + const uint8_t *xlat; ///< pointer to the translation table or NULL if none +} Atrac3pSpecCodeTab; + +static const Atrac3pSpecCodeTab atrac3p_spectra_tabs[112] = { + /* table set = A */ + /* code table = 0 */ + { 1, 4, 2, 1, -1, huff_a01_cb, huff_a01_xlat }, // wordlen = 1 + { 1, 4, 2, 0, -1, huff_a02_cb, huff_a02_xlat }, // wordlen = 2 + { 1, 2, 3, 1, -1, huff_a03_cb, huff_a03_xlat }, // wordlen = 3 + { 1, 1, 3, 0, -1, huff_a04_cb, huff_a04_xlat }, // wordlen = 4 + { 1, 2, 4, 1, -1, huff_a05_cb, huff_a05_xlat }, // wordlen = 5 + { 1, 1, 4, 0, -1, huff_a06_cb, huff_a06_xlat }, // wordlen = 6 + { 1, 1, 6, 1, -1, huff_a07_cb, huff_a07_xlat }, // wordlen = 7 + + /* code table = 1 */ + { 4, 4, 2, 1, -1, huff_a11_cb, huff_a11_xlat }, // wordlen = 1 + { 1, 4, 2, 0, -1, huff_a12_cb, huff_a12_xlat }, // wordlen = 2 + { 1, 2, 3, 1, -1, huff_a13_cb, huff_a13_xlat }, // wordlen = 3 + { 1, 2, 4, 1, -1, huff_a14_cb, huff_a14_xlat }, // wordlen = 4 + { 1, 2, 4, 1, -1, huff_a15_cb, huff_a15_xlat }, // wordlen = 5 + { 1, 2, 4, 0, -1, huff_a16_cb, huff_a16_xlat }, // wordlen = 6 + { 1, 1, 6, 1, -1, huff_a17_cb, huff_a17_xlat }, // wordlen = 7 + + /* code table = 2 */ + { 1, 4, 2, 1, -1, huff_a21_cb, huff_a21_xlat }, // wordlen = 1 + { 1, 2, 3, 1, -1, huff_a22_cb, huff_a22_xlat }, // wordlen = 2 + { 1, 2, 3, 1, -1, huff_a23_cb, huff_a23_xlat }, // wordlen = 3 + { 1, 1, 3, 0, -1, huff_a24_cb, NULL }, // wordlen = 4 + { 1, 1, 3, 0, -1, huff_a25_cb, huff_a25_xlat }, // wordlen = 5 + { 1, 2, 4, 0, -1, huff_a26_cb, huff_a26_xlat }, // wordlen = 6 + { 1, 1, 6, 1, -1, huff_a27_cb, huff_a27_xlat }, // wordlen = 7 + + /* code table = 3 */ + { 1, 2, 2, 1, -1, huff_a31_cb, huff_a31_xlat }, // wordlen = 1 + { 1, 4, 2, 0, -1, huff_a32_cb, huff_a32_xlat }, // wordlen = 2 + { 1, 4, 2, 0, -1, huff_a33_cb, huff_a33_xlat }, // wordlen = 3 + { 1, 1, 3, 0, -1, huff_a34_cb, huff_a34_xlat }, // wordlen = 4 + { 1, 2, 4, 1, -1, huff_a35_cb, huff_a35_xlat }, // wordlen = 5 + { 1, 2, 4, 0, -1, huff_a36_cb, huff_a36_xlat }, // wordlen = 6 + { 1, 1, 6, 1, -1, huff_a37_cb, huff_a37_xlat }, // wordlen = 7 + + /* code table = 4 */ + { 1, 4, 2, 1, -1, huff_a41_cb, huff_a41_xlat }, // wordlen = 1 + { 1, 4, 2, 0, -1, huff_a42_cb, huff_a42_xlat }, // wordlen = 2 + { 1, 1, 3, 1, -1, huff_a43_cb, huff_a43_xlat }, // wordlen = 3 + { 1, 2, 4, 1, -1, huff_a44_cb, huff_a44_xlat }, // wordlen = 4 + { 1, 1, 3, 0, -1, huff_a45_cb, huff_a45_xlat }, // wordlen = 5 + { 1, 2, 4, 0, -1, huff_a46_cb, huff_a46_xlat }, // wordlen = 6 + { 1, 1, 6, 1, -1, huff_a47_cb, huff_a47_xlat }, // wordlen = 7 + + /* code table = 5 */ + { 1, 4, 2, 1, -1, huff_a51_cb, huff_a51_xlat }, // wordlen = 1 + { 1, 2, 3, 1, -1, huff_a52_cb, huff_a52_xlat }, // wordlen = 2 + { 1, 1, 3, 1, -1, huff_a43_cb, huff_a53_xlat }, // wordlen = 3 + { 1, 2, 4, 1, -1, huff_a54_cb, huff_a54_xlat }, // wordlen = 4 + { 1, 1, 3, 0, -1, huff_a55_cb, huff_a55_xlat }, // wordlen = 5 + { 1, 1, 5, 1, -1, huff_a56_cb, huff_a56_xlat }, // wordlen = 6 + { 1, 1, 6, 1, -1, huff_a57_cb, huff_a57_xlat }, // wordlen = 7 + + /* code table = 6 */ + { 2, 4, 2, 1, -1, huff_a61_cb, huff_a61_xlat }, // wordlen = 1 + { 1, 2, 3, 1, -1, huff_a62_cb, huff_a62_xlat }, // wordlen = 2 + { 1, 4, 2, 0, -1, huff_a63_cb, huff_a63_xlat }, // wordlen = 3 + { 1, 2, 4, 1, -1, huff_a64_cb, huff_a64_xlat }, // wordlen = 4 + { 1, 1, 4, 1, -1, huff_a65_cb, huff_a65_xlat }, // wordlen = 5 + { 1, 1, 5, 1, -1, huff_a66_cb, huff_a66_xlat }, // wordlen = 6 + { 1, 1, 6, 1, -1, huff_a67_cb, huff_a67_xlat }, // wordlen = 7 + + /* code table = 7 */ + { 1, 2, 1, 0, -1, huff_a71_cb, NULL }, // wordlen = 1 + { 2, 4, 2, 0, -1, huff_a72_cb, huff_a72_xlat }, // wordlen = 2 + { 1, 2, 3, 1, -1, huff_a73_cb, huff_a73_xlat }, // wordlen = 3 + { 1, 2, 4, 1, -1, huff_a74_cb, huff_a74_xlat }, // wordlen = 4 + { 1, 1, 4, 1, -1, huff_a75_cb, huff_a75_xlat }, // wordlen = 5 + { 2, 2, 4, 0, -1, huff_a76_cb, huff_a76_xlat }, // wordlen = 6 + { 4, 1, 6, 1, 6, NULL, NULL }, // wordlen = 7 + + /* table set = B */ + /* code table = 0 */ + { 4, 4, 2, 1, -1, huff_b01_cb, huff_b01_xlat }, // wordlen = 1 + { 1, 4, 2, 0, -1, huff_b02_cb, huff_b02_xlat }, // wordlen = 2 + { 4, 2, 3, 1, -1, huff_b03_cb, huff_b03_xlat }, // wordlen = 3 + { 1, 2, 4, 1, -1, huff_b04_cb, huff_b04_xlat }, // wordlen = 4 + { 1, 2, 4, 1, -1, huff_b05_cb, huff_b05_xlat }, // wordlen = 5 + { 1, 1, 4, 0, 5, NULL, NULL }, // wordlen = 6 + { 1, 1, 6, 1, -1, huff_b07_cb, huff_b07_xlat }, // wordlen = 7 + + /* code table = 1 */ + { 1, 4, 2, 1, 14, NULL, NULL }, // wordlen = 1 + { 1, 4, 2, 0, -1, huff_b12_cb, huff_b12_xlat }, // wordlen = 2 + { 1, 2, 3, 1, 9, NULL, NULL }, // wordlen = 3 + { 1, 2, 4, 1, -1, huff_b14_cb, huff_b14_xlat }, // wordlen = 4 + { 1, 2, 4, 1, 11, NULL, NULL }, // wordlen = 5 + { 1, 2, 4, 0, -1, huff_b16_cb, huff_b16_xlat }, // wordlen = 6 + { 1, 1, 6, 1, 6, NULL, NULL }, // wordlen = 7 + + /* code table = 2 */ + { 4, 4, 2, 1, 28, NULL, NULL }, // wordlen = 1 + { 4, 4, 2, 0, 22, NULL, NULL }, // wordlen = 2 + { 1, 2, 3, 1, 2, NULL, NULL }, // wordlen = 3 + { 1, 2, 4, 1, 31, NULL, NULL }, // wordlen = 4 + { 2, 2, 4, 1, 60, NULL, NULL }, // wordlen = 5 + { 2, 2, 4, 0, -1, huff_b26_cb, huff_b26_xlat }, // wordlen = 6 + { 4, 1, 6, 1, 6, NULL, NULL }, // wordlen = 7 + + /* code table = 3 */ + { 1, 4, 2, 1, 35, NULL, NULL }, // wordlen = 1 + { 1, 4, 2, 0, -1, huff_b32_cb, huff_b32_xlat }, // wordlen = 2 + { 1, 4, 2, 0, -1, huff_b33_cb, huff_b33_xlat }, // wordlen = 3 + { 2, 2, 4, 1, 59, NULL, NULL }, // wordlen = 4 + { 1, 2, 4, 1, -1, huff_b35_cb, huff_b35_xlat }, // wordlen = 5 + { 1, 2, 4, 0, 75, NULL, NULL }, // wordlen = 6 + { 1, 1, 6, 1, -1, huff_b37_cb, huff_b37_xlat }, // wordlen = 7 + + /* code table = 4 */ + { 1, 4, 2, 1, -1, huff_b41_cb, huff_b41_xlat }, // wordlen = 1 + { 4, 2, 3, 1, -1, huff_b42_cb, huff_b42_xlat }, // wordlen = 2 + { 1, 2, 3, 1, -1, huff_b43_cb, huff_b43_xlat }, // wordlen = 3 + { 4, 2, 4, 1, 66, NULL, NULL }, // wordlen = 4 + { 1, 1, 3, 0, 32, NULL, NULL }, // wordlen = 5 + { 1, 2, 4, 0, 12, NULL, NULL }, // wordlen = 6 + { 1, 1, 6, 1, -1, huff_b47_cb, huff_b47_xlat }, // wordlen = 7 + + /* code table = 5 */ + { 2, 4, 2, 1, 42, NULL, NULL }, // wordlen = 1 + { 1, 2, 3, 1, -1, huff_b52_cb, huff_b52_xlat }, // wordlen = 2 + { 4, 1, 3, 1, -1, huff_b53_cb, huff_b53_xlat }, // wordlen = 3 + { 1, 1, 3, 0, 17, NULL, NULL }, // wordlen = 4 + { 1, 1, 3, 0, 39, NULL, NULL }, // wordlen = 5 + { 1, 1, 5, 1, -1, huff_b56_cb, huff_b56_xlat }, // wordlen = 6 + { 2, 1, 6, 1, 62, NULL, NULL }, // wordlen = 7 + + /* code table = 6 */ + { 1, 4, 2, 1, 28, NULL, NULL }, // wordlen = 1 + { 1, 4, 2, 0, -1, huff_b62_cb, huff_b62_xlat }, // wordlen = 2 + { 1, 1, 3, 1, -1, huff_b63_cb, huff_b63_xlat }, // wordlen = 3 + { 1, 1, 3, 0, -1, huff_b64_cb, huff_b64_xlat }, // wordlen = 4 + { 4, 2, 4, 1, -1, huff_b65_cb, huff_b65_xlat }, // wordlen = 5 + { 1, 2, 4, 0, -1, huff_b66_cb, huff_b66_xlat }, // wordlen = 6 + { 1, 1, 6, 1, -1, huff_b67_cb, huff_b67_xlat }, // wordlen = 7 + + /* code table = 7 */ + { 1, 4, 2, 1, -1, huff_b71_cb, huff_b71_xlat }, // wordlen = 1 + { 4, 4, 2, 0, 78, NULL, NULL }, // wordlen = 2 + { 4, 4, 2, 0, -1, huff_b73_cb, huff_b73_xlat }, // wordlen = 3 + { 1, 1, 4, 1, -1, huff_b74_cb, huff_b74_xlat }, // wordlen = 4 + { 1, 2, 4, 1, -1, huff_b75_cb, huff_b75_xlat }, // wordlen = 5 + { 1, 1, 5, 1, 47, NULL, NULL }, // wordlen = 6 + { 1, 1, 6, 1, -1, huff_b77_cb, huff_b77_xlat }, // wordlen = 7 +}; + +/* Huffman tables for gain control data. */ +static const uint8_t atrac3p_huff_gain_npoints1_cb[9] = { + 1, 7, 1, 1, 1, 1, 1, 1, 2 +}; + +static const uint8_t atrac3p_huff_gain_npoints2_xlat[8] = { + 0, 1, 7, 2, 6, 3, 4, 5 +}; + +static const uint8_t atrac3p_huff_gain_lev1_cb[9] = { 1, 7, 1, 0, 2, 2, 1, 2, 8 }; +static const uint8_t atrac3p_huff_gain_lev1_xlat[16] = { + 7, 5, 8, 6, 9, 4, 10, 11, 0, 1, 2, 3, 12, 13, 14, 15 +}; + +static const uint8_t atrac3p_huff_gain_lev2_cb[11] = { + 1, 9, 1, 1, 1, 1, 1, 0, 2, 0, 8 +}; + +static const uint8_t atrac3p_huff_gain_lev2_xlat[15] = { + 15, 14, 1, 13, 2, 3, 12, 4, 5, 6, 7, 8, 9, 10, 11 +}; + +static const uint8_t atrac3p_huff_gain_lev3_cb[11] = { + 1, 9, 1, 0, 3, 1, 1, 0, 2, 0, 8 +}; + +static const uint8_t atrac3p_huff_gain_lev3_xlat[16] = { + 0, 1, 14, 15, 2, 13, 3, 12, 4, 5, 6, 7, 8, 9, 10, 11 +}; + +static const uint8_t atrac3p_huff_gain_lev4_cb[11] = { + 1, 9, 1, 1, 1, 1, 1, 0, 1, 2, 8 +}; + +static const uint8_t atrac3p_huff_gain_lev4_xlat[16] = { + 0, 1, 15, 14, 2, 13, 3, 12, 4, 5, 6, 7, 8, 9, 10, 11 +}; + +static const uint8_t atrac3p_huff_gain_loc1_cb[9] = { 2, 8, 1, 2, 4, 4, 4, 0, 16 }; +static const uint8_t atrac3p_huff_gain_loc1_xlat[31] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 +}; + +static const uint8_t atrac3p_huff_gain_loc2_cb[8] = { 3, 8, 5, 3, 2, 3, 2, 16 }; +static const uint8_t atrac3p_huff_gain_loc2_xlat[31] = { + 2, 3, 4, 5, 6, 1, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 +}; + +static const uint8_t atrac3p_huff_gain_loc3_cb[7] = { 2, 6, 1, 0, 2, 11, 18 }; +static const uint8_t atrac3p_huff_gain_loc3_xlat[32] = { + 0, 1, 31, 2, 3, 4, 5, 6, 7, 26, 27, 28, 29, 30, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 +}; + +static const uint8_t atrac3p_huff_gain_loc4_cb[5] = { 4, 6, 3, 23, 6 }; +static const uint8_t atrac3p_huff_gain_loc4_xlat[32] = { + 0, 28, 29, 1, 2, 3, 4, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 30, 31, 5, 6, 7, 8, 9, 10 +}; + +static const uint8_t atrac3p_huff_gain_loc5_cb[9] = { 1, 7, 1, 0, 0, 3, 2, 6, 20 }; +static const uint8_t atrac3p_huff_gain_loc5_xlat[32] = { + 0, 1, 2, 31, 3, 4, 5, 6, 7, 8, 29, 30, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28 +}; + +/* Huffman tables for GHA waves data. */ +static const uint8_t atrac3p_huff_tonebands_cb[8] = { 1, 6, 1, 0, 1, 2, 4, 8 }; +static const uint8_t atrac3p_huff_numwavs1_cb[9] = { 1, 7, 1, 1, 1, 1, 1, 1, 2 }; +static const uint8_t atrac3p_huff_numwavs2_cb[8] = { 1, 6, 1, 1, 1, 1, 0, 4 }; +static const uint8_t atrac3p_huff_numwavs2_xlat[8] = { 0, 1, 7, 2, 3, 4, 5, 6 }; +static const uint8_t atrac3p_huff_wav_ampsf1_cb[7] = { 4, 8, 10, 8, 6, 0, 8 }; +static const uint8_t atrac3p_huff_wav_ampsf1_xlat[32] = { + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 5, 6, 7, 18, 19, 20, + 21, 22, 4, 23, 24, 25, 26, 27, 0, 1, 2, 3, 28, 29, 30, 31 +}; + +static const uint8_t atrac3p_huff_wav_ampsf2_cb[7] = { 4, 8, 11, 5, 6, 6, 4 }; +static const uint8_t atrac3p_huff_wav_ampsf2_xlat[32] = { + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 14, 15, 16, 17, 29, + 9, 10, 11, 12, 13, 30, 4, 5, 6, 7, 8, 31, 0, 1, 2, 3 +}; + +static const uint8_t atrac3p_huff_wav_ampsf3_cb[9] = { 2, 8, 1, 3, 3, 1, 4, 4, 16 }; +static const uint8_t atrac3p_huff_wav_ampsf3_xlat[32] = { + 0, 1, 2, 31, 3, 29, 30, 4, 5, 6, 27, 28, 7, 24, 25, 26, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 +}; + +static const uint8_t atrac3p_huff_freq_cb[13] = { + 1, 11, 1, 0, 0, 2, 2, 0, 9, 9, 29, 104, 100 +}; + +static const uint8_t atrac3p_huff_freq_xlat[256] = { + 0, 1, 255, 2, 254, 3, 4, 5, 6, 7, 8, 251, 252, 253, 9, 10, + 11, 12, 246, 247, 248, 249, 250, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 243, 244, 245, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, + 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193 +}; + +#endif /* AVCODEC_ATRAC3PLUS_DATA_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/atrac3plusdec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/atrac3plusdec.c new file mode 100644 index 000000000..652bd7890 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/atrac3plusdec.c @@ -0,0 +1,396 @@ +/* + * ATRAC3+ compatible decoder + * + * Copyright (c) 2010-2013 Maxim Poliakovski + * + * 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 + * Sony ATRAC3+ compatible decoder. + * + * Container formats used to store its data: + * RIFF WAV (.at3) and Sony OpenMG (.oma, .aa3). + * + * Technical description of this codec can be found here: + * http://wiki.multimedia.cx/index.php?title=ATRAC3plus + * + * Kudos to Benjamin Larsson and Michael Karcher + * for their precious technical help! + */ + +#include +#include + +#include "libavutil/channel_layout.h" +#include "libavutil/float_dsp.h" +#include "avcodec.h" +#include "get_bits.h" +#include "internal.h" +#include "atrac.h" +#include "atrac3plus.h" + +typedef struct ATRAC3PContext { + GetBitContext gb; + AVFloatDSPContext fdsp; + + DECLARE_ALIGNED(32, float, samples)[2][ATRAC3P_FRAME_SAMPLES]; ///< quantized MDCT spectrum + DECLARE_ALIGNED(32, float, mdct_buf)[2][ATRAC3P_FRAME_SAMPLES]; ///< output of the IMDCT + DECLARE_ALIGNED(32, float, time_buf)[2][ATRAC3P_FRAME_SAMPLES]; ///< output of the gain compensation + DECLARE_ALIGNED(32, float, outp_buf)[2][ATRAC3P_FRAME_SAMPLES]; + + AtracGCContext gainc_ctx; ///< gain compensation context + FFTContext mdct_ctx; + FFTContext ipqf_dct_ctx; ///< IDCT context used by IPQF + + Atrac3pChanUnitCtx *ch_units; ///< global channel units + + int num_channel_blocks; ///< number of channel blocks + uint8_t channel_blocks[5]; ///< channel configuration descriptor + uint64_t my_channel_layout; ///< current channel layout +} ATRAC3PContext; + +static av_cold int atrac3p_decode_close(AVCodecContext *avctx) +{ + av_free(((ATRAC3PContext *)(avctx->priv_data))->ch_units); + + return 0; +} + +static av_cold int set_channel_params(ATRAC3PContext *ctx, + AVCodecContext *avctx) +{ + memset(ctx->channel_blocks, 0, sizeof(ctx->channel_blocks)); + + switch (avctx->channels) { + case 1: + if (avctx->channel_layout != AV_CH_FRONT_LEFT) + avctx->channel_layout = AV_CH_LAYOUT_MONO; + + ctx->num_channel_blocks = 1; + ctx->channel_blocks[0] = CH_UNIT_MONO; + break; + case 2: + avctx->channel_layout = AV_CH_LAYOUT_STEREO; + ctx->num_channel_blocks = 1; + ctx->channel_blocks[0] = CH_UNIT_STEREO; + break; + case 3: + avctx->channel_layout = AV_CH_LAYOUT_SURROUND; + ctx->num_channel_blocks = 2; + ctx->channel_blocks[0] = CH_UNIT_STEREO; + ctx->channel_blocks[1] = CH_UNIT_MONO; + break; + case 4: + avctx->channel_layout = AV_CH_LAYOUT_4POINT0; + ctx->num_channel_blocks = 3; + ctx->channel_blocks[0] = CH_UNIT_STEREO; + ctx->channel_blocks[1] = CH_UNIT_MONO; + ctx->channel_blocks[2] = CH_UNIT_MONO; + break; + case 6: + avctx->channel_layout = AV_CH_LAYOUT_5POINT1_BACK; + ctx->num_channel_blocks = 4; + ctx->channel_blocks[0] = CH_UNIT_STEREO; + ctx->channel_blocks[1] = CH_UNIT_MONO; + ctx->channel_blocks[2] = CH_UNIT_STEREO; + ctx->channel_blocks[3] = CH_UNIT_MONO; + break; + case 7: + avctx->channel_layout = AV_CH_LAYOUT_6POINT1_BACK; + ctx->num_channel_blocks = 5; + ctx->channel_blocks[0] = CH_UNIT_STEREO; + ctx->channel_blocks[1] = CH_UNIT_MONO; + ctx->channel_blocks[2] = CH_UNIT_STEREO; + ctx->channel_blocks[3] = CH_UNIT_MONO; + ctx->channel_blocks[4] = CH_UNIT_MONO; + break; + case 8: + avctx->channel_layout = AV_CH_LAYOUT_7POINT1; + ctx->num_channel_blocks = 5; + ctx->channel_blocks[0] = CH_UNIT_STEREO; + ctx->channel_blocks[1] = CH_UNIT_MONO; + ctx->channel_blocks[2] = CH_UNIT_STEREO; + ctx->channel_blocks[3] = CH_UNIT_STEREO; + ctx->channel_blocks[4] = CH_UNIT_MONO; + break; + default: + av_log(avctx, AV_LOG_ERROR, + "Unsupported channel count: %d!\n", avctx->channels); + return AVERROR_INVALIDDATA; + } + + return 0; +} + +static av_cold int atrac3p_decode_init(AVCodecContext *avctx) +{ + ATRAC3PContext *ctx = avctx->priv_data; + int i, ch, ret; + + if (!avctx->block_align) { + av_log(avctx, AV_LOG_ERROR, "block_align is not set\n"); + return AVERROR(EINVAL); + } + + ff_atrac3p_init_vlcs(); + + avpriv_float_dsp_init(&ctx->fdsp, avctx->flags & CODEC_FLAG_BITEXACT); + + /* initialize IPQF */ + ff_mdct_init(&ctx->ipqf_dct_ctx, 5, 1, 32.0 / 32768.0); + + ff_atrac3p_init_imdct(avctx, &ctx->mdct_ctx); + + ff_atrac_init_gain_compensation(&ctx->gainc_ctx, 6, 2); + + ff_atrac3p_init_wave_synth(); + + if ((ret = set_channel_params(ctx, avctx)) < 0) + return ret; + + ctx->my_channel_layout = avctx->channel_layout; + + ctx->ch_units = av_mallocz(sizeof(*ctx->ch_units) * + ctx->num_channel_blocks); + if (!ctx->ch_units) { + atrac3p_decode_close(avctx); + return AVERROR(ENOMEM); + } + + for (i = 0; i < ctx->num_channel_blocks; i++) { + for (ch = 0; ch < 2; ch++) { + ctx->ch_units[i].channels[ch].ch_num = ch; + ctx->ch_units[i].channels[ch].wnd_shape = &ctx->ch_units[i].channels[ch].wnd_shape_hist[0][0]; + ctx->ch_units[i].channels[ch].wnd_shape_prev = &ctx->ch_units[i].channels[ch].wnd_shape_hist[1][0]; + ctx->ch_units[i].channels[ch].gain_data = &ctx->ch_units[i].channels[ch].gain_data_hist[0][0]; + ctx->ch_units[i].channels[ch].gain_data_prev = &ctx->ch_units[i].channels[ch].gain_data_hist[1][0]; + ctx->ch_units[i].channels[ch].tones_info = &ctx->ch_units[i].channels[ch].tones_info_hist[0][0]; + ctx->ch_units[i].channels[ch].tones_info_prev = &ctx->ch_units[i].channels[ch].tones_info_hist[1][0]; + } + + ctx->ch_units[i].waves_info = &ctx->ch_units[i].wave_synth_hist[0]; + ctx->ch_units[i].waves_info_prev = &ctx->ch_units[i].wave_synth_hist[1]; + } + + avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; + + return 0; +} + +static void decode_residual_spectrum(Atrac3pChanUnitCtx *ctx, + float out[2][ATRAC3P_FRAME_SAMPLES], + int num_channels, + AVCodecContext *avctx) +{ + int i, sb, ch, qu, nspeclines, RNG_index; + float *dst, q; + int16_t *src; + /* calculate RNG table index for each subband */ + int sb_RNG_index[ATRAC3P_SUBBANDS] = { 0 }; + + if (ctx->mute_flag) { + for (ch = 0; ch < num_channels; ch++) + memset(out[ch], 0, ATRAC3P_FRAME_SAMPLES * sizeof(*out[ch])); + return; + } + + for (qu = 0, RNG_index = 0; qu < ctx->used_quant_units; qu++) + RNG_index += ctx->channels[0].qu_sf_idx[qu] + + ctx->channels[1].qu_sf_idx[qu]; + + for (sb = 0; sb < ctx->num_coded_subbands; sb++, RNG_index += 128) + sb_RNG_index[sb] = RNG_index & 0x3FC; + + /* inverse quant and power compensation */ + for (ch = 0; ch < num_channels; ch++) { + /* clear channel's residual spectrum */ + memset(out[ch], 0, ATRAC3P_FRAME_SAMPLES * sizeof(*out[ch])); + + for (qu = 0; qu < ctx->used_quant_units; qu++) { + src = &ctx->channels[ch].spectrum[ff_atrac3p_qu_to_spec_pos[qu]]; + dst = &out[ch][ff_atrac3p_qu_to_spec_pos[qu]]; + nspeclines = ff_atrac3p_qu_to_spec_pos[qu + 1] - + ff_atrac3p_qu_to_spec_pos[qu]; + + if (ctx->channels[ch].qu_wordlen[qu] > 0) { + q = ff_atrac3p_sf_tab[ctx->channels[ch].qu_sf_idx[qu]] * + ff_atrac3p_mant_tab[ctx->channels[ch].qu_wordlen[qu]]; + for (i = 0; i < nspeclines; i++) + dst[i] = src[i] * q; + } + } + + for (sb = 0; sb < ctx->num_coded_subbands; sb++) + ff_atrac3p_power_compensation(ctx, ch, &out[ch][0], + sb_RNG_index[sb], sb); + } + + if (ctx->unit_type == CH_UNIT_STEREO) { + for (sb = 0; sb < ctx->num_coded_subbands; sb++) { + if (ctx->swap_channels[sb]) { + for (i = 0; i < ATRAC3P_SUBBAND_SAMPLES; i++) + FFSWAP(float, out[0][sb * ATRAC3P_SUBBAND_SAMPLES + i], + out[1][sb * ATRAC3P_SUBBAND_SAMPLES + i]); + } + + /* flip coefficients' sign if requested */ + if (ctx->negate_coeffs[sb]) + for (i = 0; i < ATRAC3P_SUBBAND_SAMPLES; i++) + out[1][sb * ATRAC3P_SUBBAND_SAMPLES + i] = -(out[1][sb * ATRAC3P_SUBBAND_SAMPLES + i]); + } + } +} + +static void reconstruct_frame(ATRAC3PContext *ctx, Atrac3pChanUnitCtx *ch_unit, + int num_channels, AVCodecContext *avctx) +{ + int ch, sb; + + for (ch = 0; ch < num_channels; ch++) { + for (sb = 0; sb < ch_unit->num_subbands; sb++) { + /* inverse transform and windowing */ + ff_atrac3p_imdct(&ctx->fdsp, &ctx->mdct_ctx, + &ctx->samples[ch][sb * ATRAC3P_SUBBAND_SAMPLES], + &ctx->mdct_buf[ch][sb * ATRAC3P_SUBBAND_SAMPLES], + (ch_unit->channels[ch].wnd_shape_prev[sb] << 1) + + ch_unit->channels[ch].wnd_shape[sb], sb); + + /* gain compensation and overlapping */ + ff_atrac_gain_compensation(&ctx->gainc_ctx, + &ctx->mdct_buf[ch][sb * ATRAC3P_SUBBAND_SAMPLES], + &ch_unit->prev_buf[ch][sb * ATRAC3P_SUBBAND_SAMPLES], + &ch_unit->channels[ch].gain_data_prev[sb], + &ch_unit->channels[ch].gain_data[sb], + ATRAC3P_SUBBAND_SAMPLES, + &ctx->time_buf[ch][sb * ATRAC3P_SUBBAND_SAMPLES]); + } + + /* zero unused subbands in both output and overlapping buffers */ + memset(&ch_unit->prev_buf[ch][ch_unit->num_subbands * ATRAC3P_SUBBAND_SAMPLES], + 0, + (ATRAC3P_SUBBANDS - ch_unit->num_subbands) * + ATRAC3P_SUBBAND_SAMPLES * + sizeof(ch_unit->prev_buf[ch][ch_unit->num_subbands * ATRAC3P_SUBBAND_SAMPLES])); + memset(&ctx->time_buf[ch][ch_unit->num_subbands * ATRAC3P_SUBBAND_SAMPLES], + 0, + (ATRAC3P_SUBBANDS - ch_unit->num_subbands) * + ATRAC3P_SUBBAND_SAMPLES * + sizeof(ctx->time_buf[ch][ch_unit->num_subbands * ATRAC3P_SUBBAND_SAMPLES])); + + /* resynthesize and add tonal signal */ + if (ch_unit->waves_info->tones_present || + ch_unit->waves_info_prev->tones_present) { + for (sb = 0; sb < ch_unit->num_subbands; sb++) + if (ch_unit->channels[ch].tones_info[sb].num_wavs || + ch_unit->channels[ch].tones_info_prev[sb].num_wavs) { + ff_atrac3p_generate_tones(ch_unit, &ctx->fdsp, ch, sb, + &ctx->time_buf[ch][sb * 128]); + } + } + + /* subband synthesis and acoustic signal output */ + ff_atrac3p_ipqf(&ctx->ipqf_dct_ctx, &ch_unit->ipqf_ctx[ch], + &ctx->time_buf[ch][0], &ctx->outp_buf[ch][0]); + } + + /* swap window shape and gain control buffers. */ + for (ch = 0; ch < num_channels; ch++) { + FFSWAP(uint8_t *, ch_unit->channels[ch].wnd_shape, + ch_unit->channels[ch].wnd_shape_prev); + FFSWAP(AtracGainInfo *, ch_unit->channels[ch].gain_data, + ch_unit->channels[ch].gain_data_prev); + FFSWAP(Atrac3pWavesData *, ch_unit->channels[ch].tones_info, + ch_unit->channels[ch].tones_info_prev); + } + + FFSWAP(Atrac3pWaveSynthParams *, ch_unit->waves_info, ch_unit->waves_info_prev); +} + +static int atrac3p_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame_ptr, AVPacket *avpkt) +{ + ATRAC3PContext *ctx = avctx->priv_data; + AVFrame *frame = data; + int i, ret, ch_unit_id, ch_block = 0, out_ch_index = 0, channels_to_process; + float **samples_p = (float **)frame->extended_data; + + frame->nb_samples = ATRAC3P_FRAME_SAMPLES; + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return ret; + } + + if ((ret = init_get_bits8(&ctx->gb, avpkt->data, avpkt->size)) < 0) + return ret; + + if (get_bits1(&ctx->gb)) { + av_log(avctx, AV_LOG_ERROR, "Invalid start bit!\n"); + return AVERROR_INVALIDDATA; + } + + while (get_bits_left(&ctx->gb) >= 2 && + (ch_unit_id = get_bits(&ctx->gb, 2)) != CH_UNIT_TERMINATOR) { + if (ch_unit_id == CH_UNIT_EXTENSION) { + avpriv_report_missing_feature(avctx, "Channel unit extension"); + return AVERROR_PATCHWELCOME; + } + if (ch_block >= ctx->num_channel_blocks || + ctx->channel_blocks[ch_block] != ch_unit_id) { + av_log(avctx, AV_LOG_ERROR, + "Frame data doesn't match channel configuration!\n"); + return AVERROR_INVALIDDATA; + } + + ctx->ch_units[ch_block].unit_type = ch_unit_id; + channels_to_process = ch_unit_id + 1; + + if ((ret = ff_atrac3p_decode_channel_unit(&ctx->gb, + &ctx->ch_units[ch_block], + channels_to_process, + avctx)) < 0) + return ret; + + decode_residual_spectrum(&ctx->ch_units[ch_block], ctx->samples, + channels_to_process, avctx); + reconstruct_frame(ctx, &ctx->ch_units[ch_block], + channels_to_process, avctx); + + for (i = 0; i < channels_to_process; i++) + memcpy(samples_p[out_ch_index + i], ctx->outp_buf[i], + ATRAC3P_FRAME_SAMPLES * sizeof(**samples_p)); + + ch_block++; + out_ch_index += channels_to_process; + } + + *got_frame_ptr = 1; + + return avctx->block_align; +} + +AVCodec ff_atrac3p_decoder = { + .name = "atrac3plus", + .long_name = NULL_IF_CONFIG_SMALL("ATRAC3+ (Adaptive TRansform Acoustic Coding 3+)"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_ATRAC3P, + .priv_data_size = sizeof(ATRAC3PContext), + .init = atrac3p_decode_init, + .close = atrac3p_decode_close, + .decode = atrac3p_decode_frame, +}; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/atrac3plusdsp.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/atrac3plusdsp.c new file mode 100644 index 000000000..3522af1e5 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/atrac3plusdsp.c @@ -0,0 +1,638 @@ +/* + * ATRAC3+ compatible decoder + * + * Copyright (c) 2010-2013 Maxim Poliakovski + * + * 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 + * DSP functions for ATRAC3+ decoder. + */ + +#include + +#include "libavutil/float_dsp.h" +#include "avcodec.h" +#include "sinewin.h" +#include "fft.h" +#include "atrac3plus.h" + +/** + * Map quant unit number to its position in the spectrum. + * To get the number of spectral lines in each quant unit do the following: + * num_specs = qu_to_spec_pos[i+1] - qu_to_spec_pos[i] + */ +const uint16_t ff_atrac3p_qu_to_spec_pos[33] = { + 0, 16, 32, 48, 64, 80, 96, 112, + 128, 160, 192, 224, 256, 288, 320, 352, + 384, 448, 512, 576, 640, 704, 768, 896, + 1024, 1152, 1280, 1408, 1536, 1664, 1792, 1920, + 2048 +}; + +/* Scalefactors table. */ +/* Approx. Equ: pow(2.0, (i - 16.0 + 0.501783948) / 3.0) */ +const float ff_atrac3p_sf_tab[64] = { + 0.027852058, 0.0350914, 0.044212341, 0.055704117, 0.0701828, + 0.088424683, 0.11140823, 0.1403656, 0.17684937, 0.22281647, 0.2807312, 0.35369873, + 0.44563293, 0.5614624, 0.70739746, 0.89126587, 1.1229248, 1.4147949, 1.7825317, + 2.2458496, 2.8295898, 3.5650635, 4.4916992, 5.6591797, 7.130127, 8.9833984, + 11.318359, 14.260254, 17.966797, 22.636719, 28.520508, 35.933594, 45.273438, + 57.041016, 71.867188, 90.546875, 114.08203, 143.73438, 181.09375, 228.16406, + 287.46875, 362.1875, 456.32812, 574.9375, 724.375, 912.65625, 1149.875, + 1448.75, 1825.3125, 2299.75, 2897.5, 3650.625, 4599.5, 5795.0, + 7301.25, 9199.0, 11590.0, 14602.5, 18398.0, 23180.0, 29205.0, + 36796.0, 46360.0, 58410.0 +}; + +/* Mantissa table. */ +/* pow(10, x * log10(2) + 0.05) / 2 / ([1,2,3,5,7,15,31] + 0.5) */ +const float ff_atrac3p_mant_tab[8] = { + 0.0, + 0.74801636, + 0.44882202, + 0.32058716, + 0.20400238, + 0.1496048, + 0.07239151, + 0.035619736 +}; + +#define ATRAC3P_MDCT_SIZE (ATRAC3P_SUBBAND_SAMPLES * 2) + +av_cold void ff_atrac3p_init_imdct(AVCodecContext *avctx, FFTContext *mdct_ctx) +{ + ff_init_ff_sine_windows(7); + ff_init_ff_sine_windows(6); + + /* Initialize the MDCT transform. */ + ff_mdct_init(mdct_ctx, 8, 1, -1.0); +} + +#define TWOPI (2 * M_PI) + +#define DEQUANT_PHASE(ph) (((ph) & 0x1F) << 6) + +static DECLARE_ALIGNED(32, float, sine_table)[2048]; ///< wave table +static DECLARE_ALIGNED(32, float, hann_window)[256]; ///< Hann windowing function +static float amp_sf_tab[64]; ///< scalefactors for quantized amplitudes + +av_cold void ff_atrac3p_init_wave_synth(void) +{ + int i; + + /* generate sine wave table */ + for (i = 0; i < 2048; i++) + sine_table[i] = sin(TWOPI * i / 2048); + + /* generate Hann window */ + for (i = 0; i < 256; i++) + hann_window[i] = (1.0f - cos(TWOPI * i / 256.0f)) * 0.5f; + + /* generate amplitude scalefactors table */ + for (i = 0; i < 64; i++) + amp_sf_tab[i] = pow(2.0f, ((double)i - 3) / 4.0f); +} + +/** + * Synthesize sine waves according to given parameters. + * + * @param[in] synth_param ptr to common synthesis parameters + * @param[in] waves_info parameters for each sine wave + * @param[in] envelope envelope data for all waves in a group + * @param[in] phase_shift flag indicates 180° phase shift + * @param[in] reg_offset region offset for trimming envelope data + * @param[out] out receives sythesized data + */ +static void waves_synth(Atrac3pWaveSynthParams *synth_param, + Atrac3pWavesData *waves_info, + Atrac3pWaveEnvelope *envelope, + int phase_shift, int reg_offset, float *out) +{ + int i, wn, inc, pos; + double amp; + Atrac3pWaveParam *wave_param = &synth_param->waves[waves_info->start_index]; + + for (wn = 0; wn < waves_info->num_wavs; wn++, wave_param++) { + /* amplitude dequantization */ + amp = amp_sf_tab[wave_param->amp_sf] * + (!synth_param->amplitude_mode + ? (wave_param->amp_index + 1) / 15.13f + : 1.0f); + + inc = wave_param->freq_index; + pos = DEQUANT_PHASE(wave_param->phase_index) - (reg_offset ^ 128) * inc & 2047; + + /* waveform generation */ + for (i = 0; i < 128; i++) { + out[i] += sine_table[pos] * amp; + pos = (pos + inc) & 2047; + } + } + + /* fade in with steep Hann window if requested */ + if (envelope->has_start_point) { + pos = (envelope->start_pos << 2) - reg_offset; + if (pos > 0 && pos <= 128) { + memset(out, 0, pos * sizeof(*out)); + if (!envelope->has_stop_point || + envelope->start_pos != envelope->stop_pos) { + out[pos + 0] *= hann_window[0]; + out[pos + 1] *= hann_window[32]; + out[pos + 2] *= hann_window[64]; + out[pos + 3] *= hann_window[96]; + } + } + } + + /* fade out with steep Hann window if requested */ + if (envelope->has_stop_point) { + pos = (envelope->stop_pos + 1 << 2) - reg_offset; + if (pos > 0 && pos <= 128) { + out[pos - 4] *= hann_window[96]; + out[pos - 3] *= hann_window[64]; + out[pos - 2] *= hann_window[32]; + out[pos - 1] *= hann_window[0]; + memset(&out[pos], 0, (128 - pos) * sizeof(out[pos])); + } + } +} + +void ff_atrac3p_generate_tones(Atrac3pChanUnitCtx *ch_unit, AVFloatDSPContext *fdsp, + int ch_num, int sb, float *out) +{ + DECLARE_ALIGNED(32, float, wavreg1)[128] = { 0 }; + DECLARE_ALIGNED(32, float, wavreg2)[128] = { 0 }; + int i, reg1_env_nonzero, reg2_env_nonzero; + Atrac3pWavesData *tones_now = &ch_unit->channels[ch_num].tones_info_prev[sb]; + Atrac3pWavesData *tones_next = &ch_unit->channels[ch_num].tones_info[sb]; + + /* reconstruct full envelopes for both overlapping regions + * from truncated bitstream data */ + if (tones_next->pend_env.has_start_point && + tones_next->pend_env.start_pos < tones_next->pend_env.stop_pos) { + tones_next->curr_env.has_start_point = 1; + tones_next->curr_env.start_pos = tones_next->pend_env.start_pos + 32; + } else if (tones_now->pend_env.has_start_point) { + tones_next->curr_env.has_start_point = 1; + tones_next->curr_env.start_pos = tones_now->pend_env.start_pos; + } else { + tones_next->curr_env.has_start_point = 0; + tones_next->curr_env.start_pos = 0; + } + + if (tones_now->pend_env.has_stop_point && + tones_now->pend_env.stop_pos >= tones_next->curr_env.start_pos) { + tones_next->curr_env.has_stop_point = 1; + tones_next->curr_env.stop_pos = tones_now->pend_env.stop_pos; + } else if (tones_next->pend_env.has_stop_point) { + tones_next->curr_env.has_stop_point = 1; + tones_next->curr_env.stop_pos = tones_next->pend_env.stop_pos + 32; + } else { + tones_next->curr_env.has_stop_point = 0; + tones_next->curr_env.stop_pos = 64; + } + + /* is the visible part of the envelope non-zero? */ + reg1_env_nonzero = (tones_now->curr_env.stop_pos < 32) ? 0 : 1; + reg2_env_nonzero = (tones_next->curr_env.start_pos >= 32) ? 0 : 1; + + /* synthesize waves for both overlapping regions */ + if (tones_now->num_wavs && reg1_env_nonzero) + waves_synth(ch_unit->waves_info_prev, tones_now, &tones_now->curr_env, + ch_unit->waves_info_prev->phase_shift[sb] & ch_num, + 128, wavreg1); + + if (tones_next->num_wavs && reg2_env_nonzero) + waves_synth(ch_unit->waves_info, tones_next, &tones_next->curr_env, + ch_unit->waves_info->phase_shift[sb] & ch_num, 0, wavreg2); + + /* Hann windowing for non-faded wave signals */ + if (tones_now->num_wavs && tones_next->num_wavs && + reg1_env_nonzero && reg2_env_nonzero) { + fdsp->vector_fmul(wavreg1, wavreg1, &hann_window[128], 128); + fdsp->vector_fmul(wavreg2, wavreg2, hann_window, 128); + } else { + if (tones_now->num_wavs && !tones_now->curr_env.has_stop_point) + fdsp->vector_fmul(wavreg1, wavreg1, &hann_window[128], 128); + + if (tones_next->num_wavs && !tones_next->curr_env.has_start_point) + fdsp->vector_fmul(wavreg2, wavreg2, hann_window, 128); + } + + /* Overlap and add to residual */ + for (i = 0; i < 128; i++) + out[i] += wavreg1[i] + wavreg2[i]; +} + +static const int subband_to_powgrp[ATRAC3P_SUBBANDS] = { + 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4 +}; + +/* noise table for power compensation */ +static const float noise_tab[1024] = { + -0.01358032, -0.05593872, 0.01696777, -0.14871216, -0.26412964, -0.09893799, 0.25723267, + 0.02008057, -0.72235107, -0.44351196, -0.22985840, 0.16833496, 0.46902466, 0.05917358, + -0.15179443, 0.41299438, -0.01287842, 0.13360596, 0.43557739, -0.09530640, -0.58422852, + 0.39266968, -0.08343506, -0.25604248, 0.22848511, 0.26013184, -0.65588379, 0.17288208, + -0.08673096, -0.05203247, 0.07299805, -0.28665161, -0.35806274, 0.06552124, -0.09387207, + 0.21099854, -0.28347778, -0.72402954, 0.05050659, -0.10635376, -0.18853760, 0.29724121, + 0.20703125, -0.29791260, -0.37634277, 0.47970581, -0.09976196, 0.32641602, -0.29248047, + -0.28237915, 0.26028442, -0.36157227, 0.22042847, -0.03222656, -0.37268066, -0.03759766, + 0.09909058, 0.23284912, 0.19320679, 0.14453125, -0.02139282, -0.19702148, 0.31533813, + -0.16741943, 0.35031128, -0.35656738, -0.66128540, -0.00701904, 0.20898438, 0.26837158, + -0.33706665, -0.04568481, 0.12600708, 0.10284424, 0.07321167, -0.18280029, 0.38101196, + 0.21301270, 0.04541016, 0.01156616, -0.26391602, -0.02346802, -0.22125244, 0.29760742, + -0.36233521, -0.31314087, -0.13967896, -0.11276245, -0.19433594, 0.34490967, 0.02343750, + 0.21963501, -0.02777100, -0.67678833, -0.08999634, 0.14233398, -0.27697754, 0.51422119, + -0.05047607, 0.48327637, 0.37167358, -0.60806274, 0.18728638, -0.15191650, 0.00637817, + 0.02832031, -0.15618896, 0.60644531, 0.21826172, 0.06384277, -0.31863403, 0.08816528, + 0.15447998, -0.07015991, -0.08154297, -0.40966797, -0.39785767, -0.11709595, 0.22052002, + 0.18466187, -0.17257690, 0.03759766, -0.06195068, 0.00433350, 0.12176514, 0.34011841, + 0.25610352, -0.05294800, 0.41033936, 0.16854858, -0.76187134, 0.13845825, -0.19418335, + -0.21524048, -0.44412231, -0.08160400, -0.28195190, -0.01873779, 0.15524292, -0.37438965, + -0.44860840, 0.43096924, -0.24746704, 0.49856567, 0.14859009, 0.38159180, 0.20541382, + -0.39175415, -0.65850830, -0.43716431, 0.13037109, -0.05111694, 0.39956665, 0.21447754, + -0.04861450, 0.33654785, 0.10589600, -0.88085938, -0.30822754, 0.38577271, 0.30047607, + 0.38836670, 0.09118652, -0.36477661, -0.01641846, -0.23031616, 0.26058960, 0.18859863, + -0.21868896, -0.17861938, -0.29754639, 0.09777832, 0.10806274, -0.51605225, 0.00076294, + 0.13259888, 0.11090088, -0.24084473, 0.24957275, 0.01379395, -0.04141235, -0.04937744, + 0.57394409, 0.27410889, 0.27587891, 0.45013428, -0.32592773, 0.11160278, -0.00970459, + 0.29092407, 0.03356934, -0.70925903, 0.04882812, 0.43499756, 0.07720947, -0.27554321, + -0.01742554, -0.08413696, -0.04028320, -0.52850342, -0.07330322, 0.05181885, 0.21362305, + -0.18765259, 0.07058716, -0.03009033, 0.32662964, 0.27023315, -0.28002930, 0.17568970, + 0.03338623, 0.30242920, -0.03921509, 0.32174683, -0.23733521, 0.08575439, -0.38269043, + 0.09194946, -0.07238770, 0.17941284, -0.51278687, -0.25146484, 0.19790649, -0.19195557, + 0.16549683, 0.42456055, 0.39129639, -0.02868652, 0.17980957, 0.24902344, -0.76583862, + -0.20959473, 0.61013794, 0.37011719, 0.36859131, -0.04486084, 0.10678101, -0.15994263, + -0.05328369, 0.28463745, -0.06420898, -0.36987305, -0.28009033, -0.11764526, 0.04312134, + -0.08038330, 0.04885864, -0.03067017, -0.00042725, 0.34289551, -0.00988770, 0.34838867, + 0.32516479, -0.16271973, 0.38269043, 0.03240967, 0.12417603, -0.14331055, -0.34902954, + -0.18325806, 0.29421997, 0.44284058, 0.75170898, -0.67245483, -0.12176514, 0.27914429, + -0.29806519, 0.19863892, 0.30087280, 0.22680664, -0.36633301, -0.32534790, -0.57553101, + -0.16641235, 0.43811035, 0.08331299, 0.15942383, 0.26516724, -0.24240112, -0.11761475, + -0.16827393, -0.14260864, 0.46343994, 0.11804199, -0.55514526, -0.02520752, -0.14309692, + 0.00448608, 0.02749634, -0.30545044, 0.70965576, 0.45108032, 0.66439819, -0.68255615, + -0.12496948, 0.09146118, -0.21109009, -0.23791504, 0.79943848, -0.35205078, -0.24963379, + 0.18719482, -0.19079590, 0.07458496, 0.07623291, -0.28781128, -0.37121582, -0.19580078, + -0.01773071, -0.16717529, 0.13040161, 0.14672852, 0.42379761, 0.03582764, 0.11431885, + 0.05145264, 0.44702148, 0.08963013, 0.01367188, -0.54519653, -0.12692261, 0.21176147, + 0.04925537, 0.30670166, -0.11029053, 0.19555664, -0.27740479, 0.23043823, 0.15554810, + -0.19299316, -0.25729370, 0.17800903, -0.03579712, -0.05065918, -0.06933594, -0.09500122, + -0.07821655, 0.23889160, -0.31900024, 0.03073120, -0.00415039, 0.61315918, 0.37176514, + -0.13442993, -0.15536499, -0.19216919, -0.37899780, 0.19992065, 0.02630615, -0.12573242, + 0.25927734, -0.02447510, 0.29629517, -0.40731812, -0.17333984, 0.24310303, -0.10607910, + 0.14828491, 0.08792114, -0.18743896, -0.05572510, -0.04833984, 0.10473633, -0.29028320, + -0.67687988, -0.28170776, -0.41687012, 0.05413818, -0.23284912, 0.09555054, -0.08969116, + -0.15112305, 0.12738037, 0.35986328, 0.28948975, 0.30691528, 0.23956299, 0.06973267, + -0.31198120, -0.18450928, 0.22280884, -0.21600342, 0.23522949, -0.61840820, -0.13012695, + 0.26412964, 0.47320557, -0.26440430, 0.38757324, 0.17352295, -0.26104736, -0.25866699, + -0.12274170, -0.29733276, 0.07687378, 0.18588257, -0.08880615, 0.31185913, 0.05313110, + -0.10885620, -0.14901733, -0.22323608, -0.08538818, 0.19812012, 0.19732666, -0.18927002, + 0.29058838, 0.25555420, -0.48599243, 0.18768311, 0.01345825, 0.34887695, 0.21530151, + 0.19857788, 0.18661499, -0.01394653, -0.09063721, -0.38781738, 0.27160645, -0.20379639, + -0.32119751, -0.23889160, 0.27096558, 0.24951172, 0.07922363, 0.07479858, -0.50946045, + 0.10220337, 0.58364868, -0.19503784, -0.18560791, -0.01165771, 0.47195435, 0.22430420, + -0.38635254, -0.03732300, -0.09179688, 0.06991577, 0.15106201, 0.20605469, -0.05969238, + -0.41821289, 0.12231445, -0.04672241, -0.05117798, -0.11523438, -0.51849365, -0.04077148, + 0.44284058, -0.64086914, 0.17019653, 0.02236938, 0.22848511, -0.23214722, -0.32354736, + -0.14068604, -0.29690552, -0.19891357, 0.02774048, -0.20965576, -0.52191162, -0.19299316, + -0.07290649, 0.49053955, -0.22302246, 0.05642700, 0.13122559, -0.20819092, -0.83590698, + -0.08181763, 0.26797485, -0.00091553, -0.09457397, 0.17089844, -0.27020264, 0.30270386, + 0.05496216, 0.09564209, -0.08590698, 0.02130127, 0.35931396, 0.21728516, -0.15396118, + -0.05053711, 0.02719116, 0.16302490, 0.43212891, 0.10229492, -0.40820312, 0.21646118, + 0.08435059, -0.11145020, -0.39962769, -0.05618286, -0.10223389, -0.60839844, 0.33724976, + -0.06341553, -0.47369385, -0.32852173, 0.05242920, 0.19635010, -0.19137573, -0.67901611, + 0.16180420, 0.05133057, -0.22283936, 0.09646606, 0.24288940, -0.45007324, 0.08804321, + 0.14053345, 0.22619629, -0.01000977, 0.36355591, -0.19863892, -0.30364990, -0.24118042, + -0.57461548, 0.26498413, 0.04345703, -0.09796143, -0.47714233, -0.23739624, 0.18737793, + 0.08926392, -0.02795410, 0.00305176, -0.08700562, -0.38711548, 0.03222656, 0.10940552, + -0.41906738, -0.01620483, -0.47061157, 0.37985229, -0.21624756, 0.47976685, -0.20046997, + -0.62533569, -0.26907349, -0.02877808, 0.00671387, -0.29071045, -0.24685669, -0.15722656, + -0.26055908, 0.29968262, 0.28225708, -0.08990479, -0.16748047, -0.46759033, -0.25067139, + -0.25183105, -0.45932007, 0.05828857, 0.29006958, 0.23840332, -0.17974854, 0.26931763, + 0.10696411, -0.06848145, -0.17126465, -0.10522461, -0.55386353, -0.42306519, -0.07608032, + 0.24380493, 0.38586426, 0.16882324, 0.26751709, 0.17303467, 0.35809326, -0.22094727, + -0.30703735, -0.28497314, -0.04321289, 0.15219116, -0.17071533, -0.39334106, 0.03439331, + -0.10809326, -0.30590820, 0.26449585, -0.07412720, 0.13638306, -0.01062012, 0.27996826, + 0.04397583, -0.05557251, -0.56933594, 0.03363037, -0.00949097, 0.52642822, -0.44329834, + 0.28308105, -0.05499268, -0.23312378, -0.29870605, -0.05123901, 0.26831055, -0.35238647, + -0.30993652, 0.34646606, -0.19775391, 0.44595337, 0.13769531, 0.45358276, 0.19961548, + 0.42681885, 0.15722656, 0.00128174, 0.23757935, 0.40988159, 0.25164795, -0.00732422, + -0.12405396, -0.43420410, -0.00402832, 0.34243774, 0.36264038, 0.18807983, -0.09301758, + -0.10296631, 0.05532837, -0.31652832, 0.14337158, 0.35040283, 0.32540894, 0.05728149, + -0.12030029, -0.25942993, -0.20312500, -0.16491699, -0.46051025, -0.08004761, 0.50772095, + 0.16168213, 0.28439331, 0.08105469, -0.19104004, 0.38589478, -0.16400146, -0.25454712, + 0.20281982, -0.20730591, -0.06311035, 0.32937622, 0.15032959, -0.05340576, 0.30487061, + -0.11648560, 0.38009644, -0.20062256, 0.43466187, 0.01150513, 0.35754395, -0.13146973, + 0.67489624, 0.05212402, 0.27914429, -0.39431763, 0.75308228, -0.13366699, 0.24453735, + 0.42248535, -0.65905762, -0.00546265, -0.03491211, -0.13659668, -0.08294678, -0.45666504, + 0.27188110, 0.12731934, 0.61148071, 0.10449219, -0.28836060, 0.00091553, 0.24618530, + 0.13119507, 0.05685425, 0.17355347, 0.42034912, 0.08514404, 0.24536133, 0.18951416, + -0.19107056, -0.15036011, 0.02334595, 0.54986572, 0.32321167, -0.16104126, -0.03054810, + 0.43594360, 0.17309570, 0.61053467, 0.24731445, 0.33334351, 0.15240479, 0.15588379, + 0.36425781, -0.30407715, -0.13302612, 0.00427246, 0.04171753, -0.33178711, 0.34216309, + -0.12463379, -0.02764893, 0.05905151, -0.31436157, 0.16531372, 0.34542847, -0.03292847, + 0.12527466, -0.12313843, -0.13171387, 0.04757690, -0.45095825, -0.19085693, 0.35342407, + -0.23239136, -0.34387207, 0.11264038, -0.15740967, 0.05273438, 0.74942017, 0.21505737, + 0.08514404, -0.42391968, -0.19531250, 0.35293579, 0.25305176, 0.15731812, -0.70324707, + -0.21591187, 0.35604858, 0.14132690, 0.11724854, 0.15853882, -0.24597168, 0.07019043, + 0.02127075, 0.12658691, 0.06390381, -0.12292480, 0.15441895, -0.47640991, 0.06195068, + 0.58981323, -0.15151978, -0.03604126, -0.45059204, -0.01672363, -0.46997070, 0.25750732, + 0.18084717, 0.06661987, 0.13253784, 0.67828369, 0.11370850, 0.11325073, -0.04611206, + -0.07791138, -0.36544800, -0.06747437, -0.31594849, 0.16131592, 0.41983032, 0.11071777, + -0.36889648, 0.30963135, -0.37875366, 0.58508301, 0.00393677, 0.12338257, 0.03424072, + -0.21728516, -0.12838745, -0.46981812, 0.05868530, -0.25015259, 0.27407837, 0.65240479, + -0.34429932, -0.15179443, 0.14056396, 0.33505249, 0.28826904, 0.09921265, 0.34390259, + 0.13656616, -0.23608398, 0.00863647, 0.02627563, -0.19119263, 0.19775391, -0.07214355, + 0.07809448, 0.03454590, -0.03417969, 0.00033569, -0.23095703, 0.18673706, 0.05798340, + 0.03814697, -0.04318237, 0.05487061, 0.08633423, 0.55950928, -0.06347656, 0.10333252, + 0.25305176, 0.05853271, 0.12246704, -0.25543213, -0.34262085, -0.36437988, -0.21304321, + -0.05093384, 0.02777100, 0.07620239, -0.21215820, -0.09326172, 0.19021606, -0.40579224, + -0.01193237, 0.19845581, -0.35336304, -0.07397461, 0.20104980, 0.08615112, -0.44375610, + 0.11419678, 0.24453735, -0.16555786, -0.05081177, -0.01406860, 0.27893066, -0.18692017, + 0.07473755, 0.03451538, -0.39733887, 0.21548462, -0.22534180, -0.39651489, -0.04989624, + -0.57662964, 0.06390381, 0.62020874, -0.13470459, 0.04345703, -0.21862793, -0.02789307, + 0.51696777, -0.27587891, 0.39004517, 0.09857178, -0.00738525, 0.31317139, 0.00048828, + -0.46572876, 0.29531860, -0.10009766, -0.27856445, 0.03594971, 0.25048828, -0.74584961, + -0.25350952, -0.03302002, 0.31188965, 0.01571655, 0.46710205, 0.21591187, 0.07260132, + -0.42132568, -0.53900146, -0.13674927, -0.16571045, -0.34454346, 0.12359619, -0.11184692, + 0.00967407, 0.34576416, -0.05761719, 0.34848022, 0.17645264, -0.39395142, 0.10339355, + 0.18215942, 0.20697021, 0.59109497, -0.11560059, -0.07385254, 0.10397339, 0.35437012, + -0.22863770, 0.01794434, 0.17559814, -0.17495728, 0.12142944, 0.10928345, -1.00000000, + -0.01379395, 0.21237183, -0.27035522, 0.27319336, -0.37066650, 0.41354370, -0.40054321, + 0.00689697, 0.26321411, 0.39266968, 0.65298462, 0.41625977, -0.13909912, 0.78375244, + -0.30941772, 0.20169067, -0.39367676, 0.94021606, -0.24066162, 0.05557251, -0.24533081, + -0.05444336, -0.76754761, -0.19375610, -0.11041260, -0.17532349, 0.16006470, 0.02188110, + 0.17465210, -0.04342651, -0.56777954, -0.40988159, 0.26687622, 0.11700439, -0.00344849, + -0.05395508, 0.37426758, -0.40719604, -0.15032959, -0.01660156, 0.04196167, -0.04559326, + -0.12969971, 0.12011719, 0.08419800, -0.11199951, 0.35174561, 0.10275269, -0.25686646, + 0.48446655, 0.03225708, 0.28408813, -0.18701172, 0.36282349, -0.03280640, 0.32302856, + 0.17233276, 0.48269653, 0.31112671, -0.04946899, 0.12774658, 0.52685547, 0.10211182, + 0.05953979, 0.05999756, 0.20144653, 0.00744629, 0.27316284, 0.24377441, 0.39672852, + 0.01702881, -0.35513306, 0.11364746, -0.13555908, 0.48880005, -0.15417480, -0.09149170, + -0.02615356, 0.46246338, -0.72250366, 0.22332764, 0.23849487, -0.25686646, -0.08514404, + -0.02062988, -0.34494019, -0.02297974, -0.80386353, -0.08074951, -0.12689209, -0.06896973, + 0.24099731, -0.35650635, -0.09558105, 0.29254150, 0.23132324, -0.16726685, 0.00000000, + -0.24237061, 0.30899048, 0.29504395, -0.20898438, 0.17059326, -0.07672119, -0.14395142, + 0.05572510, 0.20602417, -0.51550293, -0.03167725, -0.48840332, -0.20425415, 0.14144897, + 0.07275391, -0.76669312, -0.22488403, 0.20651245, 0.03259277, 0.00085449, 0.03039551, + 0.47555542, 0.38351440 +}; + +/** Noise level table for power compensation. + * Equ: pow(2.0f, (double)(6 - i) / 3.0f) where i = 0...15 */ +static const float pwc_levs[16] = { + 3.96875, 3.15625, 2.5, 2.0, 1.59375, 1.25, 1.0, 0.78125, + 0.625, 0.5, 0.40625, 0.3125, 0.25, 0.1875, 0.15625, 0.0 +}; + +/** Map subband number to quant unit number. */ +static const int subband_to_qu[17] = { + 0, 8, 12, 16, 18, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 +}; + +void ff_atrac3p_power_compensation(Atrac3pChanUnitCtx *ctx, int ch_index, + float *sp, int rng_index, int sb) +{ + AtracGainInfo *g1, *g2; + float pwcsp[ATRAC3P_SUBBAND_SAMPLES], *dst, grp_lev, qu_lev; + int i, gain_lev, gcv = 0, qu, nsp; + int swap_ch = (ctx->unit_type == CH_UNIT_STEREO && ctx->swap_channels[sb]) ? 1 : 0; + + if (ctx->channels[ch_index ^ swap_ch].power_levs[subband_to_powgrp[sb]] == ATRAC3P_POWER_COMP_OFF) + return; + + /* generate initial noise spectrum */ + for (i = 0; i < ATRAC3P_SUBBAND_SAMPLES; i++, rng_index++) + pwcsp[i] = noise_tab[rng_index & 0x3FF]; + + /* check gain control information */ + g1 = &ctx->channels[ch_index ^ swap_ch].gain_data[sb]; + g2 = &ctx->channels[ch_index ^ swap_ch].gain_data_prev[sb]; + + gain_lev = (g1->num_points > 0) ? (6 - g1->lev_code[0]) : 0; + + for (i = 0; i < g2->num_points; i++) + gcv = FFMAX(gcv, gain_lev - (g2->lev_code[i] - 6)); + + for (i = 0; i < g1->num_points; i++) + gcv = FFMAX(gcv, 6 - g1->lev_code[i]); + + grp_lev = pwc_levs[ctx->channels[ch_index ^ swap_ch].power_levs[subband_to_powgrp[sb]]] / (1 << gcv); + + /* skip the lowest two quant units (frequencies 0...351 Hz) for subband 0 */ + for (qu = subband_to_qu[sb] + (!sb ? 2 : 0); qu < subband_to_qu[sb + 1]; qu++) { + if (ctx->channels[ch_index].qu_wordlen[qu] <= 0) + continue; + + qu_lev = ff_atrac3p_sf_tab[ctx->channels[ch_index].qu_sf_idx[qu]] * + ff_atrac3p_mant_tab[ctx->channels[ch_index].qu_wordlen[qu]] / + (1 << ctx->channels[ch_index].qu_wordlen[qu]) * grp_lev; + + dst = &sp[ff_atrac3p_qu_to_spec_pos[qu]]; + nsp = ff_atrac3p_qu_to_spec_pos[qu + 1] - ff_atrac3p_qu_to_spec_pos[qu]; + + for (i = 0; i < nsp; i++) + dst[i] += pwcsp[i] * qu_lev; + } +} + +void ff_atrac3p_imdct(AVFloatDSPContext *fdsp, FFTContext *mdct_ctx, float *pIn, + float *pOut, int wind_id, int sb) +{ + int i; + + if (sb & 1) + for (i = 0; i < ATRAC3P_SUBBAND_SAMPLES / 2; i++) + FFSWAP(float, pIn[i], pIn[ATRAC3P_SUBBAND_SAMPLES - 1 - i]); + + mdct_ctx->imdct_calc(mdct_ctx, pOut, pIn); + + /* Perform windowing on the output. + * ATRAC3+ uses two different MDCT windows: + * - The first one is just the plain sine window of size 256 + * - The 2nd one is the plain sine window of size 128 + * wrapped into zero (at the start) and one (at the end) regions. + * Both regions are 32 samples long. */ + if (wind_id & 2) { /* 1st half: steep window */ + memset(pOut, 0, sizeof(float) * 32); + fdsp->vector_fmul(&pOut[32], &pOut[32], ff_sine_64, 64); + } else /* 1st half: simple sine window */ + fdsp->vector_fmul(pOut, pOut, ff_sine_128, ATRAC3P_MDCT_SIZE / 2); + + if (wind_id & 1) { /* 2nd half: steep window */ + fdsp->vector_fmul_reverse(&pOut[160], &pOut[160], ff_sine_64, 64); + memset(&pOut[224], 0, sizeof(float) * 32); + } else /* 2nd half: simple sine window */ + fdsp->vector_fmul_reverse(&pOut[128], &pOut[128], ff_sine_128, + ATRAC3P_MDCT_SIZE / 2); +} + +/* lookup table for fast modulo 23 op required for cyclic buffers of the IPQF */ +static const int mod23_lut[26] = { + 23, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 0 +}; + +/* First half of the 384-tap IPQF filtering coefficients. */ +static const float ipqf_coeffs1[ATRAC3P_PQF_FIR_LEN][16] = { + { -5.8336207e-7, -8.0604229e-7, -4.2005411e-7, -4.4400572e-8, + 3.226247e-8, 3.530856e-8, 1.2660377e-8, 0.000010516783, + -0.000011838618, 6.005389e-7, 0.0000014333754, 0.0000023108685, + 0.0000032569742, 0.0000046192422, 0.0000063894258, 0.0000070302972 }, + { -0.0000091622824, -0.000010502935, -0.0000079212787, -0.0000041712024, + -0.0000026336629, -0.0000015432918, -5.7168614e-7, 0.0000018111954, + 0.000023530851, 0.00002780562, 0.000032302323, 0.000036968919, + 0.000041575615, 0.000045337845, 0.000046043948, 0.000048585582 }, + { -0.000064464548, -0.000068306952, -0.000073081472, -0.00007612785, + -0.000074850752, -0.000070208509, -0.000062285151, -0.000058270442, + -0.000056296329, -0.000049888811, -0.000035615325, -0.000018532943, + 0.0000016657353, 0.00002610587, 0.000053397067, 0.00008079566 }, + { -0.00054488552, -0.00052537228, -0.00049731287, -0.00045778, + -0.00040612387, -0.00034301577, -0.00026866337, -0.00018248901, + -0.000084307925, 0.000025081157, 0.00014135583, 0.00026649953, + 0.00039945057, 0.00053928449, 0.00068422867, 0.00083093712 }, + { -0.0014771431, -0.001283227, -0.0010566821, -0.00079780724, + -0.00050782406, -0.00018855913, 0.00015771533, 0.00052769453, + 0.00091862219, 0.001326357, 0.0017469483, 0.0021754825, + 0.0026067684, 0.0030352892, 0.0034549395, 0.0038591374 }, + { -0.0022995141, -0.001443546, -0.00049266568, 0.00055068987, + 0.001682895, 0.0028992873, 0.0041943151, 0.0055614738, + 0.0069935122, 0.0084823566, 0.010018963, 0.011593862, + 0.013196872, 0.014817309, 0.016444042, 0.018065533 }, + { -0.034426283, -0.034281436, -0.033992987, -0.033563249, + -0.032995768, -0.032295227, -0.031467363, -0.030518902, + -0.02945766, -0.028291954, -0.027031265, -0.025685543, + -0.024265358, -0.022781773, -0.021246184, -0.019670162 }, + { -0.0030586775, -0.0037203205, -0.0042847847, -0.0047529764, + -0.0051268316, -0.0054091476, -0.0056034233, -0.005714261, + -0.0057445862, -0.0057025906, -0.0055920109, -0.0054194843, + -0.0051914565, -0.0049146507, -0.0045959447, -0.0042418269 }, + { -0.0016376863, -0.0017651899, -0.0018608454, -0.0019252141, + -0.0019593791, -0.0019653172, -0.0019450618, -0.0018990048, + -0.00183808, -0.0017501717, -0.0016481078, -0.0015320742, + -0.0014046903, -0.0012685474, -0.001125814, -0.00097943726 }, + { -0.00055432378, -0.00055472925, -0.00054783461, -0.00053276919, + -0.00051135791, -0.00048466062, -0.00045358928, -0.00042499689, + -0.00036942671, -0.0003392619, -0.00030001783, -0.00025986304, + -0.0002197204, -0.00018116167, -0.00014691355, -0.00011279432 }, + { -0.000064147389, -0.00006174868, -0.000054267788, -0.000047133824, + -0.000042927582, -0.000039477309, -0.000036340745, -0.000029687517, + -0.000049787737, -0.000041577889, -0.000033864744, -0.000026534748, + -0.000019841305, -0.000014789486, -0.000013131184, -0.0000099198869 }, + { -0.0000062990207, -0.0000072701259, -0.000011984052, -0.000017348082, + -0.000019907106, -0.000021348773, -0.000021961965, -0.000012203576, + -0.000010840992, 4.6299544e-7, 5.2588763e-7, 2.7792686e-7, + -2.3649704e-7, -0.0000010897784, -9.171448e-7, -5.22682e-7 } +}; + +/* Second half of the 384-tap IPQF filtering coefficients. */ +static const float ipqf_coeffs2[ATRAC3P_PQF_FIR_LEN][16] = { + { 5.22682e-7, 9.171448e-7, 0.0000010897784, 2.3649704e-7, + -2.7792686e-7, -5.2588763e-7, -4.6299544e-7, 0.000010840992, + -0.000012203576, -0.000021961965, -0.000021348773, -0.000019907106, + -0.000017348082, -0.000011984052, -0.0000072701259, -0.0000062990207 }, + { 0.0000099198869, 0.000013131184, 0.000014789486, 0.000019841305, + 0.000026534748, 0.000033864744, 0.000041577889, 0.000049787737, + -0.000029687517, -0.000036340745, -0.000039477309, -0.000042927582, + -0.000047133824, -0.000054267788, -0.00006174868, -0.000064147389 }, + { 0.00011279432, 0.00014691355, 0.00018116167, 0.0002197204, + 0.00025986304, 0.00030001783, 0.0003392619, 0.00036942671, + -0.00042499689, -0.00045358928, -0.00048466062, -0.00051135791, + -0.00053276919, -0.00054783461, -0.00055472925, -0.00055432378 }, + { 0.00097943726, 0.001125814, 0.0012685474, 0.0014046903, + 0.0015320742, 0.0016481078, 0.0017501717, 0.00183808, + -0.0018990048, -0.0019450618, -0.0019653172, -0.0019593791, + -0.0019252141, -0.0018608454, -0.0017651899, -0.0016376863 }, + { 0.0042418269, 0.0045959447, 0.0049146507, 0.0051914565, + 0.0054194843, 0.0055920109, 0.0057025906, 0.0057445862, + -0.005714261, -0.0056034233, -0.0054091476, -0.0051268316, + -0.0047529764, -0.0042847847, -0.0037203205, -0.0030586775 }, + { 0.019670162, 0.021246184, 0.022781773, 0.024265358, + 0.025685543, 0.027031265, 0.028291954, 0.02945766, + -0.030518902, -0.031467363, -0.032295227, -0.032995768, + -0.033563249, -0.033992987, -0.034281436, -0.034426283 }, + { -0.018065533, -0.016444042, -0.014817309, -0.013196872, + -0.011593862, -0.010018963, -0.0084823566, -0.0069935122, + 0.0055614738, 0.0041943151, 0.0028992873, 0.001682895, + 0.00055068987, -0.00049266568, -0.001443546, -0.0022995141 }, + { -0.0038591374, -0.0034549395, -0.0030352892, -0.0026067684, + -0.0021754825, -0.0017469483, -0.001326357, -0.00091862219, + 0.00052769453, 0.00015771533, -0.00018855913, -0.00050782406, + -0.00079780724, -0.0010566821, -0.001283227, -0.0014771431 }, + { -0.00083093712, -0.00068422867, -0.00053928449, -0.00039945057, + -0.00026649953, -0.00014135583, -0.000025081157, 0.000084307925, + -0.00018248901, -0.00026866337, -0.00034301577, -0.00040612387, + -0.00045778, -0.00049731287, -0.00052537228, -0.00054488552 }, + { -0.00008079566, -0.000053397067, -0.00002610587, -0.0000016657353, + 0.000018532943, 0.000035615325, 0.000049888811, 0.000056296329, + -0.000058270442, -0.000062285151, -0.000070208509, -0.000074850752, + -0.00007612785, -0.000073081472, -0.000068306952, -0.000064464548 }, + { -0.000048585582, -0.000046043948, -0.000045337845, -0.000041575615, + -0.000036968919, -0.000032302323, -0.00002780562, -0.000023530851, + 0.0000018111954, -5.7168614e-7, -0.0000015432918, -0.0000026336629, + -0.0000041712024, -0.0000079212787, -0.000010502935, -0.0000091622824 }, + { -0.0000070302972, -0.0000063894258, -0.0000046192422, -0.0000032569742, + -0.0000023108685, -0.0000014333754, -6.005389e-7, 0.000011838618, + 0.000010516783, 1.2660377e-8, 3.530856e-8, 3.226247e-8, + -4.4400572e-8, -4.2005411e-7, -8.0604229e-7, -5.8336207e-7 } +}; + +void ff_atrac3p_ipqf(FFTContext *dct_ctx, Atrac3pIPQFChannelCtx *hist, + const float *in, float *out) +{ + int i, s, sb, t, pos_now, pos_next; + DECLARE_ALIGNED(32, float, idct_in)[ATRAC3P_SUBBANDS]; + DECLARE_ALIGNED(32, float, idct_out)[ATRAC3P_SUBBANDS]; + + memset(out, 0, ATRAC3P_FRAME_SAMPLES * sizeof(*out)); + + for (s = 0; s < ATRAC3P_SUBBAND_SAMPLES; s++) { + /* pick up one sample from each subband */ + for (sb = 0; sb < ATRAC3P_SUBBANDS; sb++) + idct_in[sb] = in[sb * ATRAC3P_SUBBAND_SAMPLES + s]; + + /* Calculate the sine and cosine part of the PQF using IDCT-IV */ + dct_ctx->imdct_half(dct_ctx, idct_out, idct_in); + + /* append the result to the history */ + for (i = 0; i < 8; i++) { + hist->buf1[hist->pos][i] = idct_out[i + 8]; + hist->buf2[hist->pos][i] = idct_out[7 - i]; + } + + pos_now = hist->pos; + pos_next = mod23_lut[pos_now + 2]; // pos_next = (pos_now + 1) % 23; + + for (t = 0; t < ATRAC3P_PQF_FIR_LEN; t++) { + for (i = 0; i < 8; i++) { + out[s * 16 + i + 0] += hist->buf1[pos_now][i] * ipqf_coeffs1[t][i] + + hist->buf2[pos_next][i] * ipqf_coeffs2[t][i]; + out[s * 16 + i + 8] += hist->buf1[pos_now][7 - i] * ipqf_coeffs1[t][i + 8] + + hist->buf2[pos_next][7 - i] * ipqf_coeffs2[t][i + 8]; + } + + pos_now = mod23_lut[pos_next + 2]; // pos_now = (pos_now + 2) % 23; + pos_next = mod23_lut[pos_now + 2]; // pos_next = (pos_next + 2) % 23; + } + + hist->pos = mod23_lut[hist->pos]; // hist->pos = (hist->pos - 1) % 23; + } +} diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/avcodec.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/avcodec.h index 1662c90f2..d04be623e 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/avcodec.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/avcodec.h @@ -57,6 +57,15 @@ #include "version.h" +#if FF_API_FAST_MALLOC +// to provide fast_*alloc +#ifdef __FRAMEWORK__ +#include "mem.h" +#else +#include "libavutil/mem.h" +#endif +#endif + /** * @defgroup libavc Encoding/Decoding Library * @{ @@ -120,7 +129,9 @@ enum AVCodecID { /* video codecs */ AV_CODEC_ID_MPEG1VIDEO, AV_CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding +#if FF_API_XVMC AV_CODEC_ID_MPEG2VIDEO_XVMC, +#endif /* FF_API_XVMC */ AV_CODEC_ID_H261, AV_CODEC_ID_H263, AV_CODEC_ID_RV10, @@ -291,6 +302,9 @@ enum AVCodecID { AV_CODEC_ID_ESCAPE130_DEPRECATED, AV_CODEC_ID_G2M_DEPRECATED, AV_CODEC_ID_WEBP_DEPRECATED, + AV_CODEC_ID_HNM4_VIDEO, + AV_CODEC_ID_HEVC_DEPRECATED, + AV_CODEC_ID_FIC, AV_CODEC_ID_BRENDER_PIX= MKBETAG('B','P','I','X'), AV_CODEC_ID_Y41P = MKBETAG('Y','4','1','P'), @@ -317,7 +331,8 @@ enum AVCodecID { AV_CODEC_ID_SNOW = MKBETAG('S','N','O','W'), AV_CODEC_ID_WEBP = MKBETAG('W','E','B','P'), AV_CODEC_ID_SMVJPEG = MKBETAG('S','M','V','J'), - AV_CODEC_ID_H265 = MKBETAG('H','2','6','5'), + AV_CODEC_ID_HEVC = MKBETAG('H','2','6','5'), +#define AV_CODEC_ID_H265 AV_CODEC_ID_HEVC /* various PCM "codecs" */ AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs @@ -391,6 +406,7 @@ enum AVCodecID { AV_CODEC_ID_ADPCM_IMA_OKI = MKBETAG('O','K','I',' '), AV_CODEC_ID_ADPCM_DTK = MKBETAG('D','T','K',' '), AV_CODEC_ID_ADPCM_IMA_RAD = MKBETAG('R','A','D',' '), + AV_CODEC_ID_ADPCM_G726LE = MKBETAG('6','2','7','G'), /* AMR */ AV_CODEC_ID_AMR_NB = 0x12000, @@ -517,6 +533,7 @@ enum AVCodecID { AV_CODEC_ID_OTF = MKBETAG( 0 ,'O','T','F'), AV_CODEC_ID_SMPTE_KLV = MKBETAG('K','L','V','A'), AV_CODEC_ID_DVD_NAV = MKBETAG('D','N','A','V'), + AV_CODEC_ID_TIMED_ID3 = MKBETAG('T','I','D','3'), AV_CODEC_ID_PROBE = 0x19000, ///< codec_id is not known (like AV_CODEC_ID_NONE) but lavf should attempt to identify it @@ -639,16 +656,26 @@ enum AVColorPrimaries{ AVCOL_PRI_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC AVCOL_PRI_SMPTE240M = 7, ///< functionally identical to above AVCOL_PRI_FILM = 8, + AVCOL_PRI_BT2020 = 9, ///< ITU-R BT2020 AVCOL_PRI_NB , ///< Not part of ABI }; enum AVColorTransferCharacteristic{ - AVCOL_TRC_BT709 = 1, ///< also ITU-R BT1361 - AVCOL_TRC_UNSPECIFIED = 2, - AVCOL_TRC_GAMMA22 = 4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM - AVCOL_TRC_GAMMA28 = 5, ///< also ITU-R BT470BG - AVCOL_TRC_SMPTE240M = 7, - AVCOL_TRC_NB , ///< Not part of ABI + AVCOL_TRC_BT709 = 1, ///< also ITU-R BT1361 + AVCOL_TRC_UNSPECIFIED = 2, + AVCOL_TRC_GAMMA22 = 4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM + AVCOL_TRC_GAMMA28 = 5, ///< also ITU-R BT470BG + AVCOL_TRC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 or 625 / ITU-R BT1358 525 or 625 / ITU-R BT1700 NTSC + AVCOL_TRC_SMPTE240M = 7, + AVCOL_TRC_LINEAR = 8, ///< "Linear transfer characteristics" + AVCOL_TRC_LOG = 9, ///< "Logarithmic transfer characteristic (100:1 range)" + AVCOL_TRC_LOG_SQRT = 10, ///< "Logarithmic transfer characteristic (100 * Sqrt( 10 ) : 1 range)" + AVCOL_TRC_IEC61966_2_4 = 11, ///< IEC 61966-2-4 + AVCOL_TRC_BT1361_ECG = 12, ///< ITU-R BT1361 Extended Colour Gamut + AVCOL_TRC_IEC61966_2_1 = 13, ///< IEC 61966-2-1 (sRGB or sYCC) + AVCOL_TRC_BT2020_10 = 14, ///< ITU-R BT2020 for 10 bit system + AVCOL_TRC_BT2020_12 = 15, ///< ITU-R BT2020 for 12 bit system + AVCOL_TRC_NB , ///< Not part of ABI }; /** @@ -690,7 +717,12 @@ typedef struct RcOverride{ float quality_factor; } RcOverride; +#if FF_API_MAX_BFRAMES +/** + * @deprecated there is no libavcodec-wide limit on the number of B-frames + */ #define FF_MAX_B_FRAMES 16 +#endif /* encoding support These flags can be passed in AVCodecContext.flags before initialization. @@ -704,6 +736,7 @@ typedef struct RcOverride{ #define CODEC_FLAG_UNALIGNED 0x0001 #define CODEC_FLAG_QSCALE 0x0002 ///< Use fixed qscale. #define CODEC_FLAG_4MV 0x0004 ///< 4 MV per MB allowed / advanced prediction for H.263. +#define CODEC_FLAG_OUTPUT_CORRUPT 0x0008 ///< Output even those frames that might be corrupted #define CODEC_FLAG_QPEL 0x0010 ///< Use qpel MC. #define CODEC_FLAG_GMC 0x0020 ///< Use GMC. #define CODEC_FLAG_MV0 0x0040 ///< Always try a MB with MV=<0,0>. @@ -716,7 +749,13 @@ typedef struct RcOverride{ #define CODEC_FLAG_PASS1 0x0200 ///< Use internal 2pass ratecontrol in first pass mode. #define CODEC_FLAG_PASS2 0x0400 ///< Use internal 2pass ratecontrol in second pass mode. #define CODEC_FLAG_GRAY 0x2000 ///< Only decode/encode grayscale. -#define CODEC_FLAG_EMU_EDGE 0x4000 ///< Don't draw edges. +#if FF_API_EMU_EDGE +/** + * @deprecated edges are not used/required anymore. I.e. this flag is now always + * set. + */ +#define CODEC_FLAG_EMU_EDGE 0x4000 +#endif #define CODEC_FLAG_PSNR 0x8000 ///< error[?] variables will be set during encoding. #define CODEC_FLAG_TRUNCATED 0x00010000 /** Input bitstream might be truncated at a random location instead of only at frame boundaries. */ @@ -754,8 +793,16 @@ typedef struct RcOverride{ */ #define CODEC_CAP_DR1 0x0002 #define CODEC_CAP_TRUNCATED 0x0008 -/* Codec can export data for HW decoding (XvMC). */ +#if FF_API_XVMC +/* Codec can export data for HW decoding. This flag indicates that + * the codec would call get_format() with list that might contain HW accelerated + * pixel formats (XvMC, VDPAU, VAAPI, etc). The application can pick any of them + * including raw image format. + * The application can use the passed context to determine bitstream version, + * chroma format, resolution etc. + */ #define CODEC_CAP_HWACCEL 0x0010 +#endif /* FF_API_XVMC */ /** * Encoder or decoder requires flushing with NULL input at the end in order to * give the complete and correct output. @@ -812,12 +859,12 @@ typedef struct RcOverride{ * Codec should fill in channel configuration and samplerate instead of container */ #define CODEC_CAP_CHANNEL_CONF 0x0400 - +#if FF_API_NEG_LINESIZES /** - * Codec is able to deal with negative linesizes + * @deprecated no codecs use this capability */ #define CODEC_CAP_NEG_LINESIZES 0x0800 - +#endif /** * Codec supports frame-level multithreading. */ @@ -847,6 +894,7 @@ typedef struct RcOverride{ */ #define CODEC_CAP_LOSSLESS 0x80000000 +#if FF_API_MB_TYPE //The following defines may change, don't expect compatibility if you use them. #define MB_TYPE_INTRA4x4 0x0001 #define MB_TYPE_INTRA16x16 0x0002 //FIXME H.264-specific @@ -870,6 +918,7 @@ typedef struct RcOverride{ #define MB_TYPE_QUANT 0x00010000 #define MB_TYPE_CBP 0x00020000 //Note bits 24-31 are reserved for codec specific use (h264 ref0, mpeg1 0mv, ...) +#endif /** * Pan Scan area. @@ -900,10 +949,12 @@ typedef struct AVPanScan{ int16_t position[3][2]; }AVPanScan; +#if FF_API_QSCALE_TYPE #define FF_QSCALE_TYPE_MPEG1 0 #define FF_QSCALE_TYPE_MPEG2 1 #define FF_QSCALE_TYPE_H264 2 #define FF_QSCALE_TYPE_VP56 3 +#endif #if FF_API_GET_BUFFER #define FF_BUFFER_TYPE_INTERNAL 1 @@ -1026,6 +1077,13 @@ enum AVPacketSideDataType { * follow the timestamp specifier of a WebVTT cue. */ AV_PKT_DATA_WEBVTT_SETTINGS, + + /** + * A list of zero terminated key/value strings. There is no end marker for + * the list, so it is required to rely on the side data size to stop. This + * side data includes updated metadata which appeared in the stream. + */ + AV_PKT_DATA_METADATA_UPDATE, }; /** @@ -1336,7 +1394,9 @@ typedef struct AVCodecContext { */ int coded_width, coded_height; +#if FF_API_ASPECT_EXTENDED #define FF_ASPECT_EXTENDED 15 +#endif /** * the number of pictures in a group of pictures, or 0 for intra_only @@ -1663,12 +1723,15 @@ typedef struct AVCodecContext { #define SLICE_FLAG_ALLOW_FIELD 0x0002 ///< allow draw_horiz_band() with field slices (MPEG2 field pics) #define SLICE_FLAG_ALLOW_PLANE 0x0004 ///< allow draw_horiz_band() with 1 component at a time (SVQ1) +#if FF_API_XVMC /** * XVideo Motion Acceleration * - encoding: forbidden * - decoding: set by decoder + * @deprecated XvMC doesn't need it anymore. */ - int xvmc_acceleration; + attribute_deprecated int xvmc_acceleration; +#endif /* FF_API_XVMC */ /** * macroblock decision mode @@ -2115,12 +2178,11 @@ typedef struct AVCodecContext { * If AV_GET_BUFFER_FLAG_REF is set in flags then the frame may be reused * (read and/or written to if it is writable) later by libavcodec. * - * If CODEC_FLAG_EMU_EDGE is not set in s->flags, the buffer must contain an - * edge of the size returned by avcodec_get_edge_width() on all sides. - * * avcodec_align_dimensions2() should be used to find the required width and * height, as they normally need to be rounded up to the next multiple of 16. * + * Some decoders do not support linesizes changing between frames. + * * If frame multithreading is used and thread_safe_callbacks is set, * this callback may be called from a different thread, but not from more * than one at once. Does not need to be reentrant. @@ -2403,12 +2465,16 @@ typedef struct AVCodecContext { */ int workaround_bugs; #define FF_BUG_AUTODETECT 1 ///< autodetection +#if FF_API_OLD_MSMPEG4 #define FF_BUG_OLD_MSMPEG4 2 +#endif #define FF_BUG_XVID_ILACE 4 #define FF_BUG_UMP4 8 #define FF_BUG_NO_PADDING 16 #define FF_BUG_AMV 32 +#if FF_API_AC_VLC #define FF_BUG_AC_VLC 0 ///< Will be removed, libavcodec can now handle these non-compliant files by default. +#endif #define FF_BUG_QPEL_CHROMA 64 #define FF_BUG_STD_QPEL 128 #define FF_BUG_QPEL_CHROMA2 256 @@ -2458,7 +2524,12 @@ typedef struct AVCodecContext { #define FF_DEBUG_BITSTREAM 4 #define FF_DEBUG_MB_TYPE 8 #define FF_DEBUG_QP 16 +#if FF_API_DEBUG_MV +/** + * @deprecated this option does nothing + */ #define FF_DEBUG_MV 32 +#endif #define FF_DEBUG_DCT_COEFF 0x00000040 #define FF_DEBUG_SKIP 0x00000080 #define FF_DEBUG_STARTCODE 0x00000100 @@ -2466,13 +2537,17 @@ typedef struct AVCodecContext { #define FF_DEBUG_ER 0x00000400 #define FF_DEBUG_MMCO 0x00000800 #define FF_DEBUG_BUGS 0x00001000 -#define FF_DEBUG_VIS_QP 0x00002000 -#define FF_DEBUG_VIS_MB_TYPE 0x00004000 +#if FF_API_DEBUG_MV +#define FF_DEBUG_VIS_QP 0x00002000 ///< only access through AVOptions from outside libavcodec +#define FF_DEBUG_VIS_MB_TYPE 0x00004000 ///< only access through AVOptions from outside libavcodec +#endif #define FF_DEBUG_BUFFERS 0x00008000 #define FF_DEBUG_THREADS 0x00010000 +#if FF_API_DEBUG_MV /** * debug + * Code outside libavcodec should access this field using AVOptions * - encoding: Set by user. * - decoding: Set by user. */ @@ -2480,6 +2555,7 @@ typedef struct AVCodecContext { #define FF_DEBUG_VIS_MV_P_FOR 0x00000001 //visualize forward predicted MVs of P frames #define FF_DEBUG_VIS_MV_B_FOR 0x00000002 //visualize forward predicted MVs of B frames #define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames +#endif /** * Error recognition; may misdetect some more or less valid parts as errors. @@ -2487,14 +2563,21 @@ typedef struct AVCodecContext { * - decoding: Set by user. */ int err_recognition; -#define AV_EF_CRCCHECK (1<<0) -#define AV_EF_BITSTREAM (1<<1) -#define AV_EF_BUFFER (1<<2) -#define AV_EF_EXPLODE (1<<3) -#define AV_EF_CAREFUL (1<<16) -#define AV_EF_COMPLIANT (1<<17) -#define AV_EF_AGGRESSIVE (1<<18) +/** + * Verify checksums embedded in the bitstream (could be of either encoded or + * decoded data, depending on the codec) and print an error message on mismatch. + * If AV_EF_EXPLODE is also set, a mismatching checksum will result in the + * decoder returning an error. + */ +#define AV_EF_CRCCHECK (1<<0) +#define AV_EF_BITSTREAM (1<<1) ///< detect bitstream specification deviations +#define AV_EF_BUFFER (1<<2) ///< detect improper bitstream length +#define AV_EF_EXPLODE (1<<3) ///< abort decoding on minor error detection + +#define AV_EF_CAREFUL (1<<16) ///< consider things that violate the spec, are fast to calculate and have not been seen in the wild as errors +#define AV_EF_COMPLIANT (1<<17) ///< consider all spec non compliancies as errors +#define AV_EF_AGGRESSIVE (1<<18) ///< consider things that a sane encoder should not do as an error /** @@ -2566,7 +2649,9 @@ typedef struct AVCodecContext { #define FF_IDCT_SIMPLEVIS 18 #define FF_IDCT_FAAN 20 #define FF_IDCT_SIMPLENEON 22 +#if FF_API_ARCH_ALPHA #define FF_IDCT_SIMPLEALPHA 23 +#endif /** * bits per sample/pixel from the demuxer (needed for huffyuv). @@ -2596,7 +2681,7 @@ typedef struct AVCodecContext { /** * the picture in the bitstream * - encoding: Set by libavcodec. - * - decoding: Set by libavcodec. + * - decoding: unused */ AVFrame *coded_frame; @@ -2668,13 +2753,13 @@ typedef struct AVCodecContext { */ int (*execute2)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count); +#if FF_API_THREAD_OPAQUE /** - * thread opaque - * Can be used by execute() to store some per AVCodecContext stuff. - * - encoding: set by execute() - * - decoding: set by execute() + * @deprecated this field should not be used from outside of lavc */ + attribute_deprecated void *thread_opaque; +#endif /** * noise vs. sse weight for the nsse comparsion function @@ -2761,6 +2846,11 @@ typedef struct AVCodecContext { #define FF_PROFILE_JPEG2000_DCINEMA_2K 3 #define FF_PROFILE_JPEG2000_DCINEMA_4K 4 + +#define FF_PROFILE_HEVC_MAIN 1 +#define FF_PROFILE_HEVC_MAIN_10 2 +#define FF_PROFILE_HEVC_MAIN_STILL_PICTURE 3 + /** * level * - encoding: Set by user. @@ -2801,21 +2891,22 @@ typedef struct AVCodecContext { uint8_t *subtitle_header; int subtitle_header_size; +#if FF_API_ERROR_RATE /** - * Simulates errors in the bitstream to test error concealment. - * - encoding: Set by user. - * - decoding: unused + * @deprecated use the 'error_rate' private AVOption of the mpegvideo + * encoders */ + attribute_deprecated int error_rate; +#endif +#if FF_API_CODEC_PKT /** - * Current packet as passed into the decoder, to avoid having - * to pass the packet into every function. Currently only valid - * inside lavc and get/release_buffer callbacks. - * - decoding: set by avcodec_decode_*, read by get_buffer() for setting pkt_pts - * - encoding: unused + * @deprecated this field is not supposed to be accessed from outside lavc */ + attribute_deprecated AVPacket *pkt; +#endif /** * VBV delay coded in the last frame (in periods of a 27 MHz clock). @@ -2896,6 +2987,34 @@ typedef struct AVCodecContext { * - encoding: unused */ int skip_alpha; + + /** + * Number of samples to skip after a discontinuity + * - decoding: unused + * - encoding: set by libavcodec + */ + int seek_preroll; + +#if !FF_API_DEBUG_MV + /** + * debug motion vectors + * Code outside libavcodec should access this field using AVOptions + * - encoding: Set by user. + * - decoding: Set by user. + */ + int debug_mv; +#define FF_DEBUG_VIS_MV_P_FOR 0x00000001 //visualize forward predicted MVs of P frames +#define FF_DEBUG_VIS_MV_B_FOR 0x00000002 //visualize forward predicted MVs of B frames +#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames +#endif + + /** + * custom intra quantization matrix + * Code outside libavcodec should access this field using av_codec_g/set_chroma_intra_matrix() + * - encoding: Set by user, can be NULL. + * - decoding: unused. + */ + uint16_t *chroma_intra_matrix; } AVCodecContext; AVRational av_codec_get_pkt_timebase (const AVCodecContext *avctx); @@ -2907,6 +3026,12 @@ void av_codec_set_codec_descriptor(AVCodecContext *avctx, co int av_codec_get_lowres(const AVCodecContext *avctx); void av_codec_set_lowres(AVCodecContext *avctx, int val); +int av_codec_get_seek_preroll(const AVCodecContext *avctx); +void av_codec_set_seek_preroll(AVCodecContext *avctx, int val); + +uint16_t *av_codec_get_chroma_intra_matrix(const AVCodecContext *avctx); +void av_codec_set_chroma_intra_matrix(AVCodecContext *avctx, uint16_t *val); + /** * AVProfile. */ @@ -3014,6 +3139,10 @@ typedef struct AVCodec { void (*flush)(AVCodecContext *); } AVCodec; +int av_codec_get_max_lowres(const AVCodec *codec); + +struct MpegEncContext; + /** * AVHWAccel. */ @@ -3075,6 +3204,7 @@ typedef struct AVHWAccel { * * Meaningful slice information (codec specific) is guaranteed to * be parsed at this point. This function is mandatory. + * The only exception is XvMC, that works on MB level. * * @param avctx the codec context * @param buf the slice data buffer base @@ -3102,6 +3232,17 @@ typedef struct AVHWAccel { * AVCodecContext.release_buffer(). */ int priv_data_size; + + /** + * Called for every Macroblock in a slice. + * + * XvMC uses it to replace the ff_MPV_decode_mb(). + * Instead of decoding to raw picture, MB parameters are + * stored in an array provided by the video driver. + * + * @param s the mpeg context + */ + void (*decode_mb)(struct MpegEncContext *s); } AVHWAccel; /** @@ -3225,40 +3366,6 @@ void avcodec_register(AVCodec *codec); */ void avcodec_register_all(void); - -#if FF_API_ALLOC_CONTEXT -/** - * Allocate an AVCodecContext and set its fields to default values. The - * resulting struct can be deallocated by simply calling av_free(). - * - * @return An AVCodecContext filled with default values or NULL on failure. - * @see avcodec_get_context_defaults - * - * @deprecated use avcodec_alloc_context3() - */ -attribute_deprecated -AVCodecContext *avcodec_alloc_context(void); - -/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API! - * we WILL change its arguments and name a few times! */ -attribute_deprecated -AVCodecContext *avcodec_alloc_context2(enum AVMediaType); - -/** - * Set the fields of the given AVCodecContext to default values. - * - * @param s The AVCodecContext of which the fields should be set to default values. - * @deprecated use avcodec_get_context_defaults3 - */ -attribute_deprecated -void avcodec_get_context_defaults(AVCodecContext *s); - -/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API! - * we WILL change its arguments and name a few times! */ -attribute_deprecated -void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType); -#endif - /** * Allocate an AVCodecContext and set its fields to default values. The * resulting struct can be deallocated by calling avcodec_close() on it followed @@ -3324,20 +3431,21 @@ const AVClass *avcodec_get_subtitle_rect_class(void); */ int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src); +#if FF_API_AVFRAME_LAVC /** - * Allocate an AVFrame and set its fields to default values. The resulting - * struct must be freed using avcodec_free_frame(). - * - * @return An AVFrame filled with default values or NULL on failure. - * @see avcodec_get_frame_defaults + * @deprecated use av_frame_alloc() */ +attribute_deprecated AVFrame *avcodec_alloc_frame(void); /** * Set the fields of the given AVFrame to default values. * * @param frame The AVFrame of which the fields should be set to default values. + * + * @deprecated use av_frame_unref() */ +attribute_deprecated void avcodec_get_frame_defaults(AVFrame *frame); /** @@ -3349,41 +3457,11 @@ void avcodec_get_frame_defaults(AVFrame *frame); * @warning this function does NOT free the data buffers themselves * (it does not know how, since they might have been allocated with * a custom get_buffer()). - */ -void avcodec_free_frame(AVFrame **frame); - -#if FF_API_AVCODEC_OPEN -/** - * Initialize the AVCodecContext to use the given AVCodec. Prior to using this - * function the context has to be allocated. * - * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(), - * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for - * retrieving a codec. - * - * @warning This function is not thread safe! - * - * @code - * avcodec_register_all(); - * codec = avcodec_find_decoder(AV_CODEC_ID_H264); - * if (!codec) - * exit(1); - * - * context = avcodec_alloc_context3(codec); - * - * if (avcodec_open(context, codec) < 0) - * exit(1); - * @endcode - * - * @param avctx The context which will be set up to use the given codec. - * @param codec The codec to use within the context. - * @return zero on success, a negative value on error - * @see avcodec_alloc_context3, avcodec_find_decoder, avcodec_find_encoder, avcodec_close - * - * @deprecated use avcodec_open2 + * @deprecated use av_frame_free() */ attribute_deprecated -int avcodec_open(AVCodecContext *avctx, AVCodec *codec); +void avcodec_free_frame(AVFrame **frame); #endif /** @@ -3575,6 +3653,24 @@ int av_packet_merge_side_data(AVPacket *pkt); int av_packet_split_side_data(AVPacket *pkt); +/** + * Pack a dictionary for use in side_data. + * + * @param dict The dictionary to pack. + * @param size pointer to store the size of the returned data + * @return pointer to data if successful, NULL otherwise + */ +uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size); +/** + * Unpack a dictionary from side_data. + * + * @param data data from side_data + * @param size size of the data + * @param dict the metadata storage dictionary + * @return 0 on success, < 0 on failure + */ +int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **dict); + /** * Convenience function to free all the side data stored. @@ -3674,14 +3770,20 @@ attribute_deprecated int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame */ int avcodec_default_get_buffer2(AVCodecContext *s, AVFrame *frame, int flags); +#if FF_API_EMU_EDGE /** * Return the amount of padding in pixels which the get_buffer callback must * provide around the edge of the image for codecs which do not have the * CODEC_FLAG_EMU_EDGE flag. * * @return Required padding in pixels. + * + * @deprecated CODEC_FLAG_EMU_EDGE is deprecated, so this function is no longer + * needed */ +attribute_deprecated unsigned avcodec_get_edge_width(void); +#endif /** * Modify width and height values so that they will result in a memory @@ -3689,8 +3791,6 @@ unsigned avcodec_get_edge_width(void); * padding. * * May only be used if a codec with CODEC_CAP_DR1 has been opened. - * If CODEC_FLAG_EMU_EDGE is not set, the dimensions must have been increased - * according to avcodec_get_edge_width() before. */ void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height); @@ -3700,8 +3800,6 @@ void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height); * line sizes are a multiple of the respective linesize_align[i]. * * May only be used if a codec with CODEC_CAP_DR1 has been opened. - * If CODEC_FLAG_EMU_EDGE is not set, the dimensions must have been increased - * according to avcodec_get_edge_width() before. */ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, int linesize_align[AV_NUM_DATA_POINTERS]); @@ -3792,19 +3890,25 @@ attribute_deprecated int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *s * Decode the audio frame of size avpkt->size from avpkt->data into frame. * * Some decoders may support multiple frames in a single AVPacket. Such - * decoders would then just decode the first frame. In this case, - * avcodec_decode_audio4 has to be called again with an AVPacket containing - * the remaining data in order to decode the second frame, etc... - * Even if no frames are returned, the packet needs to be fed to the decoder - * with remaining data until it is completely consumed or an error occurs. + * decoders would then just decode the first frame and the return value would be + * less than the packet size. In this case, avcodec_decode_audio4 has to be + * called again with an AVPacket containing the remaining data in order to + * decode the second frame, etc... Even if no frames are returned, the packet + * needs to be fed to the decoder with remaining data until it is completely + * consumed or an error occurs. + * + * Some decoders (those marked with CODEC_CAP_DELAY) have a delay between input + * and output. This means that for some packets they will not immediately + * produce decoded output and need to be flushed at the end of decoding to get + * all the decoded data. Flushing is done by calling this function with packets + * with avpkt->data set to NULL and avpkt->size set to 0 until it stops + * returning samples. It is safe to flush even those decoders that are not + * marked with CODEC_CAP_DELAY, then no samples will be returned. * * @warning The input buffer, avpkt->data must be FF_INPUT_BUFFER_PADDING_SIZE * larger than the actual read bytes because some optimized bitstream * readers read 32 or 64 bits at once and could read over the end. * - * @note You might have to align the input buffer. The alignment requirements - * depend on the CPU and the decoder. - * * @param avctx the codec context * @param[out] frame The AVFrame in which to store decoded audio samples. * The decoder will allocate a buffer for the decoded frame by @@ -3819,7 +3923,10 @@ attribute_deprecated int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *s * next call to this function or until closing or flushing the * decoder. The caller may not write to it. * @param[out] got_frame_ptr Zero if no frame could be decoded, otherwise it is - * non-zero. + * non-zero. Note that this field being set to zero + * does not mean that an error has occurred. For + * decoders with CODEC_CAP_DELAY set, no given decode + * call is guaranteed to produce a frame. * @param[in] avpkt The input AVPacket containing the input buffer. * At least avpkt->data and avpkt->size should be set. Some * decoders might also require additional fields to be set. @@ -3842,13 +3949,6 @@ int avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame, * @warning The end of the input buffer buf should be set to 0 to ensure that * no overreading happens for damaged MPEG streams. * - * @note You might have to align the input buffer avpkt->data. - * The alignment requirements depend on the CPU: on some CPUs it isn't - * necessary at all, on others it won't work at all if not aligned and on others - * it will work but it will have an impact on performance. - * - * In practice, avpkt->data should have 4 byte alignment at minimum. - * * @note Codecs which have the CODEC_CAP_DELAY capability set have a delay * between input and output, these need to be fed with avpkt->data=NULL, * avpkt->size=0 at the end to return the remaining frames. @@ -3891,6 +3991,14 @@ int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, * and reusing a get_buffer written for video codecs would probably perform badly * due to a potentially very different allocation pattern. * + * Some decoders (those marked with CODEC_CAP_DELAY) have a delay between input + * and output. This means that for some packets they will not immediately + * produce decoded output and need to be flushed at the end of decoding to get + * all the decoded data. Flushing is done by calling this function with packets + * with avpkt->data set to NULL and avpkt->size set to 0 until it stops + * returning subtitles. It is safe to flush even those decoders that are not + * marked with CODEC_CAP_DELAY, then no subtitles will be returned. + * * @param avctx the codec context * @param[out] sub The AVSubtitle in which the decoded subtitle will be stored, must be freed with avsubtitle_free if *got_sub_ptr is set. @@ -4655,12 +4763,20 @@ enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const en * @} */ +#if FF_API_SET_DIMENSIONS +/** + * @deprecated this function is not supposed to be used from outside of lavc + */ +attribute_deprecated void avcodec_set_dimensions(AVCodecContext *s, int width, int height); +#endif /** * Put a string representing the codec tag codec_tag in buf. * + * @param buf buffer to place codec tag in * @param buf_size size in bytes of buf + * @param codec_tag codec tag to assign * @return the length of the string that would have been generated if * enough space had been available, excluding the trailing null */ @@ -4851,27 +4967,6 @@ AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f); /* memory */ -/** - * Reallocate the given block if it is not large enough, otherwise do nothing. - * - * @see av_realloc - */ -void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size); - -/** - * Allocate a buffer, reusing the given one if large enough. - * - * Contrary to av_fast_realloc the current buffer contents might not be - * preserved and on error the old buffer is freed, thus no special - * handling to avoid memleaks is necessary. - * - * @param ptr pointer to pointer to already allocated buffer, overwritten with pointer to new buffer - * @param size size of the buffer *ptr points to - * @param min_size minimum size of *ptr buffer after returning, *ptr will be NULL and - * *size 0 if an error occurred. - */ -void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size); - /** * Same behaviour av_fast_malloc but the buffer has additional * FF_INPUT_BUFFER_PADDING_SIZE at the end which will always be 0. diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/avpacket.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/avpacket.c index bee159d01..f966bfe89 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/avpacket.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/avpacket.c @@ -237,6 +237,7 @@ int av_copy_packet_side_data(AVPacket *pkt, AVPacket *src) pkt->side_data[i].type = src->side_data[i].type; } } + pkt->side_data_elems = src->side_data_elems; return 0; failed_alloc: @@ -380,7 +381,7 @@ FF_ENABLE_DEPRECATION_WARNINGS int av_packet_split_side_data(AVPacket *pkt){ if (!pkt->side_data_elems && pkt->size >12 && AV_RB64(pkt->data + pkt->size - 8) == FF_MERGE_MARKER){ int i; - unsigned int size, orig_pktsize = pkt->size; + unsigned int size; uint8_t *p; p = pkt->data + pkt->size - 8 - 5; @@ -401,7 +402,7 @@ int av_packet_split_side_data(AVPacket *pkt){ for (i=0; ; i++){ size= AV_RB32(p); av_assert0(size<=INT_MAX && p - pkt->data >= size); - pkt->side_data[i].data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); + pkt->side_data[i].data = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE); pkt->side_data[i].size = size; pkt->side_data[i].type = p[4]&127; if (!pkt->side_data[i].data) @@ -413,19 +414,72 @@ int av_packet_split_side_data(AVPacket *pkt){ p-= size+5; } pkt->size -= 8; - /* FFMIN() prevents overflow in case the packet wasn't allocated with - * proper padding. - * If the side data is smaller than the buffer padding size, the - * remaining bytes should have already been filled with zeros by the - * original packet allocation anyway. */ - memset(pkt->data + pkt->size, 0, - FFMIN(orig_pktsize - pkt->size, FF_INPUT_BUFFER_PADDING_SIZE)); pkt->side_data_elems = i+1; return 1; } return 0; } +uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size) +{ + AVDictionaryEntry *t = NULL; + uint8_t *data = NULL; + *size = 0; + + if (!dict) + return NULL; + + while ((t = av_dict_get(dict, "", t, AV_DICT_IGNORE_SUFFIX))) { + const size_t keylen = strlen(t->key); + const size_t valuelen = strlen(t->value); + const size_t new_size = *size + keylen + 1 + valuelen + 1; + uint8_t *const new_data = av_realloc(data, new_size); + + if (!new_data) + goto fail; + data = new_data; + if (new_size > INT_MAX) + goto fail; + + memcpy(data + *size, t->key, keylen + 1); + memcpy(data + *size + keylen + 1, t->value, valuelen + 1); + + *size = new_size; + } + + return data; + +fail: + av_freep(&data); + *size = 0; + return NULL; +} + +int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **dict) +{ + const uint8_t *end = data + size; + int ret = 0; + + if (!dict || !data || !size) + return ret; + if (size && end[-1]) + return AVERROR_INVALIDDATA; + while (data < end) { + const uint8_t *key = data; + const uint8_t *val = data + strlen(key) + 1; + + if (val >= end) + return AVERROR_INVALIDDATA; + + ret = av_dict_set(dict, key, val, 0); + if (ret < 0) + break; + data = val + strlen(val) + 1; + } + + return ret; +} + int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type, int size) { diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/bitstream.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/bitstream.c index 5129c12bb..b38c5d222 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/bitstream.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/bitstream.c @@ -112,8 +112,11 @@ static int alloc_table(VLC *vlc, int size, int use_static) abort(); // cannot do anything, init_vlc() is used with too little memory vlc->table_allocated += (1 << vlc->bits); vlc->table = av_realloc_f(vlc->table, vlc->table_allocated, sizeof(VLC_TYPE) * 2); - if (!vlc->table) + if (!vlc->table) { + vlc->table_allocated = 0; + vlc->table_size = 0; return AVERROR(ENOMEM); + } } return index; } @@ -229,6 +232,7 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes, /* note: realloc has been done, so reload tables */ table = &vlc->table[table_index]; table[j][0] = index; //code + av_assert0(table[j][0] == index); i = k-1; } } diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/codec_desc.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/codec_desc.c index 6ec9cefac..8aafa4e19 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/codec_desc.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/codec_desc.c @@ -21,10 +21,10 @@ #include -#include "avcodec.h" - #include "libavutil/common.h" #include "libavutil/internal.h" +#include "avcodec.h" +#include "version.h" static const AVCodecDescriptor codec_descriptors[] = { /* video codecs */ @@ -42,6 +42,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 video"), .props = AV_CODEC_PROP_LOSSY, }, +#if FF_API_XVMC { .id = AV_CODEC_ID_MPEG2VIDEO_XVMC, .type = AVMEDIA_TYPE_VIDEO, @@ -49,6 +50,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video XvMC (X-Video Motion Compensation)"), .props = AV_CODEC_PROP_LOSSY, }, +#endif /* FF_API_XVMC */ { .id = AV_CODEC_ID_H261, .type = AVMEDIA_TYPE_VIDEO, @@ -225,13 +227,6 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"), .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_LOSSLESS, }, - { - .id = AV_CODEC_ID_H265, - .type = AVMEDIA_TYPE_VIDEO, - .name = "h265", - .long_name = NULL_IF_CONFIG_SMALL("H.265 / HEVC"), - .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_LOSSLESS, - }, { .id = AV_CODEC_ID_INDEO3, .type = AVMEDIA_TYPE_VIDEO, @@ -1394,6 +1389,27 @@ static const AVCodecDescriptor codec_descriptors[] = { .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_LOSSLESS, }, + { + .id = AV_CODEC_ID_HNM4_VIDEO, + .type = AVMEDIA_TYPE_VIDEO, + .name = "hnm4video", + .long_name = NULL_IF_CONFIG_SMALL("HNM 4 video"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_HEVC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "hevc", + .long_name = NULL_IF_CONFIG_SMALL("H.265 / HEVC (High Efficiency Video Coding)"), + .props = AV_CODEC_PROP_LOSSY, + }, + { + .id = AV_CODEC_ID_FIC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "fic", + .long_name = NULL_IF_CONFIG_SMALL("Mirillis FIC"), + .props = AV_CODEC_PROP_LOSSY, + }, /* various PCM "codecs" */ { @@ -1853,6 +1869,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("ADPCM IMA Radical"), .props = AV_CODEC_PROP_LOSSY, }, + { + .id = AV_CODEC_ID_ADPCM_G726LE, + .type = AVMEDIA_TYPE_AUDIO, + .name = "adpcm_g726le", + .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM little-endian"), + .props = AV_CODEC_PROP_LOSSY, + }, /* AMR */ { @@ -2606,6 +2629,12 @@ static const AVCodecDescriptor codec_descriptors[] = { .name = "dvd_nav_packet", .long_name = NULL_IF_CONFIG_SMALL("DVD Nav packet"), }, + { + .id = AV_CODEC_ID_TIMED_ID3, + .type = AVMEDIA_TYPE_DATA, + .name = "timed_id3", + .long_name = NULL_IF_CONFIG_SMALL("timed ID3 metadata"), + }, }; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dca.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dca.c index 1c1c08035..fcdfef214 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dca.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dca.c @@ -25,8 +25,10 @@ #include #include -#include "put_bits.h" +#include "libavutil/error.h" + #include "dca.h" +#include "put_bits.h" const uint32_t avpriv_dca_sample_rates[16] = { diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dcadata.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dcadata.h index 15df49eba..0ae125c2f 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dcadata.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dcadata.h @@ -7305,224 +7305,222 @@ DECLARE_ALIGNED(16, static const float, fir_32bands_nonperfect)[] = +1.390191784E-007 }; +/* pre-scale lfe fir coefficients */ +#define SCALE(c) ((c) / (256.0f * 32768.0f)) DECLARE_ALIGNED(16, static const float, lfe_fir_64)[] = { - 2.658434386830777e-4, 9.029330685734748e-3, - 7.939263433218002e-2, 2.425158768892288e-1, - 3.430179357528686e-1, 2.398228943347931e-1, - 7.746443897485733e-2, 8.622321300208569e-3, - 8.179365249816328e-5, 9.450953453779220e-3, - 8.134882897138596e-2, 2.451938837766648e-1, - 3.429597318172455e-1, 2.371159791946411e-1, - 7.556436210870743e-2, 8.229630999267101e-3, - 9.439323912374676e-5, 9.887560270726680e-3, - 8.333285897970200e-2, 2.478559017181396e-1, - 3.428434133529663e-1, 2.343961596488952e-1, - 7.369252294301987e-2, 7.850865833461285e-3, - 1.082170274457894e-4, 1.033949479460716e-2, - 8.534456789493561e-2, 2.505008876323700e-1, - 3.426689505577088e-1, 2.316644787788391e-1, - 7.184901088476181e-2, 7.485736627131701e-3, - 1.233371440321207e-4, 1.080708485096693e-2, - 8.738376945257187e-2, 2.531278133392334e-1, - 3.424364924430847e-1, 2.289219647645950e-1, - 7.003392279148102e-2, 7.133882027119398e-3, - 1.397485757479444e-4, 1.129068247973919e-2, - 8.945026248693466e-2, 2.557355761528015e-1, - 3.421461284160614e-1, 2.261696159839630e-1, - 6.824731826782227e-2, 6.794991903007030e-3, - 1.575958012836054e-4, 1.179065089672804e-2, - 9.154383838176728e-2, 2.583232223987580e-1, - 3.417979776859284e-1, 2.234084606170654e-1, - 6.648923456668854e-2, 6.468691397458315e-3, - 1.769922382663936e-4, 1.230732165277004e-2, - 9.366425126791000e-2, 2.608896791934967e-1, - 3.413922190666198e-1, 2.206395119428635e-1, - 6.475970894098282e-2, 6.154712289571762e-3, - 1.981738605536520e-4, 1.284105982631445e-2, - 9.581124037504196e-2, 2.634339034557342e-1, - 3.409290313720703e-1, 2.178637981414795e-1, - 6.305878609418869e-2, 5.852684378623962e-3, - 2.211847313446924e-4, 1.339218579232693e-2, - 9.798453748226166e-2, 2.659549415111542e-1, - 3.404086530208588e-1, 2.150822728872299e-1, - 6.138643622398376e-2, 5.562345497310162e-3, - 2.460231189616024e-4, 1.396108977496624e-2, - 1.001838669180870e-1, 2.684516608715058e-1, - 3.398312926292420e-1, 2.122959494590759e-1, - 5.974265560507774e-2, 5.283284001052380e-3, - 2.726115926634520e-4, 1.454808749258518e-2, - 1.024089083075523e-1, 2.709231376647949e-1, - 3.391972482204438e-1, 2.095058411359787e-1, - 5.812742188572884e-2, 5.015311297029257e-3, - 3.013863170053810e-4, 1.515355054289102e-2, - 1.046593263745308e-1, 2.733682692050934e-1, - 3.385068178176880e-1, 2.067128717899322e-1, - 5.654069408774376e-2, 4.758012015372515e-3, - 3.328395541757345e-4, 1.577781140804291e-2, - 1.069347932934761e-1, 2.757860720157624e-1, - 3.377602994441986e-1, 2.039180546998978e-1, - 5.498242005705833e-2, 4.511159844696522e-3, - 3.658991190604866e-4, 1.642123050987720e-2, - 1.092349365353584e-1, 2.781755328178406e-1, - 3.369580209255218e-1, 2.011223286390304e-1, - 5.345252528786659e-2, 4.274417180567980e-3, - 4.018281470052898e-4, 1.708412915468216e-2, - 1.115593686699867e-1, 2.805356979370117e-1, - 3.361004292964936e-1, 1.983266174793244e-1, - 5.195093154907227e-2, 4.047499038279056e-3, - 4.401875485200435e-4, 1.776690222322941e-2, - 1.139076948165894e-1, 2.828655838966370e-1, - 3.351879119873047e-1, 1.955319195985794e-1, - 5.047753453254700e-2, 3.830091329291463e-3, - 4.812776169274002e-4, 1.846982724964619e-2, - 1.162794977426529e-1, 2.851640880107880e-1, - 3.342207968235016e-1, 1.927391141653061e-1, - 4.903224110603333e-2, 3.621967276558280e-3, - 5.252459668554366e-4, 1.919330470263958e-2, - 1.186743453145027e-1, 2.874303460121155e-1, - 3.331996202468872e-1, 1.899491697549820e-1, - 4.761491715908051e-2, 3.422776935622096e-3, - 5.721592460758984e-4, 1.993762329220772e-2, - 1.210917681455612e-1, 2.896633744239807e-1, - 3.321248590946198e-1, 1.871629506349564e-1, - 4.622544348239899e-2, 3.232272574678064e-3, - 6.222130032256246e-4, 2.070316113531590e-2, - 1.235313042998314e-1, 2.918621897697448e-1, - 3.309969604015350e-1, 1.843813359737396e-1, - 4.486365616321564e-2, 3.050152910873294e-3, - 6.755515350960195e-4, 2.149021252989769e-2, - 1.259924471378326e-1, 2.940258979797364e-1, - 3.298164308071136e-1, 1.816052496433258e-1, - 4.352942481637001e-2, 2.876190468668938e-3, - 7.324148900806904e-4, 2.229913882911205e-2, - 1.284746825695038e-1, 2.961534857749939e-1, - 3.285838961601258e-1, 1.788355410099030e-1, - 4.222255200147629e-2, 2.710093278437853e-3, - 7.928516715764999e-4, 2.313023805618286e-2, - 1.309774816036224e-1, 2.982441186904907e-1, - 3.272998929023742e-1, 1.760730892419815e-1, - 4.094288870692253e-2, 2.551567042246461e-3, - 8.570110658183694e-4, 2.398385666310787e-2, - 1.335003077983856e-1, 3.002967536449432e-1, - 3.259649574756622e-1, 1.733186990022659e-1, - 3.969023004174232e-2, 2.400433411821723e-3, - 9.251192095689476e-4, 2.486028522253036e-2, - 1.360425949096680e-1, 3.023106753826142e-1, - 3.245797157287598e-1, 1.705732345581055e-1, - 3.846437484025955e-2, 2.256359672173858e-3, - 9.974770946428180e-4, 2.575986087322235e-2, - 1.386037617921829e-1, 3.042849004268646e-1, - 3.231448531150818e-1, 1.678375005722046e-1, - 3.726511076092720e-2, 2.119151875376701e-3, - 1.073930296115577e-3, 2.668286114931106e-2, - 1.411831974983215e-1, 3.062185347080230e-1, - 3.216609656810760e-1, 1.651122719049454e-1, - 3.609224036335945e-2, 1.988604199141264e-3, - 1.155023579485714e-3, 2.762960828840732e-2, - 1.437802612781525e-1, 3.081108033657074e-1, - 3.201287388801574e-1, 1.623983532190323e-1, - 3.494550660252571e-2, 1.864377525635064e-3, - 1.240676851011813e-3, 2.860039286315441e-2, - 1.463943719863892e-1, 3.099608123302460e-1, - 3.185488879680634e-1, 1.596965193748474e-1, - 3.382468968629837e-2, 1.746327499859035e-3, - 1.331258914433420e-3, 2.959549613296986e-2, - 1.490248143672943e-1, 3.117676973342896e-1, - 3.169221282005310e-1, 1.570075154304504e-1, - 3.272953629493714e-2, 1.634211512282491e-3, - 1.426893868483603e-3, 3.061520494520664e-2, - 1.516709625720978e-1, 3.135308027267456e-1, - 3.152491748332978e-1, 1.543320864439010e-1, - 3.165979683399200e-2, 1.527829794213176e-3, + SCALE(2.658434386830777e-4), SCALE(9.029330685734748e-3), + SCALE(7.939263433218002e-2), SCALE(2.425158768892288e-1), + SCALE(3.430179357528686e-1), SCALE(2.398228943347931e-1), + SCALE(7.746443897485733e-2), SCALE(8.622321300208569e-3), + SCALE(8.179365249816328e-5), SCALE(9.450953453779220e-3), + SCALE(8.134882897138596e-2), SCALE(2.451938837766648e-1), + SCALE(3.429597318172455e-1), SCALE(2.371159791946411e-1), + SCALE(7.556436210870743e-2), SCALE(8.229630999267101e-3), + SCALE(9.439323912374676e-5), SCALE(9.887560270726680e-3), + SCALE(8.333285897970200e-2), SCALE(2.478559017181396e-1), + SCALE(3.428434133529663e-1), SCALE(2.343961596488952e-1), + SCALE(7.369252294301987e-2), SCALE(7.850865833461285e-3), + SCALE(1.082170274457894e-4), SCALE(1.033949479460716e-2), + SCALE(8.534456789493561e-2), SCALE(2.505008876323700e-1), + SCALE(3.426689505577088e-1), SCALE(2.316644787788391e-1), + SCALE(7.184901088476181e-2), SCALE(7.485736627131701e-3), + SCALE(1.233371440321207e-4), SCALE(1.080708485096693e-2), + SCALE(8.738376945257187e-2), SCALE(2.531278133392334e-1), + SCALE(3.424364924430847e-1), SCALE(2.289219647645950e-1), + SCALE(7.003392279148102e-2), SCALE(7.133882027119398e-3), + SCALE(1.397485757479444e-4), SCALE(1.129068247973919e-2), + SCALE(8.945026248693466e-2), SCALE(2.557355761528015e-1), + SCALE(3.421461284160614e-1), SCALE(2.261696159839630e-1), + SCALE(6.824731826782227e-2), SCALE(6.794991903007030e-3), + SCALE(1.575958012836054e-4), SCALE(1.179065089672804e-2), + SCALE(9.154383838176728e-2), SCALE(2.583232223987580e-1), + SCALE(3.417979776859284e-1), SCALE(2.234084606170654e-1), + SCALE(6.648923456668854e-2), SCALE(6.468691397458315e-3), + SCALE(1.769922382663936e-4), SCALE(1.230732165277004e-2), + SCALE(9.366425126791000e-2), SCALE(2.608896791934967e-1), + SCALE(3.413922190666198e-1), SCALE(2.206395119428635e-1), + SCALE(6.475970894098282e-2), SCALE(6.154712289571762e-3), + SCALE(1.981738605536520e-4), SCALE(1.284105982631445e-2), + SCALE(9.581124037504196e-2), SCALE(2.634339034557342e-1), + SCALE(3.409290313720703e-1), SCALE(2.178637981414795e-1), + SCALE(6.305878609418869e-2), SCALE(5.852684378623962e-3), + SCALE(2.211847313446924e-4), SCALE(1.339218579232693e-2), + SCALE(9.798453748226166e-2), SCALE(2.659549415111542e-1), + SCALE(3.404086530208588e-1), SCALE(2.150822728872299e-1), + SCALE(6.138643622398376e-2), SCALE(5.562345497310162e-3), + SCALE(2.460231189616024e-4), SCALE(1.396108977496624e-2), + SCALE(1.001838669180870e-1), SCALE(2.684516608715058e-1), + SCALE(3.398312926292420e-1), SCALE(2.122959494590759e-1), + SCALE(5.974265560507774e-2), SCALE(5.283284001052380e-3), + SCALE(2.726115926634520e-4), SCALE(1.454808749258518e-2), + SCALE(1.024089083075523e-1), SCALE(2.709231376647949e-1), + SCALE(3.391972482204438e-1), SCALE(2.095058411359787e-1), + SCALE(5.812742188572884e-2), SCALE(5.015311297029257e-3), + SCALE(3.013863170053810e-4), SCALE(1.515355054289102e-2), + SCALE(1.046593263745308e-1), SCALE(2.733682692050934e-1), + SCALE(3.385068178176880e-1), SCALE(2.067128717899322e-1), + SCALE(5.654069408774376e-2), SCALE(4.758012015372515e-3), + SCALE(3.328395541757345e-4), SCALE(1.577781140804291e-2), + SCALE(1.069347932934761e-1), SCALE(2.757860720157624e-1), + SCALE(3.377602994441986e-1), SCALE(2.039180546998978e-1), + SCALE(5.498242005705833e-2), SCALE(4.511159844696522e-3), + SCALE(3.658991190604866e-4), SCALE(1.642123050987720e-2), + SCALE(1.092349365353584e-1), SCALE(2.781755328178406e-1), + SCALE(3.369580209255218e-1), SCALE(2.011223286390304e-1), + SCALE(5.345252528786659e-2), SCALE(4.274417180567980e-3), + SCALE(4.018281470052898e-4), SCALE(1.708412915468216e-2), + SCALE(1.115593686699867e-1), SCALE(2.805356979370117e-1), + SCALE(3.361004292964936e-1), SCALE(1.983266174793244e-1), + SCALE(5.195093154907227e-2), SCALE(4.047499038279056e-3), + SCALE(4.401875485200435e-4), SCALE(1.776690222322941e-2), + SCALE(1.139076948165894e-1), SCALE(2.828655838966370e-1), + SCALE(3.351879119873047e-1), SCALE(1.955319195985794e-1), + SCALE(5.047753453254700e-2), SCALE(3.830091329291463e-3), + SCALE(4.812776169274002e-4), SCALE(1.846982724964619e-2), + SCALE(1.162794977426529e-1), SCALE(2.851640880107880e-1), + SCALE(3.342207968235016e-1), SCALE(1.927391141653061e-1), + SCALE(4.903224110603333e-2), SCALE(3.621967276558280e-3), + SCALE(5.252459668554366e-4), SCALE(1.919330470263958e-2), + SCALE(1.186743453145027e-1), SCALE(2.874303460121155e-1), + SCALE(3.331996202468872e-1), SCALE(1.899491697549820e-1), + SCALE(4.761491715908051e-2), SCALE(3.422776935622096e-3), + SCALE(5.721592460758984e-4), SCALE(1.993762329220772e-2), + SCALE(1.210917681455612e-1), SCALE(2.896633744239807e-1), + SCALE(3.321248590946198e-1), SCALE(1.871629506349564e-1), + SCALE(4.622544348239899e-2), SCALE(3.232272574678064e-3), + SCALE(6.222130032256246e-4), SCALE(2.070316113531590e-2), + SCALE(1.235313042998314e-1), SCALE(2.918621897697448e-1), + SCALE(3.309969604015350e-1), SCALE(1.843813359737396e-1), + SCALE(4.486365616321564e-2), SCALE(3.050152910873294e-3), + SCALE(6.755515350960195e-4), SCALE(2.149021252989769e-2), + SCALE(1.259924471378326e-1), SCALE(2.940258979797364e-1), + SCALE(3.298164308071136e-1), SCALE(1.816052496433258e-1), + SCALE(4.352942481637001e-2), SCALE(2.876190468668938e-3), + SCALE(7.324148900806904e-4), SCALE(2.229913882911205e-2), + SCALE(1.284746825695038e-1), SCALE(2.961534857749939e-1), + SCALE(3.285838961601258e-1), SCALE(1.788355410099030e-1), + SCALE(4.222255200147629e-2), SCALE(2.710093278437853e-3), + SCALE(7.928516715764999e-4), SCALE(2.313023805618286e-2), + SCALE(1.309774816036224e-1), SCALE(2.982441186904907e-1), + SCALE(3.272998929023742e-1), SCALE(1.760730892419815e-1), + SCALE(4.094288870692253e-2), SCALE(2.551567042246461e-3), + SCALE(8.570110658183694e-4), SCALE(2.398385666310787e-2), + SCALE(1.335003077983856e-1), SCALE(3.002967536449432e-1), + SCALE(3.259649574756622e-1), SCALE(1.733186990022659e-1), + SCALE(3.969023004174232e-2), SCALE(2.400433411821723e-3), + SCALE(9.251192095689476e-4), SCALE(2.486028522253036e-2), + SCALE(1.360425949096680e-1), SCALE(3.023106753826142e-1), + SCALE(3.245797157287598e-1), SCALE(1.705732345581055e-1), + SCALE(3.846437484025955e-2), SCALE(2.256359672173858e-3), + SCALE(9.974770946428180e-4), SCALE(2.575986087322235e-2), + SCALE(1.386037617921829e-1), SCALE(3.042849004268646e-1), + SCALE(3.231448531150818e-1), SCALE(1.678375005722046e-1), + SCALE(3.726511076092720e-2), SCALE(2.119151875376701e-3), + SCALE(1.073930296115577e-3), SCALE(2.668286114931106e-2), + SCALE(1.411831974983215e-1), SCALE(3.062185347080230e-1), + SCALE(3.216609656810760e-1), SCALE(1.651122719049454e-1), + SCALE(3.609224036335945e-2), SCALE(1.988604199141264e-3), + SCALE(1.155023579485714e-3), SCALE(2.762960828840732e-2), + SCALE(1.437802612781525e-1), SCALE(3.081108033657074e-1), + SCALE(3.201287388801574e-1), SCALE(1.623983532190323e-1), + SCALE(3.494550660252571e-2), SCALE(1.864377525635064e-3), + SCALE(1.240676851011813e-3), SCALE(2.860039286315441e-2), + SCALE(1.463943719863892e-1), SCALE(3.099608123302460e-1), + SCALE(3.185488879680634e-1), SCALE(1.596965193748474e-1), + SCALE(3.382468968629837e-2), SCALE(1.746327499859035e-3), + SCALE(1.331258914433420e-3), SCALE(2.959549613296986e-2), + SCALE(1.490248143672943e-1), SCALE(3.117676973342896e-1), + SCALE(3.169221282005310e-1), SCALE(1.570075154304504e-1), + SCALE(3.272953629493714e-2), SCALE(1.634211512282491e-3), + SCALE(1.426893868483603e-3), SCALE(3.061520494520664e-2), + SCALE(1.516709625720978e-1), SCALE(3.135308027267456e-1), + SCALE(3.152491748332978e-1), SCALE(1.543320864439010e-1), + SCALE(3.165979683399200e-2), SCALE(1.527829794213176e-3), }; DECLARE_ALIGNED(16, static const float, lfe_fir_128)[] = { - 0.00053168571, 0.15878495574, 0.68603444099, 0.15492856503, - 0.00016358691, 0.16269733012, 0.68591803312, 0.15112841129, - 0.00018878609, 0.16666537523, 0.68568539619, 0.14738474786, - 0.00021643363, 0.17068879306, 0.68533653021, 0.14369773865, - 0.00024667382, 0.17476719618, 0.68487155437, 0.14006754756, - 0.00027949660, 0.17890018225, 0.68429082632, 0.13649433851, - 0.00031519096, 0.18308731914, 0.68359452486, 0.13297818601, - 0.00035398375, 0.18732811511, 0.68278300762, 0.12951917946, - 0.00039634691, 0.19162209332, 0.68185669184, 0.12611730397, - 0.00044236859, 0.19596865773, 0.68081587553, 0.12277261168, - 0.00049204525, 0.20036731660, 0.67966115475, 0.11948505789, - 0.00054522208, 0.20481738448, 0.67839306593, 0.11625462025, - 0.00060277141, 0.20931822062, 0.67701220512, 0.11308115721, - 0.00066567765, 0.21386915445, 0.67551922798, 0.10996460915, - 0.00073179678, 0.21846942604, 0.67391467094, 0.10690483451, - 0.00080365466, 0.22311829031, 0.67219948769, 0.10390164703, - 0.00088037323, 0.22781492770, 0.67037439346, 0.10095486045, - 0.00096255314, 0.23255851865, 0.66844022274, 0.09806428105, - 0.00105048984, 0.23734821379, 0.66639786959, 0.09522963315, - 0.00114431616, 0.24218304455, 0.66424828768, 0.09245070815, - 0.00124442333, 0.24706205726, 0.66199249029, 0.08972713351, - 0.00135110028, 0.25198432803, 0.65963155031, 0.08705867827, - 0.00146482687, 0.25694879889, 0.65716648102, 0.08444493264, - 0.00158570008, 0.26195442677, 0.65459835529, 0.08188561350, - 0.00171401864, 0.26700007915, 0.65192854404, 0.07938029617, - 0.00185023469, 0.27208462358, 0.64915806055, 0.07692859322, - 0.00199495023, 0.27720692754, 0.64628833532, 0.07453006506, - 0.00214785640, 0.28236576915, 0.64332056046, 0.07218432426, - 0.00231004250, 0.28755992651, 0.64025616646, 0.06989086419, - 0.00248134881, 0.29278811812, 0.63709646463, 0.06764923781, - 0.00266251224, 0.29804900289, 0.63384294510, 0.06545893103, - 0.00285378192, 0.30334126949, 0.63049703836, 0.06331945211, - 0.00305565330, 0.30866351724, 0.62706029415, 0.06123027951, - 0.00326841651, 0.31401440501, 0.62353414297, 0.05919086933, - 0.00349264755, 0.31939238310, 0.61992025375, 0.05720067024, - 0.00372874714, 0.32479602098, 0.61622029543, 0.05525910854, - 0.00397720048, 0.33022382855, 0.61243581772, 0.05336561054, - 0.00423829490, 0.33567428589, 0.60856848955, 0.05151961371, - 0.00451271003, 0.34114575386, 0.60462015867, 0.04972046614, - 0.00480085658, 0.34663668275, 0.60059231520, 0.04796761274, - 0.00510312291, 0.35214546323, 0.59648692608, 0.04626038298, - 0.00542017492, 0.35767036676, 0.59230577946, 0.04459818453, - 0.00575236930, 0.36320972443, 0.58805054426, 0.04298033938, - 0.00610029325, 0.36876192689, 0.58372318745, 0.04140623659, - 0.00646453211, 0.37432509661, 0.57932555676, 0.03987516090, - 0.00684553990, 0.37989753485, 0.57485944033, 0.03838652745, - 0.00724391919, 0.38547745347, 0.57032698393, 0.03693958372, - 0.00766016589, 0.39106300473, 0.56572991610, 0.03553372994, - 0.00809498038, 0.39665243030, 0.56107026339, 0.03416819125, - 0.00854881573, 0.40224379301, 0.55634999275, 0.03284239396, - 0.00902230106, 0.40783521533, 0.55157101154, 0.03155555204, - 0.00951600447, 0.41342487931, 0.54673534632, 0.03030703776, - 0.01003060210, 0.41901078820, 0.54184508324, 0.02909611352, - 0.01056654565, 0.42459106445, 0.53690224886, 0.02792212367, - 0.01112466771, 0.43016362190, 0.53190881014, 0.02678431384, - 0.01170534454, 0.43572667241, 0.52686679363, 0.02568206564, - 0.01230939943, 0.44127810001, 0.52177828550, 0.02461459488, - 0.01293735672, 0.44681602716, 0.51664537191, 0.02358125709, - 0.01358995494, 0.45233830810, 0.51147013903, 0.02258131653, - 0.01426773332, 0.45784294605, 0.50625455379, 0.02161412500, - 0.01497144438, 0.46332800388, 0.50100076199, 0.02067894675, - 0.01570170000, 0.46879136562, 0.49571081996, 0.01977507770, - 0.01645922661, 0.47423094511, 0.49038675427, 0.01890186779, - 0.01724460535, 0.47964480519, 0.48503074050, 0.01805862412, + SCALE(0.00053168571), SCALE(0.15878495574), SCALE(0.68603444099), SCALE(0.15492856503), + SCALE(0.00016358691), SCALE(0.16269733012), SCALE(0.68591803312), SCALE(0.15112841129), + SCALE(0.00018878609), SCALE(0.16666537523), SCALE(0.68568539619), SCALE(0.14738474786), + SCALE(0.00021643363), SCALE(0.17068879306), SCALE(0.68533653021), SCALE(0.14369773865), + SCALE(0.00024667382), SCALE(0.17476719618), SCALE(0.68487155437), SCALE(0.14006754756), + SCALE(0.00027949660), SCALE(0.17890018225), SCALE(0.68429082632), SCALE(0.13649433851), + SCALE(0.00031519096), SCALE(0.18308731914), SCALE(0.68359452486), SCALE(0.13297818601), + SCALE(0.00035398375), SCALE(0.18732811511), SCALE(0.68278300762), SCALE(0.12951917946), + SCALE(0.00039634691), SCALE(0.19162209332), SCALE(0.68185669184), SCALE(0.12611730397), + SCALE(0.00044236859), SCALE(0.19596865773), SCALE(0.68081587553), SCALE(0.12277261168), + SCALE(0.00049204525), SCALE(0.20036731660), SCALE(0.67966115475), SCALE(0.11948505789), + SCALE(0.00054522208), SCALE(0.20481738448), SCALE(0.67839306593), SCALE(0.11625462025), + SCALE(0.00060277141), SCALE(0.20931822062), SCALE(0.67701220512), SCALE(0.11308115721), + SCALE(0.00066567765), SCALE(0.21386915445), SCALE(0.67551922798), SCALE(0.10996460915), + SCALE(0.00073179678), SCALE(0.21846942604), SCALE(0.67391467094), SCALE(0.10690483451), + SCALE(0.00080365466), SCALE(0.22311829031), SCALE(0.67219948769), SCALE(0.10390164703), + SCALE(0.00088037323), SCALE(0.22781492770), SCALE(0.67037439346), SCALE(0.10095486045), + SCALE(0.00096255314), SCALE(0.23255851865), SCALE(0.66844022274), SCALE(0.09806428105), + SCALE(0.00105048984), SCALE(0.23734821379), SCALE(0.66639786959), SCALE(0.09522963315), + SCALE(0.00114431616), SCALE(0.24218304455), SCALE(0.66424828768), SCALE(0.09245070815), + SCALE(0.00124442333), SCALE(0.24706205726), SCALE(0.66199249029), SCALE(0.08972713351), + SCALE(0.00135110028), SCALE(0.25198432803), SCALE(0.65963155031), SCALE(0.08705867827), + SCALE(0.00146482687), SCALE(0.25694879889), SCALE(0.65716648102), SCALE(0.08444493264), + SCALE(0.00158570008), SCALE(0.26195442677), SCALE(0.65459835529), SCALE(0.08188561350), + SCALE(0.00171401864), SCALE(0.26700007915), SCALE(0.65192854404), SCALE(0.07938029617), + SCALE(0.00185023469), SCALE(0.27208462358), SCALE(0.64915806055), SCALE(0.07692859322), + SCALE(0.00199495023), SCALE(0.27720692754), SCALE(0.64628833532), SCALE(0.07453006506), + SCALE(0.00214785640), SCALE(0.28236576915), SCALE(0.64332056046), SCALE(0.07218432426), + SCALE(0.00231004250), SCALE(0.28755992651), SCALE(0.64025616646), SCALE(0.06989086419), + SCALE(0.00248134881), SCALE(0.29278811812), SCALE(0.63709646463), SCALE(0.06764923781), + SCALE(0.00266251224), SCALE(0.29804900289), SCALE(0.63384294510), SCALE(0.06545893103), + SCALE(0.00285378192), SCALE(0.30334126949), SCALE(0.63049703836), SCALE(0.06331945211), + SCALE(0.00305565330), SCALE(0.30866351724), SCALE(0.62706029415), SCALE(0.06123027951), + SCALE(0.00326841651), SCALE(0.31401440501), SCALE(0.62353414297), SCALE(0.05919086933), + SCALE(0.00349264755), SCALE(0.31939238310), SCALE(0.61992025375), SCALE(0.05720067024), + SCALE(0.00372874714), SCALE(0.32479602098), SCALE(0.61622029543), SCALE(0.05525910854), + SCALE(0.00397720048), SCALE(0.33022382855), SCALE(0.61243581772), SCALE(0.05336561054), + SCALE(0.00423829490), SCALE(0.33567428589), SCALE(0.60856848955), SCALE(0.05151961371), + SCALE(0.00451271003), SCALE(0.34114575386), SCALE(0.60462015867), SCALE(0.04972046614), + SCALE(0.00480085658), SCALE(0.34663668275), SCALE(0.60059231520), SCALE(0.04796761274), + SCALE(0.00510312291), SCALE(0.35214546323), SCALE(0.59648692608), SCALE(0.04626038298), + SCALE(0.00542017492), SCALE(0.35767036676), SCALE(0.59230577946), SCALE(0.04459818453), + SCALE(0.00575236930), SCALE(0.36320972443), SCALE(0.58805054426), SCALE(0.04298033938), + SCALE(0.00610029325), SCALE(0.36876192689), SCALE(0.58372318745), SCALE(0.04140623659), + SCALE(0.00646453211), SCALE(0.37432509661), SCALE(0.57932555676), SCALE(0.03987516090), + SCALE(0.00684553990), SCALE(0.37989753485), SCALE(0.57485944033), SCALE(0.03838652745), + SCALE(0.00724391919), SCALE(0.38547745347), SCALE(0.57032698393), SCALE(0.03693958372), + SCALE(0.00766016589), SCALE(0.39106300473), SCALE(0.56572991610), SCALE(0.03553372994), + SCALE(0.00809498038), SCALE(0.39665243030), SCALE(0.56107026339), SCALE(0.03416819125), + SCALE(0.00854881573), SCALE(0.40224379301), SCALE(0.55634999275), SCALE(0.03284239396), + SCALE(0.00902230106), SCALE(0.40783521533), SCALE(0.55157101154), SCALE(0.03155555204), + SCALE(0.00951600447), SCALE(0.41342487931), SCALE(0.54673534632), SCALE(0.03030703776), + SCALE(0.01003060210), SCALE(0.41901078820), SCALE(0.54184508324), SCALE(0.02909611352), + SCALE(0.01056654565), SCALE(0.42459106445), SCALE(0.53690224886), SCALE(0.02792212367), + SCALE(0.01112466771), SCALE(0.43016362190), SCALE(0.53190881014), SCALE(0.02678431384), + SCALE(0.01170534454), SCALE(0.43572667241), SCALE(0.52686679363), SCALE(0.02568206564), + SCALE(0.01230939943), SCALE(0.44127810001), SCALE(0.52177828550), SCALE(0.02461459488), + SCALE(0.01293735672), SCALE(0.44681602716), SCALE(0.51664537191), SCALE(0.02358125709), + SCALE(0.01358995494), SCALE(0.45233830810), SCALE(0.51147013903), SCALE(0.02258131653), + SCALE(0.01426773332), SCALE(0.45784294605), SCALE(0.50625455379), SCALE(0.02161412500), + SCALE(0.01497144438), SCALE(0.46332800388), SCALE(0.50100076199), SCALE(0.02067894675), + SCALE(0.01570170000), SCALE(0.46879136562), SCALE(0.49571081996), SCALE(0.01977507770), + SCALE(0.01645922661), SCALE(0.47423094511), SCALE(0.49038675427), SCALE(0.01890186779), + SCALE(0.01724460535), SCALE(0.47964480519), SCALE(0.48503074050), SCALE(0.01805862412), }; +#undef SCALE -/* 10^-(dB/20), with dB being a list of dB values ranging from 0 to -72 */ -/* do a 20*log10(dca_downmix_coeffs) to reconvert the values */ - -static const float dca_downmix_coeffs[65] = { - 1.000000000000000, 0.988553094656939, 0.971627951577106, 0.944060876285923, 0.917275935389780, 0.891250938133746, - 0.865964323360065, 0.841395141645195, 0.817523037943650, 0.794328234724281, 0.771791515585012, 0.749894209332456, - 0.728618174513228, 0.707945784384138, 0.687859912308808, 0.668343917568615, 0.649381631576211, 0.630957344480193, - 0.613055792149821, 0.595662143529010, 0.578761988349121, 0.562341325190349, 0.546386549881854, 0.530884444230988, - 0.515822165072306, 0.501187233627272, 0.446683592150963, 0.398107170553497, 0.354813389233575, 0.316227766016838, - 0.281838293126445, 0.251188643150958, 0.223872113856834, 0.199526231496888, 0.177827941003892, 0.158489319246111, - 0.141253754462275, 0.125892541179417, 0.112201845430196, 0.100000000000000, 0.089125093813374, 0.079432823472428, - 0.070794578438414, 0.063095734448019, 0.053088444423099, 0.044668359215096, 0.037583740428844, 0.031622776601684, - 0.026607250597988, 0.022387211385683, 0.018836490894898, 0.015848931924611, 0.013335214321633, 0.011220184543020, - 0.009440608762859, 0.007943282347243, 0.005623413251903, 0.003981071705535, 0.002818382931264, 0.001995262314969, - 0.001412537544623, 0.001000000000000, 0.000501187233627, 0.000251188643151, 0.000000000000000, -}; - -static const float dca_downmix_scale_factors[241] = { +/* + * D.11 Look-up Table for Downmix Scale Factors + * + * Note that the range of the entries in DmixTable[] is between -60 dB and 0 dB + * with addition of -inf (|DMixCoeff| = 0), which is coded with a DmixCode = 0. + * Furthermore, the range [-60 to 0] is subdivided into 3 regions, each with a + * different grid resolution: + * + * 1) [-60.000 to -30] with resolution of 0.500 dB + * 2) [-29.750 to -15] with resolution of 0.250 dB + * 3) [-14.875 to 0] with resolution of 0.125 dB + */ +static const float dca_dmixtable[241] = { 0.001000, 0.001059, 0.001122, 0.001189, 0.001259, 0.001334, 0.001413, 0.001496, 0.001585, 0.001679, 0.001778, 0.001884, 0.001995, 0.002113, 0.002239, 0.002371, 0.002512, 0.002661, 0.002818, 0.002985, 0.003162, 0.003350, 0.003548, 0.003758, @@ -7553,20 +7551,20 @@ static const float dca_downmix_scale_factors[241] = { 0.707107, 0.718208, 0.728618, 0.739180, 0.749894, 0.760764, 0.771792, 0.782979, 0.794328, 0.805842, 0.817523, 0.829373, 0.841395, 0.853591, 0.865964, 0.878517, 0.891251, 0.904170, 0.917276, 0.930572, 0.944061, 0.957745, 0.971628, 0.985712, - 1.000000 + 1.000000, }; -static const uint8_t dca_default_coeffs[10][5][2] = { - { { 13, 13 }, }, - { { 0, 64 }, { 64, 0 }, }, - { { 0, 64 }, { 64, 0 }, }, - { { 0, 64 }, { 64, 0 }, }, - { { 0, 64 }, { 64, 0 }, }, - { { 6, 6 }, { 0, 25 }, { 25, 0 }, }, - { { 0, 25 }, { 25, 0 }, { 13, 13 }, }, - { { 6, 6 }, { 0, 25 }, { 25, 0 }, { 13, 13 }, }, - { { 0, 25 }, { 25, 0 }, { 0, 13 }, { 13, 0 }, }, - { { 6, 6 }, { 0, 25 }, { 25, 0 }, { 0, 13 }, { 13, 0 }, }, +static const float dca_default_coeffs[10][6][2] = { + { { 0.707107, 0.707107 }, { 0.000000, 0.000000 }, }, // A [LFE] + { { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, { 0.000000, 0.000000 }, }, // A + B (dual mono) [LFE] + { { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, { 0.000000, 0.000000 }, }, // L + R (stereo) [LFE] + { { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, { 0.000000, 0.000000 }, }, // (L+R) + (L-R) (sum-difference) [LFE] + { { 1.000000, 0.000000 }, { 0.000000, 1.000000 }, { 0.000000, 0.000000 }, }, // LT + RT (left and right total) [LFE] + { { 0.501187, 0.501187 }, { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.000000, 0.000000 }, }, // C + L + R [LFE] + { { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.501187 }, { 0.000000, 0.000000 }, }, // L + R + S [LFE] + { { 0.501187, 0.501187 }, { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.501187 }, { 0.000000, 0.000000 }, }, // C + L + R + S [LFE] + { { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.000000 }, { 0.000000, 0.501187 }, { 0.000000, 0.000000 }, }, // L + R + SL + SR [LFE] + { { 0.501187, 0.501187 }, { 0.707107, 0.000000 }, { 0.000000, 0.707107 }, { 0.501187, 0.000000 }, { 0.000000, 0.501187 }, { 0.000000, 0.000000 }, }, // C + L + R + SL + SR [LFE] }; /* downmix coeffs diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dcadec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dcadec.c index 07aaf68c1..b33d239bf 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dcadec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dcadec.c @@ -32,6 +32,7 @@ #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" #include "libavutil/mathematics.h" +#include "libavutil/opt.h" #include "libavutil/samplefmt.h" #include "avcodec.h" #include "fft.h" @@ -52,7 +53,6 @@ //#define TRACE #define DCA_PRIM_CHANNELS_MAX (7) -#define DCA_SUBBANDS (64) #define DCA_ABITS_MAX (32) /* Should be 28 */ #define DCA_SUBSUBFRAMES_MAX (4) #define DCA_SUBFRAMES_MAX (16) @@ -325,6 +325,8 @@ static const int8_t dca_channel_reorder_nolfe_xch[][9] = { #define DCA_BUFFER_PADDING_SIZE 1024 +#define DCA_NSYNCAUX 0x9A1105A0 + /** Bit allocation */ typedef struct { int offset; ///< code values offset @@ -346,6 +348,7 @@ static av_always_inline int get_bitalloc(GetBitContext *gb, BitAlloc *ba, } typedef struct { + const AVClass *class; ///< class for AVOptions AVCodecContext *avctx; /* Frame header */ int frame_type; ///< type of the current frame @@ -358,7 +361,6 @@ typedef struct { int bit_rate; ///< transmission bit rate int bit_rate_index; ///< transmission bit rate index - int downmix; ///< embedded downmix enabled int dynrange; ///< embedded dynamic range flag int timestamp; ///< embedded time stamp flag int aux_data; ///< auxiliary data flag @@ -397,13 +399,20 @@ typedef struct { int prediction_vq[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< prediction VQ coefs int bitalloc[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< bit allocation index int transition_mode[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< transition mode (transients) - int scale_factor[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][2]; ///< scale factors (2 if transient) + int32_t scale_factor[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][2];///< scale factors (2 if transient) int joint_huff[DCA_PRIM_CHANNELS_MAX]; ///< joint subband scale factors codebook int joint_scale_factor[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< joint subband scale factors - int downmix_coef[DCA_PRIM_CHANNELS_MAX][2]; ///< stereo downmix coefficients + float downmix_coef[DCA_PRIM_CHANNELS_MAX + 1][2]; ///< stereo downmix coefficients int dynrange_coef; ///< dynamic range coefficient - int high_freq_vq[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< VQ encoded high frequency subbands + /* Core substream's embedded downmix coefficients (cf. ETSI TS 102 114 V1.4.1) + * Input: primary audio channels (incl. LFE if present) + * Output: downmix audio channels (up to 4, no LFE) */ + uint8_t core_downmix; ///< embedded downmix coefficients available + uint8_t core_downmix_amode; ///< audio channel arrangement of embedded downmix + uint16_t core_downmix_codes[DCA_PRIM_CHANNELS_MAX + 1][4]; ///< embedded downmix coefficients (9-bit codes) + + int32_t high_freq_vq[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< VQ encoded high frequency subbands float lfe_data[2 * DCA_LFE_MAX * (DCA_BLOCKS_MAX + 4)]; ///< Low frequency effect data int lfe_scale_factor; @@ -437,6 +446,7 @@ typedef struct { /* XCh extension information */ int xch_present; ///< XCh extension present and valid int xch_base_channel; ///< index of first (only) channel containing XCH data + int xch_disable; ///< whether the XCh extension should be decoded or not /* XXCH extension information */ int xxch_chset; @@ -589,7 +599,7 @@ static int dca_parse_audio_coding_header(DCAContext *s, int base_channel, if (get_bits1(&s->gb)) { embedded_downmix = get_bits1(&s->gb); scale_factor = - 1.0f / dca_downmix_scale_factors[(get_bits(&s->gb, 6) - 1) << 2]; + 1.0f / dca_dmixtable[(get_bits(&s->gb, 6) - 1) << 2]; s->xxch_dmix_sf[s->xxch_chset] = scale_factor; @@ -610,7 +620,7 @@ static int dca_parse_audio_coding_header(DCAContext *s, int base_channel, coeff = get_bits(&s->gb, 7); sign = (coeff & 64) ? 1.0 : -1.0; - mag = dca_downmix_scale_factors[((coeff & 63) - 1) << 2]; + mag = dca_dmixtable[((coeff & 63) - 1) << 2]; ichan = dca_xxch2index(s, 1 << i); s->xxch_dmix_coeff[j][ichan] = sign * mag; } @@ -724,7 +734,7 @@ static int dca_parse_frame_header(DCAContext *s) if (!s->bit_rate) return AVERROR_INVALIDDATA; - s->downmix = get_bits(&s->gb, 1); /* note: this is FixedBit == 0 */ + skip_bits1(&s->gb); // always 0 (reserved, cf. ETSI TS 102 114 V1.4.1) s->dynrange = get_bits(&s->gb, 1); s->timestamp = get_bits(&s->gb, 1); s->aux_data = get_bits(&s->gb, 1); @@ -771,7 +781,6 @@ static int dca_parse_frame_header(DCAContext *s) s->sample_rate); av_log(s->avctx, AV_LOG_DEBUG, "bit rate: %i bits/s\n", s->bit_rate); - av_log(s->avctx, AV_LOG_DEBUG, "downmix: %i\n", s->downmix); av_log(s->avctx, AV_LOG_DEBUG, "dynrange: %i\n", s->dynrange); av_log(s->avctx, AV_LOG_DEBUG, "timestamp: %i\n", s->timestamp); av_log(s->avctx, AV_LOG_DEBUG, "aux_data: %i\n", s->aux_data); @@ -954,33 +963,6 @@ static int dca_subframe_header(DCAContext *s, int base_channel, int block_index) } } - /* Stereo downmix coefficients */ - if (!base_channel && s->prim_channels > 2) { - if (s->downmix) { - for (j = base_channel; j < s->prim_channels; j++) { - s->downmix_coef[j][0] = get_bits(&s->gb, 7); - s->downmix_coef[j][1] = get_bits(&s->gb, 7); - } - } else { - int am = s->amode & DCA_CHANNEL_MASK; - if (am >= FF_ARRAY_ELEMS(dca_default_coeffs)) { - av_log(s->avctx, AV_LOG_ERROR, - "Invalid channel mode %d\n", am); - return AVERROR_INVALIDDATA; - } - if (s->prim_channels > FF_ARRAY_ELEMS(dca_default_coeffs[0])) { - avpriv_request_sample(s->avctx, "Downmixing %d channels", - s->prim_channels); - return AVERROR_PATCHWELCOME; - } - - for (j = base_channel; j < s->prim_channels; j++) { - s->downmix_coef[j][0] = dca_default_coeffs[am][j][0]; - s->downmix_coef[j][1] = dca_default_coeffs[am][j][1]; - } - } - } - /* Dynamic range coefficient */ if (!base_channel && s->dynrange) s->dynrange_coef = get_bits(&s->gb, 8); @@ -1080,16 +1062,6 @@ static int dca_subframe_header(DCAContext *s, int base_channel, int block_index) av_log(s->avctx, AV_LOG_DEBUG, "\n"); } } - if (!base_channel && s->prim_channels > 2 && s->downmix) { - av_log(s->avctx, AV_LOG_DEBUG, "Downmix coeffs:\n"); - for (j = 0; j < s->prim_channels; j++) { - av_log(s->avctx, AV_LOG_DEBUG, "Channel 0, %d = %f\n", j, - dca_downmix_coeffs[s->downmix_coef[j][0]]); - av_log(s->avctx, AV_LOG_DEBUG, "Channel 1, %d = %f\n", j, - dca_downmix_coeffs[s->downmix_coef[j][1]]); - } - av_log(s->avctx, AV_LOG_DEBUG, "\n"); - } for (j = base_channel; j < s->prim_channels; j++) for (k = s->vq_start_subband[j]; k < s->subband_activity[j]; k++) av_log(s->avctx, AV_LOG_DEBUG, "VQ index: %i\n", s->high_freq_vq[j][k]); @@ -1132,7 +1104,7 @@ static void qmf_32_subbands(DCAContext *s, int chans, static void lfe_interpolation_fir(DCAContext *s, int decimation_select, int num_deci_sample, float *samples_in, - float *samples_out, float scale) + float *samples_out) { /* samples_in: An array holding decimated samples. * Samples in current subframe starts from samples_in[0], @@ -1142,23 +1114,23 @@ static void lfe_interpolation_fir(DCAContext *s, int decimation_select, * samples_out: An array holding interpolated samples */ - int decifactor; + int idx; const float *prCoeff; int deciindex; /* Select decimation filter */ if (decimation_select == 1) { - decifactor = 64; + idx = 1; prCoeff = lfe_fir_128; } else { - decifactor = 32; + idx = 0; prCoeff = lfe_fir_64; } /* Interpolation */ for (deciindex = 0; deciindex < num_deci_sample; deciindex++) { - s->dcadsp.lfe_fir(samples_out, samples_in, prCoeff, decifactor, scale); + s->dcadsp.lfe_fir[idx](samples_out, samples_in, prCoeff); samples_in++; - samples_out += 2 * decifactor; + samples_out += 2 * 32 * (1 + idx); } } @@ -1184,29 +1156,23 @@ static void lfe_interpolation_fir(DCAContext *s, int decimation_select, op2 \ } -static void dca_downmix(float **samples, int srcfmt, - int downmix_coef[DCA_PRIM_CHANNELS_MAX][2], +static void dca_downmix(float **samples, int srcfmt, int lfe_present, + float coef[DCA_PRIM_CHANNELS_MAX + 1][2], const int8_t *channel_mapping) { int c, l, r, sl, sr, s; int i; float t, u, v; - float coef[DCA_PRIM_CHANNELS_MAX][2]; - - for (i = 0; i < DCA_PRIM_CHANNELS_MAX; i++) { - coef[i][0] = dca_downmix_coeffs[downmix_coef[i][0]]; - coef[i][1] = dca_downmix_coeffs[downmix_coef[i][1]]; - } switch (srcfmt) { case DCA_MONO: - case DCA_CHANNEL: - case DCA_STEREO_TOTAL: - case DCA_STEREO_SUMDIFF: case DCA_4F2R: av_log(NULL, AV_LOG_ERROR, "Not implemented!\n"); break; + case DCA_CHANNEL: case DCA_STEREO: + case DCA_STEREO_TOTAL: + case DCA_STEREO_SUMDIFF: break; case DCA_3F: c = channel_mapping[0]; @@ -1241,6 +1207,14 @@ static void dca_downmix(float **samples, int srcfmt, MIX_REAR2(samples, sl, sr, 3, coef)); break; } + if (lfe_present) { + int lf_buf = dca_lfe_index[srcfmt]; + int lf_idx = dca_channels [srcfmt]; + for (i = 0; i < 256; i++) { + samples[0][i] += samples[lf_buf][i] * coef[lf_idx][0]; + samples[1][i] += samples[lf_buf][i] * coef[lf_idx][1]; + } + } } @@ -1271,16 +1245,6 @@ static int decode_blockcodes(int code1, int code2, int levels, int32_t *values) static const uint8_t abits_sizes[7] = { 7, 10, 12, 13, 15, 17, 19 }; static const uint8_t abits_levels[7] = { 3, 5, 7, 9, 13, 17, 25 }; -#ifndef int8x8_fmul_int32 -static inline void int8x8_fmul_int32(float *dst, const int8_t *src, int scale) -{ - float fscale = scale / 16.0; - int i; - for (i = 0; i < 8; i++) - dst[i] = src[i] * fscale; -} -#endif - static int dca_subsubframe(DCAContext *s, int base_channel, int block_index) { int k, l; @@ -1377,16 +1341,27 @@ static int dca_subsubframe(DCAContext *s, int base_channel, int block_index) */ if (s->prediction_mode[k][l]) { int n; - for (m = 0; m < 8; m++) { - for (n = 1; n <= 4; n++) + if (s->predictor_history) + subband_samples[k][l][0] += (adpcm_vb[s->prediction_vq[k][l]][0] * + s->subband_samples_hist[k][l][3] + + adpcm_vb[s->prediction_vq[k][l]][1] * + s->subband_samples_hist[k][l][2] + + adpcm_vb[s->prediction_vq[k][l]][2] * + s->subband_samples_hist[k][l][1] + + adpcm_vb[s->prediction_vq[k][l]][3] * + s->subband_samples_hist[k][l][0]) * + (1.0f / 8192); + for (m = 1; m < 8; m++) { + float sum = adpcm_vb[s->prediction_vq[k][l]][0] * + subband_samples[k][l][m - 1]; + for (n = 2; n <= 4; n++) if (m >= n) - subband_samples[k][l][m] += - (adpcm_vb[s->prediction_vq[k][l]][n - 1] * - subband_samples[k][l][m - n] / 8192); + sum += adpcm_vb[s->prediction_vq[k][l]][n - 1] * + subband_samples[k][l][m - n]; else if (s->predictor_history) - subband_samples[k][l][m] += - (adpcm_vb[s->prediction_vq[k][l]][n - 1] * - s->subband_samples_hist[k][l][m - n + 4] / 8192); + sum += adpcm_vb[s->prediction_vq[k][l]][n - 1] * + s->subband_samples_hist[k][l][m - n + 4]; + subband_samples[k][l][m] += sum * (1.0f / 8192); } } } @@ -1394,20 +1369,16 @@ static int dca_subsubframe(DCAContext *s, int base_channel, int block_index) /* * Decode VQ encoded high frequencies */ - for (l = s->vq_start_subband[k]; l < s->subband_activity[k]; l++) { - /* 1 vector -> 32 samples but we only need the 8 samples - * for this subsubframe. */ - int hfvq = s->high_freq_vq[k][l]; - + if (s->subband_activity[k] > s->vq_start_subband[k]) { if (!s->debug_flag & 0x01) { av_log(s->avctx, AV_LOG_DEBUG, "Stream with high frequencies VQ coding\n"); s->debug_flag |= 0x01; } - - int8x8_fmul_int32(subband_samples[k][l], - &high_freq_vq[hfvq][subsubframe * 8], - s->scale_factor[k][l][0]); + s->dcadsp.decode_hf(subband_samples[k], s->high_freq_vq[k], + high_freq_vq, subsubframe * 8, + s->scale_factor[k], s->vq_start_subband[k], + s->subband_activity[k]); } } @@ -1426,9 +1397,7 @@ static int dca_subsubframe(DCAContext *s, int base_channel, int block_index) /* Backup predictor history for adpcm */ for (k = base_channel; k < s->prim_channels; k++) for (l = 0; l < s->vq_start_subband[k]; l++) - memcpy(s->subband_samples_hist[k][l], - &subband_samples[k][l][4], - 4 * sizeof(subband_samples[0][0][0])); + AV_COPY128(s->subband_samples_hist[k][l], &subband_samples[k][l][4]); return 0; } @@ -1449,28 +1418,29 @@ static int dca_filter_channels(DCAContext *s, int block_index) M_SQRT1_2 / 32768.0 /* pcm_to_double[s->source_pcm_res] */); } - /* Down mixing */ - AV_NOWARN_DEPRECATED( request_channels = s->avctx->request_channels; ); - if (request_channels == 2 && s->prim_channels > 2) { - dca_downmix(s->samples_chanptr, s->amode, s->downmix_coef, s->channel_order_tab); - } - /* Generate LFE samples for this subsubframe FIXME!!! */ - if (s->output & DCA_LFE) { + if (s->lfe) { lfe_interpolation_fir(s, s->lfe, 2 * s->lfe, s->lfe_data + 2 * s->lfe * (block_index + 4), - s->samples_chanptr[s->lfe_index], - 1.0 / (256.0 * 32768.0)); + s->samples_chanptr[s->lfe_index]); /* Outputs 20bits pcm samples */ } + /* Downmixing to Stereo */ + if (s->prim_channels + !!s->lfe > 2 && + s->avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) { + dca_downmix(s->samples_chanptr, s->amode, !!s->lfe, s->downmix_coef, + s->channel_order_tab); + } + return 0; } static int dca_subframe_footer(DCAContext *s, int base_channel) { - int aux_data_count = 0, i; + int in, out, aux_data_count, aux_data_end, reserved; + uint32_t nsyncaux; /* * Unpack optional information @@ -1481,13 +1451,89 @@ static int dca_subframe_footer(DCAContext *s, int base_channel) if (s->timestamp) skip_bits_long(&s->gb, 32); - if (s->aux_data) + if (s->aux_data) { aux_data_count = get_bits(&s->gb, 6); - for (i = 0; i < aux_data_count; i++) - get_bits(&s->gb, 8); + // align (32-bit) + skip_bits_long(&s->gb, (-get_bits_count(&s->gb)) & 31); - if (s->crc_present && (s->downmix || s->dynrange)) + aux_data_end = 8 * aux_data_count + get_bits_count(&s->gb); + + if ((nsyncaux = get_bits_long(&s->gb, 32)) != DCA_NSYNCAUX) { + av_log(s->avctx, AV_LOG_ERROR, "nSYNCAUX mismatch %#"PRIx32"\n", + nsyncaux); + return AVERROR_INVALIDDATA; + } + + if (get_bits1(&s->gb)) { // bAUXTimeStampFlag + avpriv_request_sample(s->avctx, + "Auxiliary Decode Time Stamp Flag"); + // align (4-bit) + skip_bits(&s->gb, (-get_bits_count(&s->gb)) & 4); + // 44 bits: nMSByte (8), nMarker (4), nLSByte (28), nMarker (4) + skip_bits_long(&s->gb, 44); + } + + if ((s->core_downmix = get_bits1(&s->gb))) { + int am = get_bits(&s->gb, 3); + switch (am) { + case 0: + s->core_downmix_amode = DCA_MONO; + break; + case 1: + s->core_downmix_amode = DCA_STEREO; + break; + case 2: + s->core_downmix_amode = DCA_STEREO_TOTAL; + break; + case 3: + s->core_downmix_amode = DCA_3F; + break; + case 4: + s->core_downmix_amode = DCA_2F1R; + break; + case 5: + s->core_downmix_amode = DCA_2F2R; + break; + case 6: + s->core_downmix_amode = DCA_3F1R; + break; + default: + av_log(s->avctx, AV_LOG_ERROR, + "Invalid mode %d for embedded downmix coefficients\n", + am); + return AVERROR_INVALIDDATA; + } + for (out = 0; out < dca_channels[s->core_downmix_amode]; out++) { + for (in = 0; in < s->prim_channels + !!s->lfe; in++) { + uint16_t tmp = get_bits(&s->gb, 9); + if ((tmp & 0xFF) > 241) { + av_log(s->avctx, AV_LOG_ERROR, + "Invalid downmix coefficient code %"PRIu16"\n", + tmp); + return AVERROR_INVALIDDATA; + } + s->core_downmix_codes[in][out] = tmp; + } + } + } + + align_get_bits(&s->gb); // byte align + skip_bits(&s->gb, 16); // nAUXCRC16 + + // additional data (reserved, cf. ETSI TS 102 114 V1.4.1) + if ((reserved = (aux_data_end - get_bits_count(&s->gb))) < 0) { + av_log(s->avctx, AV_LOG_ERROR, + "Overread auxiliary data by %d bits\n", -reserved); + return AVERROR_INVALIDDATA; + } else if (reserved) { + avpriv_request_sample(s->avctx, + "Core auxiliary data reserved content"); + skip_bits_long(&s->gb, reserved); + } + } + + if (s->crc_present && s->dynrange) get_bits(&s->gb, 16); } @@ -2119,6 +2165,55 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, /* record number of core channels incase less than max channels are requested */ num_core_channels = s->prim_channels; + if (s->prim_channels + !!s->lfe > 2 && + avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) { + /* Stereo downmix coefficients + * + * The decoder can only downmix to 2-channel, so we need to ensure + * embedded downmix coefficients are actually targeting 2-channel. + */ + if (s->core_downmix && (s->core_downmix_amode == DCA_STEREO || + s->core_downmix_amode == DCA_STEREO_TOTAL)) { + int sign, code; + for (i = 0; i < s->prim_channels + !!s->lfe; i++) { + sign = s->core_downmix_codes[i][0] & 0x100 ? 1 : -1; + code = s->core_downmix_codes[i][0] & 0x0FF; + s->downmix_coef[i][0] = (!code ? 0.0f : + sign * dca_dmixtable[code - 1]); + sign = s->core_downmix_codes[i][1] & 0x100 ? 1 : -1; + code = s->core_downmix_codes[i][1] & 0x0FF; + s->downmix_coef[i][1] = (!code ? 0.0f : + sign * dca_dmixtable[code - 1]); + } + s->output = s->core_downmix_amode; + } else { + int am = s->amode & DCA_CHANNEL_MASK; + if (am >= FF_ARRAY_ELEMS(dca_default_coeffs)) { + av_log(s->avctx, AV_LOG_ERROR, + "Invalid channel mode %d\n", am); + return AVERROR_INVALIDDATA; + } + if (s->prim_channels + !!s->lfe > + FF_ARRAY_ELEMS(dca_default_coeffs[0])) { + avpriv_request_sample(s->avctx, "Downmixing %d channels", + s->prim_channels + !!s->lfe); + return AVERROR_PATCHWELCOME; + } + for (i = 0; i < s->prim_channels + !!s->lfe; i++) { + s->downmix_coef[i][0] = dca_default_coeffs[am][i][0]; + s->downmix_coef[i][1] = dca_default_coeffs[am][i][1]; + } + } + av_dlog(s->avctx, "Stereo downmix coeffs:\n"); + for (i = 0; i < s->prim_channels + !!s->lfe; i++) { + av_dlog(s->avctx, "L, input channel %d = %f\n", i, + s->downmix_coef[i][0]); + av_dlog(s->avctx, "R, input channel %d = %f\n", i, + s->downmix_coef[i][1]); + } + av_dlog(s->avctx, "\n"); + } + if (s->ext_coding) s->core_ext_mask = dca_ext_audio_descr_mask[s->ext_descr]; else @@ -2226,22 +2321,25 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, avctx->profile = s->profile; full_channels = channels = s->prim_channels + !!s->lfe; - - AV_NOWARN_DEPRECATED( request_channels = avctx->request_channels; ); /* If we have XXCH then the channel layout is managed differently */ /* note that XLL will also have another way to do things */ if (!(s->core_ext_mask & DCA_EXT_XXCH) - || (s->core_ext_mask & DCA_EXT_XXCH && request_channels > 0 - && request_channels + || (s->core_ext_mask & DCA_EXT_XXCH && avctx->request_channels > 0 + && avctx->request_channels < num_core_channels + !!s->lfe + s->xxch_chset_nch[0])) { /* xxx should also do MA extensions */ if (s->amode < 16) { avctx->channel_layout = dca_core_channel_layout[s->amode]; - - if (s->xch_present && (!request_channels || - request_channels - > num_core_channels + !!s->lfe)) { +#if FF_API_REQUEST_CHANNELS +FF_DISABLE_DEPRECATION_WARNINGS + if (s->xch_present && !s->xch_disable && + (!avctx->request_channels || + avctx->request_channels > num_core_channels + !!s->lfe)) { +FF_ENABLE_DEPRECATION_WARNINGS +#else + if (s->xch_present && !s->xch_disable) { +#endif avctx->channel_layout |= AV_CH_BACK_CENTER; if (s->lfe) { avctx->channel_layout |= AV_CH_LOW_FREQUENCY; @@ -2270,9 +2368,10 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } - if (request_channels == 2 && s->prim_channels > 2) { + if (s->prim_channels + !!s->lfe > 2 && + avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) { channels = 2; - s->output = DCA_STEREO; + s->output = s->prim_channels == 2 ? s->amode : DCA_STEREO; avctx->channel_layout = AV_CH_LAYOUT_STEREO; } else if (avctx->request_channel_layout & AV_CH_LAYOUT_NATIVE) { @@ -2318,7 +2417,7 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, * masks in some sense -- unfortunately some channels could overlap */ if (av_popcount(channel_mask) != av_popcount(channel_layout)) { av_log(avctx, AV_LOG_DEBUG, - "DTS-XXCH: Inconsistant avcodec/dts channel layouts\n"); + "DTS-XXCH: Inconsistent avcodec/dts channel layouts\n"); return AVERROR_INVALIDDATA; } @@ -2456,6 +2555,15 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, for (i = 0; i < 2 * s->lfe * 4; i++) s->lfe_data[i] = s->lfe_data[i + lfe_samples]; + /* AVMatrixEncoding + * + * DCA_STEREO_TOTAL (Lt/Rt) is equivalent to Dolby Surround */ + ret = ff_side_data_update_matrix_encoding(frame, + (s->output & ~DCA_LFE) == DCA_STEREO_TOTAL ? + AV_MATRIX_ENCODING_DOLBY : AV_MATRIX_ENCODING_NONE); + if (ret < 0) + return ret; + *got_frame_ptr = 1; return buf_size; @@ -2486,11 +2594,15 @@ static av_cold int dca_decode_init(AVCodecContext *avctx) avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; /* allow downmixing to stereo */ - AV_NOWARN_DEPRECATED( request_channels = avctx->request_channels; ); - if (avctx->channels > 0 && request_channels < avctx->channels && - request_channels == 2) { - avctx->channels = request_channels; - } +#if FF_API_REQUEST_CHANNELS +FF_DISABLE_DEPRECATION_WARNINGS + if (avctx->request_channels == 2) + avctx->request_channel_layout = AV_CH_LAYOUT_STEREO; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + if (avctx->channels > 2 && + avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) + avctx->channels = 2; return 0; } @@ -2512,6 +2624,19 @@ static const AVProfile profiles[] = { { FF_PROFILE_UNKNOWN }, }; +static const AVOption options[] = { + { "disable_xch", "disable decoding of the XCh extension", offsetof(DCAContext, xch_disable), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM|AV_OPT_FLAG_AUDIO_PARAM }, + { NULL }, +}; + +static const AVClass dca_decoder_class = { + .class_name = "DCA decoder", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, + .category = AV_CLASS_CATEGORY_DECODER, +}; + AVCodec ff_dca_decoder = { .name = "dca", .long_name = NULL_IF_CONFIG_SMALL("DCA (DTS Coherent Acoustics)"), @@ -2525,4 +2650,5 @@ AVCodec ff_dca_decoder = { .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, .profiles = NULL_IF_CONFIG_SMALL(profiles), + .priv_class = &dca_decoder_class, }; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dcadsp.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dcadsp.c index abeba2492..7d5044298 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dcadsp.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dcadsp.c @@ -24,25 +24,42 @@ #include "libavutil/intreadwrite.h" #include "dcadsp.h" -static void dca_lfe_fir_c(float *out, const float *in, const float *coefs, - int decifactor, float scale) +static void decode_hf_c(float dst[DCA_SUBBANDS][8], + const int32_t vq_num[DCA_SUBBANDS], + const int8_t hf_vq[1024][32], intptr_t vq_offset, + int32_t scale[DCA_SUBBANDS][2], + intptr_t start, intptr_t end) { - float *out2 = out + decifactor; - const float *cf0 = coefs; - const float *cf1 = coefs + 256; + int i, l; + + for (l = start; l < end; l++) { + /* 1 vector -> 32 samples but we only need the 8 samples + * for this subsubframe. */ + const int8_t *ptr = &hf_vq[vq_num[l]][vq_offset]; + float fscale = scale[l][0] * (1 / 16.0); + for (i = 0; i < 8; i++) + dst[l][i] = ptr[i] * fscale; + } +} + +static inline void +dca_lfe_fir(float *out, const float *in, const float *coefs, + int decifactor) +{ + float *out2 = out + 2 * decifactor - 1; + int num_coeffs = 256 / decifactor; int j, k; /* One decimated sample generates 2*decifactor interpolated ones */ for (k = 0; k < decifactor; k++) { float v0 = 0.0; float v1 = 0.0; - for (j = 0; j < 256 / decifactor; j++) { - float s = in[-j]; - v0 += s * *cf0++; - v1 += s * *--cf1; + for (j = 0; j < num_coeffs; j++, coefs++) { + v0 += in[-j] * *coefs; + v1 += in[j + 1 - num_coeffs] * *coefs; } - *out++ = v0 * scale; - *out2++ = v1 * scale; + *out++ = v0; + *out2-- = v1; } } @@ -74,9 +91,22 @@ static void dca_qmf_32_subbands(float samples_in[32][8], int sb_act, } } +static void dca_lfe_fir0_c(float *out, const float *in, const float *coefs) +{ + dca_lfe_fir(out, in, coefs, 32); +} + +static void dca_lfe_fir1_c(float *out, const float *in, const float *coefs) +{ + dca_lfe_fir(out, in, coefs, 64); +} + av_cold void ff_dcadsp_init(DCADSPContext *s) { - s->lfe_fir = dca_lfe_fir_c; + s->lfe_fir[0] = dca_lfe_fir0_c; + s->lfe_fir[1] = dca_lfe_fir1_c; s->qmf_32_subbands = dca_qmf_32_subbands; + s->decode_hf = decode_hf_c; if (ARCH_ARM) ff_dcadsp_init_arm(s); + if (ARCH_X86) ff_dcadsp_init_x86(s); } diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dcadsp.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dcadsp.h index d86c1f32a..abf577b61 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dcadsp.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dcadsp.h @@ -22,18 +22,25 @@ #include "avfft.h" #include "synth_filter.h" +#define DCA_SUBBANDS 64 + typedef struct DCADSPContext { - void (*lfe_fir)(float *out, const float *in, const float *coefs, - int decifactor, float scale); + void (*lfe_fir[2])(float *out, const float *in, const float *coefs); void (*qmf_32_subbands)(float samples_in[32][8], int sb_act, SynthFilterContext *synth, FFTContext *imdct, float synth_buf_ptr[512], int *synth_buf_offset, float synth_buf2[32], const float window[512], float *samples_out, float raXin[32], float scale); + void (*decode_hf)(float dst[DCA_SUBBANDS][8], + const int32_t vq_num[DCA_SUBBANDS], + const int8_t hf_vq[1024][32], intptr_t vq_offset, + int32_t scale[DCA_SUBBANDS][2], + intptr_t start, intptr_t end); } DCADSPContext; void ff_dcadsp_init(DCADSPContext *s); void ff_dcadsp_init_arm(DCADSPContext *s); +void ff_dcadsp_init_x86(DCADSPContext *s); #endif /* AVCODEC_DCADSP_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dirac.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dirac.c index d65ac9af4..ab4daf329 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dirac.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dirac.c @@ -30,6 +30,7 @@ #include "dirac.h" #include "avcodec.h" #include "golomb.h" +#include "internal.h" #include "mpeg12data.h" /* defaults for source parameters */ @@ -317,11 +318,10 @@ int avpriv_dirac_parse_sequence_header(AVCodecContext *avctx, GetBitContext *gb, if ((ret = parse_source_parameters(avctx, gb, source))) return ret; - if ((ret = av_image_check_size(source->width, source->height, 0, avctx))) + ret = ff_set_dimensions(avctx, source->width, source->height); + if (ret < 0) 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); diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dirac_dwt.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dirac_dwt.c index a4d38de9e..698f11fa8 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dirac_dwt.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/dirac_dwt.c @@ -536,6 +536,7 @@ int ff_spatial_idwt_init2(DWTContext *d, IDWTELEM *buffer, int width, int height d->vertical_compose_l0 = (void*)vertical_compose_fidelityiL0; d->vertical_compose_h0 = (void*)vertical_compose_fidelityiH0; d->horizontal_compose = horizontal_compose_fidelityi; + d->support = 0; // not really used break; case DWT_DIRAC_DAUB9_7: d->spatial_compose = spatial_compose_daub97i_dy; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/diracdec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/diracdec.c index e92139388..227c15edc 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/diracdec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/diracdec.c @@ -80,7 +80,7 @@ #define DIVRNDUP(a, b) (((a) + (b) - 1) / (b)) typedef struct { - AVFrame avframe; + AVFrame *avframe; int interpolated[3]; /* 1 if hpel[] is valid */ uint8_t *hpel[3][4]; uint8_t *hpel_base[3][4]; @@ -291,7 +291,7 @@ static DiracFrame *remove_frame(DiracFrame *framelist[], int picnum) int i, remove_idx = -1; for (i = 0; framelist[i]; i++) - if (framelist[i]->avframe.display_picture_number == picnum) { + if (framelist[i]->avframe->display_picture_number == picnum) { remove_pic = framelist[i]; remove_idx = i; } @@ -364,8 +364,8 @@ static void free_sequence_buffers(DiracContext *s) int i, j, k; for (i = 0; i < MAX_FRAMES; i++) { - if (s->all_frames[i].avframe.data[0]) { - av_frame_unref(&s->all_frames[i].avframe); + if (s->all_frames[i].avframe->data[0]) { + av_frame_unref(s->all_frames[i].avframe); memset(s->all_frames[i].interpolated, 0, sizeof(s->all_frames[i].interpolated)); } @@ -393,17 +393,23 @@ static void free_sequence_buffers(DiracContext *s) static av_cold int dirac_decode_init(AVCodecContext *avctx) { DiracContext *s = avctx->priv_data; + int i; + s->avctx = avctx; s->frame_number = -1; - if (avctx->flags&CODEC_FLAG_EMU_EDGE) { - av_log(avctx, AV_LOG_ERROR, "Edge emulation not supported!\n"); - return AVERROR_PATCHWELCOME; - } - ff_dsputil_init(&s->dsp, avctx); ff_diracdsp_init(&s->diracdsp); + for (i = 0; i < MAX_FRAMES; i++) { + s->all_frames[i].avframe = av_frame_alloc(); + if (!s->all_frames[i].avframe) { + while (i > 0) + av_frame_free(&s->all_frames[--i].avframe); + return AVERROR(ENOMEM); + } + } + return 0; } @@ -417,7 +423,13 @@ static void dirac_decode_flush(AVCodecContext *avctx) static av_cold int dirac_decode_end(AVCodecContext *avctx) { + DiracContext *s = avctx->priv_data; + int i; + dirac_decode_flush(avctx); + for (i = 0; i < MAX_FRAMES; i++) + av_frame_free(&s->all_frames[i].avframe); + return 0; } @@ -1414,8 +1426,8 @@ static int mc_subpel(DiracContext *s, DiracBlock *block, const uint8_t *src[5], y + p->yblen > p->height+EDGE_WIDTH/2 || x < 0 || y < 0) { for (i = 0; i < nplanes; i++) { - ff_emulated_edge_mc(s->edge_emu_buffer[i], p->stride, - src[i], p->stride, + ff_emulated_edge_mc(s->edge_emu_buffer[i], src[i], + p->stride, p->stride, p->xblen, p->yblen, x, y, p->width+EDGE_WIDTH/2, p->height+EDGE_WIDTH/2); src[i] = s->edge_emu_buffer[i]; @@ -1519,8 +1531,8 @@ static void interpolate_refplane(DiracContext *s, DiracFrame *ref, int plane, in just use 8 for everything for the moment */ int i, edge = EDGE_WIDTH/2; - ref->hpel[plane][0] = ref->avframe.data[plane]; - s->dsp.draw_edges(ref->hpel[plane][0], ref->avframe.linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); /* EDGE_TOP | EDGE_BOTTOM values just copied to make it build, this needs to be ensured */ + ref->hpel[plane][0] = ref->avframe->data[plane]; + s->dsp.draw_edges(ref->hpel[plane][0], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); /* EDGE_TOP | EDGE_BOTTOM values just copied to make it build, this needs to be ensured */ /* no need for hpel if we only have fpel vectors */ if (!s->mv_precision) @@ -1528,18 +1540,18 @@ static void interpolate_refplane(DiracContext *s, DiracFrame *ref, int plane, in for (i = 1; i < 4; i++) { if (!ref->hpel_base[plane][i]) - ref->hpel_base[plane][i] = av_malloc((height+2*edge) * ref->avframe.linesize[plane] + 32); + ref->hpel_base[plane][i] = av_malloc((height+2*edge) * ref->avframe->linesize[plane] + 32); /* we need to be 16-byte aligned even for chroma */ - ref->hpel[plane][i] = ref->hpel_base[plane][i] + edge*ref->avframe.linesize[plane] + 16; + ref->hpel[plane][i] = ref->hpel_base[plane][i] + edge*ref->avframe->linesize[plane] + 16; } if (!ref->interpolated[plane]) { s->diracdsp.dirac_hpel_filter(ref->hpel[plane][1], ref->hpel[plane][2], ref->hpel[plane][3], ref->hpel[plane][0], - ref->avframe.linesize[plane], width, height); - s->dsp.draw_edges(ref->hpel[plane][1], ref->avframe.linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); - s->dsp.draw_edges(ref->hpel[plane][2], ref->avframe.linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); - s->dsp.draw_edges(ref->hpel[plane][3], ref->avframe.linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); + ref->avframe->linesize[plane], width, height); + s->dsp.draw_edges(ref->hpel[plane][1], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); + s->dsp.draw_edges(ref->hpel[plane][2], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); + s->dsp.draw_edges(ref->hpel[plane][3], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); } ref->interpolated[plane] = 1; } @@ -1565,7 +1577,7 @@ static int dirac_decode_frame_internal(DiracContext *s) for (comp = 0; comp < 3; comp++) { Plane *p = &s->plane[comp]; - uint8_t *frame = s->current_picture->avframe.data[comp]; + uint8_t *frame = s->current_picture->avframe->data[comp]; /* FIXME: small resolutions */ for (i = 0; i < 4; i++) @@ -1629,6 +1641,29 @@ static int dirac_decode_frame_internal(DiracContext *s) return 0; } +static int get_buffer_with_edge(AVCodecContext *avctx, AVFrame *f, int flags) +{ + int ret, i; + int chroma_x_shift, chroma_y_shift; + avcodec_get_chroma_sub_sample(avctx->pix_fmt, &chroma_x_shift, &chroma_y_shift); + + f->width = avctx->width + 2 * EDGE_WIDTH; + f->height = avctx->height + 2 * EDGE_WIDTH + 2; + ret = ff_get_buffer(avctx, f, flags); + if (ret < 0) + return ret; + + for (i = 0; f->data[i]; i++) { + int offset = (EDGE_WIDTH >> (i && i<3 ? chroma_y_shift : 0)) * + f->linesize[i] + 32; + f->data[i] += offset; + } + f->width = avctx->width; + f->height = avctx->height; + + return 0; +} + /** * Dirac Specification -> * 11.1.1 Picture Header. picture_header() @@ -1640,7 +1675,7 @@ static int dirac_decode_picture_header(DiracContext *s) GetBitContext *gb = &s->gb; /* [DIRAC_STD] 11.1.1 Picture Header. picture_header() PICTURE_NUM */ - picnum = s->current_picture->avframe.display_picture_number = get_bits_long(gb, 32); + picnum = s->current_picture->avframe->display_picture_number = get_bits_long(gb, 32); av_log(s->avctx,AV_LOG_DEBUG,"PICTURE_NUM: %d\n",picnum); @@ -1659,9 +1694,9 @@ static int dirac_decode_picture_header(DiracContext *s) /* Jordi: this is needed if the referenced picture hasn't yet arrived */ for (j = 0; j < MAX_REFERENCE_FRAMES && refdist; j++) if (s->ref_frames[j] - && FFABS(s->ref_frames[j]->avframe.display_picture_number - refnum) < refdist) { + && FFABS(s->ref_frames[j]->avframe->display_picture_number - refnum) < refdist) { s->ref_pics[i] = s->ref_frames[j]; - refdist = FFABS(s->ref_frames[j]->avframe.display_picture_number - refnum); + refdist = FFABS(s->ref_frames[j]->avframe->display_picture_number - refnum); } if (!s->ref_pics[i] || refdist) @@ -1670,22 +1705,21 @@ static int dirac_decode_picture_header(DiracContext *s) /* if there were no references at all, allocate one */ if (!s->ref_pics[i]) for (j = 0; j < MAX_FRAMES; j++) - if (!s->all_frames[j].avframe.data[0]) { + if (!s->all_frames[j].avframe->data[0]) { s->ref_pics[i] = &s->all_frames[j]; - ff_get_buffer(s->avctx, &s->ref_pics[i]->avframe, AV_GET_BUFFER_FLAG_REF); + get_buffer_with_edge(s->avctx, s->ref_pics[i]->avframe, AV_GET_BUFFER_FLAG_REF); break; } } /* retire the reference frames that are not used anymore */ - AV_NOWARN_DEPRECATED( - if (s->current_picture->avframe.reference) { + if (s->current_picture->avframe->reference) { retire = picnum + dirac_get_se_golomb(gb); if (retire != picnum) { DiracFrame *retire_pic = remove_frame(s->ref_frames, retire); if (retire_pic) - retire_pic->avframe.reference &= DELAYED_PIC_REF; + retire_pic->avframe->reference &= DELAYED_PIC_REF; else av_log(s->avctx, AV_LOG_DEBUG, "Frame to retire not found\n"); } @@ -1693,10 +1727,9 @@ static int dirac_decode_picture_header(DiracContext *s) /* if reference array is full, remove the oldest as per the spec */ while (add_frame(s->ref_frames, MAX_REFERENCE_FRAMES, s->current_picture)) { av_log(s->avctx, AV_LOG_ERROR, "Reference frame overflow\n"); - remove_frame(s->ref_frames, s->ref_frames[0]->avframe.display_picture_number)->avframe.reference &= DELAYED_PIC_REF; + remove_frame(s->ref_frames, s->ref_frames[0]->avframe->display_picture_number)->avframe->reference &= DELAYED_PIC_REF; } } - ); if (s->num_refs) { if (dirac_unpack_prediction_parameters(s)) /* [DIRAC_STD] 11.2 Picture Prediction Data. picture_prediction() */ @@ -1719,7 +1752,7 @@ static int get_delayed_pic(DiracContext *s, AVFrame *picture, int *got_frame) /* find frame with lowest picture number */ for (i = 1; s->delay_frames[i]; i++) - if (s->delay_frames[i]->avframe.display_picture_number < out->avframe.display_picture_number) { + if (s->delay_frames[i]->avframe->display_picture_number < out->avframe->display_picture_number) { out = s->delay_frames[i]; out_idx = i; } @@ -1728,9 +1761,9 @@ static int get_delayed_pic(DiracContext *s, AVFrame *picture, int *got_frame) s->delay_frames[i] = s->delay_frames[i+1]; if (out) { - AV_NOWARN_DEPRECATED( out->avframe.reference ^= DELAYED_PIC_REF; ); + out->avframe->reference ^= DELAYED_PIC_REF; *got_frame = 1; - if((ret = av_frame_ref(picture, &out->avframe)) < 0) + if((ret = av_frame_ref(picture, out->avframe)) < 0) return ret; } @@ -1792,14 +1825,14 @@ static int dirac_decode_data_unit(AVCodecContext *avctx, const uint8_t *buf, int /* find an unused frame */ for (i = 0; i < MAX_FRAMES; i++) - if (s->all_frames[i].avframe.data[0] == NULL) + if (s->all_frames[i].avframe->data[0] == NULL) pic = &s->all_frames[i]; if (!pic) { av_log(avctx, AV_LOG_ERROR, "framelist full\n"); return -1; } - avcodec_get_frame_defaults(&pic->avframe); + av_frame_unref(pic->avframe); /* [DIRAC_STD] Defined in 9.6.1 ... */ tmp = parse_code & 0x03; /* [DIRAC_STD] num_refs() */ @@ -1810,16 +1843,16 @@ static int dirac_decode_data_unit(AVCodecContext *avctx, const uint8_t *buf, int s->num_refs = tmp; s->is_arith = (parse_code & 0x48) == 0x08; /* [DIRAC_STD] using_ac() */ s->low_delay = (parse_code & 0x88) == 0x88; /* [DIRAC_STD] is_low_delay() */ - AV_NOWARN_DEPRECATED( pic->avframe.reference = (parse_code & 0x0C) == 0x0C; ); /* [DIRAC_STD] is_reference() */ - pic->avframe.key_frame = s->num_refs == 0; /* [DIRAC_STD] is_intra() */ - pic->avframe.pict_type = s->num_refs + 1; /* Definition of AVPictureType in avutil.h */ + pic->avframe->reference = (parse_code & 0x0C) == 0x0C; /* [DIRAC_STD] is_reference() */ + pic->avframe->key_frame = s->num_refs == 0; /* [DIRAC_STD] is_intra() */ + pic->avframe->pict_type = s->num_refs + 1; /* Definition of AVPictureType in avutil.h */ - if ((ret = ff_get_buffer(avctx, &pic->avframe, (parse_code & 0x0C) == 0x0C ? AV_GET_BUFFER_FLAG_REF : 0)) < 0) + if ((ret = get_buffer_with_edge(avctx, pic->avframe, (parse_code & 0x0C) == 0x0C ? AV_GET_BUFFER_FLAG_REF : 0)) < 0) return ret; s->current_picture = pic; - s->plane[0].stride = pic->avframe.linesize[0]; - s->plane[1].stride = pic->avframe.linesize[1]; - s->plane[2].stride = pic->avframe.linesize[2]; + s->plane[0].stride = pic->avframe->linesize[0]; + s->plane[1].stride = pic->avframe->linesize[1]; + s->plane[2].stride = pic->avframe->linesize[2]; /* [DIRAC_STD] 11.1 Picture parse. picture_parse() */ if (dirac_decode_picture_header(s)) @@ -1835,7 +1868,7 @@ static int dirac_decode_data_unit(AVCodecContext *avctx, const uint8_t *buf, int static int dirac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *pkt) { DiracContext *s = avctx->priv_data; - DiracFrame *picture = data; + AVFrame *picture = data; uint8_t *buf = pkt->data; int buf_size = pkt->size; int i, data_unit_size, buf_idx = 0; @@ -1843,12 +1876,10 @@ static int dirac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, /* release unused frames */ for (i = 0; i < MAX_FRAMES; i++) - AV_NOWARN_DEPRECATED( - if (s->all_frames[i].avframe.data[0] && !s->all_frames[i].avframe.reference) { - av_frame_unref(&s->all_frames[i].avframe); + if (s->all_frames[i].avframe->data[0] && !s->all_frames[i].avframe->reference) { + av_frame_unref(s->all_frames[i].avframe); memset(s->all_frames[i].interpolated, 0, sizeof(s->all_frames[i].interpolated)); } - ); s->current_picture = NULL; *got_frame = 0; @@ -1891,40 +1922,40 @@ static int dirac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (!s->current_picture) return buf_size; - if (s->current_picture->avframe.display_picture_number > s->frame_number) { + if (s->current_picture->avframe->display_picture_number > s->frame_number) { DiracFrame *delayed_frame = remove_frame(s->delay_frames, s->frame_number); - AV_NOWARN_DEPRECATED( s->current_picture->avframe.reference |= DELAYED_PIC_REF; ); + s->current_picture->avframe->reference |= DELAYED_PIC_REF; if (add_frame(s->delay_frames, MAX_DELAY, s->current_picture)) { - int min_num = s->delay_frames[0]->avframe.display_picture_number; + int min_num = s->delay_frames[0]->avframe->display_picture_number; /* Too many delayed frames, so we display the frame with the lowest pts */ av_log(avctx, AV_LOG_ERROR, "Delay frame overflow\n"); delayed_frame = s->delay_frames[0]; for (i = 1; s->delay_frames[i]; i++) - if (s->delay_frames[i]->avframe.display_picture_number < min_num) - min_num = s->delay_frames[i]->avframe.display_picture_number; + if (s->delay_frames[i]->avframe->display_picture_number < min_num) + min_num = s->delay_frames[i]->avframe->display_picture_number; delayed_frame = remove_frame(s->delay_frames, min_num); add_frame(s->delay_frames, MAX_DELAY, s->current_picture); } if (delayed_frame) { - AV_NOWARN_DEPRECATED( delayed_frame->avframe.reference ^= DELAYED_PIC_REF; ); - if((ret=av_frame_ref(data, &delayed_frame->avframe)) < 0) + delayed_frame->avframe->reference ^= DELAYED_PIC_REF; + if((ret=av_frame_ref(data, delayed_frame->avframe)) < 0) return ret; *got_frame = 1; } - } else if (s->current_picture->avframe.display_picture_number == s->frame_number) { + } else if (s->current_picture->avframe->display_picture_number == s->frame_number) { /* The right frame at the right time :-) */ - if((ret=av_frame_ref(data, &s->current_picture->avframe)) < 0) + if((ret=av_frame_ref(data, s->current_picture->avframe)) < 0) return ret; *got_frame = 1; } if (*got_frame) - s->frame_number = picture->avframe.display_picture_number + 1; + s->frame_number = picture->display_picture_number + 1; return buf_idx; } diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/eac3dec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/eac3dec.c index 4afffcf6c..512c6feca 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/eac3dec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/eac3dec.c @@ -346,23 +346,22 @@ int ff_eac3_parse_header(AC3DecodeContext *s) if (get_bits1(gbc)) { /* center and surround mix levels */ if (s->channel_mode > AC3_CHMODE_STEREO) { - skip_bits(gbc, 2); // skip preferred stereo downmix mode + s->preferred_downmix = get_bits(gbc, 2); if (s->channel_mode & 1) { /* if three front channels exist */ - skip_bits(gbc, 3); //skip Lt/Rt center mix level - s->center_mix_level = get_bits(gbc, 3); + s->center_mix_level_ltrt = get_bits(gbc, 3); + s->center_mix_level = get_bits(gbc, 3); } if (s->channel_mode & 4) { /* if a surround channel exists */ - skip_bits(gbc, 3); //skip Lt/Rt surround mix level - s->surround_mix_level = get_bits(gbc, 3); + s->surround_mix_level_ltrt = av_clip(get_bits(gbc, 3), 3, 7); + s->surround_mix_level = av_clip(get_bits(gbc, 3), 3, 7); } } /* lfe mix level */ - if (s->lfe_on && get_bits1(gbc)) { - // TODO: use LFE mix level - skip_bits(gbc, 5); // skip LFE mix level code + if (s->lfe_on && (s->lfe_mix_level_exists = get_bits1(gbc))) { + s->lfe_mix_level = get_bits(gbc, 5); } /* info for mixing with other streams and substreams */ @@ -414,10 +413,11 @@ int ff_eac3_parse_header(AC3DecodeContext *s) s->bitstream_mode = get_bits(gbc, 3); skip_bits(gbc, 2); // skip copyright bit and original bitstream bit if (s->channel_mode == AC3_CHMODE_STEREO) { - skip_bits(gbc, 4); // skip Dolby surround and headphone mode + s->dolby_surround_mode = get_bits(gbc, 2); + s->dolby_headphone_mode = get_bits(gbc, 2); } if (s->channel_mode >= AC3_CHMODE_2F2R) { - skip_bits(gbc, 2); // skip Dolby surround EX mode + s->dolby_surround_ex_mode = get_bits(gbc, 2); } for (i = 0; i < (s->channel_mode ? 1 : 2); i++) { if (get_bits1(gbc)) { diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/error_resilience.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/error_resilience.c index b7bdf974a..755e8b9d3 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/error_resilience.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/error_resilience.c @@ -27,11 +27,13 @@ #include +#include "libavutil/internal.h" #include "avcodec.h" #include "error_resilience.h" #include "mpegvideo.h" #include "rectangle.h" #include "thread.h" +#include "version.h" /** * @param stride the number of MVs to get to the next row @@ -698,8 +700,8 @@ static int is_intra_more_likely(ERContext *s) return 0; // almost all MBs damaged -> use temporal prediction // prevent dsp.sad() check, that requires access to the image - if (CONFIG_MPEG_XVMC_DECODER && - s->avctx->xvmc_acceleration && + if (CONFIG_XVMC && + s->avctx->hwaccel && s->avctx->hwaccel->decode_mb && s->cur_pic->f.pict_type == AV_PICTURE_TYPE_I) return 1; @@ -753,7 +755,7 @@ static int is_intra_more_likely(ERContext *s) void ff_er_frame_start(ERContext *s) { - if (!s->avctx->err_recognition) + if (!s->avctx->error_concealment) return; memset(s->error_status_table, ER_MB_ERROR | VP_START | ER_MB_END, @@ -762,6 +764,17 @@ void ff_er_frame_start(ERContext *s) s->error_occurred = 0; } +static int er_supported(ERContext *s) +{ + if(s->avctx->hwaccel && s->avctx->hwaccel->decode_slice || + s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU || + !s->cur_pic || + s->cur_pic->field_picture + ) + return 0; + return 1; +} + /** * Add a slice. * @param endx x component of the last macroblock, can be -1 @@ -778,7 +791,7 @@ void ff_er_add_slice(ERContext *s, int startx, int starty, const int end_xy = s->mb_index2xy[end_i]; int mask = -1; - if (s->avctx->hwaccel) + if (s->avctx->hwaccel && s->avctx->hwaccel->decode_slice) return; if (start_i > end_i || start_xy > end_xy) { @@ -787,7 +800,7 @@ void ff_er_add_slice(ERContext *s, int startx, int starty, return; } - if (!s->avctx->err_recognition) + if (!s->avctx->error_concealment) return; mask &= ~VP_START; @@ -828,7 +841,7 @@ void ff_er_add_slice(ERContext *s, int startx, int starty, s->error_status_table[start_xy] |= VP_START; if (start_xy > 0 && !(s->avctx->active_thread_type & FF_THREAD_SLICE) && - s->avctx->skip_top * s->mb_width < start_i) { + er_supported(s) && s->avctx->skip_top * s->mb_width < start_i) { int prev_status = s->error_status_table[s->mb_index2xy[start_i - 1]]; prev_status &= ~ VP_START; @@ -851,11 +864,9 @@ void ff_er_frame_end(ERContext *s) /* We do not support ER of field pictures yet, * though it should not crash if enabled. */ - if (!s->avctx->err_recognition || s->error_count == 0 || + if (!s->avctx->error_concealment || s->error_count == 0 || s->avctx->lowres || - s->avctx->hwaccel || - s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU || - !s->cur_pic || s->cur_pic->field_picture || + !er_supported(s) || s->error_count == 3 * s->mb_width * (s->avctx->skip_top + s->avctx->skip_bottom)) { return; @@ -1173,8 +1184,8 @@ void ff_er_frame_end(ERContext *s) } else guess_mv(s); - /* the filters below are not XvMC compatible, skip them */ - if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration) + /* the filters below manipulate raw image, skip them */ + if (CONFIG_XVMC && s->avctx->hwaccel && s->avctx->hwaccel->decode_mb) goto ec_clean; /* fill DC for inter blocks */ for (mb_y = 0; mb_y < s->mb_height; mb_y++) { diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/frame_thread_encoder.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/frame_thread_encoder.c index 581bdf554..0de110d08 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/frame_thread_encoder.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/frame_thread_encoder.c @@ -126,6 +126,31 @@ int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){ || !(avctx->codec->capabilities & CODEC_CAP_INTRA_ONLY)) return 0; + if( !avctx->thread_count + && avctx->codec_id == AV_CODEC_ID_MJPEG + && !(avctx->flags & CODEC_FLAG_QSCALE)) { + av_log(avctx, AV_LOG_DEBUG, + "Forcing thread count to 1 for MJPEG encoding, use -thread_type slice " + "or a constant quantizer if you want to use multiple cpu cores\n"); + avctx->thread_count = 1; + } + if( avctx->thread_count > 1 + && avctx->codec_id == AV_CODEC_ID_MJPEG + && !(avctx->flags & CODEC_FLAG_QSCALE)) + av_log(avctx, AV_LOG_WARNING, + "MJPEG CBR encoding works badly with frame multi-threading, consider " + "using -threads 1, -thread_type slice or a constant quantizer.\n"); + + if (avctx->codec_id == AV_CODEC_ID_HUFFYUV || + avctx->codec_id == AV_CODEC_ID_FFVHUFF) { + // huffyuv doesnt support these with multiple frame threads currently + if (avctx->context_model > 0 || (avctx->flags & CODEC_FLAG_PASS1)) { + av_log(avctx, AV_LOG_WARNING, + "Forcing thread count to 1 for huffyuv encoding with first pass or context 1\n"); + avctx->thread_count = 1; + } + } + if(!avctx->thread_count) { avctx->thread_count = av_cpu_count(); avctx->thread_count = FFMIN(avctx->thread_count, MAX_THREADS); diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g726.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g726.c index 6de3be629..073bd6fbc 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g726.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/g726.c @@ -97,6 +97,7 @@ typedef struct G726Context { int sez; /**< estimated second order prediction */ int y; /**< quantizer scaling factor for the next iteration */ int code_size; + int little_endian; /**< little-endian bitstream as used in aiff and Sun AU */ } G726Context; static const int quant_tbl16[] = /**< 16kbit/s 2bits per sample */ @@ -397,7 +398,7 @@ AVCodec ff_adpcm_g726_encoder = { }; #endif -#if CONFIG_ADPCM_G726_DECODER +#if CONFIG_ADPCM_G726_DECODER || CONFIG_ADPCM_G726LE_DECODER static av_cold int g726_decode_init(AVCodecContext *avctx) { G726Context* c = avctx->priv_data; @@ -409,6 +410,8 @@ static av_cold int g726_decode_init(AVCodecContext *avctx) avctx->channels = 1; avctx->channel_layout = AV_CH_LAYOUT_MONO; + c->little_endian = !strcmp(avctx->codec->name, "g726le"); + c->code_size = avctx->bits_per_coded_sample; if (c->code_size < 2 || c->code_size > 5) { av_log(avctx, AV_LOG_ERROR, "Invalid number of bits %d\n", c->code_size); @@ -443,7 +446,9 @@ static int g726_decode_frame(AVCodecContext *avctx, void *data, init_get_bits(&gb, buf, buf_size * 8); while (out_samples--) - *samples++ = g726_decode(c, get_bits(&gb, c->code_size)); + *samples++ = g726_decode(c, c->little_endian ? + get_bits_le(&gb, c->code_size) : + get_bits(&gb, c->code_size)); if (get_bits_left(&gb) > 0) av_log(avctx, AV_LOG_ERROR, "Frame invalidly split, missing parser?\n"); @@ -458,7 +463,9 @@ static void g726_decode_flush(AVCodecContext *avctx) G726Context *c = avctx->priv_data; g726_reset(c); } +#endif +#if CONFIG_ADPCM_G726_DECODER AVCodec ff_adpcm_g726_decoder = { .name = "g726", .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"), @@ -471,3 +478,17 @@ AVCodec ff_adpcm_g726_decoder = { .capabilities = CODEC_CAP_DR1, }; #endif + +#if CONFIG_ADPCM_G726LE_DECODER +AVCodec ff_adpcm_g726le_decoder = { + .name = "g726le", + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_ADPCM_G726LE, + .priv_data_size = sizeof(G726Context), + .init = g726_decode_init, + .decode = g726_decode_frame, + .flush = g726_decode_flush, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM little-endian"), +}; +#endif diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsm.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsm.h index e56f4cd0b..53d65c4dc 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsm.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsm.h @@ -22,10 +22,24 @@ #define AVCODEC_GSM_H /* bytes per block */ -#define GSM_BLOCK_SIZE 33 -#define GSM_MS_BLOCK_SIZE 65 +#define GSM_BLOCK_SIZE 33 +#define GSM_MS_BLOCK_SIZE 65 +#define MSN_MIN_BLOCK_SIZE 41 /* samples per block */ #define GSM_FRAME_SIZE 160 +enum GSMModes { + GSM_13000 = 0, + MSN_12400, + MSN_11800, + MSN_11200, + MSN_10600, + MSN_10000, + MSN_9400, + MSN_8800, + MSN_8200, + NUM_GSM_MODES +}; + #endif /* AVCODEC_GSM_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsm_parser.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsm_parser.c index f76bbef3e..9a3b94ef1 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsm_parser.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsm_parser.c @@ -50,7 +50,8 @@ static int gsm_parse(AVCodecParserContext *s1, AVCodecContext *avctx, s->duration = GSM_FRAME_SIZE; break; case AV_CODEC_ID_GSM_MS: - s->block_size = GSM_MS_BLOCK_SIZE; + s->block_size = avctx->block_align ? avctx->block_align + : GSM_MS_BLOCK_SIZE; s->duration = GSM_FRAME_SIZE * 2; break; default: diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec.c index 6817e65ac..5a9a23a51 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec.c @@ -34,14 +34,6 @@ static av_cold int gsm_init(AVCodecContext *avctx) { - if (avctx->codec_tag == 0x0032 && - avctx->bit_rate != 13000 && - avctx->bit_rate != 17912 && - avctx->bit_rate != 35824 && - avctx->bit_rate != 71656) { - av_log(avctx, AV_LOG_ERROR, "Unsupported audio mode\n"); - return AVERROR_PATCHWELCOME; - } avctx->channels = 1; avctx->channel_layout = AV_CH_LAYOUT_MONO; if (!avctx->sample_rate) @@ -55,8 +47,16 @@ static av_cold int gsm_init(AVCodecContext *avctx) break; case AV_CODEC_ID_GSM_MS: avctx->frame_size = 2 * GSM_FRAME_SIZE; - avctx->block_align = GSM_MS_BLOCK_SIZE; - default: break; + if (!avctx->block_align) + avctx->block_align = GSM_MS_BLOCK_SIZE; + else + if (avctx->block_align < MSN_MIN_BLOCK_SIZE || + avctx->block_align > GSM_MS_BLOCK_SIZE || + (avctx->block_align - MSN_MIN_BLOCK_SIZE) % 3) { + av_log(avctx, AV_LOG_ERROR, "Invalid block alignment %d\n", + avctx->block_align); + return AVERROR_INVALIDDATA; + } } return 0; @@ -88,12 +88,13 @@ static int gsm_decode_frame(AVCodecContext *avctx, void *data, init_get_bits(&gb, buf, buf_size * 8); if (get_bits(&gb, 4) != 0xd) av_log(avctx, AV_LOG_WARNING, "Missing GSM magic!\n"); - res = gsm_decode_block(avctx, samples, &gb); + res = gsm_decode_block(avctx, samples, &gb, GSM_13000); if (res < 0) return res; break; case AV_CODEC_ID_GSM_MS: - res = ff_msgsm_decode_block(avctx, samples, buf); + res = ff_msgsm_decode_block(avctx, samples, buf, + (GSM_MS_BLOCK_SIZE - avctx->block_align) / 3); if (res < 0) return res; default: break; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec_data.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec_data.c index 4324ea28a..d90c69b98 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec_data.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec_data.c @@ -92,3 +92,29 @@ const int16_t ff_gsm_dequant_tab[64][8] = { {-26879, -19199, -11520, -3840, 3840, 11520, 19199, 26879}, {-28671, -20479, -12288, -4096, 4096, 12288, 20479, 28671} }; + +static const int apcm_bits[11][13] = { + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1 }, + { 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1 }, + { 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1 }, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, + { 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, + { 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, + { 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, + { 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, + { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 } +}; + +const int* const ff_gsm_apcm_bits[][4] = { + { apcm_bits[10], apcm_bits[10], apcm_bits[10], apcm_bits[10] }, // 13000 + { apcm_bits[10], apcm_bits[10], apcm_bits[10], apcm_bits[ 6] }, // 12400 + { apcm_bits[10], apcm_bits[10], apcm_bits[ 7], apcm_bits[ 5] }, // 11800 + { apcm_bits[10], apcm_bits[ 8], apcm_bits[ 5], apcm_bits[ 5] }, // 11200 + { apcm_bits[ 9], apcm_bits[ 5], apcm_bits[ 5], apcm_bits[ 5] }, // 10600 + { apcm_bits[ 5], apcm_bits[ 5], apcm_bits[ 5], apcm_bits[ 1] }, // 10000 + { apcm_bits[ 5], apcm_bits[ 5], apcm_bits[ 2], apcm_bits[ 0] }, // 9400 + { apcm_bits[ 5], apcm_bits[ 3], apcm_bits[ 0], apcm_bits[ 0] }, // 8800 + { apcm_bits[ 4], apcm_bits[ 0], apcm_bits[ 0], apcm_bits[ 0] }, // 8200 +}; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec_data.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec_data.h index fd89ed63e..b57194b8d 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec_data.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec_data.h @@ -40,4 +40,6 @@ typedef struct GSMContext { extern const uint16_t ff_gsm_long_term_gain_tab[4]; extern const int16_t ff_gsm_dequant_tab[64][8]; +extern const int* const ff_gsm_apcm_bits[][4]; + #endif /* AVCODEC_GSMDEC_DATA_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec_template.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec_template.c index 0f559530e..0c60813a4 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec_template.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/gsmdec_template.c @@ -28,13 +28,22 @@ #include "gsm.h" #include "gsmdec_data.h" -static void apcm_dequant_add(GetBitContext *gb, int16_t *dst) +static const int requant_tab[4][8] = { + { 0 }, + { 0, 7 }, + { 0, 2, 5, 7 }, + { 0, 1, 2, 3, 4, 5, 6, 7 } +}; + +static void apcm_dequant_add(GetBitContext *gb, int16_t *dst, const int *frame_bits) { - int i; + int i, val; int maxidx = get_bits(gb, 6); const int16_t *tab = ff_gsm_dequant_tab[maxidx]; - for (i = 0; i < 13; i++) - dst[3*i] += tab[get_bits(gb, 3)]; + for (i = 0; i < 13; i++) { + val = get_bits(gb, frame_bits[i]); + dst[3*i] += tab[requant_tab[frame_bits[i]][val]]; + } } static inline int gsm_mult(int a, int b) @@ -118,7 +127,7 @@ static int postprocess(int16_t *data, int msr) } static int gsm_decode_block(AVCodecContext *avctx, int16_t *samples, - GetBitContext *gb) + GetBitContext *gb, int mode) { GSMContext *ctx = avctx->priv_data; int i; @@ -139,7 +148,7 @@ static int gsm_decode_block(AVCodecContext *avctx, int16_t *samples, int offset = get_bits(gb, 2); lag = av_clip(lag, 40, 120); long_term_synth(ref_dst, lag, gain_idx); - apcm_dequant_add(gb, ref_dst + offset); + apcm_dequant_add(gb, ref_dst + offset, ff_gsm_apcm_bits[mode][i]); ref_dst += 40; } memcpy(ctx->ref_buf, ctx->ref_buf + 160, 120 * sizeof(*ctx->ref_buf)); diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/hpeldsp.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/hpeldsp.c index 5cebd9dd5..ccf99d89c 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/hpeldsp.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/hpeldsp.c @@ -56,6 +56,8 @@ av_cold void ff_hpeldsp_init(HpelDSPContext *c, int flags) hpel_funcs(avg, [3], 2); hpel_funcs(avg_no_rnd,, 16); + if (ARCH_AARCH64) + ff_hpeldsp_init_aarch64(c, flags); if (ARCH_ALPHA) ff_hpeldsp_init_alpha(c, flags); if (ARCH_ARM) diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/internal.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/internal.h index 96976e1ae..8aa0ac101 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/internal.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/internal.h @@ -27,6 +27,7 @@ #include #include "libavutil/buffer.h" +#include "libavutil/channel_layout.h" #include "libavutil/mathematics.h" #include "libavutil/pixfmt.h" #include "avcodec.h" @@ -91,10 +92,18 @@ typedef struct AVCodecInternal { */ int last_audio_frame; - AVFrame to_free; + AVFrame *to_free; FramePool *pool; + void *thread_ctx; + + /** + * Current packet as passed into the decoder, to avoid having to pass the + * packet into every function. + */ + AVPacket *pkt; + /** * temporary buffer used for encoders to store their bitstream */ @@ -118,11 +127,10 @@ struct AVCodecDefault { * Return the hardware accelerated codec for codec codec_id and * pixel format pix_fmt. * - * @param codec_id the codec to match - * @param pix_fmt the pixel format to match + * @param avctx The codec context containing the codec_id and pixel format. * @return the hardware accelerated codec, or NULL if none was found. */ -AVHWAccel *ff_find_hwaccel(enum AVCodecID codec_id, enum AVPixelFormat pix_fmt); +AVHWAccel *ff_find_hwaccel(AVCodecContext *avctx); /** * Return the index into tab at which {a,b} match elements {[0],[1]} of tab. @@ -225,4 +233,16 @@ const uint8_t *avpriv_find_start_code(const uint8_t *p, const uint8_t *end, uint32_t *state); +/** + * Check that the provided frame dimensions are valid and set them on the codec + * context. + */ +int ff_set_dimensions(AVCodecContext *s, int width, int height); + +/** + * Add or update AV_FRAME_DATA_MATRIXENCODING side data. + */ +int ff_side_data_update_matrix_encoding(AVFrame *frame, + enum AVMatrixEncoding matrix_encoding); + #endif /* AVCODEC_INTERNAL_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/lpc.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/lpc.c index 9b46f5273..83643cc18 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/lpc.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/lpc.c @@ -20,7 +20,7 @@ */ #include "libavutil/common.h" -#include "libavutil/lls.h" +#include "libavutil/lls2.h" #include "libavutil/internal.h" #define LPC_USE_DOUBLE @@ -209,7 +209,7 @@ int ff_lpc_calc_coefs(LPCContext *s, } if (lpc_type == FF_LPC_TYPE_CHOLESKY) { - LLSModel m[2]; + LLSModel2 m[2]; LOCAL_ALIGNED(32, double, var, [FFALIGN(MAX_LPC_ORDER+1,4)]); double av_uninit(weight); memset(var, 0, FFALIGN(MAX_LPC_ORDER+1,4)*sizeof(*var)); @@ -218,7 +218,7 @@ int ff_lpc_calc_coefs(LPCContext *s, m[0].coeff[max_order-1][j] = -lpc[max_order-1][j]; for(; pass> FRAC_BITS) - -#define SAMPLES_BUF_SIZE 4096 - -typedef struct MpegAudioContext { - PutBitContext pb; - int nb_channels; - int lsf; /* 1 if mpeg2 low bitrate selected */ - int bitrate_index; /* bit rate */ - int freq_index; - int frame_size; /* frame size, in bits, without padding */ - /* padding computation */ - int frame_frac, frame_frac_incr, do_padding; - short samples_buf[MPA_MAX_CHANNELS][SAMPLES_BUF_SIZE]; /* buffer for filter */ - int samples_offset[MPA_MAX_CHANNELS]; /* offset in samples_buf */ - int sb_samples[MPA_MAX_CHANNELS][3][12][SBLIMIT]; - unsigned char scale_factors[MPA_MAX_CHANNELS][SBLIMIT][3]; /* scale factors */ - /* code to group 3 scale factors */ - unsigned char scale_code[MPA_MAX_CHANNELS][SBLIMIT]; - int sblimit; /* number of used subbands */ - const unsigned char *alloc_table; -} MpegAudioContext; - -/* define it to use floats in quantization (I don't like floats !) */ -#define USE_FLOATS - -#include "mpegaudiodata.h" -#include "mpegaudiotab.h" - -static av_cold int MPA_encode_init(AVCodecContext *avctx) -{ - MpegAudioContext *s = avctx->priv_data; - int freq = avctx->sample_rate; - int bitrate = avctx->bit_rate; - int channels = avctx->channels; - int i, v, table; - float a; - - if (channels <= 0 || channels > 2){ - av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed in mp2\n", channels); - return AVERROR(EINVAL); - } - bitrate = bitrate / 1000; - s->nb_channels = channels; - avctx->frame_size = MPA_FRAME_SIZE; - avctx->delay = 512 - 32 + 1; - - /* encoding freq */ - s->lsf = 0; - for(i=0;i<3;i++) { - if (avpriv_mpa_freq_tab[i] == freq) - break; - if ((avpriv_mpa_freq_tab[i] / 2) == freq) { - s->lsf = 1; - break; - } - } - if (i == 3){ - av_log(avctx, AV_LOG_ERROR, "Sampling rate %d is not allowed in mp2\n", freq); - return AVERROR(EINVAL); - } - s->freq_index = i; - - /* encoding bitrate & frequency */ - for(i=0;i<15;i++) { - if (avpriv_mpa_bitrate_tab[s->lsf][1][i] == bitrate) - break; - } - if (i == 15){ - av_log(avctx, AV_LOG_ERROR, "bitrate %d is not allowed in mp2\n", bitrate); - return AVERROR(EINVAL); - } - s->bitrate_index = i; - - /* compute total header size & pad bit */ - - a = (float)(bitrate * 1000 * MPA_FRAME_SIZE) / (freq * 8.0); - s->frame_size = ((int)a) * 8; - - /* frame fractional size to compute padding */ - s->frame_frac = 0; - s->frame_frac_incr = (int)((a - floor(a)) * 65536.0); - - /* select the right allocation table */ - table = ff_mpa_l2_select_table(bitrate, s->nb_channels, freq, s->lsf); - - /* number of used subbands */ - s->sblimit = ff_mpa_sblimit_table[table]; - s->alloc_table = ff_mpa_alloc_tables[table]; - - av_dlog(avctx, "%d kb/s, %d Hz, frame_size=%d bits, table=%d, padincr=%x\n", - bitrate, freq, s->frame_size, table, s->frame_frac_incr); - - for(i=0;inb_channels;i++) - s->samples_offset[i] = 0; - - for(i=0;i<257;i++) { - int v; - v = ff_mpa_enwindow[i]; -#if WFRAC_BITS != 16 - v = (v + (1 << (16 - WFRAC_BITS - 1))) >> (16 - WFRAC_BITS); -#endif - filter_bank[i] = v; - if ((i & 63) != 0) - v = -v; - if (i != 0) - filter_bank[512 - i] = v; - } - - for(i=0;i<64;i++) { - v = (int)(exp2((3 - i) / 3.0) * (1 << 20)); - if (v <= 0) - v = 1; - scale_factor_table[i] = v; -#ifdef USE_FLOATS - scale_factor_inv_table[i] = exp2(-(3 - i) / 3.0) / (float)(1 << 20); -#else -#define P 15 - scale_factor_shift[i] = 21 - P - (i / 3); - scale_factor_mult[i] = (1 << P) * exp2((i % 3) / 3.0); -#endif - } - for(i=0;i<128;i++) { - v = i - 64; - if (v <= -3) - v = 0; - else if (v < 0) - v = 1; - else if (v == 0) - v = 2; - else if (v < 3) - v = 3; - else - v = 4; - scale_diff_table[i] = v; - } - - for(i=0;i<17;i++) { - v = ff_mpa_quant_bits[i]; - if (v < 0) - v = -v; - else - v = v * 3; - total_quant_bits[i] = 12 * v; - } - - return 0; -} - -/* 32 point floating point IDCT without 1/sqrt(2) coef zero scaling */ -static void idct32(int *out, int *tab) -{ - int i, j; - int *t, *t1, xr; - const int *xp = costab32; - - for(j=31;j>=3;j-=2) tab[j] += tab[j - 2]; - - t = tab + 30; - t1 = tab + 2; - do { - t[0] += t[-4]; - t[1] += t[1 - 4]; - t -= 4; - } while (t != t1); - - t = tab + 28; - t1 = tab + 4; - do { - t[0] += t[-8]; - t[1] += t[1-8]; - t[2] += t[2-8]; - t[3] += t[3-8]; - t -= 8; - } while (t != t1); - - t = tab; - t1 = tab + 32; - do { - t[ 3] = -t[ 3]; - t[ 6] = -t[ 6]; - - t[11] = -t[11]; - t[12] = -t[12]; - t[13] = -t[13]; - t[15] = -t[15]; - t += 16; - } while (t != t1); - - - t = tab; - t1 = tab + 8; - do { - int x1, x2, x3, x4; - - x3 = MUL(t[16], FIX(SQRT2*0.5)); - x4 = t[0] - x3; - x3 = t[0] + x3; - - x2 = MUL(-(t[24] + t[8]), FIX(SQRT2*0.5)); - x1 = MUL((t[8] - x2), xp[0]); - x2 = MUL((t[8] + x2), xp[1]); - - t[ 0] = x3 + x1; - t[ 8] = x4 - x2; - t[16] = x4 + x2; - t[24] = x3 - x1; - t++; - } while (t != t1); - - xp += 2; - t = tab; - t1 = tab + 4; - do { - xr = MUL(t[28],xp[0]); - t[28] = (t[0] - xr); - t[0] = (t[0] + xr); - - xr = MUL(t[4],xp[1]); - t[ 4] = (t[24] - xr); - t[24] = (t[24] + xr); - - xr = MUL(t[20],xp[2]); - t[20] = (t[8] - xr); - t[ 8] = (t[8] + xr); - - xr = MUL(t[12],xp[3]); - t[12] = (t[16] - xr); - t[16] = (t[16] + xr); - t++; - } while (t != t1); - xp += 4; - - for (i = 0; i < 4; i++) { - xr = MUL(tab[30-i*4],xp[0]); - tab[30-i*4] = (tab[i*4] - xr); - tab[ i*4] = (tab[i*4] + xr); - - xr = MUL(tab[ 2+i*4],xp[1]); - tab[ 2+i*4] = (tab[28-i*4] - xr); - tab[28-i*4] = (tab[28-i*4] + xr); - - xr = MUL(tab[31-i*4],xp[0]); - tab[31-i*4] = (tab[1+i*4] - xr); - tab[ 1+i*4] = (tab[1+i*4] + xr); - - xr = MUL(tab[ 3+i*4],xp[1]); - tab[ 3+i*4] = (tab[29-i*4] - xr); - tab[29-i*4] = (tab[29-i*4] + xr); - - xp += 2; - } - - t = tab + 30; - t1 = tab + 1; - do { - xr = MUL(t1[0], *xp); - t1[0] = (t[0] - xr); - t[0] = (t[0] + xr); - t -= 2; - t1 += 2; - xp++; - } while (t >= tab); - - for(i=0;i<32;i++) { - out[i] = tab[bitinv32[i]]; - } -} - -#define WSHIFT (WFRAC_BITS + 15 - FRAC_BITS) - -static void filter(MpegAudioContext *s, int ch, const short *samples, int incr) -{ - short *p, *q; - int sum, offset, i, j; - int tmp[64]; - int tmp1[32]; - int *out; - - offset = s->samples_offset[ch]; - out = &s->sb_samples[ch][0][0][0]; - for(j=0;j<36;j++) { - /* 32 samples at once */ - for(i=0;i<32;i++) { - s->samples_buf[ch][offset + (31 - i)] = samples[0]; - samples += incr; - } - - /* filter */ - p = s->samples_buf[ch] + offset; - q = filter_bank; - /* maxsum = 23169 */ - for(i=0;i<64;i++) { - sum = p[0*64] * q[0*64]; - sum += p[1*64] * q[1*64]; - sum += p[2*64] * q[2*64]; - sum += p[3*64] * q[3*64]; - sum += p[4*64] * q[4*64]; - sum += p[5*64] * q[5*64]; - sum += p[6*64] * q[6*64]; - sum += p[7*64] * q[7*64]; - tmp[i] = sum; - p++; - q++; - } - tmp1[0] = tmp[16] >> WSHIFT; - for( i=1; i<=16; i++ ) tmp1[i] = (tmp[i+16]+tmp[16-i]) >> WSHIFT; - for( i=17; i<=31; i++ ) tmp1[i] = (tmp[i+16]-tmp[80-i]) >> WSHIFT; - - idct32(out, tmp1); - - /* advance of 32 samples */ - offset -= 32; - out += 32; - /* handle the wrap around */ - if (offset < 0) { - memmove(s->samples_buf[ch] + SAMPLES_BUF_SIZE - (512 - 32), - s->samples_buf[ch], (512 - 32) * 2); - offset = SAMPLES_BUF_SIZE - 512; - } - } - s->samples_offset[ch] = offset; -} - -static void compute_scale_factors(unsigned char scale_code[SBLIMIT], - unsigned char scale_factors[SBLIMIT][3], - int sb_samples[3][12][SBLIMIT], - int sblimit) -{ - int *p, vmax, v, n, i, j, k, code; - int index, d1, d2; - unsigned char *sf = &scale_factors[0][0]; - - for(j=0;j vmax) - vmax = v; - } - /* compute the scale factor index using log 2 computations */ - if (vmax > 1) { - n = av_log2(vmax); - /* n is the position of the MSB of vmax. now - use at most 2 compares to find the index */ - index = (21 - n) * 3 - 3; - if (index >= 0) { - while (vmax <= scale_factor_table[index+1]) - index++; - } else { - index = 0; /* very unlikely case of overflow */ - } - } else { - index = 62; /* value 63 is not allowed */ - } - - av_dlog(NULL, "%2d:%d in=%x %x %d\n", - j, i, vmax, scale_factor_table[index], index); - /* store the scale factor */ - av_assert2(index >=0 && index <= 63); - sf[i] = index; - } - - /* compute the transmission factor : look if the scale factors - are close enough to each other */ - d1 = scale_diff_table[sf[0] - sf[1] + 64]; - d2 = scale_diff_table[sf[1] - sf[2] + 64]; - - /* handle the 25 cases */ - switch(d1 * 5 + d2) { - case 0*5+0: - case 0*5+4: - case 3*5+4: - case 4*5+0: - case 4*5+4: - code = 0; - break; - case 0*5+1: - case 0*5+2: - case 4*5+1: - case 4*5+2: - code = 3; - sf[2] = sf[1]; - break; - case 0*5+3: - case 4*5+3: - code = 3; - sf[1] = sf[2]; - break; - case 1*5+0: - case 1*5+4: - case 2*5+4: - code = 1; - sf[1] = sf[0]; - break; - case 1*5+1: - case 1*5+2: - case 2*5+0: - case 2*5+1: - case 2*5+2: - code = 2; - sf[1] = sf[2] = sf[0]; - break; - case 2*5+3: - case 3*5+3: - code = 2; - sf[0] = sf[1] = sf[2]; - break; - case 3*5+0: - case 3*5+1: - case 3*5+2: - code = 2; - sf[0] = sf[2] = sf[1]; - break; - case 1*5+3: - code = 2; - if (sf[0] > sf[2]) - sf[0] = sf[2]; - sf[1] = sf[2] = sf[0]; - break; - default: - av_assert2(0); //cannot happen - code = 0; /* kill warning */ - } - - av_dlog(NULL, "%d: %2d %2d %2d %d %d -> %d\n", j, - sf[0], sf[1], sf[2], d1, d2, code); - scale_code[j] = code; - sf += 3; - } -} - -/* The most important function : psycho acoustic module. In this - encoder there is basically none, so this is the worst you can do, - but also this is the simpler. */ -static void psycho_acoustic_model(MpegAudioContext *s, short smr[SBLIMIT]) -{ - int i; - - for(i=0;isblimit;i++) { - smr[i] = (int)(fixed_smr[i] * 10); - } -} - - -#define SB_NOTALLOCATED 0 -#define SB_ALLOCATED 1 -#define SB_NOMORE 2 - -/* Try to maximize the smr while using a number of bits inferior to - the frame size. I tried to make the code simpler, faster and - smaller than other encoders :-) */ -static void compute_bit_allocation(MpegAudioContext *s, - short smr1[MPA_MAX_CHANNELS][SBLIMIT], - unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT], - int *padding) -{ - int i, ch, b, max_smr, max_ch, max_sb, current_frame_size, max_frame_size; - int incr; - short smr[MPA_MAX_CHANNELS][SBLIMIT]; - unsigned char subband_status[MPA_MAX_CHANNELS][SBLIMIT]; - const unsigned char *alloc; - - memcpy(smr, smr1, s->nb_channels * sizeof(short) * SBLIMIT); - memset(subband_status, SB_NOTALLOCATED, s->nb_channels * SBLIMIT); - memset(bit_alloc, 0, s->nb_channels * SBLIMIT); - - /* compute frame size and padding */ - max_frame_size = s->frame_size; - s->frame_frac += s->frame_frac_incr; - if (s->frame_frac >= 65536) { - s->frame_frac -= 65536; - s->do_padding = 1; - max_frame_size += 8; - } else { - s->do_padding = 0; - } - - /* compute the header + bit alloc size */ - current_frame_size = 32; - alloc = s->alloc_table; - for(i=0;isblimit;i++) { - incr = alloc[0]; - current_frame_size += incr * s->nb_channels; - alloc += 1 << incr; - } - for(;;) { - /* look for the subband with the largest signal to mask ratio */ - max_sb = -1; - max_ch = -1; - max_smr = INT_MIN; - for(ch=0;chnb_channels;ch++) { - for(i=0;isblimit;i++) { - if (smr[ch][i] > max_smr && subband_status[ch][i] != SB_NOMORE) { - max_smr = smr[ch][i]; - max_sb = i; - max_ch = ch; - } - } - } - if (max_sb < 0) - break; - av_dlog(NULL, "current=%d max=%d max_sb=%d max_ch=%d alloc=%d\n", - current_frame_size, max_frame_size, max_sb, max_ch, - bit_alloc[max_ch][max_sb]); - - /* find alloc table entry (XXX: not optimal, should use - pointer table) */ - alloc = s->alloc_table; - for(i=0;iscale_code[max_ch][max_sb]] * 6; - incr += total_quant_bits[alloc[1]]; - } else { - /* increments bit allocation */ - b = bit_alloc[max_ch][max_sb]; - incr = total_quant_bits[alloc[b + 1]] - - total_quant_bits[alloc[b]]; - } - - if (current_frame_size + incr <= max_frame_size) { - /* can increase size */ - b = ++bit_alloc[max_ch][max_sb]; - current_frame_size += incr; - /* decrease smr by the resolution we added */ - smr[max_ch][max_sb] = smr1[max_ch][max_sb] - quant_snr[alloc[b]]; - /* max allocation size reached ? */ - if (b == ((1 << alloc[0]) - 1)) - subband_status[max_ch][max_sb] = SB_NOMORE; - else - subband_status[max_ch][max_sb] = SB_ALLOCATED; - } else { - /* cannot increase the size of this subband */ - subband_status[max_ch][max_sb] = SB_NOMORE; - } - } - *padding = max_frame_size - current_frame_size; - av_assert0(*padding >= 0); -} - -/* - * Output the mpeg audio layer 2 frame. Note how the code is small - * compared to other encoders :-) - */ -static void encode_frame(MpegAudioContext *s, - unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT], - int padding) -{ - int i, j, k, l, bit_alloc_bits, b, ch; - unsigned char *sf; - int q[3]; - PutBitContext *p = &s->pb; - - /* header */ - - put_bits(p, 12, 0xfff); - put_bits(p, 1, 1 - s->lsf); /* 1 = mpeg1 ID, 0 = mpeg2 lsf ID */ - put_bits(p, 2, 4-2); /* layer 2 */ - put_bits(p, 1, 1); /* no error protection */ - put_bits(p, 4, s->bitrate_index); - put_bits(p, 2, s->freq_index); - put_bits(p, 1, s->do_padding); /* use padding */ - put_bits(p, 1, 0); /* private_bit */ - put_bits(p, 2, s->nb_channels == 2 ? MPA_STEREO : MPA_MONO); - put_bits(p, 2, 0); /* mode_ext */ - put_bits(p, 1, 0); /* no copyright */ - put_bits(p, 1, 1); /* original */ - put_bits(p, 2, 0); /* no emphasis */ - - /* bit allocation */ - j = 0; - for(i=0;isblimit;i++) { - bit_alloc_bits = s->alloc_table[j]; - for(ch=0;chnb_channels;ch++) { - put_bits(p, bit_alloc_bits, bit_alloc[ch][i]); - } - j += 1 << bit_alloc_bits; - } - - /* scale codes */ - for(i=0;isblimit;i++) { - for(ch=0;chnb_channels;ch++) { - if (bit_alloc[ch][i]) - put_bits(p, 2, s->scale_code[ch][i]); - } - } - - /* scale factors */ - for(i=0;isblimit;i++) { - for(ch=0;chnb_channels;ch++) { - if (bit_alloc[ch][i]) { - sf = &s->scale_factors[ch][i][0]; - switch(s->scale_code[ch][i]) { - case 0: - put_bits(p, 6, sf[0]); - put_bits(p, 6, sf[1]); - put_bits(p, 6, sf[2]); - break; - case 3: - case 1: - put_bits(p, 6, sf[0]); - put_bits(p, 6, sf[2]); - break; - case 2: - put_bits(p, 6, sf[0]); - break; - } - } - } - } - - /* quantization & write sub band samples */ - - for(k=0;k<3;k++) { - for(l=0;l<12;l+=3) { - j = 0; - for(i=0;isblimit;i++) { - bit_alloc_bits = s->alloc_table[j]; - for(ch=0;chnb_channels;ch++) { - b = bit_alloc[ch][i]; - if (b) { - int qindex, steps, m, sample, bits; - /* we encode 3 sub band samples of the same sub band at a time */ - qindex = s->alloc_table[j+b]; - steps = ff_mpa_quant_steps[qindex]; - for(m=0;m<3;m++) { - sample = s->sb_samples[ch][k][l + m][i]; - /* divide by scale factor */ -#ifdef USE_FLOATS - { - float a; - a = (float)sample * scale_factor_inv_table[s->scale_factors[ch][i][k]]; - q[m] = (int)((a + 1.0) * steps * 0.5); - } -#else - { - int q1, e, shift, mult; - e = s->scale_factors[ch][i][k]; - shift = scale_factor_shift[e]; - mult = scale_factor_mult[e]; - - /* normalize to P bits */ - if (shift < 0) - q1 = sample << (-shift); - else - q1 = sample >> shift; - q1 = (q1 * mult) >> P; - q[m] = ((q1 + (1 << P)) * steps) >> (P + 1); - } -#endif - if (q[m] >= steps) - q[m] = steps - 1; - av_assert2(q[m] >= 0 && q[m] < steps); - } - bits = ff_mpa_quant_bits[qindex]; - if (bits < 0) { - /* group the 3 values to save bits */ - put_bits(p, -bits, - q[0] + steps * (q[1] + steps * q[2])); - } else { - put_bits(p, bits, q[0]); - put_bits(p, bits, q[1]); - put_bits(p, bits, q[2]); - } - } - } - /* next subband in alloc table */ - j += 1 << bit_alloc_bits; - } - } - } - - /* padding */ - for(i=0;ipriv_data; - const int16_t *samples = (const int16_t *)frame->data[0]; - short smr[MPA_MAX_CHANNELS][SBLIMIT]; - unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT]; - int padding, i, ret; - - for(i=0;inb_channels;i++) { - filter(s, i, samples + i, s->nb_channels); - } - - for(i=0;inb_channels;i++) { - compute_scale_factors(s->scale_code[i], s->scale_factors[i], - s->sb_samples[i], s->sblimit); - } - for(i=0;inb_channels;i++) { - psycho_acoustic_model(s, smr[i]); - } - compute_bit_allocation(s, smr, bit_alloc, &padding); - - if ((ret = ff_alloc_packet2(avctx, avpkt, MPA_MAX_CODED_FRAME_SIZE)) < 0) - return ret; - - init_put_bits(&s->pb, avpkt->data, avpkt->size); - - encode_frame(s, bit_alloc, padding); - - if (frame->pts != AV_NOPTS_VALUE) - avpkt->pts = frame->pts - ff_samples_to_time_base(avctx, avctx->delay); - - avpkt->size = put_bits_count(&s->pb) / 8; - *got_packet_ptr = 1; - return 0; -} - -static const AVCodecDefault mp2_defaults[] = { - { (const uint8_t *) "b", (const uint8_t *) "128k" }, - { NULL }, -}; - -AVCodec ff_mp2_encoder = { - .name = "mp2", - .long_name = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"), - .type = AVMEDIA_TYPE_AUDIO, - .id = AV_CODEC_ID_MP2, - .priv_data_size = sizeof(MpegAudioContext), - .init = MPA_encode_init, - .encode2 = MPA_encode_frame, - .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, - AV_SAMPLE_FMT_NONE }, - .supported_samplerates = (const int[]){ - 44100, 48000, 32000, 22050, 24000, 16000, 0 - }, - .channel_layouts = (const uint64_t[]){ AV_CH_LAYOUT_MONO, - AV_CH_LAYOUT_STEREO, - 0 }, - .defaults = mp2_defaults, -}; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/msgsmdec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/msgsmdec.c index 90e83ae7a..4c4ddb46f 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/msgsmdec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/msgsmdec.c @@ -26,13 +26,13 @@ #include "gsmdec_template.c" int ff_msgsm_decode_block(AVCodecContext *avctx, int16_t *samples, - const uint8_t *buf) + const uint8_t *buf, int mode) { int res; GetBitContext gb; init_get_bits(&gb, buf, GSM_MS_BLOCK_SIZE * 8); - res = gsm_decode_block(avctx, samples, &gb); + res = gsm_decode_block(avctx, samples, &gb, mode); if (res < 0) return res; - return gsm_decode_block(avctx, samples + GSM_FRAME_SIZE, &gb); + return gsm_decode_block(avctx, samples + GSM_FRAME_SIZE, &gb, mode); } diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/msgsmdec.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/msgsmdec.h index 3bfd1fd40..b2a1a627a 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/msgsmdec.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/msgsmdec.h @@ -25,6 +25,6 @@ #include "avcodec.h" int ff_msgsm_decode_block(AVCodecContext *avctx, int16_t *samples, - const uint8_t *buf); + const uint8_t *buf, int mode); #endif /* AVCODEC_MSGSMDEC_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/old_codec_ids.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/old_codec_ids.h index 597e3d2c0..858ea6e65 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/old_codec_ids.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/old_codec_ids.h @@ -38,7 +38,9 @@ /* video codecs */ CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding +#if FF_API_XVMC CODEC_ID_MPEG2VIDEO_XVMC, +#endif CODEC_ID_H261, CODEC_ID_H263, CODEC_ID_RV10, diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/options.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/options.c index 9c00c62e1..5ee9d6bd7 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/options.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/options.c @@ -53,7 +53,7 @@ static void *codec_child_next(void *obj, void *prev) static const AVClass *codec_child_class_next(const AVClass *prev) { - const AVCodec *c = NULL; + AVCodec *c = NULL; /* find the codec that corresponds to prev */ while (prev && (c = av_codec_next(c))) @@ -61,7 +61,7 @@ static const AVClass *codec_child_class_next(const AVClass *prev) break; /* find next codec with priv options */ - while ((c = av_codec_next(c))) + while (c = av_codec_next(c)) if (c->priv_class) return c->priv_class; return NULL; @@ -86,14 +86,6 @@ static const AVClass av_codec_context_class = { .get_category = get_category, }; -#if FF_API_ALLOC_CONTEXT -void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType codec_type){ - AVCodec c= {0}; - c.type= codec_type; - avcodec_get_context_defaults3(s, &c); -} -#endif - int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec) { int flags=0; @@ -111,9 +103,7 @@ int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec) flags= AV_OPT_FLAG_VIDEO_PARAM; else if(s->codec_type == AVMEDIA_TYPE_SUBTITLE) flags= AV_OPT_FLAG_SUBTITLE_PARAM; - AV_NOWARN_DEPRECATED( av_opt_set_defaults2(s, flags, flags); - ); s->time_base = (AVRational){0,1}; s->get_buffer2 = avcodec_default_get_buffer2; @@ -142,7 +132,7 @@ int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec) int ret; const AVCodecDefault *d = codec->defaults; while (d->key) { - ret = av_opt_set(s, (const char *) d->key, (const char *) d->value, 0); + ret = av_opt_set(s, d->key, d->value, 0); av_assert0(ret >= 0); d++; } @@ -164,26 +154,6 @@ AVCodecContext *avcodec_alloc_context3(const AVCodec *codec) return avctx; } -#if FF_API_ALLOC_CONTEXT -AVCodecContext *avcodec_alloc_context2(enum AVMediaType codec_type){ - AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext)); - - if(avctx==NULL) return NULL; - - avcodec_get_context_defaults2(avctx, codec_type); - - return avctx; -} - -void avcodec_get_context_defaults(AVCodecContext *s){ - avcodec_get_context_defaults2(s, AVMEDIA_TYPE_UNKNOWN); -} - -AVCodecContext *avcodec_alloc_context(void){ - return avcodec_alloc_context2(AVMEDIA_TYPE_UNKNOWN); -} -#endif - int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src) { if (avcodec_is_open(dest)) { // check that the dest context is uninitialized @@ -203,7 +173,6 @@ int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src) dest->codec = NULL; dest->slice_offset = NULL; dest->hwaccel = NULL; - dest->thread_opaque = NULL; dest->internal = NULL; /* reallocate values that should be allocated separately */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/rawdec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/rawdec.c index 54ed52df0..0423e38c1 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/rawdec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/rawdec.c @@ -25,6 +25,7 @@ */ #include "avcodec.h" +#include "internal.h" #include "raw.h" #include "libavutil/avassert.h" #include "libavutil/buffer.h" @@ -40,6 +41,7 @@ typedef struct RawVideoContext { int flip; int is_2_4_bpp; // 2 or 4 bpp raw in avi/mov int is_yuv2; + int is_lt_16bpp; // 16bpp pixfmt and bits_per_coded_sample < 16 int tff; } RawVideoContext; @@ -107,7 +109,7 @@ static av_cold int raw_init_decoder(AVCodecContext *avctx) if ( avctx->codec_tag == MKTAG('r','a','w',' ') || avctx->codec_tag == MKTAG('N','O','1','6')) avctx->pix_fmt = avpriv_find_pix_fmt(pix_fmt_bps_mov, - avctx->bits_per_coded_sample); + avctx->bits_per_coded_sample & 0x1f); else if (avctx->codec_tag == MKTAG('W', 'R', 'A', 'W')) avctx->pix_fmt = avpriv_find_pix_fmt(pix_fmt_bps_avi, avctx->bits_per_coded_sample); @@ -133,7 +135,7 @@ static av_cold int raw_init_decoder(AVCodecContext *avctx) memset(context->palette->data, 0, AVPALETTE_SIZE); } - if ((avctx->bits_per_coded_sample == 4 || avctx->bits_per_coded_sample == 2) && + if (((avctx->bits_per_coded_sample & 0x1f) == 4 || (avctx->bits_per_coded_sample & 0x1f) == 2) && avctx->pix_fmt == AV_PIX_FMT_PAL8 && (!avctx->codec_tag || avctx->codec_tag == MKTAG('r','a','w',' '))) { context->is_2_4_bpp = 1; @@ -141,6 +143,7 @@ static av_cold int raw_init_decoder(AVCodecContext *avctx) FFALIGN(avctx->width, 16), avctx->height); } else { + context->is_lt_16bpp = av_get_bits_per_pixel(desc) == 16 && avctx->bits_per_coded_sample && avctx->bits_per_coded_sample < 16; context->frame_size = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height); } @@ -174,7 +177,7 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame, int buf_size = avpkt->size; int linesize_align = 4; int res, len; - int need_copy = !avpkt->buf || context->is_2_4_bpp || context->is_yuv2; + int need_copy = !avpkt->buf || context->is_2_4_bpp || context->is_yuv2 || context->is_lt_16bpp; AVFrame *frame = data; AVPicture *picture = data; @@ -182,9 +185,9 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame, frame->pict_type = AV_PICTURE_TYPE_I; frame->key_frame = 1; frame->reordered_opaque = avctx->reordered_opaque; - frame->pkt_pts = avctx->pkt->pts; - av_frame_set_pkt_pos (frame, avctx->pkt->pos); - av_frame_set_pkt_duration(frame, avctx->pkt->duration); + frame->pkt_pts = avctx->internal->pkt->pts; + av_frame_set_pkt_pos (frame, avctx->internal->pkt->pos); + av_frame_set_pkt_duration(frame, avctx->internal->pkt->duration); if (context->tff >= 0) { frame->interlaced_frame = 1; @@ -206,14 +209,14 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame, int i; uint8_t *dst = frame->buf[0]->data; buf_size = context->frame_size - AVPALETTE_SIZE; - if (avctx->bits_per_coded_sample == 4) { + if ((avctx->bits_per_coded_sample & 0x1f) == 4) { for (i = 0; 2 * i + 1 < buf_size && isize; i++) { dst[2 * i + 0] = buf[i] >> 4; dst[2 * i + 1] = buf[i] & 15; } linesize_align = 8; } else { - av_assert0(avctx->bits_per_coded_sample == 2); + av_assert0((avctx->bits_per_coded_sample & 0x1f) == 2); for (i = 0; 4 * i + 3 < buf_size && isize; i++) { dst[4 * i + 0] = buf[i] >> 6; dst[4 * i + 1] = buf[i] >> 4 & 3; @@ -223,6 +226,17 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame, linesize_align = 16; } buf = dst; + } else if (context->is_lt_16bpp) { + int i; + uint8_t *dst = frame->buf[0]->data; + if (desc->flags & AV_PIX_FMT_FLAG_BE) { + for (i = 0; i + 1 < buf_size; i += 2) + AV_WB16(dst + i, AV_RB16(buf + i) << (16 - avctx->bits_per_coded_sample)); + } else { + for (i = 0; i + 1 < buf_size; i += 2) + AV_WL16(dst + i, AV_RL16(buf + i) << (16 - avctx->bits_per_coded_sample)); + } + buf = dst; } else if (need_copy) { memcpy(frame->buf[0]->data, buf, buf_size); buf = frame->buf[0]->data; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/tak_parser.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/tak_parser.c index e45366c02..5d8460c90 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/tak_parser.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/tak_parser.c @@ -97,7 +97,7 @@ static int tak_parse(AVCodecParserContext *s, AVCodecContext *avctx, } found: - if ((consumed && !buf_size && next == END_NOT_FOUND) || + if (consumed && !buf_size && next == END_NOT_FOUND || ff_combine_frame(pc, next, &buf, &buf_size) < 0) { *poutbuf = NULL; *poutbuf_size = 0; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/takdec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/takdec.c index a832c58e9..86ca3ac01 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/takdec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/takdec.c @@ -163,8 +163,8 @@ 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; + 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) @@ -190,7 +190,7 @@ static void decode_lpc(int32_t *coeffs, int mode, int length) if (mode == 1) { int a1 = *coeffs++; - for (i = 0; i < (length - 1) >> 1; i++) { + for (i = 0; i < length - 1 >> 1; i++) { *coeffs += a1; coeffs[1] += *coeffs; a1 = coeffs[1]; @@ -204,7 +204,7 @@ static void decode_lpc(int32_t *coeffs, int mode, int length) coeffs[1] = a2; if (length > 2) { coeffs += 2; - for (i = 0; i < (length - 2) >> 1; i++) { + for (i = 0; i < length - 2 >> 1; i++) { int a3 = *coeffs + a1; int a4 = a3 + a2; *coeffs = a4; @@ -436,8 +436,8 @@ static int decode_subframe(TAKDecContext *s, int32_t *decoded, 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; + x = *p1 + (s->predictors[i] * *p2 + 256 >> 9); + *p2 += s->predictors[i] * *p1 + 256 >> 9; *p1++ = x; p2--; } @@ -579,7 +579,7 @@ static int decorrelate(TAKDecContext *s, int c1, int c2, int length) for (i = 0; i < length; i++) { int32_t a = p1[i]; int32_t b = p2[i]; - b = (dfactor * (b >> dshift) + 128) >> 8 << dshift; + b = dfactor * (b >> dshift) + 128 >> 8 << dshift; p1[i] = b - a; } break; @@ -686,11 +686,12 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, if ((ret = ff_tak_decode_frame_header(avctx, gb, &s->ti, 0)) < 0) return ret; - if (avctx->err_recognition & AV_EF_CRCCHECK) { + if (avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_COMPLIANT)) { 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 (avctx->err_recognition & AV_EF_EXPLODE) + return AVERROR_INVALIDDATA; } } @@ -720,11 +721,9 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, 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; - } + 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); @@ -767,7 +766,7 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, } else { if (s->ti.codec == TAK_CODEC_MONO_STEREO) { for (chan = 0; chan < avctx->channels; chan++) - if ((ret = decode_channel(s, chan))) + if (ret = decode_channel(s, chan)) return ret; if (avctx->channels == 2) { @@ -777,7 +776,7 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, } s->dmode = get_bits(gb, 3); - if ((ret = decorrelate(s, 0, 1, s->nb_samples - 1))) + if (ret = decorrelate(s, 0, 1, s->nb_samples - 1)) return ret; } } else if (s->ti.codec == TAK_CODEC_MULTICHANNEL) { @@ -825,18 +824,18 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, 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))) + if (ret = decode_channel(s, s->mcdparams[i].chan2)) return ret; - if ((ret = decode_channel(s, s->mcdparams[i].chan1))) + 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, + if (ret = decorrelate(s, s->mcdparams[i].chan2, s->mcdparams[i].chan1, - s->nb_samples - 1))) + s->nb_samples - 1)) return ret; } } @@ -861,11 +860,12 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, else if (get_bits_left(gb) > 0) av_log(avctx, AV_LOG_DEBUG, "underread\n"); - if (avctx->err_recognition & AV_EF_CRCCHECK) { + if (avctx->err_recognition & (AV_EF_CRCCHECK | AV_EF_COMPLIANT)) { 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; + if (avctx->err_recognition & AV_EF_EXPLODE) + return AVERROR_INVALIDDATA; } } @@ -894,7 +894,6 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, samples[i] <<= 8; } break; - default: break; } *got_frame_ptr = 1; @@ -932,6 +931,7 @@ static av_cold int tak_decode_close(AVCodecContext *avctx) AVCodec ff_tak_decoder = { .name = "tak", + .long_name = NULL_IF_CONFIG_SMALL("TAK (Tom's lossless Audio Kompressor)"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_TAK, .priv_data_size = sizeof(TAKDecContext), @@ -941,7 +941,6 @@ AVCodec ff_tak_decoder = { .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, diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/truespeech.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/truespeech.c index 09c30c7aa..d3e3b20e9 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/truespeech.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/truespeech.c @@ -21,7 +21,6 @@ #include "libavutil/channel_layout.h" #include "libavutil/intreadwrite.h" -#include "libavutil/internal.h" #include "avcodec.h" #include "dsputil.h" #include "get_bits.h" diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/tta.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/tta.c index 91fc1f299..8778541e5 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/tta.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/tta.c @@ -29,8 +29,8 @@ #define BITSTREAM_READER_LE #include -#include "config.h" #include "ttadata.h" +#include "ttadsp.h" #include "avcodec.h" #include "get_bits.h" #include "thread.h" @@ -39,7 +39,6 @@ #include "libavutil/crc.h" #include "libavutil/intreadwrite.h" #include "libavutil/opt.h" -#include "libavutil/internal.h" #define FORMAT_SIMPLE 1 #define FORMAT_ENCRYPTED 2 @@ -58,39 +57,9 @@ typedef struct TTAContext { uint8_t crc_pass[8]; uint8_t *pass; TTAChannel *ch_ctx; + TTADSPContext dsp; } TTAContext; -static inline void ttafilter_process(TTAFilter *c, int32_t *in) -{ - register int32_t *dl = c->dl, *qm = c->qm, *dx = c->dx, sum = c->round; - - if (c->error < 0) { - qm[0] -= dx[0]; qm[1] -= dx[1]; qm[2] -= dx[2]; qm[3] -= dx[3]; - qm[4] -= dx[4]; qm[5] -= dx[5]; qm[6] -= dx[6]; qm[7] -= dx[7]; - } else if (c->error > 0) { - qm[0] += dx[0]; qm[1] += dx[1]; qm[2] += dx[2]; qm[3] += dx[3]; - qm[4] += dx[4]; qm[5] += dx[5]; qm[6] += dx[6]; qm[7] += dx[7]; - } - - sum += dl[0] * qm[0] + dl[1] * qm[1] + dl[2] * qm[2] + dl[3] * qm[3] + - dl[4] * qm[4] + dl[5] * qm[5] + dl[6] * qm[6] + dl[7] * qm[7]; - - dx[0] = dx[1]; dx[1] = dx[2]; dx[2] = dx[3]; dx[3] = dx[4]; - dl[0] = dl[1]; dl[1] = dl[2]; dl[2] = dl[3]; dl[3] = dl[4]; - - dx[4] = ((dl[4] >> 30) | 1); - dx[5] = ((dl[5] >> 30) | 2) & ~1; - dx[6] = ((dl[6] >> 30) | 2) & ~1; - dx[7] = ((dl[7] >> 30) | 4) & ~3; - - c->error = *in; - *in += (sum >> c->shift); - - dl[4] = -dl[5]; dl[5] = -dl[6]; - dl[6] = *in - dl[7]; dl[7] = *in; - dl[5] += dl[6]; dl[4] += dl[5]; -} - static const int64_t tta_channel_layouts[7] = { AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY, @@ -118,7 +87,7 @@ static int tta_check_crc(TTAContext *s, const uint8_t *buf, int buf_size) static uint64_t tta_check_crc64(uint8_t *pass) { uint64_t crc = UINT64_MAX, poly = 0x42F0E1EBA9EA3693U; - uint8_t *end = pass + strlen((const char *) pass); + uint8_t *end = pass + strlen((const char *)pass); int i; while (pass < end) { @@ -236,6 +205,8 @@ static av_cold int tta_decode_init(AVCodecContext * avctx) return AVERROR_INVALIDDATA; } + ff_ttadsp_init(&s->dsp); + return allocate_buffers(avctx); } @@ -253,7 +224,8 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, int32_t *p; if (avctx->err_recognition & AV_EF_CRCCHECK) { - if (buf_size < 4 || tta_check_crc(s, buf, buf_size - 4)) + if (buf_size < 4 || + (tta_check_crc(s, buf, buf_size - 4) && avctx->err_recognition & AV_EF_EXPLODE)) return AVERROR_INVALIDDATA; } @@ -336,7 +308,8 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, *p = 1 + ((value >> 1) ^ ((value & 1) - 1)); // run hybrid filter - ttafilter_process(filter, p); + s->dsp.ttafilter_process_dec(filter->qm, filter->dx, filter->dl, &filter->error, p, + filter->shift, filter->round); // fixed order prediction #define PRED(x, k) (int32_t)((((uint64_t)x << k) - x) >> k) @@ -451,7 +424,6 @@ AVCodec ff_tta_decoder = { .init = tta_decode_init, .close = tta_decode_close, .decode = tta_decode_frame, - .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy), - .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS, + .capabilities = CODEC_CAP_DR1, .priv_class = &tta_decoder_class, }; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ttadsp.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ttadsp.c new file mode 100644 index 000000000..30b7ab9eb --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ttadsp.c @@ -0,0 +1,57 @@ +/* + * 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 "ttadsp.h" + +static void ttafilter_process_dec_c(int32_t *qm, int32_t *dx, int32_t *dl, + int32_t *error, int32_t *in, int32_t shift, + int32_t round) { + if (*error < 0) { + qm[0] -= dx[0]; qm[1] -= dx[1]; qm[2] -= dx[2]; qm[3] -= dx[3]; + qm[4] -= dx[4]; qm[5] -= dx[5]; qm[6] -= dx[6]; qm[7] -= dx[7]; + } else if (*error > 0) { + qm[0] += dx[0]; qm[1] += dx[1]; qm[2] += dx[2]; qm[3] += dx[3]; + qm[4] += dx[4]; qm[5] += dx[5]; qm[6] += dx[6]; qm[7] += dx[7]; + } + + round += dl[0] * qm[0] + dl[1] * qm[1] + dl[2] * qm[2] + dl[3] * qm[3] + + dl[4] * qm[4] + dl[5] * qm[5] + dl[6] * qm[6] + dl[7] * qm[7]; + + dx[0] = dx[1]; dx[1] = dx[2]; dx[2] = dx[3]; dx[3] = dx[4]; + dl[0] = dl[1]; dl[1] = dl[2]; dl[2] = dl[3]; dl[3] = dl[4]; + + dx[4] = ((dl[4] >> 30) | 1); + dx[5] = ((dl[5] >> 30) | 2) & ~1; + dx[6] = ((dl[6] >> 30) | 2) & ~1; + dx[7] = ((dl[7] >> 30) | 4) & ~3; + + *error = *in; + *in += (round >> shift); + + dl[4] = -dl[5]; dl[5] = -dl[6]; + dl[6] = *in - dl[7]; dl[7] = *in; + dl[5] += dl[6]; dl[4] += dl[5]; +} + +av_cold void ff_ttadsp_init(TTADSPContext *c) +{ + c->ttafilter_process_dec = ttafilter_process_dec_c; + + if (ARCH_X86) + ff_ttadsp_init_x86(c); +} diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ttadsp.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ttadsp.h new file mode 100644 index 000000000..56930f1c8 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/ttadsp.h @@ -0,0 +1,34 @@ +/* + * 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_TTADSP_H +#define AVCODEC_TTADSP_H + +#include +#include "ttadata.h" + +typedef struct TTADSPContext { + void (*ttafilter_process_dec)(int32_t *qm, int32_t *dx, int32_t *dl, + int32_t *error, int32_t *in, int32_t shift, + int32_t round); +} TTADSPContext; + +void ff_ttadsp_init(TTADSPContext *c); +void ff_ttadsp_init_x86(TTADSPContext *c); + +#endif /* AVCODEC_TTADSP_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/twinvq.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/twinvq.c index 8af5cf5b8..f38dc91f0 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/twinvq.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/twinvq.c @@ -216,7 +216,7 @@ static void dec_gain(TwinVQContext *tctx, enum TwinVQFrameType ftype, float *out) { const TwinVQModeTab *mtab = tctx->mtab; - const TwinVQFrameData *bits = &tctx->bits; + const TwinVQFrameData *bits = &tctx->bits[tctx->cur_frame]; int i, j; int sub = mtab->fmode[ftype].sub; float step = TWINVQ_AMP_MAX / ((1 << TWINVQ_GAIN_BITS) - 1); @@ -377,11 +377,12 @@ static void imdct_and_window(TwinVQContext *tctx, enum TwinVQFrameType ftype, } static void imdct_output(TwinVQContext *tctx, enum TwinVQFrameType ftype, - int wtype, float **out) + int wtype, float **out, int offset) { const TwinVQModeTab *mtab = tctx->mtab; float *prev_buf = tctx->prev_frame + tctx->last_block_pos[0]; int size1, size2, i; + float *out1, *out2; for (i = 0; i < tctx->avctx->channels; i++) imdct_and_window(tctx, ftype, wtype, @@ -395,15 +396,17 @@ static void imdct_output(TwinVQContext *tctx, enum TwinVQFrameType ftype, size2 = tctx->last_block_pos[0]; size1 = mtab->size - size2; - memcpy(&out[0][0], prev_buf, size1 * sizeof(out[0][0])); - memcpy(&out[0][size1], tctx->curr_frame, size2 * sizeof(out[0][0])); + out1 = &out[0][0] + offset; + memcpy(out1, prev_buf, size1 * sizeof(*out1)); + memcpy(out1 + size1, tctx->curr_frame, size2 * sizeof(*out1)); if (tctx->avctx->channels == 2) { - memcpy(&out[1][0], &prev_buf[2 * mtab->size], - size1 * sizeof(out[1][0])); - memcpy(&out[1][size1], &tctx->curr_frame[2 * mtab->size], - size2 * sizeof(out[1][0])); - tctx->fdsp.butterflies_float(out[0], out[1], mtab->size); + out2 = &out[1][0] + offset; + memcpy(out2, &prev_buf[2 * mtab->size], + size1 * sizeof(*out2)); + memcpy(out2 + size1, &tctx->curr_frame[2 * mtab->size], + size2 * sizeof(*out2)); + tctx->fdsp.butterflies_float(out1, out2, mtab->size); } } @@ -411,7 +414,7 @@ static void read_and_decode_spectrum(TwinVQContext *tctx, float *out, enum TwinVQFrameType ftype) { const TwinVQModeTab *mtab = tctx->mtab; - TwinVQFrameData *bits = &tctx->bits; + TwinVQFrameData *bits = &tctx->bits[tctx->cur_frame]; int channels = tctx->avctx->channels; int sub = mtab->fmode[ftype].sub; int block_size = mtab->size / sub; @@ -484,7 +487,7 @@ int ff_twinvq_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ if (tctx->discarded_packets >= 2) { - frame->nb_samples = mtab->size; + frame->nb_samples = mtab->size * tctx->frames_per_packet; if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; out = (float **)frame->extended_data; @@ -499,11 +502,17 @@ int ff_twinvq_decode_frame(AVCodecContext *avctx, void *data, if ((ret = tctx->read_bitstream(avctx, tctx, buf, buf_size)) < 0) return ret; - read_and_decode_spectrum(tctx, tctx->spectrum, tctx->bits.ftype); + for (tctx->cur_frame = 0; tctx->cur_frame < tctx->frames_per_packet; + tctx->cur_frame++) { + read_and_decode_spectrum(tctx, tctx->spectrum, + tctx->bits[tctx->cur_frame].ftype); - imdct_output(tctx, tctx->bits.ftype, tctx->bits.window_type, out); + imdct_output(tctx, tctx->bits[tctx->cur_frame].ftype, + tctx->bits[tctx->cur_frame].window_type, out, + tctx->cur_frame * mtab->size); - FFSWAP(float *, tctx->curr_frame, tctx->prev_frame); + FFSWAP(float *, tctx->curr_frame, tctx->prev_frame); + } if (tctx->discarded_packets < 2) { tctx->discarded_packets++; @@ -513,6 +522,9 @@ int ff_twinvq_decode_frame(AVCodecContext *avctx, void *data, *got_frame_ptr = 1; + // VQF can deliver packets 1 byte greater than block align + if (buf_size == avctx->block_align + 1) + return buf_size; return avctx->block_align; } @@ -693,7 +705,7 @@ static av_cold void init_bitstream_params(TwinVQContext *tctx) TWINVQ_WINDOW_TYPE_BITS + mtab->fmode[i].sub * (bse_bits[i] + n_ch * TWINVQ_SUB_GAIN_BITS); - if (tctx->codec == TWINVQ_CODEC_METASOUND) { + if (tctx->codec == TWINVQ_CODEC_METASOUND && !tctx->is_6kbps) { bsize_no_main_cb[1] += 2; bsize_no_main_cb[2] += 2; } @@ -763,6 +775,20 @@ av_cold int ff_twinvq_decode_init(AVCodecContext *avctx) tctx->avctx = avctx; avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; + if (!avctx->block_align) { + avctx->block_align = tctx->frame_size + 7 >> 3; + } else if (avctx->block_align * 8 < tctx->frame_size) { + av_log(avctx, AV_LOG_ERROR, "Block align is %d bits, expected %d\n", + avctx->block_align * 8, tctx->frame_size); + return AVERROR_INVALIDDATA; + } + tctx->frames_per_packet = avctx->block_align * 8 / tctx->frame_size; + if (tctx->frames_per_packet > TWINVQ_MAX_FRAMES_PER_PACKET) { + av_log(avctx, AV_LOG_ERROR, "Too many frames per packet (%d)\n", + tctx->frames_per_packet); + return AVERROR_INVALIDDATA; + } + avpriv_float_dsp_init(&tctx->fdsp, avctx->flags & CODEC_FLAG_BITEXACT); if ((ret = init_mdct_win(tctx))) { av_log(avctx, AV_LOG_ERROR, "Error initializing MDCT\n"); diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/twinvq.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/twinvq.h index 44215db59..c4e9688d4 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/twinvq.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/twinvq.h @@ -58,6 +58,8 @@ enum TwinVQFrameType { #define TWINVQ_SUBBLOCKS_MAX 16 #define TWINVQ_BARK_N_COEF_MAX 4 +#define TWINVQ_MAX_FRAMES_PER_PACKET 2 + /** * Parameters and tables that are different for each frame type */ @@ -139,6 +141,8 @@ typedef struct TwinVQContext { const TwinVQModeTab *mtab; + int is_6kbps; + // history float lsp_hist[2][20]; ///< LSP coefficients of the last frame float bark_hist[3][2][40]; ///< BSE coefficients of last frame @@ -162,7 +166,8 @@ typedef struct TwinVQContext { // scratch buffers float *tmp_buf; - TwinVQFrameData bits; + int frame_size, frames_per_packet, cur_frame; + TwinVQFrameData bits[TWINVQ_MAX_FRAMES_PER_PACKET]; enum TwinVQCodec codec; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/twinvqdec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/twinvqdec.c index 067df56d7..67ce03139 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/twinvqdec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/twinvqdec.c @@ -251,7 +251,7 @@ static void read_cb_data(TwinVQContext *tctx, GetBitContext *gb, static int twinvq_read_bitstream(AVCodecContext *avctx, TwinVQContext *tctx, const uint8_t *buf, int buf_size) { - TwinVQFrameData *bits = &tctx->bits; + TwinVQFrameData *bits = &tctx->bits[0]; const TwinVQModeTab *mtab = tctx->mtab; int channels = tctx->avctx->channels; int sub; @@ -268,7 +268,7 @@ static int twinvq_read_bitstream(AVCodecContext *avctx, TwinVQContext *tctx, return AVERROR_INVALIDDATA; } - bits->ftype = ff_twinvq_wtype_to_ftype_table[tctx->bits.window_type]; + bits->ftype = ff_twinvq_wtype_to_ftype_table[tctx->bits[0].window_type]; sub = mtab->fmode[bits->ftype].sub; @@ -312,7 +312,7 @@ static int twinvq_read_bitstream(AVCodecContext *avctx, TwinVQContext *tctx, } } - return 0; + return (get_bits_count(&gb) + 7) / 8; } static av_cold int twinvq_decode_init(AVCodecContext *avctx) @@ -396,13 +396,18 @@ static av_cold int twinvq_decode_init(AVCodecContext *avctx) return -1; } - avctx->block_align = (avctx->bit_rate * tctx->mtab->size - / avctx->sample_rate + 15) / 8; - tctx->codec = TWINVQ_CODEC_VQF; tctx->read_bitstream = twinvq_read_bitstream; tctx->dec_bark_env = dec_bark_env; tctx->decode_ppc = decode_ppc; + tctx->frame_size = avctx->bit_rate * tctx->mtab->size + / avctx->sample_rate + 8; + tctx->is_6kbps = 0; + if (avctx->block_align && avctx->block_align * 8 / tctx->frame_size > 1) { + av_log(avctx, AV_LOG_ERROR, + "VQF TwinVQ should have only one frame per packet\n"); + return AVERROR_INVALIDDATA; + } return ff_twinvq_decode_init(avctx); } diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/utils.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/utils.c index 08dd556f9..63abe234a 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/utils.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/utils.c @@ -26,7 +26,6 @@ */ #include "config.h" -#include "libavutil/avutil.h" #include "libavutil/atomic.h" #include "libavutil/attributes.h" #include "libavutil/avassert.h" @@ -57,30 +56,84 @@ # include #endif -volatile int ff_avcodec_locked = 0; -static int volatile entangled_thread_counter = 0; -static int (*lockmgr_cb)(void **mutex, enum AVLockOp op) = NULL; -static void *codec_mutex = NULL; -static void *avformat_mutex = NULL; +#if HAVE_PTHREADS +#include +#elif HAVE_W32THREADS +#include "compat/w32pthreads.h" +#elif HAVE_OS2THREADS +#include "compat/os2threads.h" +#endif -void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size) +#if HAVE_PTHREADS || HAVE_W32THREADS || HAVE_OS2THREADS +static int default_lockmgr_cb(void **arg, enum AVLockOp op) { - if (min_size < *size) - return ptr; + void * volatile * mutex = arg; + int err; - min_size = FFMAX(17 * min_size / 16 + 32, min_size); + switch (op) { + case AV_LOCK_CREATE: + return 0; + case AV_LOCK_OBTAIN: + if (!*mutex) { + pthread_mutex_t *tmp = av_malloc(sizeof(pthread_mutex_t)); + if (!tmp) + return AVERROR(ENOMEM); + if ((err = pthread_mutex_init(tmp, NULL))) { + av_free(tmp); + return AVERROR(err); + } + if (avpriv_atomic_ptr_cas(mutex, NULL, tmp)) { + pthread_mutex_destroy(tmp); + av_free(tmp); + } + } - ptr = av_realloc(ptr, min_size); - /* we could set this to the unmodified min_size but this is safer - * if the user lost the ptr and uses NULL now - */ - if (!ptr) - min_size = 0; + if ((err = pthread_mutex_lock(*mutex))) + return AVERROR(err); - *size = min_size; + return 0; + case AV_LOCK_RELEASE: + if ((err = pthread_mutex_unlock(*mutex))) + return AVERROR(err); - return ptr; + return 0; + case AV_LOCK_DESTROY: + if (*mutex) + pthread_mutex_destroy(*mutex); + av_free(*mutex); + avpriv_atomic_ptr_cas(mutex, *mutex, NULL); + return 0; + } + return 1; } +static int (*lockmgr_cb)(void **mutex, enum AVLockOp op) = default_lockmgr_cb; +#else +static int (*lockmgr_cb)(void **mutex, enum AVLockOp op) = NULL; +#endif + + +volatile int ff_avcodec_locked; +static int volatile entangled_thread_counter = 0; +static void *codec_mutex; +static void *avformat_mutex; + +#if CONFIG_RAISE_MAJOR +# define LIBNAME "LIBAVCODEC_155" +#else +# define LIBNAME "LIBAVCODEC_55" +#endif + +#if FF_API_FAST_MALLOC && CONFIG_SHARED && HAVE_SYMVER +FF_SYMVER(void*, av_fast_realloc, (void *ptr, unsigned int *size, size_t min_size), LIBNAME) +{ + return av_fast_realloc(ptr, size, min_size); +} + +FF_SYMVER(void, av_fast_malloc, (void *ptr, unsigned int *size, size_t min_size), LIBNAME) +{ + av_fast_malloc(ptr, size, min_size); +} +#endif static inline int ff_fast_malloc(void *ptr, unsigned int *size, size_t min_size, int zero_realloc) { @@ -96,11 +149,6 @@ static inline int ff_fast_malloc(void *ptr, unsigned int *size, size_t min_size, return 1; } -void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size) -{ - ff_fast_malloc(ptr, size, min_size, 0); -} - void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size) { uint8_t **p = ptr; @@ -127,6 +175,7 @@ void av_fast_padded_mallocz(void *ptr, unsigned int *size, size_t min_size) /* encoder management */ static AVCodec *first_avcodec = NULL; +static AVCodec **last_avcodec = &first_avcodec; const AVCodec *av_codec_next(const AVCodec *c) { @@ -162,26 +211,67 @@ av_cold void avcodec_register(AVCodec *codec) { AVCodec **p; avcodec_init(); - p = &first_avcodec; + p = last_avcodec; codec->next = NULL; - while(avpriv_atomic_ptr_cas((void * volatile *)p, NULL, codec)) + + while(*p || avpriv_atomic_ptr_cas((void * volatile *)p, NULL, codec)) p = &(*p)->next; + last_avcodec = &codec->next; if (codec->init_static_data) codec->init_static_data(codec); } +#if FF_API_EMU_EDGE unsigned avcodec_get_edge_width(void) { return EDGE_WIDTH; } +#endif +#if FF_API_SET_DIMENSIONS void avcodec_set_dimensions(AVCodecContext *s, int width, int height) { + int ret = ff_set_dimensions(s, width, height); + if (ret < 0) { + av_log(s, AV_LOG_WARNING, "Failed to set dimensions %d %d\n", width, height); + } +} +#endif + +int ff_set_dimensions(AVCodecContext *s, int width, int height) +{ + int ret = av_image_check_size(width, height, 0, s); + + if (ret < 0) + width = height = 0; + s->coded_width = width; s->coded_height = height; s->width = FF_CEIL_RSHIFT(width, s->lowres); s->height = FF_CEIL_RSHIFT(height, s->lowres); + + return ret; +} + +int ff_side_data_update_matrix_encoding(AVFrame *frame, + enum AVMatrixEncoding matrix_encoding) +{ + AVFrameSideData *side_data; + enum AVMatrixEncoding *data; + + side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_MATRIXENCODING); + if (!side_data) + side_data = av_frame_new_side_data(frame, AV_FRAME_DATA_MATRIXENCODING, + sizeof(enum AVMatrixEncoding)); + + if (!side_data) + return AVERROR(ENOMEM); + + data = (enum AVMatrixEncoding*)side_data->data; + *data = matrix_encoding; + + return 0; } #if HAVE_NEON || ARCH_PPC || HAVE_MMX @@ -226,6 +316,12 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, case AV_PIX_FMT_YUV420P14BE: case AV_PIX_FMT_YUV420P16LE: case AV_PIX_FMT_YUV420P16BE: + case AV_PIX_FMT_YUVA420P9LE: + case AV_PIX_FMT_YUVA420P9BE: + case AV_PIX_FMT_YUVA420P10LE: + case AV_PIX_FMT_YUVA420P10BE: + case AV_PIX_FMT_YUVA420P16LE: + case AV_PIX_FMT_YUVA420P16BE: case AV_PIX_FMT_YUV422P9LE: case AV_PIX_FMT_YUV422P9BE: case AV_PIX_FMT_YUV422P10LE: @@ -236,6 +332,12 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, case AV_PIX_FMT_YUV422P14BE: case AV_PIX_FMT_YUV422P16LE: case AV_PIX_FMT_YUV422P16BE: + case AV_PIX_FMT_YUVA422P9LE: + case AV_PIX_FMT_YUVA422P9BE: + case AV_PIX_FMT_YUVA422P10LE: + case AV_PIX_FMT_YUVA422P10BE: + case AV_PIX_FMT_YUVA422P16LE: + case AV_PIX_FMT_YUVA422P16BE: case AV_PIX_FMT_YUV444P9LE: case AV_PIX_FMT_YUV444P9BE: case AV_PIX_FMT_YUV444P10LE: @@ -246,18 +348,6 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, case AV_PIX_FMT_YUV444P14BE: case AV_PIX_FMT_YUV444P16LE: case AV_PIX_FMT_YUV444P16BE: - case AV_PIX_FMT_YUVA420P9LE: - case AV_PIX_FMT_YUVA420P9BE: - case AV_PIX_FMT_YUVA420P10LE: - case AV_PIX_FMT_YUVA420P10BE: - case AV_PIX_FMT_YUVA420P16LE: - case AV_PIX_FMT_YUVA420P16BE: - case AV_PIX_FMT_YUVA422P9LE: - case AV_PIX_FMT_YUVA422P9BE: - case AV_PIX_FMT_YUVA422P10LE: - case AV_PIX_FMT_YUVA422P10BE: - case AV_PIX_FMT_YUVA422P16LE: - case AV_PIX_FMT_YUVA422P16BE: case AV_PIX_FMT_YUVA444P9LE: case AV_PIX_FMT_YUVA444P9BE: case AV_PIX_FMT_YUVA444P10LE: @@ -661,11 +751,11 @@ FF_ENABLE_DEPRECATION_WARNINGS int ff_init_buffer_info(AVCodecContext *avctx, AVFrame *frame) { - if (avctx->pkt) { - frame->pkt_pts = avctx->pkt->pts; - av_frame_set_pkt_pos (frame, avctx->pkt->pos); - av_frame_set_pkt_duration(frame, avctx->pkt->duration); - av_frame_set_pkt_size (frame, avctx->pkt->size); + if (avctx->internal->pkt) { + frame->pkt_pts = avctx->internal->pkt->pts; + av_frame_set_pkt_pos (frame, avctx->internal->pkt->pos); + av_frame_set_pkt_duration(frame, avctx->internal->pkt->duration); + av_frame_set_pkt_size (frame, avctx->internal->pkt->size); } else { frame->pkt_pts = AV_NOPTS_VALUE; av_frame_set_pkt_pos (frame, -1); @@ -676,10 +766,7 @@ int ff_init_buffer_info(AVCodecContext *avctx, AVFrame *frame) switch (avctx->codec->type) { case AVMEDIA_TYPE_VIDEO: - frame->width = FFMAX(avctx->width, FF_CEIL_RSHIFT(avctx->coded_width, avctx->lowres)); - frame->height = FFMAX(avctx->height, FF_CEIL_RSHIFT(avctx->coded_height, avctx->lowres)); - if (frame->format < 0) - frame->format = avctx->pix_fmt; + frame->format = avctx->pix_fmt; if (!frame->sample_aspect_ratio.num) frame->sample_aspect_ratio = avctx->sample_aspect_ratio; if (av_frame_get_colorspace(frame) == AVCOL_SPC_UNSPECIFIED) @@ -712,7 +799,7 @@ int ff_init_buffer_info(AVCodecContext *avctx, AVFrame *frame) } av_frame_set_channels(frame, avctx->channels); break; - default:break; + default: break; } return 0; } @@ -747,6 +834,7 @@ FF_ENABLE_DEPRECATION_WARNINGS static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags) { + int override_dimensions = 1; int ret; if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { @@ -755,6 +843,13 @@ static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags) return AVERROR(EINVAL); } } + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { + if (frame->width <= 0 || frame->height <= 0) { + frame->width = FFMAX(avctx->width, FF_CEIL_RSHIFT(avctx->coded_width, avctx->lowres)); + frame->height = FFMAX(avctx->height, FF_CEIL_RSHIFT(avctx->coded_height, avctx->lowres)); + override_dimensions = 0; + } + } if ((ret = ff_init_buffer_info(avctx, frame)) < 0) return ret; @@ -877,7 +972,7 @@ FF_ENABLE_DEPRECATION_WARNINGS ret = avctx->get_buffer2(avctx, frame, flags); - if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && !override_dimensions) { frame->width = avctx->width; frame->height = avctx->height; } @@ -895,7 +990,7 @@ int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) static int reget_buffer_internal(AVCodecContext *avctx, AVFrame *frame) { - AVFrame tmp; + AVFrame *tmp; int ret; av_assert0(avctx->codec_type == AVMEDIA_TYPE_VIDEO); @@ -911,21 +1006,26 @@ static int reget_buffer_internal(AVCodecContext *avctx, AVFrame *frame) if (!frame->data[0]) return ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF); - if (av_frame_is_writable(frame)) + if (av_frame_is_writable(frame)) { + frame->pkt_pts = avctx->internal->pkt ? avctx->internal->pkt->pts : AV_NOPTS_VALUE; + frame->reordered_opaque = avctx->reordered_opaque; return 0; + } - av_frame_move_ref(&tmp, frame); + tmp = av_frame_alloc(); + if (!tmp) + return AVERROR(ENOMEM); + + av_frame_move_ref(tmp, frame); ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF); if (ret < 0) { - av_frame_unref(&tmp); + av_frame_free(&tmp); return ret; } - av_image_copy(frame->data, frame->linesize, (const uint8_t **)tmp.data, tmp.linesize, - frame->format, frame->width, frame->height); - - av_frame_unref(&tmp); + av_frame_copy(frame, tmp); + av_frame_free(&tmp); return 0; } @@ -990,6 +1090,7 @@ enum AVPixelFormat avcodec_default_get_format(struct AVCodecContext *s, const en return fmt[0]; } +#if FF_API_AVFRAME_LAVC void avcodec_get_frame_defaults(AVFrame *frame) { #if LIBAVCODEC_VERSION_MAJOR >= 55 @@ -1000,52 +1101,30 @@ void avcodec_get_frame_defaults(AVFrame *frame) #endif memset(frame, 0, sizeof(AVFrame)); - - frame->pts = - frame->pkt_dts = - frame->pkt_pts = AV_NOPTS_VALUE; - av_frame_set_best_effort_timestamp(frame, AV_NOPTS_VALUE); - av_frame_set_pkt_duration (frame, 0); - av_frame_set_pkt_pos (frame, -1); - av_frame_set_pkt_size (frame, -1); - frame->key_frame = 1; - frame->sample_aspect_ratio = (AVRational) {0, 1 }; - frame->format = -1; /* unknown */ - frame->extended_data = frame->data; - av_frame_set_colorspace(frame, AVCOL_SPC_UNSPECIFIED); + av_frame_unref(frame); } AVFrame *avcodec_alloc_frame(void) { - AVFrame *frame = av_malloc(sizeof(AVFrame)); - - if (frame == NULL) - return NULL; - - frame->extended_data = NULL; - avcodec_get_frame_defaults(frame); - - return frame; + return av_frame_alloc(); } void avcodec_free_frame(AVFrame **frame) { - AVFrame *f; - - if (!frame || !*frame) - return; - - f = *frame; - - if (f->extended_data != f->data) - av_freep(&f->extended_data); - - av_freep(frame); + av_frame_free(frame); } +#endif MAKE_ACCESSORS(AVCodecContext, codec, AVRational, pkt_timebase) MAKE_ACCESSORS(AVCodecContext, codec, const AVCodecDescriptor *, codec_descriptor) MAKE_ACCESSORS(AVCodecContext, codec, int, lowres) +MAKE_ACCESSORS(AVCodecContext, codec, int, seek_preroll) +MAKE_ACCESSORS(AVCodecContext, codec, uint16_t*, chroma_intra_matrix) + +int av_codec_get_max_lowres(const AVCodec *codec) +{ + return codec->max_lowres; +} static void avcodec_get_subtitle_defaults(AVSubtitle *sub) { @@ -1076,13 +1155,6 @@ static int get_bit_rate(AVCodecContext *ctx) return bit_rate; } -#if FF_API_AVCODEC_OPEN -int attribute_align_arg avcodec_open(AVCodecContext *avctx, AVCodec *codec) -{ - return avcodec_open2(avctx, codec, NULL); -} -#endif - int attribute_align_arg ff_codec_open2_recursive(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options) { int ret = 0; @@ -1137,6 +1209,12 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code goto free_and_end; } + avctx->internal->to_free = av_frame_alloc(); + if (!avctx->internal->to_free) { + ret = AVERROR(ENOMEM); + goto free_and_end; + } + if (codec->priv_data_size > 0) { if (!avctx->priv_data) { avctx->priv_data = av_mallocz(codec->priv_data_size); @@ -1157,20 +1235,22 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code if ((ret = av_opt_set_dict(avctx, &tmp)) < 0) goto free_and_end; - // only call avcodec_set_dimensions() for non H.264/VP6F codecs so as not to overwrite previously setup dimensions + // only call ff_set_dimensions() for non H.264/VP6F codecs so as not to overwrite previously setup dimensions if (!(avctx->coded_width && avctx->coded_height && avctx->width && avctx->height && (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_VP6F))) { if (avctx->coded_width && avctx->coded_height) - avcodec_set_dimensions(avctx, avctx->coded_width, avctx->coded_height); + ret = ff_set_dimensions(avctx, avctx->coded_width, avctx->coded_height); else if (avctx->width && avctx->height) - avcodec_set_dimensions(avctx, avctx->width, avctx->height); + ret = ff_set_dimensions(avctx, avctx->width, avctx->height); + if (ret < 0) + goto free_and_end; } if ((avctx->coded_width || avctx->coded_height || avctx->width || avctx->height) && ( av_image_check_size(avctx->coded_width, avctx->coded_height, 0, avctx) < 0 || av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0)) { av_log(avctx, AV_LOG_WARNING, "Ignoring invalid width/height values\n"); - avcodec_set_dimensions(avctx, 0, 0); + ff_set_dimensions(avctx, 0, 0); } /* if the decoder init function was already called previously, @@ -1377,8 +1457,8 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code avctx->channel_layout = 0; } } - if (avctx->channels < 0 || - avctx->channels > FF_SANE_NB_CHANNELS) { + if (avctx->channels && (avctx->channels < 0 || + avctx->channels > FF_SANE_NB_CHANNELS)) { ret = AVERROR(EINVAL); goto free_and_end; } @@ -1431,8 +1511,10 @@ end: free_and_end: av_dict_free(&tmp); av_freep(&avctx->priv_data); - if (avctx->internal) + if (avctx->internal) { + av_frame_free(&avctx->internal->to_free); av_freep(&avctx->internal->pool); + } av_freep(&avctx->internal); avctx->codec = NULL; goto end; @@ -1456,7 +1538,9 @@ int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int64_t size) av_fast_padded_malloc(&avctx->internal->byte_buffer, &avctx->internal->byte_buffer_size, size); avpkt->data = avctx->internal->byte_buffer; avpkt->size = avctx->internal->byte_buffer_size; - AV_NOWARN_DEPRECATED( avpkt->destruct = NULL; ); +FF_DISABLE_DEPRECATION_WARNINGS + avpkt->destruct = NULL; +FF_ENABLE_DEPRECATION_WARNINGS } } @@ -1503,7 +1587,7 @@ static int pad_last_frame(AVCodecContext *s, AVFrame **dst, const AVFrame *src) AVFrame *frame = NULL; int ret; - if (!(frame = avcodec_alloc_frame())) + if (!(frame = av_frame_alloc())) return AVERROR(ENOMEM); frame->format = src->format; @@ -1623,7 +1707,9 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, } avpkt->buf = user_pkt.buf; avpkt->data = user_pkt.data; - AV_NOWARN_DEPRECATED( avpkt->destruct = user_pkt.destruct; ); +FF_DISABLE_DEPRECATION_WARNINGS + avpkt->destruct = user_pkt.destruct; +FF_ENABLE_DEPRECATION_WARNINGS } else { if (av_dup_packet(avpkt) < 0) { ret = AVERROR(ENOMEM); @@ -1664,7 +1750,6 @@ int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx, const short *samples) { AVPacket pkt; - AVFrame frame0 = { { 0 } }; AVFrame *frame; int ret, samples_size, got_packet; @@ -1673,8 +1758,9 @@ int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx, pkt.size = buf_size; if (samples) { - frame = &frame0; - avcodec_get_frame_defaults(frame); + frame = av_frame_alloc(); + if (!frame) + return AVERROR(ENOMEM); if (avctx->frame_size) { frame->nb_samples = avctx->frame_size; @@ -1685,13 +1771,16 @@ int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx, if (!av_get_bits_per_sample(avctx->codec_id)) { av_log(avctx, AV_LOG_ERROR, "avcodec_encode_audio() does not " "support this codec\n"); + av_frame_free(&frame); return AVERROR(EINVAL); } nb_samples = (int64_t)buf_size * 8 / (av_get_bits_per_sample(avctx->codec_id) * avctx->channels); - if (nb_samples >= INT_MAX) + if (nb_samples >= INT_MAX) { + av_frame_free(&frame); return AVERROR(EINVAL); + } frame->nb_samples = nb_samples; } @@ -1703,8 +1792,10 @@ int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx, if ((ret = avcodec_fill_audio_frame(frame, avctx->channels, avctx->sample_fmt, (const uint8_t *)samples, - samples_size, 1)) < 0) + samples_size, 1)) < 0) { + av_frame_free(&frame); return ret; + } /* fabricate frame pts from sample count. * this is needed because the avcodec_encode_audio() API does not have @@ -1731,6 +1822,7 @@ int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx, if (frame && frame->extended_data != frame->data) av_freep(&frame->extended_data); + av_frame_free(&frame); return ret ? ret : pkt.size; } @@ -1817,7 +1909,9 @@ int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, } avpkt->buf = user_pkt.buf; avpkt->data = user_pkt.data; - AV_NOWARN_DEPRECATED( avpkt->destruct = user_pkt.destruct; ); +FF_DISABLE_DEPRECATION_WARNINGS + avpkt->destruct = user_pkt.destruct; +FF_ENABLE_DEPRECATION_WARNINGS } else { if (av_dup_packet(avpkt) < 0) { ret = AVERROR(ENOMEM); @@ -1881,11 +1975,15 @@ static int64_t guess_correct_pts(AVCodecContext *ctx, if (dts != AV_NOPTS_VALUE) { ctx->pts_correction_num_faulty_dts += dts <= ctx->pts_correction_last_dts; ctx->pts_correction_last_dts = dts; - } + } else if (reordered_pts != AV_NOPTS_VALUE) + ctx->pts_correction_last_dts = reordered_pts; + if (reordered_pts != AV_NOPTS_VALUE) { ctx->pts_correction_num_faulty_pts += reordered_pts <= ctx->pts_correction_last_pts; ctx->pts_correction_last_pts = reordered_pts; - } + } else if(dts != AV_NOPTS_VALUE) + ctx->pts_correction_last_pts = dts; + if ((ctx->pts_correction_num_faulty_pts<=ctx->pts_correction_num_faulty_dts || dts == AV_NOPTS_VALUE) && reordered_pts != AV_NOPTS_VALUE) pts = reordered_pts; @@ -1895,69 +1993,119 @@ static int64_t guess_correct_pts(AVCodecContext *ctx, return pts; } -static void apply_param_change(AVCodecContext *avctx, AVPacket *avpkt) +static int apply_param_change(AVCodecContext *avctx, AVPacket *avpkt) { - int size = 0; + int size = 0, ret; const uint8_t *data; uint32_t flags; - if (!(avctx->codec->capabilities & CODEC_CAP_PARAM_CHANGE)) - return; - data = av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, &size); - if (!data || size < 4) - return; + if (!data) + return 0; + + if (!(avctx->codec->capabilities & CODEC_CAP_PARAM_CHANGE)) { + av_log(avctx, AV_LOG_ERROR, "This decoder does not support parameter " + "changes, but PARAM_CHANGE side data was sent to it.\n"); + return AVERROR(EINVAL); + } + + if (size < 4) + goto fail; + flags = bytestream_get_le32(&data); size -= 4; - if (size < 4) /* Required for any of the changes */ - return; + if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT) { + if (size < 4) + goto fail; avctx->channels = bytestream_get_le32(&data); size -= 4; } if (flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT) { if (size < 8) - return; + goto fail; avctx->channel_layout = bytestream_get_le64(&data); size -= 8; } - if (size < 4) - return; if (flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE) { + if (size < 4) + goto fail; avctx->sample_rate = bytestream_get_le32(&data); size -= 4; } if (flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS) { if (size < 8) - return; + goto fail; avctx->width = bytestream_get_le32(&data); avctx->height = bytestream_get_le32(&data); - avcodec_set_dimensions(avctx, avctx->width, avctx->height); size -= 8; + ret = ff_set_dimensions(avctx, avctx->width, avctx->height); + if (ret < 0) + return ret; } + + return 0; +fail: + av_log(avctx, AV_LOG_ERROR, "PARAM_CHANGE side data too small.\n"); + return AVERROR_INVALIDDATA; } static int add_metadata_from_side_data(AVCodecContext *avctx, AVFrame *frame) { - int size, ret = 0; + int size; const uint8_t *side_metadata; - const uint8_t *end; - side_metadata = av_packet_get_side_data(avctx->pkt, + AVDictionary **frame_md = avpriv_frame_get_metadatap(frame); + + side_metadata = av_packet_get_side_data(avctx->internal->pkt, AV_PKT_DATA_STRINGS_METADATA, &size); - if (!side_metadata) - goto end; - end = side_metadata + size; - while (side_metadata < end) { - const uint8_t *key = side_metadata; - const uint8_t *val = side_metadata + strlen((const char *)key) + 1; - int ret = av_dict_set(avpriv_frame_get_metadatap(frame), (const char *)key, (const char *)val, 0); - if (ret < 0) - break; - side_metadata = val + strlen((const char *)val) + 1; - } -end: - return ret; + return av_packet_unpack_dictionary(side_metadata, size, frame_md); +} + +static int unrefcount_frame(AVCodecInternal *avci, AVFrame *frame) +{ + int ret; + + /* move the original frame to our backup */ + av_frame_unref(avci->to_free); + av_frame_move_ref(avci->to_free, frame); + + /* now copy everything except the AVBufferRefs back + * note that we make a COPY of the side data, so calling av_frame_free() on + * the caller's frame will work properly */ + ret = av_frame_copy_props(frame, avci->to_free); + if (ret < 0) + return ret; + + memcpy(frame->data, avci->to_free->data, sizeof(frame->data)); + memcpy(frame->linesize, avci->to_free->linesize, sizeof(frame->linesize)); + if (avci->to_free->extended_data != avci->to_free->data) { + int planes = av_frame_get_channels(avci->to_free); + int size = planes * sizeof(*frame->extended_data); + + if (!size) { + av_frame_unref(frame); + return AVERROR_BUG; + } + + frame->extended_data = av_malloc(size); + if (!frame->extended_data) { + av_frame_unref(frame); + return AVERROR(ENOMEM); + } + memcpy(frame->extended_data, avci->to_free->extended_data, + size); + } else + frame->extended_data = frame->data; + + frame->format = avci->to_free->format; + frame->width = avci->to_free->width; + frame->height = avci->to_free->height; + frame->channel_layout = avci->to_free->channel_layout; + frame->nb_samples = avci->to_free->nb_samples; + av_frame_set_channels(frame, av_frame_get_channels(avci->to_free)); + + return 0; } int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, @@ -1980,15 +2128,18 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi if ((avctx->coded_width || avctx->coded_height) && av_image_check_size(avctx->coded_width, avctx->coded_height, 0, avctx)) return AVERROR(EINVAL); - avcodec_get_frame_defaults(picture); - - if (!avctx->refcounted_frames) - av_frame_unref(&avci->to_free); + av_frame_unref(picture); if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type & FF_THREAD_FRAME)) { int did_split = av_packet_split_side_data(&tmp); - apply_param_change(avctx, &tmp); - avctx->pkt = &tmp; + ret = apply_param_change(avctx, &tmp); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n"); + if (avctx->err_recognition & AV_EF_EXPLODE) + goto fail; + } + + avctx->internal->pkt = &tmp; if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) ret = ff_thread_decode_frame(avctx, picture, got_picture_ptr, &tmp); @@ -2011,23 +2162,21 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi } add_metadata_from_side_data(avctx, picture); +fail: emms_c(); //needed to avoid an emms_c() call before every return; - avctx->pkt = NULL; + avctx->internal->pkt = NULL; if (did_split) { av_packet_free_side_data(&tmp); if(ret == tmp.size) ret = avpkt->size; } - if (ret < 0 && picture->data[0]) - av_frame_unref(picture); - if (*got_picture_ptr) { if (!avctx->refcounted_frames) { - avci->to_free = *picture; - avci->to_free.extended_data = avci->to_free.data; - memset(picture->buf, 0, sizeof(picture->buf)); + int err = unrefcount_frame(avci, picture); + if (err < 0) + return err; } avctx->frame_number++; @@ -2035,13 +2184,14 @@ int attribute_align_arg avcodec_decode_video2(AVCodecContext *avctx, AVFrame *pi guess_correct_pts(avctx, picture->pkt_pts, picture->pkt_dts)); - } + } else + av_frame_unref(picture); } else ret = 0; /* many decoders assign whole AVFrames, thus overwriting extended_data; * make sure it's set correctly */ - picture->extended_data = picture->data; + av_assert0(!picture->extended_data || picture->extended_data == picture->data); return ret; } @@ -2051,9 +2201,11 @@ int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *sa int *frame_size_ptr, AVPacket *avpkt) { - AVFrame frame = { { 0 } }; + AVFrame *frame = av_frame_alloc(); int ret, got_frame = 0; + if (!frame) + return AVERROR(ENOMEM); if (avctx->get_buffer != avcodec_default_get_buffer) { av_log(avctx, AV_LOG_ERROR, "Custom get_buffer() for use with" "avcodec_decode_audio3() detected. Overriding with avcodec_default_get_buffer\n"); @@ -2063,26 +2215,27 @@ int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *sa avctx->release_buffer = avcodec_default_release_buffer; } - ret = avcodec_decode_audio4(avctx, &frame, &got_frame, avpkt); + ret = avcodec_decode_audio4(avctx, frame, &got_frame, avpkt); if (ret >= 0 && got_frame) { int ch, plane_size; int planar = av_sample_fmt_is_planar(avctx->sample_fmt); int data_size = av_samples_get_buffer_size(&plane_size, avctx->channels, - frame.nb_samples, + frame->nb_samples, avctx->sample_fmt, 1); if (*frame_size_ptr < data_size) { av_log(avctx, AV_LOG_ERROR, "output buffer size is too small for " "the current frame (%d < %d)\n", *frame_size_ptr, data_size); + av_frame_free(&frame); return AVERROR(EINVAL); } - memcpy(samples, frame.extended_data[0], plane_size); + memcpy(samples, frame->extended_data[0], plane_size); if (planar && avctx->channels > 1) { uint8_t *out = ((uint8_t *)samples) + plane_size; for (ch = 1; ch < avctx->channels; ch++) { - memcpy(out, frame.extended_data[ch], plane_size); + memcpy(out, frame->extended_data[ch], plane_size); out += plane_size; } } @@ -2090,6 +2243,7 @@ int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *sa } else { *frame_size_ptr = 0; } + av_frame_free(&frame); return ret; } @@ -2101,7 +2255,6 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, const AVPacket *avpkt) { AVCodecInternal *avci = avctx->internal; - int planar, channels; int ret = 0; *got_frame_ptr = 0; @@ -2117,10 +2270,7 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, return AVERROR(EINVAL); } - avcodec_get_frame_defaults(frame); - - if (!avctx->refcounted_frames) - av_frame_unref(&avci->to_free); + av_frame_unref(frame); if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size || (avctx->active_thread_type & FF_THREAD_FRAME)) { uint8_t *side; @@ -2129,9 +2279,14 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, // copy to ensure we do not change avpkt AVPacket tmp = *avpkt; int did_split = av_packet_split_side_data(&tmp); - apply_param_change(avctx, &tmp); + ret = apply_param_change(avctx, &tmp); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Error applying parameter changes.\n"); + if (avctx->err_recognition & AV_EF_EXPLODE) + goto fail; + } - avctx->pkt = &tmp; + avctx->internal->pkt = &tmp; if (HAVE_THREADS && avctx->active_thread_type & FF_THREAD_FRAME) ret = ff_thread_decode_frame(avctx, frame, got_frame_ptr, &tmp); else { @@ -2155,7 +2310,7 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, frame->sample_rate = avctx->sample_rate; } - side= av_packet_get_side_data(avctx->pkt, AV_PKT_DATA_SKIP_SAMPLES, &side_size); + side= av_packet_get_side_data(avctx->internal->pkt, AV_PKT_DATA_SKIP_SAMPLES, &side_size); if(side && side_size>=10) { avctx->internal->skip_samples = AV_RL32(side); av_log(avctx, AV_LOG_DEBUG, "skip %d samples due to side data\n", @@ -2209,8 +2364,8 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, frame->nb_samples -= discard_padding; } } - - avctx->pkt = NULL; +fail: + avctx->internal->pkt = NULL; if (did_split) { av_packet_free_side_data(&tmp); if(ret == tmp.size) @@ -2219,28 +2374,14 @@ int attribute_align_arg avcodec_decode_audio4(AVCodecContext *avctx, if (ret >= 0 && *got_frame_ptr) { if (!avctx->refcounted_frames) { - avci->to_free = *frame; - avci->to_free.extended_data = avci->to_free.data; - memset(frame->buf, 0, sizeof(frame->buf)); - frame->extended_buf = NULL; - frame->nb_extended_buf = 0; + int err = unrefcount_frame(avci, frame); + if (err < 0) + return err; } - } else if (frame->data[0]) + } else av_frame_unref(frame); } - /* many decoders assign whole AVFrames, thus overwriting extended_data; - * make sure it's set correctly; assume decoders that actually use - * extended_data are doing it correctly */ - if (*got_frame_ptr) { - planar = av_sample_fmt_is_planar(frame->format); - channels = av_frame_get_channels(frame); - if (!(planar && channels > AV_NUM_DATA_POINTERS)) - frame->extended_data = frame->data; - } else { - frame->extended_data = NULL; - } - return ret; } @@ -2256,7 +2397,7 @@ static int recode_subtitle(AVCodecContext *avctx, AVPacket tmp; #endif - if (avctx->sub_charenc_mode != FF_SUB_CHARENC_MODE_PRE_DECODER) + if (avctx->sub_charenc_mode != FF_SUB_CHARENC_MODE_PRE_DECODER || inpkt->size == 0) return 0; #if CONFIG_ICONV @@ -2327,6 +2468,12 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, { int i, ret = 0; + if (!avpkt->data && avpkt->size) { + av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n"); + return AVERROR(EINVAL); + } + if (!avctx->codec) + return AVERROR(EINVAL); if (avctx->codec->type != AVMEDIA_TYPE_SUBTITLE) { av_log(avctx, AV_LOG_ERROR, "Invalid media type for subtitles\n"); return AVERROR(EINVAL); @@ -2335,18 +2482,28 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, *got_sub_ptr = 0; avcodec_get_subtitle_defaults(sub); - if (avpkt->size) { + if ((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size) { AVPacket pkt_recoded; AVPacket tmp = *avpkt; int did_split = av_packet_split_side_data(&tmp); //apply_param_change(avctx, &tmp); + if (did_split) { + /* FFMIN() prevents overflow in case the packet wasn't allocated with + * proper padding. + * If the side data is smaller than the buffer padding size, the + * remaining bytes should have already been filled with zeros by the + * original packet allocation anyway. */ + memset(tmp.data + tmp.size, 0, + FFMIN(avpkt->size - tmp.size, FF_INPUT_BUFFER_PADDING_SIZE)); + } + pkt_recoded = tmp; ret = recode_subtitle(avctx, &pkt_recoded, &tmp); if (ret < 0) { *got_sub_ptr = 0; } else { - avctx->pkt = &pkt_recoded; + avctx->internal->pkt = &pkt_recoded; if (avctx->pkt_timebase.den && avpkt->pts != AV_NOPTS_VALUE) sub->pts = av_rescale_q(avpkt->pts, @@ -2383,7 +2540,7 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, sub->format = 0; else if (avctx->codec_descriptor->props & AV_CODEC_PROP_TEXT_SUB) sub->format = 1; - avctx->pkt = NULL; + avctx->internal->pkt = NULL; } if (did_split) { @@ -2450,15 +2607,14 @@ av_cold int avcodec_close(AVCodecContext *avctx) ff_frame_thread_encoder_free(avctx); ff_lock_avcodec(avctx); } - if (HAVE_THREADS && avctx->thread_opaque) + if (HAVE_THREADS && avctx->internal->thread_ctx) ff_thread_free(avctx); if (avctx->codec && avctx->codec->close) avctx->codec->close(avctx); avctx->coded_frame = NULL; avctx->internal->byte_buffer_size = 0; av_freep(&avctx->internal->byte_buffer); - if (!avctx->refcounted_frames) - av_frame_unref(&avctx->internal->to_free); + av_frame_free(&avctx->internal->to_free); for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++) av_buffer_pool_uninit(&pool->pools[i]); av_freep(&avctx->internal->pool); @@ -2491,6 +2647,7 @@ static enum AVCodecID remap_deprecated_codec_id(enum AVCodecID id) case AV_CODEC_ID_ESCAPE130_DEPRECATED : return AV_CODEC_ID_ESCAPE130; case AV_CODEC_ID_G2M_DEPRECATED : return AV_CODEC_ID_G2M; case AV_CODEC_ID_WEBP_DEPRECATED: return AV_CODEC_ID_WEBP; + case AV_CODEC_ID_HEVC_DEPRECATED: return AV_CODEC_ID_HEVC; default : return id; } } @@ -2779,7 +2936,7 @@ void avcodec_flush_buffers(AVCodecContext *avctx) avctx->pts_correction_last_dts = INT64_MIN; if (!avctx->refcounted_frames) - av_frame_unref(&avctx->internal->to_free); + av_frame_unref(avctx->internal->to_free); } int av_get_exact_bits_per_sample(enum AVCodecID codec_id) @@ -3012,7 +3169,7 @@ int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes) return blocks * ((ba - 4 * ch) * 2 / ch); case AV_CODEC_ID_ADPCM_MS: return blocks * (2 + (ba - 7 * ch) * 2 / ch); - default:break; + default: break; } } @@ -3029,7 +3186,7 @@ int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes) return frame_bytes / ((FFALIGN(ch, 2) * bps) / 8); case AV_CODEC_ID_S302M: return 2 * (frame_bytes / ((bps + 4) / 4)) / ch; - default:break; + default: break; } } } @@ -3097,13 +3254,15 @@ FF_ENABLE_DEPRECATION_WARNINGS #endif /* FF_API_MISSING_SAMPLE */ static AVHWAccel *first_hwaccel = NULL; +static AVHWAccel **last_hwaccel = &first_hwaccel; void av_register_hwaccel(AVHWAccel *hwaccel) { - AVHWAccel **p = &first_hwaccel; + AVHWAccel **p = last_hwaccel; hwaccel->next = NULL; - while(avpriv_atomic_ptr_cas((void * volatile *)p, NULL, hwaccel)) + while(*p || avpriv_atomic_ptr_cas((void * volatile *)p, NULL, hwaccel)) p = &(*p)->next; + last_hwaccel = &hwaccel->next; } AVHWAccel *av_hwaccel_next(AVHWAccel *hwaccel) @@ -3111,8 +3270,11 @@ AVHWAccel *av_hwaccel_next(AVHWAccel *hwaccel) return hwaccel ? hwaccel->next : first_hwaccel; } -AVHWAccel *ff_find_hwaccel(enum AVCodecID codec_id, enum AVPixelFormat pix_fmt) +AVHWAccel *ff_find_hwaccel(AVCodecContext *avctx) { + enum AVCodecID codec_id = avctx->codec->id; + enum AVPixelFormat pix_fmt = avctx->pix_fmt; + AVHWAccel *hwaccel = NULL; while ((hwaccel = av_hwaccel_next(hwaccel))) @@ -3254,6 +3416,23 @@ int ff_thread_can_start_frame(AVCodecContext *avctx) return 1; } +int ff_alloc_entries(AVCodecContext *avctx, int count) +{ + return 0; +} + +void ff_reset_entries(AVCodecContext *avctx) +{ +} + +void ff_thread_await_progress2(AVCodecContext *avctx, int field, int thread, int shift) +{ +} + +void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n) +{ +} + #endif enum AVMediaType avcodec_get_type(enum AVCodecID codec_id) @@ -3289,7 +3468,7 @@ int avpriv_bprint_to_extradata(AVCodecContext *avctx, struct AVBPrint *buf) ret = av_bprint_finalize(buf, &str); if (ret < 0) return ret; - avctx->extradata = (uint8_t *) str; + avctx->extradata = (uint8_t *)str; /* Note: the string is NUL terminated (so extradata can be read as a * string), but the ending character is not accounted in the size (in * binary formats you are likely not supposed to mux that character). When diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/version.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/version.h index d5c8bb5c7..0c3afc417 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/version.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/version.h @@ -27,14 +27,14 @@ */ #ifdef __FRAMEWORK__ -#include "avutil.h" +#include "version.h" #else -#include "libavutil/avutil.h" +#include "libavutil/version.h" #endif #define LIBAVCODEC_VERSION_MAJOR 55 -#define LIBAVCODEC_VERSION_MINOR 33 -#define LIBAVCODEC_VERSION_MICRO 101 +#define LIBAVCODEC_VERSION_MINOR 52 +#define LIBAVCODEC_VERSION_MICRO 102 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ @@ -55,19 +55,9 @@ #ifndef FF_API_REQUEST_CHANNELS #define FF_API_REQUEST_CHANNELS (LIBAVCODEC_VERSION_MAJOR < 56) #endif -#ifndef FF_API_ALLOC_CONTEXT -#define FF_API_ALLOC_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 55) -#endif -#ifndef FF_API_AVCODEC_OPEN -#define FF_API_AVCODEC_OPEN (LIBAVCODEC_VERSION_MAJOR < 55) -#endif #ifndef FF_API_OLD_DECODE_AUDIO #define FF_API_OLD_DECODE_AUDIO (LIBAVCODEC_VERSION_MAJOR < 56) #endif -#ifndef FF_API_OLD_TIMECODE -#define FF_API_OLD_TIMECODE (LIBAVCODEC_VERSION_MAJOR < 55) -#endif - #ifndef FF_API_OLD_ENCODE_AUDIO #define FF_API_OLD_ENCODE_AUDIO (LIBAVCODEC_VERSION_MAJOR < 56) #endif @@ -77,8 +67,11 @@ #ifndef FF_API_CODEC_ID #define FF_API_CODEC_ID (LIBAVCODEC_VERSION_MAJOR < 56) #endif +#ifndef FF_API_AUDIO_CONVERT +#define FF_API_AUDIO_CONVERT (LIBAVCODEC_VERSION_MAJOR < 56) +#endif #ifndef FF_API_AVCODEC_RESAMPLE -#define FF_API_AVCODEC_RESAMPLE (LIBAVCODEC_VERSION_MAJOR < 56) +#define FF_API_AVCODEC_RESAMPLE FF_API_AUDIO_CONVERT #endif #ifndef FF_API_DEINTERLACE #define FF_API_DEINTERLACE (LIBAVCODEC_VERSION_MAJOR < 56) @@ -104,5 +97,53 @@ #ifndef FF_API_VOXWARE #define FF_API_VOXWARE (LIBAVCODEC_VERSION_MAJOR < 56) #endif +#ifndef FF_API_SET_DIMENSIONS +#define FF_API_SET_DIMENSIONS (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_DEBUG_MV +#define FF_API_DEBUG_MV (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_AC_VLC +#define FF_API_AC_VLC (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_OLD_MSMPEG4 +#define FF_API_OLD_MSMPEG4 (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_ASPECT_EXTENDED +#define FF_API_ASPECT_EXTENDED (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_THREAD_OPAQUE +#define FF_API_THREAD_OPAQUE (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_CODEC_PKT +#define FF_API_CODEC_PKT (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_ARCH_ALPHA +#define FF_API_ARCH_ALPHA (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_XVMC +#define FF_API_XVMC (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_ERROR_RATE +#define FF_API_ERROR_RATE (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_QSCALE_TYPE +#define FF_API_QSCALE_TYPE (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_MB_TYPE +#define FF_API_MB_TYPE (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_MAX_BFRAMES +#define FF_API_MAX_BFRAMES (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_FAST_MALLOC +#define FF_API_FAST_MALLOC (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_NEG_LINESIZES +#define FF_API_NEG_LINESIZES (LIBAVCODEC_VERSION_MAJOR < 56) +#endif +#ifndef FF_API_EMU_EDGE +#define FF_API_EMU_EDGE (LIBAVCODEC_VERSION_MAJOR < 56) +#endif #endif /* AVCODEC_VERSION_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/videodsp.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/videodsp.h index e85dff355..4721efda9 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/videodsp.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/videodsp.h @@ -30,8 +30,8 @@ #include #define EMULATED_EDGE(depth) \ -void ff_emulated_edge_mc_ ## depth(uint8_t *dst, ptrdiff_t dst_stride, \ - const uint8_t *src, ptrdiff_t src_stride, \ +void ff_emulated_edge_mc_ ## depth(uint8_t *dst, const uint8_t *src, \ + ptrdiff_t dst_stride, ptrdiff_t src_stride, \ int block_w, int block_h,\ int src_x, int src_y, int w, int h); @@ -47,8 +47,10 @@ typedef struct VideoDSPContext { * @param dst_stride number of bytes between 2 vertically adjacent samples * in destination buffer * @param src source buffer - * @param src_stride number of bytes between 2 vertically adjacent samples - * in source buffer + * @param dst_linesize number of bytes between 2 vertically adjacent + * samples in the destination buffer + * @param src_linesize number of bytes between 2 vertically adjacent + * samples in both the source buffer * @param block_w width of block * @param block_h height of block * @param src_x x coordinate of the top left sample of the block in the @@ -58,8 +60,9 @@ typedef struct VideoDSPContext { * @param w width of the source buffer * @param h height of the source buffer */ - void (*emulated_edge_mc)(uint8_t *dst, ptrdiff_t dst_stride, - const uint8_t *src, ptrdiff_t src_stride, + void (*emulated_edge_mc)(uint8_t *dst, const uint8_t *src, + ptrdiff_t dst_linesize, + ptrdiff_t src_linesize, int block_w, int block_h, int src_x, int src_y, int w, int h); diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/videodsp_template.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/videodsp_template.c index f7e7bfdb1..c569c30d6 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/videodsp_template.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/videodsp_template.c @@ -20,8 +20,9 @@ */ #include "bit_depth_template.c" -void FUNC(ff_emulated_edge_mc)(uint8_t *buf, ptrdiff_t buf_stride, - const uint8_t *src, ptrdiff_t src_stride, +void FUNC(ff_emulated_edge_mc)(uint8_t *buf, const uint8_t *src, + ptrdiff_t buf_linesize, + ptrdiff_t src_linesize, int block_w, int block_h, int src_x, int src_y, int w, int h) { @@ -32,12 +33,12 @@ void FUNC(ff_emulated_edge_mc)(uint8_t *buf, ptrdiff_t buf_stride, return; if (src_y >= h) { - src -= src_y * src_stride; - src += (h - 1) * src_stride; + src -= src_y * src_linesize; + src += (h - 1) * src_linesize; src_y = h - 1; } else if (src_y <= -block_h) { - src -= src_y * src_stride; - src += (1 - block_h) * src_stride; + src -= src_y * src_linesize; + src += (1 - block_h) * src_linesize; src_y = 1 - block_h; } if (src_x >= w) { @@ -56,30 +57,30 @@ void FUNC(ff_emulated_edge_mc)(uint8_t *buf, ptrdiff_t buf_stride, av_assert2(start_x < end_x && block_w); w = end_x - start_x; - src += start_y * src_stride + start_x * sizeof(pixel); + src += start_y * src_linesize + start_x * sizeof(pixel); buf += start_x * sizeof(pixel); // top for (y = 0; y < start_y; y++) { memcpy(buf, src, w * sizeof(pixel)); - buf += buf_stride; + buf += buf_linesize; } // copy existing part for (; y < end_y; y++) { memcpy(buf, src, w * sizeof(pixel)); - src += src_stride; - buf += buf_stride; + src += src_linesize; + buf += buf_linesize; } // bottom - src -= src_stride; + src -= src_linesize; for (; y < block_h; y++) { memcpy(buf, src, w * sizeof(pixel)); - buf += buf_stride; + buf += buf_linesize; } - buf -= block_h * buf_stride + start_x * sizeof(pixel); + buf -= block_h * buf_linesize + start_x * sizeof(pixel); while (block_h--) { pixel *bufp = (pixel *) buf; @@ -92,6 +93,6 @@ void FUNC(ff_emulated_edge_mc)(uint8_t *buf, ptrdiff_t buf_stride, for (x = end_x; x < block_w; x++) { bufp[x] = bufp[end_x - 1]; } - buf += buf_stride; + buf += buf_linesize; } } diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/wmadec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/wmadec.c index 8fc0cca80..b1816b4ee 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/wmadec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/wmadec.c @@ -100,6 +100,9 @@ static av_cold int wma_decode_init(AVCodecContext * avctx) } } + for (i=0; imax_exponent[i] = 1.0; + if(ff_wma_init(avctx, flags2)<0) return -1; @@ -948,6 +951,7 @@ static av_cold void flush(AVCodecContext *avctx) #if CONFIG_WMAV1_DECODER AVCodec ff_wmav1_decoder = { .name = "wmav1", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_WMAV1, .priv_data_size = sizeof(WMACodecContext), @@ -956,7 +960,6 @@ AVCodec ff_wmav1_decoder = { .decode = wma_decode_superframe, .flush = flush, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, }; @@ -964,6 +967,7 @@ AVCodec ff_wmav1_decoder = { #if CONFIG_WMAV2_DECODER AVCodec ff_wmav2_decoder = { .name = "wmav2", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_WMAV2, .priv_data_size = sizeof(WMACodecContext), @@ -972,7 +976,6 @@ AVCodec ff_wmav2_decoder = { .decode = wma_decode_superframe, .flush = flush, .capabilities = CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, }; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/wmalosslessdec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/wmalosslessdec.c index a745794ed..f83ba9daa 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/wmalosslessdec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/wmalosslessdec.c @@ -24,7 +24,6 @@ #include "libavutil/attributes.h" #include "libavutil/avassert.h" -#include "libavutil/internal.h" #include "avcodec.h" #include "internal.h" @@ -128,8 +127,8 @@ typedef struct WmallDecodeCtx { int8_t mclms_order; int8_t mclms_scaling; - int16_t mclms_coeffs[128]; - int16_t mclms_coeffs_cur[4]; + int16_t mclms_coeffs[WMALL_MAX_CHANNELS * WMALL_MAX_CHANNELS * 32]; + int16_t mclms_coeffs_cur[WMALL_MAX_CHANNELS * WMALL_MAX_CHANNELS]; int16_t mclms_prevvalues[WMALL_MAX_CHANNELS * 2 * 32]; int16_t mclms_updates[WMALL_MAX_CHANNELS * 2 * 32]; int mclms_recent; @@ -349,11 +348,11 @@ static int decode_tilehdr(WmallDecodeCtx *s) if (num_samples[c] == min_channel_len) { if (fixed_channel_layout || channels_for_cur_subframe == 1 || (min_channel_len == s->samples_per_frame - s->min_samples_per_subframe)) { - contains_subframe[c] = in_use = 1; + contains_subframe[c] = 1; } else { - if (get_bits1(&s->gb)) - contains_subframe[c] = in_use = 1; + contains_subframe[c] = get_bits1(&s->gb); } + in_use |= contains_subframe[c]; } else contains_subframe[c] = 0; } @@ -653,10 +652,10 @@ static void mclms_update(WmallDecodeCtx *s, int icoef, int *pred) if (s->mclms_recent == 0) { memcpy(&s->mclms_prevvalues[order * num_channels], s->mclms_prevvalues, - 2 * order * num_channels); + sizeof(int16_t) * order * num_channels); memcpy(&s->mclms_updates[order * num_channels], s->mclms_updates, - 2 * order * num_channels); + sizeof(int16_t) * order * num_channels); s->mclms_recent = num_channels * order; } } @@ -677,7 +676,7 @@ static void mclms_predict(WmallDecodeCtx *s, int icoef, int *pred) for (i = 0; i < ich; i++) pred[ich] += s->channel_residues[i][icoef] * s->mclms_coeffs_cur[i + num_channels * ich]; - pred[ich] += 1 << (s->mclms_scaling - 1); + pred[ich] += 1 << s->mclms_scaling - 1; pred[ich] >>= s->mclms_scaling; s->channel_residues[ich][icoef] += pred[ich]; } @@ -709,7 +708,7 @@ static void lms_update(WmallDecodeCtx *s, int ich, int ilms, { int icoef; int recent = s->cdlms[ich][ilms].recent; - int range = 1 << (s->bits_per_sample - 1); + int range = 1 << s->bits_per_sample - 1; if (residue < 0) { for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++) @@ -1039,9 +1038,10 @@ static int decode_frame(WmallDecodeCtx *s) len = get_bits(gb, s->log2_frame_size); /* decode tile information */ - if (decode_tilehdr(s)) { + if ((ret = decode_tilehdr(s))) { s->packet_loss = 1; - return 0; + av_frame_unref(s->frame); + return ret; } /* read drc info */ @@ -1076,8 +1076,11 @@ static int decode_frame(WmallDecodeCtx *s) /* decode all subframes */ while (!s->parsed_all_subframes) { + int decoded_samples = s->channel[0].decoded_samples; if (decode_subframe(s) < 0) { s->packet_loss = 1; + if (s->frame->nb_samples) + s->frame->nb_samples = decoded_samples; return 0; } } @@ -1183,6 +1186,8 @@ static int decode_packet(AVCodecContext *avctx, void *data, int *got_frame_ptr, if (s->packet_done || s->packet_loss) { s->packet_done = 0; + if (!buf_size) + return 0; /* sanity check for the buffer length */ if (buf_size < avctx->block_align) { av_log(avctx, AV_LOG_ERROR, "buf size %d invalid\n", buf_size); @@ -1305,6 +1310,7 @@ static av_cold int decode_close(AVCodecContext *avctx) AVCodec ff_wmalossless_decoder = { .name = "wmalossless", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio Lossless"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_WMALOSSLESS, .priv_data_size = sizeof(WmallDecodeCtx), @@ -1313,7 +1319,6 @@ AVCodec ff_wmalossless_decoder = { .decode = decode_packet, .flush = flush, .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1 | CODEC_CAP_DELAY, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio Lossless"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_S32P, AV_SAMPLE_FMT_NONE }, diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/wmaprodec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/wmaprodec.c index 33705084e..d57c24ddd 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/wmaprodec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/wmaprodec.c @@ -89,7 +89,6 @@ #include "libavutil/float_dsp.h" #include "libavutil/intfloat.h" #include "libavutil/intreadwrite.h" -#include "libavutil/internal.h" #include "avcodec.h" #include "internal.h" #include "get_bits.h" @@ -682,7 +681,7 @@ static void decode_decorrelation_matrix(WMAProDecodeCtx *s, /** *@brief Decode channel transformation parameters *@param s codec context - *@return 0 in case of success, < 0 in case of bitstream errors + *@return >= 0 in case of success, < 0 in case of bitstream errors */ static int decode_channel_transform(WMAProDecodeCtx* s) { @@ -1649,6 +1648,7 @@ static void flush(AVCodecContext *avctx) */ AVCodec ff_wmapro_decoder = { .name = "wmapro", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 9 Professional"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_WMAPRO, .priv_data_size = sizeof(WMAProDecodeCtx), @@ -1657,7 +1657,6 @@ AVCodec ff_wmapro_decoder = { .decode = decode_packet, .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1, .flush = flush, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 9 Professional"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, }; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/wmavoice.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/wmavoice.c index ac53215ba..c2737abd4 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/wmavoice.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/wmavoice.c @@ -30,7 +30,6 @@ #include "libavutil/channel_layout.h" #include "libavutil/float_dsp.h" #include "libavutil/mem.h" -#include "libavutil/internal.h" #include "avcodec.h" #include "internal.h" #include "get_bits.h" @@ -2063,6 +2062,7 @@ static av_cold void wmavoice_flush(AVCodecContext *ctx) AVCodec ff_wmavoice_decoder = { .name = "wmavoice", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio Voice"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_WMAVOICE, .priv_data_size = sizeof(WMAVoiceContext), @@ -2072,5 +2072,4 @@ AVCodec ff_wmavoice_decoder = { .decode = wmavoice_decode_packet, .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1, .flush = wmavoice_flush, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio Voice"), }; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/x86/dcadsp_init.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/x86/dcadsp_init.c new file mode 100644 index 000000000..48880d628 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/x86/dcadsp_init.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2012-2014 Christophe Gisquet + * + * 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/attributes.h" +#include "libavutil/cpu.h" +#include "libavutil/x86/cpu.h" +#include "libavcodec/dcadsp.h" + +void ff_decode_hf_sse(float dst[DCA_SUBBANDS][8], const int vq_num[DCA_SUBBANDS], + const int8_t hf_vq[1024][32], intptr_t vq_offset, + int scale[DCA_SUBBANDS][2], intptr_t start, intptr_t end); +void ff_decode_hf_sse2(float dst[DCA_SUBBANDS][8], const int vq_num[DCA_SUBBANDS], + const int8_t hf_vq[1024][32], intptr_t vq_offset, + int scale[DCA_SUBBANDS][2], intptr_t start, intptr_t end); +void ff_decode_hf_sse4(float dst[DCA_SUBBANDS][8], const int vq_num[DCA_SUBBANDS], + const int8_t hf_vq[1024][32], intptr_t vq_offset, + int scale[DCA_SUBBANDS][2], intptr_t start, intptr_t end); +void ff_dca_lfe_fir0_sse(float *out, const float *in, const float *coefs); +void ff_dca_lfe_fir1_sse(float *out, const float *in, const float *coefs); + +av_cold void ff_dcadsp_init_x86(DCADSPContext *s) +{ + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSE(cpu_flags)) { +#if ARCH_X86_32 + s->decode_hf = ff_decode_hf_sse; +#endif + s->lfe_fir[0] = ff_dca_lfe_fir0_sse; + s->lfe_fir[1] = ff_dca_lfe_fir1_sse; + } + + if (EXTERNAL_SSE2(cpu_flags)) { + s->decode_hf = ff_decode_hf_sse2; + } + + if (EXTERNAL_SSE4(cpu_flags)) { + s->decode_hf = ff_decode_hf_sse4; + } +} + + +#define SYNTH_FILTER_FUNC(opt) \ +void ff_synth_filter_inner_##opt(float *synth_buf_ptr, float synth_buf2[32], \ + const float window[512], \ + float out[32], intptr_t offset, float scale); \ +static void synth_filter_##opt(FFTContext *imdct, \ + float *synth_buf_ptr, int *synth_buf_offset, \ + float synth_buf2[32], const float window[512], \ + float out[32], const float in[32], float scale) \ +{ \ + float *synth_buf= synth_buf_ptr + *synth_buf_offset; \ + \ + imdct->imdct_half(imdct, synth_buf, in); \ + \ + ff_synth_filter_inner_##opt(synth_buf, synth_buf2, window, \ + out, *synth_buf_offset, scale); \ + \ + *synth_buf_offset = (*synth_buf_offset - 32) & 511; \ +} \ + +#if HAVE_YASM +#if ARCH_X86_32 +SYNTH_FILTER_FUNC(sse) +#endif +SYNTH_FILTER_FUNC(sse2) +SYNTH_FILTER_FUNC(avx) +SYNTH_FILTER_FUNC(fma3) +#endif /* HAVE_YASM */ + +av_cold void ff_synth_filter_init_x86(SynthFilterContext *s) +{ +#if HAVE_YASM + int cpu_flags = av_get_cpu_flags(); + +#if ARCH_X86_32 + if (EXTERNAL_SSE(cpu_flags)) { + s->synth_filter_float = synth_filter_sse; + } +#endif + if (EXTERNAL_SSE2(cpu_flags)) { + s->synth_filter_float = synth_filter_sse2; + } + if (EXTERNAL_AVX(cpu_flags)) { + s->synth_filter_float = synth_filter_avx; + } + if (EXTERNAL_FMA3(cpu_flags)) { + s->synth_filter_float = synth_filter_fma3; + } +#endif /* HAVE_YASM */ +} diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/x86/hpeldsp_init.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/x86/hpeldsp_init.c index ad6b3d0f0..385f01b4b 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/x86/hpeldsp_init.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/x86/hpeldsp_init.c @@ -22,7 +22,7 @@ * MMX optimization by Nick Kurshev */ -#include "config.h" +#include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/x86/asm.h" #include "libavutil/x86/cpu.h" @@ -252,19 +252,19 @@ static void hpeldsp_init_sse2(HpelDSPContext *c, int flags, int cpu_flags) #endif /* HAVE_SSE2_EXTERNAL */ } -void ff_hpeldsp_init_x86(HpelDSPContext *c, int flags) +av_cold void ff_hpeldsp_init_x86(HpelDSPContext *c, int flags) { int cpu_flags = av_get_cpu_flags(); if (INLINE_MMX(cpu_flags)) hpeldsp_init_mmx(c, flags, cpu_flags); - if (EXTERNAL_MMXEXT(cpu_flags)) - hpeldsp_init_mmxext(c, flags, cpu_flags); - if (EXTERNAL_AMD3DNOW(cpu_flags)) hpeldsp_init_3dnow(c, flags, cpu_flags); + if (EXTERNAL_MMXEXT(cpu_flags)) + hpeldsp_init_mmxext(c, flags, cpu_flags); + if (EXTERNAL_SSE2(cpu_flags)) hpeldsp_init_sse2(c, flags, cpu_flags); } diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/x86/mpegaudiodsp.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/x86/mpegaudiodsp.c index 464911905..3654c8124 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/x86/mpegaudiodsp.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/x86/mpegaudiodsp.c @@ -30,7 +30,9 @@ static void imdct36_blocks_ ## CPU(float *out, float *buf, float *in, int count, int switch_point, int block_type);\ void ff_imdct36_float_ ## CPU(float *out, float *buf, float *in, float *win); +#if ARCH_X86_32 DECL(sse) +#endif DECL(sse2) DECL(sse3) DECL(ssse3) @@ -223,7 +225,9 @@ static void imdct36_blocks_ ## CPU1(float *out, float *buf, float *in, \ } #if HAVE_SSE +#if ARCH_X86_32 DECL_IMDCT_BLOCKS(sse,sse) +#endif DECL_IMDCT_BLOCKS(sse2,sse) DECL_IMDCT_BLOCKS(sse3,sse) DECL_IMDCT_BLOCKS(ssse3,sse) @@ -235,9 +239,7 @@ DECL_IMDCT_BLOCKS(avx,avx) av_cold void ff_mpadsp_init_x86(MPADSPContext *s) { -#if HAVE_SSE2_INLINE || HAVE_YASM int cpu_flags = av_get_cpu_flags(); -#endif int i, j; for (j = 0; j < 4; j++) { @@ -254,15 +256,17 @@ av_cold void ff_mpadsp_init_x86(MPADSPContext *s) } #if HAVE_SSE2_INLINE - if (cpu_flags & AV_CPU_FLAG_SSE2) { + if (INLINE_SSE2(cpu_flags)) { s->apply_window_float = apply_window_mp3; } #endif /* HAVE_SSE2_INLINE */ #if HAVE_YASM +#if ARCH_X86_32 if (EXTERNAL_SSE(cpu_flags)) { s->imdct36_blocks_float = imdct36_blocks_sse; } +#endif if (EXTERNAL_SSE2(cpu_flags)) { s->imdct36_blocks_float = imdct36_blocks_sse2; } diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/x86/ttadsp_init.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/x86/ttadsp_init.c new file mode 100644 index 000000000..47dc87f6a --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavcodec/x86/ttadsp_init.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2014 James Almer + * + * 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 "libavcodec/ttadsp.h" +#include "libavutil/x86/cpu.h" +#include "config.h" + +void ff_ttafilter_process_dec_ssse3(int32_t *qm, int32_t *dx, int32_t *dl, + int32_t *error, int32_t *in, int32_t shift, + int32_t round); +void ff_ttafilter_process_dec_sse4(int32_t *qm, int32_t *dx, int32_t *dl, + int32_t *error, int32_t *in, int32_t shift, + int32_t round); + +av_cold void ff_ttadsp_init_x86(TTADSPContext *c) +{ +#if HAVE_YASM + int cpu_flags = av_get_cpu_flags(); + + if (EXTERNAL_SSSE3(cpu_flags)) + c->ttafilter_process_dec = ff_ttafilter_process_dec_ssse3; + if (EXTERNAL_SSE4(cpu_flags)) + c->ttafilter_process_dec = ff_ttafilter_process_dec_sse4; +#endif +} diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/aacdec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/aacdec.c index aed4981b4..fea41120f 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/aacdec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/aacdec.c @@ -20,7 +20,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "config.h" #include "libavutil/intreadwrite.h" #include "avformat.h" #include "internal.h" @@ -91,7 +90,7 @@ static int adts_aac_read_header(AVFormatContext *s) AVInputFormat ff_aac_demuxer = { .name = "aac", - .long_name = NULL_IF_CONFIG_SMALL("raw ADTS AAC (Advanced Audio Coding)"), + .long_name = "raw ADTS AAC (Advanced Audio Coding)", .read_probe = adts_aac_probe, .read_header = adts_aac_read_header, .read_packet = ff_raw_read_partial_packet, diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/allformats.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/allformats.c index e4e84c542..eefdccf95 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/allformats.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/allformats.c @@ -19,8 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "avformat.h" #include "config.h" +#include "avformat.h" #include "rtp.h" #include "rdt.h" #include "url.h" @@ -46,8 +46,7 @@ { \ extern URLProtocol ff_##x##_protocol; \ if (CONFIG_##X##_PROTOCOL) \ - ffurl_register_protocol(&ff_##x##_protocol, \ - sizeof(ff_##x##_protocol)); \ + ffurl_register_protocol(&ff_##x##_protocol); \ } void av_register_all(void) @@ -136,8 +135,10 @@ void av_register_all(void) REGISTER_MUXDEMUX(H261, h261); REGISTER_MUXDEMUX(H263, h263); REGISTER_MUXDEMUX(H264, h264); - REGISTER_DEMUXER (H265, h265); + REGISTER_MUXER (HDS, hds); + REGISTER_MUXDEMUX(HEVC, hevc); REGISTER_MUXDEMUX(HLS, hls); + REGISTER_DEMUXER (HNM, hnm); REGISTER_MUXDEMUX(ICO, ico); REGISTER_DEMUXER (IDCIN, idcin); REGISTER_DEMUXER (IDF, idf); @@ -205,6 +206,7 @@ void av_register_all(void) REGISTER_DEMUXER (NUV, nuv); REGISTER_MUXDEMUX(OGG, ogg); REGISTER_MUXDEMUX(OMA, oma); + REGISTER_MUXER (OPUS, opus); REGISTER_DEMUXER (PAF, paf); REGISTER_MUXDEMUX(PCM_ALAW, pcm_alaw); REGISTER_MUXDEMUX(PCM_MULAW, pcm_mulaw); @@ -248,9 +250,10 @@ void av_register_all(void) REGISTER_MUXDEMUX(SAP, sap); REGISTER_DEMUXER (SBG, sbg); REGISTER_DEMUXER (SDP, sdp); + REGISTER_DEMUXER (SDR2, sdr2); #if CONFIG_RTPDEC - av_register_rtp_dynamic_payload_handlers(); - av_register_rdt_dynamic_payload_handlers(); + ff_register_rtp_dynamic_payload_handlers(); + ff_register_rdt_dynamic_payload_handlers(); #endif REGISTER_DEMUXER (SEGAFILM, segafilm); REGISTER_MUXER (SEGMENT, segment); @@ -264,6 +267,7 @@ void av_register_all(void) REGISTER_DEMUXER (SOL, sol); REGISTER_MUXDEMUX(SOX, sox); REGISTER_MUXDEMUX(SPDIF, spdif); + REGISTER_MUXER (SPEEX, speex); REGISTER_MUXDEMUX(SRT, srt); REGISTER_DEMUXER (STR, str); REGISTER_DEMUXER (SUBVIEWER1, subviewer1); @@ -282,6 +286,7 @@ void av_register_all(void) REGISTER_DEMUXER (TTA, tta); REGISTER_DEMUXER (TXD, txd); REGISTER_DEMUXER (TTY, tty); + REGISTER_MUXER (UNCODEDFRAMECRC, uncodedframecrc); REGISTER_MUXDEMUX(VC1, vc1); REGISTER_MUXDEMUX(VC1T, vc1t); REGISTER_DEMUXER (VIVO, vivo); @@ -334,6 +339,7 @@ void av_register_all(void) REGISTER_PROTOCOL(RTP, rtp); REGISTER_PROTOCOL(SCTP, sctp); REGISTER_PROTOCOL(SRTP, srtp); + REGISTER_PROTOCOL(SUBFILE, subfile); REGISTER_PROTOCOL(TCP, tcp); REGISTER_PROTOCOL(TLS, tls); REGISTER_PROTOCOL(UDP, udp); diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/ape.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/ape.c index 7f37a3515..50d536e8c 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/ape.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/ape.c @@ -22,7 +22,6 @@ #include -#include "config.h" #include "libavutil/intreadwrite.h" #include "avformat.h" #include "internal.h" @@ -87,10 +86,14 @@ typedef struct { static int ape_probe(AVProbeData * p) { - if (p->buf[0] == 'M' && p->buf[1] == 'A' && p->buf[2] == 'C' && p->buf[3] == ' ') - return AVPROBE_SCORE_MAX; + int version = AV_RL16(p->buf+4); + if (AV_RL32(p->buf) != MKTAG('M', 'A', 'C', ' ')) + return 0; - return 0; + if (version < APE_MIN_VERSION || version > APE_MAX_VERSION) + return AVPROBE_SCORE_MAX/4; + + return AVPROBE_SCORE_MAX; } static void ape_dumpinfo(AVFormatContext * s, APEContext * ape_ctx) @@ -279,18 +282,20 @@ static int ape_read_header(AVFormatContext * s) ape->totalsamples += ape->blocksperframe * (ape->totalframes - 1); if (ape->seektablelength > 0) { - ape->seektable = av_malloc(ape->seektablelength); + ape->seektable = av_mallocz(ape->seektablelength); if (!ape->seektable) return AVERROR(ENOMEM); for (i = 0; i < ape->seektablelength / sizeof(uint32_t) && !pb->eof_reached; i++) ape->seektable[i] = avio_rl32(pb); if (ape->fileversion < 3810) { - ape->bittable = av_malloc(ape->totalframes); + ape->bittable = av_mallocz(ape->totalframes); if (!ape->bittable) return AVERROR(ENOMEM); for (i = 0; i < ape->totalframes && !pb->eof_reached; i++) ape->bittable[i] = avio_r8(pb); } + if (pb->eof_reached) + av_log(s, AV_LOG_WARNING, "File truncated\n"); } ape->frames[0].pos = ape->firstframe; @@ -355,8 +360,8 @@ static int ape_read_header(AVFormatContext * s) st->duration = total_blocks; avpriv_set_pts_info(st, 64, 1, ape->samplerate); - st->codec->extradata = av_malloc(APE_EXTRADATA_SIZE); - st->codec->extradata_size = APE_EXTRADATA_SIZE; + if (ff_alloc_extradata(st->codec, APE_EXTRADATA_SIZE)) + return AVERROR(ENOMEM); AV_WL16(st->codec->extradata + 0, ape->fileversion); AV_WL16(st->codec->extradata + 2, ape->compressiontype); AV_WL16(st->codec->extradata + 4, ape->formatflags); @@ -412,8 +417,10 @@ static int ape_read_packet(AVFormatContext * s, AVPacket * pkt) AV_WL32(pkt->data , nblocks); AV_WL32(pkt->data + 4, ape->frames[ape->currentframe].skip); ret = avio_read(s->pb, pkt->data + extra_size, ape->frames[ape->currentframe].size); - if (ret < 0) + if (ret < 0) { + av_free_packet(pkt); return ret; + } pkt->pts = ape->frames[ape->currentframe].pts; pkt->stream_index = 0; @@ -454,7 +461,7 @@ static int ape_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp AVInputFormat ff_ape_demuxer = { .name = "ape", - .long_name = NULL_IF_CONFIG_SMALL("Monkey's Audio"), + .long_name = "Monkey's Audio", .priv_data_size = sizeof(APEContext), .read_probe = ape_probe, .read_header = ape_read_header, diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/apetag.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/apetag.c index 6b8267d10..03582f369 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/apetag.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/apetag.c @@ -62,15 +62,15 @@ static int ape_tag_read_field(AVFormatContext *s) if (!st) return AVERROR(ENOMEM); - size -= avio_get_str(pb, size, (char *) filename, sizeof(filename)); + size -= avio_get_str(pb, size, (char *)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, (const char *) key, (const char *) filename, 0); + av_dict_set(&st->metadata, (const char *)key, (const char *)filename, 0); - if ((id = ff_guess_image2_codec((const char *) filename)) != AV_CODEC_ID_NONE) { + if ((id = ff_guess_image2_codec((const char *)filename)) != AV_CODEC_ID_NONE) { AVPacket pkt; int ret; @@ -88,14 +88,8 @@ static int ape_tag_read_field(AVFormatContext *s) 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) + if (ff_get_extradata(st->codec, s->pb, size) < 0) 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 { @@ -108,7 +102,7 @@ static int ape_tag_read_field(AVFormatContext *s) return c; } value[c] = 0; - av_dict_set(&s->metadata, (const char *) key, (const char *) value, AV_DICT_DONT_STRDUP_VAL); + av_dict_set(&s->metadata, (const char *)key, (const char *)value, AV_DICT_DONT_STRDUP_VAL); } return 0; } @@ -128,7 +122,7 @@ int64_t ff_ape_parse_tag(AVFormatContext *s) avio_seek(pb, file_size - APE_TAG_FOOTER_BYTES, SEEK_SET); avio_read(pb, buf, 8); /* APETAGEX */ - if (strncmp((const char *) buf, APE_TAG_PREAMBLE, 8)) { + if (strncmp((const char *)buf, APE_TAG_PREAMBLE, 8)) { return 0; } @@ -194,7 +188,7 @@ int ff_ape_write_tag(AVFormatContext *s) while ((e = av_dict_get(s->metadata, "", e, AV_DICT_IGNORE_SUFFIX))) { int val_len; - if (!string_is_ascii((const unsigned char *) e->key)) { + if (!string_is_ascii((const uint8_t *)e->key)) { av_log(s, AV_LOG_WARNING, "Non ASCII keys are not allowed\n"); continue; } @@ -203,7 +197,7 @@ int ff_ape_write_tag(AVFormatContext *s) 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, (const unsigned char *) e->value, val_len); // value + avio_write(dyn_bc, (const unsigned char *)e->value, val_len); // value count++; } if (!count) @@ -215,7 +209,7 @@ int ff_ape_write_tag(AVFormatContext *s) size += 20; // header - avio_write(s->pb, (const unsigned char *) "APETAGEX", 8); // id + avio_write(s->pb, (const unsigned char *)"APETAGEX", 8); // id avio_wl32(s->pb, APE_TAG_VERSION); // version avio_wl32(s->pb, size); avio_wl32(s->pb, count); @@ -223,7 +217,7 @@ int ff_ape_write_tag(AVFormatContext *s) avio_write(s->pb, dyn_buf, size - 20); // footer - avio_write(s->pb, (const unsigned char *) "APETAGEX", 8); // id + avio_write(s->pb, (const unsigned char *)"APETAGEX", 8); // id avio_wl32(s->pb, APE_TAG_VERSION); // version avio_wl32(s->pb, size); // size avio_wl32(s->pb, count); // tag count diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/asf.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/asf.h index 904d3486e..0c9598a8d 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/asf.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/asf.h @@ -43,6 +43,7 @@ typedef struct ASFStream { int timestamp; int64_t duration; int skip_to_key; + int pkt_clean; int ds_span; /* descrambling */ int ds_packet_size; @@ -188,6 +189,4 @@ extern const AVMetadataConv ff_asf_metadata_conv[]; extern AVInputFormat ff_asf_demuxer; -void ff_put_guid(AVIOContext *s, const ff_asf_guid *g); - #endif /* AVFORMAT_ASF_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/asfdec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/asfdec.c index 670a2e63e..9077bce00 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/asfdec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/asfdec.c @@ -1120,8 +1120,7 @@ static int asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt) if (url_feof(pb)) return AVERROR_EOF; - if (asf->packet_size_left < FRAME_HEADER_SIZE || - asf->packet_segments < 1) { + if (asf->packet_size_left < FRAME_HEADER_SIZE) { int ret = asf->packet_size_left + asf->packet_padsize; assert(ret >= 0); @@ -1136,7 +1135,7 @@ static int asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt) } if (asf->packet_time_start == 0) { if (asf_read_frame_header(s, pb) < 0) { - asf->packet_segments = 0; + asf->packet_time_start = asf->packet_segments = 0; continue; } if (asf->stream_index < 0 || @@ -1158,6 +1157,16 @@ static int asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt) asf_st = asf->asf_st; av_assert0(asf_st); + if (!asf_st->frag_offset && asf->packet_frag_offset) { + av_dlog(s, "skipping asf data pkt with fragment offset for " + "stream:%d, expected:%d but got %d from pkt)\n", + asf->stream_index, asf_st->frag_offset, + asf->packet_frag_offset); + avio_skip(pb, asf->packet_frag_size); + asf->packet_size_left -= asf->packet_frag_size; + continue; + } + if (asf->packet_replic_size == 1) { // frag_offset is here used as the beginning timestamp asf->packet_frag_timestamp = asf->packet_time_start; @@ -1190,6 +1199,7 @@ static int asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt) asf_st->pkt.dts = asf->packet_frag_timestamp - asf->hdr.preroll; asf_st->pkt.stream_index = asf->stream_index; asf_st->pkt.pos = asf_st->packet_pos = asf->packet_pos; + asf_st->pkt_clean = 0; if (asf_st->pkt.data && asf_st->palette_changed) { uint8_t *pal; @@ -1230,6 +1240,11 @@ static int asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt) continue; } + if (asf->packet_frag_offset != asf_st->frag_offset && !asf_st->pkt_clean) { + memset(asf_st->pkt.data + asf_st->frag_offset, 0, asf_st->pkt.size - asf_st->frag_offset); + asf_st->pkt_clean = 1; + } + ret = avio_read(pb, asf_st->pkt.data + asf->packet_frag_offset, asf->packet_frag_size); if (ret != asf->packet_frag_size) { @@ -1347,7 +1362,6 @@ static void asf_reset_header(AVFormatContext *s) int i; asf->packet_size_left = 0; - asf->packet_segments = 0; asf->packet_flags = 0; asf->packet_property = 0; asf->packet_timestamp = 0; @@ -1450,30 +1464,30 @@ static int64_t asf_read_pts(AVFormatContext *s, int stream_index, return pts; } -static void asf_build_simple_index(AVFormatContext *s, int stream_index) +static int asf_build_simple_index(AVFormatContext *s, int stream_index) { ff_asf_guid g; ASFContext *asf = s->priv_data; int64_t current_pos = avio_tell(s->pb); + int ret = 0; - if(avio_seek(s->pb, asf->data_object_offset + asf->data_object_size, SEEK_SET) < 0) { - asf->index_read= -1; - return; + if((ret = avio_seek(s->pb, asf->data_object_offset + asf->data_object_size, SEEK_SET)) < 0) { + return ret; } - ff_get_guid(s->pb, &g); + if ((ret = ff_get_guid(s->pb, &g)) < 0) + goto end; /* the data object can be followed by other top-level objects, * skip them until the simple index object is reached */ while (ff_guidcmp(&g, &ff_asf_simple_index_header)) { int64_t gsize = avio_rl64(s->pb); if (gsize < 24 || url_feof(s->pb)) { - avio_seek(s->pb, current_pos, SEEK_SET); - asf->index_read= -1; - return; + goto end; } avio_skip(s->pb, gsize - 24); - ff_get_guid(s->pb, &g); + if ((ret = ff_get_guid(s->pb, &g)) < 0) + goto end; } { @@ -1481,7 +1495,8 @@ static void asf_build_simple_index(AVFormatContext *s, int stream_index) int pct, ict; int i; int64_t av_unused gsize = avio_rl64(s->pb); - ff_get_guid(s->pb, &g); + if ((ret = ff_get_guid(s->pb, &g)) < 0) + goto end; itime = avio_rl64(s->pb); pct = avio_rl32(s->pb); ict = avio_rl32(s->pb); @@ -1504,7 +1519,12 @@ static void asf_build_simple_index(AVFormatContext *s, int stream_index) } asf->index_read = ict > 1; } +end: +// if (url_feof(s->pb)) { +// ret = 0; +// } avio_seek(s->pb, current_pos, SEEK_SET); + return ret; } static int asf_read_seek(AVFormatContext *s, int stream_index, @@ -1512,6 +1532,7 @@ static int asf_read_seek(AVFormatContext *s, int stream_index, { ASFContext *asf = s->priv_data; AVStream *st = s->streams[stream_index]; + int ret = 0; if (s->packet_size <= 0) return -1; @@ -1525,10 +1546,20 @@ static int asf_read_seek(AVFormatContext *s, int stream_index, return ret; } - if (!asf->index_read) - asf_build_simple_index(s, stream_index); + /* explicitly handle the case of seeking to 0 */ + if (!pts) { + asf_reset_header(s); + avio_seek(s->pb, s->data_offset, SEEK_SET); + return 0; + } - if ((asf->index_read > 0 && st->index_entries)) { + if (!asf->index_read) { + ret = asf_build_simple_index(s, stream_index); + if (ret < 0) + asf->index_read = -1; + } + + if (asf->index_read > 0 && st->index_entries) { int index = av_index_search_timestamp(st, pts, flags); if (index >= 0) { /* find the position */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/astdec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/astdec.c index a76bb206f..ec199d26e 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/astdec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/astdec.c @@ -19,23 +19,23 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "config.h" - #include "libavutil/channel_layout.h" #include "libavutil/intreadwrite.h" -#include "libavutil/internal.h" #include "avformat.h" #include "internal.h" #include "ast.h" static int ast_probe(AVProbeData *p) { - if (AV_RL32(p->buf) == MKTAG('S','T','R','M') && - AV_RB16(p->buf + 10) && - AV_RB16(p->buf + 12) && - AV_RB32(p->buf + 16)) - return AVPROBE_SCORE_MAX / 3 * 2; - return 0; + if (AV_RL32(p->buf) != MKTAG('S','T','R','M')) + return 0; + + if (!AV_RB16(p->buf + 10) || + !AV_RB16(p->buf + 12) || AV_RB16(p->buf + 12) > 256 || + !AV_RB32(p->buf + 16) || AV_RB32(p->buf + 16) > 8*48000) + return AVPROBE_SCORE_MAX / 8; + + return AVPROBE_SCORE_MAX / 3 * 2; } static int ast_read_header(AVFormatContext *s) @@ -112,7 +112,7 @@ static int ast_read_packet(AVFormatContext *s, AVPacket *pkt) AVInputFormat ff_ast_demuxer = { .name = "ast", - .long_name = NULL_IF_CONFIG_SMALL("AST (Audio Stream)"), + .long_name = "AST (Audio Stream)", .read_probe = ast_probe, .read_header = ast_read_header, .read_packet = ast_read_packet, diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/avformat.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/avformat.h index b30d3c2d9..103814ed4 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/avformat.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/avformat.h @@ -173,6 +173,58 @@ * * @defgroup lavf_encoding Muxing * @{ + * Muxers take encoded data in the form of @ref AVPacket "AVPackets" and write + * it into files or other output bytestreams in the specified container format. + * + * The main API functions for muxing are avformat_write_header() for writing the + * file header, av_write_frame() / av_interleaved_write_frame() for writing the + * packets and av_write_trailer() for finalizing the file. + * + * At the beginning of the muxing process, the caller must first call + * avformat_alloc_context() to create a muxing context. The caller then sets up + * the muxer by filling the various fields in this context: + * + * - The @ref AVFormatContext.oformat "oformat" field must be set to select the + * muxer that will be used. + * - Unless the format is of the AVFMT_NOFILE type, the @ref AVFormatContext.pb + * "pb" field must be set to an opened IO context, either returned from + * avio_open2() or a custom one. + * - Unless the format is of the AVFMT_NOSTREAMS type, at least one stream must + * be created with the avformat_new_stream() function. The caller should fill + * the @ref AVStream.codec "stream codec context" information, such as the + * codec @ref AVCodecContext.codec_type "type", @ref AVCodecContext.codec_id + * "id" and other parameters (e.g. width / height, the pixel or sample format, + * etc.) as known. The @ref AVCodecContext.time_base "codec timebase" should + * be set to the timebase that the caller desires to use for this stream (note + * that the timebase actually used by the muxer can be different, as will be + * described later). + * - The caller may fill in additional information, such as @ref + * AVFormatContext.metadata "global" or @ref AVStream.metadata "per-stream" + * metadata, @ref AVFormatContext.chapters "chapters", @ref + * AVFormatContext.programs "programs", etc. as described in the + * AVFormatContext documentation. Whether such information will actually be + * stored in the output depends on what the container format and the muxer + * support. + * + * When the muxing context is fully set up, the caller must call + * avformat_write_header() to initialize the muxer internals and write the file + * header. Whether anything actually is written to the IO context at this step + * depends on the muxer, but this function must always be called. Any muxer + * private options must be passed in the options parameter to this function. + * + * The data is then sent to the muxer by repeatedly calling av_write_frame() or + * av_interleaved_write_frame() (consult those functions' documentation for + * discussion on the difference between them; only one of them may be used with + * a single muxing context, they should not be mixed). Do note that the timing + * information on the packets sent to the muxer must be in the corresponding + * AVStream's timebase. That timebase is set by the muxer (in the + * avformat_write_header() step) and may be different from the timebase the + * caller set on the codec context. + * + * Once all the data has been written, the caller must call av_write_trailer() + * to flush any buffered packets and finalize the output file, then close the IO + * context (if any) and finally free the muxing context with + * avformat_free_context(). * @} * * @defgroup lavf_io I/O Read/Write @@ -217,6 +269,7 @@ struct AVFormatContext; +struct AVDeviceInfoList; /** * @defgroup metadata_api Public Metadata API @@ -298,6 +351,7 @@ struct AVFormatContext; * Allocate and read the payload of a packet and initialize its * fields with default values. * + * @param s associated IO context * @param pkt packet * @param size desired payload size * @return >0 (read size) if OK, AVERROR_xxx otherwise @@ -313,6 +367,7 @@ int av_get_packet(AVIOContext *s, AVPacket *pkt, int size); * when there is no reasonable way to know (an upper bound of) * the final size. * + * @param s associated IO context * @param pkt packet * @param size amount of data to read * @return >0 (read size) if OK, AVERROR_xxx otherwise, previous data @@ -346,6 +401,8 @@ typedef struct AVProbeData { } AVProbeData; #define AVPROBE_SCORE_RETRY (AVPROBE_SCORE_MAX/4) +#define AVPROBE_SCORE_STREAM_RETRY (AVPROBE_SCORE_MAX/4-1) + #define AVPROBE_SCORE_EXTENSION 50 ///< score for file extension #define AVPROBE_SCORE_MAX 100 ///< maximum score @@ -461,6 +518,27 @@ typedef struct AVOutputFormat { void (*get_output_timestamp)(struct AVFormatContext *s, int stream, int64_t *dts, int64_t *wall); + /** + * Allows sending messages from application to device. + */ + int (*control_message)(struct AVFormatContext *s, int type, + void *data, size_t data_size); + + /** + * Write an uncoded AVFrame. + * + * See av_write_uncoded_frame() for details. + * + * The library will free *frame afterwards, but the muxer can prevent it + * by setting the pointer to NULL. + */ + int (*write_uncoded_frame)(struct AVFormatContext *, int stream_index, + AVFrame **frame, unsigned flags); + /** + * Returns device list with it properties. + * @see avdevice_list_devices() for more details. + */ + int (*get_device_list)(struct AVFormatContext *s, struct AVDeviceInfoList *device_list); } AVOutputFormat; /** * @} @@ -589,6 +667,12 @@ typedef struct AVInputFormat { * Active streams are all streams that have AVStream.discard < AVDISCARD_ALL. */ int (*read_seek2)(struct AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags); + + /** + * Returns device list with it properties. + * @see avdevice_list_devices() for more details. + */ + int (*get_device_list)(struct AVFormatContext *s, struct AVDeviceInfoList *device_list); } AVInputFormat; /** * @} @@ -764,6 +848,7 @@ typedef struct AVStream { int64_t last_dts; int64_t duration_gcd; int duration_count; + int64_t rfps_duration_sum; double (*duration_error)[2][MAX_STD_TIMEBASES]; int64_t codec_info_duration; int64_t codec_info_duration_fields; @@ -783,6 +868,11 @@ typedef struct AVStream { int pts_wrap_bits; /**< number of bits in pts (used for wrapping control) */ +#if FF_API_REFERENCE_DTS + /* a hack to keep ABI compatibility for ffmpeg and other applications, which accesses parser even + * though it should not */ + int64_t do_not_use; +#endif // Timestamp generation support: /** * Timestamp corresponding to the last dts sync point. @@ -791,7 +881,6 @@ typedef struct AVStream { * a DTS is received from the underlying container. Otherwise set to * AV_NOPTS_VALUE by default. */ - int64_t reference_dts; int64_t first_dts; int64_t cur_dts; int64_t last_IP_pts; @@ -896,6 +985,24 @@ typedef struct AVStream { */ int pts_wrap_behavior; + /** + * Internal data to prevent doing update_initial_durations() twice + */ + int update_initial_durations_done; + + /** + * Internal data to generate dts from pts + */ + int64_t pts_reorder_error[MAX_REORDER_DELAY+1]; + uint8_t pts_reorder_error_count[MAX_REORDER_DELAY+1]; + + /** + * Internal data to analyze DTS and detect faulty mpeg streams + */ + int64_t last_dts_for_order_check; + uint8_t dts_ordered; + uint8_t dts_misordered; + } AVStream; AVRational av_stream_get_r_frame_rate(const AVStream *s); @@ -946,6 +1053,13 @@ typedef struct AVChapter { } AVChapter; +/** + * Callback used by devices to communicate with application. + */ +typedef int (*av_format_control_message)(struct AVFormatContext *s, int type, + void *data, size_t data_size); + + /** * The duration of a video can be estimated through various ways, and this enum can be used * to know how the duration was estimated. @@ -956,6 +1070,8 @@ enum AVDurationEstimationMethod { AVFMT_DURATION_FROM_BITRATE ///< Duration estimated from bitrate (less accurate) }; +typedef struct AVFormatInternal AVFormatInternal; + /** * Format I/O context. * New fields can be added to the end with minor version bumps. @@ -966,32 +1082,41 @@ enum AVDurationEstimationMethod { */ typedef struct AVFormatContext { /** - * A class for logging and AVOptions. Set by avformat_alloc_context(). + * A class for logging and @ref avoptions. Set by avformat_alloc_context(). * Exports (de)muxer private options if they exist. */ const AVClass *av_class; /** - * Can only be iformat or oformat, not both at the same time. + * The input container format. * - * decoding: set by avformat_open_input(). - * encoding: set by the user. + * Demuxing only, set by avformat_open_input(). */ struct AVInputFormat *iformat; + + /** + * The output container format. + * + * Muxing only, must be set by the caller before avformat_write_header(). + */ struct AVOutputFormat *oformat; /** * Format private data. This is an AVOptions-enabled struct * if and only if iformat/oformat.priv_class is not NULL. + * + * - muxing: set by avformat_write_header() + * - demuxing: set by avformat_open_input() */ void *priv_data; /** * I/O context. * - * decoding: either set by the user before avformat_open_input() (then - * the user must close it manually) or set by avformat_open_input(). - * encoding: set by the user. + * - demuxing: either set by the user before avformat_open_input() (then + * the user must close it manually) or set by avformat_open_input(). + * - muxing: set by the user before avformat_write_header(). The caller must + * take care of closing / freeing the IO context. * * Do NOT set this field if AVFMT_NOFILE flag is set in * iformat/oformat.flags. In such a case, the (de)muxer will handle @@ -1002,37 +1127,54 @@ typedef struct AVFormatContext { /* stream info */ int ctx_flags; /**< Format-specific flags, see AVFMTCTX_xx */ + /** + * Number of elements in AVFormatContext.streams. + * + * Set by avformat_new_stream(), must not be modified by any other code. + */ + unsigned int nb_streams; /** * A list of all streams in the file. New streams are created with * avformat_new_stream(). * - * decoding: streams are created by libavformat in avformat_open_input(). - * If AVFMTCTX_NOHEADER is set in ctx_flags, then new streams may also - * appear in av_read_frame(). - * encoding: streams are created by the user before avformat_write_header(). + * - demuxing: streams are created by libavformat in avformat_open_input(). + * If AVFMTCTX_NOHEADER is set in ctx_flags, then new streams may also + * appear in av_read_frame(). + * - muxing: streams are created by the user before avformat_write_header(). + * + * Freed by libavformat in avformat_free_context(). */ - unsigned int nb_streams; AVStream **streams; - char filename[1024]; /**< input or output filename */ + /** + * input or output filename + * + * - demuxing: set by avformat_open_input() + * - muxing: may be set by the caller before avformat_write_header() + */ + char filename[1024]; /** - * Decoding: position of the first frame of the component, in + * Position of the first frame of the component, in * AV_TIME_BASE fractional seconds. NEVER set this value directly: * It is deduced from the AVStream values. + * + * Demuxing only, set by libavformat. */ int64_t start_time; /** - * Decoding: duration of the stream, in AV_TIME_BASE fractional + * Duration of the stream, in AV_TIME_BASE fractional * seconds. Only set this value if you know none of the individual stream * durations and also do not set any of them. This is deduced from the * AVStream values if not set. + * + * Demuxing only, set by libavformat. */ int64_t duration; /** - * Decoding: total stream bitrate in bit/s, 0 if not + * Total stream bitrate in bit/s, 0 if not * available. Never set it directly if the file_size and the * duration are known as FFmpeg can compute it automatically. */ @@ -1058,13 +1200,16 @@ typedef struct AVFormatContext { #define AVFMT_FLAG_KEEP_SIDE_DATA 0x40000 ///< Don't merge side data but keep it separate. /** - * decoding: size of data to probe; encoding: unused. + * Maximum size of the data read from input for determining + * the input container format. + * Demuxing only, set by the caller before avformat_open_input(). */ unsigned int probesize; /** - * decoding: maximum time (in AV_TIME_BASE units) during which the input should - * be analyzed in avformat_find_stream_info(). + * Maximum duration (in AV_TIME_BASE units) of the data read + * from input in avformat_find_stream_info(). + * Demuxing only, set by the caller before avformat_find_stream_info(). */ int max_analyze_duration; @@ -1099,8 +1244,8 @@ typedef struct AVFormatContext { * accurate seeking (depends on demuxer). * Demuxers for which a full in-memory index is mandatory will ignore * this. - * muxing : unused - * demuxing: set by user + * - muxing: unused + * - demuxing: set by user */ unsigned int max_index_size; @@ -1118,41 +1263,49 @@ typedef struct AVFormatContext { * in the trailer. To write chapters in the trailer, nb_chapters * must be zero when write_header is called and non-zero when * write_trailer is called. - * muxing : set by user - * demuxing: set by libavformat + * - muxing: set by user + * - demuxing: set by libavformat */ unsigned int nb_chapters; AVChapter **chapters; + /** + * Metadata that applies to the whole file. + * + * - demuxing: set by libavformat in avformat_open_input() + * - muxing: may be set by the caller before avformat_write_header() + * + * Freed by libavformat in avformat_free_context(). + */ AVDictionary *metadata; /** * Start time of the stream in real world time, in microseconds - * since the unix epoch (00:00 1st January 1970). That is, pts=0 - * in the stream was captured at this real world time. - * - encoding: Set by user. - * - decoding: Unused. + * since the Unix epoch (00:00 1st January 1970). That is, pts=0 in the + * stream was captured at this real world time. + * Muxing only, set by the caller before avformat_write_header(). */ int64_t start_time_realtime; /** - * decoding: number of frames used to probe fps + * The number of frames used for determining the framerate in + * avformat_find_stream_info(). + * Demuxing only, set by the caller before avformat_find_stream_info(). */ int fps_probe_size; /** * Error recognition; higher values will detect more errors but may * misdetect some more or less valid parts as errors. - * - encoding: unused - * - decoding: Set by user. + * Demuxing only, set by the caller before avformat_open_input(). */ int error_recognition; /** * Custom interrupt callbacks for the I/O layer. * - * decoding: set by the user before avformat_open_input(). - * encoding: set by the user before avformat_write_header() + * demuxing: set by the user before avformat_open_input(). + * muxing: set by the user before avformat_write_header() * (mainly useful for AVFMT_NOFILE formats). The callback * should also be passed to avio_open2() if it's used to * open the file. @@ -1165,6 +1318,24 @@ typedef struct AVFormatContext { int debug; #define FF_FDEBUG_TS 0x0001 + /** + * Maximum buffering duration for interleaving. + * + * To ensure all the streams are interleaved correctly, + * av_interleaved_write_frame() will wait until it has at least one packet + * for each stream before actually writing any packets to the output file. + * When some streams are "sparse" (i.e. there are large gaps between + * successive packets), this can result in excessive buffering. + * + * This field specifies the maximum difference between the timestamps of the + * first and the last packet in the muxing queue, above which libavformat + * will output a packet regardless of whether it has queued a packet for all + * the streams. + * + * Muxing only, set by the caller before avformat_write_header(). + */ + int64_t max_interleave_delta; + /** * Transport stream id. * This will be moved into demuxer private options. Thus no API/ABI compatibility @@ -1239,14 +1410,14 @@ typedef struct AVFormatContext { /** * Correct single timestamp overflows * - encoding: unused - * - decoding: Set by user via AVOPtions (NO direct access) + * - decoding: Set by user via AVOptions (NO direct access) */ unsigned int correct_ts_overflow; /** * Force seeking to any (also non key) frames. * - encoding: unused - * - decoding: Set by user via AVOPtions (NO direct access) + * - decoding: Set by user via AVOptions (NO direct access) */ int seek2any; @@ -1316,6 +1487,12 @@ typedef struct AVFormatContext { */ AVRational offset_timebase; + /** + * An opaque field for libavformat internal usage. + * Must not be accessed in any way by callers. + */ + AVFormatInternal *internal; + /** * IO repositioned flag. * This is set by avformat when the underlaying IO context read pointer @@ -1323,9 +1500,70 @@ typedef struct AVFormatContext { * Demuxers can use the flag to detect such changes. */ int io_repositioned; + + /** + * Forced video codec. + * This allows forcing a specific decoder, even when there are multiple with + * the same codec_id. + * Demuxing: Set by user via av_format_set_video_codec (NO direct access). + */ + AVCodec *video_codec; + + /** + * Forced audio codec. + * This allows forcing a specific decoder, even when there are multiple with + * the same codec_id. + * Demuxing: Set by user via av_format_set_audio_codec (NO direct access). + */ + AVCodec *audio_codec; + + /** + * Forced subtitle codec. + * This allows forcing a specific decoder, even when there are multiple with + * the same codec_id. + * Demuxing: Set by user via av_format_set_subtitle_codec (NO direct access). + */ + AVCodec *subtitle_codec; + + /** + * Number of bytes to be written as padding in a metadata header. + * Demuxing: Unused. + * Muxing: Set by user via av_format_set_metadata_header_padding. + */ + int metadata_header_padding; + + /** + * User data. + * This is a place for some private data of the user. + * Mostly usable with control_message_cb or any future callbacks in device's context. + */ + void *opaque; + + /** + * Callback used by devices to communicate with application. + */ + av_format_control_message control_message_cb; + + /** + * Output timestamp offset, in microseconds. + * Muxing: set by user via AVOptions (NO direct access) + */ + int64_t output_ts_offset; } AVFormatContext; int av_format_get_probe_score(const AVFormatContext *s); +AVCodec * av_format_get_video_codec(const AVFormatContext *s); +void av_format_set_video_codec(AVFormatContext *s, AVCodec *c); +AVCodec * av_format_get_audio_codec(const AVFormatContext *s); +void av_format_set_audio_codec(AVFormatContext *s, AVCodec *c); +AVCodec * av_format_get_subtitle_codec(const AVFormatContext *s); +void av_format_set_subtitle_codec(AVFormatContext *s, AVCodec *c); +int av_format_get_metadata_header_padding(const AVFormatContext *s); +void av_format_set_metadata_header_padding(AVFormatContext *s, int c); +void * av_format_get_opaque(const AVFormatContext *s); +void av_format_set_opaque(AVFormatContext *s, void *opaque); +av_format_control_message av_format_get_control_message_cb(const AVFormatContext *s); +void av_format_set_control_message_cb(AVFormatContext *s, av_format_control_message callback); /** * Returns the method used to set ctx->duration. @@ -1439,6 +1677,7 @@ const AVClass *avformat_get_class(void); * User is required to call avcodec_close() and avformat_free_context() to * clean up the allocation by avformat_new_stream(). * + * @param s media file handle * @param c If non-NULL, the AVCodecContext corresponding to the new stream * will be initialized to use this codec. This is needed for e.g. codec-specific * defaults to be set, so codec should be provided if it is known. @@ -1496,6 +1735,7 @@ AVInputFormat *av_find_input_format(const char *short_name); /** * Guess the file format. * + * @param pd data to be probed * @param is_opened Whether the file is already opened; determines whether * demuxers with or without AVFMT_NOFILE are probed. */ @@ -1504,6 +1744,7 @@ AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened); /** * Guess the file format. * + * @param pd data to be probed * @param is_opened Whether the file is already opened; determines whether * demuxers with or without AVFMT_NOFILE are probed. * @param score_max A probe score larger that this is required to accept a @@ -1657,7 +1898,7 @@ int av_find_best_stream(AVFormatContext *ic, enum AVMediaType type, int wanted_stream_nb, int related_stream, - const AVCodec **decoder_ret, + AVCodec **decoder_ret, int flags); #if FF_API_READ_PACKET @@ -1707,6 +1948,8 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt); /** * Seek to the keyframe at timestamp. * 'timestamp' in 'stream_index'. + * + * @param s media file handle * @param stream_index If stream_index is (-1), a default * stream is selected, and timestamp is automatically converted * from AV_TIME_BASE units to the stream specific time_base. @@ -1734,6 +1977,7 @@ int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, * keyframes (this may not be supported by all demuxers). * If flags contain AVSEEK_FLAG_BACKWARD, it is ignored. * + * @param s media file handle * @param stream_index index of the stream which is used as time base reference * @param min_ts smallest acceptable timestamp * @param ts target timestamp @@ -1833,49 +2077,108 @@ int avformat_write_header(AVFormatContext *s, AVDictionary **options); /** * Write a packet to an output media file. * - * The packet shall contain one audio or video frame. - * The packet must be correctly interleaved according to the container - * specification, if not then av_interleaved_write_frame must be used. + * This function passes the packet directly to the muxer, without any buffering + * or reordering. The caller is responsible for correctly interleaving the + * packets if the format requires it. Callers that want libavformat to handle + * the interleaving should call av_interleaved_write_frame() instead of this + * function. * * @param s media file handle - * @param pkt The packet, which contains the stream_index, buf/buf_size, - * dts/pts, ... - * This can be NULL (at any time, not just at the end), in - * order to immediately flush data buffered within the muxer, - * for muxers that buffer up data internally before writing it - * to the output. + * @param pkt The packet containing the data to be written. Note that unlike + * av_interleaved_write_frame(), this function does not take + * ownership of the packet passed to it (though some muxers may make + * an internal reference to the input packet). + *
+ * This parameter can be NULL (at any time, not just at the end), in + * order to immediately flush data buffered within the muxer, for + * muxers that buffer up data internally before writing it to the + * output. + *
+ * Packet's @ref AVPacket.stream_index "stream_index" field must be + * set to the index of the corresponding stream in @ref + * AVFormatContext.streams "s->streams". It is very strongly + * recommended that timing information (@ref AVPacket.pts "pts", @ref + * AVPacket.dts "dts", @ref AVPacket.duration "duration") is set to + * correct values. * @return < 0 on error, = 0 if OK, 1 if flushed and there is no more data to flush + * + * @see av_interleaved_write_frame() */ int av_write_frame(AVFormatContext *s, AVPacket *pkt); /** * Write a packet to an output media file ensuring correct interleaving. * - * The packet must contain one audio or video frame. - * If the packets are already correctly interleaved, the application should - * call av_write_frame() instead as it is slightly faster. It is also important - * to keep in mind that completely non-interleaved input will need huge amounts - * of memory to interleave with this, so it is preferable to interleave at the - * demuxer level. + * This function will buffer the packets internally as needed to make sure the + * packets in the output file are properly interleaved in the order of + * increasing dts. Callers doing their own interleaving should call + * av_write_frame() instead of this function. * * @param s media file handle - * @param pkt The packet containing the data to be written. pkt->buf must be set - * to a valid AVBufferRef describing the packet data. Libavformat takes - * ownership of this reference and will unref it when it sees fit. The caller - * must not access the data through this reference after this function returns. - * This can be NULL (at any time, not just at the end), to flush the - * interleaving queues. - * Packet's @ref AVPacket.stream_index "stream_index" field must be set to the - * index of the corresponding stream in @ref AVFormatContext.streams - * "s.streams". - * It is very strongly recommended that timing information (@ref AVPacket.pts - * "pts", @ref AVPacket.dts "dts" @ref AVPacket.duration "duration") is set to - * correct values. + * @param pkt The packet containing the data to be written. + *
+ * If the packet is reference-counted, this function will take + * ownership of this reference and unreference it later when it sees + * fit. + * The caller must not access the data through this reference after + * this function returns. If the packet is not reference-counted, + * libavformat will make a copy. + *
+ * This parameter can be NULL (at any time, not just at the end), to + * flush the interleaving queues. + *
+ * Packet's @ref AVPacket.stream_index "stream_index" field must be + * set to the index of the corresponding stream in @ref + * AVFormatContext.streams "s->streams". It is very strongly + * recommended that timing information (@ref AVPacket.pts "pts", @ref + * AVPacket.dts "dts", @ref AVPacket.duration "duration") is set to + * correct values. * - * @return 0 on success, a negative AVERROR on error. + * @return 0 on success, a negative AVERROR on error. Libavformat will always + * take care of freeing the packet, even if this function fails. + * + * @see av_write_frame(), AVFormatContext.max_interleave_delta */ int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt); +/** + * Write a uncoded frame to an output media file. + * + * The frame must be correctly interleaved according to the container + * specification; if not, then av_interleaved_write_frame() must be used. + * + * See av_interleaved_write_frame() for details. + */ +int av_write_uncoded_frame(AVFormatContext *s, int stream_index, + AVFrame *frame); + +/** + * Write a uncoded frame to an output media file. + * + * If the muxer supports it, this function allows to write an AVFrame + * structure directly, without encoding it into a packet. + * It is mostly useful for devices and similar special muxers that use raw + * video or PCM data and will not serialize it into a byte stream. + * + * To test whether it is possible to use it with a given muxer and stream, + * use av_write_uncoded_frame_query(). + * + * The caller gives up ownership of the frame and must not access it + * afterwards. + * + * @return >=0 for success, a negative code on error + */ +int av_interleaved_write_uncoded_frame(AVFormatContext *s, int stream_index, + AVFrame *frame); + +/** + * Test whether a muxer supports uncoded frame. + * + * @return >=0 if an uncoded frame can be written to that muxer and stream, + * <0 if not + */ +int av_write_uncoded_frame_query(AVFormatContext *s, int stream_index); + /** * Write the stream trailer to an output media file and free the * file private data. @@ -1999,6 +2302,7 @@ void av_pkt_dump_log2(void *avcl, int level, AVPacket *pkt, int dump_payload, * * @param tags list of supported codec_id-codec_tag pairs, as stored * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag + * @param tag codec tag to match to a codec ID */ enum AVCodecID av_codec_get_id(const struct AVCodecTag * const *tags, unsigned int tag); @@ -2008,6 +2312,7 @@ enum AVCodecID av_codec_get_id(const struct AVCodecTag * const *tags, unsigned i * * @param tags list of supported codec_id-codec_tag pairs, as stored * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag + * @param id codec ID to match to a codec tag */ unsigned int av_codec_get_tag(const struct AVCodecTag * const *tags, enum AVCodecID id); @@ -2027,6 +2332,9 @@ int av_find_default_stream_index(AVFormatContext *s); /** * Get the index for a specific timestamp. + * + * @param st stream that the timestamp belongs to + * @param timestamp timestamp to retrieve the index for * @param flags if AVSEEK_FLAG_BACKWARD then the returned index will correspond * to the timestamp which is <= the requested one, if backward * is 0, then it will be >= @@ -2123,6 +2431,7 @@ int av_sdp_create(AVFormatContext *ac[], int n_files, char *buf, int size); * Return a positive value if the given filename has one of the given * extensions, 0 otherwise. * + * @param filename file name to check against the given extensions * @param extensions a comma-separated list of filename extensions */ int av_match_ext(const char *filename, const char *extensions); @@ -2130,6 +2439,8 @@ int av_match_ext(const char *filename, const char *extensions); /** * Test if the given container can store a codec. * + * @param ofmt container to check for compatibility + * @param codec_id codec to potentially store in container * @param std_compliance standards compliance level, one of FF_COMPLIANCE_* * * @return 1 if codec with ID codec_id can be stored in ofmt, 0 if it cannot. @@ -2157,6 +2468,14 @@ const struct AVCodecTag *avformat_get_riff_video_tags(void); * @return the table mapping RIFF FourCCs for audio to AVCodecID. */ const struct AVCodecTag *avformat_get_riff_audio_tags(void); +/** + * @return the table mapping MOV FourCCs for video to libavcodec AVCodecID. + */ +const struct AVCodecTag *avformat_get_mov_video_tags(void); +/** + * @return the table mapping MOV FourCCs for audio to AVCodecID. + */ +const struct AVCodecTag *avformat_get_mov_audio_tags(void); /** * @} diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/avidec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/avidec.c index 8e316ca04..f79b0dfb6 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/avidec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/avidec.c @@ -19,6 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include + #include "libavutil/avassert.h" #include "libavutil/avstring.h" #include "libavutil/bswap.h" @@ -111,8 +113,8 @@ static int avi_load_index(AVFormatContext *s); static int guess_ni_flag(AVFormatContext *s); #define print_tag(str, tag, size) \ - av_dlog(NULL, "%s: tag=%c%c%c%c size=0x%x\n", \ - str, tag & 0xff, \ + av_dlog(NULL, "pos:%"PRIX64" %s: tag=%c%c%c%c size=0x%x\n", \ + avio_tell(pb), str, tag & 0xff, \ (tag >> 8) & 0xff, \ (tag >> 16) & 0xff, \ (tag >> 24) & 0xff, \ @@ -135,10 +137,10 @@ static int get_riff(AVFormatContext *s, AVIOContext *pb) int i; /* check RIFF header */ - avio_read(pb, (unsigned char *)header, 4); + avio_read(pb, header, 4); avi->riff_end = avio_rl32(pb); /* RIFF chunk size */ avi->riff_end += avio_tell(pb); /* RIFF chunk end */ - avio_read(pb, (unsigned char *)header + 4, 4); + avio_read(pb, header + 4, 4); for (i = 0; avi_headers[i][0]; i++) if (!memcmp(header, avi_headers[i], 8)) @@ -303,7 +305,7 @@ static int avi_read_tag(AVFormatContext *s, AVStream *st, uint32_t tag, value = av_malloc(size + 1); if (!value) return AVERROR(ENOMEM); - avio_read(pb, (unsigned char *)value, size); + avio_read(pb, value, size); value[size] = 0; AV_WL32(key, tag); @@ -348,7 +350,8 @@ static void avi_read_nikon(AVFormatContext *s, uint64_t end) uint16_t size = avio_rl16(s->pb); const char *name = NULL; char buffer[64] = { 0 }; - size -= avio_read(s->pb, (unsigned char *)buffer, + size = FFMIN(size, tag_end - avio_tell(s->pb)); + size -= avio_read(s->pb, buffer, FFMIN(size, sizeof(buffer) - 1)); switch (tag) { case 0x03: @@ -444,7 +447,7 @@ static int avi_read_header(AVFormatContext *s) size += (size & 1); size -= avio_read(pb, date, FFMIN(size, sizeof(date) - 1)); avio_skip(pb, size); - avi_metadata_creation_time(&s->metadata, (char *)date); + avi_metadata_creation_time(&s->metadata, date); break; } case MKTAG('d', 'm', 'l', 'h'): @@ -522,7 +525,8 @@ static int avi_read_header(AVFormatContext *s) avi->dv_demux = avpriv_dv_init_demux(s); if (!avi->dv_demux) goto fail; - } + } else + goto fail; s->streams[0]->priv_data = ast; avio_skip(pb, 3 * 4); ast->scale = avio_rl32(pb); @@ -622,6 +626,10 @@ static int avi_read_header(AVFormatContext *s) if (cur_pos < list_end) size = FFMIN(size, list_end - cur_pos); st = s->streams[stream_index]; + if (st->codec->codec_type != AVMEDIA_TYPE_UNKNOWN) { + avio_skip(pb, size); + break; + } switch (codec_type) { case AVMEDIA_TYPE_VIDEO: if (amv_file_format) { @@ -647,15 +655,8 @@ static int avi_read_header(AVFormatContext *s) st->codec->extradata_size = esize - 10 * 4; } else st->codec->extradata_size = size - 10 * 4; - st->codec->extradata = av_malloc(st->codec->extradata_size + - FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) { - st->codec->extradata_size = 0; + if (ff_get_extradata(st->codec, pb, st->codec->extradata_size) < 0) return AVERROR(ENOMEM); - } - avio_read(pb, - st->codec->extradata, - st->codec->extradata_size); } // FIXME: check if the encoder really did this correctly @@ -688,6 +689,8 @@ static int avi_read_header(AVFormatContext *s) /* This is needed to get the pict type which is necessary * for generating correct pts. */ st->need_parsing = AVSTREAM_PARSE_HEADERS; + if (st->codec->codec_tag == MKTAG('V', 'S', 'S', 'H')) + st->need_parsing = AVSTREAM_PARSE_FULL; if (st->codec->codec_tag == 0 && st->codec->height > 0 && st->codec->extradata_size < 1U << 30) { @@ -747,9 +750,9 @@ static int avi_read_header(AVFormatContext *s) av_log(s, AV_LOG_DEBUG, "overriding invalid dshow_block_align of %d\n", ast->dshow_block_align); ast->dshow_block_align = 0; } - if ((st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align == 1024 && ast->sample_size == 1024) || - (st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align == 4096 && ast->sample_size == 4096) || - (st->codec->codec_id == AV_CODEC_ID_MP3 && ast->dshow_block_align == 1152 && ast->sample_size == 1152)) { + if (st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align == 1024 && ast->sample_size == 1024 || + st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align == 4096 && ast->sample_size == 4096 || + st->codec->codec_id == AV_CODEC_ID_MP3 && ast->dshow_block_align == 1152 && ast->sample_size == 1152) { av_log(s, AV_LOG_DEBUG, "overriding sample_size\n"); ast->sample_size = 0; } @@ -780,13 +783,8 @@ static int avi_read_header(AVFormatContext *s) st = s->streams[stream_index]; if (size<(1<<30)) { - st->codec->extradata_size= size; - st->codec->extradata= av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) { - st->codec->extradata_size= 0; + if (ff_get_extradata(st->codec, pb, size) < 0) return AVERROR(ENOMEM); - } - avio_read(pb, st->codec->extradata, st->codec->extradata_size); } if (st->codec->extradata_size & 1) //FIXME check if the encoder really did this correctly @@ -906,12 +904,14 @@ fail: static int read_gab2_sub(AVStream *st, AVPacket *pkt) { if (pkt->size >= 7 && - !strcmp((char *)pkt->data, "GAB2") && AV_RL16(pkt->data + 5) == 2) { + pkt->size < INT_MAX - AVPROBE_PADDING_SIZE && + !strcmp(pkt->data, "GAB2") && AV_RL16(pkt->data + 5) == 2) { uint8_t desc[256]; int score = AVPROBE_SCORE_EXTENSION, ret; AVIStream *ast = st->priv_data; AVInputFormat *sub_demuxer; AVRational time_base; + int size; AVIOContext *pb = avio_alloc_context(pkt->data + 7, pkt->size - 7, 0, NULL, NULL, NULL, NULL); @@ -921,17 +921,23 @@ static int read_gab2_sub(AVStream *st, AVPacket *pkt) if (desc_len > pb->buf_end - pb->buf_ptr) goto error; - ret = avio_get_str16le(pb, desc_len, (char *)desc, sizeof(desc)); + ret = avio_get_str16le(pb, desc_len, desc, sizeof(desc)); avio_skip(pb, desc_len - ret); if (*desc) - av_dict_set(&st->metadata, "title", (const char *)desc, 0); + av_dict_set(&st->metadata, "title", desc, 0); avio_rl16(pb); /* flags? */ avio_rl32(pb); /* data size */ - pd = (AVProbeData) { .buf = pb->buf_ptr, - .buf_size = pb->buf_end - pb->buf_ptr }; - if (!(sub_demuxer = av_probe_input_format2(&pd, 1, &score))) + size = pb->buf_end - pb->buf_ptr; + pd = (AVProbeData) { .buf = av_mallocz(size + AVPROBE_PADDING_SIZE), + .buf_size = size }; + if (!pd.buf) + goto error; + memcpy(pd.buf, pb->buf_ptr, size); + sub_demuxer = av_probe_input_format2(&pd, 1, &score); + av_freep(&pd.buf); + if (!sub_demuxer) goto error; if (!(ast->sub_ctx = avformat_alloc_context())) @@ -1044,7 +1050,7 @@ start_sync: goto start_sync; } - n = get_stream_idx(d); + n = avi->dv_demux ? 0 : get_stream_idx(d); if (!((i - avi->last_pkt_pos) & 1) && get_stream_idx(d + 1) < s->nb_streams) @@ -1161,6 +1167,8 @@ static int avi_read_packet(AVFormatContext *s, AVPacket *pkt) int size = avpriv_dv_get_packet(avi->dv_demux, pkt); if (size >= 0) return size; + else + goto resync; } if (avi->non_interleaved) { @@ -1311,10 +1319,9 @@ FF_ENABLE_DEPRECATION_WARNINGS size); pkt->stream_index = avi->stream_index; - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { + if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->index_entries) { AVIndexEntry *e; int index; - av_assert0(st->index_entries); index = av_index_search_timestamp(st, ast->frame_offset, 0); e = &st->index_entries[index]; @@ -1584,6 +1591,12 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t pos, pos_min; AVIStream *ast; + /* Does not matter which stream is requested dv in avi has the + * stream information in the first video stream. + */ + if (avi->dv_demux) + stream_index = 0; + if (!avi->index_loaded) { /* we only load the index on demand */ avi_load_index(s); @@ -1616,7 +1629,6 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, /* One and only one real stream for DV in AVI, and it has video */ /* offsets. Calling with other stream indexes should have failed */ /* the av_index_search_timestamp call above. */ - av_assert0(stream_index == 0); if (avio_seek(s->pb, pos, SEEK_SET) < 0) return -1; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/avio.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/avio.c index 0a19b96da..19825337b 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/avio.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/avio.c @@ -42,8 +42,10 @@ URLProtocol *ffurl_protocol_next(URLProtocol *prev) static const char *urlcontext_to_name(void *ptr) { URLContext *h = (URLContext *)ptr; - if(h->prot) return h->prot->name; - else return "NULL"; + if (h->prot) + return h->prot->name; + else + return "NULL"; } static void *urlcontext_child_next(void *obj, void *prev) @@ -64,53 +66,48 @@ static const AVClass *urlcontext_child_class_next(const AVClass *prev) break; /* find next protocol with priv options */ - while ((p = ffurl_protocol_next(p))) + while (p = ffurl_protocol_next(p)) if (p->priv_data_class) return p->priv_data_class; return NULL; - } -static const AVOption options[] = {{NULL}}; +static const AVOption options[] = { { NULL } }; const AVClass ffurl_context_class = { - .class_name = "URLContext", - .item_name = urlcontext_to_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, - .child_next = urlcontext_child_next, + .class_name = "URLContext", + .item_name = urlcontext_to_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, + .child_next = urlcontext_child_next, .child_class_next = urlcontext_child_class_next, }; /*@}*/ - const char *avio_enum_protocols(void **opaque, int output) { URLProtocol *p; *opaque = ffurl_protocol_next(*opaque); - if (!(p = *opaque)) return NULL; + if (!(p = *opaque)) + return NULL; if ((output && p->url_write) || (!output && p->url_read)) return p->name; return avio_enum_protocols(opaque, output); } -int ffurl_register_protocol(URLProtocol *protocol, int size) +int ffurl_register_protocol(URLProtocol *protocol) { URLProtocol **p; - if (size < sizeof(URLProtocol)) { - URLProtocol* temp = av_mallocz(sizeof(URLProtocol)); - memcpy(temp, protocol, size); - protocol = temp; - } p = &first_protocol; - while (*p != NULL) p = &(*p)->next; - *p = protocol; + while (*p != NULL) + p = &(*p)->next; + *p = protocol; protocol->next = NULL; return 0; } -static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up, - const char *filename, int flags, - const AVIOInterruptCB *int_cb) +static int url_alloc_for_protocol(URLContext **puc, struct URLProtocol *up, + const char *filename, int flags, + const AVIOInterruptCB *int_cb) { URLContext *uc; int err; @@ -135,18 +132,22 @@ static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up, goto fail; } uc->av_class = &ffurl_context_class; - uc->filename = (char *) &uc[1]; + uc->filename = (char *)&uc[1]; strcpy(uc->filename, filename); - uc->prot = up; - uc->flags = flags; - uc->is_streamed = 0; /* default = not streamed */ + uc->prot = up; + uc->flags = flags; + uc->is_streamed = 0; /* default = not streamed */ uc->max_packet_size = 0; /* default: stream file */ if (up->priv_data_size) { uc->priv_data = av_mallocz(up->priv_data_size); + if (!uc->priv_data) { + err = AVERROR(ENOMEM); + goto fail; + } if (up->priv_data_class) { int proto_len= strlen(up->name); char *start = strchr(uc->filename, ','); - *(const AVClass**)uc->priv_data = up->priv_data_class; + *(const AVClass **)uc->priv_data = up->priv_data_class; av_opt_set_defaults(uc->priv_data); if(!strncmp(up->name, uc->filename, proto_len) && uc->filename + proto_len == start){ int ret= 0; @@ -178,8 +179,11 @@ static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up, *puc = uc; return 0; - fail: +fail: *puc = NULL; + if (uc) + av_freep(&uc->priv_data); + av_freep(&uc); #if CONFIG_NETWORK if (up->flags & URL_PROTOCOL_FLAG_NETWORK) ff_network_close(); @@ -187,19 +191,22 @@ static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up, return err; } -int ffurl_connect(URLContext* uc, AVDictionary **options) +int ffurl_connect(URLContext *uc, AVDictionary **options) { int err = - uc->prot->url_open2 ? uc->prot->url_open2(uc, uc->filename, uc->flags, options) : + uc->prot->url_open2 ? uc->prot->url_open2(uc, + uc->filename, + uc->flags, + options) : uc->prot->url_open(uc, uc->filename, uc->flags); if (err) return err; uc->is_connected = 1; - //We must be careful here as ffurl_seek() could be slow, for example for http - if( (uc->flags & AVIO_FLAG_WRITE) - || !strcmp(uc->prot->name, "file")) - if(!uc->is_streamed && ffurl_seek(uc, 0, SEEK_SET) < 0) - uc->is_streamed= 1; + /* We must be careful here as ffurl_seek() could be slow, + * for example for http */ + if ((uc->flags & AVIO_FLAG_WRITE) || !strcmp(uc->prot->name, "file")) + if (!uc->is_streamed && ffurl_seek(uc, 0, SEEK_SET) < 0) + uc->is_streamed = 1; return 0; } @@ -208,24 +215,19 @@ int ffurl_connect(URLContext* uc, AVDictionary **options) "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ "0123456789+-." -int ffurl_alloc(URLContext **puc, const char *filename, int flags, - const AVIOInterruptCB *int_cb) +static struct URLProtocol *url_find_protocol(const char *filename) { URLProtocol *up = NULL; char proto_str[128], proto_nested[128], *ptr; size_t proto_len = strspn(filename, URL_SCHEME_CHARS); - if (!first_protocol) { - av_log(NULL, AV_LOG_WARNING, "No URL Protocols are registered. " - "Missing call to av_register_all()?\n"); - } - - if ((filename[proto_len] != ':' && - (filename[proto_len] != ',' || !strchr(filename + proto_len + 1, ':'))) || + if (filename[proto_len] != ':' && + (filename[proto_len] != ',' || !strchr(filename + proto_len + 1, ':')) || is_dos_path(filename)) strcpy(proto_str, "file"); else - av_strlcpy(proto_str, filename, FFMIN(proto_len+1, sizeof(proto_str))); + av_strlcpy(proto_str, filename, + FFMIN(proto_len + 1, sizeof(proto_str))); if ((ptr = strchr(proto_str, ','))) *ptr = '\0'; @@ -233,15 +235,33 @@ int ffurl_alloc(URLContext **puc, const char *filename, int flags, if ((ptr = strchr(proto_nested, '+'))) *ptr = '\0'; - while ((up = ffurl_protocol_next(up))) { + while (up = ffurl_protocol_next(up)) { if (!strcmp(proto_str, up->name)) - return url_alloc_for_protocol (puc, up, filename, flags, int_cb); + break; if (up->flags & URL_PROTOCOL_FLAG_NESTED_SCHEME && !strcmp(proto_nested, up->name)) - return url_alloc_for_protocol (puc, up, filename, flags, int_cb); + break; } + + return up; +} + +int ffurl_alloc(URLContext **puc, const char *filename, int flags, + const AVIOInterruptCB *int_cb) +{ + URLProtocol *p = NULL; + + if (!first_protocol) { + av_log(NULL, AV_LOG_WARNING, "No URL Protocols are registered. " + "Missing call to av_register_all()?\n"); + } + + p = url_find_protocol(filename); + if (p) + return url_alloc_for_protocol(puc, p, filename, flags, int_cb); + *puc = NULL; - if (!strcmp("https", proto_str)) + if (av_strstart("https:", filename, NULL)) av_log(NULL, AV_LOG_WARNING, "https protocol not found, recompile with openssl or gnutls enabled.\n"); return AVERROR_PROTOCOL_NOT_FOUND; } @@ -250,7 +270,7 @@ int ffurl_open(URLContext **puc, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options) { int ret = ffurl_alloc(puc, filename, flags, int_cb); - if (ret) + if (ret < 0) return ret; if (options && (*puc)->prot->priv_data_class && (ret = av_opt_set_dict((*puc)->priv_data, options)) < 0) @@ -264,8 +284,11 @@ fail: return ret; } -static inline int retry_transfer_wrapper(URLContext *h, unsigned char *buf, int size, int size_min, - int (*transfer_func)(URLContext *h, unsigned char *buf, int size)) +static inline int retry_transfer_wrapper(URLContext *h, uint8_t *buf, + int size, int size_min, + int (*transfer_func)(URLContext *h, + uint8_t *buf, + int size)) { int ret, len; int fast_retries = 5; @@ -275,7 +298,7 @@ static inline int retry_transfer_wrapper(URLContext *h, unsigned char *buf, int while (len < size_min) { if (ff_check_interrupt(&h->interrupt_callback)) return AVERROR_EXIT; - ret = transfer_func(h, buf+len, size-len); + ret = transfer_func(h, buf + len, size - len); if (ret == AVERROR(EINTR)) continue; if (h->flags & AVIO_FLAG_NONBLOCK) @@ -296,7 +319,7 @@ static inline int retry_transfer_wrapper(URLContext *h, unsigned char *buf, int } else if (ret < 1) return (ret < 0 && ret != AVERROR_EOF) ? ret : len; if (ret) - fast_retries = FFMAX(fast_retries, 2); + fast_retries = FFMAX(fast_retries, 2); len += ret; } return len; @@ -341,7 +364,8 @@ int ffurl_closep(URLContext **hh) { URLContext *h= *hh; int ret = 0; - if (!h) return 0; /* can happen when ffurl_open fails */ + if (!h) + return 0; /* can happen when ffurl_open fails */ if (h->is_connected && h->prot->url_close) ret = h->prot->url_close(h); @@ -364,11 +388,18 @@ int ffurl_close(URLContext *h) } +const char *avio_find_protocol_name(const char *url) +{ + URLProtocol *p = url_find_protocol(url); + + return p ? p->name : NULL; +} + int avio_check(const char *url, int flags) { URLContext *h; int ret = ffurl_alloc(&h, url, flags, NULL); - if (ret) + if (ret < 0) return ret; if (h->prot->url_check) { @@ -387,8 +418,8 @@ int64_t ffurl_size(URLContext *h) { int64_t pos, size; - size= ffurl_seek(h, 0, AVSEEK_SIZE); - if(size<0){ + size = ffurl_seek(h, 0, AVSEEK_SIZE); + if (size < 0) { pos = ffurl_seek(h, 0, SEEK_CUR); if ((size = ffurl_seek(h, -1, SEEK_END)) < 0) return size; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/avio.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/avio.h index 94d410699..ee265f905 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/avio.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/avio.h @@ -156,6 +156,15 @@ typedef struct AVIOContext { /* unbuffered I/O */ +/** + * Return the name of the protocol that will handle the passed URL. + * + * NULL is returned if no protocol could be found for the given URL. + * + * @return Name of the protocol or NULL. + */ +const char *avio_find_protocol_name(const char *url); + /** * Return AVIO_FLAG_* access flags corresponding to the access permissions * of the resource in url, or a negative value corresponding to an @@ -372,9 +381,10 @@ int avio_get_str16be(AVIOContext *pb, int maxlen, char *buf, int buflen); * * @param s Used to return the pointer to the created AVIOContext. * In case of failure the pointed to value is set to NULL. + * @param url resource to access * @param flags flags which control how the resource indicated by url * is to be opened - * @return 0 in case of success, a negative value corresponding to an + * @return >= 0 in case of success, a negative value corresponding to an * AVERROR code in case of failure */ int avio_open(AVIOContext **s, const char *url, int flags); @@ -387,13 +397,14 @@ int avio_open(AVIOContext **s, const char *url, int flags); * * @param s Used to return the pointer to the created AVIOContext. * In case of failure the pointed to value is set to NULL. + * @param url resource to access * @param flags flags which control how the resource indicated by url * is to be opened * @param int_cb an interrupt callback to be used at the protocols level * @param options A dictionary filled with protocol-private options. On return * this parameter will be destroyed and replaced with a dict containing options * that were not found. May be NULL. - * @return 0 in case of success, a negative value corresponding to an + * @return >= 0 in case of success, a negative value corresponding to an * AVERROR code in case of failure */ int avio_open2(AVIOContext **s, const char *url, int flags, @@ -460,6 +471,8 @@ const char *avio_enum_protocols(void **opaque, int output); /** * Pause and resume playing - only meaningful if using a network streaming * protocol (e.g. MMS). + * + * @param h IO context from which to call the read_pause function pointer * @param pause 1 for pause, 0 for resume */ int avio_pause(AVIOContext *h, int pause); @@ -467,6 +480,8 @@ int avio_pause(AVIOContext *h, int pause); /** * Seek to a given timestamp relative to some component stream. * Only meaningful if using a network streaming protocol (e.g. MMS.). + * + * @param h IO context from which to call the seek function pointers * @param stream_index The stream index that the timestamp is relative to. * If stream_index is (-1) the timestamp should be in AV_TIME_BASE * units from the beginning of the presentation. diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/aviobuf.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/aviobuf.c index 0bf78e482..95fdf200e 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/aviobuf.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/aviobuf.c @@ -201,12 +201,14 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence) int64_t offset1; int64_t pos; int force = whence & AVSEEK_FORCE; + int buffer_size; whence &= ~AVSEEK_FORCE; if(!s) return AVERROR(EINVAL); - pos = s->pos - (s->write_flag ? 0 : (s->buf_end - s->buffer)); + buffer_size = s->buf_end - s->buffer; + pos = s->pos - (s->write_flag ? 0 : buffer_size); if (whence != SEEK_CUR && whence != SEEK_SET) return AVERROR(EINVAL); @@ -219,7 +221,7 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence) } offset1 = offset - pos; if (!s->must_flush && (!s->direct || !s->seek) && - offset1 >= 0 && offset1 <= (s->buf_end - s->buffer)) { + offset1 >= 0 && offset1 <= buffer_size) { /* can do the seek inside the buffer */ s->buf_ptr = s->buffer + offset1; } else if ((!s->seekable || @@ -232,9 +234,20 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence) if (s->eof_reached) return AVERROR_EOF; s->buf_ptr = s->buf_end + offset - s->pos; - } else { + } else if(!s->write_flag && offset1 < 0 && -offset1 < buffer_size>>1 && s->seek && offset > 0) { int64_t res; + pos -= FFMIN(buffer_size>>1, pos); + if ((res = s->seek(s->opaque, pos, SEEK_SET)) < 0) + return res; + s->buf_end = + s->buf_ptr = s->buffer; + s->pos = pos; + s->eof_reached = 0; + fill_buffer(s); + return avio_seek(s, offset, SEEK_SET | force); + } else { + int64_t res; if (s->write_flag) { flush_buffer(s); s->must_flush = 1; @@ -317,17 +330,24 @@ int avio_put_str(AVIOContext *s, const char *str) int avio_put_str16le(AVIOContext *s, const char *str) { - const uint8_t *q = (const uint8_t *) str; + const uint8_t *q = str; int ret = 0; + int err = 0; while (*q) { uint32_t ch; uint16_t tmp; - GET_UTF8(ch, *q++, break;) + GET_UTF8(ch, *q++, goto invalid;) PUT_UTF16(ch, tmp, avio_wl16(s, tmp); ret += 2;) + continue; +invalid: + av_log(s, AV_LOG_ERROR, "Invaid UTF8 sequence in avio_put_str16le\n"); + err = AVERROR(EINVAL); } avio_wl16(s, 0); + if (err) + return err; ret += 2; return ret; } @@ -891,7 +911,7 @@ int avio_printf(AVIOContext *s, const char *fmt, ...) va_start(ap, fmt); ret = vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); - avio_write(s, (const unsigned char *) buf, strlen(buf)); + avio_write(s, buf, strlen(buf)); return ret; } @@ -1029,14 +1049,20 @@ int ffio_open_dyn_packet_buf(AVIOContext **s, int max_packet_size) int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer) { - DynBuffer *d = s->opaque; + DynBuffer *d; int size; static const char padbuf[FF_INPUT_BUFFER_PADDING_SIZE] = {0}; int padding = 0; + if (!s) { + *pbuffer = NULL; + return 0; + } + d = s->opaque; + /* don't attempt to pad fixed-size packet buffers */ if (!s->max_packet_size) { - avio_write(s, (const unsigned char *) padbuf, sizeof(padbuf)); + avio_write(s, padbuf, sizeof(padbuf)); padding = FF_INPUT_BUFFER_PADDING_SIZE; } diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/dtsdec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/dtsdec.c index 9f3fe8bd4..c395d2238 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/dtsdec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/dtsdec.c @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "config.h" #include "libavcodec/bytestream.h" #include "avformat.h" #include "rawdec.h" @@ -73,7 +72,7 @@ static int dts_probe(AVProbeData *p) AVInputFormat ff_dts_demuxer = { .name = "dts", - .long_name = NULL_IF_CONFIG_SMALL("raw DTS"), + .long_name = "raw DTS", .read_probe = dts_probe, .read_header = ff_raw_audio_read_header, .read_packet = ff_raw_read_partial_packet, diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/dtshddec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/dtshddec.c index a69d14b5b..8581bf35b 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/dtshddec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/dtshddec.c @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "config.h" #include "libavutil/intreadwrite.h" #include "libavutil/dict.h" #include "avformat.h" @@ -91,7 +90,7 @@ static int dtshd_read_header(AVFormatContext *s) value = av_malloc(chunk_size); if (!value) goto skip; - avio_read(pb, (unsigned char *) value, chunk_size); + avio_read(pb, (unsigned char *)value, chunk_size); value[chunk_size - 1] = 0; av_dict_set(&s->metadata, "fileinfo", value, AV_DICT_DONT_STRDUP_VAL); @@ -129,7 +128,7 @@ static int raw_read_packet(AVFormatContext *s, AVPacket *pkt) AVInputFormat ff_dtshd_demuxer = { .name = "dtshd", - .long_name = NULL_IF_CONFIG_SMALL("raw DTS-HD"), + .long_name = "raw DTS-HD", .priv_data_size = sizeof(DTSHDDemuxContext), .read_probe = dtshd_probe, .read_header = dtshd_read_header, diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/id3v2.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/id3v2.c index c46147d12..f1b4e6003 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/id3v2.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/id3v2.c @@ -354,7 +354,7 @@ static void read_comm(AVFormatContext *s, AVIOContext *pb, int taglen, * Parse GEOB tag into a ID3v2ExtraMetaGEOB struct. */ static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen, - char *tag, ID3v2ExtraMeta **extra_meta) + char *tag, ID3v2ExtraMeta **extra_meta, int isv34) { ID3v2ExtraMetaGEOB *geob_data = NULL; ID3v2ExtraMeta *new_extra = NULL; @@ -486,7 +486,7 @@ static void free_apic(void *obj) } static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, - char *tag, ID3v2ExtraMeta **extra_meta) + char *tag, ID3v2ExtraMeta **extra_meta, int isv34) { int enc, pic_type; char mimetype[64]; @@ -508,7 +508,12 @@ static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, taglen--; /* mimetype */ + if (isv34) { taglen -= avio_get_str(pb, taglen, mimetype, sizeof(mimetype)); + } else { + avio_read(pb, mimetype, 3); + mimetype[3] = 0; + } while (mime->id != AV_CODEC_ID_NONE) { if (!av_strncasecmp(mime->str, mimetype, sizeof(mimetype))) { id = mime->id; @@ -559,7 +564,7 @@ fail: avio_seek(pb, end, SEEK_SET); } -static void read_chapter(AVFormatContext *s, AVIOContext *pb, int len, char *ttag, ID3v2ExtraMeta **extra_meta) +static void read_chapter(AVFormatContext *s, AVIOContext *pb, int len, char *ttag, ID3v2ExtraMeta **extra_meta, int isv34) { AVRational time_base = {1, 1000}; uint32_t start, end; @@ -568,6 +573,14 @@ static void read_chapter(AVFormatContext *s, AVIOContext *pb, int len, char *tta int taglen; char tag[5]; + if (!s) { + /* We should probably just put the chapter data to extra_meta here + * and do the AVFormatContext-needing part in a separate + * ff_id3v2_parse_apic()-like function. */ + av_log(NULL, AV_LOG_DEBUG, "No AVFormatContext, skipped ID3 chapter data\n"); + return; + } + if (decode_str(s, pb, 0, &dst, &len) < 0) return; if (len < 16) @@ -585,15 +598,14 @@ static void read_chapter(AVFormatContext *s, AVIOContext *pb, int len, char *tta len -= 16; while (len > 10) { - avio_read(pb, (unsigned char *) tag, 4); + if (avio_read(pb, tag, 4) < 4) + goto end; tag[4] = 0; taglen = avio_rb32(pb); avio_skip(pb, 2); len -= 10; - if (taglen < 0 || taglen > len) { - av_free(dst); - return; - } + if (taglen < 0 || taglen > len) + goto end; if (tag[0] == 'T') read_ttag(s, pb, taglen, &chapter->metadata, tag); else @@ -603,14 +615,60 @@ static void read_chapter(AVFormatContext *s, AVIOContext *pb, int len, char *tta ff_metadata_conv(&chapter->metadata, NULL, ff_id3v2_34_metadata_conv); ff_metadata_conv(&chapter->metadata, NULL, ff_id3v2_4_metadata_conv); +end: av_free(dst); } +static void free_priv(void *obj) +{ + ID3v2ExtraMetaPRIV *priv = obj; + av_freep(&priv->owner); + av_freep(&priv->data); + av_freep(&priv); +} + +static void read_priv(AVFormatContext *s, AVIOContext *pb, int taglen, + char *tag, ID3v2ExtraMeta **extra_meta, int isv34) +{ + ID3v2ExtraMeta *meta; + ID3v2ExtraMetaPRIV *priv; + + meta = av_mallocz(sizeof(*meta)); + priv = av_mallocz(sizeof(*priv)); + + if (!meta || !priv) + goto fail; + + if (decode_str(s, pb, ID3v2_ENCODING_ISO8859, &priv->owner, &taglen) < 0) + goto fail; + + priv->data = av_malloc(taglen); + if (!priv->data) + goto fail; + + priv->datasize = taglen; + + if (avio_read(pb, priv->data, priv->datasize) != priv->datasize) + goto fail; + + meta->tag = "PRIV"; + meta->data = priv; + meta->next = *extra_meta; + *extra_meta = meta; + + return; + +fail: + if (priv) + free_priv(priv); + av_freep(&meta); +} + typedef struct ID3v2EMFunc { const char *tag3; const char *tag4; void (*read)(AVFormatContext *, AVIOContext *, int, char *, - ID3v2ExtraMeta **); + ID3v2ExtraMeta **, int isv34); void (*free)(void *obj); } ID3v2EMFunc; @@ -618,6 +676,7 @@ static const ID3v2EMFunc id3v2_extra_meta_funcs[] = { { "GEO", "GEOB", read_geobtag, free_geobtag }, { "PIC", "APIC", read_apic, free_apic }, { "CHAP","CHAP", read_chapter, NULL }, + { "PRIV","PRIV", read_priv, free_priv }, { NULL } }; @@ -640,16 +699,17 @@ static const ID3v2EMFunc *get_extra_meta_func(const char *tag, int isv34) return NULL; } -static void id3v2_parse(AVFormatContext *s, int len, uint8_t version, +static void id3v2_parse(AVIOContext *pb, AVDictionary **metadata, + AVFormatContext *s, int len, uint8_t version, uint8_t flags, ID3v2ExtraMeta **extra_meta) { int isv34, unsync; unsigned tlen; char tag[5]; - int64_t next, end = avio_tell(s->pb) + len; + int64_t next, end = avio_tell(pb) + len; int taghdrlen; const char *reason = NULL; - AVIOContext pb; + AVIOContext pb_local; AVIOContext *pbx; unsigned char *buffer = NULL; int buffer_size = 0; @@ -683,7 +743,7 @@ static void id3v2_parse(AVFormatContext *s, int len, uint8_t version, unsync = flags & 0x80; if (isv34 && flags & 0x40) { /* Extended header present, just skip over it */ - int extlen = get_size(s->pb, 4); + int extlen = get_size(pb, 4); if (version == 4) /* In v2.4 the length includes the length field we just read. */ extlen -= 4; @@ -692,7 +752,7 @@ static void id3v2_parse(AVFormatContext *s, int len, uint8_t version, reason = "invalid extended header length"; goto error; } - avio_skip(s->pb, extlen); + avio_skip(pb, extlen); len -= extlen + 4; if (len < 0) { reason = "extended header too long."; @@ -708,18 +768,20 @@ static void id3v2_parse(AVFormatContext *s, int len, uint8_t version, unsigned long dlen; if (isv34) { - avio_read(s->pb, (unsigned char *) tag, 4); + if (avio_read(pb, tag, 4) < 4) + break; tag[4] = 0; if (version == 3) { - tlen = avio_rb32(s->pb); + tlen = avio_rb32(pb); } else - tlen = get_size(s->pb, 4); - tflags = avio_rb16(s->pb); + tlen = get_size(pb, 4); + tflags = avio_rb16(pb); tunsync = tflags & ID3v2_FLAG_UNSYNCH; } else { - avio_read(s->pb, (unsigned char *) tag, 3); + if (avio_read(pb, tag, 3) < 3) + break; tag[3] = 0; - tlen = avio_rb24(s->pb); + tlen = avio_rb24(pb); } if (tlen > (1<<28)) break; @@ -728,7 +790,7 @@ static void id3v2_parse(AVFormatContext *s, int len, uint8_t version, if (len < 0) break; - next = avio_tell(s->pb) + tlen; + next = avio_tell(pb) + tlen; if (!tlen) { if (tag[0]) @@ -740,7 +802,7 @@ static void id3v2_parse(AVFormatContext *s, int len, uint8_t version, if (tflags & ID3v2_FLAG_DATALEN) { if (tlen < 4) break; - dlen = avio_rb32(s->pb); + dlen = avio_rb32(pb); tlen -= 4; } else dlen = tlen; @@ -759,38 +821,38 @@ static void id3v2_parse(AVFormatContext *s, int len, uint8_t version, type = "encrypted and compressed"; av_log(s, AV_LOG_WARNING, "Skipping %s ID3v2 frame %s.\n", type, tag); - avio_skip(s->pb, tlen); + avio_skip(pb, tlen); /* check for text tag or supported special meta tag */ - } else if (tag[0] == 'T' || memcmp(tag, "COMM", 4) == 0 || + } else if (tag[0] == 'T' || (extra_meta && (extra_func = get_extra_meta_func(tag, isv34)))) { - pbx = s->pb; + pbx = pb; if (unsync || tunsync || tcomp) { - av_fast_malloc(&buffer, (unsigned int *) &buffer_size, tlen); + av_fast_malloc(&buffer, &buffer_size, tlen); if (!buffer) { av_log(s, AV_LOG_ERROR, "Failed to alloc %d bytes\n", tlen); goto seek; } } if (unsync || tunsync) { - int64_t end = avio_tell(s->pb) + tlen; + int64_t end = avio_tell(pb) + tlen; uint8_t *b; b = buffer; - while (avio_tell(s->pb) < end && b - buffer < tlen && !s->pb->eof_reached) { - *b++ = avio_r8(s->pb); - if (*(b - 1) == 0xff && avio_tell(s->pb) < end - 1 && + while (avio_tell(pb) < end && b - buffer < tlen && !pb->eof_reached) { + *b++ = avio_r8(pb); + if (*(b - 1) == 0xff && avio_tell(pb) < end - 1 && b - buffer < tlen && - !s->pb->eof_reached ) { - uint8_t val = avio_r8(s->pb); - *b++ = val ? val : avio_r8(s->pb); + !pb->eof_reached ) { + uint8_t val = avio_r8(pb); + *b++ = val ? val : avio_r8(pb); } } - ffio_init_context(&pb, buffer, b - buffer, 0, NULL, NULL, NULL, + ffio_init_context(&pb_local, buffer, b - buffer, 0, NULL, NULL, NULL, NULL); tlen = b - buffer; - pbx = &pb; // read from sync buffer + pbx = &pb_local; // read from sync buffer } #if CONFIG_ZLIB @@ -806,7 +868,7 @@ static void id3v2_parse(AVFormatContext *s, int len, uint8_t version, } if (!(unsync || tunsync)) { - err = avio_read(s->pb, buffer, tlen); + err = avio_read(pb, buffer, tlen); if (err < 0) { av_log(s, AV_LOG_ERROR, "Failed to read compressed tag\n"); goto seek; @@ -819,28 +881,26 @@ static void id3v2_parse(AVFormatContext *s, int len, uint8_t version, av_log(s, AV_LOG_ERROR, "Failed to uncompress tag: %d\n", err); goto seek; } - ffio_init_context(&pb, uncompressed_buffer, dlen, 0, NULL, NULL, NULL, NULL); + ffio_init_context(&pb_local, uncompressed_buffer, dlen, 0, NULL, NULL, NULL, NULL); tlen = dlen; - pbx = &pb; // read from sync buffer + pbx = &pb_local; // read from sync buffer } #endif if (tag[0] == 'T') /* parse text tag */ - read_ttag(s, pbx, tlen, &s->metadata, tag); - else if (memcmp(tag, "COMM", 4) == 0) - read_comm(s, pbx, tlen, &s->metadata); + read_ttag(s, pbx, tlen, metadata, tag); else /* parse special meta tag */ - extra_func->read(s, pbx, tlen, tag, extra_meta); + extra_func->read(s, pbx, tlen, tag, extra_meta, isv34); } else if (!tag[0]) { if (tag[1]) av_log(s, AV_LOG_WARNING, "invalid frame id, assuming padding\n"); - avio_skip(s->pb, tlen); + avio_skip(pb, tlen); break; } /* Skip to end of tag */ seek: - avio_seek(s->pb, next, SEEK_SET); + avio_seek(pb, next, SEEK_SET); } /* Footer preset, always 10 bytes, skip over it */ @@ -851,14 +911,15 @@ error: if (reason) av_log(s, AV_LOG_INFO, "ID3v2.%d tag skipped, cannot handle %s\n", version, reason); - avio_seek(s->pb, end, SEEK_SET); + avio_seek(pb, end, SEEK_SET); av_free(buffer); av_free(uncompressed_buffer); return; } -void ff_id3v2_read(AVFormatContext *s, const char *magic, - ID3v2ExtraMeta **extra_meta) +static void id3v2_read_internal(AVIOContext *pb, AVDictionary **metadata, + AVFormatContext *s, const char *magic, + ID3v2ExtraMeta **extra_meta) { int len, ret; uint8_t buf[ID3v2_HEADER_SIZE]; @@ -867,10 +928,10 @@ void ff_id3v2_read(AVFormatContext *s, const char *magic, do { /* save the current offset in case there's nothing to read/skip */ - off = avio_tell(s->pb); - ret = avio_read(s->pb, buf, ID3v2_HEADER_SIZE); + off = avio_tell(pb); + ret = avio_read(pb, buf, ID3v2_HEADER_SIZE); if (ret != ID3v2_HEADER_SIZE) { - avio_seek(s->pb, off, SEEK_SET); + avio_seek(pb, off, SEEK_SET); break; } found_header = ff_id3v2_match(buf, magic); @@ -880,15 +941,27 @@ void ff_id3v2_read(AVFormatContext *s, const char *magic, ((buf[7] & 0x7f) << 14) | ((buf[8] & 0x7f) << 7) | (buf[9] & 0x7f); - id3v2_parse(s, len, buf[3], buf[5], extra_meta); + id3v2_parse(pb, metadata, s, len, buf[3], buf[5], extra_meta); } else { - avio_seek(s->pb, off, SEEK_SET); + avio_seek(pb, off, SEEK_SET); } } while (found_header); - ff_metadata_conv(&s->metadata, NULL, ff_id3v2_34_metadata_conv); - ff_metadata_conv(&s->metadata, NULL, id3v2_2_metadata_conv); - ff_metadata_conv(&s->metadata, NULL, ff_id3v2_4_metadata_conv); - merge_date(&s->metadata); + ff_metadata_conv(metadata, NULL, ff_id3v2_34_metadata_conv); + ff_metadata_conv(metadata, NULL, id3v2_2_metadata_conv); + ff_metadata_conv(metadata, NULL, ff_id3v2_4_metadata_conv); + merge_date(metadata); +} + +void ff_id3v2_read_dict(AVIOContext *pb, AVDictionary **metadata, + const char *magic, ID3v2ExtraMeta **extra_meta) +{ + id3v2_read_internal(pb, metadata, NULL, magic, extra_meta); +} + +void ff_id3v2_read(AVFormatContext *s, const char *magic, + ID3v2ExtraMeta **extra_meta) +{ + id3v2_read_internal(s->pb, &s->metadata, s, magic, extra_meta); } void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta) diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/id3v2.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/id3v2.h index e89392213..eb4dc799e 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/id3v2.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/id3v2.h @@ -73,6 +73,12 @@ typedef struct ID3v2ExtraMetaAPIC { enum AVCodecID id; } ID3v2ExtraMetaAPIC; +typedef struct ID3v2ExtraMetaPRIV { + uint8_t *owner; + uint8_t *data; + uint32_t datasize; +} ID3v2ExtraMetaPRIV; + /** * Detect ID3v2 Header. * @param buf must be ID3v2_HEADER_SIZE byte long @@ -89,7 +95,21 @@ int ff_id3v2_match(const uint8_t *buf, const char *magic); int ff_id3v2_tag_len(const uint8_t *buf); /** - * Read an ID3v2 tag, including supported extra metadata + * Read an ID3v2 tag into specified dictionary and retrieve supported extra metadata. + * + * Chapters are not currently read by this variant. + * + * @param metadata Parsed metadata is stored here + * @param extra_meta If not NULL, extra metadata is parsed into a list of + * ID3v2ExtraMeta structs and *extra_meta points to the head of the list + */ +void ff_id3v2_read_dict(AVIOContext *pb, AVDictionary **metadata, const char *magic, ID3v2ExtraMeta **extra_meta); + +/** + * Read an ID3v2 tag, including supported extra metadata and chapters. + * + * Data is read from and stored to AVFormatContext. + * * @param extra_meta If not NULL, extra metadata is parsed into a list of * ID3v2ExtraMeta structs and *extra_meta points to the head of the list */ @@ -114,7 +134,7 @@ int ff_id3v2_write_apic(AVFormatContext *s, ID3v2EncContext *id3, AVPacket *pkt) /** * Finalize an opened ID3v2 tag. */ -void ff_id3v2_finish(ID3v2EncContext *id3, AVIOContext *pb); +void ff_id3v2_finish(ID3v2EncContext *id3, AVIOContext *pb, int padding_bytes); /** * Write an ID3v2 tag containing all global metadata from s. diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/internal.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/internal.h index b69dbc7c6..f19cebf22 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/internal.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/internal.h @@ -22,14 +22,13 @@ #define AVFORMAT_INTERNAL_H #include -#include #include "avformat.h" #define MAX_URL_SIZE 4096 /** size of probe buffer, for guessing file type from file contents */ #define PROBE_BUF_MIN 2048 -#define PROBE_BUF_MAX (1<<20) +#define PROBE_BUF_MAX (1 << 20) #ifdef DEBUG # define hex_dump_debug(class, buf, size) av_hex_dump_log(class, AV_LOG_DEBUG, buf, size) @@ -47,6 +46,14 @@ typedef struct CodecMime{ enum AVCodecID id; } CodecMime; +struct AVFormatInternal { + /** + * Number of streams relevant for interleaving. + * Muxing only. + */ + int nb_interleaved_streams; +}; + #ifdef __GNUC__ #define dynarray_add(tab, nb_ptr, elem)\ do {\ @@ -358,8 +365,51 @@ enum AVCodecID ff_get_pcm_codec_id(int bps, int flt, int be, int sflags); AVRational ff_choose_timebase(AVFormatContext *s, AVStream *st, int min_precission); /** - * Generate standard extradata for AVC-Intra based on width/height and field order. + * Generate standard extradata for AVC-Intra based on width/height and field + * order. */ -void ff_generate_avci_extradata(AVStream *st); +int ff_generate_avci_extradata(AVStream *st); + +/** + * Allocate extradata with additional FF_INPUT_BUFFER_PADDING_SIZE at end + * which is always set to 0. + * + * @param size size of extradata + * @return 0 if OK, AVERROR_xxx on error + */ +int ff_alloc_extradata(AVCodecContext *avctx, int size); + +/** + * Allocate extradata with additional FF_INPUT_BUFFER_PADDING_SIZE at end + * which is always set to 0 and fill it from pb. + * + * @param size size of extradata + * @return >= 0 if OK, AVERROR_xxx on error + */ +int ff_get_extradata(AVCodecContext *avctx, AVIOContext *pb, int size); + +/** + * add frame for rfps calculation. + * + * @param dts timestamp of the i-th frame + * @return 0 if OK, AVERROR_xxx on error + */ +int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t dts); + +void ff_rfps_calculate(AVFormatContext *ic); + +/** + * Flags for AVFormatContext.write_uncoded_frame() + */ +enum AVWriteUncodedFrameFlags { + + /** + * Query whether the feature is possible on this stream. + * The frame argument is ignored. + */ + AV_WRITE_UNCODED_FRAME_QUERY = 0x0001, + +}; + #endif /* AVFORMAT_INTERNAL_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/mp3dec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/mp3dec.c index f26c1f138..900544e67 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/mp3dec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/mp3dec.c @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "config.h" #include "libavutil/opt.h" #include "libavutil/avstring.h" #include "libavutil/intreadwrite.h" @@ -29,11 +28,8 @@ #include "internal.h" #include "id3v2.h" #include "id3v1.h" -#include "apetag.h" #include "libavcodec/mpegaudiodecheader.h" -#define MP3_RESYNC_TOLERANCE_BYTES 65536 - #define XING_FLAG_FRAMES 0x01 #define XING_FLAG_SIZE 0x02 #define XING_FLAG_TOC 0x04 @@ -71,6 +67,8 @@ static int mp3_read_probe(AVProbeData *p) for(; buf < end; buf= buf2+1) { buf2 = buf; + if(ff_mpa_check_header(AV_RB32(buf2))) + continue; for(frames = 0; buf2 < end; frames++) { header = AV_RB32(buf2); @@ -132,8 +130,6 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) MPADecodeHeader c; int vbrtag_size = 0; int is_cbr; - AVDictionaryEntry *de; - uint64_t duration = 0; v = avio_rb32(s->pb); if(ff_mpa_check_header(v) < 0) @@ -143,10 +139,7 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) vbrtag_size = c.frame_size; if(c.layer != 3) return -1; - - mp3->start_pad = 0; - mp3->end_pad = 0; - + spf = c.lsf ? 576 : 1152; /* Samples per frame, layer 3 */ /* Check for Xing / Info tag */ @@ -172,8 +165,10 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) mp3->start_pad = v>>12; mp3-> end_pad = v&4095; st->skip_samples = mp3->start_pad + 528 + 1; - if (mp3->end_pad >= 528 + 1) - mp3->end_pad -= 528 + 1; + if (!st->start_time) + st->start_time = av_rescale_q(st->skip_samples, + (AVRational){1, c.sample_rate}, + st->time_base); av_log(s, AV_LOG_DEBUG, "pad %d %d\n", mp3->start_pad, mp3-> end_pad); } } @@ -190,58 +185,18 @@ static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) frames = avio_rb32(s->pb); } } - - if (!frames) - vbrtag_size = 0; - if (s->metadata && (de = av_dict_get(s->metadata, "iTunSMPB", NULL, 0))) { - uint32_t zero, start_pad, end_pad; - uint64_t last_eight_frames_offset; - if (sscanf(de->value, "%x %x %x %llx %x %llx", &zero, &start_pad, &end_pad, &duration, &zero, &last_eight_frames_offset) < 6) { - duration = 0; - } - else { - mp3->start_pad = start_pad; - mp3->end_pad = end_pad; - if (end_pad >= 528 + 1) - mp3->end_pad = end_pad - (528 + 1); - st->skip_samples = mp3->start_pad + 528 + 1; - av_log(s, AV_LOG_DEBUG, "pad %d %d\n", mp3->start_pad, mp3->end_pad); - if (s->pb->seekable) { - int i; - size = last_eight_frames_offset; - avio_seek(s->pb, base + vbrtag_size + last_eight_frames_offset, SEEK_SET); - for (i = 0; i < 8; ++i) { - v = avio_rb32(s->pb); - if (ff_mpa_check_header(v) < 0) - return -1; - if (avpriv_mpegaudio_decode_header(&c, v) != 0) - break; - size += c.frame_size; - avio_skip(s->pb, c.frame_size - 4); - } - } - } - } - - if(!frames && !size && !duration) + if(!frames && !size) return -1; /* Skip the vbr tag frame */ avio_seek(s->pb, base + vbrtag_size, SEEK_SET); - if (duration) - st->duration = av_rescale_q(duration, (AVRational){1, c.sample_rate}, st->time_base); - else if(frames) + if(frames) st->duration = av_rescale_q(frames, (AVRational){spf, c.sample_rate}, - st->time_base) - av_rescale_q(mp3->end_pad, (AVRational){1, c.sample_rate}, st->time_base); - - if (size) { - if (duration) - st->codec->bit_rate = av_rescale(size, 8 * c.sample_rate, duration); - else if (frames) - st->codec->bit_rate = av_rescale(size, 8 * c.sample_rate, frames * (int64_t)spf); - } + st->time_base); + if (size && frames && !is_cbr) + st->codec->bit_rate = av_rescale(size, 8 * c.sample_rate, frames * (int64_t)spf); mp3->is_cbr = is_cbr; mp3->header_filesize = size; @@ -276,60 +231,8 @@ static int mp3_read_header(AVFormatContext *s) if(s->pb->seekable) mp3->filesize = avio_size(s->pb); - if (mp3_parse_vbr_tags(s, st, off) < 0 && s->pb->seekable) - { - uint64_t duration = 0; - uint8_t buf[8]; - int sample_rate = 0; - int retry_count; - /* Time for a full parse! */ - avio_seek(s->pb, mp3->filesize - 128, SEEK_SET); - avio_read(s->pb, buf, 3); - if (buf[0] == 'T' && buf[1] == 'A' && buf[2] == 'G') - mp3->filesize -= 128; - avio_seek(s->pb, mp3->filesize - APE_TAG_FOOTER_BYTES, SEEK_SET); - avio_read(s->pb, buf, 8); - if (memcmp(buf, APE_TAG_PREAMBLE, 8) == 0) - { - avio_seek(s->pb, 4, SEEK_CUR); - mp3->filesize -= avio_rl32(s->pb) + APE_TAG_FOOTER_BYTES; - } + if (mp3_parse_vbr_tags(s, st, off) < 0) avio_seek(s->pb, off, SEEK_SET); - retry_count = MP3_RESYNC_TOLERANCE_BYTES; - while (avio_tell(s->pb) < mp3->filesize) - { - MPADecodeHeader c; - uint32_t v, spf; - - v = avio_rb32(s->pb); - - if(ff_mpa_check_header(v) < 0) - { - if (--retry_count) - { - avio_seek(s->pb, -3, SEEK_CUR); - continue; - } - else break; - } - - retry_count = MP3_RESYNC_TOLERANCE_BYTES; - - if (avpriv_mpegaudio_decode_header(&c, v) != 0) - break; - - if (!sample_rate) - sample_rate = c.sample_rate; - - spf = c.lsf ? 576 : 1152; /* Samples per frame, layer 3 */ - - duration += spf; - - avio_skip(s->pb, c.frame_size - 4); - } - avio_seek(s->pb, off, SEEK_SET); - st->duration = duration && sample_rate ? av_rescale_q(duration, (AVRational){1, sample_rate}, st->time_base) : 0; - } /* the parameters will be extracted from the compressed bitstream */ return 0; @@ -387,70 +290,60 @@ static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { MP3DecContext *mp3 = s->priv_data; + AVIndexEntry *ie, ie1; AVStream *st = s->streams[0]; - int64_t timestamp_samples = 0; - uint32_t v, spf; + int64_t ret = av_index_search_timestamp(st, timestamp, flags); + int i, j; + int dir = (flags&AVSEEK_FLAG_BACKWARD) ? -1 : 1; - timestamp = av_clip64(timestamp, 0, st->duration); - - /* Screw it, we're doing a full stream parse! */ - avio_seek(s->pb, s->data_offset, SEEK_SET); - - st->skip_samples = 0; - - if (timestamp > 0) { - int64_t skipped = 0; - int64_t skip_extra = 0; - int retry_count = MP3_RESYNC_TOLERANCE_BYTES; - do { - MPADecodeHeader c; - - v = avio_rb32(s->pb); - - if(ff_mpa_check_header(v) < 0) - { - if (--retry_count) - { - avio_seek(s->pb, -3, SEEK_CUR); - continue; - } - else - return -1; - } - - retry_count = MP3_RESYNC_TOLERANCE_BYTES; - - if (avpriv_mpegaudio_decode_header(&c, v) != 0) - return -1; + if (mp3->is_cbr && st->duration > 0 && mp3->header_filesize > s->data_offset) { + int64_t filesize = avio_size(s->pb); + int64_t duration; + if (filesize <= s->data_offset) + filesize = mp3->header_filesize; + filesize -= s->data_offset; + duration = av_rescale(st->duration, filesize, mp3->header_filesize - s->data_offset); + ie = &ie1; + timestamp = av_clip64(timestamp, 0, duration); + ie->timestamp = timestamp; + ie->pos = av_rescale(timestamp, filesize, duration) + s->data_offset; + } else if (mp3->xing_toc) { + if (ret < 0) + return ret; - avio_seek(s->pb, -4, SEEK_CUR); + ie = &st->index_entries[ret]; + } else { + st->skip_samples = timestamp <= 0 ? mp3->start_pad + 528 + 1 : 0; - spf = c.lsf ? 576 : 1152; /* Samples per frame, layer 3 */ - - if (!timestamp_samples) { - timestamp_samples = av_rescale_q(timestamp, st->time_base, (AVRational){1, c.sample_rate}) + mp3->start_pad + 528 + 1; - if (timestamp_samples >= spf * 8 ) { - timestamp_samples -= spf * 8; - skip_extra = spf * 8; - } - else { - skip_extra = timestamp_samples; - timestamp_samples = 0; - } - } - - if ( skipped + spf > timestamp_samples ) break; - - skipped += spf; - - avio_skip(s->pb, c.frame_size); - } while ( (!timestamp_samples || skipped < timestamp_samples) && avio_tell(s->pb) < mp3->filesize ); - - st->skip_samples = timestamp_samples - skipped + skip_extra; + return -1; } - - ff_update_cur_dts(s, st, timestamp); - + + if (dir < 0) + avio_seek(s->pb, FFMAX(ie->pos - 4096, 0), SEEK_SET); + ret = avio_seek(s->pb, ie->pos, SEEK_SET); + if (ret < 0) + return ret; + +#define MIN_VALID 3 + for(i=0; i<4096; i++) { + int64_t pos = ie->pos + i*dir; + for(j=0; jpb, ie->pos + i*dir, SEEK_SET); + if (ret < 0) + return ret; + ff_update_cur_dts(s, st, ie->timestamp); + st->skip_samples = ie->timestamp <= 0 ? mp3->start_pad + 528 + 1 : 0; return 0; } @@ -469,7 +362,7 @@ static const AVClass demuxer_class = { AVInputFormat ff_mp3_demuxer = { .name = "mp3", - .long_name = NULL_IF_CONFIG_SMALL("MP2/3 (MPEG audio layer 2/3)"), + .long_name = "MP2/3 (MPEG audio layer 2/3)", .read_probe = mp3_read_probe, .read_header = mp3_read_header, .read_packet = mp3_read_packet, diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/mpeg.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/mpeg.c index 489035747..35d3f6bb9 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/mpeg.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/mpeg.c @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "config.h" #include "avformat.h" #include "internal.h" #include "mpeg.h" @@ -194,6 +193,8 @@ static long mpegps_psm_parse(MpegDemuxContext *m, AVIOContext *pb) /* skip program_stream_info */ avio_skip(pb, ps_info_length); es_map_length = avio_rb16(pb); + /* Ignore es_map_length, trust psm_length */ + es_map_length = psm_length - ps_info_length - 10; /* at least one es available? */ while (es_map_length >= 4){ @@ -522,7 +523,13 @@ static int mpegps_read_packet(AVFormatContext *s, codec_id = AV_CODEC_ID_DVD_NAV; } else if (startcode >= 0x1c0 && startcode <= 0x1df) { type = AVMEDIA_TYPE_AUDIO; - codec_id = m->sofdec > 0 ? AV_CODEC_ID_ADPCM_ADX : AV_CODEC_ID_MP2; + if (m->sofdec > 0) { + codec_id = AV_CODEC_ID_ADPCM_ADX; + // Auto-detect AC-3 + request_probe = 50; + } else { + codec_id = AV_CODEC_ID_MP2; + } } else if (startcode >= 0x80 && startcode <= 0x87) { type = AVMEDIA_TYPE_AUDIO; codec_id = AV_CODEC_ID_AC3; @@ -624,7 +631,7 @@ static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index, AVInputFormat ff_mpegps_demuxer = { .name = "mpeg", - .long_name = NULL_IF_CONFIG_SMALL("MPEG-PS (MPEG-2 Program Stream)"), + .long_name = "MPEG-PS (MPEG-2 Program Stream)", .priv_data_size = sizeof(MpegDemuxContext), .read_probe = mpegps_probe, .read_header = mpegps_read_header, @@ -917,6 +924,8 @@ static int vobsub_read_seek(AVFormatContext *s, int stream_index, return ret; } + if (stream_index == -1) // only 1 stream + stream_index = 0; return ff_subtitles_queue_seek(&vobsub->q[stream_index], s, stream_index, min_ts, ts, max_ts, flags); } diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/mux.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/mux.c index ba2960032..a578b01b3 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/mux.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/mux.c @@ -189,7 +189,7 @@ static int validate_codec_tag(AVFormatContext *s, AVStream *st) const AVCodecTag *avctag; int n; enum AVCodecID id = AV_CODEC_ID_NONE; - unsigned int tag = 0; + int64_t tag = -1; /** * Check that tag + id is in the table @@ -212,7 +212,7 @@ static int validate_codec_tag(AVFormatContext *s, AVStream *st) } if (id != AV_CODEC_ID_NONE) return 0; - if (tag && (st->codec->strict_std_compliance >= FF_COMPLIANCE_NORMAL)) + if (tag >= 0 && (st->codec->strict_std_compliance >= FF_COMPLIANCE_NORMAL)) return 0; return 1; } @@ -237,7 +237,7 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options) // some sanity checks if (s->nb_streams == 0 && !(of->flags & AVFMT_NOSTREAMS)) { - av_log(s, AV_LOG_ERROR, "no streams\n"); + av_log(s, AV_LOG_ERROR, "No streams to mux were specified\n"); ret = AVERROR(EINVAL); goto fail; } @@ -288,7 +288,6 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options) } } break; - default:break; } if (of->codec_tag) { @@ -321,6 +320,9 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options) av_log(s, AV_LOG_WARNING, "Codec for stream %d does not use global headers " "but container format requires global headers\n", i); + + if (codec->codec_type != AVMEDIA_TYPE_ATTACHMENT) + s->internal->nb_interleaved_streams++; } if (!s->priv_data && of->priv_data_size > 0) { @@ -340,6 +342,8 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options) /* set muxer identification string */ if (s->nb_streams && !(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) { av_dict_set(&s->metadata, "encoder", LIBAVFORMAT_IDENT, 0); + } else { + av_dict_set(&s->metadata, "encoder", NULL, 0); } if (options) { @@ -389,7 +393,7 @@ int avformat_write_header(AVFormatContext *s, AVDictionary **options) { int ret = 0; - if ((ret = init_muxer(s, options))) + if (ret = init_muxer(s, options)) return ret; if (s->oformat->write_header) { @@ -413,6 +417,15 @@ int avformat_write_header(AVFormatContext *s, AVDictionary **options) return 0; } +#define AV_PKT_FLAG_UNCODED_FRAME 0x2000 + +/* Note: using sizeof(AVFrame) from outside lavu is unsafe in general, but + it is only being used internally to this file as a consistency check. + The value is chosen to be very unlikely to appear on its own and to cause + immediate failure if used anywhere as a real size. */ +#define UNCODED_FRAME_PACKET_SIZE (INT_MIN / 3 * 2 + (int)sizeof(AVFrame)) + + //FIXME merge with compute_pkt_fields static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt) { @@ -478,7 +491,9 @@ static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt) /* update pts */ switch (st->codec->codec_type) { case AVMEDIA_TYPE_AUDIO: - frame_size = ff_get_audio_frame_size(st->codec, pkt->size, 1); + frame_size = (pkt->flags & AV_PKT_FLAG_UNCODED_FRAME) ? + ((AVFrame *)pkt->data)->nb_samples : + ff_get_audio_frame_size(st->codec, pkt->size, 1); /* HACK/FIXME, we skip the initial 0 size packets as they are most * likely equal to the encoder delay, but it would be better if we @@ -509,11 +524,21 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) { int ret, did_split; + if (s->output_ts_offset) { + AVStream *st = s->streams[pkt->stream_index]; + int64_t offset = av_rescale_q(s->output_ts_offset, AV_TIME_BASE_Q, st->time_base); + + if (pkt->dts != AV_NOPTS_VALUE) + pkt->dts += offset; + if (pkt->pts != AV_NOPTS_VALUE) + pkt->pts += offset; + } + if (s->avoid_negative_ts > 0) { AVStream *st = s->streams[pkt->stream_index]; int64_t offset = st->mux_ts_offset; - if (pkt->dts < 0 && pkt->dts != AV_NOPTS_VALUE && !s->offset) { + if ((pkt->dts < 0 || s->avoid_negative_ts == 2) && pkt->dts != AV_NOPTS_VALUE && !s->offset) { s->offset = -pkt->dts; s->offset_timebase = st->time_base; } @@ -535,7 +560,14 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) } did_split = av_packet_split_side_data(pkt); - ret = s->oformat->write_packet(s, pkt); + if ((pkt->flags & AV_PKT_FLAG_UNCODED_FRAME)) { + AVFrame *frame = (AVFrame *)pkt->data; + av_assert0(pkt->size == UNCODED_FRAME_PACKET_SIZE); + ret = s->oformat->write_uncoded_frame(s, pkt->stream_index, &frame, 0); + av_frame_free(&frame); + } else { + ret = s->oformat->write_packet(s, pkt); + } if (s->flush_packets && s->pb && ret >= 0 && s->flags & AVFMT_FLAG_FLUSH_PACKETS) avio_flush(s->pb); @@ -546,10 +578,33 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) return ret; } +static int check_packet(AVFormatContext *s, AVPacket *pkt) +{ + if (!pkt) + return 0; + + if (pkt->stream_index < 0 || pkt->stream_index >= s->nb_streams) { + av_log(s, AV_LOG_ERROR, "Invalid packet stream index: %d\n", + pkt->stream_index); + return AVERROR(EINVAL); + } + + if (s->streams[pkt->stream_index]->codec->codec_type == AVMEDIA_TYPE_ATTACHMENT) { + av_log(s, AV_LOG_ERROR, "Received a packet for an attachment stream.\n"); + return AVERROR(EINVAL); + } + + return 0; +} + int av_write_frame(AVFormatContext *s, AVPacket *pkt) { int ret; + ret = check_packet(s, pkt); + if (ret < 0) + return ret; + if (!pkt) { if (s->oformat->flags & AVFMT_ALLOW_FLUSH) { ret = s->oformat->write_packet(s, NULL); @@ -584,6 +639,7 @@ int ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt, AVPacketList **next_point, *this_pktl; AVStream *st = s->streams[pkt->stream_index]; int chunked = s->max_chunk_size || s->max_chunk_duration; + int ret; this_pktl = av_mallocz(sizeof(AVPacketList)); if (!this_pktl) @@ -595,8 +651,17 @@ FF_DISABLE_DEPRECATION_WARNINGS FF_ENABLE_DEPRECATION_WARNINGS #endif pkt->buf = NULL; - av_dup_packet(&this_pktl->pkt); // duplicate the packet if it uses non-allocated memory - av_copy_packet_side_data(&this_pktl->pkt, &this_pktl->pkt); // copy side data + if ((pkt->flags & AV_PKT_FLAG_UNCODED_FRAME)) { + av_assert0(pkt->size == UNCODED_FRAME_PACKET_SIZE); + av_assert0(((AVFrame *)pkt->data)->buf); + } else { + // duplicate the packet if it uses non-allocated memory + if ((ret = av_dup_packet(&this_pktl->pkt)) < 0) { + av_free(this_pktl); + return ret; + } + av_copy_packet_side_data(&this_pktl->pkt, &this_pktl->pkt); // copy side data + } if (s->streams[pkt->stream_index]->last_in_packet_buffer) { next_point = &(st->last_in_packet_buffer->next); @@ -676,7 +741,6 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, { AVPacketList *pktl; int stream_count = 0, noninterleaved_count = 0; - int64_t delta_dts_max = 0; int i, ret; if (pkt) { @@ -693,27 +757,38 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, } } - if (s->nb_streams == stream_count) { + if (s->internal->nb_interleaved_streams == stream_count) flush = 1; - } else if (!flush) { - for (i=0; i < s->nb_streams; i++) { - if (s->streams[i]->last_in_packet_buffer) { - int64_t delta_dts = - av_rescale_q(s->streams[i]->last_in_packet_buffer->pkt.dts, - s->streams[i]->time_base, - AV_TIME_BASE_Q) - - av_rescale_q(s->packet_buffer->pkt.dts, - s->streams[s->packet_buffer->pkt.stream_index]->time_base, - AV_TIME_BASE_Q); - delta_dts_max= FFMAX(delta_dts_max, delta_dts); - } + + if (s->max_interleave_delta > 0 && s->packet_buffer && !flush) { + AVPacket *top_pkt = &s->packet_buffer->pkt; + int64_t delta_dts = INT64_MIN; + int64_t top_dts = av_rescale_q(top_pkt->dts, + s->streams[top_pkt->stream_index]->time_base, + AV_TIME_BASE_Q); + + for (i = 0; i < s->nb_streams; i++) { + int64_t last_dts; + const AVPacketList *last = s->streams[i]->last_in_packet_buffer; + + if (!last) + continue; + + last_dts = av_rescale_q(last->pkt.dts, + s->streams[i]->time_base, + AV_TIME_BASE_Q); + delta_dts = FFMAX(delta_dts, last_dts - top_dts); } - if (s->nb_streams == stream_count+noninterleaved_count && - delta_dts_max > 20*AV_TIME_BASE) { - av_log(s, AV_LOG_DEBUG, "flushing with %d noninterleaved\n", noninterleaved_count); + + if (delta_dts > s->max_interleave_delta) { + av_log(s, AV_LOG_DEBUG, + "Delay between the first packet and last packet in the " + "muxing queue is %"PRId64" > %"PRId64": forcing output\n", + delta_dts, s->max_interleave_delta); flush = 1; } } + if (stream_count && flush) { AVStream *st; pktl = s->packet_buffer; @@ -759,20 +834,28 @@ int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt) { int ret, flush = 0; + ret = check_packet(s, pkt); + if (ret < 0) + goto fail; + if (pkt) { AVStream *st = s->streams[pkt->stream_index]; //FIXME/XXX/HACK drop zero sized packets - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && pkt->size == 0) - return 0; + if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && pkt->size == 0) { + ret = 0; + goto fail; + } av_dlog(s, "av_interleaved_write_frame size:%d dts:%s pts:%s\n", pkt->size, av_ts2str(pkt->dts), av_ts2str(pkt->pts)); if ((ret = compute_pkt_fields2(s, st, pkt)) < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS)) - return ret; + goto fail; - if (pkt->dts == AV_NOPTS_VALUE && !(s->oformat->flags & AVFMT_NOTIMESTAMPS)) - return AVERROR(EINVAL); + if (pkt->dts == AV_NOPTS_VALUE && !(s->oformat->flags & AVFMT_NOTIMESTAMPS)) { + ret = AVERROR(EINVAL); + goto fail; + } } else { av_dlog(s, "av_interleaved_write_frame FLUSH\n"); flush = 1; @@ -781,6 +864,11 @@ int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt) for (;; ) { AVPacket opkt; int ret = interleave_packet(s, &opkt, pkt, flush); + if (pkt) { + memset(pkt, 0, sizeof(*pkt)); + av_init_packet(pkt); + pkt = NULL; + } if (ret <= 0) //FIXME cleanup needed for ret<0 ? return ret; @@ -789,13 +877,15 @@ int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt) s->streams[opkt.stream_index]->nb_frames++; av_free_packet(&opkt); - pkt = NULL; if (ret < 0) return ret; if(s->pb && s->pb->error) return s->pb->error; } +fail: + av_packet_unref(pkt); + return ret; } int av_write_trailer(AVFormatContext *s) @@ -870,3 +960,51 @@ int ff_write_chained(AVFormatContext *dst, int dst_stream, AVPacket *pkt, dst->streams[dst_stream]->time_base); return av_write_frame(dst, &local_pkt); } + +static int av_write_uncoded_frame_internal(AVFormatContext *s, int stream_index, + AVFrame *frame, int interleaved) +{ + AVPacket pkt, *pktp; + + av_assert0(s->oformat); + if (!s->oformat->write_uncoded_frame) + return AVERROR(ENOSYS); + + if (!frame) { + pktp = NULL; + } else { + pktp = &pkt; + av_init_packet(&pkt); + pkt.data = (void *)frame; + pkt.size = UNCODED_FRAME_PACKET_SIZE; + pkt.pts = + pkt.dts = frame->pts; + pkt.duration = av_frame_get_pkt_duration(frame); + pkt.stream_index = stream_index; + pkt.flags |= AV_PKT_FLAG_UNCODED_FRAME; + } + + return interleaved ? av_interleaved_write_frame(s, pktp) : + av_write_frame(s, pktp); +} + +int av_write_uncoded_frame(AVFormatContext *s, int stream_index, + AVFrame *frame) +{ + return av_write_uncoded_frame_internal(s, stream_index, frame, 0); +} + +int av_interleaved_write_uncoded_frame(AVFormatContext *s, int stream_index, + AVFrame *frame) +{ + return av_write_uncoded_frame_internal(s, stream_index, frame, 1); +} + +int av_write_uncoded_frame_query(AVFormatContext *s, int stream_index) +{ + av_assert0(s->oformat); + if (!s->oformat->write_uncoded_frame) + return AVERROR(ENOSYS); + return s->oformat->write_uncoded_frame(s, stream_index, NULL, + AV_WRITE_UNCODED_FRAME_QUERY); +} diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/options.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/options.c index d58d76104..55a8e07f2 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/options.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/options.c @@ -19,6 +19,7 @@ */ #include "avformat.h" #include "avio_internal.h" +#include "internal.h" #include "libavutil/opt.h" /** @@ -41,7 +42,7 @@ static void *format_child_next(void *obj, void *prev) AVFormatContext *s = obj; if (!prev && s->priv_data && ((s->iformat && s->iformat->priv_class) || - (s->oformat && s->oformat->priv_class))) + (s->oformat && s->oformat->priv_class))) return s->priv_data; if (s->pb && s->pb->av_class && prev != s->pb) return s->pb; @@ -109,6 +110,13 @@ AVFormatContext *avformat_alloc_context(void) ic = av_malloc(sizeof(AVFormatContext)); if (!ic) return ic; avformat_get_context_defaults(ic); + + ic->internal = av_mallocz(sizeof(*ic->internal)); + if (!ic->internal) { + avformat_free_context(ic); + return NULL; + } + return ic; } diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/riff.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/riff.c index 853c56998..2ad9c9f67 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/riff.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/riff.c @@ -40,6 +40,9 @@ const AVCodecTag ff_codec_bmp_tags[] = { { AV_CODEC_ID_H264, MKTAG('V', 'S', 'S', 'H') }, { AV_CODEC_ID_H264, MKTAG('Q', '2', '6', '4') }, /* QNAP surveillance system */ { AV_CODEC_ID_H264, MKTAG('V', '2', '6', '4') }, + { AV_CODEC_ID_H264, MKTAG('G', 'A', 'V', 'C') }, /* GeoVision camera */ + { AV_CODEC_ID_H264, MKTAG('U', 'M', 'S', 'V') }, + { AV_CODEC_ID_H264, MKTAG('I', 'N', 'M', 'C') }, { AV_CODEC_ID_H263, MKTAG('H', '2', '6', '3') }, { AV_CODEC_ID_H263, MKTAG('X', '2', '6', '3') }, { AV_CODEC_ID_H263, MKTAG('T', '2', '6', '3') }, @@ -83,11 +86,13 @@ const AVCodecTag ff_codec_bmp_tags[] = { { AV_CODEC_ID_MPEG4, MKTAG('M', '4', 'T', '3') }, { AV_CODEC_ID_MPEG4, MKTAG('G', 'E', 'O', 'X') }, /* flipped video */ + { AV_CODEC_ID_MPEG4, MKTAG('G', '2', '6', '4') }, + /* flipped video */ { AV_CODEC_ID_MPEG4, MKTAG('H', 'D', 'X', '4') }, { AV_CODEC_ID_MPEG4, MKTAG('D', 'M', '4', 'V') }, { AV_CODEC_ID_MPEG4, MKTAG('D', 'M', 'K', '2') }, + { AV_CODEC_ID_MPEG4, MKTAG('D', 'Y', 'M', '4') }, { AV_CODEC_ID_MPEG4, MKTAG('D', 'I', 'G', 'I') }, - { AV_CODEC_ID_MPEG4, MKTAG('I', 'N', 'M', 'C') }, /* Ephv MPEG-4 */ { AV_CODEC_ID_MPEG4, MKTAG('E', 'P', 'H', 'V') }, { AV_CODEC_ID_MPEG4, MKTAG('E', 'M', '4', 'A') }, @@ -250,9 +255,11 @@ const AVCodecTag ff_codec_bmp_tags[] = { { AV_CODEC_ID_VP6, MKTAG('V', 'P', '6', '0') }, { AV_CODEC_ID_VP6, MKTAG('V', 'P', '6', '1') }, { AV_CODEC_ID_VP6, MKTAG('V', 'P', '6', '2') }, + { AV_CODEC_ID_VP6A, MKTAG('V', 'P', '6', 'A') }, { AV_CODEC_ID_VP6F, MKTAG('V', 'P', '6', 'F') }, { AV_CODEC_ID_VP6F, MKTAG('F', 'L', 'V', '4') }, { AV_CODEC_ID_VP8, MKTAG('V', 'P', '8', '0') }, + { AV_CODEC_ID_VP9, MKTAG('V', 'P', '9', '0') }, { AV_CODEC_ID_ASV1, MKTAG('A', 'S', 'V', '1') }, { AV_CODEC_ID_ASV2, MKTAG('A', 'S', 'V', '2') }, { AV_CODEC_ID_VCR1, MKTAG('V', 'C', 'R', '1') }, @@ -349,6 +356,7 @@ const AVCodecTag ff_codec_bmp_tags[] = { { AV_CODEC_ID_G2M, MKTAG('G', '2', 'M', '2') }, { AV_CODEC_ID_G2M, MKTAG('G', '2', 'M', '3') }, { AV_CODEC_ID_G2M, MKTAG('G', '2', 'M', '4') }, + { AV_CODEC_ID_FIC, MKTAG('F', 'I', 'C', 'V') }, { AV_CODEC_ID_NONE, 0 } }; @@ -406,6 +414,8 @@ const AVCodecTag ff_codec_wav_tags[] = { { AV_CODEC_ID_AAC, 0x1600 }, { AV_CODEC_ID_AAC_LATM, 0x1602 }, { AV_CODEC_ID_AC3, 0x2000 }, + /* There is no Microsoft Format Tag for E-AC3, the GUID has to be used */ + { AV_CODEC_ID_EAC3, 0x2000 }, { AV_CODEC_ID_DTS, 0x2001 }, { AV_CODEC_ID_SONIC, 0x2048 }, { AV_CODEC_ID_SONIC_LS, 0x2048 }, @@ -449,3 +459,11 @@ const struct AVCodecTag *avformat_get_riff_audio_tags(void) { return ff_codec_wav_tags; } + +const AVCodecGuid ff_codec_wav_guids[] = { + { AV_CODEC_ID_AC3, { 0x2C, 0x80, 0x6D, 0xE0, 0x46, 0xDB, 0xCF, 0x11, 0xB4, 0xD1, 0x00, 0x80, 0x5F, 0x6C, 0xBB, 0xEA } }, + { AV_CODEC_ID_ATRAC3P, { 0xBF, 0xAA, 0x23, 0xE9, 0x58, 0xCB, 0x71, 0x44, 0xA1, 0x19, 0xFF, 0xFA, 0x01, 0xE4, 0xCE, 0x62 } }, + { AV_CODEC_ID_EAC3, { 0xAF, 0x87, 0xFB, 0xA7, 0x02, 0x2D, 0xFB, 0x42, 0xA4, 0xD4, 0x05, 0xCD, 0x93, 0x84, 0x3B, 0xDD } }, + { AV_CODEC_ID_MP2, { 0x2B, 0x80, 0x6D, 0xE0, 0x46, 0xDB, 0xCF, 0x11, 0xB4, 0xD1, 0x00, 0x80, 0x5F, 0x6C, 0xBB, 0xEA } }, + { AV_CODEC_ID_NONE } +}; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/riff.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/riff.h index 1bf437e06..dba38034e 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/riff.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/riff.h @@ -45,7 +45,7 @@ void ff_end_tag(AVIOContext *pb, int64_t start); */ int ff_get_bmp_header(AVIOContext *pb, AVStream *st, unsigned *esize); -void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc, const AVCodecTag *tags, int for_asf); +void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc, const AVCodecTag *tags, int for_asf, int ignore_extradata); int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc); enum AVCodecID ff_wav_codec_get_id(unsigned int tag, int bps); int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size); @@ -91,7 +91,9 @@ static av_always_inline int ff_guidcmp(const void *g1, const void *g2) return memcmp(g1, g2, sizeof(ff_asf_guid)); } -void ff_get_guid(AVIOContext *s, ff_asf_guid *g); +int ff_get_guid(AVIOContext *s, ff_asf_guid *g); +void ff_put_guid(AVIOContext *s, const ff_asf_guid *g); +const ff_asf_guid *get_codec_guid(enum AVCodecID id, const AVCodecGuid *av_guid); enum AVCodecID ff_codec_guid_get_id(const AVCodecGuid *guids, ff_asf_guid guid); diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/riffdec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/riffdec.c index 77f4cb96b..c3dd371d1 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/riffdec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/riffdec.c @@ -29,19 +29,14 @@ #include "avio_internal.h" #include "riff.h" -const AVCodecGuid ff_codec_wav_guids[] = { - { AV_CODEC_ID_AC3, { 0x2C, 0x80, 0x6D, 0xE0, 0x46, 0xDB, 0xCF, 0x11, 0xB4, 0xD1, 0x00, 0x80, 0x5F, 0x6C, 0xBB, 0xEA } }, - { AV_CODEC_ID_ATRAC3P, { 0xBF, 0xAA, 0x23, 0xE9, 0x58, 0xCB, 0x71, 0x44, 0xA1, 0x19, 0xFF, 0xFA, 0x01, 0xE4, 0xCE, 0x62 } }, - { AV_CODEC_ID_EAC3, { 0xAF, 0x87, 0xFB, 0xA7, 0x02, 0x2D, 0xFB, 0x42, 0xA4, 0xD4, 0x05, 0xCD, 0x93, 0x84, 0x3B, 0xDD } }, - { AV_CODEC_ID_MP2, { 0x2B, 0x80, 0x6D, 0xE0, 0x46, 0xDB, 0xCF, 0x11, 0xB4, 0xD1, 0x00, 0x80, 0x5F, 0x6C, 0xBB, 0xEA } }, - { AV_CODEC_ID_NONE } -}; - -void ff_get_guid(AVIOContext *s, ff_asf_guid *g) +int ff_get_guid(AVIOContext *s, ff_asf_guid *g) { av_assert0(sizeof(*g) == 16); //compiler will optimize this out - if (avio_read(s, *g, sizeof(*g)) < (int)sizeof(*g)) + if (avio_read(s, *g, sizeof(*g)) < (int)sizeof(*g)) { memset(*g, 0, sizeof(*g)); + return AVERROR_INVALIDDATA; + } + return 0; } enum AVCodecID ff_codec_guid_get_id(const AVCodecGuid *guids, ff_asf_guid guid) @@ -115,14 +110,10 @@ int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size) cbSize -= 22; size -= 22; } - codec->extradata_size = cbSize; if (cbSize > 0) { av_free(codec->extradata); - codec->extradata = av_mallocz(codec->extradata_size + - FF_INPUT_BUFFER_PADDING_SIZE); - if (!codec->extradata) + if (ff_get_extradata(codec, pb, cbSize) < 0) return AVERROR(ENOMEM); - avio_read(pb, codec->extradata, codec->extradata_size); size -= cbSize; } diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/spdifdec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/spdifdec.c index 033fca28b..7da16c95b 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/spdifdec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/spdifdec.c @@ -29,7 +29,6 @@ #include "spdif.h" #include "libavcodec/ac3.h" #include "libavcodec/aacadtsdec.h" -#include "libavutil/internal.h" static int spdif_get_offset_and_codec(AVFormatContext *s, enum IEC61937DataType data_type, @@ -57,8 +56,8 @@ static int spdif_get_offset_and_codec(AVFormatContext *s, *codec = AV_CODEC_ID_MP3; break; case IEC61937_MPEG2_AAC: - init_get_bits(&gbc, (const uint8_t *) buf, AAC_ADTS_HEADER_SIZE * 8); - if (avpriv_aac_parse_header(&gbc, &aac_hdr)) { + init_get_bits(&gbc, buf, AAC_ADTS_HEADER_SIZE * 8); + if (avpriv_aac_parse_header(&gbc, &aac_hdr) < 0) { if (s) /* be silent during a probe */ av_log(s, AV_LOG_ERROR, "Invalid AAC packet in IEC 61937\n"); return AVERROR_INVALIDDATA; @@ -141,7 +140,7 @@ int ff_spdif_probe(const uint8_t *p_buf, int buf_size, enum AVCodecID *codec) /* skip directly to the next sync code */ if (!spdif_get_offset_and_codec(NULL, (buf[2] << 8) | buf[1], - (const char *) &buf[5], &offset, codec)) { + &buf[5], &offset, codec)) { if (buf + offset >= p_buf + buf_size) break; expected_code = buf + offset; @@ -199,7 +198,7 @@ int ff_spdif_read_packet(AVFormatContext *s, AVPacket *pkt) } ff_spdif_bswap_buf16((uint16_t *)pkt->data, (uint16_t *)pkt->data, pkt->size >> 1); - ret = spdif_get_offset_and_codec(s, data_type, (const char *) pkt->data, + ret = spdif_get_offset_and_codec(s, data_type, pkt->data, &offset, &codec_id); if (ret) { av_free_packet(pkt); diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/url.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/url.h index 7b46b59da..0923c70d6 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/url.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/url.h @@ -106,7 +106,7 @@ typedef struct URLProtocol { * is to be opened * @param int_cb interrupt callback to use for the URLContext, may be * NULL - * @return 0 in case of success, a negative value corresponding to an + * @return >= 0 in case of success, a negative value corresponding to an * AVERROR code in case of failure */ int ffurl_alloc(URLContext **puc, const char *filename, int flags, @@ -135,7 +135,7 @@ int ffurl_connect(URLContext *uc, AVDictionary **options); * @param options A dictionary filled with protocol-private options. On return * this parameter will be destroyed and replaced with a dict containing options * that were not found. May be NULL. - * @return 0 in case of success, a negative value corresponding to an + * @return >= 0 in case of success, a negative value corresponding to an * AVERROR code in case of failure */ int ffurl_open(URLContext **puc, const char *filename, int flags, @@ -231,10 +231,8 @@ int ffurl_shutdown(URLContext *h, int flags); /** * Register the URLProtocol protocol. - * - * @param size the size of the URLProtocol struct referenced */ -int ffurl_register_protocol(URLProtocol *protocol, int size); +int ffurl_register_protocol(URLProtocol *protocol); /** * Check if the user has requested to interrup a blocking function diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/utils.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/utils.c index 888ca5b61..b25aadb24 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/utils.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/utils.c @@ -19,35 +19,39 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "avformat.h" -#include "avio_internal.h" -#include "internal.h" -#include "libavcodec/internal.h" -#include "libavcodec/raw.h" -#include "libavcodec/bytestream.h" -#include "libavutil/opt.h" -#include "libavutil/dict.h" -#include "libavutil/internal.h" -#include "libavutil/pixdesc.h" -#include "metadata.h" -#include "id3v2.h" +#undef NDEBUG +#include +#include +#include + +#include "config.h" + #include "libavutil/avassert.h" #include "libavutil/avstring.h" +#include "libavutil/dict.h" +#include "libavutil/internal.h" #include "libavutil/mathematics.h" +#include "libavutil/opt.h" #include "libavutil/parseutils.h" +#include "libavutil/pixdesc.h" #include "libavutil/time_.h" #include "libavutil/timestamp.h" -#include "riff.h" + +#include "libavcodec/bytestream.h" +#include "libavcodec/internal.h" +#include "libavcodec/raw.h" + #include "audiointerleave.h" -#include "url.h" -#include +#include "avformat.h" +#include "avio_internal.h" +#include "id3v2.h" +#include "internal.h" +#include "metadata.h" #if CONFIG_NETWORK #include "network.h" #endif -#include - -#undef NDEBUG -#include +#include "riff.h" +#include "url.h" /** * @file @@ -90,21 +94,39 @@ static int64_t wrap_timestamp(AVStream *st, int64_t timestamp) st->pts_wrap_reference != AV_NOPTS_VALUE && timestamp != AV_NOPTS_VALUE) { if (st->pts_wrap_behavior == AV_PTS_WRAP_ADD_OFFSET && timestamp < st->pts_wrap_reference) - return timestamp + (1ULL<pts_wrap_bits); + return timestamp + (1ULL << st->pts_wrap_bits); else if (st->pts_wrap_behavior == AV_PTS_WRAP_SUB_OFFSET && timestamp >= st->pts_wrap_reference) - return timestamp - (1ULL<pts_wrap_bits); + return timestamp - (1ULL << st->pts_wrap_bits); } return timestamp; } MAKE_ACCESSORS(AVStream, stream, AVRational, r_frame_rate) +MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, video_codec) +MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, audio_codec) +MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, subtitle_codec) +MAKE_ACCESSORS(AVFormatContext, format, int, metadata_header_padding) +MAKE_ACCESSORS(AVFormatContext, format, void *, opaque) +MAKE_ACCESSORS(AVFormatContext, format, av_format_control_message, control_message_cb) -static const AVCodec *find_decoder(AVStream *st, enum AVCodecID codec_id) +static AVCodec *find_decoder(AVFormatContext *s, AVStream *st, enum AVCodecID codec_id) { if (st->codec->codec) return st->codec->codec; + switch (st->codec->codec_type) { + case AVMEDIA_TYPE_VIDEO: + if (s->video_codec) return s->video_codec; + break; + case AVMEDIA_TYPE_AUDIO: + if (s->audio_codec) return s->audio_codec; + break; + case AVMEDIA_TYPE_SUBTITLE: + if (s->subtitle_codec) return s->subtitle_codec; + break; + } + return avcodec_find_decoder(codec_id); } @@ -118,28 +140,26 @@ int av_format_get_probe_score(const AVFormatContext *s) int ffio_limit(AVIOContext *s, int size) { - if(s->maxsize>=0){ + if (s->maxsize>= 0) { int64_t remaining= s->maxsize - avio_tell(s); - if(remaining < size){ - int64_t newsize= avio_size(s); - if(!s->maxsize || s->maxsizemaxsize= newsize - !newsize; + if (remaining < size) { + int64_t newsize = avio_size(s); + if (!s->maxsize || s->maxsizemaxsize = newsize - !newsize; remaining= s->maxsize - avio_tell(s); remaining= FFMAX(remaining, 0); } - if(s->maxsize>=0 && remaining+1 < size){ + if (s->maxsize>= 0 && remaining+1 < size) { av_log(NULL, remaining ? AV_LOG_ERROR : AV_LOG_DEBUG, "Truncating packet of size %d to %"PRId64"\n", size, remaining+1); - size= remaining+1; + size = remaining+1; } } return size; } -/* - * Read the data in sane-sized chunks and append to pkt. - * Return the number of bytes read or an error. - */ +/* Read the data in sane-sized chunks and append to pkt. + * Return the number of bytes read or an error. */ static int append_packet_chunked(AVIOContext *s, AVPacket *pkt, int size) { int64_t orig_pos = pkt->pos; // av_grow_packet might reset pos @@ -150,10 +170,8 @@ static int append_packet_chunked(AVIOContext *s, AVPacket *pkt, int size) int prev_size = pkt->size; int read_size; - /* - * When the caller requests a lot of data, limit it to the amount left - * in file or SANE_CHUNK_SIZE when it is not known - */ + /* When the caller requests a lot of data, limit it to the amount + * left in file or SANE_CHUNK_SIZE when it is not known. */ read_size = size; if (read_size > SANE_CHUNK_SIZE/10) { read_size = ffio_limit(s, read_size); @@ -200,29 +218,30 @@ int av_append_packet(AVIOContext *s, AVPacket *pkt, int size) return append_packet_chunked(s, pkt, size); } - int av_filename_number_test(const char *filename) { char buf[1024]; - return filename && (av_get_frame_filename(buf, sizeof(buf), filename, 1)>=0); + return filename && + (av_get_frame_filename(buf, sizeof(buf), filename, 1) >= 0); } -AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened, int *score_ret) +AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened, + int *score_ret) { AVProbeData lpd = *pd; AVInputFormat *fmt1 = NULL, *fmt; - int score, nodat = 0, score_max=0; + int score, nodat = 0, score_max = 0; const static uint8_t zerobuffer[AVPROBE_PADDING_SIZE]; if (!lpd.buf) - lpd.buf = (unsigned char *) zerobuffer; + lpd.buf = zerobuffer; if (lpd.buf_size > 10 && ff_id3v2_match(lpd.buf, ID3v2_DEFAULT_MAGIC)) { int id3len = ff_id3v2_tag_len(lpd.buf); if (lpd.buf_size > id3len + 16) { - lpd.buf += id3len; + lpd.buf += id3len; lpd.buf_size -= id3len; - }else + } else nodat = 1; } @@ -233,22 +252,21 @@ AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened, int *score score = 0; if (fmt1->read_probe) { score = fmt1->read_probe(&lpd); - if(fmt1->extensions && av_match_ext(lpd.filename, fmt1->extensions)) + if (fmt1->extensions && av_match_ext(lpd.filename, fmt1->extensions)) score = FFMAX(score, nodat ? AVPROBE_SCORE_EXTENSION / 2 - 1 : 1); } else if (fmt1->extensions) { - if (av_match_ext(lpd.filename, fmt1->extensions)) { + if (av_match_ext(lpd.filename, fmt1->extensions)) score = AVPROBE_SCORE_EXTENSION; - } } if (score > score_max) { score_max = score; - fmt = fmt1; - }else if (score == score_max) + fmt = fmt1; + } else if (score == score_max) fmt = NULL; } - if(nodat) + if (nodat) score_max = FFMIN(AVPROBE_SCORE_EXTENSION / 2 - 1, score_max); - *score_ret= score_max; + *score_ret = score_max; return fmt; } @@ -256,32 +274,37 @@ AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened, int *score AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max) { int score_ret; - AVInputFormat *fmt= av_probe_input_format3(pd, is_opened, &score_ret); - if(score_ret > *score_max){ - *score_max= score_ret; + AVInputFormat *fmt = av_probe_input_format3(pd, is_opened, &score_ret); + if (score_ret > *score_max) { + *score_max = score_ret; return fmt; - }else + } else return NULL; } -AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened){ - int score=0; +AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened) +{ + int score = 0; return av_probe_input_format2(pd, is_opened, &score); } -static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, AVProbeData *pd) +static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, + AVProbeData *pd) { static const struct { - const char *name; enum AVCodecID id; enum AVMediaType type; + const char *name; + enum AVCodecID id; + enum AVMediaType type; } fmt_id_type[] = { - { "aac" , AV_CODEC_ID_AAC , AVMEDIA_TYPE_AUDIO }, - { "ac3" , AV_CODEC_ID_AC3 , AVMEDIA_TYPE_AUDIO }, - { "dts" , AV_CODEC_ID_DTS , AVMEDIA_TYPE_AUDIO }, - { "eac3" , AV_CODEC_ID_EAC3 , AVMEDIA_TYPE_AUDIO }, - { "h264" , AV_CODEC_ID_H264 , AVMEDIA_TYPE_VIDEO }, - { "loas" , AV_CODEC_ID_AAC_LATM , AVMEDIA_TYPE_AUDIO }, - { "m4v" , AV_CODEC_ID_MPEG4 , AVMEDIA_TYPE_VIDEO }, - { "mp3" , AV_CODEC_ID_MP3 , AVMEDIA_TYPE_AUDIO }, + { "aac", AV_CODEC_ID_AAC, AVMEDIA_TYPE_AUDIO }, + { "ac3", AV_CODEC_ID_AC3, AVMEDIA_TYPE_AUDIO }, + { "dts", AV_CODEC_ID_DTS, AVMEDIA_TYPE_AUDIO }, + { "eac3", AV_CODEC_ID_EAC3, AVMEDIA_TYPE_AUDIO }, + { "h264", AV_CODEC_ID_H264, AVMEDIA_TYPE_VIDEO }, + { "hevc", AV_CODEC_ID_HEVC, AVMEDIA_TYPE_VIDEO }, + { "loas", AV_CODEC_ID_AAC_LATM, AVMEDIA_TYPE_AUDIO }, + { "m4v", AV_CODEC_ID_MPEG4, AVMEDIA_TYPE_VIDEO }, + { "mp3", AV_CODEC_ID_MP3, AVMEDIA_TYPE_AUDIO }, { "mpegvideo", AV_CODEC_ID_MPEG2VIDEO, AVMEDIA_TYPE_VIDEO }, { 0 } }; @@ -290,8 +313,10 @@ static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, AVProbeDa if (fmt && st->request_probe <= score) { int i; - av_log(s, AV_LOG_DEBUG, "Probe with size=%d, packets=%d detected %s with score=%d\n", - pd->buf_size, MAX_PROBE_PACKETS - st->probe_packets, fmt->name, score); + av_log(s, AV_LOG_DEBUG, + "Probe with size=%d, packets=%d detected %s with score=%d\n", + pd->buf_size, MAX_PROBE_PACKETS - st->probe_packets, + fmt->name, score); for (i = 0; fmt_id_type[i].name; i++) { if (!strcmp(fmt->name, fmt_id_type[i].name)) { st->codec->codec_id = fmt_id_type[i].id; @@ -306,7 +331,7 @@ static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, AVProbeDa /************************************************************/ /* input media file */ -int av_demuxer_open(AVFormatContext *ic){ +int av_demuxer_open(AVFormatContext *ic) { int err; if (ic->iformat->read_header) { @@ -326,65 +351,75 @@ int av_probe_input_buffer2(AVIOContext *pb, AVInputFormat **fmt, const char *filename, void *logctx, unsigned int offset, unsigned int max_probe_size) { - AVProbeData pd = { filename ? filename : "", NULL, -offset }; - unsigned char *buf = NULL; + AVProbeData pd = { filename ? filename : "" }; + uint8_t *buf = NULL; uint8_t *mime_type; int ret = 0, probe_size, buf_offset = 0; int score = 0; - if (!max_probe_size) { + if (!max_probe_size) max_probe_size = PROBE_BUF_MAX; - } else if (max_probe_size > PROBE_BUF_MAX) { + else if (max_probe_size > PROBE_BUF_MAX) max_probe_size = PROBE_BUF_MAX; - } else if (max_probe_size < PROBE_BUF_MIN) { + else if (max_probe_size < PROBE_BUF_MIN) { av_log(logctx, AV_LOG_ERROR, "Specified probe size value %u cannot be < %u\n", max_probe_size, PROBE_BUF_MIN); return AVERROR(EINVAL); } - if (offset >= max_probe_size) { + if (offset >= max_probe_size) return AVERROR(EINVAL); - } if (!*fmt && pb->av_class && av_opt_get(pb, "mime_type", AV_OPT_SEARCH_CHILDREN, &mime_type) >= 0 && mime_type) { - if (!av_strcasecmp((const char *) mime_type, "audio/aacp")) { + if (!av_strcasecmp(mime_type, "audio/aacp")) { *fmt = av_find_input_format("aac"); } av_freep(&mime_type); } - for(probe_size= PROBE_BUF_MIN; probe_size<=max_probe_size && !*fmt; - probe_size = FFMIN(probe_size<<1, FFMAX(max_probe_size, probe_size+1))) { - - if (probe_size < offset) { - continue; - } + for (probe_size = PROBE_BUF_MIN; probe_size <= max_probe_size && !*fmt; + probe_size = FFMIN(probe_size << 1, + FFMAX(max_probe_size, probe_size + 1))) { score = probe_size < max_probe_size ? AVPROBE_SCORE_RETRY : 0; - /* read probe data */ + /* Read probe data. */ if ((ret = av_reallocp(&buf, probe_size + AVPROBE_PADDING_SIZE)) < 0) return ret; - if ((ret = avio_read(pb, buf + buf_offset, probe_size - buf_offset)) < 0) { - /* fail if error was not end of file, otherwise, lower score */ + if ((ret = avio_read(pb, buf + buf_offset, + probe_size - buf_offset)) < 0) { + /* Fail if error was not end of file, otherwise, lower score. */ if (ret != AVERROR_EOF) { av_free(buf); return ret; } score = 0; - ret = 0; /* error was end of file, nothing read */ + ret = 0; /* error was end of file, nothing read */ } - pd.buf_size = buf_offset += ret; + buf_offset += ret; + if (buf_offset < offset) + continue; + pd.buf_size = buf_offset - offset; pd.buf = &buf[offset]; memset(pd.buf + pd.buf_size, 0, AVPROBE_PADDING_SIZE); - /* guess file format */ + /* Guess file format. */ *fmt = av_probe_input_format2(&pd, 1, &score); - if(*fmt){ - if(score <= AVPROBE_SCORE_RETRY){ //this can only be true in the last iteration - av_log(logctx, AV_LOG_WARNING, "Format %s detected only with low score of %d, misdetection possible!\n", (*fmt)->name, score); - }else - av_log(logctx, AV_LOG_DEBUG, "Format %s probed with size=%d and score=%d\n", (*fmt)->name, probe_size, score); + if (*fmt) { + /* This can only be true in the last iteration. */ + if (score <= AVPROBE_SCORE_RETRY) { + av_log(logctx, AV_LOG_WARNING, + "Format %s detected only with low score of %d, " + "misdetection possible!\n", (*fmt)->name, score); + } else + av_log(logctx, AV_LOG_DEBUG, + "Format %s probed with size=%d and score=%d\n", + (*fmt)->name, probe_size, score); +#if 0 + FILE *f = fopen("probestat.tmp", "ab"); + fprintf(f, "probe_size:%d format:%s score:%d filename:%s\n", probe_size, (*fmt)->name, score, filename); + fclose(f); +#endif } } @@ -393,8 +428,8 @@ int av_probe_input_buffer2(AVIOContext *pb, AVInputFormat **fmt, return AVERROR_INVALIDDATA; } - /* rewind. reuse probe buffer to avoid seeking */ - ret = ffio_rewind_with_probe_data(pb, &buf, pd.buf_size); + /* Rewind. Reuse probe buffer to avoid seeking. */ + ret = ffio_rewind_with_probe_data(pb, &buf, buf_offset); return ret < 0 ? ret : score; } @@ -407,25 +442,26 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt, return ret < 0 ? ret : 0; } - -/* open input file and probe the format if necessary */ -static int init_input(AVFormatContext *s, const char *filename, AVDictionary **options) +/* Open input file and probe the format if necessary. */ +static int init_input(AVFormatContext *s, const char *filename, + AVDictionary **options) { int ret; - AVProbeData pd = {filename, NULL, 0}; + AVProbeData pd = { filename, NULL, 0 }; int score = AVPROBE_SCORE_RETRY; if (s->pb) { s->flags |= AVFMT_FLAG_CUSTOM_IO; if (!s->iformat) - return av_probe_input_buffer2(s->pb, &s->iformat, filename, s, 0, s->probesize); + return av_probe_input_buffer2(s->pb, &s->iformat, filename, + s, 0, s->probesize); else if (s->iformat->flags & AVFMT_NOFILE) av_log(s, AV_LOG_WARNING, "Custom AVIOContext makes no sense and " "will be ignored with AVFMT_NOFILE format.\n"); return 0; } - if ( (s->iformat && s->iformat->flags & AVFMT_NOFILE) || + if ((s->iformat && s->iformat->flags & AVFMT_NOFILE) || (!s->iformat && (s->iformat = av_probe_input_format2(&pd, 0, &score)))) return score; @@ -434,11 +470,13 @@ static int init_input(AVFormatContext *s, const char *filename, AVDictionary **o return ret; if (s->iformat) return 0; - return av_probe_input_buffer2(s->pb, &s->iformat, filename, s, 0, s->probesize); + return av_probe_input_buffer2(s->pb, &s->iformat, filename, + s, 0, s->probesize); } static AVPacket *add_to_pktbuf(AVPacketList **packet_buffer, AVPacket *pkt, - AVPacketList **plast_pktl){ + AVPacketList **plast_pktl) +{ AVPacketList *pktl = av_mallocz(sizeof(AVPacketList)); if (!pktl) return NULL; @@ -448,9 +486,9 @@ static AVPacket *add_to_pktbuf(AVPacketList **packet_buffer, AVPacket *pkt, else *packet_buffer = pktl; - /* add the packet in the buffered packet list */ + /* Add the packet in the buffered packet list. */ *plast_pktl = pktl; - pktl->pkt= *pkt; + pktl->pkt = *pkt; return &pktl->pkt; } @@ -461,16 +499,18 @@ int avformat_queue_attached_pictures(AVFormatContext *s) if (s->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC && s->streams[i]->discard < AVDISCARD_ALL) { AVPacket copy = s->streams[i]->attached_pic; - copy.buf = av_buffer_ref(copy.buf); + copy.buf = av_buffer_ref(copy.buf); if (!copy.buf) return AVERROR(ENOMEM); - add_to_pktbuf(&s->raw_packet_buffer, ©, &s->raw_packet_buffer_end); + add_to_pktbuf(&s->raw_packet_buffer, ©, + &s->raw_packet_buffer_end); } return 0; } -int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options) +int avformat_open_input(AVFormatContext **ps, const char *filename, + AVInputFormat *fmt, AVDictionary **options) { AVFormatContext *s = *ps; int ret = 0; @@ -479,7 +519,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma if (!s && !(s = avformat_alloc_context())) return AVERROR(ENOMEM); - if (!s->av_class){ + if (!s->av_class) { av_log(NULL, AV_LOG_ERROR, "Input context has not been properly allocated by avformat_alloc_context() and is not NULL either\n"); return AVERROR(EINVAL); } @@ -497,7 +537,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma s->probe_score = ret; avio_skip(s->pb, s->skip_initial_bytes); - /* check filename in case an image number is expected */ + /* Check filename in case an image number is expected. */ if (s->iformat->flags & AVFMT_NEEDNUMBER) { if (!av_filename_number_test(filename)) { ret = AVERROR(EINVAL); @@ -508,14 +548,14 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma s->duration = s->start_time = AV_NOPTS_VALUE; av_strlcpy(s->filename, filename ? filename : "", sizeof(s->filename)); - /* allocate private data */ + /* Allocate private data. */ if (s->iformat->priv_data_size > 0) { if (!(s->priv_data = av_mallocz(s->iformat->priv_data_size))) { ret = AVERROR(ENOMEM); goto fail; } if (s->iformat->priv_class) { - *(const AVClass**)s->priv_data = s->iformat->priv_class; + *(const AVClass **) s->priv_data = s->iformat->priv_class; av_opt_set_defaults(s->priv_data); if ((ret = av_opt_set_dict(s->priv_data, &tmp)) < 0) goto fail; @@ -533,7 +573,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma if (id3v2_extra_meta) { if (!strcmp(s->iformat->name, "mp3") || !strcmp(s->iformat->name, "aac") || !strcmp(s->iformat->name, "tta")) { - if((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0) + if ((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0) goto fail; } else av_log(s, AV_LOG_DEBUG, "demuxer does not support additional id3 data, skipping\n"); @@ -569,23 +609,25 @@ fail: static void force_codec_ids(AVFormatContext *s, AVStream *st) { - switch(st->codec->codec_type){ + switch (st->codec->codec_type) { case AVMEDIA_TYPE_VIDEO: - if(s->video_codec_id) st->codec->codec_id= s->video_codec_id; + if (s->video_codec_id) + st->codec->codec_id = s->video_codec_id; break; case AVMEDIA_TYPE_AUDIO: - if(s->audio_codec_id) st->codec->codec_id= s->audio_codec_id; + if (s->audio_codec_id) + st->codec->codec_id = s->audio_codec_id; break; case AVMEDIA_TYPE_SUBTITLE: - if(s->subtitle_codec_id)st->codec->codec_id= s->subtitle_codec_id; + if (s->subtitle_codec_id) + st->codec->codec_id = s->subtitle_codec_id; break; - default:break; } } static int probe_codec(AVFormatContext *s, AVStream *st, const AVPacket *pkt) { - if(st->request_probe>0){ + if (st->request_probe>0) { AVProbeData *pd = &st->probe_data; int end; av_log(s, AV_LOG_DEBUG, "probing stream %d pp:%d\n", st->index, st->probe_packets); @@ -593,38 +635,38 @@ static int probe_codec(AVFormatContext *s, AVStream *st, const AVPacket *pkt) if (pkt) { uint8_t *new_buf = av_realloc(pd->buf, pd->buf_size+pkt->size+AVPROBE_PADDING_SIZE); - if(!new_buf) { + if (!new_buf) { av_log(s, AV_LOG_WARNING, "Failed to reallocate probe buffer for stream %d\n", st->index); goto no_packet; } pd->buf = new_buf; - memcpy(pd->buf+pd->buf_size, pkt->data, pkt->size); + memcpy(pd->buf + pd->buf_size, pkt->data, pkt->size); pd->buf_size += pkt->size; - memset(pd->buf+pd->buf_size, 0, AVPROBE_PADDING_SIZE); + memset(pd->buf + pd->buf_size, 0, AVPROBE_PADDING_SIZE); } else { no_packet: st->probe_packets = 0; if (!pd->buf_size) { - av_log(s, AV_LOG_WARNING, "nothing to probe for stream %d\n", - st->index); + av_log(s, AV_LOG_WARNING, + "nothing to probe for stream %d\n", st->index); } } end= s->raw_packet_buffer_remaining_size <= 0 - || st->probe_packets<=0; + || st->probe_packets<= 0; - if(end || av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)){ - int score= set_codec_from_probe_data(s, st, pd); - if( (st->codec->codec_id != AV_CODEC_ID_NONE && score > AVPROBE_SCORE_RETRY) - || end){ - pd->buf_size=0; + if (end || av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)) { + int score = set_codec_from_probe_data(s, st, pd); + if ( (st->codec->codec_id != AV_CODEC_ID_NONE && score > AVPROBE_SCORE_STREAM_RETRY) + || end) { + pd->buf_size = 0; av_freep(&pd->buf); - st->request_probe= -1; - if(st->codec->codec_id != AV_CODEC_ID_NONE){ + st->request_probe = -1; + if (st->codec->codec_id != AV_CODEC_ID_NONE) { av_log(s, AV_LOG_DEBUG, "probed stream %d\n", st->index); - }else + } else av_log(s, AV_LOG_WARNING, "probed stream %d failed\n", st->index); } force_codec_ids(s, st); @@ -633,23 +675,86 @@ no_packet: return 0; } +static int update_wrap_reference(AVFormatContext *s, AVStream *st, int stream_index, AVPacket *pkt) +{ + int64_t ref = pkt->dts; + int i, pts_wrap_behavior; + int64_t pts_wrap_reference; + AVProgram *first_program; + + if (ref == AV_NOPTS_VALUE) + ref = pkt->pts; + if (st->pts_wrap_reference != AV_NOPTS_VALUE || st->pts_wrap_bits >= 63 || ref == AV_NOPTS_VALUE || !s->correct_ts_overflow) + return 0; + ref &= (1LL << st->pts_wrap_bits)-1; + + // reference time stamp should be 60 s before first time stamp + pts_wrap_reference = ref - av_rescale(60, st->time_base.den, st->time_base.num); + // if first time stamp is not more than 1/8 and 60s before the wrap point, subtract rather than add wrap offset + pts_wrap_behavior = (ref < (1LL << st->pts_wrap_bits) - (1LL << st->pts_wrap_bits-3)) || + (ref < (1LL << st->pts_wrap_bits) - av_rescale(60, st->time_base.den, st->time_base.num)) ? + AV_PTS_WRAP_ADD_OFFSET : AV_PTS_WRAP_SUB_OFFSET; + + first_program = av_find_program_from_stream(s, NULL, stream_index); + + if (!first_program) { + int default_stream_index = av_find_default_stream_index(s); + if (s->streams[default_stream_index]->pts_wrap_reference == AV_NOPTS_VALUE) { + for (i = 0; i < s->nb_streams; i++) { + s->streams[i]->pts_wrap_reference = pts_wrap_reference; + s->streams[i]->pts_wrap_behavior = pts_wrap_behavior; + } + } + else { + st->pts_wrap_reference = s->streams[default_stream_index]->pts_wrap_reference; + st->pts_wrap_behavior = s->streams[default_stream_index]->pts_wrap_behavior; + } + } + else { + AVProgram *program = first_program; + while (program) { + if (program->pts_wrap_reference != AV_NOPTS_VALUE) { + pts_wrap_reference = program->pts_wrap_reference; + pts_wrap_behavior = program->pts_wrap_behavior; + break; + } + program = av_find_program_from_stream(s, program, stream_index); + } + + // update every program with differing pts_wrap_reference + program = first_program; + while (program) { + if (program->pts_wrap_reference != pts_wrap_reference) { + for (i = 0; inb_stream_indexes; i++) { + s->streams[program->stream_index[i]]->pts_wrap_reference = pts_wrap_reference; + s->streams[program->stream_index[i]]->pts_wrap_behavior = pts_wrap_behavior; + } + + program->pts_wrap_reference = pts_wrap_reference; + program->pts_wrap_behavior = pts_wrap_behavior; + } + program = av_find_program_from_stream(s, program, stream_index); + } + } + return 1; +} + int ff_read_packet(AVFormatContext *s, AVPacket *pkt) { int ret, i, err; AVStream *st; - for(;;){ + for (;;) { AVPacketList *pktl = s->raw_packet_buffer; if (pktl) { *pkt = pktl->pkt; - st = s->streams[pkt->stream_index]; - if (s->raw_packet_buffer_remaining_size <= 0) { + st = s->streams[pkt->stream_index]; + if (s->raw_packet_buffer_remaining_size <= 0) if ((err = probe_codec(s, st, NULL)) < 0) return err; - } - if(st->request_probe <= 0){ - s->raw_packet_buffer = pktl->next; + if (st->request_probe <= 0) { + s->raw_packet_buffer = pktl->next; s->raw_packet_buffer_remaining_size += pkt->size; av_free(pktl); return 0; @@ -659,16 +764,15 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt) pkt->data = NULL; pkt->size = 0; av_init_packet(pkt); - ret= s->iformat->read_packet(s, pkt); + ret = s->iformat->read_packet(s, pkt); if (ret < 0) { if (!pktl || ret == AVERROR(EAGAIN)) return ret; for (i = 0; i < s->nb_streams; i++) { st = s->streams[i]; - if (st->probe_packets) { + if (st->probe_packets) if ((err = probe_codec(s, st, NULL)) < 0) return err; - } av_assert0(st->request_probe <= 0); } continue; @@ -683,15 +787,23 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt) continue; } - if(!(s->flags & AVFMT_FLAG_KEEP_SIDE_DATA)) - av_packet_merge_side_data(pkt); - - if(pkt->stream_index >= (unsigned)s->nb_streams){ + if (pkt->stream_index >= (unsigned)s->nb_streams) { av_log(s, AV_LOG_ERROR, "Invalid stream index %d\n", pkt->stream_index); continue; } - st= s->streams[pkt->stream_index]; + st = s->streams[pkt->stream_index]; + + if (update_wrap_reference(s, st, pkt->stream_index, pkt) && st->pts_wrap_behavior == AV_PTS_WRAP_SUB_OFFSET) { + // correct first time stamps to negative values + if (!is_relative(st->first_dts)) + st->first_dts = wrap_timestamp(st, st->first_dts); + if (!is_relative(st->start_time)) + st->start_time = wrap_timestamp(st, st->start_time); + if (!is_relative(st->cur_dts)) + st->cur_dts = wrap_timestamp(st, st->cur_dts); + } + pkt->dts = wrap_timestamp(st, pkt->dts); pkt->pts = wrap_timestamp(st, pkt->pts); @@ -701,7 +813,7 @@ int ff_read_packet(AVFormatContext *s, AVPacket *pkt) if (s->use_wallclock_as_timestamps) pkt->dts = pkt->pts = av_rescale_q(av_gettime(), AV_TIME_BASE_Q, st->time_base); - if(!pktl && st->request_probe <= 0) + if (!pktl && st->request_probe <= 0) return ret; add_to_pktbuf(&s->raw_packet_buffer, pkt, &s->raw_packet_buffer_end); @@ -753,7 +865,7 @@ int ff_get_audio_frame_size(AVCodecContext *enc, int size, int mux) //For WMA we currently have no other means to calculate duration thus we //do it here by assuming CBR, which is true for all known cases. - if(!mux && enc->bit_rate>0 && size>0 && enc->sample_rate>0 && enc->block_align>1) { + if (!mux && enc->bit_rate>0 && size>0 && enc->sample_rate>0 && enc->block_align>1) { if (enc->codec_id == AV_CODEC_ID_WMAV1 || enc->codec_id == AV_CODEC_ID_WMAV2) return ((int64_t)size * 8 * enc->sample_rate) / enc->bit_rate; } @@ -761,7 +873,6 @@ int ff_get_audio_frame_size(AVCodecContext *enc, int size, int mux) return -1; } - /** * Return the frame duration in seconds. Return 0 if not available. */ @@ -772,15 +883,15 @@ void ff_compute_frame_duration(int *pnum, int *pden, AVStream *st, *pnum = 0; *pden = 0; - switch(st->codec->codec_type) { + switch (st->codec->codec_type) { case AVMEDIA_TYPE_VIDEO: if (st->r_frame_rate.num && !pc) { *pnum = st->r_frame_rate.den; *pden = st->r_frame_rate.num; - } else if(st->time_base.num*1000LL > st->time_base.den) { + } else if (st->time_base.num * 1000LL > st->time_base.den) { *pnum = st->time_base.num; *pden = st->time_base.den; - }else if(st->codec->time_base.num*1000LL > st->codec->time_base.den){ + } else if (st->codec->time_base.num * 1000LL > st->codec->time_base.den) { *pnum = st->codec->time_base.num; *pden = st->codec->time_base.den; if (pc && pc->repeat_pict) { @@ -789,11 +900,11 @@ void ff_compute_frame_duration(int *pnum, int *pden, AVStream *st, else *pnum *= 1 + pc->repeat_pict; } - //If this codec can be interlaced or progressive then we need a parser to compute duration of a packet - //Thus if we have no parser in such case leave duration undefined. - if(st->codec->ticks_per_frame>1 && !pc){ + /* If this codec can be interlaced or progressive then we need + * a parser to compute duration of a packet. Thus if we have + * no parser in such case leave duration undefined. */ + if (st->codec->ticks_per_frame > 1 && !pc) *pnum = *pden = 0; - } } break; case AVMEDIA_TYPE_AUDIO: @@ -808,10 +919,10 @@ void ff_compute_frame_duration(int *pnum, int *pden, AVStream *st, } } -static int is_intra_only(AVCodecContext *enc){ +static int is_intra_only(AVCodecContext *enc) { const AVCodecDescriptor *desc; - if(enc->codec_type != AVMEDIA_TYPE_VIDEO) + if (enc->codec_type != AVMEDIA_TYPE_VIDEO) return 1; desc = av_codec_get_codec_descriptor(enc); @@ -826,17 +937,17 @@ static int is_intra_only(AVCodecContext *enc){ static int has_decode_delay_been_guessed(AVStream *st) { - if(st->codec->codec_id != AV_CODEC_ID_H264) return 1; - if(!st->info) // if we have left find_stream_info then nb_decoded_frames won't increase anymore for stream copy + if (st->codec->codec_id != AV_CODEC_ID_H264) return 1; + if (!st->info) // if we have left find_stream_info then nb_decoded_frames won't increase anymore for stream copy return 1; #if CONFIG_H264_DECODER - if(st->codec->has_b_frames && + if (st->codec->has_b_frames && avpriv_h264_has_num_reorder_frames(st->codec) == st->codec->has_b_frames) return 1; #endif - if(st->codec->has_b_frames<3) + if (st->codec->has_b_frames<3) return st->nb_decoded_frames >= 7; - else if(st->codec->has_b_frames<4) + else if (st->codec->has_b_frames<4) return st->nb_decoded_frames >= 18; else return st->nb_decoded_frames >= 20; @@ -846,123 +957,100 @@ static AVPacketList *get_next_pkt(AVFormatContext *s, AVStream *st, AVPacketList { if (pktl->next) return pktl->next; - if (pktl == s->parse_queue_end) - return s->packet_buffer; + if (pktl == s->packet_buffer_end) + return s->parse_queue; return NULL; } -static int update_wrap_reference(AVFormatContext *s, AVStream *st, int stream_index) -{ - if (s->correct_ts_overflow && st->pts_wrap_bits < 63 && - st->pts_wrap_reference == AV_NOPTS_VALUE && st->first_dts != AV_NOPTS_VALUE) { +static int64_t select_from_pts_buffer(AVStream *st, int64_t *pts_buffer, int64_t dts) { + int onein_oneout = st->codec->codec_id != AV_CODEC_ID_H264 && + st->codec->codec_id != AV_CODEC_ID_HEVC; + + if(!onein_oneout) { + int delay = st->codec->has_b_frames; int i; - // reference time stamp should be 60 s before first time stamp - int64_t pts_wrap_reference = st->first_dts - av_rescale(60, st->time_base.den, st->time_base.num); - // if first time stamp is not more than 1/8 and 60s before the wrap point, subtract rather than add wrap offset - int pts_wrap_behavior = (st->first_dts < (1LL<pts_wrap_bits) - (1LL<<(st->pts_wrap_bits-3))) || - (st->first_dts < (1LL<pts_wrap_bits) - av_rescale(60, st->time_base.den, st->time_base.num)) ? - AV_PTS_WRAP_ADD_OFFSET : AV_PTS_WRAP_SUB_OFFSET; - - AVProgram *first_program = av_find_program_from_stream(s, NULL, stream_index); - - if (!first_program) { - int default_stream_index = av_find_default_stream_index(s); - if (s->streams[default_stream_index]->pts_wrap_reference == AV_NOPTS_VALUE) { - for (i=0; inb_streams; i++) { - s->streams[i]->pts_wrap_reference = pts_wrap_reference; - s->streams[i]->pts_wrap_behavior = pts_wrap_behavior; - } - } - else { - st->pts_wrap_reference = s->streams[default_stream_index]->pts_wrap_reference; - st->pts_wrap_behavior = s->streams[default_stream_index]->pts_wrap_behavior; - } - } - else { - AVProgram *program = first_program; - while (program) { - if (program->pts_wrap_reference != AV_NOPTS_VALUE) { - pts_wrap_reference = program->pts_wrap_reference; - pts_wrap_behavior = program->pts_wrap_behavior; - break; - } - program = av_find_program_from_stream(s, program, stream_index); - } - - // update every program with differing pts_wrap_reference - program = first_program; - while(program) { - if (program->pts_wrap_reference != pts_wrap_reference) { - for (i=0; inb_stream_indexes; i++) { - s->streams[program->stream_index[i]]->pts_wrap_reference = pts_wrap_reference; - s->streams[program->stream_index[i]]->pts_wrap_behavior = pts_wrap_behavior; + if (dts == AV_NOPTS_VALUE) { + int64_t best_score = INT64_MAX; + for (i = 0; ipts_reorder_error_count[i]) { + int64_t score = st->pts_reorder_error[i] / st->pts_reorder_error_count[i]; + if (score < best_score) { + best_score = score; + dts = pts_buffer[i]; + } + } + } + } else { + for (i = 0; ipts_reorder_error[i]; + diff = FFMAX(diff, st->pts_reorder_error[i]); + st->pts_reorder_error[i] = diff; + st->pts_reorder_error_count[i]++; + if (st->pts_reorder_error_count[i] > 250) { + st->pts_reorder_error[i] >>= 1; + st->pts_reorder_error_count[i] >>= 1; } - - program->pts_wrap_reference = pts_wrap_reference; - program->pts_wrap_behavior = pts_wrap_behavior; } - program = av_find_program_from_stream(s, program, stream_index); } } - return 1; } - return 0; + + if (dts == AV_NOPTS_VALUE) + dts = pts_buffer[0]; + + return dts; } static void update_initial_timestamps(AVFormatContext *s, int stream_index, int64_t dts, int64_t pts, AVPacket *pkt) { - AVStream *st= s->streams[stream_index]; - AVPacketList *pktl= s->parse_queue ? s->parse_queue : s->packet_buffer; + AVStream *st = s->streams[stream_index]; + AVPacketList *pktl = s->packet_buffer ? s->packet_buffer : s->parse_queue; int64_t pts_buffer[MAX_REORDER_DELAY+1]; int64_t shift; int i, delay; - if(st->first_dts != AV_NOPTS_VALUE || dts == AV_NOPTS_VALUE || st->cur_dts == AV_NOPTS_VALUE || is_relative(dts)) + if (st->first_dts != AV_NOPTS_VALUE || + dts == AV_NOPTS_VALUE || + st->cur_dts == AV_NOPTS_VALUE || + is_relative(dts)) return; - delay = st->codec->has_b_frames; - st->first_dts= dts - (st->cur_dts - RELATIVE_TS_BASE); - st->cur_dts= dts; - shift = st->first_dts - RELATIVE_TS_BASE; + delay = st->codec->has_b_frames; + st->first_dts = dts - (st->cur_dts - RELATIVE_TS_BASE); + st->cur_dts = dts; + shift = st->first_dts - RELATIVE_TS_BASE; - for (i=0; ipkt.stream_index != stream_index) + for (; pktl; pktl = get_next_pkt(s, st, pktl)) { + if (pktl->pkt.stream_index != stream_index) continue; - if(is_relative(pktl->pkt.pts)) + if (is_relative(pktl->pkt.pts)) pktl->pkt.pts += shift; - if(is_relative(pktl->pkt.dts)) + if (is_relative(pktl->pkt.dts)) pktl->pkt.dts += shift; - if(st->start_time == AV_NOPTS_VALUE && pktl->pkt.pts != AV_NOPTS_VALUE) - st->start_time= pktl->pkt.pts; + if (st->start_time == AV_NOPTS_VALUE && pktl->pkt.pts != AV_NOPTS_VALUE) + st->start_time = pktl->pkt.pts; - if(pktl->pkt.pts != AV_NOPTS_VALUE && delay <= MAX_REORDER_DELAY && has_decode_delay_been_guessed(st)){ - pts_buffer[0]= pktl->pkt.pts; - for(i=0; i pts_buffer[i+1]; i++) - FFSWAP(int64_t, pts_buffer[i], pts_buffer[i+1]); - if(pktl->pkt.dts == AV_NOPTS_VALUE) - pktl->pkt.dts= pts_buffer[0]; + if (pktl->pkt.pts != AV_NOPTS_VALUE && delay <= MAX_REORDER_DELAY && has_decode_delay_been_guessed(st)) { + pts_buffer[0] = pktl->pkt.pts; + for (i = 0; i pts_buffer[i + 1]; i++) + FFSWAP(int64_t, pts_buffer[i], pts_buffer[i + 1]); + + pktl->pkt.dts = select_from_pts_buffer(st, pts_buffer, pktl->pkt.dts); } } - if (update_wrap_reference(s, st, stream_index) && st->pts_wrap_behavior == AV_PTS_WRAP_SUB_OFFSET) { - // correct first time stamps to negative values - st->first_dts = wrap_timestamp(st, st->first_dts); - st->cur_dts = wrap_timestamp(st, st->cur_dts); - pkt->dts = wrap_timestamp(st, pkt->dts); - pkt->pts = wrap_timestamp(st, pkt->pts); - pts = wrap_timestamp(st, pts); - } - if (st->start_time == AV_NOPTS_VALUE) st->start_time = pts; } @@ -970,47 +1058,54 @@ static void update_initial_timestamps(AVFormatContext *s, int stream_index, static void update_initial_durations(AVFormatContext *s, AVStream *st, int stream_index, int duration) { - AVPacketList *pktl= s->parse_queue ? s->parse_queue : s->packet_buffer; - int64_t cur_dts= RELATIVE_TS_BASE; + AVPacketList *pktl = s->packet_buffer ? s->packet_buffer : s->parse_queue; + int64_t cur_dts = RELATIVE_TS_BASE; - if(st->first_dts != AV_NOPTS_VALUE){ - cur_dts= st->first_dts; - for(; pktl; pktl= get_next_pkt(s, st, pktl)){ - if(pktl->pkt.stream_index == stream_index){ - if(pktl->pkt.pts != pktl->pkt.dts || pktl->pkt.dts != AV_NOPTS_VALUE || pktl->pkt.duration) + if (st->first_dts != AV_NOPTS_VALUE) { + if (st->update_initial_durations_done) + return; + st->update_initial_durations_done = 1; + cur_dts = st->first_dts; + for (; pktl; pktl = get_next_pkt(s, st, pktl)) { + if (pktl->pkt.stream_index == stream_index) { + if (pktl->pkt.pts != pktl->pkt.dts || + pktl->pkt.dts != AV_NOPTS_VALUE || + pktl->pkt.duration) break; cur_dts -= duration; } } - if(pktl && pktl->pkt.dts != st->first_dts) { - av_log(s, AV_LOG_DEBUG, "first_dts %s not matching first dts %s in the queue\n", av_ts2str(st->first_dts), av_ts2str(pktl->pkt.dts)); + if (pktl && pktl->pkt.dts != st->first_dts) { + av_log(s, AV_LOG_DEBUG, "first_dts %s not matching first dts %s (pts %s, duration %d) in the queue\n", + av_ts2str(st->first_dts), av_ts2str(pktl->pkt.dts), av_ts2str(pktl->pkt.pts), pktl->pkt.duration); return; } - if(!pktl) { + if (!pktl) { av_log(s, AV_LOG_DEBUG, "first_dts %s but no packet with dts in the queue\n", av_ts2str(st->first_dts)); return; } - pktl= s->parse_queue ? s->parse_queue : s->packet_buffer; + pktl = s->packet_buffer ? s->packet_buffer : s->parse_queue; st->first_dts = cur_dts; - }else if(st->cur_dts != RELATIVE_TS_BASE) + } else if (st->cur_dts != RELATIVE_TS_BASE) return; - for(; pktl; pktl= get_next_pkt(s, st, pktl)){ - if(pktl->pkt.stream_index != stream_index) + for (; pktl; pktl = get_next_pkt(s, st, pktl)) { + if (pktl->pkt.stream_index != stream_index) continue; - if(pktl->pkt.pts == pktl->pkt.dts && (pktl->pkt.dts == AV_NOPTS_VALUE || pktl->pkt.dts == st->first_dts) - && !pktl->pkt.duration){ - pktl->pkt.dts= cur_dts; - if(!st->codec->has_b_frames) - pktl->pkt.pts= cur_dts; + if (pktl->pkt.pts == pktl->pkt.dts && + (pktl->pkt.dts == AV_NOPTS_VALUE || pktl->pkt.dts == st->first_dts) && + !pktl->pkt.duration) { + pktl->pkt.dts = cur_dts; + if (!st->codec->has_b_frames) + pktl->pkt.pts = cur_dts; // if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO) pktl->pkt.duration = duration; - }else + } else break; cur_dts = pktl->pkt.dts + pktl->pkt.duration; } - if(!pktl) - st->cur_dts= cur_dts; + if (!pktl) + st->cur_dts = cur_dts; } static void compute_pkt_fields(AVFormatContext *s, AVStream *st, @@ -1018,23 +1113,49 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, { int num, den, presentation_delayed, delay, i; int64_t offset; + AVRational duration; + int onein_oneout = st->codec->codec_id != AV_CODEC_ID_H264 && + st->codec->codec_id != AV_CODEC_ID_HEVC; if (s->flags & AVFMT_FLAG_NOFILLIN) return; - if((s->flags & AVFMT_FLAG_IGNDTS) && pkt->pts != AV_NOPTS_VALUE) - pkt->dts= AV_NOPTS_VALUE; + if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && pkt->dts != AV_NOPTS_VALUE) { + if (pkt->dts == pkt->pts && st->last_dts_for_order_check != AV_NOPTS_VALUE) { + if (st->last_dts_for_order_check <= pkt->dts) { + st->dts_ordered++; + } else { + av_log(s, st->dts_misordered ? AV_LOG_DEBUG : AV_LOG_WARNING, + "DTS %"PRIi64" < %"PRIi64" out of order\n", + pkt->dts, + st->last_dts_for_order_check); + st->dts_misordered++; + } + if (st->dts_ordered + st->dts_misordered > 250) { + st->dts_ordered >>= 1; + st->dts_misordered >>= 1; + } + } - if (st->codec->codec_id != AV_CODEC_ID_H264 && pc && pc->pict_type == AV_PICTURE_TYPE_B) + st->last_dts_for_order_check = pkt->dts; + if (st->dts_ordered < 8*st->dts_misordered && pkt->dts == pkt->pts) + pkt->dts = AV_NOPTS_VALUE; + } + + if ((s->flags & AVFMT_FLAG_IGNDTS) && pkt->pts != AV_NOPTS_VALUE) + pkt->dts = AV_NOPTS_VALUE; + + if (pc && pc->pict_type == AV_PICTURE_TYPE_B + && !st->codec->has_b_frames) //FIXME Set low_delay = 0 when has_b_frames = 1 st->codec->has_b_frames = 1; /* do we have a video B-frame ? */ - delay= st->codec->has_b_frames; + delay = st->codec->has_b_frames; presentation_delayed = 0; /* XXX: need has_b_frame, but cannot get it if the codec is - not initialized */ + * not initialized */ if (delay && pc && pc->pict_type != AV_PICTURE_TYPE_B) presentation_delayed = 1; @@ -1042,69 +1163,64 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, if (pkt->pts != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && st->pts_wrap_bits < 63 && pkt->dts - (1LL << (st->pts_wrap_bits - 1)) > pkt->pts) { - if(is_relative(st->cur_dts) || pkt->dts - (1LL<<(st->pts_wrap_bits-1)) > st->cur_dts) { - pkt->dts -= 1LL<pts_wrap_bits; + if (is_relative(st->cur_dts) || pkt->dts - (1LL<<(st->pts_wrap_bits - 1)) > st->cur_dts) { + pkt->dts -= 1LL << st->pts_wrap_bits; } else - pkt->pts += 1LL<pts_wrap_bits; + pkt->pts += 1LL << st->pts_wrap_bits; } - // some mpeg2 in mpeg-ps lack dts (issue171 / input_file.mpg) - // we take the conservative approach and discard both - // Note, if this is misbehaving for a H.264 file then possibly presentation_delayed is not set correctly. - if(delay==1 && pkt->dts == pkt->pts && pkt->dts != AV_NOPTS_VALUE && presentation_delayed){ + /* Some MPEG-2 in MPEG-PS lack dts (issue #171 / input_file.mpg). + * We take the conservative approach and discard both. + * Note: If this is misbehaving for an H.264 file, then possibly + * presentation_delayed is not set correctly. */ + if (delay == 1 && pkt->dts == pkt->pts && + pkt->dts != AV_NOPTS_VALUE && presentation_delayed) { av_log(s, AV_LOG_DEBUG, "invalid dts/pts combination %"PRIi64"\n", pkt->dts); - if(strcmp(s->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2")) // otherwise we discard correct timestamps for vc1-wmapro.ism - pkt->dts= AV_NOPTS_VALUE; + if ( strcmp(s->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") + && strcmp(s->iformat->name, "flv")) // otherwise we discard correct timestamps for vc1-wmapro.ism + pkt->dts = AV_NOPTS_VALUE; } + duration = av_mul_q((AVRational) {pkt->duration, 1}, st->time_base); if (pkt->duration == 0) { ff_compute_frame_duration(&num, &den, st, pc, pkt); if (den && num) { - pkt->duration = av_rescale_rnd(1, num * (int64_t)st->time_base.den, den * (int64_t)st->time_base.num, AV_ROUND_DOWN); + duration = (AVRational) {num, den}; + pkt->duration = av_rescale_rnd(1, + num * (int64_t) st->time_base.den, + den * (int64_t) st->time_base.num, + AV_ROUND_DOWN); } } - if(pkt->duration != 0 && (s->packet_buffer || s->parse_queue)) + + if (pkt->duration != 0 && (s->packet_buffer || s->parse_queue)) update_initial_durations(s, st, pkt->stream_index, pkt->duration); - /* correct timestamps with byte offset if demuxers only have timestamps - on packet boundaries */ - if(pc && st->need_parsing == AVSTREAM_PARSE_TIMESTAMPS && pkt->size){ + /* Correct timestamps with byte offset if demuxers only have timestamps + * on packet boundaries */ + if (pc && st->need_parsing == AVSTREAM_PARSE_TIMESTAMPS && pkt->size) { /* this will estimate bitrate based on this frame's duration and size */ offset = av_rescale(pc->offset, pkt->duration, pkt->size); - if(pkt->pts != AV_NOPTS_VALUE) + if (pkt->pts != AV_NOPTS_VALUE) pkt->pts += offset; - if(pkt->dts != AV_NOPTS_VALUE) + if (pkt->dts != AV_NOPTS_VALUE) pkt->dts += offset; } - if (pc && pc->dts_sync_point >= 0) { - // we have synchronization info from the parser - int64_t den = st->codec->time_base.den * (int64_t) st->time_base.num; - if (den > 0) { - int64_t num = st->codec->time_base.num * (int64_t) st->time_base.den; - if (pkt->dts != AV_NOPTS_VALUE) { - // got DTS from the stream, update reference timestamp - st->reference_dts = pkt->dts - pc->dts_ref_dts_delta * num / den; - pkt->pts = pkt->dts + pc->pts_dts_delta * num / den; - } else if (st->reference_dts != AV_NOPTS_VALUE) { - // compute DTS based on reference timestamp - pkt->dts = st->reference_dts + pc->dts_ref_dts_delta * num / den; - pkt->pts = pkt->dts + pc->pts_dts_delta * num / den; - } - if (pc->dts_sync_point > 0) - st->reference_dts = pkt->dts; // new reference - } - } - /* This may be redundant, but it should not hurt. */ - if(pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts > pkt->dts) + if (pkt->dts != AV_NOPTS_VALUE && + pkt->pts != AV_NOPTS_VALUE && + pkt->pts > pkt->dts) presentation_delayed = 1; - av_dlog(NULL, "IN delayed:%d pts:%s, dts:%s cur_dts:%s st:%d pc:%p duration:%d\n", - presentation_delayed, av_ts2str(pkt->pts), av_ts2str(pkt->dts), av_ts2str(st->cur_dts), pkt->stream_index, pc, pkt->duration); - /* interpolate PTS and DTS if they are not present */ - //We skip H264 currently because delay and has_b_frames are not reliably set - if((delay==0 || (delay==1 && pc)) && st->codec->codec_id != AV_CODEC_ID_H264){ + av_dlog(NULL, + "IN delayed:%d pts:%s, dts:%s cur_dts:%s st:%d pc:%p duration:%d\n", + presentation_delayed, av_ts2str(pkt->pts), av_ts2str(pkt->dts), av_ts2str(st->cur_dts), + pkt->stream_index, pc, pkt->duration); + /* Interpolate PTS and DTS if they are not present. We skip H264 + * currently because delay and has_b_frames are not reliably set. */ + if ((delay == 0 || (delay == 1 && pc)) && + onein_oneout) { if (presentation_delayed) { /* DTS = decompression timestamp */ /* PTS = presentation timestamp */ @@ -1114,20 +1230,19 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, if (pkt->dts == AV_NOPTS_VALUE) pkt->dts = st->cur_dts; - /* this is tricky: the dts must be incremented by the duration - of the frame we are displaying, i.e. the last I- or P-frame */ + /* This is tricky: the dts must be incremented by the duration + * of the frame we are displaying, i.e. the last I- or P-frame. */ if (st->last_IP_duration == 0) st->last_IP_duration = pkt->duration; - if(pkt->dts != AV_NOPTS_VALUE) + if (pkt->dts != AV_NOPTS_VALUE) st->cur_dts = pkt->dts + st->last_IP_duration; - st->last_IP_duration = pkt->duration; - st->last_IP_pts= pkt->pts; - /* cannot compute PTS if not present (we can compute it only - by knowing the future */ + st->last_IP_duration = pkt->duration; + st->last_IP_pts = pkt->pts; + /* Cannot compute PTS if not present (we can compute it only + * by knowing the future. */ } else if (pkt->pts != AV_NOPTS_VALUE || pkt->dts != AV_NOPTS_VALUE || pkt->duration ) { - int duration = pkt->duration; /* presentation is not delayed : PTS and DTS are the same */ if (pkt->pts == AV_NOPTS_VALUE) @@ -1138,21 +1253,22 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, pkt->pts = st->cur_dts; pkt->dts = pkt->pts; if (pkt->pts != AV_NOPTS_VALUE) - st->cur_dts = pkt->pts + duration; + st->cur_dts = av_add_stable(st->time_base, pkt->pts, duration, 1); } } - if(pkt->pts != AV_NOPTS_VALUE && delay <= MAX_REORDER_DELAY && has_decode_delay_been_guessed(st)){ - st->pts_buffer[0]= pkt->pts; - for(i=0; ipts_buffer[i] > st->pts_buffer[i+1]; i++) - FFSWAP(int64_t, st->pts_buffer[i], st->pts_buffer[i+1]); - if(pkt->dts == AV_NOPTS_VALUE) - pkt->dts= st->pts_buffer[0]; + if (pkt->pts != AV_NOPTS_VALUE && delay <= MAX_REORDER_DELAY && has_decode_delay_been_guessed(st)) { + st->pts_buffer[0] = pkt->pts; + for (i = 0; ipts_buffer[i] > st->pts_buffer[i + 1]; i++) + FFSWAP(int64_t, st->pts_buffer[i], st->pts_buffer[i + 1]); + + pkt->dts = select_from_pts_buffer(st, st->pts_buffer, pkt->dts); } - if(st->codec->codec_id == AV_CODEC_ID_H264){ // we skipped it above so we try here - update_initial_timestamps(s, pkt->stream_index, pkt->dts, pkt->pts, pkt); // this should happen on the first packet - } - if(pkt->dts > st->cur_dts) + // We skipped it above so we try here. + if (!onein_oneout) + // This should happen on the first packet + update_initial_timestamps(s, pkt->stream_index, pkt->dts, pkt->pts, pkt); + if (pkt->dts > st->cur_dts) st->cur_dts = pkt->dts; av_dlog(NULL, "OUTdelayed:%d/%d pts:%s, dts:%s cur_dts:%s\n", @@ -1177,21 +1293,21 @@ static void free_packet_buffer(AVPacketList **pkt_buf, AVPacketList **pkt_buf_en } /** - * Parse a packet, add all split parts to parse_queue + * Parse a packet, add all split parts to parse_queue. * - * @param pkt packet to parse, NULL when flushing the parser at end of stream + * @param pkt Packet to parse, NULL when flushing the parser at end of stream. */ static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index) { AVPacket out_pkt = { 0 }, flush_pkt = { 0 }; - AVStream *st = s->streams[stream_index]; - uint8_t *data = pkt ? pkt->data : NULL; - int size = pkt ? pkt->size : 0; + AVStream *st = s->streams[stream_index]; + uint8_t *data = pkt ? pkt->data : NULL; + int size = pkt ? pkt->size : 0; int ret = 0, got_output = 0; if (!pkt) { av_init_packet(&flush_pkt); - pkt = &flush_pkt; + pkt = &flush_pkt; got_output = 1; } else if (!size && st->parser->flags & PARSER_FLAG_COMPLETE_FRAMES) { // preserve 0-size sync packets @@ -1202,7 +1318,7 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index) int len; av_init_packet(&out_pkt); - len = av_parser_parse2(st->parser, st->codec, + len = av_parser_parse2(st->parser, st->codec, &out_pkt.data, &out_pkt.size, data, size, pkt->pts, pkt->dts, pkt->pos); @@ -1220,18 +1336,19 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index) if (pkt->side_data) { out_pkt.side_data = pkt->side_data; out_pkt.side_data_elems = pkt->side_data_elems; - pkt->side_data = NULL; - pkt->side_data_elems = 0; + pkt->side_data = NULL; + pkt->side_data_elems = 0; } /* set the duration */ out_pkt.duration = 0; if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { if (st->codec->sample_rate > 0) { - out_pkt.duration = av_rescale_q_rnd(st->parser->duration, - (AVRational){ 1, st->codec->sample_rate }, - st->time_base, - AV_ROUND_DOWN); + out_pkt.duration = + av_rescale_q_rnd(st->parser->duration, + (AVRational) { 1, st->codec->sample_rate }, + st->time_base, + AV_ROUND_DOWN); } } else if (st->codec->time_base.num != 0 && st->codec->time_base.den != 0) { @@ -1242,11 +1359,11 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index) } out_pkt.stream_index = st->index; - out_pkt.pts = st->parser->pts; - out_pkt.dts = st->parser->dts; - out_pkt.pos = st->parser->pos; + out_pkt.pts = st->parser->pts; + out_pkt.dts = st->parser->dts; + out_pkt.pos = st->parser->pos; - if(st->need_parsing == AVSTREAM_PARSE_FULL_RAW) + if (st->need_parsing == AVSTREAM_PARSE_FULL_RAW) out_pkt.pos = st->parser->frame_offset; if (st->parser->key_frame == 1 || @@ -1254,14 +1371,14 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index) st->parser->pict_type == AV_PICTURE_TYPE_I)) out_pkt.flags |= AV_PKT_FLAG_KEY; - if(st->parser->key_frame == -1 && st->parser->pict_type==AV_PICTURE_TYPE_NONE && (pkt->flags&AV_PKT_FLAG_KEY)) + if (st->parser->key_frame == -1 && st->parser->pict_type ==AV_PICTURE_TYPE_NONE && (pkt->flags&AV_PKT_FLAG_KEY)) out_pkt.flags |= AV_PKT_FLAG_KEY; compute_pkt_fields(s, st, st->parser, &out_pkt); if (out_pkt.data == pkt->data && out_pkt.size == pkt->size) { - out_pkt.buf = pkt->buf; - pkt->buf = NULL; + out_pkt.buf = pkt->buf; + pkt->buf = NULL; #if FF_API_DESTRUCT_PACKET FF_DISABLE_DEPRECATION_WARNINGS out_pkt.destruct = pkt->destruct; @@ -1279,7 +1396,6 @@ FF_ENABLE_DEPRECATION_WARNINGS } } - /* end of the stream => close and free the parser */ if (pkt == &flush_pkt) { av_parser_close(st->parser); @@ -1297,8 +1413,8 @@ static int read_from_packet_buffer(AVPacketList **pkt_buffer, { AVPacketList *pktl; av_assert0(*pkt_buffer); - pktl = *pkt_buffer; - *pkt = pktl->pkt; + pktl = *pkt_buffer; + *pkt = pktl->pkt; *pkt_buffer = pktl->next; if (!pktl->next) *pkt_buffer_end = NULL; @@ -1322,7 +1438,7 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) if (ret == AVERROR(EAGAIN)) return ret; /* flush the parsers */ - for(i = 0; i < s->nb_streams; i++) { + for (i = 0; i < s->nb_streams; i++) { st = s->streams[i]; if (st->parser && st->need_parsing) parse_packet(s, NULL, st->index); @@ -1337,20 +1453,20 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) if (cur_pkt.pts != AV_NOPTS_VALUE && cur_pkt.dts != AV_NOPTS_VALUE && cur_pkt.pts < cur_pkt.dts) { - av_log(s, AV_LOG_WARNING, "Invalid timestamps stream=%d, pts=%s, dts=%s, size=%d\n", + av_log(s, AV_LOG_WARNING, + "Invalid timestamps stream=%d, pts=%s, dts=%s, size=%d\n", cur_pkt.stream_index, av_ts2str(cur_pkt.pts), av_ts2str(cur_pkt.dts), cur_pkt.size); } if (s->debug & FF_FDEBUG_TS) - av_log(s, AV_LOG_DEBUG, "ff_read_packet stream=%d, pts=%s, dts=%s, size=%d, duration=%d, flags=%d\n", + av_log(s, AV_LOG_DEBUG, + "ff_read_packet stream=%d, pts=%s, dts=%s, size=%d, duration=%d, flags=%d\n", cur_pkt.stream_index, av_ts2str(cur_pkt.pts), av_ts2str(cur_pkt.dts), - cur_pkt.size, - cur_pkt.duration, - cur_pkt.flags); + cur_pkt.size, cur_pkt.duration, cur_pkt.flags); if (st->need_parsing && !st->parser && !(s->flags & AVFMT_FLAG_NOPARSE)) { st->parser = av_parser_init(st->codec->codec_id); @@ -1360,13 +1476,12 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) avcodec_get_name(st->codec->codec_id)); /* no parser available: just output the raw packets */ st->need_parsing = AVSTREAM_PARSE_NONE; - } else if(st->need_parsing == AVSTREAM_PARSE_HEADERS) { + } else if (st->need_parsing == AVSTREAM_PARSE_HEADERS) st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES; - } else if(st->need_parsing == AVSTREAM_PARSE_FULL_ONCE) { + else if (st->need_parsing == AVSTREAM_PARSE_FULL_ONCE) st->parser->flags |= PARSER_FLAG_ONCE; - } else if(st->need_parsing == AVSTREAM_PARSE_FULL_RAW) { + else if (st->need_parsing == AVSTREAM_PARSE_FULL_RAW) st->parser->flags |= PARSER_FLAG_USE_CODEC_TS; - } } if (!st->need_parsing || !st->parser) { @@ -1376,7 +1491,8 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) if ((s->iformat->flags & AVFMT_GENERIC_INDEX) && (pkt->flags & AV_PKT_FLAG_KEY) && pkt->dts != AV_NOPTS_VALUE) { ff_reduce_index(s, st->index); - av_add_index_entry(st, pkt->pos, pkt->dts, 0, 0, AVINDEX_KEYFRAME); + av_add_index_entry(st, pkt->pos, pkt->dts, + 0, 0, AVINDEX_KEYFRAME); } got_packet = 1; } else if (st->discard < AVDISCARD_ALL) { @@ -1400,14 +1516,29 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) if (!got_packet && s->parse_queue) ret = read_from_packet_buffer(&s->parse_queue, &s->parse_queue_end, pkt); - if(s->debug & FF_FDEBUG_TS) - av_log(s, AV_LOG_DEBUG, "read_frame_internal stream=%d, pts=%s, dts=%s, size=%d, duration=%d, flags=%d\n", - pkt->stream_index, - av_ts2str(pkt->pts), - av_ts2str(pkt->dts), - pkt->size, - pkt->duration, - pkt->flags); + if (ret >= 0) { + AVStream *st = s->streams[pkt->stream_index]; + if (st->skip_samples) { + uint8_t *p = av_packet_new_side_data(pkt, AV_PKT_DATA_SKIP_SAMPLES, 10); + if (p) { + AV_WL32(p, st->skip_samples); + av_log(s, AV_LOG_DEBUG, "demuxer injecting skip %d\n", st->skip_samples); + } + st->skip_samples = 0; + } + } + + if (ret >= 0 && !(s->flags & AVFMT_FLAG_KEEP_SIDE_DATA)) + av_packet_merge_side_data(pkt); + + if (s->debug & FF_FDEBUG_TS) + av_log(s, AV_LOG_DEBUG, + "read_frame_internal stream=%d, pts=%s, dts=%s, " + "size=%d, duration=%d, flags=%d\n", + pkt->stream_index, + av_ts2str(pkt->pts), + av_ts2str(pkt->dts), + pkt->size, pkt->duration, pkt->flags); return ret; } @@ -1415,14 +1546,15 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) int av_read_frame(AVFormatContext *s, AVPacket *pkt) { const int genpts = s->flags & AVFMT_FLAG_GENPTS; - int eof = 0; + int eof = 0; int ret; AVStream *st; if (!genpts) { - ret = s->packet_buffer ? - read_from_packet_buffer(&s->packet_buffer, &s->packet_buffer_end, pkt) : - read_frame_internal(s, pkt); + ret = s->packet_buffer + ? read_from_packet_buffer(&s->packet_buffer, + &s->packet_buffer_end, pkt) + : read_frame_internal(s, pkt); if (ret < 0) return ret; goto return_packet; @@ -1442,7 +1574,8 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt) while (pktl && next_pkt->pts == AV_NOPTS_VALUE) { if (pktl->pkt.stream_index == next_pkt->stream_index && (av_compare_mod(next_pkt->dts, pktl->pkt.dts, 2LL << (wrap_bits - 1)) < 0)) { - if (av_compare_mod(pktl->pkt.pts, pktl->pkt.dts, 2LL << (wrap_bits - 1))) { //not b frame + if (av_compare_mod(pktl->pkt.pts, pktl->pkt.dts, 2LL << (wrap_bits - 1))) { + // not B-frame next_pkt->pts = pktl->pkt.dts; } if (last_dts != AV_NOPTS_VALUE) { @@ -1482,20 +1615,13 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt) } if (av_dup_packet(add_to_pktbuf(&s->packet_buffer, pkt, - &s->packet_buffer_end)) < 0) + &s->packet_buffer_end)) < 0) return AVERROR(ENOMEM); } return_packet: st = s->streams[pkt->stream_index]; - if (st->skip_samples) { - uint8_t *p = av_packet_new_side_data(pkt, AV_PKT_DATA_SKIP_SAMPLES, 10); - AV_WL32(p, st->skip_samples); - av_log(s, AV_LOG_DEBUG, "demuxer injecting skip %d\n", st->skip_samples); - st->skip_samples = 0; - } - if ((s->iformat->flags & AVFMT_GENERIC_INDEX) && pkt->flags & AV_PKT_FLAG_KEY) { ff_reduce_index(s, st->index); av_add_index_entry(st, pkt->pos, pkt->dts, 0, 0, AVINDEX_KEYFRAME); @@ -1530,21 +1656,20 @@ int av_find_default_stream_index(AVFormatContext *s) if (s->nb_streams <= 0) return -1; - for(i = 0; i < s->nb_streams; i++) { + for (i = 0; i < s->nb_streams; i++) { st = s->streams[i]; if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && !(st->disposition & AV_DISPOSITION_ATTACHED_PIC)) { return i; } - if (first_audio_index < 0 && st->codec->codec_type == AVMEDIA_TYPE_AUDIO) + if (first_audio_index < 0 && + st->codec->codec_type == AVMEDIA_TYPE_AUDIO) first_audio_index = i; } return first_audio_index >= 0 ? first_audio_index : 0; } -/** - * Flush the frame reader. - */ +/** Flush the frame reader. */ void ff_read_frame_flush(AVFormatContext *s) { AVStream *st; @@ -1552,8 +1677,8 @@ void ff_read_frame_flush(AVFormatContext *s) flush_packet_queue(s); - /* for each stream, reset read state */ - for(i = 0; i < s->nb_streams; i++) { + /* Reset read state for each stream. */ + for (i = 0; i < s->nb_streams; i++) { st = s->streams[i]; if (st->parser) { @@ -1561,14 +1686,17 @@ void ff_read_frame_flush(AVFormatContext *s) st->parser = NULL; } st->last_IP_pts = AV_NOPTS_VALUE; - if(st->first_dts == AV_NOPTS_VALUE) st->cur_dts = RELATIVE_TS_BASE; - else st->cur_dts = AV_NOPTS_VALUE; /* we set the current DTS to an unspecified origin */ - st->reference_dts = AV_NOPTS_VALUE; + st->last_dts_for_order_check = AV_NOPTS_VALUE; + if (st->first_dts == AV_NOPTS_VALUE) + st->cur_dts = RELATIVE_TS_BASE; + else + /* We set the current DTS to an unspecified origin. */ + st->cur_dts = AV_NOPTS_VALUE; st->probe_packets = MAX_PROBE_PACKETS; - for(j=0; jpts_buffer[j]= AV_NOPTS_VALUE; + for (j = 0; j < MAX_REORDER_DELAY + 1; j++) + st->pts_buffer[j] = AV_NOPTS_VALUE; } } @@ -1576,40 +1704,45 @@ void ff_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp) { int i; - for(i = 0; i < s->nb_streams; i++) { + for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; - st->cur_dts = av_rescale(timestamp, - st->time_base.den * (int64_t)ref_st->time_base.num, - st->time_base.num * (int64_t)ref_st->time_base.den); + st->cur_dts = + av_rescale(timestamp, + st->time_base.den * (int64_t) ref_st->time_base.num, + st->time_base.num * (int64_t) ref_st->time_base.den); } } void ff_reduce_index(AVFormatContext *s, int stream_index) { - AVStream *st= s->streams[stream_index]; - unsigned int max_entries= s->max_index_size / sizeof(AVIndexEntry); + AVStream *st = s->streams[stream_index]; + unsigned int max_entries = s->max_index_size / sizeof(AVIndexEntry); - if((unsigned)st->nb_index_entries >= max_entries){ + if ((unsigned) st->nb_index_entries >= max_entries) { int i; - for(i=0; 2*inb_index_entries; i++) - st->index_entries[i]= st->index_entries[2*i]; - st->nb_index_entries= i; + for (i = 0; 2 * i < st->nb_index_entries; i++) + st->index_entries[i] = st->index_entries[2 * i]; + st->nb_index_entries = i; } } int ff_add_index_entry(AVIndexEntry **index_entries, int *nb_index_entries, unsigned int *index_entries_allocated_size, - int64_t pos, int64_t timestamp, int size, int distance, int flags) + int64_t pos, int64_t timestamp, + int size, int distance, int flags) { AVIndexEntry *entries, *ie; int index; - if((unsigned)*nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry)) + if ((unsigned) *nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry)) return -1; - if(timestamp == AV_NOPTS_VALUE) + if (timestamp == AV_NOPTS_VALUE) + return AVERROR(EINVAL); + + if (size < 0 || size > 0x3FFFFFFF) return AVERROR(EINVAL); if (is_relative(timestamp)) //FIXME this maintains previous behavior but we should shift by the correct offset once known @@ -1619,39 +1752,42 @@ int ff_add_index_entry(AVIndexEntry **index_entries, index_entries_allocated_size, (*nb_index_entries + 1) * sizeof(AVIndexEntry)); - if(!entries) + if (!entries) return -1; - *index_entries= entries; + *index_entries = entries; - index= ff_index_search_timestamp(*index_entries, *nb_index_entries, timestamp, AVSEEK_FLAG_ANY); + index = ff_index_search_timestamp(*index_entries, *nb_index_entries, + timestamp, AVSEEK_FLAG_ANY); - if(index<0){ - index= (*nb_index_entries)++; - ie= &entries[index]; - av_assert0(index==0 || ie[-1].timestamp < timestamp); - }else{ - ie= &entries[index]; - if(ie->timestamp != timestamp){ - if(ie->timestamp <= timestamp) + if (index < 0) { + index = (*nb_index_entries)++; + ie = &entries[index]; + av_assert0(index == 0 || ie[-1].timestamp < timestamp); + } else { + ie = &entries[index]; + if (ie->timestamp != timestamp) { + if (ie->timestamp <= timestamp) return -1; - memmove(entries + index + 1, entries + index, sizeof(AVIndexEntry)*(*nb_index_entries - index)); + memmove(entries + index + 1, entries + index, + sizeof(AVIndexEntry) * (*nb_index_entries - index)); (*nb_index_entries)++; - }else if(ie->pos == pos && distance < ie->min_distance) //do not reduce the distance - distance= ie->min_distance; + } else if (ie->pos == pos && distance < ie->min_distance) + // do not reduce the distance + distance = ie->min_distance; } - ie->pos = pos; - ie->timestamp = timestamp; - ie->min_distance= distance; - ie->size= size; - ie->flags = flags; + ie->pos = pos; + ie->timestamp = timestamp; + ie->min_distance = distance; + ie->size = size; + ie->flags = flags; return index; } -int av_add_index_entry(AVStream *st, - int64_t pos, int64_t timestamp, int size, int distance, int flags) +int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, + int size, int distance, int flags) { timestamp = wrap_timestamp(st, timestamp); return ff_add_index_entry(&st->index_entries, &st->nb_index_entries, @@ -1665,36 +1801,34 @@ int ff_index_search_timestamp(const AVIndexEntry *entries, int nb_entries, int a, b, m; int64_t timestamp; - a = - 1; + a = -1; b = nb_entries; - //optimize appending index entries at the end - if(b && entries[b-1].timestamp < wanted_timestamp) - a= b-1; + // Optimize appending index entries at the end. + if (b && entries[b - 1].timestamp < wanted_timestamp) + a = b - 1; while (b - a > 1) { - m = (a + b) >> 1; + m = (a + b) >> 1; timestamp = entries[m].timestamp; - if(timestamp >= wanted_timestamp) + if (timestamp >= wanted_timestamp) b = m; - if(timestamp <= wanted_timestamp) + if (timestamp <= wanted_timestamp) a = m; } - m= (flags & AVSEEK_FLAG_BACKWARD) ? a : b; + m = (flags & AVSEEK_FLAG_BACKWARD) ? a : b; - if(!(flags & AVSEEK_FLAG_ANY)){ - while(m>=0 && m= 0 && m < nb_entries && + !(entries[m].flags & AVINDEX_KEYFRAME)) m += (flags & AVSEEK_FLAG_BACKWARD) ? -1 : 1; - } - } - if(m == nb_entries) + if (m == nb_entries) return -1; - return m; + return m; } -int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp, - int flags) +int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp, int flags) { return ff_index_search_timestamp(st->index_entries, st->nb_index_entries, wanted_timestamp, flags); @@ -1709,9 +1843,10 @@ static int64_t ff_read_timestamp(AVFormatContext *s, int stream_index, int64_t * return ts; } -int ff_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags) +int ff_seek_frame_binary(AVFormatContext *s, int stream_index, + int64_t target_ts, int flags) { - AVInputFormat *avif= s->iformat; + AVInputFormat *avif = s->iformat; int64_t av_uninit(pos_min), av_uninit(pos_max), pos, pos_limit; int64_t ts_min, ts_max, ts; int index; @@ -1723,42 +1858,47 @@ int ff_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts av_dlog(s, "read_seek: %d %s\n", stream_index, av_ts2str(target_ts)); - ts_max= - ts_min= AV_NOPTS_VALUE; - pos_limit= -1; //gcc falsely says it may be uninitialized + ts_max = + ts_min = AV_NOPTS_VALUE; + pos_limit = -1; // GCC falsely says it may be uninitialized. - st= s->streams[stream_index]; - if(st->index_entries){ + st = s->streams[stream_index]; + if (st->index_entries) { AVIndexEntry *e; - index= av_index_search_timestamp(st, target_ts, flags | AVSEEK_FLAG_BACKWARD); //FIXME whole func must be checked for non-keyframe entries in index case, especially read_timestamp() - index= FFMAX(index, 0); - e= &st->index_entries[index]; + /* FIXME: Whole function must be checked for non-keyframe entries in + * index case, especially read_timestamp(). */ + index = av_index_search_timestamp(st, target_ts, + flags | AVSEEK_FLAG_BACKWARD); + index = FFMAX(index, 0); + e = &st->index_entries[index]; - if(e->timestamp <= target_ts || e->pos == e->min_distance){ - pos_min= e->pos; - ts_min= e->timestamp; + if (e->timestamp <= target_ts || e->pos == e->min_distance) { + pos_min = e->pos; + ts_min = e->timestamp; av_dlog(s, "using cached pos_min=0x%"PRIx64" dts_min=%s\n", pos_min, av_ts2str(ts_min)); - }else{ - av_assert1(index==0); + } else { + av_assert1(index == 0); } - index= av_index_search_timestamp(st, target_ts, flags & ~AVSEEK_FLAG_BACKWARD); + index = av_index_search_timestamp(st, target_ts, + flags & ~AVSEEK_FLAG_BACKWARD); av_assert0(index < st->nb_index_entries); - if(index >= 0){ - e= &st->index_entries[index]; + if (index >= 0) { + e = &st->index_entries[index]; av_assert1(e->timestamp >= target_ts); - pos_max= e->pos; - ts_max= e->timestamp; - pos_limit= pos_max - e->min_distance; - av_dlog(s, "using cached pos_max=0x%"PRIx64" pos_limit=0x%"PRIx64" dts_max=%s\n", - pos_max, pos_limit, av_ts2str(ts_max)); + pos_max = e->pos; + ts_max = e->timestamp; + pos_limit = pos_max - e->min_distance; + av_dlog(s, "using cached pos_max=0x%"PRIx64" pos_limit=0x%"PRIx64 + " dts_max=%s\n", pos_max, pos_limit, av_ts2str(ts_max)); } } - pos= ff_gen_search(s, stream_index, target_ts, pos_min, pos_max, pos_limit, ts_min, ts_max, flags, &ts, avif->read_timestamp); - if(pos<0) + pos = ff_gen_search(s, stream_index, target_ts, pos_min, pos_max, pos_limit, + ts_min, ts_max, flags, &ts, avif->read_timestamp); + if (pos < 0) return -1; /* do the seek */ @@ -1774,28 +1914,30 @@ int ff_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts int ff_find_last_ts(AVFormatContext *s, int stream_index, int64_t *ts, int64_t *pos, int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t )) { - int64_t step= 1024; + int64_t step = 1024; int64_t limit, ts_max; int64_t filesize = avio_size(s->pb); - int64_t pos_max = filesize - 1; - do{ + int64_t pos_max = filesize - 1; + do { limit = pos_max; pos_max = FFMAX(0, (pos_max) - step); - ts_max = ff_read_timestamp(s, stream_index, &pos_max, limit, read_timestamp); - step += step; - }while(ts_max == AV_NOPTS_VALUE && 2*limit > step); + ts_max = ff_read_timestamp(s, stream_index, + &pos_max, limit, read_timestamp); + step += step; + } while (ts_max == AV_NOPTS_VALUE && 2*limit > step); if (ts_max == AV_NOPTS_VALUE) return -1; - for(;;){ + for (;;) { int64_t tmp_pos = pos_max + 1; - int64_t tmp_ts = ff_read_timestamp(s, stream_index, &tmp_pos, INT64_MAX, read_timestamp); - if(tmp_ts == AV_NOPTS_VALUE) + int64_t tmp_ts = ff_read_timestamp(s, stream_index, + &tmp_pos, INT64_MAX, read_timestamp); + if (tmp_ts == AV_NOPTS_VALUE) break; av_assert0(tmp_pos > pos_max); ts_max = tmp_ts; pos_max = tmp_pos; - if(tmp_pos >= filesize) + if (tmp_pos >= filesize) break; } @@ -1809,8 +1951,10 @@ int ff_find_last_ts(AVFormatContext *s, int stream_index, int64_t *ts, int64_t * int64_t ff_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, int64_t pos_min, int64_t pos_max, int64_t pos_limit, - int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret, - int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t )) + int64_t ts_min, int64_t ts_max, + int flags, int64_t *ts_ret, + int64_t (*read_timestamp)(struct AVFormatContext *, int, + int64_t *, int64_t)) { int64_t pos, ts; int64_t start_pos; @@ -1819,107 +1963,114 @@ int64_t ff_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, av_dlog(s, "gen_seek: %d %s\n", stream_index, av_ts2str(target_ts)); - if(ts_min == AV_NOPTS_VALUE){ + if (ts_min == AV_NOPTS_VALUE) { pos_min = s->data_offset; - ts_min = ff_read_timestamp(s, stream_index, &pos_min, INT64_MAX, read_timestamp); + ts_min = ff_read_timestamp(s, stream_index, &pos_min, INT64_MAX, read_timestamp); if (ts_min == AV_NOPTS_VALUE) return -1; } - if(ts_min >= target_ts){ - *ts_ret= ts_min; + if (ts_min >= target_ts) { + *ts_ret = ts_min; return pos_min; } - if(ts_max == AV_NOPTS_VALUE){ + if (ts_max == AV_NOPTS_VALUE) { if ((ret = ff_find_last_ts(s, stream_index, &ts_max, &pos_max, read_timestamp)) < 0) return ret; - pos_limit= pos_max; + pos_limit = pos_max; } - if(ts_max <= target_ts){ - *ts_ret= ts_max; + if (ts_max <= target_ts) { + *ts_ret = ts_max; return pos_max; } - if(ts_min > ts_max){ + if (ts_min > ts_max) return -1; - }else if(ts_min == ts_max){ - pos_limit= pos_min; - } + else if (ts_min == ts_max) + pos_limit = pos_min; - no_change=0; + no_change = 0; while (pos_min < pos_limit) { - av_dlog(s, "pos_min=0x%"PRIx64" pos_max=0x%"PRIx64" dts_min=%s dts_max=%s\n", + av_dlog(s, + "pos_min=0x%"PRIx64" pos_max=0x%"PRIx64" dts_min=%s dts_max=%s\n", pos_min, pos_max, av_ts2str(ts_min), av_ts2str(ts_max)); assert(pos_limit <= pos_max); - if(no_change==0){ - int64_t approximate_keyframe_distance= pos_max - pos_limit; + if (no_change == 0) { + int64_t approximate_keyframe_distance = pos_max - pos_limit; // interpolate position (better than dichotomy) - pos = av_rescale(target_ts - ts_min, pos_max - pos_min, ts_max - ts_min) - + pos_min - approximate_keyframe_distance; - }else if(no_change==1){ - // bisection, if interpolation failed to change min or max pos last time - pos = (pos_min + pos_limit)>>1; - }else{ + pos = av_rescale(target_ts - ts_min, pos_max - pos_min, + ts_max - ts_min) + + pos_min - approximate_keyframe_distance; + } else if (no_change == 1) { + // bisection if interpolation did not change min / max pos last time + pos = (pos_min + pos_limit) >> 1; + } else { /* linear search if bisection failed, can only happen if there - are very few or no keyframes between min/max */ - pos=pos_min; + * are very few or no keyframes between min/max */ + pos = pos_min; } - if(pos <= pos_min) - pos= pos_min + 1; - else if(pos > pos_limit) - pos= pos_limit; - start_pos= pos; + if (pos <= pos_min) + pos = pos_min + 1; + else if (pos > pos_limit) + pos = pos_limit; + start_pos = pos; - ts = ff_read_timestamp(s, stream_index, &pos, INT64_MAX, read_timestamp); //may pass pos_limit instead of -1 - if(pos == pos_max) + // May pass pos_limit instead of -1. + ts = ff_read_timestamp(s, stream_index, &pos, INT64_MAX, read_timestamp); + if (pos == pos_max) no_change++; else - no_change=0; - av_dlog(s, "%"PRId64" %"PRId64" %"PRId64" / %s %s %s target:%s limit:%"PRId64" start:%"PRId64" noc:%d\n", + no_change = 0; + av_dlog(s, "%"PRId64" %"PRId64" %"PRId64" / %s %s %s" + " target:%s limit:%"PRId64" start:%"PRId64" noc:%d\n", pos_min, pos, pos_max, av_ts2str(ts_min), av_ts2str(ts), av_ts2str(ts_max), av_ts2str(target_ts), pos_limit, start_pos, no_change); - if(ts == AV_NOPTS_VALUE){ + if (ts == AV_NOPTS_VALUE) { av_log(s, AV_LOG_ERROR, "read_timestamp() failed in the middle\n"); return -1; } assert(ts != AV_NOPTS_VALUE); if (target_ts <= ts) { pos_limit = start_pos - 1; - pos_max = pos; - ts_max = ts; + pos_max = pos; + ts_max = ts; } if (target_ts >= ts) { pos_min = pos; - ts_min = ts; + ts_min = ts; } } - pos = (flags & AVSEEK_FLAG_BACKWARD) ? pos_min : pos_max; - ts = (flags & AVSEEK_FLAG_BACKWARD) ? ts_min : ts_max; + pos = (flags & AVSEEK_FLAG_BACKWARD) ? pos_min : pos_max; + ts = (flags & AVSEEK_FLAG_BACKWARD) ? ts_min : ts_max; #if 0 pos_min = pos; - ts_min = ff_read_timestamp(s, stream_index, &pos_min, INT64_MAX, read_timestamp); + ts_min = ff_read_timestamp(s, stream_index, &pos_min, INT64_MAX, read_timestamp); pos_min++; ts_max = ff_read_timestamp(s, stream_index, &pos_min, INT64_MAX, read_timestamp); av_dlog(s, "pos=0x%"PRIx64" %s<=%s<=%s\n", pos, av_ts2str(ts_min), av_ts2str(target_ts), av_ts2str(ts_max)); #endif - *ts_ret= ts; + *ts_ret = ts; return pos; } -static int seek_frame_byte(AVFormatContext *s, int stream_index, int64_t pos, int flags){ +static int seek_frame_byte(AVFormatContext *s, int stream_index, + int64_t pos, int flags) +{ int64_t pos_min, pos_max; pos_min = s->data_offset; pos_max = avio_size(s->pb) - 1; - if (pos < pos_min) pos= pos_min; - else if(pos > pos_max) pos= pos_max; + if (pos < pos_min) + pos = pos_min; + else if (pos > pos_max) + pos = pos_max; avio_seek(s->pb, pos, SEEK_SET); @@ -1928,8 +2079,8 @@ static int seek_frame_byte(AVFormatContext *s, int stream_index, int64_t pos, in return 0; } -static int seek_frame_generic(AVFormatContext *s, - int stream_index, int64_t timestamp, int flags) +static int seek_frame_generic(AVFormatContext *s, int stream_index, + int64_t timestamp, int flags) { int index; int64_t ret; @@ -1940,35 +2091,36 @@ static int seek_frame_generic(AVFormatContext *s, index = av_index_search_timestamp(st, timestamp, flags); - if(index < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp) + if (index < 0 && st->nb_index_entries && + timestamp < st->index_entries[0].timestamp) return -1; - if(index < 0 || index==st->nb_index_entries-1){ + if (index < 0 || index == st->nb_index_entries - 1) { AVPacket pkt; - int nonkey=0; + int nonkey = 0; - if(st->nb_index_entries){ + if (st->nb_index_entries) { av_assert0(st->index_entries); - ie= &st->index_entries[st->nb_index_entries-1]; + ie = &st->index_entries[st->nb_index_entries - 1]; if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0) return ret; ff_update_cur_dts(s, st, ie->timestamp); - }else{ + } else { if ((ret = avio_seek(s->pb, s->data_offset, SEEK_SET)) < 0) return ret; } for (;;) { int read_status; - do{ + do { read_status = av_read_frame(s, &pkt); } while (read_status == AVERROR(EAGAIN)); if (read_status < 0) break; av_free_packet(&pkt); - if(stream_index == pkt.stream_index && pkt.dts > timestamp){ - if(pkt.flags & AV_PKT_FLAG_KEY) + if (stream_index == pkt.stream_index && pkt.dts > timestamp) { + if (pkt.flags & AV_PKT_FLAG_KEY) break; - if(nonkey++ > 1000 && st->codec->codec_id != AV_CODEC_ID_CDGRAPHICS){ + if (nonkey++ > 1000 && st->codec->codec_id != AV_CODEC_ID_CDGRAPHICS) { av_log(s, AV_LOG_ERROR,"seek_frame_generic failed as this stream seems to contain no keyframes after the target timestamp, %d non keyframes found\n", nonkey); break; } @@ -1980,10 +2132,9 @@ static int seek_frame_generic(AVFormatContext *s, return -1; ff_read_frame_flush(s); - if (s->iformat->read_seek){ - if(s->iformat->read_seek(s, stream_index, timestamp, flags) >= 0) + if (s->iformat->read_seek) + if (s->iformat->read_seek(s, stream_index, timestamp, flags) >= 0) return 0; - } ie = &st->index_entries[index]; if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0) return ret; @@ -2005,14 +2156,15 @@ static int seek_frame_internal(AVFormatContext *s, int stream_index, return seek_frame_byte(s, stream_index, timestamp, flags); } - if(stream_index < 0){ - stream_index= av_find_default_stream_index(s); - if(stream_index < 0) + if (stream_index < 0) { + stream_index = av_find_default_stream_index(s); + if (stream_index < 0) return -1; - st= s->streams[stream_index]; + st = s->streams[stream_index]; /* timestamp for default must be expressed in AV_TIME_BASE units */ - timestamp = av_rescale(timestamp, st->time_base.den, AV_TIME_BASE * (int64_t)st->time_base.num); + timestamp = av_rescale(timestamp, st->time_base.den, + AV_TIME_BASE * (int64_t) st->time_base.num); } /* first, we try the format specific seek */ @@ -2021,22 +2173,22 @@ static int seek_frame_internal(AVFormatContext *s, int stream_index, ret = s->iformat->read_seek(s, stream_index, timestamp, flags); } else ret = -1; - if (ret >= 0) { + if (ret >= 0) return 0; - } - if (s->iformat->read_timestamp && !(s->iformat->flags & AVFMT_NOBINSEARCH)) { + if (s->iformat->read_timestamp && + !(s->iformat->flags & AVFMT_NOBINSEARCH)) { ff_read_frame_flush(s); return ff_seek_frame_binary(s, stream_index, timestamp, flags); } else if (!(s->iformat->flags & AVFMT_NOGENSEARCH)) { ff_read_frame_flush(s); return seek_frame_generic(s, stream_index, timestamp, flags); - } - else + } else return -1; } -int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) +int av_seek_frame(AVFormatContext *s, int stream_index, + int64_t timestamp, int flags) { int ret; @@ -2058,14 +2210,15 @@ int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int f return ret; } -int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags) +int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, + int64_t ts, int64_t max_ts, int flags) { - if(min_ts > ts || max_ts < ts) + if (min_ts > ts || max_ts < ts) return -1; if (stream_index < -1 || stream_index >= (int)s->nb_streams) return AVERROR(EINVAL); - if(s->seek2any>0) + if (s->seek2any>0) flags |= AVSEEK_FLAG_ANY; flags &= ~AVSEEK_FLAG_BACKWARD; @@ -2084,15 +2237,16 @@ int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int AV_ROUND_DOWN | AV_ROUND_PASS_MINMAX); } - ret = s->iformat->read_seek2(s, stream_index, min_ts, ts, max_ts, flags); + ret = s->iformat->read_seek2(s, stream_index, min_ts, + ts, max_ts, flags); if (ret >= 0) ret = avformat_queue_attached_pictures(s); return ret; } - if(s->iformat->read_timestamp){ - //try to seek via read_timestamp() + if (s->iformat->read_timestamp) { + // try to seek via read_timestamp() } // Fall back on old API if new is not implemented but old is. @@ -2124,7 +2278,7 @@ static int has_duration(AVFormatContext *ic) int i; AVStream *st; - for(i = 0;i < ic->nb_streams; i++) { + for (i = 0; i < ic->nb_streams; i++) { st = ic->streams[i]; if (st->duration != AV_NOPTS_VALUE) return 1; @@ -2149,47 +2303,50 @@ static void update_stream_timings(AVFormatContext *ic) start_time = INT64_MAX; start_time_text = INT64_MAX; - end_time = INT64_MIN; - duration = INT64_MIN; - for(i = 0;i < ic->nb_streams; i++) { + end_time = INT64_MIN; + duration = INT64_MIN; + for (i = 0; i < ic->nb_streams; i++) { st = ic->streams[i]; if (st->start_time != AV_NOPTS_VALUE && st->time_base.den) { - start_time1= av_rescale_q(st->start_time, st->time_base, AV_TIME_BASE_Q); + start_time1 = av_rescale_q(st->start_time, st->time_base, + AV_TIME_BASE_Q); if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE || st->codec->codec_type == AVMEDIA_TYPE_DATA) { if (start_time1 < start_time_text) start_time_text = start_time1; } else start_time = FFMIN(start_time, start_time1); - end_time1 = AV_NOPTS_VALUE; + end_time1 = AV_NOPTS_VALUE; if (st->duration != AV_NOPTS_VALUE) { - end_time1 = start_time1 - + av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q); + end_time1 = start_time1 + + av_rescale_q(st->duration, st->time_base, + AV_TIME_BASE_Q); end_time = FFMAX(end_time, end_time1); } - for(p = NULL; (p = av_find_program_from_stream(ic, p, i)); ){ - if(p->start_time == AV_NOPTS_VALUE || p->start_time > start_time1) + for (p = NULL; (p = av_find_program_from_stream(ic, p, i)); ) { + if (p->start_time == AV_NOPTS_VALUE || p->start_time > start_time1) p->start_time = start_time1; - if(p->end_time < end_time1) + if (p->end_time < end_time1) p->end_time = end_time1; } } if (st->duration != AV_NOPTS_VALUE) { - duration1 = av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q); - duration = FFMAX(duration, duration1); + duration1 = av_rescale_q(st->duration, st->time_base, + AV_TIME_BASE_Q); + duration = FFMAX(duration, duration1); } } if (start_time == INT64_MAX || (start_time > start_time_text && start_time - start_time_text < AV_TIME_BASE)) start_time = start_time_text; - else if(start_time > start_time_text) + else if (start_time > start_time_text) av_log(ic, AV_LOG_VERBOSE, "Ignoring outlier non primary stream starttime %f\n", start_time_text / (float)AV_TIME_BASE); if (start_time != INT64_MAX) { ic->start_time = start_time; if (end_time != INT64_MIN) { if (ic->nb_programs) { - for (i=0; inb_programs; i++) { + for (i = 0; i < ic->nb_programs; i++) { p = ic->programs[i]; - if(p->start_time != AV_NOPTS_VALUE && p->end_time > p->start_time) + if (p->start_time != AV_NOPTS_VALUE && p->end_time > p->start_time) duration = FFMAX(duration, p->end_time - p->start_time); } } else @@ -2199,13 +2356,13 @@ static void update_stream_timings(AVFormatContext *ic) if (duration != INT64_MIN && duration > 0 && ic->duration == AV_NOPTS_VALUE) { ic->duration = duration; } - if (ic->pb && (filesize = avio_size(ic->pb)) > 0 && ic->duration != AV_NOPTS_VALUE) { - /* compute the bitrate */ - double bitrate = (double)filesize * 8.0 * AV_TIME_BASE / - (double)ic->duration; - if (bitrate >= 0 && bitrate <= INT_MAX) - ic->bit_rate = bitrate; - } + if (ic->pb && (filesize = avio_size(ic->pb)) > 0 && ic->duration != AV_NOPTS_VALUE) { + /* compute the bitrate */ + double bitrate = (double) filesize * 8.0 * AV_TIME_BASE / + (double) ic->duration; + if (bitrate >= 0 && bitrate <= INT_MAX) + ic->bit_rate = bitrate; + } } static void fill_all_stream_timings(AVFormatContext *ic) @@ -2214,13 +2371,15 @@ static void fill_all_stream_timings(AVFormatContext *ic) AVStream *st; update_stream_timings(ic); - for(i = 0;i < ic->nb_streams; i++) { + for (i = 0; i < ic->nb_streams; i++) { st = ic->streams[i]; if (st->start_time == AV_NOPTS_VALUE) { - if(ic->start_time != AV_NOPTS_VALUE) - st->start_time = av_rescale_q(ic->start_time, AV_TIME_BASE_Q, st->time_base); - if(ic->duration != AV_NOPTS_VALUE) - st->duration = av_rescale_q(ic->duration, AV_TIME_BASE_Q, st->time_base); + if (ic->start_time != AV_NOPTS_VALUE) + st->start_time = av_rescale_q(ic->start_time, AV_TIME_BASE_Q, + st->time_base); + if (ic->duration != AV_NOPTS_VALUE) + st->duration = av_rescale_q(ic->duration, AV_TIME_BASE_Q, + st->time_base); } } } @@ -2234,7 +2393,7 @@ static void estimate_timings_from_bit_rate(AVFormatContext *ic) /* if bit_rate is already set, we believe it */ if (ic->bit_rate <= 0) { int bit_rate = 0; - for(i=0;inb_streams;i++) { + for (i = 0; i < ic->nb_streams; i++) { st = ic->streams[i]; if (st->codec->bit_rate > 0) { if (INT_MAX - st->codec->bit_rate < bit_rate) { @@ -2252,11 +2411,13 @@ static void estimate_timings_from_bit_rate(AVFormatContext *ic) ic->bit_rate != 0) { filesize = ic->pb ? avio_size(ic->pb) : 0; if (filesize > 0) { - for(i = 0; i < ic->nb_streams; i++) { - st = ic->streams[i]; + for (i = 0; i < ic->nb_streams; i++) { + st = ic->streams[i]; if ( st->time_base.num <= INT64_MAX / ic->bit_rate && st->duration == AV_NOPTS_VALUE) { - duration= av_rescale(8*filesize, st->time_base.den, ic->bit_rate*(int64_t)st->time_base.num); + duration = av_rescale(8 * filesize, st->time_base.den, + ic->bit_rate * + (int64_t) st->time_base.num); st->duration = duration; show_warning = 1; } @@ -2264,7 +2425,8 @@ static void estimate_timings_from_bit_rate(AVFormatContext *ic) } } if (show_warning) - av_log(ic, AV_LOG_WARNING, "Estimating duration from bitrate, this may be inaccurate\n"); + av_log(ic, AV_LOG_WARNING, + "Estimating duration from bitrate, this may be inaccurate\n"); } #define DURATION_MAX_READ_SIZE 250000LL @@ -2278,19 +2440,22 @@ static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset) int read_size, i, ret; int64_t end_time; int64_t filesize, offset, duration; - int retry=0; + int retry = 0; /* flush packet queue */ flush_packet_queue(ic); - for (i=0; inb_streams; i++) { + for (i = 0; i < ic->nb_streams; i++) { st = ic->streams[i]; - if (st->start_time == AV_NOPTS_VALUE && st->first_dts == AV_NOPTS_VALUE) - av_log(st->codec, AV_LOG_WARNING, "start time is not set in estimate_timings_from_pts\n"); + if (st->start_time == AV_NOPTS_VALUE && + st->first_dts == AV_NOPTS_VALUE && + st->codec->codec_type != AVMEDIA_TYPE_UNKNOWN) + av_log(st->codec, AV_LOG_WARNING, + "start time is not set in estimate_timings_from_pts\n"); if (st->parser) { av_parser_close(st->parser); - st->parser= NULL; + st->parser = NULL; } } @@ -2298,24 +2463,24 @@ static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset) /* XXX: may need to support wrapping */ filesize = ic->pb ? avio_size(ic->pb) : 0; end_time = AV_NOPTS_VALUE; - do{ - offset = filesize - (DURATION_MAX_READ_SIZE<pb, offset, SEEK_SET); read_size = 0; - for(;;) { - if (read_size >= DURATION_MAX_READ_SIZE<<(FFMAX(retry-1,0))) + for (;;) { + if (read_size >= DURATION_MAX_READ_SIZE << (FFMAX(retry - 1, 0))) break; do { ret = ff_read_packet(ic, pkt); - } while(ret == AVERROR(EAGAIN)); + } while (ret == AVERROR(EAGAIN)); if (ret != 0) break; read_size += pkt->size; - st = ic->streams[pkt->stream_index]; + st = ic->streams[pkt->stream_index]; if (pkt->pts != AV_NOPTS_VALUE && (st->start_time != AV_NOPTS_VALUE || st->first_dts != AV_NOPTS_VALUE)) { @@ -2325,7 +2490,7 @@ static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset) else duration -= st->first_dts; if (duration > 0) { - if (st->duration == AV_NOPTS_VALUE || st->info->last_duration<=0 || + if (st->duration == AV_NOPTS_VALUE || st->info->last_duration<= 0 || (st->duration < duration && FFABS(duration - st->info->last_duration) < 60LL*st->time_base.den / st->time_base.num)) st->duration = duration; st->info->last_duration = duration; @@ -2333,18 +2498,22 @@ static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset) } av_free_packet(pkt); } - }while( end_time==AV_NOPTS_VALUE - && filesize > (DURATION_MAX_READ_SIZE< (DURATION_MAX_READ_SIZE << retry) && + ++retry <= DURATION_MAX_RETRY); fill_all_stream_timings(ic); avio_seek(ic->pb, old_offset, SEEK_SET); - for (i=0; inb_streams; i++) { - st= ic->streams[i]; - st->cur_dts= st->first_dts; + for (i = 0; i < ic->nb_streams; i++) { + int j; + + st = ic->streams[i]; + st->cur_dts = st->first_dts; st->last_IP_pts = AV_NOPTS_VALUE; - st->reference_dts = AV_NOPTS_VALUE; + st->last_dts_for_order_check = AV_NOPTS_VALUE; + for (j = 0; j < MAX_REORDER_DELAY + 1; j++) + st->pts_buffer[j] = AV_NOPTS_VALUE; } } @@ -2368,7 +2537,7 @@ static void estimate_timings(AVFormatContext *ic, int64_t old_offset) ic->duration_estimation_method = AVFMT_DURATION_FROM_PTS; } else if (has_duration(ic)) { /* at least one component has timings - we use them for all - the components */ + * the components */ fill_all_stream_timings(ic); ic->duration_estimation_method = AVFMT_DURATION_FROM_STREAM; } else { @@ -2381,13 +2550,14 @@ static void estimate_timings(AVFormatContext *ic, int64_t old_offset) { int i; AVStream av_unused *st; - for(i = 0;i < ic->nb_streams; i++) { + for (i = 0; i < ic->nb_streams; i++) { st = ic->streams[i]; av_dlog(ic, "%d: start_time: %0.3f duration: %0.3f\n", i, (double) st->start_time / AV_TIME_BASE, (double) st->duration / AV_TIME_BASE); } - av_dlog(ic, "stream: start_time: %0.3f duration: %0.3f bitrate=%d kb/s\n", + av_dlog(ic, + "stream: start_time: %0.3f duration: %0.3f bitrate=%d kb/s\n", (double) ic->start_time / AV_TIME_BASE, (double) ic->duration / AV_TIME_BASE, ic->bit_rate / 1000); @@ -2408,7 +2578,8 @@ static int has_codec_parameters(AVStream *st, const char **errmsg_ptr) case AVMEDIA_TYPE_AUDIO: if (!avctx->frame_size && determinable_frame_size(avctx)) FAIL("unspecified frame size"); - if (st->info->found_decoder >= 0 && avctx->sample_fmt == AV_SAMPLE_FMT_NONE) + if (st->info->found_decoder >= 0 && + avctx->sample_fmt == AV_SAMPLE_FMT_NONE) FAIL("unspecified sample format"); if (!avctx->sample_rate) FAIL("unspecified sample rate"); @@ -2431,9 +2602,7 @@ static int has_codec_parameters(AVStream *st, const char **errmsg_ptr) FAIL("unspecified size"); break; case AVMEDIA_TYPE_DATA: - if(avctx->codec_id == AV_CODEC_ID_NONE) return 1; - break; - default:break; + if (avctx->codec_id == AV_CODEC_ID_NONE) return 1; } if (avctx->codec_id == AV_CODEC_ID_NONE) @@ -2442,11 +2611,12 @@ static int has_codec_parameters(AVStream *st, const char **errmsg_ptr) } /* returns 1 or 0 if or if not decoded data was returned, or a negative error */ -static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **options) +static int try_decode_frame(AVFormatContext *s, AVStream *st, AVPacket *avpkt, + AVDictionary **options) { const AVCodec *codec; int got_picture = 1, ret = 0; - AVFrame *frame = avcodec_alloc_frame(); + AVFrame *frame = av_frame_alloc(); AVSubtitle subtitle; AVPacket pkt = *avpkt; @@ -2456,16 +2626,16 @@ static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **option if (!avcodec_is_open(st->codec) && !st->info->found_decoder) { AVDictionary *thread_opt = NULL; - codec = find_decoder(st, st->codec->codec_id); + codec = find_decoder(s, st, st->codec->codec_id); if (!codec) { st->info->found_decoder = -1; - ret = -1; + ret = -1; goto fail; } - /* force thread count to 1 since the h264 decoder will not extract SPS - * and PPS to extradata during multi-threaded decoding */ + /* Force thread count to 1 since the H.264 decoder will not extract + * SPS and PPS to extradata during multi-threaded decoding. */ av_dict_set(options ? options : &thread_opt, "threads", "1", 0); ret = avcodec_open2(st->codec, codec, options ? options : &thread_opt); if (!options) @@ -2485,12 +2655,11 @@ static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **option while ((pkt.size > 0 || (!pkt.data && got_picture)) && ret >= 0 && - (!has_codec_parameters(st, NULL) || - !has_decode_delay_been_guessed(st) || - (!st->codec_info_nb_frames && st->codec->codec->capabilities & CODEC_CAP_CHANNEL_CONF))) { + (!has_codec_parameters(st, NULL) || !has_decode_delay_been_guessed(st) || + (!st->codec_info_nb_frames && + st->codec->codec->capabilities & CODEC_CAP_CHANNEL_CONF))) { got_picture = 0; - avcodec_get_frame_defaults(frame); - switch(st->codec->codec_type) { + switch (st->codec->codec_type) { case AVMEDIA_TYPE_VIDEO: ret = avcodec_decode_video2(st->codec, frame, &got_picture, &pkt); @@ -2515,11 +2684,11 @@ static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **option } } - if(!pkt.data && !got_picture) + if (!pkt.data && !got_picture) ret = -1; fail: - avcodec_free_frame(&frame); + av_frame_free(&frame); return ret; } @@ -2536,14 +2705,12 @@ unsigned int ff_codec_get_tag(const AVCodecTag *tags, enum AVCodecID id) enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag) { int i; - for(i=0; tags[i].id != AV_CODEC_ID_NONE;i++) { - if(tag == tags[i].tag) + for (i = 0; tags[i].id != AV_CODEC_ID_NONE; i++) + if (tag == tags[i].tag) return tags[i].id; - } - for(i=0; tags[i].id != AV_CODEC_ID_NONE; i++) { + for (i = 0; tags[i].id != AV_CODEC_ID_NONE; i++) if (avpriv_toupper4(tag) == avpriv_toupper4(tags[i].tag)) return tags[i].id; - } return AV_CODEC_ID_NONE; } @@ -2551,34 +2718,47 @@ enum AVCodecID ff_get_pcm_codec_id(int bps, int flt, int be, int sflags) { if (flt) { switch (bps) { - case 32: return be ? AV_CODEC_ID_PCM_F32BE : AV_CODEC_ID_PCM_F32LE; - case 64: return be ? AV_CODEC_ID_PCM_F64BE : AV_CODEC_ID_PCM_F64LE; - default: return AV_CODEC_ID_NONE; + case 32: + return be ? AV_CODEC_ID_PCM_F32BE : AV_CODEC_ID_PCM_F32LE; + case 64: + return be ? AV_CODEC_ID_PCM_F64BE : AV_CODEC_ID_PCM_F64LE; + default: + return AV_CODEC_ID_NONE; } } else { bps += 7; bps >>= 3; if (sflags & (1 << (bps - 1))) { switch (bps) { - case 1: return AV_CODEC_ID_PCM_S8; - case 2: return be ? AV_CODEC_ID_PCM_S16BE : AV_CODEC_ID_PCM_S16LE; - case 3: return be ? AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE; - case 4: return be ? AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE; - default: return AV_CODEC_ID_NONE; + case 1: + return AV_CODEC_ID_PCM_S8; + case 2: + return be ? AV_CODEC_ID_PCM_S16BE : AV_CODEC_ID_PCM_S16LE; + case 3: + return be ? AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE; + case 4: + return be ? AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE; + default: + return AV_CODEC_ID_NONE; } } else { switch (bps) { - case 1: return AV_CODEC_ID_PCM_U8; - case 2: return be ? AV_CODEC_ID_PCM_U16BE : AV_CODEC_ID_PCM_U16LE; - case 3: return be ? AV_CODEC_ID_PCM_U24BE : AV_CODEC_ID_PCM_U24LE; - case 4: return be ? AV_CODEC_ID_PCM_U32BE : AV_CODEC_ID_PCM_U32LE; - default: return AV_CODEC_ID_NONE; + case 1: + return AV_CODEC_ID_PCM_U8; + case 2: + return be ? AV_CODEC_ID_PCM_U16BE : AV_CODEC_ID_PCM_U16LE; + case 3: + return be ? AV_CODEC_ID_PCM_U24BE : AV_CODEC_ID_PCM_U24LE; + case 4: + return be ? AV_CODEC_ID_PCM_U32BE : AV_CODEC_ID_PCM_U32LE; + default: + return AV_CODEC_ID_NONE; } } } } -unsigned int av_codec_get_tag(const AVCodecTag * const *tags, enum AVCodecID id) +unsigned int av_codec_get_tag(const AVCodecTag *const *tags, enum AVCodecID id) { unsigned int tag; if (!av_codec_get_tag2(tags, id, &tag)) @@ -2590,7 +2770,7 @@ int av_codec_get_tag2(const AVCodecTag * const *tags, enum AVCodecID id, unsigned int *tag) { int i; - for(i=0; tags && tags[i]; i++){ + for (i = 0; tags && tags[i]; i++) { const AVCodecTag *codec_tags = tags[i]; while (codec_tags->id != AV_CODEC_ID_NONE) { if (codec_tags->id == id) { @@ -2603,12 +2783,13 @@ int av_codec_get_tag2(const AVCodecTag * const *tags, enum AVCodecID id, return 0; } -enum AVCodecID av_codec_get_id(const AVCodecTag * const *tags, unsigned int tag) +enum AVCodecID av_codec_get_id(const AVCodecTag *const *tags, unsigned int tag) { int i; - for(i=0; tags && tags[i]; i++){ - enum AVCodecID id= ff_codec_get_id(tags[i], tag); - if(id!=AV_CODEC_ID_NONE) return id; + for (i = 0; tags && tags[i]; i++) { + enum AVCodecID id = ff_codec_get_id(tags[i], tag); + if (id != AV_CODEC_ID_NONE) + return id; } return AV_CODEC_ID_NONE; } @@ -2616,17 +2797,20 @@ enum AVCodecID av_codec_get_id(const AVCodecTag * const *tags, unsigned int tag) static void compute_chapters_end(AVFormatContext *s) { unsigned int i, j; - int64_t max_time = s->duration + ((s->start_time == AV_NOPTS_VALUE) ? 0 : s->start_time); + int64_t max_time = s->duration + + ((s->start_time == AV_NOPTS_VALUE) ? 0 : s->start_time); for (i = 0; i < s->nb_chapters; i++) if (s->chapters[i]->end == AV_NOPTS_VALUE) { AVChapter *ch = s->chapters[i]; - int64_t end = max_time ? av_rescale_q(max_time, AV_TIME_BASE_Q, ch->time_base) - : INT64_MAX; + int64_t end = max_time ? av_rescale_q(max_time, AV_TIME_BASE_Q, + ch->time_base) + : INT64_MAX; for (j = 0; j < s->nb_chapters; j++) { - AVChapter *ch1 = s->chapters[j]; - int64_t next_start = av_rescale_q(ch1->start, ch1->time_base, ch->time_base); + AVChapter *ch1 = s->chapters[j]; + int64_t next_start = av_rescale_q(ch1->start, ch1->time_base, + ch->time_base); if (j != i && next_start > ch->start && next_start < end) end = next_start; } @@ -2634,28 +2818,29 @@ static void compute_chapters_end(AVFormatContext *s) } } -static int get_std_framerate(int i){ - if(i<60*12) return (i+1)*1001; - else return ((const int[]){24,30,60,12,15,48})[i-60*12]*1000*12; +static int get_std_framerate(int i) +{ + if (i < 60 * 12) + return (i + 1) * 1001; + else + return ((const int[]) { 24, 30, 60, 12, 15, 48 })[i - 60 * 12] * 1000 * 12; } -/* - * Is the time base unreliable. +/* Is the time base unreliable? * This is a heuristic to balance between quick acceptance of the values in * the headers vs. some extra checks. * Old DivX and Xvid often have nonsense timebases like 1fps or 2fps. * MPEG-2 commonly misuses field repeat flags to store different framerates. - * And there are "variable" fps files this needs to detect as well. - */ -static int tb_unreliable(AVCodecContext *c){ - if( c->time_base.den >= 101L*c->time_base.num - || c->time_base.den < 5L*c->time_base.num -/* || c->codec_tag == AV_RL32("DIVX") - || c->codec_tag == AV_RL32("XVID")*/ - || c->codec_tag == AV_RL32("mp4v") - || c->codec_id == AV_CODEC_ID_MPEG2VIDEO - || c->codec_id == AV_CODEC_ID_H264 - ) + * And there are "variable" fps files this needs to detect as well. */ +static int tb_unreliable(AVCodecContext *c) +{ + if (c->time_base.den >= 101L * c->time_base.num || + c->time_base.den < 5L * c->time_base.num || + // c->codec_tag == AV_RL32("DIVX") || + // c->codec_tag == AV_RL32("XVID") || + c->codec_tag == AV_RL32("mp4v") || + c->codec_id == AV_CODEC_ID_MPEG2VIDEO || + c->codec_id == AV_CODEC_ID_H264) return 1; return 0; } @@ -2667,38 +2852,189 @@ int av_find_stream_info(AVFormatContext *ic) } #endif +int ff_alloc_extradata(AVCodecContext *avctx, int size) +{ + int ret; + + if (size < 0 || size >= INT32_MAX - FF_INPUT_BUFFER_PADDING_SIZE) { + avctx->extradata_size = 0; + return AVERROR(EINVAL); + } + avctx->extradata = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); + if (avctx->extradata) { + memset(avctx->extradata + size, 0, FF_INPUT_BUFFER_PADDING_SIZE); + avctx->extradata_size = size; + ret = 0; + } else { + avctx->extradata_size = 0; + ret = AVERROR(ENOMEM); + } + return ret; +} + +int ff_get_extradata(AVCodecContext *avctx, AVIOContext *pb, int size) +{ + int ret = ff_alloc_extradata(avctx, size); + if (ret < 0) + return ret; + ret = avio_read(pb, avctx->extradata, size); + if (ret != size) { + av_freep(&avctx->extradata); + avctx->extradata_size = 0; + av_log(avctx, AV_LOG_ERROR, "Failed to read extradata of size %d\n", size); + return ret < 0 ? ret : AVERROR_INVALIDDATA; + } + + return ret; +} + +int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t ts) +{ + int i, j; + int64_t last = st->info->last_dts; + + if ( ts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && ts > last + && ts - (uint64_t)last < INT64_MAX) { + double dts = (is_relative(ts) ? ts - RELATIVE_TS_BASE : ts) * av_q2d(st->time_base); + int64_t duration = ts - last; + + if (!st->info->duration_error) + st->info->duration_error = av_mallocz(sizeof(st->info->duration_error[0])*2); + if (!st->info->duration_error) + return AVERROR(ENOMEM); + +// if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) +// av_log(NULL, AV_LOG_ERROR, "%f\n", dts); + for (i = 0; iinfo->duration_error[0][1][i] < 1e10) { + int framerate = get_std_framerate(i); + double sdts = dts*framerate/(1001*12); + for (j= 0; j<2; j++) { + int64_t ticks = llrint(sdts+j*0.5); + double error= sdts - ticks + j*0.5; + st->info->duration_error[j][0][i] += error; + st->info->duration_error[j][1][i] += error*error; + } + } + } + st->info->duration_count++; + st->info->rfps_duration_sum += duration; + + if (st->info->duration_count % 10 == 0) { + int n = st->info->duration_count; + for (i = 0; iinfo->duration_error[0][1][i] < 1e10) { + double a0 = st->info->duration_error[0][0][i] / n; + double error0 = st->info->duration_error[0][1][i] / n - a0*a0; + double a1 = st->info->duration_error[1][0][i] / n; + double error1 = st->info->duration_error[1][1][i] / n - a1*a1; + if (error0 > 0.04 && error1 > 0.04) { + st->info->duration_error[0][1][i] = 2e10; + st->info->duration_error[1][1][i] = 2e10; + } + } + } + } + + // ignore the first 4 values, they might have some random jitter + if (st->info->duration_count > 3 && is_relative(ts) == is_relative(last)) + st->info->duration_gcd = av_gcd(st->info->duration_gcd, duration); + } + if (ts != AV_NOPTS_VALUE) + st->info->last_dts = ts; + + return 0; +} + +void ff_rfps_calculate(AVFormatContext *ic) +{ + int i, j; + + for (i = 0; i < ic->nb_streams; i++) { + AVStream *st = ic->streams[i]; + + if (st->codec->codec_type != AVMEDIA_TYPE_VIDEO) + continue; + // the check for tb_unreliable() is not completely correct, since this is not about handling + // a unreliable/inexact time base, but a time base that is finer than necessary, as e.g. + // ipmovie.c produces. + if (tb_unreliable(st->codec) && st->info->duration_count > 15 && st->info->duration_gcd > FFMAX(1, st->time_base.den/(500LL*st->time_base.num)) && !st->r_frame_rate.num) + av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, st->time_base.den, st->time_base.num * st->info->duration_gcd, INT_MAX); + if (st->info->duration_count>1 && !st->r_frame_rate.num + && tb_unreliable(st->codec)) { + int num = 0; + double best_error= 0.01; + + for (j= 0; jinfo->codec_info_duration && st->info->codec_info_duration*av_q2d(st->time_base) < (1001*12.0)/get_std_framerate(j)) + continue; + if (!st->info->codec_info_duration && 1.0 < (1001*12.0)/get_std_framerate(j)) + continue; + + if (av_q2d(st->time_base) * st->info->rfps_duration_sum / st->info->duration_count < (1001*12.0 * 0.8)/get_std_framerate(j)) + continue; + + for (k= 0; k<2; k++) { + int n = st->info->duration_count; + double a= st->info->duration_error[k][0][j] / n; + double error= st->info->duration_error[k][1][j]/n - a*a; + + if (error < best_error && best_error> 0.000000001) { + best_error= error; + num = get_std_framerate(j); + } + if (error < 0.02) + av_log(NULL, AV_LOG_DEBUG, "rfps: %f %f\n", get_std_framerate(j) / 12.0/1001, error); + } + } + // do not increase frame rate by more than 1 % in order to match a standard rate. + if (num && (!st->r_frame_rate.num || (double)num/(12*1001) < 1.01 * av_q2d(st->r_frame_rate))) + av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, num, 12*1001, INT_MAX); + } + + av_freep(&st->info->duration_error); + st->info->last_dts = AV_NOPTS_VALUE; + st->info->duration_count = 0; + st->info->rfps_duration_sum = 0; + } +} + int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) { int i, count, ret = 0, j; int64_t read_size; AVStream *st; AVPacket pkt1, *pkt; - int64_t old_offset = avio_tell(ic->pb); - int orig_nb_streams = ic->nb_streams; // new streams might appear, no options for those - int flush_codecs = ic->probesize > 0; + int64_t old_offset = avio_tell(ic->pb); + // new streams might appear, no options for those + int orig_nb_streams = ic->nb_streams; + int flush_codecs = ic->probesize > 0; - if(ic->pb) - av_log(ic, AV_LOG_DEBUG, "File position before avformat_find_stream_info() is %"PRId64"\n", avio_tell(ic->pb)); + if (ic->pb) + av_log(ic, AV_LOG_DEBUG, "Before avformat_find_stream_info() pos: %"PRId64" bytes read:%"PRId64" seeks:%d\n", + avio_tell(ic->pb), ic->pb->bytes_read, ic->pb->seek_count); - for(i=0;inb_streams;i++) { + for (i = 0; i < ic->nb_streams; i++) { const AVCodec *codec; AVDictionary *thread_opt = NULL; st = ic->streams[i]; if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO || st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) { -/* if(!st->time_base.num) - st->time_base= */ - if(!st->codec->time_base.num) - st->codec->time_base= st->time_base; +/* if (!st->time_base.num) + st->time_base = */ + if (!st->codec->time_base.num) + st->codec->time_base = st->time_base; } - //only for the split stuff + // only for the split stuff if (!st->parser && !(ic->flags & AVFMT_FLAG_NOPARSE)) { st->parser = av_parser_init(st->codec->codec_id); - if(st->parser){ - if(st->need_parsing == AVSTREAM_PARSE_HEADERS){ + if (st->parser) { + if (st->need_parsing == AVSTREAM_PARSE_HEADERS) { st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES; - } else if(st->need_parsing == AVSTREAM_PARSE_FULL_RAW) { + } else if (st->need_parsing == AVSTREAM_PARSE_FULL_RAW) { st->parser->flags |= PARSER_FLAG_USE_CODEC_TS; } } else if (st->need_parsing) { @@ -2707,29 +3043,32 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) avcodec_get_name(st->codec->codec_id)); } } - codec = find_decoder(st, st->codec->codec_id); + codec = find_decoder(ic, st, st->codec->codec_id); - /* force thread count to 1 since the h264 decoder will not extract SPS - * and PPS to extradata during multi-threaded decoding */ + /* Force thread count to 1 since the H.264 decoder will not extract + * SPS and PPS to extradata during multi-threaded decoding. */ av_dict_set(options ? &options[i] : &thread_opt, "threads", "1", 0); /* Ensure that subtitle_header is properly set. */ if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE - && codec && !st->codec->codec) - avcodec_open2(st->codec, codec, options ? &options[i] - : &thread_opt); + && codec && !st->codec->codec) { + if (avcodec_open2(st->codec, codec, options ? &options[i] : &thread_opt) < 0) + av_log(ic, AV_LOG_WARNING, + "Failed to open codec in av_find_stream_info\n"); + } - //try to just open decoders, in case this is enough to get parameters + // Try to just open decoders, in case this is enough to get parameters. if (!has_codec_parameters(st, NULL) && st->request_probe <= 0) { if (codec && !st->codec->codec) - avcodec_open2(st->codec, codec, options ? &options[i] - : &thread_opt); + if (avcodec_open2(st->codec, codec, options ? &options[i] : &thread_opt) < 0) + av_log(ic, AV_LOG_WARNING, + "Failed to open codec in av_find_stream_info\n"); } if (!options) av_dict_free(&thread_opt); } - for (i=0; inb_streams; i++) { + for (i = 0; i < ic->nb_streams; i++) { #if FF_API_R_FRAME_RATE ic->streams[i]->info->last_dts = AV_NOPTS_VALUE; #endif @@ -2737,25 +3076,25 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) ic->streams[i]->info->fps_last_dts = AV_NOPTS_VALUE; } - count = 0; + count = 0; read_size = 0; - for(;;) { - if (ff_check_interrupt(&ic->interrupt_callback)){ - ret= AVERROR_EXIT; + for (;;) { + if (ff_check_interrupt(&ic->interrupt_callback)) { + ret = AVERROR_EXIT; av_log(ic, AV_LOG_DEBUG, "interrupted\n"); break; } /* check if one codec still needs to be handled */ - for(i=0;inb_streams;i++) { + for (i = 0; i < ic->nb_streams; i++) { int fps_analyze_framecount = 20; st = ic->streams[i]; if (!has_codec_parameters(st, NULL)) break; - /* if the timebase is coarse (like the usual millisecond precision - of mkv), we need to analyze more frames to reliably arrive at - the correct fps */ + /* If the timebase is coarse (like the usual millisecond precision + * of mkv), we need to analyze more frames to reliably arrive at + * the correct fps. */ if (av_q2d(st->time_base) > 0.0005) fps_analyze_framecount *= 2; if (ic->fps_probe_size >= 0) @@ -2763,11 +3102,13 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) if (st->disposition & AV_DISPOSITION_ATTACHED_PIC) fps_analyze_framecount = 0; /* variable fps and no guess at the real fps */ - if( tb_unreliable(st->codec) && !(st->r_frame_rate.num && st->avg_frame_rate.num) - && st->info->duration_count < fps_analyze_framecount - && st->codec->codec_type == AVMEDIA_TYPE_VIDEO) + if (tb_unreliable(st->codec) && + !(st->r_frame_rate.num && st->avg_frame_rate.num) && + st->info->duration_count < fps_analyze_framecount && + st->codec->codec_type == AVMEDIA_TYPE_VIDEO) break; - if(st->parser && st->parser->parser->split && !st->codec->extradata) + if (st->parser && st->parser->parser->split && + !st->codec->extradata) break; if (st->first_dts == AV_NOPTS_VALUE && (st->codec->codec_type == AVMEDIA_TYPE_VIDEO || @@ -2775,24 +3116,25 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) break; } if (i == ic->nb_streams) { - /* NOTE: if the format has no header, then we need to read - some packets to get most of the streams, so we cannot - stop here */ + /* NOTE: If the format has no header, then we need to read some + * packets to get most of the streams, so we cannot stop here. */ if (!(ic->ctx_flags & AVFMTCTX_NOHEADER)) { - /* if we found the info for all the codecs, we can stop */ + /* If we found the info for all the codecs, we can stop. */ ret = count; av_log(ic, AV_LOG_DEBUG, "All info found\n"); flush_codecs = 0; break; } } - /* we did not get all the codec info, but we read too much data */ + /* We did not get all the codec info, but we read too much data. */ if (read_size >= ic->probesize) { ret = count; - av_log(ic, AV_LOG_DEBUG, "Probe buffer size limit of %d bytes reached\n", ic->probesize); + av_log(ic, AV_LOG_DEBUG, + "Probe buffer size limit of %d bytes reached\n", ic->probesize); for (i = 0; i < ic->nb_streams; i++) if (!ic->streams[i]->r_frame_rate.num && ic->streams[i]->info->duration_count <= 1 && + ic->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO && strcmp(ic->iformat->name, "image2")) av_log(ic, AV_LOG_WARNING, "Stream #%d: not enough frames to estimate rate; " @@ -2800,8 +3142,8 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) break; } - /* NOTE: a new stream can be added there if no header in file - (AVFMTCTX_NOHEADER) */ + /* NOTE: A new stream can be added there if no header in file + * (AVFMTCTX_NOHEADER). */ ret = read_frame_internal(ic, &pkt1); if (ret == AVERROR(EAGAIN)) continue; @@ -2824,31 +3166,39 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) goto find_stream_info_err; } - read_size += pkt->size; - st = ic->streams[pkt->stream_index]; + if (!(st->disposition & AV_DISPOSITION_ATTACHED_PIC)) + read_size += pkt->size; + if (pkt->dts != AV_NOPTS_VALUE && st->codec_info_nb_frames > 1) { /* check for non-increasing dts */ if (st->info->fps_last_dts != AV_NOPTS_VALUE && st->info->fps_last_dts >= pkt->dts) { - av_log(ic, AV_LOG_DEBUG, "Non-increasing DTS in stream %d: " - "packet %d with DTS %"PRId64", packet %d with DTS " - "%"PRId64"\n", st->index, st->info->fps_last_dts_idx, - st->info->fps_last_dts, st->codec_info_nb_frames, pkt->dts); - st->info->fps_first_dts = st->info->fps_last_dts = AV_NOPTS_VALUE; + av_log(ic, AV_LOG_DEBUG, + "Non-increasing DTS in stream %d: packet %d with DTS " + "%"PRId64", packet %d with DTS %"PRId64"\n", + st->index, st->info->fps_last_dts_idx, + st->info->fps_last_dts, st->codec_info_nb_frames, + pkt->dts); + st->info->fps_first_dts = + st->info->fps_last_dts = AV_NOPTS_VALUE; } - /* check for a discontinuity in dts - if the difference in dts - * is more than 1000 times the average packet duration in the sequence, - * we treat it as a discontinuity */ + /* Check for a discontinuity in dts. If the difference in dts + * is more than 1000 times the average packet duration in the + * sequence, we treat it as a discontinuity. */ if (st->info->fps_last_dts != AV_NOPTS_VALUE && st->info->fps_last_dts_idx > st->info->fps_first_dts_idx && (pkt->dts - st->info->fps_last_dts) / 1000 > - (st->info->fps_last_dts - st->info->fps_first_dts) / (st->info->fps_last_dts_idx - st->info->fps_first_dts_idx)) { - av_log(ic, AV_LOG_WARNING, "DTS discontinuity in stream %d: " - "packet %d with DTS %"PRId64", packet %d with DTS " - "%"PRId64"\n", st->index, st->info->fps_last_dts_idx, - st->info->fps_last_dts, st->codec_info_nb_frames, pkt->dts); - st->info->fps_first_dts = st->info->fps_last_dts = AV_NOPTS_VALUE; + (st->info->fps_last_dts - st->info->fps_first_dts) / + (st->info->fps_last_dts_idx - st->info->fps_first_dts_idx)) { + av_log(ic, AV_LOG_WARNING, + "DTS discontinuity in stream %d: packet %d with DTS " + "%"PRId64", packet %d with DTS %"PRId64"\n", + st->index, st->info->fps_last_dts_idx, + st->info->fps_last_dts, st->codec_info_nb_frames, + pkt->dts); + st->info->fps_first_dts = + st->info->fps_last_dts = AV_NOPTS_VALUE; } /* update stored dts values */ @@ -2856,17 +3206,17 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) st->info->fps_first_dts = pkt->dts; st->info->fps_first_dts_idx = st->codec_info_nb_frames; } - st->info->fps_last_dts = pkt->dts; + st->info->fps_last_dts = pkt->dts; st->info->fps_last_dts_idx = st->codec_info_nb_frames; } if (st->codec_info_nb_frames>1) { - int64_t t=0; + int64_t t = 0; if (st->time_base.den > 0) t = av_rescale_q(st->info->codec_info_duration, st->time_base, AV_TIME_BASE_Q); if (st->avg_frame_rate.num > 0) t = FFMAX(t, av_rescale_q(st->codec_info_nb_frames, av_inv_q(st->avg_frame_rate), AV_TIME_BASE_Q)); - if ( t==0 + if ( t == 0 && st->codec_info_nb_frames>30 && st->info->fps_first_dts != AV_NOPTS_VALUE && st->info->fps_last_dts != AV_NOPTS_VALUE) @@ -2878,66 +3228,33 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) } if (pkt->duration) { st->info->codec_info_duration += pkt->duration; - st->info->codec_info_duration_fields += st->parser && st->need_parsing && st->codec->ticks_per_frame==2 ? st->parser->repeat_pict + 1 : 2; + st->info->codec_info_duration_fields += st->parser && st->need_parsing && st->codec->ticks_per_frame ==2 ? st->parser->repeat_pict + 1 : 2; } } #if FF_API_R_FRAME_RATE - { - int64_t last = st->info->last_dts; - - if( pkt->dts != AV_NOPTS_VALUE && last != AV_NOPTS_VALUE && pkt->dts > last - && pkt->dts - (uint64_t)last < INT64_MAX){ - double dts= (is_relative(pkt->dts) ? pkt->dts - RELATIVE_TS_BASE : pkt->dts) * av_q2d(st->time_base); - int64_t duration= pkt->dts - last; - - if (!st->info->duration_error) - st->info->duration_error = av_mallocz(sizeof(st->info->duration_error[0])*2); - if (!st->info->duration_error) - return AVERROR(ENOMEM); - -// if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO) -// av_log(NULL, AV_LOG_ERROR, "%f\n", dts); - for (i=0; iinfo->duration_error[j][0][i] += error; - st->info->duration_error[j][1][i] += error*error; - } - } - st->info->duration_count++; - // ignore the first 4 values, they might have some random jitter - if (st->info->duration_count > 3 && is_relative(pkt->dts) == is_relative(last)) - st->info->duration_gcd = av_gcd(st->info->duration_gcd, duration); - } - if (pkt->dts != AV_NOPTS_VALUE) - st->info->last_dts = pkt->dts; - } + ff_rfps_add_frame(ic, st, pkt->dts); #endif - if(st->parser && st->parser->parser->split && !st->codec->extradata){ - int i= st->parser->parser->split(st->codec, pkt->data, pkt->size); + if (st->parser && st->parser->parser->split && !st->codec->extradata) { + int i = st->parser->parser->split(st->codec, pkt->data, pkt->size); if (i > 0 && i < FF_MAX_EXTRADATA_SIZE) { - st->codec->extradata_size= i; - st->codec->extradata= av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) + if (ff_alloc_extradata(st->codec, i)) return AVERROR(ENOMEM); - memcpy(st->codec->extradata, pkt->data, st->codec->extradata_size); - memset(st->codec->extradata + i, 0, FF_INPUT_BUFFER_PADDING_SIZE); + memcpy(st->codec->extradata, pkt->data, + st->codec->extradata_size); } } - /* if still no information, we try to open the codec and to - decompress the frame. We try to avoid that in most cases as - it takes longer and uses more memory. For MPEG-4, we need to - decompress for QuickTime. - - If CODEC_CAP_CHANNEL_CONF is set this will force decoding of at - least one frame of codec data, this makes sure the codec initializes - the channel configuration and does not only trust the values from the container. - */ - try_decode_frame(st, pkt, (options && i < orig_nb_streams ) ? &options[i] : NULL); + /* If still no information, we try to open the codec and to + * decompress the frame. We try to avoid that in most cases as + * it takes longer and uses more memory. For MPEG-4, we need to + * decompress for QuickTime. + * + * If CODEC_CAP_CHANNEL_CONF is set this will force decoding of at + * least one frame of codec data, this makes sure the codec initializes + * the channel configuration and does not only trust the values from + * the container. */ + try_decode_frame(ic, st, pkt, + (options && i < orig_nb_streams) ? &options[i] : NULL); st->codec_info_nb_frames++; count++; @@ -2948,16 +3265,16 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) int err = 0; av_init_packet(&empty_pkt); - for(i=0;inb_streams;i++) { + for (i = 0; i < ic->nb_streams; i++) { st = ic->streams[i]; /* flush the decoders */ if (st->info->found_decoder == 1) { do { - err = try_decode_frame(st, &empty_pkt, - (options && i < orig_nb_streams) ? - &options[i] : NULL); + err = try_decode_frame(ic, st, &empty_pkt, + (options && i < orig_nb_streams) + ? &options[i] : NULL); } while (err > 0 && !has_codec_parameters(st, NULL)); if (err < 0) { @@ -2969,22 +3286,27 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) } // close codecs which were opened in try_decode_frame() - for(i=0;inb_streams;i++) { + for (i = 0; i < ic->nb_streams; i++) { st = ic->streams[i]; avcodec_close(st->codec); } - for(i=0;inb_streams;i++) { + + ff_rfps_calculate(ic); + + for (i = 0; i < ic->nb_streams; i++) { st = ic->streams[i]; if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - if(st->codec->codec_id == AV_CODEC_ID_RAWVIDEO && !st->codec->codec_tag && !st->codec->bits_per_coded_sample){ + if (st->codec->codec_id == AV_CODEC_ID_RAWVIDEO && !st->codec->codec_tag && !st->codec->bits_per_coded_sample) { uint32_t tag= avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt); if (avpriv_find_pix_fmt(ff_raw_pix_fmt_tags, tag) == st->codec->pix_fmt) st->codec->codec_tag= tag; } /* estimate average framerate if not set by demuxer */ - if (st->info->codec_info_duration_fields && !st->avg_frame_rate.num && st->info->codec_info_duration) { - int best_fps = 0; + if (st->info->codec_info_duration_fields && + !st->avg_frame_rate.num && + st->info->codec_info_duration) { + int best_fps = 0; double best_error = 0.01; if (st->info->codec_info_duration >= INT64_MAX / st->time_base.num / 2|| @@ -2992,96 +3314,68 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) st->info->codec_info_duration < 0) continue; av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den, - st->info->codec_info_duration_fields*(int64_t)st->time_base.den, - st->info->codec_info_duration*2*(int64_t)st->time_base.num, 60000); + st->info->codec_info_duration_fields * (int64_t) st->time_base.den, + st->info->codec_info_duration * 2 * (int64_t) st->time_base.num, 60000); - /* round guessed framerate to a "standard" framerate if it's - * within 1% of the original estimate*/ - for (j = 1; j < MAX_STD_TIMEBASES; j++) { - AVRational std_fps = { get_std_framerate(j), 12*1001 }; - double error = fabs(av_q2d(st->avg_frame_rate) / av_q2d(std_fps) - 1); + /* Round guessed framerate to a "standard" framerate if it's + * within 1% of the original estimate. */ + for (j = 0; j < MAX_STD_TIMEBASES; j++) { + AVRational std_fps = { get_std_framerate(j), 12 * 1001 }; + double error = fabs(av_q2d(st->avg_frame_rate) / + av_q2d(std_fps) - 1); if (error < best_error) { best_error = error; best_fps = std_fps.num; } } - if (best_fps) { + if (best_fps) av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den, - best_fps, 12*1001, INT_MAX); - } - } - // the check for tb_unreliable() is not completely correct, since this is not about handling - // a unreliable/inexact time base, but a time base that is finer than necessary, as e.g. - // ipmovie.c produces. - if (tb_unreliable(st->codec) && st->info->duration_count > 15 && st->info->duration_gcd > FFMAX(1, st->time_base.den/(500LL*st->time_base.num)) && !st->r_frame_rate.num) - av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, st->time_base.den, st->time_base.num * st->info->duration_gcd, INT_MAX); - if (st->info->duration_count>1 && !st->r_frame_rate.num - && tb_unreliable(st->codec)) { - int num = 0; - double best_error= 0.01; - - for (j=0; jinfo->codec_info_duration && st->info->codec_info_duration*av_q2d(st->time_base) < (1001*12.0)/get_std_framerate(j)) - continue; - if(!st->info->codec_info_duration && 1.0 < (1001*12.0)/get_std_framerate(j)) - continue; - for(k=0; k<2; k++){ - int n= st->info->duration_count; - double a= st->info->duration_error[k][0][j] / n; - double error= st->info->duration_error[k][1][j]/n - a*a; - - if(error < best_error && best_error> 0.000000001){ - best_error= error; - num = get_std_framerate(j); - } - if(error < 0.02) - av_log(NULL, AV_LOG_DEBUG, "rfps: %f %f\n", get_std_framerate(j) / 12.0/1001, error); - } - } - // do not increase frame rate by more than 1 % in order to match a standard rate. - if (num && (!st->r_frame_rate.num || (double)num/(12*1001) < 1.01 * av_q2d(st->r_frame_rate))) - av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, num, 12*1001, INT_MAX); + best_fps, 12 * 1001, INT_MAX); } - if (!st->r_frame_rate.num){ - if( st->codec->time_base.den * (int64_t)st->time_base.num - <= st->codec->time_base.num * st->codec->ticks_per_frame * (int64_t)st->time_base.den){ + if (!st->r_frame_rate.num) { + if ( st->codec->time_base.den * (int64_t) st->time_base.num + <= st->codec->time_base.num * st->codec->ticks_per_frame * (int64_t) st->time_base.den) { st->r_frame_rate.num = st->codec->time_base.den; st->r_frame_rate.den = st->codec->time_base.num * st->codec->ticks_per_frame; - }else{ + } else { st->r_frame_rate.num = st->time_base.den; st->r_frame_rate.den = st->time_base.num; } } - }else if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - if(!st->codec->bits_per_coded_sample) - st->codec->bits_per_coded_sample= av_get_bits_per_sample(st->codec->codec_id); + } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { + if (!st->codec->bits_per_coded_sample) + st->codec->bits_per_coded_sample = + av_get_bits_per_sample(st->codec->codec_id); // set stream disposition based on audio service type switch (st->codec->audio_service_type) { case AV_AUDIO_SERVICE_TYPE_EFFECTS: - st->disposition = AV_DISPOSITION_CLEAN_EFFECTS; break; + st->disposition = AV_DISPOSITION_CLEAN_EFFECTS; + break; case AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED: - st->disposition = AV_DISPOSITION_VISUAL_IMPAIRED; break; + st->disposition = AV_DISPOSITION_VISUAL_IMPAIRED; + break; case AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED: - st->disposition = AV_DISPOSITION_HEARING_IMPAIRED; break; + st->disposition = AV_DISPOSITION_HEARING_IMPAIRED; + break; case AV_AUDIO_SERVICE_TYPE_COMMENTARY: - st->disposition = AV_DISPOSITION_COMMENT; break; + st->disposition = AV_DISPOSITION_COMMENT; + break; case AV_AUDIO_SERVICE_TYPE_KARAOKE: - st->disposition = AV_DISPOSITION_KARAOKE; break; - default:break; + st->disposition = AV_DISPOSITION_KARAOKE; + break; } } } - if(ic->probesize) + if (ic->probesize) estimate_timings(ic, old_offset); if (ret >= 0 && ic->nb_streams) - ret = -1; /* we could not have all the codec parameters before EOF */ - for(i=0;inb_streams;i++) { + /* We could not have all the codec parameters before EOF. */ + ret = -1; + for (i = 0; i < ic->nb_streams; i++) { const char *errmsg; st = ic->streams[i]; if (!has_codec_parameters(st, &errmsg)) { @@ -3098,17 +3392,18 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) compute_chapters_end(ic); - find_stream_info_err: - for (i=0; i < ic->nb_streams; i++) { +find_stream_info_err: + for (i = 0; i < ic->nb_streams; i++) { st = ic->streams[i]; - if (ic->streams[i]->codec && ic->streams[i]->codec->codec_type != AVMEDIA_TYPE_AUDIO) + if (ic->streams[i]->codec->codec_type != AVMEDIA_TYPE_AUDIO) ic->streams[i]->codec->thread_count = 0; if (st->info) av_freep(&st->info->duration_error); av_freep(&ic->streams[i]->info); } - if(ic->pb) - av_log(ic, AV_LOG_DEBUG, "File position after avformat_find_stream_info() is %"PRId64"\n", avio_tell(ic->pb)); + if (ic->pb) + av_log(ic, AV_LOG_DEBUG, "After avformat_find_stream_info() pos: %"PRId64" bytes read:%"PRId64" seeks:%d frames:%d\n", + avio_tell(ic->pb), ic->pb->bytes_read, ic->pb->seek_count, count); return ret; } @@ -3129,37 +3424,38 @@ AVProgram *av_find_program_from_stream(AVFormatContext *ic, AVProgram *last, int return NULL; } -int av_find_best_stream(AVFormatContext *ic, - enum AVMediaType type, - int wanted_stream_nb, - int related_stream, - const AVCodec **decoder_ret, - int flags) +int av_find_best_stream(AVFormatContext *ic, enum AVMediaType type, + int wanted_stream_nb, int related_stream, + AVCodec **decoder_ret, int flags) { int i, nb_streams = ic->nb_streams; int ret = AVERROR_STREAM_NOT_FOUND, best_count = -1, best_bitrate = -1, best_multiframe = -1, count, bitrate, multiframe; unsigned *program = NULL; - const AVCodec *decoder = NULL, *best_decoder = NULL; + AVCodec *decoder = NULL, *best_decoder = NULL; if (related_stream >= 0 && wanted_stream_nb < 0) { AVProgram *p = av_find_program_from_stream(ic, NULL, related_stream); if (p) { - program = p->stream_index; + program = p->stream_index; nb_streams = p->nb_stream_indexes; } } for (i = 0; i < nb_streams; i++) { int real_stream_index = program ? program[i] : i; - AVStream *st = ic->streams[real_stream_index]; + AVStream *st = ic->streams[real_stream_index]; AVCodecContext *avctx = st->codec; if (avctx->codec_type != type) continue; if (wanted_stream_nb >= 0 && real_stream_index != wanted_stream_nb) continue; - if (st->disposition & (AV_DISPOSITION_HEARING_IMPAIRED|AV_DISPOSITION_VISUAL_IMPAIRED)) + if (wanted_stream_nb != real_stream_index && + st->disposition & (AV_DISPOSITION_HEARING_IMPAIRED | + AV_DISPOSITION_VISUAL_IMPAIRED)) + continue; + if (type == AVMEDIA_TYPE_AUDIO && !avctx->channels) continue; if (decoder_ret) { - decoder = find_decoder(st, st->codec->codec_id); + decoder = find_decoder(ic, st, st->codec->codec_id); if (!decoder) { if (ret < 0) ret = AVERROR_DECODER_NOT_FOUND; @@ -3173,15 +3469,16 @@ int av_find_best_stream(AVFormatContext *ic, (best_multiframe == multiframe && best_bitrate > bitrate) || (best_multiframe == multiframe && best_bitrate == bitrate && best_count >= count)) continue; - best_count = count; + best_count = count; best_bitrate = bitrate; best_multiframe = multiframe; - ret = real_stream_index; + ret = real_stream_index; best_decoder = decoder; if (program && i == nb_streams - 1 && ret < 0) { - program = NULL; + program = NULL; nb_streams = ic->nb_streams; - i = 0; /* no related stream found, try again with everything */ + /* no related stream found, try again with everything */ + i = 0; } } if (decoder_ret) @@ -3209,9 +3506,9 @@ int av_read_pause(AVFormatContext *s) return AVERROR(ENOSYS); } -void ff_free_stream(AVFormatContext *s, AVStream *st){ +void ff_free_stream(AVFormatContext *s, AVStream *st) { av_assert0(s->nb_streams>0); - av_assert0(s->streams[ s->nb_streams-1 ] == st); + av_assert0(s->streams[ s->nb_streams - 1 ] == st); if (st->parser) { av_parser_close(st->parser); @@ -3242,23 +3539,24 @@ void avformat_free_context(AVFormatContext *s) if (s->iformat && s->iformat->priv_class && s->priv_data) av_opt_free(s->priv_data); - for(i=s->nb_streams-1; i>=0; i--) { + for (i = s->nb_streams - 1; i >= 0; i--) { ff_free_stream(s, s->streams[i]); } - for(i=s->nb_programs-1; i>=0; i--) { + for (i = s->nb_programs - 1; i >= 0; i--) { av_dict_free(&s->programs[i]->metadata); av_freep(&s->programs[i]->stream_index); av_freep(&s->programs[i]); } av_freep(&s->programs); av_freep(&s->priv_data); - while(s->nb_chapters--) { + while (s->nb_chapters--) { av_dict_free(&s->chapters[s->nb_chapters]->metadata); av_freep(&s->chapters[s->nb_chapters]); } av_freep(&s->chapters); av_dict_free(&s->metadata); av_freep(&s->streams); + av_freep(&s->internal); av_free(s); } @@ -3277,7 +3575,7 @@ void avformat_close_input(AVFormatContext **ps) if (!ps || !*ps) return; - s = *ps; + s = *ps; pb = s->pb; if ((s->iformat && s->iformat->flags & AVFMT_NOFILE) || @@ -3286,10 +3584,9 @@ void avformat_close_input(AVFormatContext **ps) flush_packet_queue(s); - if (s->iformat) { + if (s->iformat) if (s->iformat->read_close) s->iformat->read_close(s); - } avformat_free_context(s); @@ -3331,19 +3628,18 @@ AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c) st->info->last_dts = AV_NOPTS_VALUE; st->codec = avcodec_alloc_context3(c); - if (s->iformat) { + if (s->iformat) /* no default bitrate if decoding */ st->codec->bit_rate = 0; - } - st->index = s->nb_streams; + st->index = s->nb_streams; st->start_time = AV_NOPTS_VALUE; - st->duration = AV_NOPTS_VALUE; - /* we set the current DTS to 0 so that formats without any timestamps - but durations get some timestamps, formats with some unknown - timestamps have their first few packets buffered and the - timestamps corrected before they are returned to the user */ - st->cur_dts = s->iformat ? RELATIVE_TS_BASE : 0; - st->first_dts = AV_NOPTS_VALUE; + st->duration = AV_NOPTS_VALUE; + /* we set the current DTS to 0 so that formats without any timestamps + * but durations get some timestamps, formats with some unknown + * timestamps have their first few packets buffered and the + * timestamps corrected before they are returned to the user */ + st->cur_dts = s->iformat ? RELATIVE_TS_BASE : 0; + st->first_dts = AV_NOPTS_VALUE; st->probe_packets = MAX_PROBE_PACKETS; st->pts_wrap_reference = AV_NOPTS_VALUE; st->pts_wrap_behavior = AV_PTS_WRAP_IGNORE; @@ -3351,11 +3647,11 @@ AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c) /* default pts setting is MPEG-like */ avpriv_set_pts_info(st, 33, 1, 90000); st->last_IP_pts = AV_NOPTS_VALUE; - for(i=0; ipts_buffer[i]= AV_NOPTS_VALUE; - st->reference_dts = AV_NOPTS_VALUE; + st->last_dts_for_order_check = AV_NOPTS_VALUE; + for (i = 0; i < MAX_REORDER_DELAY + 1; i++) + st->pts_buffer[i] = AV_NOPTS_VALUE; - st->sample_aspect_ratio = (AVRational){0,1}; + st->sample_aspect_ratio = (AVRational) { 0, 1 }; #if FF_API_R_FRAME_RATE st->info->last_dts = AV_NOPTS_VALUE; @@ -3369,20 +3665,20 @@ AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c) AVProgram *av_new_program(AVFormatContext *ac, int id) { - AVProgram *program=NULL; + AVProgram *program = NULL; int i; av_dlog(ac, "new_program: id=0x%04x\n", id); - for(i=0; inb_programs; i++) - if(ac->programs[i]->id == id) + for (i = 0; i < ac->nb_programs; i++) + if (ac->programs[i]->id == id) program = ac->programs[i]; - if(!program){ + if (!program) { program = av_mallocz(sizeof(AVProgram)); if (!program) return NULL; - dynarray_add(&ac->programs, (int *) &ac->nb_programs, program); + dynarray_add(&ac->programs, &ac->nb_programs, program); program->discard = AVDISCARD_NONE; } program->id = id; @@ -3395,34 +3691,35 @@ AVProgram *av_new_program(AVFormatContext *ac, int id) return program; } -AVChapter *avpriv_new_chapter(AVFormatContext *s, int id, AVRational time_base, int64_t start, int64_t end, const char *title) +AVChapter *avpriv_new_chapter(AVFormatContext *s, int id, AVRational time_base, + int64_t start, int64_t end, const char *title) { AVChapter *chapter = NULL; int i; - for(i=0; inb_chapters; i++) - if(s->chapters[i]->id == id) + for (i = 0; i < s->nb_chapters; i++) + if (s->chapters[i]->id == id) chapter = s->chapters[i]; - if(!chapter){ - chapter= av_mallocz(sizeof(AVChapter)); - if(!chapter) + if (!chapter) { + chapter = av_mallocz(sizeof(AVChapter)); + if (!chapter) return NULL; - dynarray_add(&s->chapters, (int *) &s->nb_chapters, chapter); + dynarray_add(&s->chapters, &s->nb_chapters, chapter); } av_dict_set(&chapter->metadata, "title", title, 0); - chapter->id = id; - chapter->time_base= time_base; - chapter->start = start; - chapter->end = end; + chapter->id = id; + chapter->time_base = time_base; + chapter->start = start; + chapter->end = end; return chapter; } -void ff_program_add_stream_index(AVFormatContext *ac, int progid, unsigned int idx) +void ff_program_add_stream_index(AVFormatContext *ac, int progid, unsigned idx) { int i, j; - AVProgram *program=NULL; + AVProgram *program = NULL; void *tmp; if (idx >= ac->nb_streams) { @@ -3430,16 +3727,16 @@ void ff_program_add_stream_index(AVFormatContext *ac, int progid, unsigned int i return; } - for(i=0; inb_programs; i++){ - if(ac->programs[i]->id != progid) + for (i = 0; i < ac->nb_programs; i++) { + if (ac->programs[i]->id != progid) continue; program = ac->programs[i]; - for(j=0; jnb_stream_indexes; j++) - if(program->stream_index[j] == idx) + for (j = 0; j < program->nb_stream_indexes; j++) + if (program->stream_index[j] == idx) return; tmp = av_realloc_array(program->stream_index, program->nb_stream_indexes+1, sizeof(unsigned int)); - if(!tmp) + if (!tmp) return; program->stream_index = tmp; program->stream_index[program->nb_stream_indexes++] = idx; @@ -3447,24 +3744,29 @@ void ff_program_add_stream_index(AVFormatContext *ac, int progid, unsigned int i } } -static void print_fps(double d, const char *postfix){ - uint64_t v= lrintf(d*100); - if (v% 100 ) av_log(NULL, AV_LOG_INFO, ", %3.2f %s", d, postfix); - else if(v%(100*1000)) av_log(NULL, AV_LOG_INFO, ", %1.0f %s", d, postfix); - else av_log(NULL, AV_LOG_INFO, ", %1.0fk %s", d/1000, postfix); +static void print_fps(double d, const char *postfix) +{ + uint64_t v = lrintf(d * 100); + if (v % 100) + av_log(NULL, AV_LOG_INFO, ", %3.2f %s", d, postfix); + else if (v % (100 * 1000)) + av_log(NULL, AV_LOG_INFO, ", %1.0f %s", d, postfix); + else + av_log(NULL, AV_LOG_INFO, ", %1.0fk %s", d / 1000, postfix); } static void dump_metadata(void *ctx, AVDictionary *m, const char *indent) { - if(m && !(av_dict_count(m) == 1 && av_dict_get(m, "language", NULL, 0))){ - AVDictionaryEntry *tag=NULL; + if (m && !(av_dict_count(m) == 1 && av_dict_get(m, "language", NULL, 0))) { + AVDictionaryEntry *tag = NULL; av_log(ctx, AV_LOG_INFO, "%sMetadata:\n", indent); - while((tag=av_dict_get(m, "", tag, AV_DICT_IGNORE_SUFFIX))) { - if(strcmp("language", tag->key)){ + while ((tag = av_dict_get(m, "", tag, AV_DICT_IGNORE_SUFFIX))) + if (strcmp("language", tag->key)) { const char *p = tag->value; - av_log(ctx, AV_LOG_INFO, "%s %-16s: ", indent, tag->key); - while(*p) { + av_log(ctx, AV_LOG_INFO, + "%s %-16s: ", indent, tag->key); + while (*p) { char tmp[256]; size_t len = strcspn(p, "\x8\xa\xb\xc\xd"); av_strlcpy(tmp, p, FFMIN(sizeof(tmp), len+1)); @@ -3476,12 +3778,12 @@ static void dump_metadata(void *ctx, AVDictionary *m, const char *indent) } av_log(ctx, AV_LOG_INFO, "\n"); } - } } } /* "user interface" functions */ -static void dump_stream_format(AVFormatContext *ic, int i, int index, int is_output) +static void dump_stream_format(AVFormatContext *ic, int i, + int index, int is_output) { char buf[256]; int flags = (is_output ? ic->oformat->flags : ic->iformat->flags); @@ -3496,30 +3798,31 @@ static void dump_stream_format(AVFormatContext *ic, int i, int index, int is_out av_log(NULL, AV_LOG_INFO, "[0x%x]", st->id); if (lang) av_log(NULL, AV_LOG_INFO, "(%s)", lang->value); - av_log(NULL, AV_LOG_DEBUG, ", %d, %d/%d", st->codec_info_nb_frames, st->time_base.num/g, st->time_base.den/g); + av_log(NULL, AV_LOG_DEBUG, ", %d, %d/%d", st->codec_info_nb_frames, + st->time_base.num / g, st->time_base.den / g); av_log(NULL, AV_LOG_INFO, ": %s", buf); if (st->sample_aspect_ratio.num && // default av_cmp_q(st->sample_aspect_ratio, st->codec->sample_aspect_ratio)) { AVRational display_aspect_ratio; av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den, - st->codec->width*st->sample_aspect_ratio.num, - st->codec->height*st->sample_aspect_ratio.den, - 1024*1024); + st->codec->width * st->sample_aspect_ratio.num, + st->codec->height * st->sample_aspect_ratio.den, + 1024 * 1024); av_log(NULL, AV_LOG_INFO, ", SAR %d:%d DAR %d:%d", - st->sample_aspect_ratio.num, st->sample_aspect_ratio.den, - display_aspect_ratio.num, display_aspect_ratio.den); + st->sample_aspect_ratio.num, st->sample_aspect_ratio.den, + display_aspect_ratio.num, display_aspect_ratio.den); } - if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO){ - if(st->avg_frame_rate.den && st->avg_frame_rate.num) + if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { + if (st->avg_frame_rate.den && st->avg_frame_rate.num) print_fps(av_q2d(st->avg_frame_rate), "fps"); #if FF_API_R_FRAME_RATE - if(st->r_frame_rate.den && st->r_frame_rate.num) + if (st->r_frame_rate.den && st->r_frame_rate.num) print_fps(av_q2d(st->r_frame_rate), "tbr"); #endif - if(st->time_base.den && st->time_base.num) - print_fps(1/av_q2d(st->time_base), "tbn"); - if(st->codec->time_base.den && st->codec->time_base.num) - print_fps(1/av_q2d(st->codec->time_base), "tbc"); + if (st->time_base.den && st->time_base.num) + print_fps(1 / av_q2d(st->time_base), "tbn"); + if (st->codec->time_base.den && st->codec->time_base.num) + print_fps(1 / av_q2d(st->codec->time_base), "tbc"); } if (st->disposition & AV_DISPOSITION_DEFAULT) av_log(NULL, AV_LOG_INFO, " (default)"); @@ -3545,10 +3848,8 @@ static void dump_stream_format(AVFormatContext *ic, int i, int index, int is_out dump_metadata(NULL, st->metadata, " "); } -void av_dump_format(AVFormatContext *ic, - int index, - const char *url, - int is_output) +void av_dump_format(AVFormatContext *ic, int index, + const char *url, int is_output) { int i; uint8_t *printed = ic->nb_streams ? av_mallocz(ic->nb_streams) : NULL; @@ -3556,19 +3857,19 @@ void av_dump_format(AVFormatContext *ic, return; av_log(NULL, AV_LOG_INFO, "%s #%d, %s, %s '%s':\n", - is_output ? "Output" : "Input", - index, - is_output ? ic->oformat->name : ic->iformat->name, - is_output ? "to" : "from", url); + is_output ? "Output" : "Input", + index, + is_output ? ic->oformat->name : ic->iformat->name, + is_output ? "to" : "from", url); dump_metadata(NULL, ic->metadata, " "); if (!is_output) { av_log(NULL, AV_LOG_INFO, " Duration: "); if (ic->duration != AV_NOPTS_VALUE) { int hours, mins, secs, us; int64_t duration = ic->duration + 5000; - secs = duration / AV_TIME_BASE; - us = duration % AV_TIME_BASE; - mins = secs / 60; + secs = duration / AV_TIME_BASE; + us = duration % AV_TIME_BASE; + mins = secs / 60; secs %= 60; hours = mins / 60; mins %= 60; @@ -3581,36 +3882,38 @@ void av_dump_format(AVFormatContext *ic, int secs, us; av_log(NULL, AV_LOG_INFO, ", start: "); secs = ic->start_time / AV_TIME_BASE; - us = abs(ic->start_time % AV_TIME_BASE); + us = abs(ic->start_time % AV_TIME_BASE); av_log(NULL, AV_LOG_INFO, "%d.%06d", - secs, (int)av_rescale(us, 1000000, AV_TIME_BASE)); + secs, (int) av_rescale(us, 1000000, AV_TIME_BASE)); } av_log(NULL, AV_LOG_INFO, ", bitrate: "); - if (ic->bit_rate) { - av_log(NULL, AV_LOG_INFO,"%d kb/s", ic->bit_rate / 1000); - } else { + if (ic->bit_rate) + av_log(NULL, AV_LOG_INFO, "%d kb/s", ic->bit_rate / 1000); + else av_log(NULL, AV_LOG_INFO, "N/A"); - } av_log(NULL, AV_LOG_INFO, "\n"); } for (i = 0; i < ic->nb_chapters; i++) { AVChapter *ch = ic->chapters[i]; av_log(NULL, AV_LOG_INFO, " Chapter #%d.%d: ", index, i); - av_log(NULL, AV_LOG_INFO, "start %f, ", ch->start * av_q2d(ch->time_base)); - av_log(NULL, AV_LOG_INFO, "end %f\n", ch->end * av_q2d(ch->time_base)); + av_log(NULL, AV_LOG_INFO, + "start %f, ", ch->start * av_q2d(ch->time_base)); + av_log(NULL, AV_LOG_INFO, + "end %f\n", ch->end * av_q2d(ch->time_base)); dump_metadata(NULL, ch->metadata, " "); } - if(ic->nb_programs) { + if (ic->nb_programs) { int j, k, total = 0; - for(j=0; jnb_programs; j++) { + for (j = 0; j < ic->nb_programs; j++) { AVDictionaryEntry *name = av_dict_get(ic->programs[j]->metadata, "name", NULL, 0); av_log(NULL, AV_LOG_INFO, " Program %d %s\n", ic->programs[j]->id, name ? name->value : ""); dump_metadata(NULL, ic->programs[j]->metadata, " "); - for(k=0; kprograms[j]->nb_stream_indexes; k++) { - dump_stream_format(ic, ic->programs[j]->stream_index[k], index, is_output); + for (k = 0; k < ic->programs[j]->nb_stream_indexes; k++) { + dump_stream_format(ic, ic->programs[j]->stream_index[k], + index, is_output); printed[ic->programs[j]->stream_index[k]] = 1; } total += ic->programs[j]->nb_stream_indexes; @@ -3618,7 +3921,7 @@ void av_dump_format(AVFormatContext *ic, if (total < ic->nb_streams) av_log(NULL, AV_LOG_INFO, " No Program\n"); } - for(i=0;inb_streams;i++) + for (i = 0; i < ic->nb_streams; i++) if (!printed[i]) dump_stream_format(ic, i, index, is_output); @@ -3627,11 +3930,10 @@ void av_dump_format(AVFormatContext *ic, uint64_t ff_ntp_time(void) { - return (av_gettime() / 1000) * 1000 + NTP_OFFSET_US; + return (av_gettime() / 1000) * 1000 + NTP_OFFSET_US; } -int av_get_frame_filename(char *buf, int buf_size, - const char *path, int number) +int av_get_frame_filename(char *buf, int buf_size, const char *path, int number) { const char *p; char *q, buf1[20], c; @@ -3640,20 +3942,19 @@ int av_get_frame_filename(char *buf, int buf_size, q = buf; p = path; percentd_found = 0; - for(;;) { + for (;;) { c = *p++; if (c == '\0') break; if (c == '%') { do { nd = 0; - while (av_isdigit(*p)) { + while (av_isdigit(*p)) nd = nd * 10 + *p++ - '0'; - } c = *p++; } while (av_isdigit(c)); - switch(c) { + switch (c) { case '%': goto addchar; case 'd': @@ -3671,7 +3972,7 @@ int av_get_frame_filename(char *buf, int buf_size, goto fail; } } else { - addchar: +addchar: if ((q - buf) < buf_size - 1) *q++ = c; } @@ -3680,38 +3981,44 @@ int av_get_frame_filename(char *buf, int buf_size, goto fail; *q = '\0'; return 0; - fail: +fail: *q = '\0'; return -1; } +#define HEXDUMP_PRINT(...) \ + do { \ + if (!f) \ + av_log(avcl, level, __VA_ARGS__); \ + else \ + fprintf(f, __VA_ARGS__); \ + } while (0) + static void hex_dump_internal(void *avcl, FILE *f, int level, const uint8_t *buf, int size) { int len, i, j, c; -#define PRINT(...) do { if (!f) av_log(avcl, level, __VA_ARGS__); else fprintf(f, __VA_ARGS__); } while(0) - for(i=0;i 16) len = 16; - PRINT("%08x ", i); - for(j=0;j<16;j++) { + HEXDUMP_PRINT("%08x ", i); + for (j = 0; j < 16; j++) { if (j < len) - PRINT(" %02x", buf[i+j]); + HEXDUMP_PRINT(" %02x", buf[i + j]); else - PRINT(" "); + HEXDUMP_PRINT(" "); } - PRINT(" "); - for(j=0;j '~') c = '.'; - PRINT("%c", c); + HEXDUMP_PRINT("%c", c); } - PRINT("\n"); + HEXDUMP_PRINT("\n"); } -#undef PRINT } void av_hex_dump(FILE *f, const uint8_t *buf, int size) @@ -3724,27 +4031,26 @@ void av_hex_dump_log(void *avcl, int level, const uint8_t *buf, int size) hex_dump_internal(avcl, NULL, level, buf, size); } -static void pkt_dump_internal(void *avcl, FILE *f, int level, AVPacket *pkt, int dump_payload, AVRational time_base) +static void pkt_dump_internal(void *avcl, FILE *f, int level, AVPacket *pkt, + int dump_payload, AVRational time_base) { -#define PRINT(...) do { if (!f) av_log(avcl, level, __VA_ARGS__); else fprintf(f, __VA_ARGS__); } while(0) - PRINT("stream #%d:\n", pkt->stream_index); - PRINT(" keyframe=%d\n", ((pkt->flags & AV_PKT_FLAG_KEY) != 0)); - PRINT(" duration=%0.3f\n", pkt->duration * av_q2d(time_base)); + HEXDUMP_PRINT("stream #%d:\n", pkt->stream_index); + HEXDUMP_PRINT(" keyframe=%d\n", (pkt->flags & AV_PKT_FLAG_KEY) != 0); + HEXDUMP_PRINT(" duration=%0.3f\n", pkt->duration * av_q2d(time_base)); /* DTS is _always_ valid after av_read_frame() */ - PRINT(" dts="); + HEXDUMP_PRINT(" dts="); if (pkt->dts == AV_NOPTS_VALUE) - PRINT("N/A"); + HEXDUMP_PRINT("N/A"); else - PRINT("%0.3f", pkt->dts * av_q2d(time_base)); + HEXDUMP_PRINT("%0.3f", pkt->dts * av_q2d(time_base)); /* PTS may not be known if B-frames are present. */ - PRINT(" pts="); + HEXDUMP_PRINT(" pts="); if (pkt->pts == AV_NOPTS_VALUE) - PRINT("N/A"); + HEXDUMP_PRINT("N/A"); else - PRINT("%0.3f", pkt->pts * av_q2d(time_base)); - PRINT("\n"); - PRINT(" size=%d\n", pkt->size); -#undef PRINT + HEXDUMP_PRINT("%0.3f", pkt->pts * av_q2d(time_base)); + HEXDUMP_PRINT("\n"); + HEXDUMP_PRINT(" size=%d\n", pkt->size); if (dump_payload) av_hex_dump(f, pkt->data, pkt->size); } @@ -3763,24 +4069,29 @@ void av_pkt_dump_log2(void *avcl, int level, AVPacket *pkt, int dump_payload, void av_url_split(char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, - int *port_ptr, - char *path, int path_size, - const char *url) + int *port_ptr, char *path, int path_size, const char *url) { const char *p, *ls, *ls2, *at, *at2, *col, *brk; - if (port_ptr) *port_ptr = -1; - if (proto_size > 0) proto[0] = 0; - if (authorization_size > 0) authorization[0] = 0; - if (hostname_size > 0) hostname[0] = 0; - if (path_size > 0) path[0] = 0; + if (port_ptr) + *port_ptr = -1; + if (proto_size > 0) + proto[0] = 0; + if (authorization_size > 0) + authorization[0] = 0; + if (hostname_size > 0) + hostname[0] = 0; + if (path_size > 0) + path[0] = 0; /* parse protocol */ if ((p = strchr(url, ':'))) { av_strlcpy(proto, url, FFMIN(proto_size, p + 1 - url)); p++; /* skip ':' */ - if (*p == '/') p++; - if (*p == '/') p++; + if (*p == '/') + p++; + if (*p == '/') + p++; } else { /* no protocol means plain filename */ av_strlcpy(path, url, path_size); @@ -3790,14 +4101,14 @@ void av_url_split(char *proto, int proto_size, /* separate path from hostname */ ls = strchr(p, '/'); ls2 = strchr(p, '?'); - if(!ls) + if (!ls) ls = ls2; else if (ls && ls2) ls = FFMIN(ls, ls2); - if(ls) + if (ls) av_strlcpy(path, ls, path_size); else - ls = &p[strlen(p)]; // XXX + ls = &p[strlen(p)]; // XXX /* the rest is hostname, use that to parse auth/port */ if (ls != p) { @@ -3818,7 +4129,8 @@ void av_url_split(char *proto, int proto_size, } else if ((col = strchr(p, ':')) && col < ls) { av_strlcpy(hostname, p, FFMIN(col + 1 - p, hostname_size)); - if (port_ptr) *port_ptr = atoi(col + 1); + if (port_ptr) + *port_ptr = atoi(col + 1); } else av_strlcpy(hostname, p, FFMIN(ls + 1 - p, hostname_size)); @@ -3838,7 +4150,7 @@ char *ff_data_to_hex(char *buff, const uint8_t *src, int s, int lowercase) 'c', 'd', 'e', 'f' }; const char *hex_table = lowercase ? hex_table_lc : hex_table_uc; - for(i = 0; i < s; i++) { + for (i = 0; i < s; i++) { buff[i * 2] = hex_table[src[i] >> 4]; buff[i * 2 + 1] = hex_table[src[i] & 0xF]; } @@ -3851,7 +4163,7 @@ int ff_hex_to_data(uint8_t *data, const char *p) int c, len, v; len = 0; - v = 1; + v = 1; for (;;) { p += strspn(p, SPACE_CHARS); if (*p == '\0') @@ -3886,17 +4198,23 @@ void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den) { AVRational new_tb; - if(av_reduce(&new_tb.num, &new_tb.den, pts_num, pts_den, INT_MAX)){ - if(new_tb.num != pts_num) - av_log(NULL, AV_LOG_DEBUG, "st:%d removing common factor %d from timebase\n", s->index, pts_num/new_tb.num); - }else - av_log(NULL, AV_LOG_WARNING, "st:%d has too large timebase, reducing\n", s->index); + if (av_reduce(&new_tb.num, &new_tb.den, pts_num, pts_den, INT_MAX)) { + if (new_tb.num != pts_num) + av_log(NULL, AV_LOG_DEBUG, + "st:%d removing common factor %d from timebase\n", + s->index, pts_num / new_tb.num); + } else + av_log(NULL, AV_LOG_WARNING, + "st:%d has too large timebase, reducing\n", s->index); - if(new_tb.num <= 0 || new_tb.den <= 0) { - av_log(NULL, AV_LOG_ERROR, "Ignoring attempt to set invalid timebase %d/%d for st:%d\n", new_tb.num, new_tb.den, s->index); + if (new_tb.num <= 0 || new_tb.den <= 0) { + av_log(NULL, AV_LOG_ERROR, + "Ignoring attempt to set invalid timebase %d/%d for st:%d\n", + new_tb.num, new_tb.den, + s->index); return; } - s->time_base = new_tb; + s->time_base = new_tb; av_codec_set_pkt_timebase(s->codec, new_tb); s->pts_wrap_bits = pts_wrap_bits; } @@ -3958,16 +4276,15 @@ void ff_parse_key_value(const char *str, ff_parse_key_val_cb callback_get_buf, int ff_find_stream_index(AVFormatContext *s, int id) { int i; - for (i = 0; i < s->nb_streams; i++) { + for (i = 0; i < s->nb_streams; i++) if (s->streams[i]->id == id) return i; - } return -1; } int64_t ff_iso8601_to_unix_time(const char *datestr) { - struct tm time1 = {0}, time2 = {0}; + struct tm time1 = { 0 }, time2 = { 0 }; char *ret1, *ret2; ret1 = av_small_strptime(datestr, "%Y - %m - %d %H:%M:%S", &time1); ret2 = av_small_strptime(datestr, "%Y - %m - %dT%H:%M:%S", &time2); @@ -3977,14 +4294,16 @@ int64_t ff_iso8601_to_unix_time(const char *datestr) return av_timegm(&time1); } -int avformat_query_codec(AVOutputFormat *ofmt, enum AVCodecID codec_id, int std_compliance) +int avformat_query_codec(AVOutputFormat *ofmt, enum AVCodecID codec_id, + int std_compliance) { if (ofmt) { if (ofmt->query_codec) return ofmt->query_codec(codec_id, std_compliance); else if (ofmt->codec_tag) return !!av_codec_get_tag(ofmt->codec_tag, codec_id); - else if (codec_id == ofmt->video_codec || codec_id == ofmt->audio_codec || + else if (codec_id == ofmt->video_codec || + codec_id == ofmt->audio_codec || codec_id == ofmt->subtitle_codec) return 1; } @@ -4022,19 +4341,19 @@ int ff_add_param_change(AVPacket *pkt, int32_t channels, if (!pkt) return AVERROR(EINVAL); if (channels) { - size += 4; + size += 4; flags |= AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT; } if (channel_layout) { - size += 8; + size += 8; flags |= AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT; } if (sample_rate) { - size += 4; + size += 4; flags |= AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE; } if (width || height) { - size += 8; + size += 8; flags |= AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS; } data = av_packet_new_side_data(pkt, AV_PKT_DATA_PARAM_CHANGE, size); @@ -4080,10 +4399,16 @@ AVRational av_guess_sample_aspect_ratio(AVFormatContext *format, AVStream *strea AVRational av_guess_frame_rate(AVFormatContext *format, AVStream *st, AVFrame *frame) { AVRational fr = st->r_frame_rate; + AVRational codec_fr = av_inv_q(st->codec->time_base); + AVRational avg_fr = st->avg_frame_rate; + + if (avg_fr.num > 0 && avg_fr.den > 0 && fr.num > 0 && fr.den > 0 && + av_q2d(avg_fr) < 70 && av_q2d(fr) > 210) { + fr = avg_fr; + } + if (st->codec->ticks_per_frame > 1) { - AVRational codec_fr = av_inv_q(st->codec->time_base); - AVRational avg_fr = st->avg_frame_rate; codec_fr.den *= st->codec->ticks_per_frame; if ( codec_fr.num > 0 && codec_fr.den > 0 && av_q2d(codec_fr) < av_q2d(fr)*0.7 && fabs(1.0 - av_q2d(av_div_q(avg_fr, fr))) > 0.1) @@ -4154,7 +4479,7 @@ int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st, return AVERROR(EINVAL); } -void ff_generate_avci_extradata(AVStream *st) +int ff_generate_avci_extradata(AVStream *st) { static const uint8_t avci100_1080p_extradata[] = { // SPS @@ -4221,8 +4546,10 @@ void ff_generate_avci_extradata(AVStream *st) 0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x31, 0x12, 0x11 }; - int size = 0; - const uint8_t *data = 0; + + const uint8_t *data = NULL; + int size = 0; + if (st->codec->width == 1920) { if (st->codec->field_order == AV_FIELD_PROGRESSIVE) { data = avci100_1080p_extradata; @@ -4238,13 +4565,14 @@ void ff_generate_avci_extradata(AVStream *st) data = avci100_720p_extradata; size = sizeof(avci100_720p_extradata); } + if (!size) - return; + return 0; + av_freep(&st->codec->extradata); - st->codec->extradata_size = 0; - st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return; + if (ff_alloc_extradata(st->codec, size)) + return AVERROR(ENOMEM); memcpy(st->codec->extradata, data, size); - st->codec->extradata_size = size; + + return 0; } diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/version.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/version.h index 10b6a36b9..f9fc9d830 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/version.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/version.h @@ -27,11 +27,11 @@ * Libavformat version macros */ -#include "libavutil/avutil.h" +#include "libavutil/version.h" #define LIBAVFORMAT_VERSION_MAJOR 55 -#define LIBAVFORMAT_VERSION_MINOR 18 -#define LIBAVFORMAT_VERSION_MICRO 104 +#define LIBAVFORMAT_VERSION_MINOR 34 +#define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ @@ -48,6 +48,9 @@ * dropped at a future version bump. The defines themselves are not part of * the public API and may change, break or disappear at any time. */ +#ifndef FF_API_REFERENCE_DTS +#define FF_API_REFERENCE_DTS (LIBAVFORMAT_VERSION_MAJOR < 56) +#endif #ifndef FF_API_ALLOC_OUTPUT_CONTEXT #define FF_API_ALLOC_OUTPUT_CONTEXT (LIBAVFORMAT_VERSION_MAJOR < 56) diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/vqf.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/vqf.c index c47a8578f..66dda8de5 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/vqf.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/vqf.c @@ -43,6 +43,9 @@ static int vqf_probe(AVProbeData *probe_packet) if (!memcmp(probe_packet->buf + 4, "00052200", 8)) return AVPROBE_SCORE_MAX; + if (AV_RL32(probe_packet->buf + 12) > (1<<27)) + return AVPROBE_SCORE_EXTENSION/2; + return AVPROBE_SCORE_EXTENSION; } @@ -220,9 +223,8 @@ static int vqf_read_header(AVFormatContext *s) avpriv_set_pts_info(st, 64, size, st->codec->sample_rate); /* put first 12 bytes of COMM chunk in extradata */ - if (!(st->codec->extradata = av_malloc(12 + FF_INPUT_BUFFER_PADDING_SIZE))) + if (ff_alloc_extradata(st->codec, 12)) return AVERROR(ENOMEM); - st->codec->extradata_size = 12; memcpy(st->codec->extradata, comm_chunk, 12); ff_metadata_conv_ctx(s, NULL, vqf_metadata_conv); @@ -247,7 +249,7 @@ static int vqf_read_packet(AVFormatContext *s, AVPacket *pkt) pkt->data[1] = c->last_frame_bits; ret = avio_read(s->pb, pkt->data+2, size); - if (ret<=0) { + if (ret != size) { av_free_packet(pkt); return AVERROR(EIO); } diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/wavdec.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/wavdec.c index 575a2f3b0..afaf0a0e5 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/wavdec.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/wavdec.c @@ -23,6 +23,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include + #include "config.h" #include "libavutil/avassert.h" @@ -355,10 +357,7 @@ static int wav_read_header(AVFormatContext *s) vst->codec->codec_id = AV_CODEC_ID_SMVJPEG; vst->codec->width = avio_rl24(pb); vst->codec->height = avio_rl24(pb); - vst->codec->extradata_size = 4; - vst->codec->extradata = av_malloc(vst->codec->extradata_size + - FF_INPUT_BUFFER_PADDING_SIZE); - if (!vst->codec->extradata) { + if (ff_alloc_extradata(vst->codec, 4)) { av_log(s, AV_LOG_ERROR, "Could not allocate extradata.\n"); return AVERROR(ENOMEM); } @@ -405,11 +404,15 @@ break_loop: avio_seek(pb, data_ofs, SEEK_SET); - if (!sample_count && st->codec->channels && - av_get_bits_per_sample(st->codec->codec_id) && wav->data_end <= avio_size(pb)) - sample_count = (data_size << 3) / - (st->codec->channels * - (uint64_t)av_get_bits_per_sample(st->codec->codec_id)); + if (!sample_count || av_get_exact_bits_per_sample(st->codec->codec_id) > 0) + if ( st->codec->channels + && data_size + && av_get_bits_per_sample(st->codec->codec_id) + && wav->data_end <= avio_size(pb)) + sample_count = (data_size << 3) + / + (st->codec->channels * (uint64_t)av_get_bits_per_sample(st->codec->codec_id)); + if (sample_count) st->duration = sample_count; @@ -467,8 +470,8 @@ static int wav_read_packet(AVFormatContext *s, AVPacket *pkt) if (wav->smv_data_ofs > 0) { int64_t audio_dts, video_dts; smv_retry: - audio_dts = s->streams[0]->cur_dts; - video_dts = s->streams[1]->cur_dts; + audio_dts = (int32_t)s->streams[0]->cur_dts; + video_dts = (int32_t)s->streams[1]->cur_dts; if (audio_dts != AV_NOPTS_VALUE && video_dts != AV_NOPTS_VALUE) { /*We always return a video frame first to get the pixel format first*/ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/xwma.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/xwma.c index 4591c60c1..9623dd1a3 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/xwma.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavformat/xwma.c @@ -19,13 +19,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "config.h" - #include +#include #include "avformat.h" -#include "internal.h" #include "libavutil/internal.h" +#include "internal.h" #include "riff.h" /* @@ -274,7 +273,7 @@ static int xwma_read_packet(AVFormatContext *s, AVPacket *pkt) AVInputFormat ff_xwma_demuxer = { .name = "xwma", - .long_name = NULL_IF_CONFIG_SMALL("Microsoft xWMA"), + .long_name = "Microsoft xWMA", .priv_data_size = sizeof(XWMAContext), .read_probe = xwma_probe, .read_header = xwma_read_header, diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/attributes.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/attributes.h index 0f8ff423c..7d3f4a91c 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/attributes.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/attributes.h @@ -76,7 +76,7 @@ # define av_cold #endif -#if AV_GCC_VERSION_AT_LEAST(4,1) +#if AV_GCC_VERSION_AT_LEAST(4,1) && !defined(__llvm__) # define av_flatten __attribute__((flatten)) #else # define av_flatten @@ -96,7 +96,7 @@ * scheduled for removal. */ #ifndef AV_NOWARN_DEPRECATED -#if AV_GCC_VERSION_AT_LEAST(4,6) || defined(__clang__) +#if AV_GCC_VERSION_AT_LEAST(4,6) # define AV_NOWARN_DEPRECATED(code) \ _Pragma("GCC diagnostic push") \ _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") \ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/avutil.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/avutil.h index 4986f4f9e..d6566c116 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/avutil.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/avutil.h @@ -41,7 +41,7 @@ * @li @ref lavu "libavutil" common utility library * @li @ref lswr "libswresample" audio resampling, format conversion and mixing * @li @ref lpp "libpostproc" post processing library - * @li @ref lsws "libswscale" color conversion and scaling library + * @li @ref libsws "libswscale" color conversion and scaling library * * @section ffmpeg_versioning Versioning and compatibility * @@ -128,6 +128,12 @@ * * @} * + * @defgroup lavu_log Logging Facility + * + * @{ + * + * @} + * * @defgroup lavu_misc Other * * @{ @@ -139,6 +145,12 @@ * @{ * * @} + * + * @defgroup preproc_misc Preprocessor String Macros + * + * @{ + * + * @} */ @@ -271,9 +283,9 @@ char av_get_picture_type_char(enum AVPictureType pict_type); #include "common.h" #include "error.h" #include "version.h" +#include "macros.h" #include "mathematics.h" #include "rational.h" -#include "intfloat_readwrite.h" #include "log.h" #include "pixfmt.h" @@ -306,6 +318,13 @@ unsigned av_int_list_length_for_size(unsigned elsize, #define av_int_list_length(list, term) \ av_int_list_length_for_size(sizeof(*(list)), list, term) +/** + * Open a file using a UTF-8 filename. + * The API of this function matches POSIX fopen(), errors are returned through + * errno. + */ +FILE *av_fopen_utf8(const char *path, const char *mode); + /** * @} * @} diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/bprint.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/bprint.c index 2535c1728..7786e3bce 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/bprint.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/bprint.c @@ -221,7 +221,7 @@ void av_bprint_get_buffer(AVBPrint *buf, unsigned size, if (size > av_bprint_room(buf)) av_bprint_alloc(buf, size); *actual_size = av_bprint_room(buf); - *mem = *actual_size ? (unsigned char *)buf->str + buf->len : NULL; + *mem = *actual_size ? buf->str + buf->len : NULL; } void av_bprint_clear(AVBPrint *buf) diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/channel_layout.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/channel_layout.c index e5827605e..4c0677f79 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/channel_layout.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/channel_layout.c @@ -23,6 +23,8 @@ * audio channel layout utility functions */ +#include + #include "avstring.h" #include "avutil.h" #include "channel_layout.h" @@ -103,7 +105,11 @@ static const struct { { "downmix", 2, AV_CH_LAYOUT_STEREO_DOWNMIX, }, }; +#if FF_API_GET_CHANNEL_LAYOUT_COMPAT +static uint64_t get_channel_layout_single(const char *name, int name_len, int compat) +#else static uint64_t get_channel_layout_single(const char *name, int name_len) +#endif { int i; char *end; @@ -120,16 +126,40 @@ static uint64_t get_channel_layout_single(const char *name, int name_len) !memcmp(channel_names[i].name, name, name_len)) return (int64_t)1 << i; i = strtol(name, &end, 10); - if (end - name == name_len || - (end + 1 - name == name_len && *end == 'c')) + +#if FF_API_GET_CHANNEL_LAYOUT_COMPAT + if (compat) { + if (end - name == name_len || + (end + 1 - name == name_len && *end == 'c')) { + layout = av_get_default_channel_layout(i); + if (end - name == name_len) { + av_log(NULL, AV_LOG_WARNING, + "Single channel layout '%.*s' is interpreted as a number of channels, " + "switch to the syntax '%.*sc' otherwise it will be interpreted as a " + "channel layout number in a later version\n", + name_len, name, name_len, name); + return layout; + } + } + } else { +#endif + if ((end + 1 - name == name_len && *end == 'c')) return av_get_default_channel_layout(i); +#if FF_API_GET_CHANNEL_LAYOUT_COMPAT + } +#endif + layout = strtoll(name, &end, 0); if (end - name == name_len) return FFMAX(layout, 0); return 0; } +#if FF_API_GET_CHANNEL_LAYOUT_COMPAT +uint64_t ff_get_channel_layout(const char *name, int compat) +#else uint64_t av_get_channel_layout(const char *name) +#endif { const char *n, *e; const char *name_end = name + strlen(name); @@ -137,7 +167,11 @@ uint64_t av_get_channel_layout(const char *name) for (n = name; n < name_end; n = e + 1) { for (e = n; e < name_end && *e != '+' && *e != '|'; e++); +#if FF_API_GET_CHANNEL_LAYOUT_COMPAT + layout_single = get_channel_layout_single(n, e - n, compat); +#else layout_single = get_channel_layout_single(n, e - n); +#endif if (!layout_single) return 0; layout |= layout_single; @@ -145,6 +179,13 @@ uint64_t av_get_channel_layout(const char *name) return layout; } +#if FF_API_GET_CHANNEL_LAYOUT_COMPAT +uint64_t av_get_channel_layout(const char *name) +{ + return ff_get_channel_layout(name, 1); +} +#endif + void av_bprint_channel_layout(struct AVBPrint *bp, int nb_channels, uint64_t channel_layout) { diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/channel_layout.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/channel_layout.h index 290609831..bc6befd8e 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/channel_layout.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/channel_layout.h @@ -114,6 +114,10 @@ enum AVMatrixEncoding { AV_MATRIX_ENCODING_NONE, AV_MATRIX_ENCODING_DOLBY, AV_MATRIX_ENCODING_DPLII, + AV_MATRIX_ENCODING_DPLIIX, + AV_MATRIX_ENCODING_DPLIIZ, + AV_MATRIX_ENCODING_DOLBYEX, + AV_MATRIX_ENCODING_DOLBYHEADPHONE, AV_MATRIX_ENCODING_NB }; @@ -136,7 +140,12 @@ enum AVMatrixEncoding { * - a channel layout mask, in hexadecimal starting with "0x" (see the * AV_CH_* macros). * - * Example: "stereo+FC" = "2+FC" = "2c+1c" = "0x7" + * @warning Starting from the next major bump the trailing character + * 'c' to specify a number of channels will be required, while a + * channel layout mask could also be specified as a decimal number + * (if and only if not followed by "c"). + * + * Example: "stereo+FC" = "2c+FC" = "2c+1c" = "0x7" */ uint64_t av_get_channel_layout(const char *name); diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/common.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/common.h index 0ed92f8a3..b2bb670bb 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/common.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/common.h @@ -26,10 +26,15 @@ #ifndef AVUTIL_COMMON_H #define AVUTIL_COMMON_H +#if defined(__cplusplus) && !defined(__STDC_CONSTANT_MACROS) && !defined(UINT64_C) +#error missing -D__STDC_CONSTANT_MACROS / #define __STDC_CONSTANT_MACROS +#endif + #include #include #include #include +#include #include #include #include @@ -299,6 +304,11 @@ static av_always_inline av_const int av_popcount64_c(uint64_t x) * input, this could be *ptr++. * @param ERROR Expression to be evaluated on invalid input, * typically a goto statement. + * + * @warning ERROR should not contain a loop control statement which + * could interact with the internal while loop, and should force an + * exit from the macro code (e.g. through a goto or a return) in order + * to prevent undefined results. */ #define GET_UTF8(val, GET_BYTE, ERROR)\ val= GET_BYTE;\ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/cpu.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/cpu.c index cec94e545..256bd237d 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/cpu.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/cpu.c @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include + #include "cpu.h" #include "cpu_internal.h" #include "config.h" @@ -54,9 +56,14 @@ int av_get_cpu_flags(void) if (checked) return flags; - if (ARCH_ARM) flags = ff_get_cpu_flags_arm(); - if (ARCH_PPC) flags = ff_get_cpu_flags_ppc(); - if (ARCH_X86) flags = ff_get_cpu_flags_x86(); + if (ARCH_AARCH64) + flags = ff_get_cpu_flags_aarch64(); + if (ARCH_ARM) + flags = ff_get_cpu_flags_arm(); + if (ARCH_PPC) + flags = ff_get_cpu_flags_ppc(); + if (ARCH_X86) + flags = ff_get_cpu_flags_x86(); checked = 1; return flags; @@ -84,7 +91,11 @@ int av_parse_cpu_flags(const char *s) #define CPUFLAG_SSE42 (AV_CPU_FLAG_SSE42 | CPUFLAG_SSE4) #define CPUFLAG_AVX (AV_CPU_FLAG_AVX | CPUFLAG_SSE42) #define CPUFLAG_XOP (AV_CPU_FLAG_XOP | CPUFLAG_AVX) +#define CPUFLAG_FMA3 (AV_CPU_FLAG_FMA3 | CPUFLAG_AVX) #define CPUFLAG_FMA4 (AV_CPU_FLAG_FMA4 | CPUFLAG_AVX) +#define CPUFLAG_AVX2 (AV_CPU_FLAG_AVX2 | CPUFLAG_AVX) +#define CPUFLAG_BMI1 (AV_CPU_FLAG_BMI1) +#define CPUFLAG_BMI2 (AV_CPU_FLAG_BMI2 | CPUFLAG_BMI1) static const AVOption cpuflags_opts[] = { { "flags" , NULL, 0, AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT64_MIN, INT64_MAX, .unit = "flags" }, #if ARCH_PPC @@ -103,7 +114,11 @@ int av_parse_cpu_flags(const char *s) { "sse4.2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_SSE42 }, .unit = "flags" }, { "avx" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_AVX }, .unit = "flags" }, { "xop" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_XOP }, .unit = "flags" }, + { "fma3" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_FMA3 }, .unit = "flags" }, { "fma4" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_FMA4 }, .unit = "flags" }, + { "avx2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_AVX2 }, .unit = "flags" }, + { "bmi1" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_BMI1 }, .unit = "flags" }, + { "bmi2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_BMI2 }, .unit = "flags" }, { "3dnow" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_3DNOW }, .unit = "flags" }, { "3dnowext", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CPUFLAG_3DNOWEXT }, .unit = "flags" }, { "cmov", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_CMOV }, .unit = "flags" }, @@ -114,6 +129,9 @@ int av_parse_cpu_flags(const char *s) { "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" }, { "vfpv3", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFPV3 }, .unit = "flags" }, { "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" }, +#elif ARCH_AARCH64 + { "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" }, + { "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" }, #endif { NULL }, }; @@ -154,7 +172,11 @@ int av_parse_cpu_caps(unsigned *flags, const char *s) { "sse4.2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_SSE42 }, .unit = "flags" }, { "avx" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_AVX }, .unit = "flags" }, { "xop" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_XOP }, .unit = "flags" }, + { "fma3" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_FMA3 }, .unit = "flags" }, { "fma4" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_FMA4 }, .unit = "flags" }, + { "avx2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_AVX2 }, .unit = "flags" }, + { "bmi1" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_BMI1 }, .unit = "flags" }, + { "bmi2" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_BMI2 }, .unit = "flags" }, { "3dnow" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_3DNOW }, .unit = "flags" }, { "3dnowext", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_3DNOWEXT }, .unit = "flags" }, { "cmov", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_CMOV }, .unit = "flags" }, @@ -193,7 +215,7 @@ int av_parse_cpu_caps(unsigned *flags, const char *s) }; const AVClass *pclass = &class; - return av_opt_eval_flags(&pclass, &cpuflags_opts[0], s, (int *) flags); + return av_opt_eval_flags(&pclass, &cpuflags_opts[0], s, flags); } int av_cpu_count(void) @@ -240,7 +262,10 @@ static const struct { int flag; const char *name; } cpu_flag_tab[] = { -#if ARCH_ARM +#if ARCH_AARCH64 + { AV_CPU_FLAG_NEON, "neon" }, + { AV_CPU_FLAG_VFP, "vfp" }, +#elif ARCH_ARM { AV_CPU_FLAG_ARMV5TE, "armv5te" }, { AV_CPU_FLAG_ARMV6, "armv6" }, { AV_CPU_FLAG_ARMV6T2, "armv6t2" }, @@ -263,10 +288,14 @@ static const struct { { AV_CPU_FLAG_SSE42, "sse4.2" }, { AV_CPU_FLAG_AVX, "avx" }, { AV_CPU_FLAG_XOP, "xop" }, + { AV_CPU_FLAG_FMA3, "fma3" }, { AV_CPU_FLAG_FMA4, "fma4" }, { AV_CPU_FLAG_3DNOW, "3dnow" }, { AV_CPU_FLAG_3DNOWEXT, "3dnowext" }, { AV_CPU_FLAG_CMOV, "cmov" }, + { AV_CPU_FLAG_AVX2, "avx2" }, + { AV_CPU_FLAG_BMI1, "bmi1" }, + { AV_CPU_FLAG_BMI2, "bmi2" }, #endif { 0 } }; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/cpu.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/cpu.h index e9e07317f..0ad400fef 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/cpu.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/cpu.h @@ -33,9 +33,11 @@ #define AV_CPU_FLAG_SSE 0x0008 ///< SSE functions #define AV_CPU_FLAG_SSE2 0x0010 ///< PIV SSE2 functions #define AV_CPU_FLAG_SSE2SLOW 0x40000000 ///< SSE2 supported, but usually not faster + ///< than regular MMX/SSE (e.g. Core1) #define AV_CPU_FLAG_3DNOWEXT 0x0020 ///< AMD 3DNowExt #define AV_CPU_FLAG_SSE3 0x0040 ///< Prescott SSE3 functions #define AV_CPU_FLAG_SSE3SLOW 0x20000000 ///< SSE3 supported, but usually not faster + ///< than regular MMX/SSE (e.g. Core1) #define AV_CPU_FLAG_SSSE3 0x0080 ///< Conroe SSSE3 functions #define AV_CPU_FLAG_ATOM 0x10000000 ///< Atom processor, some SSSE3 instructions are slower #define AV_CPU_FLAG_SSE4 0x0100 ///< Penryn SSE4.1 functions @@ -48,6 +50,10 @@ // #else // #define AV_CPU_FLAG_CMOV 0x1000 ///< supports cmov instruction // #endif +#define AV_CPU_FLAG_AVX2 0x8000 ///< AVX2 functions: requires OS support even if YMM registers aren't used +#define AV_CPU_FLAG_FMA3 0x10000 ///< Haswell FMA3 functions +#define AV_CPU_FLAG_BMI1 0x20000 ///< Bit Manipulation Instruction Set 1 +#define AV_CPU_FLAG_BMI2 0x40000 ///< Bit Manipulation Instruction Set 2 #define AV_CPU_FLAG_ALTIVEC 0x0001 ///< standard diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/downmix_info.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/downmix_info.c new file mode 100644 index 000000000..c634c6a79 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/downmix_info.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2014 Tim Walker + * + * 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 "downmix_info.h" +#include "frame.h" + +AVDownmixInfo *av_downmix_info_update_side_data(AVFrame *frame) +{ + AVFrameSideData *side_data; + + side_data = av_frame_get_side_data(frame, AV_FRAME_DATA_DOWNMIX_INFO); + + if (!side_data) + side_data = av_frame_new_side_data(frame, AV_FRAME_DATA_DOWNMIX_INFO, + sizeof(AVDownmixInfo)); + + if (!side_data) + return NULL; + + return (AVDownmixInfo*)side_data->data; +} diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/downmix_info.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/downmix_info.h new file mode 100644 index 000000000..c369891c0 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/downmix_info.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2014 Tim Walker + * + * 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 AVUTIL_DOWNMIX_INFO_H +#define AVUTIL_DOWNMIX_INFO_H + +#include "frame.h" + +/** + * @file + * audio downmix medatata + */ + +/** + * @addtogroup lavu_audio + * @{ + */ + +/** + * @defgroup downmix_info Audio downmix metadata + * @{ + */ + +/** + * Possible downmix types. + */ +enum AVDownmixType { + AV_DOWNMIX_TYPE_UNKNOWN, /**< Not indicated. */ + AV_DOWNMIX_TYPE_LORO, /**< Lo/Ro 2-channel downmix (Stereo). */ + AV_DOWNMIX_TYPE_LTRT, /**< Lt/Rt 2-channel downmix, Dolby Surround compatible. */ + AV_DOWNMIX_TYPE_DPLII, /**< Lt/Rt 2-channel downmix, Dolby Pro Logic II compatible. */ + AV_DOWNMIX_TYPE_NB /**< Number of downmix types. Not part of ABI. */ +}; + +/** + * This structure describes optional metadata relevant to a downmix procedure. + * + * All fields are set by the decoder to the value indicated in the audio + * bitstream (if present), or to a "sane" default otherwise. + */ +typedef struct AVDownmixInfo { + /** + * Type of downmix preferred by the mastering engineer. + */ + enum AVDownmixType preferred_downmix_type; + + /** + * Absolute scale factor representing the nominal level of the center + * channel during a regular downmix. + */ + double center_mix_level; + + /** + * Absolute scale factor representing the nominal level of the center + * channel during an Lt/Rt compatible downmix. + */ + double center_mix_level_ltrt; + + /** + * Absolute scale factor representing the nominal level of the surround + * channels during a regular downmix. + */ + double surround_mix_level; + + /** + * Absolute scale factor representing the nominal level of the surround + * channels during an Lt/Rt compatible downmix. + */ + double surround_mix_level_ltrt; + + /** + * Absolute scale factor representing the level at which the LFE data is + * mixed into L/R channels during downmixing. + */ + double lfe_mix_level; +} AVDownmixInfo; + +/** + * Get a frame's AV_FRAME_DATA_DOWNMIX_INFO side data for editing. + * + * The side data is created and added to the frame if it's absent. + * + * @param frame the frame for which the side data is to be obtained. + * + * @return the AVDownmixInfo structure to be edited by the caller. + */ +AVDownmixInfo *av_downmix_info_update_side_data(AVFrame *frame); + +/** + * @} + */ + +/** + * @} + */ + +#endif /* AVUTIL_DOWNMIX_INFO_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/eval.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/eval.c index ea869e776..4a313bfad 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/eval.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/eval.c @@ -26,8 +26,6 @@ * see http://joe.hotchkiss.com/programming/eval/eval.html */ -#include "config.h" - #include #include "attributes.h" #include "avutil.h" @@ -35,8 +33,9 @@ #include "eval.h" #include "log.h" #include "mathematics.h" -#include "time_.h" +#include "time.h" #include "avstring.h" +#include "timer.h" typedef struct Parser { const AVClass *class; @@ -237,9 +236,7 @@ static double eval_expr(Parser *p, AVExpr *e) double x_max = eval_expr(p, e->param[1]); for(i=-1; i<1024; i++) { if(i<255) { - AV_NOWARN_DEPRECATED( p->var[0] = av_reverse[i&255]*x_max/255; - ); } else { p->var[0] = x_max*pow(0.9, i-255); if (i&1) p->var[0] *= -1; @@ -296,7 +293,6 @@ static double eval_expr(Parser *p, AVExpr *e) case e_hypot:return e->value * (sqrt(d*d + d2*d2)); case e_bitand: return isnan(d) || isnan(d2) ? NAN : e->value * ((long int)d & (long int)d2); case e_bitor: return isnan(d) || isnan(d2) ? NAN : e->value * ((long int)d | (long int)d2); - default:break; } } } diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/frame.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/frame.c index de3b757ba..1b7f137e1 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/frame.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/frame.c @@ -53,26 +53,22 @@ int av_frame_set_qp_table(AVFrame *f, AVBufferRef *buf, int stride, int qp_type) f->qp_table_buf = buf; -AV_NOWARN_DEPRECATED( - f->qscale_table = (int8_t *) buf->data; + f->qscale_table = buf->data; f->qstride = stride; f->qscale_type = qp_type; -); return 0; } int8_t *av_frame_get_qp_table(AVFrame *f, int *stride, int *type) { -AV_NOWARN_DEPRECATED( *stride = f->qstride; *type = f->qscale_type; -); if (!f->qp_table_buf) return NULL; - return (int8_t *) f->qp_table_buf->data; + return f->qp_table_buf->data; } const char *av_get_colorspace_name(enum AVColorSpace val) @@ -164,7 +160,7 @@ static int get_video_buffer(AVFrame *frame, int align) if (i == 1 || i == 2) h = FF_CEIL_RSHIFT(h, desc->log2_chroma_h); - frame->buf[i] = av_buffer_alloc(frame->linesize[i] * h + 16); + frame->buf[i] = av_buffer_alloc(frame->linesize[i] * h + 16 + 16/*STRIDE_ALIGN*/ - 1); if (!frame->buf[i]) goto fail; @@ -188,11 +184,17 @@ fail: static int get_audio_buffer(AVFrame *frame, int align) { - int channels = frame->channels; + int channels; int planar = av_sample_fmt_is_planar(frame->format); - int planes = planar ? channels : 1; + int planes; int ret, i; + if (!frame->channels) + frame->channels = av_get_channel_layout_nb_channels(frame->channel_layout); + + channels = frame->channels; + planes = planar ? channels : 1; + CHECK_CHANNELS_CONSISTENCY(frame); if (!frame->linesize[0]) { ret = av_samples_get_buffer_size(&frame->linesize[0], channels, @@ -249,7 +251,7 @@ int av_frame_get_buffer(AVFrame *frame, int align) return AVERROR(EINVAL); } -int av_frame_ref(AVFrame *dst, AVFrame *src) +int av_frame_ref(AVFrame *dst, const AVFrame *src) { int i, ret = 0; @@ -270,16 +272,11 @@ int av_frame_ref(AVFrame *dst, AVFrame *src) if (ret < 0) return ret; - if (src->nb_samples) { - int ch = src->channels; - CHECK_CHANNELS_CONSISTENCY(src); - av_samples_copy(dst->extended_data, src->extended_data, 0, 0, - dst->nb_samples, ch, dst->format); - } else { - av_image_copy(dst->data, dst->linesize, (const uint8_t **) src->data, src->linesize, - dst->format, dst->width, dst->height); - } - return 0; + ret = av_frame_copy(dst, src); + if (ret < 0) + av_frame_unref(dst); + + return ret; } /* ref the buffers */ @@ -340,7 +337,7 @@ fail: return ret; } -AVFrame *av_frame_clone(AVFrame *src) +AVFrame *av_frame_clone(const AVFrame *src) { AVFrame *ret = av_frame_alloc(); @@ -423,14 +420,10 @@ int av_frame_make_writable(AVFrame *frame) if (ret < 0) return ret; - if (tmp.nb_samples) { - int ch = tmp.channels; - CHECK_CHANNELS_CONSISTENCY(&tmp); - av_samples_copy(tmp.extended_data, frame->extended_data, 0, 0, - frame->nb_samples, ch, frame->format); - } else { - av_image_copy(tmp.data, tmp.linesize, (const uint8_t **) frame->data, frame->linesize, - frame->format, frame->width, frame->height); + ret = av_frame_copy(&tmp, frame); + if (ret < 0) { + av_frame_unref(&tmp); + return ret; } ret = av_frame_copy_props(&tmp, frame); @@ -452,34 +445,33 @@ int av_frame_copy_props(AVFrame *dst, const AVFrame *src) { int i; - dst->key_frame = src->key_frame; - dst->pict_type = src->pict_type; - dst->sample_aspect_ratio = src->sample_aspect_ratio; - dst->pts = src->pts; - dst->repeat_pict = src->repeat_pict; - dst->interlaced_frame = src->interlaced_frame; - dst->top_field_first = src->top_field_first; - dst->palette_has_changed = src->palette_has_changed; - dst->sample_rate = src->sample_rate; - dst->opaque = src->opaque; + dst->key_frame = src->key_frame; + dst->pict_type = src->pict_type; + dst->sample_aspect_ratio = src->sample_aspect_ratio; + dst->pts = src->pts; + dst->repeat_pict = src->repeat_pict; + dst->interlaced_frame = src->interlaced_frame; + dst->top_field_first = src->top_field_first; + dst->palette_has_changed = src->palette_has_changed; + dst->sample_rate = src->sample_rate; + dst->opaque = src->opaque; #if FF_API_AVFRAME_LAVC -AV_NOWARN_DEPRECATED( - dst->type = src->type; -); + dst->type = src->type; #endif - dst->pkt_pts = src->pkt_pts; - dst->pkt_dts = src->pkt_dts; - dst->pkt_pos = src->pkt_pos; - dst->pkt_size = src->pkt_size; - dst->pkt_duration = src->pkt_duration; - dst->reordered_opaque = src->reordered_opaque; - dst->quality = src->quality; - dst->best_effort_timestamp = src->best_effort_timestamp; - dst->coded_picture_number = src->coded_picture_number; + dst->pkt_pts = src->pkt_pts; + dst->pkt_dts = src->pkt_dts; + dst->pkt_pos = src->pkt_pos; + dst->pkt_size = src->pkt_size; + dst->pkt_duration = src->pkt_duration; + dst->reordered_opaque = src->reordered_opaque; + dst->quality = src->quality; + dst->best_effort_timestamp = src->best_effort_timestamp; + dst->coded_picture_number = src->coded_picture_number; dst->display_picture_number = src->display_picture_number; - dst->decode_error_flags = src->decode_error_flags; - dst->colorspace = src->colorspace; - dst->color_range = src->color_range; + dst->flags = src->flags; + dst->decode_error_flags = src->decode_error_flags; + dst->colorspace = src->colorspace; + dst->color_range = src->color_range; av_dict_copy(&dst->metadata, src->metadata, 0); @@ -502,19 +494,15 @@ AV_NOWARN_DEPRECATED( av_dict_copy(&sd_dst->metadata, sd_src->metadata, 0); } -AV_NOWARN_DEPRECATED( dst->qscale_table = NULL; dst->qstride = 0; dst->qscale_type = 0; -); if (src->qp_table_buf) { dst->qp_table_buf = av_buffer_ref(src->qp_table_buf); if (dst->qp_table_buf) { -AV_NOWARN_DEPRECATED( - dst->qscale_table = (int8_t *) dst->qp_table_buf->data; + dst->qscale_table = dst->qp_table_buf->data; dst->qstride = src->qstride; dst->qscale_type = src->qscale_type; -); } } @@ -596,3 +584,62 @@ AVFrameSideData *av_frame_get_side_data(const AVFrame *frame, } return NULL; } + +static int frame_copy_video(AVFrame *dst, const AVFrame *src) +{ + const uint8_t *src_data[4]; + int i, planes; + + if (dst->width != src->width || + dst->height != src->height) + return AVERROR(EINVAL); + + planes = av_pix_fmt_count_planes(dst->format); + for (i = 0; i < planes; i++) + if (!dst->data[i] || !src->data[i]) + return AVERROR(EINVAL); + + memcpy(src_data, src->data, sizeof(src_data)); + av_image_copy(dst->data, dst->linesize, + src_data, src->linesize, + dst->format, dst->width, dst->height); + + return 0; +} + +static int frame_copy_audio(AVFrame *dst, const AVFrame *src) +{ + int planar = av_sample_fmt_is_planar(dst->format); + int channels = dst->channels; + int planes = planar ? channels : 1; + int i; + + if (dst->nb_samples != src->nb_samples || + dst->channels != src->channels || + dst->channel_layout != src->channel_layout) + return AVERROR(EINVAL); + + CHECK_CHANNELS_CONSISTENCY(src); + + for (i = 0; i < planes; i++) + if (!dst->extended_data[i] || !src->extended_data[i]) + return AVERROR(EINVAL); + + av_samples_copy(dst->extended_data, src->extended_data, 0, 0, + dst->nb_samples, channels, dst->format); + + return 0; +} + +int av_frame_copy(AVFrame *dst, const AVFrame *src) +{ + if (dst->format != src->format || dst->format < 0) + return AVERROR(EINVAL); + + if (dst->width > 0 && dst->height > 0) + return frame_copy_video(dst, src); + else if (dst->nb_samples > 0 && dst->channel_layout) + return frame_copy_audio(dst, src); + + return AVERROR(EINVAL); +} diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/frame.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/frame.h index 0b6245e01..9fedba863 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/frame.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/frame.h @@ -17,33 +17,37 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +/** + * @file + * @ingroup lavu_frame + * reference-counted frame API + */ + #ifndef AVUTIL_FRAME_H #define AVUTIL_FRAME_H #include -#ifdef __FRAMEWORK__ -#include "version.h" -#else -#include "libavcodec/version.h" -#endif - #include "avutil.h" #include "buffer.h" #include "dict.h" #include "rational.h" #include "samplefmt.h" +#include "version.h" + enum AVColorSpace{ - AVCOL_SPC_RGB = 0, - AVCOL_SPC_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B - AVCOL_SPC_UNSPECIFIED = 2, - AVCOL_SPC_FCC = 4, - AVCOL_SPC_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 - AVCOL_SPC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above - AVCOL_SPC_SMPTE240M = 7, - AVCOL_SPC_YCOCG = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16 - AVCOL_SPC_NB , ///< Not part of ABI + AVCOL_SPC_RGB = 0, + AVCOL_SPC_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B + AVCOL_SPC_UNSPECIFIED = 2, + AVCOL_SPC_FCC = 4, + AVCOL_SPC_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 + AVCOL_SPC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above + AVCOL_SPC_SMPTE240M = 7, + AVCOL_SPC_YCOCG = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16 + AVCOL_SPC_BT2020_NCL = 9, ///< ITU-R BT2020 non-constant luminance system + AVCOL_SPC_BT2020_CL = 10, ///< ITU-R BT2020 constant luminance system + AVCOL_SPC_NB , ///< Not part of ABI }; #define AVCOL_SPC_YCGCO AVCOL_SPC_YCOCG @@ -54,11 +58,40 @@ enum AVColorRange{ AVCOL_RANGE_NB , ///< Not part of ABI }; + +/** + * @defgroup lavu_frame AVFrame + * @ingroup lavu_data + * + * @{ + * AVFrame is an abstraction for reference-counted raw multimedia data. + */ + enum AVFrameSideDataType { /** * The data is the AVPanScan struct defined in libavcodec. */ AV_FRAME_DATA_PANSCAN, + /** + * ATSC A53 Part 4 Closed Captions. + * A53 CC bitstream is stored as uint8_t in AVFrameSideData.data. + * The number of bytes of CC data is AVFrameSideData.size. + */ + AV_FRAME_DATA_A53_CC, + /** + * Stereoscopic 3d metadata. + * The data is the AVStereo3D struct defined in libavutil/stereo3d.h. + */ + AV_FRAME_DATA_STEREO3D, + /** + * The data is the AVMatrixEncoding enum defined in libavutil/channel_layout.h. + */ + AV_FRAME_DATA_MATRIXENCODING, + /** + * Metadata relevant to a downmix procedure. + * The data is the AVDownmixInfo struct defined in libavutil/downmix_info.h. + */ + AV_FRAME_DATA_DOWNMIX_INFO, }; typedef struct AVFrameSideData { @@ -390,6 +423,26 @@ typedef struct AVFrame { AVFrameSideData **side_data; int nb_side_data; +/** + * @defgroup lavu_frame_flags AV_FRAME_FLAGS + * Flags describing additional frame properties. + * + * @{ + */ + +/** + * The frame data may be corrupted, e.g. due to decoding errors. + */ +#define AV_FRAME_FLAG_CORRUPT (1 << 0) +/** + * @} + */ + + /** + * Frame flags, a combination of @ref lavu_frame_flags + */ + int flags; + /** * frame timestamp estimated using various heuristics, in stream time base * Code outside libavcodec should access this field using: @@ -543,7 +596,7 @@ AVFrame *av_frame_alloc(void); void av_frame_free(AVFrame **frame); /** - * Setup a new reference to the data described by a given frame. + * Set up a new reference to the data described by the source frame. * * Copy frame properties from src to dst and create a new reference for each * AVBufferRef from src. @@ -553,7 +606,7 @@ void av_frame_free(AVFrame **frame); * * @return 0 on success, a negative AVERROR on error */ -int av_frame_ref(AVFrame *dst, AVFrame *src); +int av_frame_ref(AVFrame *dst, const AVFrame *src); /** * Create a new frame that references the same data as src. @@ -562,7 +615,7 @@ int av_frame_ref(AVFrame *dst, AVFrame *src); * * @return newly created AVFrame on success, NULL on error. */ -AVFrame *av_frame_clone(AVFrame *src); +AVFrame *av_frame_clone(const AVFrame *src); /** * Unreference all the buffers referenced by frame and reset the frame fields. @@ -620,6 +673,19 @@ int av_frame_is_writable(AVFrame *frame); */ int av_frame_make_writable(AVFrame *frame); +/** + * Copy the frame data from src to dst. + * + * This function does not allocate anything, dst must be already initialized and + * allocated with the same parameters as src. + * + * This function only copies the frame data (i.e. the contents of the data / + * extended data arrays), not any other properties. + * + * @return >= 0 on success, a negative AVERROR on error. + */ +int av_frame_copy(AVFrame *dst, const AVFrame *src); + /** * Copy only "metadata" fields from src to dst. * @@ -660,4 +726,8 @@ AVFrameSideData *av_frame_new_side_data(AVFrame *frame, AVFrameSideData *av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type); +/** + * @} + */ + #endif /* AVUTIL_FRAME_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/internal.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/internal.h index ae7f4cc11..01326c513 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/internal.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/internal.h @@ -39,6 +39,7 @@ #include "timer.h" #include "cpu.h" #include "dict.h" +#include "version.h" #if ARCH_X86 # include "x86/emms.h" @@ -63,7 +64,7 @@ #endif #if HAVE_PRAGMA_DEPRECATED -# if defined(__ICL) +# if defined(__ICL) || defined (__INTEL_COMPILER) # define FF_DISABLE_DEPRECATION_WARNINGS __pragma(warning(push)) __pragma(warning(disable:1478)) # define FF_ENABLE_DEPRECATION_WARNINGS __pragma(warning(pop)) # elif defined(_MSC_VER) @@ -211,7 +212,7 @@ void avpriv_report_missing_feature(void *avc, void avpriv_request_sample(void *avc, const char *msg, ...) av_printf_format(2, 3); -#if HAVE_MSVCRT +#if HAVE_LIBC_MSVCRT #define avpriv_open ff_open #endif @@ -220,4 +221,8 @@ void avpriv_request_sample(void *avc, */ int avpriv_open(const char *filename, int flags, ...); +#if FF_API_GET_CHANNEL_LAYOUT_COMPAT +uint64_t ff_get_channel_layout(const char *name, int compat); +#endif + #endif /* AVUTIL_INTERNAL_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/lls.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/lls2.c similarity index 82% rename from Frameworks/FFMPEG/ffmpeg-minimal/libavutil/lls.c rename to Frameworks/FFMPEG/ffmpeg-minimal/libavutil/lls2.c index 361dc9848..06a0eb8c7 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/lls.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/lls2.c @@ -31,9 +31,9 @@ #include "config.h" #include "attributes.h" #include "version.h" -#include "lls.h" +#include "lls2.h" -static void update_lls(LLSModel *m, double *var) +static void update_lls(LLSModel2 *m, double *var) { int i, j; @@ -44,7 +44,7 @@ static void update_lls(LLSModel *m, double *var) } } -void avpriv_solve_lls(LLSModel *m, double threshold, unsigned short min_order) +void avpriv_solve_lls2(LLSModel2 *m, double threshold, unsigned short min_order) { int i, j, k; double (*factor)[MAX_VARS_ALIGN] = (void *) &m->covariance[1][0]; @@ -101,7 +101,7 @@ void avpriv_solve_lls(LLSModel *m, double threshold, unsigned short min_order) } } -static double evaluate_lls(LLSModel *m, double *param, int order) +static double evaluate_lls(LLSModel2 *m, double *param, int order) { int i; double out = 0; @@ -112,9 +112,9 @@ static double evaluate_lls(LLSModel *m, double *param, int order) return out; } -av_cold void avpriv_init_lls(LLSModel *m, int indep_count) +av_cold void avpriv_init_lls2(LLSModel2 *m, int indep_count) { - memset(m, 0, sizeof(LLSModel)); + memset(m, 0, sizeof(LLSModel2)); m->indep_count = indep_count; m->update_lls = update_lls; m->evaluate_lls = evaluate_lls; @@ -122,25 +122,6 @@ av_cold void avpriv_init_lls(LLSModel *m, int indep_count) ff_init_lls_x86(m); } -#if FF_API_LLS_PRIVATE -av_cold void av_init_lls(LLSModel *m, int indep_count) -{ - avpriv_init_lls(m, indep_count); -} -void av_update_lls(LLSModel *m, double *param, double decay) -{ - m->update_lls(m, param); -} -void av_solve_lls(LLSModel *m, double threshold, int min_order) -{ - avpriv_solve_lls(m, threshold, min_order); -} -double av_evaluate_lls(LLSModel *m, double *param, int order) -{ - return m->evaluate_lls(m, param, order); -} -#endif /* FF_API_LLS_PRIVATE */ - #ifdef TEST #include @@ -149,12 +130,12 @@ double av_evaluate_lls(LLSModel *m, double *param, int order) int main(void) { - LLSModel m; + LLSModel2 m; int i, order; AVLFG lfg; av_lfg_init(&lfg, 1); - avpriv_init_lls(&m, 3); + avpriv_init_lls2(&m, 3); for (i = 0; i < 100; i++) { LOCAL_ALIGNED(32, double, var, [4]); @@ -165,7 +146,7 @@ int main(void) var[2] = var[1] + av_lfg_get(&lfg) / (double) UINT_MAX - 0.5; var[3] = var[2] + av_lfg_get(&lfg) / (double) UINT_MAX - 0.5; m.update_lls(&m, var); - avpriv_solve_lls(&m, 0.001, 0); + avpriv_solve_lls2(&m, 0.001, 0); for (order = 0; order < 3; order++) { eval = m.evaluate_lls(&m, var + 1, order); printf("real:%9f order:%d pred:%9f var:%f coeffs:%f %9f %9f\n", diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/lls.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/lls2.h similarity index 72% rename from Frameworks/FFMPEG/ffmpeg-minimal/libavutil/lls.h rename to Frameworks/FFMPEG/ffmpeg-minimal/libavutil/lls2.h index c62d78a23..35815d270 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/lls.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/lls2.h @@ -30,12 +30,12 @@ #define MAX_VARS 32 #define MAX_VARS_ALIGN FFALIGN(MAX_VARS+1,4) -//FIXME avoid direct access to LLSModel from outside +//FIXME avoid direct access to LLSModel2 from outside /** * Linear least squares model. */ -typedef struct LLSModel { +typedef struct LLSModel2 { DECLARE_ALIGNED(32, double, covariance[MAX_VARS_ALIGN][MAX_VARS_ALIGN]); DECLARE_ALIGNED(32, double, coeff[MAX_VARS][MAX_VARS]); double variance[MAX_VARS]; @@ -47,25 +47,18 @@ typedef struct LLSModel { * 32-byte aligned, and any padding elements must be initialized * (i.e not denormal/nan). */ - void (*update_lls)(struct LLSModel *m, double *var); + void (*update_lls)(struct LLSModel2 *m, double *var); /** * Inner product of var[] and the LPC coefs. * @param m this context * @param var training samples, excluding the value to be predicted. unaligned. * @param order lpc order */ - double (*evaluate_lls)(struct LLSModel *m, double *var, int order); -} LLSModel; + double (*evaluate_lls)(struct LLSModel2 *m, double *var, int order); +} LLSModel2; -void avpriv_init_lls(LLSModel *m, int indep_count); -void ff_init_lls_x86(LLSModel *m); -void avpriv_solve_lls(LLSModel *m, double threshold, unsigned short min_order); - -#if FF_API_LLS_PRIVATE -void av_init_lls(LLSModel *m, int indep_count); -void av_update_lls(LLSModel *m, double *param, double decay); -void av_solve_lls(LLSModel *m, double threshold, int min_order); -double av_evaluate_lls(LLSModel *m, double *param, int order); -#endif /* FF_API_LLS_PRIVATE */ +void avpriv_init_lls2(LLSModel2 *m, int indep_count); +void ff_init_lls_x86(LLSModel2 *m); +void avpriv_solve_lls2(LLSModel2 *m, double threshold, unsigned short min_order); #endif /* AVUTIL_LLS_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/log.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/log.c index 34fd169b6..a0bb5e468 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/log.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/log.c @@ -40,6 +40,11 @@ #include "internal.h" #include "log.h" +#if HAVE_PTHREADS +#include +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +#endif + #define LINE_SZ 1024 static int av_log_level = AV_LOG_INFO; @@ -66,13 +71,16 @@ static const uint8_t color[16 + AV_CLASS_CATEGORY_NB] = { [16+AV_CLASS_CATEGORY_BITSTREAM_FILTER] = 9, [16+AV_CLASS_CATEGORY_SWSCALER ] = 7, [16+AV_CLASS_CATEGORY_SWRESAMPLER ] = 7, + [16+AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT ] = 13, + [16+AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT ] = 5, + [16+AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT ] = 13, + [16+AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT ] = 5, + [16+AV_CLASS_CATEGORY_DEVICE_OUTPUT ] = 13, + [16+AV_CLASS_CATEGORY_DEVICE_INPUT ] = 5, }; static int16_t background, attr_orig; static HANDLE con; -#define set_color(x) SetConsoleTextAttribute(con, background | color[x]) -#define set_256color set_color -#define reset_color() SetConsoleTextAttribute(con, attr_orig) #else static const uint32_t color[16 + AV_CLASS_CATEGORY_NB] = { @@ -94,16 +102,22 @@ static const uint32_t color[16 + AV_CLASS_CATEGORY_NB] = { [16+AV_CLASS_CATEGORY_BITSTREAM_FILTER] = 192 << 8 | 0x14, [16+AV_CLASS_CATEGORY_SWSCALER ] = 153 << 8 | 0x14, [16+AV_CLASS_CATEGORY_SWRESAMPLER ] = 147 << 8 | 0x14, + [16+AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT ] = 213 << 8 | 0x15, + [16+AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT ] = 207 << 8 | 0x05, + [16+AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT ] = 213 << 8 | 0x15, + [16+AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT ] = 207 << 8 | 0x05, + [16+AV_CLASS_CATEGORY_DEVICE_OUTPUT ] = 213 << 8 | 0x15, + [16+AV_CLASS_CATEGORY_DEVICE_INPUT ] = 207 << 8 | 0x05, }; -#define set_color(x) fprintf(stderr, "\033[%d;3%dm", (color[x] >> 4) & 15, color[x] & 15) -#define set_256color(x) fprintf(stderr, "\033[48;5;%dm\033[38;5;%dm", (color[x] >> 16) & 0xff, (color[x] >> 8) & 0xff) -#define reset_color() fprintf(stderr, "\033[0m") #endif static int use_color = -1; static void colored_fputs(int level, const char *str) { + if (!*str) + return; + if (use_color < 0) { #if HAVE_SETCONSOLETEXTATTRIBUTE CONSOLE_SCREEN_BUFFER_INFO con_info; @@ -127,14 +141,29 @@ static void colored_fputs(int level, const char *str) #endif } - if (use_color == 1) { - set_color(level); - } else if (use_color == 256) - set_256color(level); +#if HAVE_SETCONSOLETEXTATTRIBUTE + if (use_color && level != AV_LOG_INFO/8) + SetConsoleTextAttribute(con, background | color[level]); fputs(str, stderr); - if (use_color) { - reset_color(); - } + if (use_color && level != AV_LOG_INFO/8) + SetConsoleTextAttribute(con, attr_orig); +#else + if (use_color == 1 && level != AV_LOG_INFO/8) { + fprintf(stderr, + "\033[%d;3%dm%s\033[0m", + (color[level] >> 4) & 15, + color[level] & 15, + str); + } else if (use_color == 256 && level != AV_LOG_INFO/8) { + fprintf(stderr, + "\033[48;5;%dm\033[38;5;%dm%s\033[0m", + (color[level] >> 16) & 0xff, + (color[level] >> 8) & 0xff, + str); + } else + fputs(str, stderr); +#endif + } const char *av_default_item_name(void *ptr) @@ -168,10 +197,10 @@ static int get_category(void *ptr){ return avc->category + 16; } -static void format_line(void *ptr, int level, const char *fmt, va_list vl, +static void format_line(void *avcl, int level, const char *fmt, va_list vl, AVBPrint part[3], int *print_prefix, int type[2]) { - AVClass* avc = ptr ? *(AVClass **) ptr : NULL; + AVClass* avc = avcl ? *(AVClass **) avcl : NULL; av_bprint_init(part+0, 0, 1); av_bprint_init(part+1, 0, 1); av_bprint_init(part+2, 0, 65536); @@ -179,7 +208,7 @@ static void format_line(void *ptr, int level, const char *fmt, va_list vl, if(type) type[0] = type[1] = AV_CLASS_CATEGORY_NA + 16; if (*print_prefix && avc) { if (avc->parent_log_context_offset) { - AVClass** parent = *(AVClass ***) (((uint8_t *) ptr) + + AVClass** parent = *(AVClass ***) (((uint8_t *) avcl) + avc->parent_log_context_offset); if (parent && *parent) { av_bprintf(part+0, "[%s @ %p] ", @@ -188,14 +217,14 @@ static void format_line(void *ptr, int level, const char *fmt, va_list vl, } } av_bprintf(part+1, "[%s @ %p] ", - avc->item_name(ptr), ptr); - if(type) type[1] = get_category(ptr); + avc->item_name(avcl), avcl); + if(type) type[1] = get_category(avcl); } av_vbprintf(part+2, fmt, vl); if(*part[0].str || *part[1].str || *part[2].str) { - char lastc = part[2].len ? part[2].str[part[2].len - 1] : 0; + char lastc = part[2].len && part[2].len <= part[2].size ? part[2].str[part[2].len - 1] : 0; *print_prefix = lastc == '\n' || lastc == '\r'; } } @@ -221,6 +250,10 @@ void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl) if (level > av_log_level) return; +#if HAVE_PTHREADS + pthread_mutex_lock(&mutex); +#endif + format_line(ptr, level, fmt, vl, part, &print_prefix, type); snprintf(line, sizeof(line), "%s%s%s", part[0].str, part[1].str, part[2].str); @@ -234,21 +267,24 @@ void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl) count++; if (is_atty == 1) fprintf(stderr, " Last message repeated %d times\r", count); - av_bprint_finalize(part+2, NULL); - return; + goto end; } if (count > 0) { fprintf(stderr, " Last message repeated %d times\n", count); count = 0; } strcpy(prev, line); - sanitize((uint8_t *) part[0].str); + sanitize(part[0].str); colored_fputs(type[0], part[0].str); - sanitize((uint8_t *) part[1].str); + sanitize(part[1].str); colored_fputs(type[1], part[1].str); - sanitize((uint8_t *) part[2].str); + sanitize(part[2].str); colored_fputs(av_clip(level >> 3, 0, 6), part[2].str); +end: av_bprint_finalize(part+2, NULL); +#if HAVE_PTHREADS + pthread_mutex_unlock(&mutex); +#endif } static void (*av_log_callback)(void*, int, const char*, va_list) = @@ -268,8 +304,9 @@ void av_log(void* avcl, int level, const char *fmt, ...) void av_vlog(void* avcl, int level, const char *fmt, va_list vl) { - if(av_log_callback) - av_log_callback(avcl, level, fmt, vl); + void (*log_callback)(void*, int, const char*, va_list) = av_log_callback; + if (log_callback) + log_callback(avcl, level, fmt, vl); } int av_log_get_level(void) diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/log.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/log.h index 7ea95fa50..f16e38221 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/log.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/log.h @@ -37,6 +37,12 @@ typedef enum { AV_CLASS_CATEGORY_BITSTREAM_FILTER, AV_CLASS_CATEGORY_SWSCALER, AV_CLASS_CATEGORY_SWRESAMPLER, + AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT = 40, + AV_CLASS_CATEGORY_DEVICE_VIDEO_INPUT, + AV_CLASS_CATEGORY_DEVICE_AUDIO_OUTPUT, + AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT, + AV_CLASS_CATEGORY_DEVICE_OUTPUT, + AV_CLASS_CATEGORY_DEVICE_INPUT, AV_CLASS_CATEGORY_NB, ///< not part of ABI/API }AVClassCategory; @@ -125,8 +131,19 @@ typedef struct AVClass { int (*query_ranges)(struct AVOptionRanges **, void *obj, const char *key, int flags); } AVClass; -/* av_log API */ +/** + * @addtogroup lavu_log + * + * @{ + * + * @defgroup lavu_log_constants Logging Constants + * + * @{ + */ +/** + * Print no output. + */ #define AV_LOG_QUIET -8 /** @@ -153,7 +170,14 @@ typedef struct AVClass { */ #define AV_LOG_WARNING 24 +/** + * Standard information. + */ #define AV_LOG_INFO 32 + +/** + * Detailed information. + */ #define AV_LOG_VERBOSE 40 /** @@ -163,27 +187,97 @@ typedef struct AVClass { #define AV_LOG_MAX_OFFSET (AV_LOG_DEBUG - AV_LOG_QUIET) +/** + * @} + */ + /** * Send the specified message to the log if the level is less than or equal * to the current av_log_level. By default, all logging messages are sent to - * stderr. This behavior can be altered by setting a different av_vlog callback + * stderr. This behavior can be altered by setting a different logging callback * function. + * @see av_log_set_callback * * @param avcl A pointer to an arbitrary struct of which the first field is a - * pointer to an AVClass struct. - * @param level The importance level of the message, lower values signifying - * higher importance. + * pointer to an AVClass struct. + * @param level The importance level of the message expressed using a @ref + * lavu_log_constants "Logging Constant". * @param fmt The format string (printf-compatible) that specifies how - * subsequent arguments are converted to output. - * @see av_vlog + * subsequent arguments are converted to output. */ void av_log(void *avcl, int level, const char *fmt, ...) av_printf_format(3, 4); -void av_vlog(void *avcl, int level, const char *fmt, va_list); + +/** + * Send the specified message to the log if the level is less than or equal + * to the current av_log_level. By default, all logging messages are sent to + * stderr. This behavior can be altered by setting a different logging callback + * function. + * @see av_log_set_callback + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct. + * @param level The importance level of the message expressed using a @ref + * lavu_log_constants "Logging Constant". + * @param fmt The format string (printf-compatible) that specifies how + * subsequent arguments are converted to output. + * @param vl The arguments referenced by the format string. + */ +void av_vlog(void *avcl, int level, const char *fmt, va_list vl); + +/** + * Get the current log level + * + * @see lavu_log_constants + * + * @return Current log level + */ int av_log_get_level(void); -void av_log_set_level(int); -void av_log_set_callback(void (*)(void*, int, const char*, va_list)); -void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl); + +/** + * Set the log level + * + * @see lavu_log_constants + * + * @param level Logging level + */ +void av_log_set_level(int level); + +/** + * Set the logging callback + * + * @note The callback must be thread safe, even if the application does not use + * threads itself as some codecs are multithreaded. + * + * @see av_log_default_callback + * + * @param callback A logging function with a compatible signature. + */ +void av_log_set_callback(void (*callback)(void*, int, const char*, va_list)); + +/** + * Default logging callback + * + * It prints the message to stderr, optionally colorizing it. + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct. + * @param level The importance level of the message expressed using a @ref + * lavu_log_constants "Logging Constant". + * @param fmt The format string (printf-compatible) that specifies how + * subsequent arguments are converted to output. + * @param vl The arguments referenced by the format string. + */ +void av_log_default_callback(void *avcl, int level, const char *fmt, + va_list vl); + +/** + * Return the context name + * + * @param ctx The AVClass context + * + * @return The AVClass class_name + */ const char* av_default_item_name(void* ctx); AVClassCategory av_default_get_category(void *ptr); @@ -219,4 +313,8 @@ void av_log_format_line(void *ptr, int level, const char *fmt, va_list vl, #define AV_LOG_SKIP_REPEATED 1 void av_log_set_flags(int arg); +/** + * @} + */ + #endif /* AVUTIL_LOG_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/macros.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/macros.h new file mode 100644 index 000000000..446532377 --- /dev/null +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/macros.h @@ -0,0 +1,48 @@ +/* + * 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 + * @ingroup lavu + * Utility Preprocessor macros + */ + +#ifndef AVUTIL_MACROS_H +#define AVUTIL_MACROS_H + +/** + * @addtogroup preproc_misc Preprocessor String Macros + * + * String manipulation macros + * + * @{ + */ + +#define AV_STRINGIFY(s) AV_TOSTRING(s) +#define AV_TOSTRING(s) #s + +#define AV_GLUE(a, b) a ## b +#define AV_JOIN(a, b) AV_GLUE(a, b) + +/** + * @} + */ + +#define AV_PRAGMA(s) _Pragma(#s) + +#endif /* AVUTIL_MACROS_H */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/mathematics.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/mathematics.c index f9cf87da8..30963aa07 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/mathematics.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/mathematics.c @@ -63,6 +63,9 @@ int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd){ av_assert2(b >=0); av_assert2((unsigned)(rnd&~AV_ROUND_PASS_MINMAX)<=5 && (rnd&~AV_ROUND_PASS_MINMAX)!=4); + if (c <= 0 || b < 0 || !((unsigned)(rnd&~AV_ROUND_PASS_MINMAX)<=5 && (rnd&~AV_ROUND_PASS_MINMAX)!=4)) + return INT64_MIN; + if (rnd & AV_ROUND_PASS_MINMAX) { if (a == INT64_MIN || a == INT64_MAX) return a; @@ -171,3 +174,17 @@ simple_round: return av_rescale_q(this, fs_tb, out_tb); } + +int64_t av_add_stable(AVRational ts_tb, int64_t ts, AVRational inc_tb, int64_t inc) +{ + AVRational step = av_mul_q(inc_tb, (AVRational) {inc, 1}); + + if (av_cmp_q(step, ts_tb) < 0) { + //increase step is too small for even 1 step to be representable + return ts; + } else { + int64_t old = av_rescale_q(ts, ts_tb, step); + int64_t old_ts = av_rescale_q(old, step, ts_tb); + return av_rescale_q(old + 1, step, ts_tb) + (ts - old_ts); + } +} diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/mathematics.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/mathematics.h index 71f039221..88739e80b 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/mathematics.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/mathematics.h @@ -45,6 +45,9 @@ #ifndef M_PI #define M_PI 3.14159265358979323846 /* pi */ #endif +#ifndef M_PI_2 +#define M_PI_2 1.57079632679489661923 /* pi/2 */ +#endif #ifndef M_SQRT1_2 #define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ #endif @@ -133,14 +136,28 @@ int64_t av_compare_mod(uint64_t a, uint64_t b, uint64_t mod); * Rescale a timestamp while preserving known durations. * * @param in_ts Input timestamp - * @param in_tb Input timesbase + * @param in_tb Input timebase * @param fs_tb Duration and *last timebase * @param duration duration till the next call - * @param out_tb Output timesbase + * @param out_tb Output timebase */ int64_t av_rescale_delta(AVRational in_tb, int64_t in_ts, AVRational fs_tb, int duration, int64_t *last, AVRational out_tb); /** + * Add a value to a timestamp. + * + * This function gurantees that when the same value is repeatly added that + * no accumulation of rounding errors occurs. + * + * @param ts Input timestamp + * @param ts_tb Input timestamp timebase + * @param inc value to add to ts + * @param inc_tb inc timebase + */ +int64_t av_add_stable(AVRational ts_tb, int64_t ts, AVRational inc_tb, int64_t inc); + + + /** * @} */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/mem.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/mem.c index a7f306a3a..10b0137a7 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/mem.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/mem.c @@ -38,6 +38,7 @@ #include "avassert.h" #include "avutil.h" +#include "common.h" #include "intreadwrite.h" #include "mem.h" @@ -258,7 +259,7 @@ char *av_strdup(const char *s) char *ptr = NULL; if (s) { int len = strlen(s) + 1; - ptr = av_malloc(len); + ptr = av_realloc(NULL, len); if (ptr) memcpy(ptr, s, len); } @@ -463,3 +464,41 @@ void av_memcpy_backptr(uint8_t *dst, int back, int cnt) } } +void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size) +{ + if (min_size < *size) + return ptr; + + min_size = FFMAX(17 * min_size / 16 + 32, min_size); + + ptr = av_realloc(ptr, min_size); + /* we could set this to the unmodified min_size but this is safer + * if the user lost the ptr and uses NULL now + */ + if (!ptr) + min_size = 0; + + *size = min_size; + + return ptr; +} + +static inline int ff_fast_malloc(void *ptr, unsigned int *size, size_t min_size, int zero_realloc) +{ + void **p = ptr; + if (min_size < *size) + return 0; + min_size = FFMAX(17 * min_size / 16 + 32, min_size); + av_free(*p); + *p = zero_realloc ? av_mallocz(min_size) : av_malloc(min_size); + if (!*p) + min_size = 0; + *size = min_size; + return 1; +} + +void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size) +{ + ff_fast_malloc(ptr, size, min_size, 0); +} + diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/mem.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/mem.h index b73b72435..703ce8193 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/mem.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/mem.h @@ -92,7 +92,7 @@ void *av_malloc(size_t size) av_malloc_attrib av_alloc_size(1); */ av_alloc_size(1, 2) static inline void *av_malloc_array(size_t nmemb, size_t size) { - if (size <= 0 || nmemb >= INT_MAX / size) + if (!size || nmemb >= INT_MAX / size) return NULL; return av_malloc(nmemb * size); } @@ -227,7 +227,7 @@ void *av_calloc(size_t nmemb, size_t size) av_malloc_attrib; */ av_alloc_size(1, 2) static inline void *av_mallocz_array(size_t nmemb, size_t size) { - if (size <= 0 || nmemb >= INT_MAX / size) + if (!size || nmemb >= INT_MAX / size) return NULL; return av_mallocz(nmemb * size); } @@ -335,6 +335,27 @@ void av_max_alloc(size_t max); */ void av_memcpy_backptr(uint8_t *dst, int back, int cnt); +/** + * Reallocate the given block if it is not large enough, otherwise do nothing. + * + * @see av_realloc + */ +void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size); + +/** + * Allocate a buffer, reusing the given one if large enough. + * + * Contrary to av_fast_realloc the current buffer contents might not be + * preserved and on error the old buffer is freed, thus no special + * handling to avoid memleaks is necessary. + * + * @param ptr pointer to pointer to already allocated buffer, overwritten with pointer to new buffer + * @param size size of the buffer *ptr points to + * @param min_size minimum size of *ptr buffer after returning, *ptr will be NULL and + * *size 0 if an error occurred. + */ +void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size); + /** * @} */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/opt.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/opt.c index c6381461d..652a2ddbb 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/opt.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/opt.c @@ -27,6 +27,7 @@ #include "avutil.h" #include "avstring.h" +#include "channel_layout.h" #include "common.h" #include "opt.h" #include "eval.h" @@ -77,6 +78,7 @@ static int read_number(const AVOption *o, void *dst, double *num, int *den, int6 case AV_OPT_TYPE_PIXEL_FMT: case AV_OPT_TYPE_SAMPLE_FMT: case AV_OPT_TYPE_INT: *intnum = *(int *)dst;return 0; + case AV_OPT_TYPE_CHANNEL_LAYOUT: case AV_OPT_TYPE_DURATION: case AV_OPT_TYPE_INT64: *intnum = *(int64_t *)dst;return 0; case AV_OPT_TYPE_FLOAT: *num = *(float *)dst;return 0; @@ -85,18 +87,27 @@ static int read_number(const AVOption *o, void *dst, double *num, int *den, int6 *den = ((AVRational*)dst)->den; return 0; case AV_OPT_TYPE_CONST: *num = o->default_val.dbl; return 0; - default:break; } return AVERROR(EINVAL); } static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum) { - if (o->max*den < num*intnum || o->min*den > num*intnum) { + if (o->type != AV_OPT_TYPE_FLAGS && + (o->max * den < num * intnum || o->min * den > num * intnum)) { av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range [%g - %g]\n", num*intnum/den, o->name, o->min, o->max); return AVERROR(ERANGE); } + if (o->type == AV_OPT_TYPE_FLAGS) { + double d = num*intnum/den; + if (d < -1.5 || d > 0xFFFFFFFF+0.5 || (llrint(d*256) & 255)) { + av_log(obj, AV_LOG_ERROR, + "Value %f for parameter '%s' is not a valid set of 32bit integer flags\n", + num*intnum/den, o->name); + return AVERROR(ERANGE); + } + } switch (o->type) { case AV_OPT_TYPE_FLAGS: @@ -104,6 +115,7 @@ static int write_number(void *obj, const AVOption *o, void *dst, double num, int case AV_OPT_TYPE_SAMPLE_FMT: case AV_OPT_TYPE_INT: *(int *)dst= llrint(num/den)*intnum; break; case AV_OPT_TYPE_DURATION: + case AV_OPT_TYPE_CHANNEL_LAYOUT: case AV_OPT_TYPE_INT64: *(int64_t *)dst= llrint(num/den)*intnum; break; case AV_OPT_TYPE_FLOAT: *(float *)dst= num*intnum/den; break; case AV_OPT_TYPE_DOUBLE:*(double *)dst= num*intnum/den; break; @@ -170,7 +182,7 @@ static int set_string_binary(void *obj, const AVOption *o, const char *val, uint static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **dst) { av_freep(dst); - *dst = (uint8_t *)av_strdup(val); + *dst = av_strdup(val); return 0; } @@ -183,6 +195,15 @@ static int set_string(void *obj, const AVOption *o, const char *val, uint8_t **d static int set_string_number(void *obj, void *target_obj, const AVOption *o, const char *val, void *dst) { int ret = 0, notfirst = 0; + int num, den; + char c; + + if (sscanf(val, "%d%*1[:/]%d%c", &num, &den, &c) == 2) { + if ((ret = write_number(obj, o, dst, 1, den, num)) >= 0) + return ret; + ret = 0; + } + for (;;) { int i, den = 1; char buf[256]; @@ -240,6 +261,101 @@ static int set_string_number(void *obj, void *target_obj, const AVOption *o, con return 0; } +static int set_string_image_size(void *obj, const AVOption *o, const char *val, int *dst) +{ + int ret; + + if (!val || !strcmp(val, "none")) { + dst[0] = + dst[1] = 0; + return 0; + } + ret = av_parse_video_size(dst, dst + 1, val); + if (ret < 0) + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as image size\n", val); + return ret; +} + +static int set_string_video_rate(void *obj, const AVOption *o, const char *val, AVRational *dst) +{ + int ret; + if (!val) { + ret = AVERROR(EINVAL); + } else { + ret = av_parse_video_rate(dst, val); + } + if (ret < 0) + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as video rate\n", val); + return ret; +} + +static int set_string_color(void *obj, const AVOption *o, const char *val, uint8_t *dst) +{ + int ret; + + if (!val) { + return 0; + } else { + ret = av_parse_color(dst, val, -1, obj); + if (ret < 0) + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as color\n", val); + return ret; + } + return 0; +} + +static int set_string_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst, + int fmt_nb, int ((*get_fmt)(const char *)), const char *desc) +{ + int fmt, min, max; + + if (!val || !strcmp(val, "none")) { + fmt = -1; + } else { + fmt = get_fmt(val); + if (fmt == -1) { + char *tail; + fmt = strtol(val, &tail, 0); + if (*tail || (unsigned)fmt >= fmt_nb) { + av_log(obj, AV_LOG_ERROR, + "Unable to parse option value \"%s\" as %s\n", val, desc); + return AVERROR(EINVAL); + } + } + } + + min = FFMAX(o->min, -1); + max = FFMIN(o->max, fmt_nb-1); + + // hack for compatibility with old ffmpeg + if(min == 0 && max == 0) { + min = -1; + max = fmt_nb-1; + } + + if (fmt < min || fmt > max) { + av_log(obj, AV_LOG_ERROR, + "Value %d for parameter '%s' out of %s format range [%d - %d]\n", + fmt, o->name, desc, min, max); + return AVERROR(ERANGE); + } + + *(int *)dst = fmt; + return 0; +} + +static int set_string_pixel_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst) +{ + return set_string_fmt(obj, o, val, dst, + AV_PIX_FMT_NB, av_get_pix_fmt, "pixel format"); +} + +static int set_string_sample_fmt(void *obj, const AVOption *o, const char *val, uint8_t *dst) +{ + return set_string_fmt(obj, o, val, dst, + AV_SAMPLE_FMT_NB, av_get_sample_fmt, "sample format"); +} + #if FF_API_OLD_AVOPTIONS int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out) { @@ -252,7 +368,7 @@ int av_set_string3(void *obj, const char *name, const char *val, int alloc, cons int av_opt_set(void *obj, const char *name, const char *val, int search_flags) { - int ret; + int ret = 0; void *dst, *target_obj; const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); if (!o || !target_obj) @@ -260,7 +376,11 @@ int av_opt_set(void *obj, const char *name, const char *val, int search_flags) if (!val && (o->type != AV_OPT_TYPE_STRING && o->type != AV_OPT_TYPE_PIXEL_FMT && o->type != AV_OPT_TYPE_SAMPLE_FMT && o->type != AV_OPT_TYPE_IMAGE_SIZE && o->type != AV_OPT_TYPE_VIDEO_RATE && - o->type != AV_OPT_TYPE_DURATION && o->type != AV_OPT_TYPE_COLOR)) + o->type != AV_OPT_TYPE_DURATION && o->type != AV_OPT_TYPE_COLOR && + o->type != AV_OPT_TYPE_CHANNEL_LAYOUT)) + return AVERROR(EINVAL); + + if (o->flags & AV_OPT_FLAG_READONLY) return AVERROR(EINVAL); dst = ((uint8_t*)target_obj) + o->offset; @@ -273,56 +393,10 @@ int av_opt_set(void *obj, const char *name, const char *val, int search_flags) case AV_OPT_TYPE_FLOAT: case AV_OPT_TYPE_DOUBLE: case AV_OPT_TYPE_RATIONAL: return set_string_number(obj, target_obj, o, val, dst); - case AV_OPT_TYPE_IMAGE_SIZE: - if (!val || !strcmp(val, "none")) { - *(int *)dst = *((int *)dst + 1) = 0; - return 0; - } - ret = av_parse_video_size(dst, ((int *)dst) + 1, val); - if (ret < 0) - av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as image size\n", val); - return ret; - case AV_OPT_TYPE_VIDEO_RATE: - if (!val) { - ret = AVERROR(EINVAL); - } else { - ret = av_parse_video_rate(dst, val); - } - if (ret < 0) - av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as video rate\n", val); - return ret; - case AV_OPT_TYPE_PIXEL_FMT: - if (!val || !strcmp(val, "none")) { - ret = AV_PIX_FMT_NONE; - } else { - ret = av_get_pix_fmt(val); - if (ret == AV_PIX_FMT_NONE) { - char *tail; - ret = strtol(val, &tail, 0); - if (*tail || (unsigned)ret >= AV_PIX_FMT_NB) { - av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as pixel format\n", val); - return AVERROR(EINVAL); - } - } - } - *(enum AVPixelFormat *)dst = ret; - return 0; - case AV_OPT_TYPE_SAMPLE_FMT: - if (!val || !strcmp(val, "none")) { - ret = AV_SAMPLE_FMT_NONE; - } else { - ret = av_get_sample_fmt(val); - if (ret == AV_SAMPLE_FMT_NONE) { - char *tail; - ret = strtol(val, &tail, 0); - if (*tail || (unsigned)ret >= AV_SAMPLE_FMT_NB) { - av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as sample format\n", val); - return AVERROR(EINVAL); - } - } - } - *(enum AVSampleFormat *)dst = ret; - return 0; + case AV_OPT_TYPE_IMAGE_SIZE: return set_string_image_size(obj, o, val, dst); + case AV_OPT_TYPE_VIDEO_RATE: return set_string_video_rate(obj, o, val, dst); + case AV_OPT_TYPE_PIXEL_FMT: return set_string_pixel_fmt(obj, o, val, dst); + case AV_OPT_TYPE_SAMPLE_FMT: return set_string_sample_fmt(obj, o, val, dst); case AV_OPT_TYPE_DURATION: if (!val) { *(int64_t *)dst = 0; @@ -333,17 +407,24 @@ int av_opt_set(void *obj, const char *name, const char *val, int search_flags) return ret; } break; - case AV_OPT_TYPE_COLOR: - if (!val) { - return 0; + case AV_OPT_TYPE_COLOR: return set_string_color(obj, o, val, dst); + case AV_OPT_TYPE_CHANNEL_LAYOUT: + if (!val || !strcmp(val, "none")) { + *(int64_t *)dst = 0; } else { - ret = av_parse_color(dst, val, -1, obj); - if (ret < 0) - av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as color\n", val); +#if FF_API_GET_CHANNEL_LAYOUT_COMPAT + int64_t cl = ff_get_channel_layout(val, 0); +#else + int64_t cl = av_get_channel_layout(val); +#endif + if (!cl) { + av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\" as channel layout\n", val); + ret = AVERROR(EINVAL); + } + *(int64_t *)dst = cl; return ret; } break; - default:break; } av_log(obj, AV_LOG_ERROR, "Invalid option type.\n"); @@ -353,7 +434,7 @@ int av_opt_set(void *obj, const char *name, const char *val, int search_flags) #define OPT_EVAL_NUMBER(name, opttype, vartype)\ int av_opt_eval_ ## name(void *obj, const AVOption *o, const char *val, vartype *name ## _out)\ {\ - if (!o || o->type != opttype)\ + if (!o || o->type != opttype || o->flags & AV_OPT_FLAG_READONLY)\ return AVERROR(EINVAL);\ return set_string_number(obj, obj, o, val, name ## _out);\ } @@ -374,6 +455,9 @@ static int set_number(void *obj, const char *name, double num, int den, int64_t if (!o || !target_obj) return AVERROR_OPTION_NOT_FOUND; + if (o->flags & AV_OPT_FLAG_READONLY) + return AVERROR(EINVAL); + dst = ((uint8_t*)target_obj) + o->offset; return write_number(obj, o, dst, num, den, intnum); } @@ -430,7 +514,7 @@ int av_opt_set_bin(void *obj, const char *name, const uint8_t *val, int len, int if (!o || !target_obj) return AVERROR_OPTION_NOT_FOUND; - if (o->type != AV_OPT_TYPE_BINARY) + if (o->type != AV_OPT_TYPE_BINARY || o->flags & AV_OPT_FLAG_READONLY) return AVERROR(EINVAL); ptr = len ? av_malloc(len) : NULL; @@ -505,15 +589,15 @@ static int set_format(void *obj, const char *name, int fmt, int search_flags, return AVERROR(EINVAL); } -#if LIBAVUTIL_VERSION_MAJOR < 53 +#if LIBAVUTIL_VERSION_MAJOR < 54 if (class->version && class->version < AV_VERSION_INT(52, 11, 100)) { min = -1; max = nb_fmts-1; } else #endif { - min = FFMIN(o->min, -1); - max = FFMAX(o->max, nb_fmts-1); + min = FFMAX(o->min, -1); + max = FFMIN(o->max, nb_fmts-1); } if (fmt < min || fmt > max) { av_log(obj, AV_LOG_ERROR, @@ -535,6 +619,22 @@ int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, return set_format(obj, name, fmt, search_flags, AV_OPT_TYPE_SAMPLE_FMT, "sample", AV_SAMPLE_FMT_NB); } +int av_opt_set_channel_layout(void *obj, const char *name, int64_t cl, int search_flags) +{ + void *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) { + av_log(obj, AV_LOG_ERROR, + "The value set by option '%s' is not a channel layout.\n", o->name); + return AVERROR(EINVAL); + } + *(int *)(((int64_t *)target_obj) + o->offset) = cl; + return 0; +} + #if FF_API_OLD_AVOPTIONS /** * @@ -591,19 +691,19 @@ int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val) buf[0] = 0; switch (o->type) { - case AV_OPT_TYPE_FLAGS: ret = snprintf((char *)buf, sizeof(buf), "0x%08X", *(int *)dst);break; - case AV_OPT_TYPE_INT: ret = snprintf((char *)buf, sizeof(buf), "%d" , *(int *)dst);break; - case AV_OPT_TYPE_INT64: ret = snprintf((char *)buf, sizeof(buf), "%"PRId64, *(int64_t*)dst);break; - case AV_OPT_TYPE_FLOAT: ret = snprintf((char *)buf, sizeof(buf), "%f" , *(float *)dst);break; - case AV_OPT_TYPE_DOUBLE: ret = snprintf((char *)buf, sizeof(buf), "%f" , *(double *)dst);break; + case AV_OPT_TYPE_FLAGS: ret = snprintf(buf, sizeof(buf), "0x%08X", *(int *)dst);break; + case AV_OPT_TYPE_INT: ret = snprintf(buf, sizeof(buf), "%d" , *(int *)dst);break; + case AV_OPT_TYPE_INT64: ret = snprintf(buf, sizeof(buf), "%"PRId64, *(int64_t*)dst);break; + case AV_OPT_TYPE_FLOAT: ret = snprintf(buf, sizeof(buf), "%f" , *(float *)dst);break; + case AV_OPT_TYPE_DOUBLE: ret = snprintf(buf, sizeof(buf), "%f" , *(double *)dst);break; case AV_OPT_TYPE_VIDEO_RATE: - case AV_OPT_TYPE_RATIONAL: ret = snprintf((char *)buf, sizeof(buf), "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break; - case AV_OPT_TYPE_CONST: ret = snprintf((char *)buf, sizeof(buf), "%f" , o->default_val.dbl);break; + case AV_OPT_TYPE_RATIONAL: ret = snprintf(buf, sizeof(buf), "%d/%d", ((AVRational*)dst)->num, ((AVRational*)dst)->den);break; + case AV_OPT_TYPE_CONST: ret = snprintf(buf, sizeof(buf), "%f" , o->default_val.dbl);break; case AV_OPT_TYPE_STRING: if (*(uint8_t**)dst) - *out_val = (uint8_t*)av_strdup(*(char**)dst); + *out_val = av_strdup(*(uint8_t**)dst); else - *out_val = (uint8_t*)av_strdup(""); + *out_val = av_strdup(""); return 0; case AV_OPT_TYPE_BINARY: len = *(int*)(((uint8_t *)dst) + sizeof(uint8_t *)); @@ -613,25 +713,29 @@ int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val) return AVERROR(ENOMEM); bin = *(uint8_t**)dst; for (i = 0; i < len; i++) - snprintf((char *)*out_val + i*2, 3, "%02X", bin[i]); + snprintf(*out_val + i*2, 3, "%02X", bin[i]); return 0; case AV_OPT_TYPE_IMAGE_SIZE: - ret = snprintf((char *)buf, sizeof(buf), "%dx%d", ((int *)dst)[0], ((int *)dst)[1]); + ret = snprintf(buf, sizeof(buf), "%dx%d", ((int *)dst)[0], ((int *)dst)[1]); break; case AV_OPT_TYPE_PIXEL_FMT: - ret = snprintf((char *)buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_pix_fmt_name(*(enum AVPixelFormat *)dst), "none")); + ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_pix_fmt_name(*(enum AVPixelFormat *)dst), "none")); break; case AV_OPT_TYPE_SAMPLE_FMT: - ret = snprintf((char *)buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_sample_fmt_name(*(enum AVSampleFormat *)dst), "none")); + ret = snprintf(buf, sizeof(buf), "%s", (char *)av_x_if_null(av_get_sample_fmt_name(*(enum AVSampleFormat *)dst), "none")); break; case AV_OPT_TYPE_DURATION: i64 = *(int64_t *)dst; - ret = snprintf((char *)buf, sizeof(buf), "%"PRIi64"d:%02d:%02d.%06d", + ret = snprintf(buf, sizeof(buf), "%"PRIi64"d:%02d:%02d.%06d", i64 / 3600000000, (int)((i64 / 60000000) % 60), (int)((i64 / 1000000) % 60), (int)(i64 % 1000000)); break; case AV_OPT_TYPE_COLOR: - ret = snprintf((char *)buf, sizeof(buf), "0x%02x%02x%02x%02x", ((int *)dst)[0], ((int *)dst)[1], ((int *)dst)[2], ((int *)dst)[3]); + ret = snprintf(buf, sizeof(buf), "0x%02x%02x%02x%02x", ((int *)dst)[0], ((int *)dst)[1], ((int *)dst)[2], ((int *)dst)[3]); + break; + case AV_OPT_TYPE_CHANNEL_LAYOUT: + i64 = *(int64_t *)dst; + ret = snprintf(buf, sizeof(buf), "0x%"PRIx64, i64); break; default: return AVERROR(EINVAL); @@ -639,7 +743,7 @@ int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val) if (ret >= sizeof(buf)) return AVERROR(EINVAL); - *out_val = (uint8_t*) av_strdup((char *)buf); + *out_val = av_strdup(buf); return 0; } @@ -802,6 +906,23 @@ int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AV return get_format(obj, name, search_flags, out_fmt, AV_OPT_TYPE_SAMPLE_FMT, "sample"); } +int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *cl) +{ + void *dst, *target_obj; + const AVOption *o = av_opt_find2(obj, name, NULL, 0, search_flags, &target_obj); + if (!o || !target_obj) + return AVERROR_OPTION_NOT_FOUND; + if (o->type != AV_OPT_TYPE_CHANNEL_LAYOUT) { + av_log(obj, AV_LOG_ERROR, + "The value for option '%s' is not a channel layout.\n", name); + return AVERROR(EINVAL); + } + + dst = ((uint8_t*)target_obj) + o->offset; + *cl = *(int64_t *)dst; + return 0; +} + int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name) { const AVOption *field = av_opt_find(obj, field_name, NULL, 0, 0); @@ -821,6 +942,8 @@ static void log_value(void *av_log_obj, int level, double d) av_log(av_log_obj, level, "INT_MAX"); } else if (d == INT_MIN) { av_log(av_log_obj, level, "INT_MIN"); + } else if (d == UINT32_MAX) { + av_log(av_log_obj, level, "UINT32_MAX"); } else if (d == (double)INT64_MAX) { av_log(av_log_obj, level, "I64_MAX"); } else if (d == INT64_MIN) { @@ -829,6 +952,18 @@ static void log_value(void *av_log_obj, int level, double d) av_log(av_log_obj, level, "FLT_MAX"); } else if (d == FLT_MIN) { av_log(av_log_obj, level, "FLT_MIN"); + } else if (d == -FLT_MAX) { + av_log(av_log_obj, level, "-FLT_MAX"); + } else if (d == -FLT_MIN) { + av_log(av_log_obj, level, "-FLT_MIN"); + } else if (d == DBL_MAX) { + av_log(av_log_obj, level, "DBL_MAX"); + } else if (d == DBL_MIN) { + av_log(av_log_obj, level, "DBL_MIN"); + } else if (d == -DBL_MAX) { + av_log(av_log_obj, level, "-DBL_MAX"); + } else if (d == -DBL_MIN) { + av_log(av_log_obj, level, "-DBL_MIN"); } else { av_log(av_log_obj, level, "%g", d); } @@ -905,6 +1040,9 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit, case AV_OPT_TYPE_COLOR: av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); break; + case AV_OPT_TYPE_CHANNEL_LAYOUT: + av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); + break; case AV_OPT_TYPE_CONST: default: av_log(av_log_obj, AV_LOG_INFO, "%-12s ", ""); @@ -916,6 +1054,8 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit, av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_VIDEO_PARAM ) ? 'V' : '.'); av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_AUDIO_PARAM ) ? 'A' : '.'); av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_SUBTITLE_PARAM) ? 'S' : '.'); + av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_EXPORT) ? 'X' : '.'); + av_log(av_log_obj, AV_LOG_INFO, "%c", (opt->flags & AV_OPT_FLAG_READONLY) ? 'R' : '.'); if (opt->help) av_log(av_log_obj, AV_LOG_INFO, " %s", opt->help); @@ -935,7 +1075,6 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit, av_log(av_log_obj, AV_LOG_INFO, ")"); } break; - default:break; } av_opt_freep_ranges(&r); } @@ -977,7 +1116,9 @@ static void opt_list(void *obj, void *av_log_obj, const char *unit, case AV_OPT_TYPE_VIDEO_RATE: av_log(av_log_obj, AV_LOG_INFO, "\"%s\"", opt->default_val.str); break; - default:break; + case AV_OPT_TYPE_CHANNEL_LAYOUT: + av_log(av_log_obj, AV_LOG_INFO, "0x%"PRIx64, opt->default_val.i64); + break; } av_log(av_log_obj, AV_LOG_INFO, ")"); } @@ -1004,9 +1145,7 @@ int av_opt_show2(void *obj, void *av_log_obj, int req_flags, int rej_flags) void av_opt_set_defaults(void *s) { #if FF_API_OLD_AVOPTIONS -AV_NOWARN_DEPRECATED( av_opt_set_defaults2(s, 0, 0); -); } void av_opt_set_defaults2(void *s, int mask, int flags) @@ -1015,10 +1154,15 @@ void av_opt_set_defaults2(void *s, int mask, int flags) const AVClass *class = *(AVClass **)s; const AVOption *opt = NULL; while ((opt = av_opt_next(s, opt)) != NULL) { + void *dst = ((uint8_t*)s) + opt->offset; #if FF_API_OLD_AVOPTIONS if ((opt->flags & mask) != flags) continue; #endif + + if (opt->flags & AV_OPT_FLAG_READONLY) + continue; + switch (opt->type) { case AV_OPT_TYPE_CONST: /* Nothing to be done here */ @@ -1027,42 +1171,49 @@ void av_opt_set_defaults2(void *s, int mask, int flags) case AV_OPT_TYPE_INT: case AV_OPT_TYPE_INT64: case AV_OPT_TYPE_DURATION: - av_opt_set_int(s, opt->name, opt->default_val.i64, 0); + case AV_OPT_TYPE_CHANNEL_LAYOUT: + write_number(s, opt, dst, 1, 1, opt->default_val.i64); break; case AV_OPT_TYPE_DOUBLE: case AV_OPT_TYPE_FLOAT: { double val; val = opt->default_val.dbl; - av_opt_set_double(s, opt->name, val, 0); + write_number(s, opt, dst, val, 1, 1); } break; case AV_OPT_TYPE_RATIONAL: { AVRational val; val = av_d2q(opt->default_val.dbl, INT_MAX); - av_opt_set_q(s, opt->name, val, 0); + write_number(s, opt, dst, 1, val.den, val.num); } break; case AV_OPT_TYPE_COLOR: + set_string_color(s, opt, opt->default_val.str, dst); + break; case AV_OPT_TYPE_STRING: + set_string(s, opt, opt->default_val.str, dst); + break; case AV_OPT_TYPE_IMAGE_SIZE: + set_string_image_size(s, opt, opt->default_val.str, dst); + break; case AV_OPT_TYPE_VIDEO_RATE: - av_opt_set(s, opt->name, opt->default_val.str, 0); + set_string_video_rate(s, opt, opt->default_val.str, dst); break; case AV_OPT_TYPE_PIXEL_FMT: -#if LIBAVUTIL_VERSION_MAJOR < 53 +#if LIBAVUTIL_VERSION_MAJOR < 54 if (class->version && class->version < AV_VERSION_INT(52, 10, 100)) av_opt_set(s, opt->name, opt->default_val.str, 0); else #endif - av_opt_set_pixel_fmt(s, opt->name, opt->default_val.i64, 0); + write_number(s, opt, dst, 1, 1, opt->default_val.i64); break; case AV_OPT_TYPE_SAMPLE_FMT: -#if LIBAVUTIL_VERSION_MAJOR < 53 +#if LIBAVUTIL_VERSION_MAJOR < 54 if (class->version && class->version < AV_VERSION_INT(52, 10, 100)) av_opt_set(s, opt->name, opt->default_val.str, 0); else #endif - av_opt_set_sample_fmt(s, opt->name, opt->default_val.i64, 0); + write_number(s, opt, dst, 1, 1, opt->default_val.i64); break; case AV_OPT_TYPE_BINARY: /* Cannot set default for binary */ @@ -1308,18 +1459,18 @@ const AVOption *av_opt_find2(void *obj, const char *name, const char *unit, if (search_flags & AV_OPT_SEARCH_CHILDREN) { if (search_flags & AV_OPT_SEARCH_FAKE_OBJ) { const AVClass *child = NULL; - while ((child = av_opt_child_class_next(c, child))) - if ((o = av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL))) + while (child = av_opt_child_class_next(c, child)) + if (o = av_opt_find2(&child, name, unit, opt_flags, search_flags, NULL)) return o; } else { void *child = NULL; - while ((child = av_opt_child_next(obj, child))) - if ((o = av_opt_find2(child, name, unit, opt_flags, search_flags, target_obj))) + while (child = av_opt_child_next(obj, child)) + if (o = av_opt_find2(child, name, unit, opt_flags, search_flags, target_obj)) return o; } } - while ((o = av_opt_next(obj, o))) { + while (o = av_opt_next(obj, o)) { if (!strcmp(o->name, name) && (o->flags & opt_flags) == opt_flags && ((!unit && o->type != AV_OPT_TYPE_CONST) || (unit && o->type == AV_OPT_TYPE_CONST && o->unit && !strcmp(o->unit, unit)))) { @@ -1403,6 +1554,7 @@ int av_opt_query_ranges_default(AVOptionRanges **ranges_arg, void *obj, const ch case AV_OPT_TYPE_DOUBLE: case AV_OPT_TYPE_DURATION: case AV_OPT_TYPE_COLOR: + case AV_OPT_TYPE_CHANNEL_LAYOUT: break; case AV_OPT_TYPE_STRING: range->component_min = 0; @@ -1470,6 +1622,7 @@ typedef struct TestContext enum AVSampleFormat sample_fmt; int64_t duration; uint8_t color[4]; + int64_t channel_layout; } TestContext; #define OFFSET(x) offsetof(TestContext, x) @@ -1488,11 +1641,12 @@ static const AVOption test_options[]= { {"lame", "set lame flag ", 0, AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_LAME}, INT_MIN, INT_MAX, 0, "flags" }, {"mu", "set mu flag ", 0, AV_OPT_TYPE_CONST, {.i64 = TEST_FLAG_MU}, INT_MIN, INT_MAX, 0, "flags" }, {"size", "set size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE,{0}, 0, 0 }, -{"pix_fmt", "set pixfmt", OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, -1, AV_PIX_FMT_NB-1}, -{"sample_fmt", "set samplefmt", OFFSET(sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, {.i64 = AV_SAMPLE_FMT_NONE}, -1, AV_SAMPLE_FMT_NB-1}, +{"pix_fmt", "set pixfmt", OFFSET(pix_fmt), AV_OPT_TYPE_PIXEL_FMT, {.i64 = AV_PIX_FMT_NONE}, -1, INT_MAX}, +{"sample_fmt", "set samplefmt", OFFSET(sample_fmt), AV_OPT_TYPE_SAMPLE_FMT, {.i64 = AV_SAMPLE_FMT_NONE}, -1, INT_MAX}, {"video_rate", "set videorate", OFFSET(video_rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, 0 }, {"duration", "set duration", OFFSET(duration), AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX}, {"color", "set color", OFFSET(color), AV_OPT_TYPE_COLOR, {.str = "pink"}, 0, 0}, +{"cl", "set channel layout", OFFSET(channel_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64 = AV_CH_LAYOUT_HEXAGONAL}, 0, INT64_MAX}, {NULL}, }; @@ -1554,6 +1708,8 @@ int main(void) "color=blue", "color=0x223300", "color=0x42FF07AA", + "cl=stereo+downmix", + "cl=foo", }; test_ctx.class = &test_class; @@ -1567,7 +1723,7 @@ int main(void) av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]); printf("\n"); } - av_freep(&test_ctx.string); + av_opt_free(&test_ctx); } printf("\nTesting av_opt_set_from_string()\n"); @@ -1588,7 +1744,6 @@ int main(void) test_ctx.class = &test_class; av_opt_set_defaults(&test_ctx); - test_ctx.string = av_strdup("default"); av_log_set_level(AV_LOG_DEBUG); @@ -1598,7 +1753,7 @@ int main(void) av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]); printf("\n"); } - av_freep(&test_ctx.string); + av_opt_free(&test_ctx); } return 0; diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/opt.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/opt.h index 3882751f0..cd1b18e4c 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/opt.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/opt.h @@ -233,6 +233,7 @@ enum AVOptionType{ AV_OPT_TYPE_VIDEO_RATE = MKBETAG('V','R','A','T'), ///< offset must point to AVRational AV_OPT_TYPE_DURATION = MKBETAG('D','U','R',' '), AV_OPT_TYPE_COLOR = MKBETAG('C','O','L','R'), + AV_OPT_TYPE_CHANNEL_LAYOUT = MKBETAG('C','H','L','A'), #if FF_API_OLD_AVOPTIONS FF_OPT_TYPE_FLAGS = 0, FF_OPT_TYPE_INT, @@ -281,10 +282,21 @@ typedef struct AVOption { int flags; #define AV_OPT_FLAG_ENCODING_PARAM 1 ///< a generic parameter which can be set by the user for muxing or encoding #define AV_OPT_FLAG_DECODING_PARAM 2 ///< a generic parameter which can be set by the user for demuxing or decoding +#if FF_API_OPT_TYPE_METADATA #define AV_OPT_FLAG_METADATA 4 ///< some data extracted or inserted into the file like title, comment, ... +#endif #define AV_OPT_FLAG_AUDIO_PARAM 8 #define AV_OPT_FLAG_VIDEO_PARAM 16 #define AV_OPT_FLAG_SUBTITLE_PARAM 32 +/** + * The option is inteded for exporting values to the caller. + */ +#define AV_OPT_FLAG_EXPORT 64 +/** + * The option may not be set through the AVOptions API, only read. + * This flag only makes sense when AV_OPT_FLAG_EXPORT is also set. + */ +#define AV_OPT_FLAG_READONLY 128 #define AV_OPT_FLAG_FILTERING_PARAM (1<<16) ///< a generic parameter which can be set by the user for filtering //FIXME think about enc-audio, ... style flags @@ -319,7 +331,7 @@ typedef struct AVOptionRanges { /** * Look for an option in obj. Look only for the options which * have the flags set as specified in mask and flags (that is, - * for which it is the case that opt->flags & mask == flags). + * for which it is the case that (opt->flags & mask) == flags). * * @param[in] obj a pointer to a struct whose first element is a * pointer to an AVClass @@ -657,6 +669,7 @@ int av_opt_set_image_size(void *obj, const char *name, int w, int h, int search_ int av_opt_set_pixel_fmt (void *obj, const char *name, enum AVPixelFormat fmt, int search_flags); int av_opt_set_sample_fmt(void *obj, const char *name, enum AVSampleFormat fmt, int search_flags); int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int search_flags); +int av_opt_set_channel_layout(void *obj, const char *name, int64_t ch_layout, int search_flags); /** * Set a binary option to an integer list. @@ -687,10 +700,10 @@ int av_opt_set_video_rate(void *obj, const char *name, AVRational val, int searc * @param[in] search_flags flags passed to av_opt_find2. I.e. if AV_OPT_SEARCH_CHILDREN * is passed here, then the option may be found in a child of obj. * @param[out] out_val value of the option will be written here - * @return 0 on success, a negative error code otherwise + * @return >=0 on success, a negative error code otherwise */ /** - * @note the returned string will av_malloc()ed and must be av_free()ed by the caller + * @note the returned string will be av_malloc()ed and must be av_free()ed by the caller */ int av_opt_get (void *obj, const char *name, int search_flags, uint8_t **out_val); int av_opt_get_int (void *obj, const char *name, int search_flags, int64_t *out_val); @@ -700,6 +713,7 @@ int av_opt_get_image_size(void *obj, const char *name, int search_flags, int *w_ int av_opt_get_pixel_fmt (void *obj, const char *name, int search_flags, enum AVPixelFormat *out_fmt); int av_opt_get_sample_fmt(void *obj, const char *name, int search_flags, enum AVSampleFormat *out_fmt); int av_opt_get_video_rate(void *obj, const char *name, int search_flags, AVRational *out_val); +int av_opt_get_channel_layout(void *obj, const char *name, int search_flags, int64_t *ch_layout); /** * @} */ diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/parseutils.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/parseutils.c index 5797e9efb..ba4b4e1b7 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/parseutils.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/parseutils.c @@ -115,6 +115,12 @@ static const VideoSizeAbbr video_size_abbrs[] = { { "4k", 4096,2160 }, /* Digital Cinema System Specification */ { "4kflat", 3996,2160 }, { "4kscope", 4096,1716 }, + { "nhd", 640,360 }, + { "hqvga", 240,160 }, + { "wqvga", 400,240 }, + { "fwqvga", 432,240 }, + { "hvga", 480,320 }, + { "qhd", 960,540 }, }; static const VideoRateAbbr video_rate_abbrs[]= { @@ -414,6 +420,20 @@ int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen, return 0; } +const char *av_get_known_color_name(int color_idx, const uint8_t **rgbp) +{ + const ColorEntry *color; + + if ((unsigned)color_idx >= FF_ARRAY_ELEMS(color_table)) + return NULL; + + color = &color_table[color_idx]; + if (rgbp) + *rgbp = color->rgb_color; + + return color->name; +} + /* get a positive number between n_min and n_max, for a maximum length of len_max. Return -1 if error. */ static int date_get_num(const char **pp, @@ -593,12 +613,14 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration) dt.tm_hour = 0; } if (!q) { + char *o; /* parse timestr as S+ */ - dt.tm_sec = strtol(p, (void *)&q, 10); - if (q == p) /* the parsing didn't succeed */ + dt.tm_sec = strtol(p, &o, 10); + if (o == p) /* the parsing didn't succeed */ return AVERROR(EINVAL); dt.tm_min = 0; dt.tm_hour = 0; + q = o; } } diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/pixdesc.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/pixdesc.c index 78f21c320..7d41b2220 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/pixdesc.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/pixdesc.c @@ -29,6 +29,7 @@ #include "internal.h" #include "intreadwrite.h" #include "avstring.h" +#include "version.h" void av_read_image_line(uint16_t *dst, const uint8_t *data[4], const int linesize[4], @@ -313,6 +314,7 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { }, .flags = AV_PIX_FMT_FLAG_PLANAR, }, +#if FF_API_XVMC [AV_PIX_FMT_XVMC_MPEG2_MC] = { .name = "xvmcmc", .flags = AV_PIX_FMT_FLAG_HWACCEL, @@ -321,6 +323,13 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { .name = "xvmcidct", .flags = AV_PIX_FMT_FLAG_HWACCEL, }, +#endif /* FF_API_XVMC */ +#if !FF_API_XVMC + [AV_PIX_FMT_XVMC] = { + .name = "xvmc", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, +#endif /* !FF_API_XVMC */ [AV_PIX_FMT_UYVY422] = { .name = "uyvy422", .nb_components = 3, @@ -1761,50 +1770,62 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { [AV_PIX_FMT_BAYER_BGGR8] = { .name = "bayer_bggr8", BAYER8_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_RGB, }, [AV_PIX_FMT_BAYER_BGGR16LE] = { .name = "bayer_bggr16le", BAYER16_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_RGB, }, [AV_PIX_FMT_BAYER_BGGR16BE] = { .name = "bayer_bggr16be", BAYER16_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB, }, [AV_PIX_FMT_BAYER_RGGB8] = { .name = "bayer_rggb8", BAYER8_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_RGB, }, [AV_PIX_FMT_BAYER_RGGB16LE] = { .name = "bayer_rggb16le", BAYER16_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_RGB, }, [AV_PIX_FMT_BAYER_RGGB16BE] = { .name = "bayer_rggb16be", BAYER16_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB, }, [AV_PIX_FMT_BAYER_GBRG8] = { .name = "bayer_gbrg8", BAYER8_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_RGB, }, [AV_PIX_FMT_BAYER_GBRG16LE] = { .name = "bayer_gbrg16le", BAYER16_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_RGB, }, [AV_PIX_FMT_BAYER_GBRG16BE] = { .name = "bayer_gbrg16be", BAYER16_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB, }, [AV_PIX_FMT_BAYER_GRBG8] = { .name = "bayer_grbg8", BAYER8_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_RGB, }, [AV_PIX_FMT_BAYER_GRBG16LE] = { .name = "bayer_grbg16le", BAYER16_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_RGB, }, [AV_PIX_FMT_BAYER_GRBG16BE] = { .name = "bayer_grbg16be", BAYER16_DESC_COMMON + .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_RGB, }, [AV_PIX_FMT_NV16] = { .name = "nv16", @@ -1992,13 +2013,10 @@ int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt) } void ff_check_pixfmt_descriptors(void){ - int i, j, k; + int i, j; - AV_NOWARN_DEPRECATED( k = FF_ARRAY_ELEMS(av_pix_fmt_descriptors); ); - for (i=0; i #include "avassert.h" #include "internal.h" +#include "intreadwrite.h" #include "timer.h" #include "random_seed.h" #include "sha.h" -#include "intreadwrite.h" #ifndef TEST #define TEST 0 @@ -65,7 +65,7 @@ static uint32_t get_generic_seed(void) struct AVSHA *sha = (void*)tmp; clock_t last_t = 0; static uint64_t i = 0; - static uint32_t buffer[512] = {0}; + static uint32_t buffer[512] = { 0 }; unsigned char digest[20]; uint64_t last_i = i; @@ -84,11 +84,11 @@ static uint32_t get_generic_seed(void) for (;;) { clock_t t = clock(); - if(last_t == t){ - buffer[i&511]++; - }else{ - buffer[++i&511]+= (t-last_t) % 3294638521U; - if((last_i && i-last_i > 4) || i-last_i > 64 || (TEST && i-last_i > 8)) + if (last_t == t) { + buffer[i & 511]++; + } else { + buffer[++i & 511] += (t - last_t) % 3294638521U; + if (last_i && i - last_i > 4 || i - last_i > 64 || TEST && i - last_i > 8) break; } last_t = t; @@ -98,9 +98,9 @@ static uint32_t get_generic_seed(void) buffer[0] = buffer[1] = 0; av_sha_init(sha, 160); - av_sha_update(sha, (uint8_t*)buffer, sizeof(buffer)); + av_sha_update(sha, (const uint8_t *)buffer, sizeof(buffer)); av_sha_final(sha, digest); - return AV_RB32(digest) + AV_RB32(digest+16); + return AV_RB32(digest) + AV_RB32(digest + 16); } uint32_t av_get_random_seed(void) diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/sha.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/sha.c index c3c9284e2..0cf94245a 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/sha.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/sha.c @@ -343,9 +343,9 @@ void av_sha_final(AVSHA* ctx, uint8_t *digest) int i; uint64_t finalcount = av_be2ne64(ctx->count << 3); - av_sha_update(ctx, (const uint8_t *) "\200", 1); + av_sha_update(ctx, "\200", 1); while ((ctx->count & 63) != 56) - av_sha_update(ctx, (const uint8_t *) "", 1); + av_sha_update(ctx, "", 1); av_sha_update(ctx, (uint8_t *)&finalcount, 8); /* Should cause a transform() */ for (i = 0; i < ctx->digest_len; i++) AV_WB32(digest + i*4, ctx->state[i]); diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/version.h b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/version.h index cc64e4ab1..fc959ebd7 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/version.h +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/version.h @@ -21,25 +21,7 @@ #ifndef AVUTIL_VERSION_H #define AVUTIL_VERSION_H -/** - * @defgroup preproc_misc Preprocessor String Macros - * - * String manipulation macros - * - * @{ - */ - -#define AV_STRINGIFY(s) AV_TOSTRING(s) -#define AV_TOSTRING(s) #s - -#define AV_GLUE(a, b) a ## b -#define AV_JOIN(a, b) AV_GLUE(a, b) - -#define AV_PRAGMA(s) _Pragma(#s) - -/** - * @} - */ +#include "macros.h" /** * @defgroup version_utils Library Version Macros @@ -58,7 +40,6 @@ * @} */ - /** * @file * @ingroup lavu @@ -75,8 +56,8 @@ */ #define LIBAVUTIL_VERSION_MAJOR 52 -#define LIBAVUTIL_VERSION_MINOR 46 -#define LIBAVUTIL_VERSION_MICRO 100 +#define LIBAVUTIL_VERSION_MINOR 66 +#define LIBAVUTIL_VERSION_MICRO 101 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ LIBAVUTIL_VERSION_MINOR, \ @@ -100,43 +81,61 @@ */ #ifndef FF_API_GET_BITS_PER_SAMPLE_FMT -#define FF_API_GET_BITS_PER_SAMPLE_FMT (LIBAVUTIL_VERSION_MAJOR < 53) +#define FF_API_GET_BITS_PER_SAMPLE_FMT (LIBAVUTIL_VERSION_MAJOR < 54) #endif #ifndef FF_API_FIND_OPT -#define FF_API_FIND_OPT (LIBAVUTIL_VERSION_MAJOR < 53) +#define FF_API_FIND_OPT (LIBAVUTIL_VERSION_MAJOR < 54) #endif #ifndef FF_API_OLD_AVOPTIONS -#define FF_API_OLD_AVOPTIONS (LIBAVUTIL_VERSION_MAJOR < 53) +#define FF_API_OLD_AVOPTIONS (LIBAVUTIL_VERSION_MAJOR < 54) #endif #ifndef FF_API_PIX_FMT -#define FF_API_PIX_FMT (LIBAVUTIL_VERSION_MAJOR < 53) +#define FF_API_PIX_FMT (LIBAVUTIL_VERSION_MAJOR < 54) #endif #ifndef FF_API_CONTEXT_SIZE -#define FF_API_CONTEXT_SIZE (LIBAVUTIL_VERSION_MAJOR < 53) +#define FF_API_CONTEXT_SIZE (LIBAVUTIL_VERSION_MAJOR < 54) #endif #ifndef FF_API_PIX_FMT_DESC -#define FF_API_PIX_FMT_DESC (LIBAVUTIL_VERSION_MAJOR < 53) +#define FF_API_PIX_FMT_DESC (LIBAVUTIL_VERSION_MAJOR < 54) #endif #ifndef FF_API_AV_REVERSE -#define FF_API_AV_REVERSE (LIBAVUTIL_VERSION_MAJOR < 53) +#define FF_API_AV_REVERSE (LIBAVUTIL_VERSION_MAJOR < 54) #endif #ifndef FF_API_AUDIOCONVERT -#define FF_API_AUDIOCONVERT (LIBAVUTIL_VERSION_MAJOR < 53) +#define FF_API_AUDIOCONVERT (LIBAVUTIL_VERSION_MAJOR < 54) #endif #ifndef FF_API_CPU_FLAG_MMX2 -#define FF_API_CPU_FLAG_MMX2 (LIBAVUTIL_VERSION_MAJOR < 53) +#define FF_API_CPU_FLAG_MMX2 (LIBAVUTIL_VERSION_MAJOR < 54) #endif #ifndef FF_API_SAMPLES_UTILS_RETURN_ZERO -#define FF_API_SAMPLES_UTILS_RETURN_ZERO (LIBAVUTIL_VERSION_MAJOR < 53) +#define FF_API_SAMPLES_UTILS_RETURN_ZERO (LIBAVUTIL_VERSION_MAJOR < 54) #endif #ifndef FF_API_LLS_PRIVATE -#define FF_API_LLS_PRIVATE (LIBAVUTIL_VERSION_MAJOR < 53) +#define FF_API_LLS_PRIVATE (LIBAVUTIL_VERSION_MAJOR < 54) +#endif +#ifndef FF_API_LLS1 +#define FF_API_LLS1 (LIBAVUTIL_VERSION_MAJOR < 54) #endif #ifndef FF_API_AVFRAME_LAVC -#define FF_API_AVFRAME_LAVC (LIBAVUTIL_VERSION_MAJOR < 53) +#define FF_API_AVFRAME_LAVC (LIBAVUTIL_VERSION_MAJOR < 54) #endif #ifndef FF_API_VDPAU -#define FF_API_VDPAU (LIBAVUTIL_VERSION_MAJOR < 53) +#define FF_API_VDPAU (LIBAVUTIL_VERSION_MAJOR < 54) +#endif +#ifndef FF_API_GET_CHANNEL_LAYOUT_COMPAT +#define FF_API_GET_CHANNEL_LAYOUT_COMPAT (LIBAVUTIL_VERSION_MAJOR < 54) +#endif +#ifndef FF_API_OLD_OPENCL +#define FF_API_OLD_OPENCL (LIBAVUTIL_VERSION_MAJOR < 54) +#endif +#ifndef FF_API_XVMC +#define FF_API_XVMC (LIBAVUTIL_VERSION_MAJOR < 54) +#endif +#ifndef FF_API_INTFLOAT +#define FF_API_INTFLOAT (LIBAVUTIL_VERSION_MAJOR < 54) +#endif +#ifndef FF_API_OPT_TYPE_METADATA +#define FF_API_OPT_TYPE_METADATA (LIBAVUTIL_VERSION_MAJOR < 54) #endif /** diff --git a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/x86/lls_init.c b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/x86/lls_init.c index 181ca38da..bf999d5fc 100644 --- a/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/x86/lls_init.c +++ b/Frameworks/FFMPEG/ffmpeg-minimal/libavutil/x86/lls_init.c @@ -20,14 +20,14 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "libavutil/lls.h" +#include "libavutil/lls2.h" #include "libavutil/x86/cpu.h" -void ff_update_lls_sse2(LLSModel *m, double *var); -void ff_update_lls_avx(LLSModel *m, double *var); -double ff_evaluate_lls_sse2(LLSModel *m, double *var, int order); +void ff_update_lls_sse2(LLSModel2 *m, double *var); +void ff_update_lls_avx(LLSModel2 *m, double *var); +double ff_evaluate_lls_sse2(LLSModel2 *m, double *var, int order); -av_cold void ff_init_lls_x86(LLSModel *m) +av_cold void ff_init_lls_x86(LLSModel2 *m) { int cpu_flags = av_get_cpu_flags(); if (EXTERNAL_SSE2(cpu_flags)) { diff --git a/Plugins/FFMPEG/FFMPEGDecoder.m b/Plugins/FFMPEG/FFMPEGDecoder.m index 6eca3aeb3..beb7f3a80 100644 --- a/Plugins/FFMPEG/FFMPEGDecoder.m +++ b/Plugins/FFMPEG/FFMPEGDecoder.m @@ -109,8 +109,8 @@ int lockmgr_callback(void ** mutex, enum AVLockOp op) return NO; } - lastDecodedFrame = avcodec_alloc_frame(); - avcodec_get_frame_defaults(lastDecodedFrame); + lastDecodedFrame = av_frame_alloc(); + av_frame_unref(lastDecodedFrame); lastReadPacket = malloc(sizeof(AVPacket)); av_new_packet(lastReadPacket, 0); readNextPacket = YES; @@ -201,7 +201,10 @@ int lockmgr_callback(void ** mutex, enum AVLockOp op) lastDecodedFrame->nb_samples, codecCtx->sample_fmt, 1); - if(readNextPacket && !endOfStream) + if ( dataSize < 0 ) + dataSize = 0; + + while(readNextPacket && !endOfStream) { // consume next chunk of encoded data from input stream av_free_packet(lastReadPacket); @@ -209,10 +212,11 @@ int lockmgr_callback(void ** mutex, enum AVLockOp op) { DLog(@"End of stream"); endOfStream = YES; - if (dataSize <= bytesConsumedFromDecodedFrame) - break; // end of stream; } + if (lastReadPacket->stream_index != streamIndex) + continue; + readNextPacket = NO; // we probably won't need to consume another chunk bytesReadFromPacket = 0; // until this one is fully decoded } @@ -223,10 +227,25 @@ int lockmgr_callback(void ** mutex, enum AVLockOp op) break; // consumed all decoded samples - decode more - avcodec_get_frame_defaults(lastDecodedFrame); + av_frame_unref(lastDecodedFrame); bytesConsumedFromDecodedFrame = 0; - int len = avcodec_decode_audio4(codecCtx, lastDecodedFrame, &gotFrame, lastReadPacket); - if (len < 0 || (!gotFrame)) + int len; + do { + len = avcodec_decode_audio4(codecCtx, lastDecodedFrame, &gotFrame, lastReadPacket); + if (len > 0) + { + if (len >= lastReadPacket->size) { + lastReadPacket->data -= bytesReadFromPacket; + lastReadPacket->size += bytesReadFromPacket; + readNextPacket = YES; + break; + } + bytesReadFromPacket += len; + lastReadPacket->data += len; + lastReadPacket->size -= len; + } + } while (!gotFrame && len > 0); + if (len < 0) { char errbuf[4096]; av_strerror(len, errbuf, 4096); @@ -241,18 +260,9 @@ int lockmgr_callback(void ** mutex, enum AVLockOp op) dataSize = av_samples_get_buffer_size(&planeSize, codecCtx->channels, lastDecodedFrame->nb_samples, codecCtx->sample_fmt, 1); - bytesReadFromPacket += len; - } - - if (bytesReadFromPacket >= lastReadPacket->size) - { - // decoding consumed all the read packet - read another next time - readNextPacket = YES; - } - else - { - lastReadPacket->data += len; - lastReadPacket->size -= len; + + if ( dataSize < 0 ) + dataSize = 0; } } diff --git a/Plugins/FFMPEG/FFMPEGFileProtocols.m b/Plugins/FFMPEG/FFMPEGFileProtocols.m index 58322f024..e71016c64 100644 --- a/Plugins/FFMPEG/FFMPEGFileProtocols.m +++ b/Plugins/FFMPEG/FFMPEGFileProtocols.m @@ -139,7 +139,7 @@ URLProtocol ff_unpack_protocol = { void registerCogProtocols() { - ffurl_register_protocol(&ff_file_protocol, sizeof(ff_file_protocol)); - ffurl_register_protocol(&ff_http_protocol, sizeof(ff_http_protocol)); - ffurl_register_protocol(&ff_unpack_protocol, sizeof(ff_unpack_protocol)); + ffurl_register_protocol(&ff_file_protocol); + ffurl_register_protocol(&ff_http_protocol); + ffurl_register_protocol(&ff_unpack_protocol); }