diff --git a/projects/RPi/patches/xbmc-master/xbmc-master-newclock3.patch b/projects/RPi/patches/xbmc-master/xbmc-master-newclock3.patch index 3e6e28f397..e97d1435b4 100644 --- a/projects/RPi/patches/xbmc-master/xbmc-master-newclock3.patch +++ b/projects/RPi/patches/xbmc-master/xbmc-master-newclock3.patch @@ -1,7 +1,7 @@ -From 95f1a8b37a6c081793be8f1c86a92a43b5a7b94b Mon Sep 17 00:00:00 2001 +From 1e848e4c33ff52db81a2abb033d37f62c4e519ce Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Thu, 14 Nov 2013 19:48:41 +0000 -Subject: [PATCH 01/83] More efficient infobool expression evaluator +Subject: [PATCH 01/89] More efficient infobool expression evaluator Expession infobools are evaluated at runtime from one or more single infobools and a combination of boolean NOT, AND and OR operators. Previously, parsing @@ -500,10 +500,10 @@ index 4e0faee..0a91399 100644 1.9.3 -From 9c8f3e1cd443da07f238f392f65ac599be76a58a Mon Sep 17 00:00:00 2001 +From 54756a644dbe76e206898f1e032ef62dcdcf707d Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Mon, 24 Mar 2014 22:26:21 +0000 -Subject: [PATCH 02/83] Where an infobool expression failed to parse, evaluate +Subject: [PATCH 02/89] Where an infobool expression failed to parse, evaluate the infobool as false. Previously, this would result in a segfault due to the dereferencing of an uninitialised pointer to the head of the expression tree. @@ -530,10 +530,10 @@ index db461dd..7c54064 100644 1.9.3 -From a963605e64c59f03629d6b94b3e8eb85e3aec51c Mon Sep 17 00:00:00 2001 +From ae418d7b77094510181ef155ecd256e1cabb013b Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Tue, 26 Nov 2013 20:09:48 +0000 -Subject: [PATCH 03/83] Add caching of infolabels +Subject: [PATCH 03/89] Add caching of infolabels The functions CGUIInfoLabel::GetLabel and CGUIInfoLabel::GetItemLabel take a number of strings returned from CGUIInfoManager::GetImage or @@ -746,10 +746,10 @@ index 8c1c1dc..418b2c4 100644 1.9.3 -From 40b0137cdcf5435743fa01d202f3cda9bbf8266c Mon Sep 17 00:00:00 2001 +From 46c5a5ed81ff6fb37b767b99be0435478e27c4d1 Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Tue, 10 Dec 2013 01:12:31 +0000 -Subject: [PATCH 04/83] De-duplication of string cache for non-item and item +Subject: [PATCH 04/89] De-duplication of string cache for non-item and item labels --- @@ -889,219 +889,10 @@ index 418b2c4..6d9ebf7 100644 1.9.3 -From fa4732e78babd7a0b0d91f2e6ecebe490474c2a1 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Fri, 21 Feb 2014 15:16:13 +0000 -Subject: [PATCH 05/83] Faster and simpler portable implementation of - MathUtils::round_int(). - -Much as I like a bit of inline assembler, I have also removed the ARM versions -of MathUtils::truncate_int() and MathUtils::round_int(). The former was just -how any sane compiler should have assembled a cast from double to signed int -anyway. The latter was a much too complicated way to achieve the desired -effect, and was switched out in most ARM builds anyway in favour of the old -portable implementation that used floor(). - -Verified that MathUtils::test() still passes, and that GCC is now able to -inline MathUtils::round_int(), where it didn't previously. - -I tested on a Raspberry Pi with the default theme, displaying the front page -with the RSS ticker enabled. This saturates the CPU, so I'm measuring the -improvement using the debug window's FPS figure. This patch improves this from -~50.8 FPS to ~52.6 FPS. ---- - xbmc/utils/MathUtils.h | 129 +++++++++++++++++++++++-------------------------- - 1 file changed, 61 insertions(+), 68 deletions(-) - -diff --git a/xbmc/utils/MathUtils.h b/xbmc/utils/MathUtils.h -index 96af9f4..0dae77d 100644 ---- a/xbmc/utils/MathUtils.h -+++ b/xbmc/utils/MathUtils.h -@@ -34,17 +34,13 @@ - - #if defined(__ppc__) || \ - defined(__powerpc__) || \ -- (defined(TARGET_DARWIN_IOS) && defined(__llvm__)) || \ -- (defined(TARGET_ANDROID) && defined(__arm__)) || \ -- defined(TARGET_RASPBERRY_PI) -+ defined(__arm__) - #define DISABLE_MATHUTILS_ASM_ROUND_INT - #endif - - #if defined(__ppc__) || \ - defined(__powerpc__) || \ -- (defined(TARGET_DARWIN) && defined(__llvm__)) || \ -- (defined(TARGET_ANDROID) && defined(__arm__)) || \ -- defined(TARGET_RASPBERRY_PI) -+ defined(__arm__) - #define DISABLE_MATHUTILS_ASM_TRUNCATE_INT - #endif - -@@ -73,60 +69,63 @@ namespace MathUtils - { - assert(x > static_cast(INT_MIN / 2) - 1.0); - assert(x < static_cast(INT_MAX / 2) + 1.0); -- const float round_to_nearest = 0.5f; -- int i; - - #if defined(DISABLE_MATHUTILS_ASM_ROUND_INT) -- i = floor(x + round_to_nearest); -- --#elif defined(__arm__) -- // From 'ARM-v7-M Architecture Reference Manual' page A7-569: -- // "The floating-point to integer operation (vcvt) [normally] uses the Round towards Zero rounding mode" -- // Because of this...we must use some less-than-straightforward logic to perform this operation without -- // changing the rounding mode flags -- -- /* The assembly below implements the following logic: -- if (x < 0) -- inc = -0.5f -- else -- inc = 0.5f -- int_val = trunc(x+inc); -- err = x - int_val; -- if (err == 0.5f) -- int_val++; -- return int_val; -- */ -+ /* This implementation warrants some further explanation. -+ * -+ * First, a couple of notes on rounding: -+ * 1) C casts from float/double to integer round towards zero. -+ * 2) Float/double additions are rounded according to the normal rules, -+ * in other words: on some architectures, it's fixed at compile-time, -+ * and on others it can be set using fesetround()). The following -+ * analysis assumes round-to-nearest with ties rounding to even. This -+ * is a fairly sensible choice, and is the default with ARM VFP. -+ * -+ * What this function wants is round-to-nearest with ties rounding to -+ * +infinity. This isn't an IEEE rounding mode, even if we could guarantee -+ * that all architectures supported fesetround(), which they don't. Instead, -+ * this adds an offset of 2147483648.5 (= 0x80000000.8p0), then casts to -+ * an unsigned int (crucially, all possible inputs are now in a range where -+ * round to zero acts the same as round to -infinity) and then subtracts -+ * 0x80000000 in the integer domain. The 0.5 component of the offset -+ * converts what is effectively a round down into a round to nearest, with -+ * ties rounding up, as desired. -+ * -+ * There is a catch, that because there is a double rounding, there is a -+ * small region where the input falls just *below* a tie, where the addition -+ * of the offset causes a round *up* to an exact integer, due to the finite -+ * level of precision available in floating point. You need to be aware of -+ * this when calling this function, although at present it is not believed -+ * that XBMC ever attempts to round numbers in this window. -+ * -+ * It is worth proving the size of the affected window. Recall that double -+ * precision employs a mantissa of 52 bits. -+ * 1) For all inputs -0.5 <= x <= INT_MAX -+ * Once the offset is applied, the most significant binary digit in the -+ * floating-point representation is +2^31. -+ * At this magnitude, the smallest step representable in double precision -+ * is 2^31 / 2^52 = 0.000000476837158203125 -+ * So the size of the range which is rounded up due to the addition is -+ * half the size of this step, or 0.0000002384185791015625 -+ * -+ * 2) For all inputs INT_MIN/2 < x < -0.5 -+ * Once the offset is applied, the most significant binary digit in the -+ * floating-point representation is +2^30. -+ * At this magnitude, the smallest step representable in double precision -+ * is 2^30 / 2^52 = 0.0000002384185791015625 -+ * So the size of the range which is rounded up due to the addition is -+ * half the size of this step, or 0.00000011920928955078125 -+ * -+ * 3) For all inputs INT_MIN <= x <= INT_MIN/2 -+ * The representation once the offset is applied has equal or greater -+ * precision than the input, so the addition does not cause rounding. -+ */ -+ return ((unsigned int) (x + 0x80000000.8p0)) - 0x80000000; - -- __asm__ __volatile__ ( --#if defined(__ARM_PCS_VFP) -- "fconstd d1,#%G[rnd_val] \n\t" // Copy round_to_nearest into a working register (d1 = 0.5) - #else -- "vmov.F64 d1,%[rnd_val] \n\t" --#endif -- "fcmpezd %P[value] \n\t" // Check value against zero (value == 0?) -- "fmstat \n\t" // Copy the floating-point status flags into the general-purpose status flags -- "it mi \n\t" -- "vnegmi.F64 d1, d1 \n\t" // if N-flag is set, negate round_to_nearest (if (value < 0) d1 = -1 * d1) -- "vadd.F64 d1,%P[value],d1 \n\t" // Add round_to_nearest to value, store result in working register (d1 += value) -- "vcvt.S32.F64 s3,d1 \n\t" // Truncate(round towards zero) (s3 = (int)d1) -- "vmov %[result],s3 \n\t" // Store the integer result in a general-purpose register (result = s3) -- "vcvt.F64.S32 d1,s3 \n\t" // Convert back to floating-point (d1 = (double)s3) -- "vsub.F64 d1,%P[value],d1 \n\t" // Calculate the error (d1 = value - d1) --#if defined(__ARM_PCS_VFP) -- "fconstd d2,#%G[rnd_val] \n\t" // d2 = 0.5; --#else -- "vmov.F64 d2,%[rnd_val] \n\t" --#endif -- "fcmped d1, d2 \n\t" // (d1 == 0.5?) -- "fmstat \n\t" // Copy the floating-point status flags into the general-purpose status flags -- "it eq \n\t" -- "addeq %[result],#1 \n\t" // (if (d1 == d2) result++;) -- : [result] "=r"(i) // Outputs -- : [rnd_val] "Dv" (round_to_nearest), [value] "w"(x) // Inputs -- : "d1", "d2", "s3" // Clobbers -- ); -- --#elif defined(__SSE2__) -+ const float round_to_nearest = 0.5f; -+ int i; -+#if defined(__SSE2__) - const float round_dn_to_nearest = 0.4999999f; - i = (x > 0) ? _mm_cvttsd_si32(_mm_set_sd(x + round_to_nearest)) : _mm_cvttsd_si32(_mm_set_sd(x - round_dn_to_nearest)); - -@@ -150,8 +149,8 @@ namespace MathUtils - ); - - #endif -- - return i; -+#endif - } - - /*! \brief Truncate to nearest integer. -@@ -165,20 +164,13 @@ namespace MathUtils - { - assert(x > static_cast(INT_MIN / 2) - 1.0); - assert(x < static_cast(INT_MAX / 2) + 1.0); -- int i; - - #if defined(DISABLE_MATHUTILS_ASM_TRUNCATE_INT) -- return i = (int)x; -- --#elif defined(__arm__) -- __asm__ __volatile__ ( -- "vcvt.S32.F64 %[result],%P[value] \n\t" // Truncate(round towards zero) and store the result -- : [result] "=w"(i) // Outputs -- : [value] "w"(x) // Inputs -- ); -- return i; -+ return x; - --#elif defined(TARGET_WINDOWS) -+#else -+ int i; -+#if defined(TARGET_WINDOWS) - const float round_towards_m_i = -0.5f; - __asm - { -@@ -204,6 +196,7 @@ namespace MathUtils - if (x < 0) - i = -i; - return (i); -+#endif - } - - inline int64_t abs(int64_t a) --- -1.9.3 - - -From f856b99e0c2da186b79b2a348a6b9262a6c422e7 Mon Sep 17 00:00:00 2001 +From 44dddb64bcaeb1df88eb77042e6892136324b965 Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Wed, 11 Dec 2013 17:21:54 +0000 -Subject: [PATCH 06/83] Move the reference-counting of Begin and End calls from +Subject: [PATCH 05/89] Move the reference-counting of Begin and End calls from DX and GL source files into GUIFontTTF.cpp. --- @@ -1456,10 +1247,10 @@ index a0dacba..6736cf7 100644 1.9.3 -From ab163dd0b07739063096b1d63b9b249d60e90252 Mon Sep 17 00:00:00 2001 +From 0b5b995143d15dde129189ffc6c3a87694937423 Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Wed, 11 Dec 2013 18:47:54 +0000 -Subject: [PATCH 07/83] Convert CGUIFontTTFBase::m_vertex to be managed as a +Subject: [PATCH 06/89] Convert CGUIFontTTFBase::m_vertex to be managed as a std::vector. Also retired CGUIFontTTFBase::m_vertex_count and CGUIFontTTFBase::m_vertex_size because these can be derived from vector member functions. @@ -1641,10 +1432,10 @@ index 93b7ea6..a4e8571 100644 1.9.3 -From 98eeca8362b37dda75ab4bad4b4617797f4966cc Mon Sep 17 00:00:00 2001 +From be0a214744ed17c7bd7ad9470585b4ba4e6dc83e Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Mon, 16 Dec 2013 18:58:12 +0000 -Subject: [PATCH 08/83] CGUIFontTTFBase::RenderCharacter can now append to +Subject: [PATCH 07/89] CGUIFontTTFBase::RenderCharacter can now append to arbitrary vectors of vertices rather than only CGUIFontTTFBase::m_vertex --- @@ -1720,10 +1511,10 @@ index 35e3cf9..4a6a696 100644 1.9.3 -From 0d407650eb4dcf3b87559bfe3a1f3af454dc977c Mon Sep 17 00:00:00 2001 +From 5eb0e1ba472411d194f338703fd29957702920d9 Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Wed, 15 Jan 2014 17:18:38 +0000 -Subject: [PATCH 09/83] Add a cache of font glyph bounding box vertices. This +Subject: [PATCH 08/89] Add a cache of font glyph bounding box vertices. This is implemented as a template because ultimately we will key on different parameters and store values of different types, depending upon whether we have a GLES or non-GLES backend, and for GLES, whether or not the currently @@ -2383,10 +2174,10 @@ index f351c99..9036ba9 100644 1.9.3 -From 5e4242ab8a0c4f34b866502b1c86079ca3736db4 Mon Sep 17 00:00:00 2001 +From 85e826a5720ea95f9c2a72ecba648c7840caec67 Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Thu, 23 Jan 2014 22:24:17 +0000 -Subject: [PATCH 10/83] Lay the groundwork for hardware clipping. +Subject: [PATCH 09/89] Lay the groundwork for hardware clipping. For glScissor() to replace CGraphicContext::ClipRect, a necessary condition is that no shear or rotation is introduced between the coordinate systems @@ -2651,10 +2442,10 @@ index 98e398a..81ee49e 100644 1.9.3 -From 5899b464bdeed40bc33261ef164455b5cc441519 Mon Sep 17 00:00:00 2001 +From 914504c45b98fad938d0e4c39300914930a1f2ea Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Thu, 23 Jan 2014 16:42:22 +0000 -Subject: [PATCH 11/83] Increase font cache hit rate by keying on the +Subject: [PATCH 10/89] Increase font cache hit rate by keying on the fractional part of m_originX and m_originY *after* they have been through the graphics context's transformation matrix, plus the scale/rotation elements of the matrix, rather than the origin in the original frame of reference plus @@ -2858,10 +2649,10 @@ index 7cb4669..78445ab 100644 1.9.3 -From 43765dfc3fa30499a8d6c388a28c2c90e923a3fc Mon Sep 17 00:00:00 2001 +From e14a42ba0c137bda31d4ac51b4e29dc60fcc9a30 Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Wed, 8 Jan 2014 12:16:33 +0000 -Subject: [PATCH 12/83] Rewrite of scrolling text code. +Subject: [PATCH 11/89] Rewrite of scrolling text code. No longer shuffles the string round to minimise the number of characters before the clipping rectangle; this doesn't save much on rendering time but @@ -3180,10 +2971,10 @@ index 2c6f366..b74faf2 100644 1.9.3 -From c6f7cf0791ff7eeaa0d1b2eb0ada543512a74ce0 Mon Sep 17 00:00:00 2001 +From 6275fb573c9bfed479dabdfc3ccabddf063f6ea7 Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Mon, 27 Jan 2014 23:21:10 +0000 -Subject: [PATCH 13/83] Move the application of the translation offsets into +Subject: [PATCH 12/89] Move the application of the translation offsets into the GLES code. Still all pure software at this stage. Main change is in the data types at the interface between CGUIFontTTFBase and CGUIFontTTFGL. The old way (array of vertices in m_vertex) are retained in addition, for the @@ -3379,10 +3170,10 @@ index cb56987..f6aa081 100644 1.9.3 -From a011b1e8821ca48897058bada140e663085e7d1e Mon Sep 17 00:00:00 2001 +From f16154e4a9130f1b0c4d79e4df090f8c24f8f5b4 Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Wed, 15 Jan 2014 15:28:06 +0000 -Subject: [PATCH 14/83] Rather than applying the translation offsets to the +Subject: [PATCH 13/89] Rather than applying the translation offsets to the vertices, now applies them to the model view matrix from the top of the matrix stack and pushes it over to OpenGL. The vertices themselves are still all held client-side. @@ -3529,10 +3320,10 @@ index 81ee49e..d2f9cd1 100644 1.9.3 -From 1e15bddd4df1bd6fda866e1b4b885e232e08ec71 Mon Sep 17 00:00:00 2001 +From 7b4b56c7bce76682ee4eee01336247b7df6527f1 Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Wed, 29 Jan 2014 13:21:19 +0000 -Subject: [PATCH 15/83] Enable hardware clipping. +Subject: [PATCH 14/89] Enable hardware clipping. --- xbmc/guilib/GUIFontTTF.cpp | 4 ++-- @@ -3608,10 +3399,10 @@ index fbffaa0..b7618e1 100644 1.9.3 -From b9c662e2a9d0253b6636b509d35110b2952662a6 Mon Sep 17 00:00:00 2001 +From ae887f8ccf7998b3dfe89dd913382c5306fa6372 Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Wed, 15 Jan 2014 15:32:51 +0000 -Subject: [PATCH 16/83] Move the vertex data across to a vertex buffer object +Subject: [PATCH 15/89] Move the vertex data across to a vertex buffer object just prior to drawing. --- @@ -3665,10 +3456,10 @@ index b7618e1..0df3749 100644 1.9.3 -From 1b6fcf9424aabc726870fffd0dada2d2f4327ad8 Mon Sep 17 00:00:00 2001 +From d5e155d952f161802b2aab970e42fc2cf3ebadd4 Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Wed, 15 Jan 2014 16:04:04 +0000 -Subject: [PATCH 17/83] Move vertex data into an OpenGL VBO when the font cache +Subject: [PATCH 16/89] Move vertex data into an OpenGL VBO when the font cache entry is populated. The font cache now stores the "name" (handle) of the VBO, rather than a vector of vertices. @@ -3943,10 +3734,10 @@ index 6736cf7..168fb21 100644 1.9.3 -From 92331e5e7174c1aeaeead138c2793ef55ec2cfe4 Mon Sep 17 00:00:00 2001 +From dfbd136df43019c4fbb3b8a10bdc248be9bc6bc9 Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Thu, 16 Jan 2014 16:29:42 +0000 -Subject: [PATCH 18/83] Switch from glDrawArrays() to glDrawElements(). This +Subject: [PATCH 17/89] Switch from glDrawArrays() to glDrawElements(). This involves setting up a static VBO containing the indexes necessary to convert from quads to triangles on the fly in the GPU. @@ -4169,10 +3960,10 @@ index 6de3532..258a293 100644 1.9.3 -From 9aced5f8c6aeb6ed0faf5251a983ebe5cf7adcab Mon Sep 17 00:00:00 2001 +From c9a92c083400a821fb55c671df27e9131df782d9 Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Tue, 4 Feb 2014 16:17:57 +0000 -Subject: [PATCH 19/83] Update Windows project files +Subject: [PATCH 18/89] Update Windows project files --- project/VS2010Express/XBMC.vcxproj | 2 ++ @@ -4180,7 +3971,7 @@ Subject: [PATCH 19/83] Update Windows project files 2 files changed, 8 insertions(+) diff --git a/project/VS2010Express/XBMC.vcxproj b/project/VS2010Express/XBMC.vcxproj -index 055722f..fffbf54 100644 +index b749bd8..e752bb8 100644 --- a/project/VS2010Express/XBMC.vcxproj +++ b/project/VS2010Express/XBMC.vcxproj @@ -425,6 +425,7 @@ @@ -4191,7 +3982,7 @@ index 055722f..fffbf54 100644 -@@ -1743,6 +1744,7 @@ +@@ -1741,6 +1742,7 @@ @@ -4200,10 +3991,10 @@ index 055722f..fffbf54 100644 diff --git a/project/VS2010Express/XBMC.vcxproj.filters b/project/VS2010Express/XBMC.vcxproj.filters -index 2d2c5dc..68965cd 100644 +index 29f0879..e5a18dd 100644 --- a/project/VS2010Express/XBMC.vcxproj.filters +++ b/project/VS2010Express/XBMC.vcxproj.filters -@@ -1009,6 +1009,9 @@ +@@ -1006,6 +1006,9 @@ guilib @@ -4213,7 +4004,7 @@ index 2d2c5dc..68965cd 100644 guilib -@@ -3927,6 +3930,9 @@ +@@ -3918,6 +3921,9 @@ guilib @@ -4227,17 +4018,17 @@ index 2d2c5dc..68965cd 100644 1.9.3 -From 82db4d070392a1bae49bbd0888e4c92de0754e70 Mon Sep 17 00:00:00 2001 +From 8f7b12fcd5178dd1aa35f07ff79c82140b3f1815 Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Tue, 4 Feb 2014 16:49:45 +0000 -Subject: [PATCH 20/83] Update XCode project file +Subject: [PATCH 19/89] Update XCode project file --- XBMC.xcodeproj/project.pbxproj | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/XBMC.xcodeproj/project.pbxproj b/XBMC.xcodeproj/project.pbxproj -index eedbd8a..0d06e80 100644 +index 6adc55d..ebe3151 100644 --- a/XBMC.xcodeproj/project.pbxproj +++ b/XBMC.xcodeproj/project.pbxproj @@ -168,6 +168,9 @@ @@ -4250,7 +4041,7 @@ index eedbd8a..0d06e80 100644 32C631281423A90F00F18420 /* JpegIO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 32C631261423A90F00F18420 /* JpegIO.cpp */; }; 36A9443D15821E2800727135 /* DatabaseUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36A9443B15821E2800727135 /* DatabaseUtils.cpp */; }; 36A9444115821E7C00727135 /* SortUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36A9443F15821E7C00727135 /* SortUtils.cpp */; }; -@@ -4022,6 +4025,8 @@ +@@ -4016,6 +4019,8 @@ 1DAFDB7B16DFDCA7007F8C68 /* PeripheralBusCEC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PeripheralBusCEC.h; sourceTree = ""; }; 1DE0443315828F4B005DDB4D /* Exception.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Exception.cpp; path = commons/Exception.cpp; sourceTree = ""; }; 1DE0443415828F4B005DDB4D /* Exception.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Exception.h; path = commons/Exception.h; sourceTree = ""; }; @@ -4259,7 +4050,7 @@ index eedbd8a..0d06e80 100644 32C631261423A90F00F18420 /* JpegIO.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JpegIO.cpp; sourceTree = ""; }; 32C631271423A90F00F18420 /* JpegIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JpegIO.h; sourceTree = ""; }; 36A9443B15821E2800727135 /* DatabaseUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DatabaseUtils.cpp; sourceTree = ""; }; -@@ -6536,6 +6541,8 @@ +@@ -6526,6 +6531,8 @@ 18B7C76A1294222E009E7A26 /* GUIFixedListContainer.cpp */, 18B7C7101294222D009E7A26 /* GUIFixedListContainer.h */, 18B7C76B1294222E009E7A26 /* GUIFont.cpp */, @@ -4268,26 +4059,26 @@ index eedbd8a..0d06e80 100644 18B7C7111294222D009E7A26 /* GUIFont.h */, 18B7C76C1294222E009E7A26 /* GUIFontManager.cpp */, 18B7C7121294222D009E7A26 /* GUIFontManager.h */, -@@ -11854,6 +11861,7 @@ - 7CCDACB019275D1F0074CF51 /* NptStdcEnvironment.cpp in Sources */, +@@ -11846,6 +11853,7 @@ 7CCDACC119275D790074CF51 /* NptAppleAutoreleasePool.mm in Sources */, 7CCDACCA19275D790074CF51 /* NptAppleLogConfig.mm in Sources */, + 7CAA469019427AED00008885 /* PosixDirectory.cpp in Sources */, + 2FD7EC5F18A14FE50047F86C /* GUIFontCache.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; -@@ -13049,6 +13057,7 @@ - 7CCDACB219275D1F0074CF51 /* NptStdcEnvironment.cpp in Sources */, +@@ -13039,6 +13047,7 @@ 7CCDACC319275D790074CF51 /* NptAppleAutoreleasePool.mm in Sources */, 7CCDACCC19275D790074CF51 /* NptAppleLogConfig.mm in Sources */, + 7CAA469219427AED00008885 /* PosixDirectory.cpp in Sources */, + 2FD7EC6118A14FE50047F86C /* GUIFontCache.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; -@@ -14246,6 +14255,7 @@ - 7CCDACB119275D1F0074CF51 /* NptStdcEnvironment.cpp in Sources */, +@@ -14234,6 +14243,7 @@ 7CCDACC219275D790074CF51 /* NptAppleAutoreleasePool.mm in Sources */, 7CCDACCB19275D790074CF51 /* NptAppleLogConfig.mm in Sources */, + 7CAA469119427AED00008885 /* PosixDirectory.cpp in Sources */, + 2FD7EC6018A14FE50047F86C /* GUIFontCache.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -4296,10 +4087,10 @@ index eedbd8a..0d06e80 100644 1.9.3 -From 8347e694684e9d9c1f0e9b22db637a8d861e1f82 Mon Sep 17 00:00:00 2001 +From 3d9b25b781d99d3baaed901c46000377a2b66493 Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Tue, 4 Feb 2014 17:44:34 +0000 -Subject: [PATCH 21/83] Clang seems to be more picky than gcc about some C++ +Subject: [PATCH 20/89] Clang seems to be more picky than gcc about some C++ template syntax --- @@ -4367,10 +4158,10 @@ index 895fa72..bd84b9a 100644 1.9.3 -From 5fe6f1890560652a1c45818dcee077fc2f98d9de Mon Sep 17 00:00:00 2001 +From f8c6566791e144dbad09778a8923dd27b7fe4790 Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Tue, 4 Feb 2014 18:52:14 +0000 -Subject: [PATCH 22/83] Fix header to hopefully permit iOS builds to work +Subject: [PATCH 21/89] Fix header to hopefully permit iOS builds to work again. GUIShader.cpp added #include windowing/egl/WinSystemEGL.h inside a but also need the header windowing/osx/WinSystemIOS.h instead. The only thing GUIShader.cpp needed was g_windowing.GetViewPort, which is provided by the @@ -4399,10 +4190,10 @@ index 53bce09..86330cc 100644 1.9.3 -From d9b756de272d283f89b34ed571d2638e98f5e455 Mon Sep 17 00:00:00 2001 +From 242f5e7c687e477f459447a2ced5a92d11d014ce Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Tue, 8 Apr 2014 18:14:55 +0100 -Subject: [PATCH 23/83] Fix font display in stereoscopic modes +Subject: [PATCH 22/89] Fix font display in stereoscopic modes CGUIFontTTFGL::LastEnd was previously using the relatively high-level CGraphicContext::SetScissors function to enforce hardware clipping. However, the coordinates it passed in already contained the stereoscopic offset, so @@ -4443,10 +4234,10 @@ index d476409..8466a81 100644 1.9.3 -From 802f19c0964cac22f67e70b311893b24cf836dad Mon Sep 17 00:00:00 2001 +From 9d115ff708d8b89c5120d0fc3497f407bf586baf Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 10 Jan 2014 12:10:43 +0000 -Subject: [PATCH 24/83] [rbp] Don't override dvdplayer with omxplayer. +Subject: [PATCH 23/89] [rbp] Don't override dvdplayer with omxplayer. Using dvdplayer can be useful on the Pi. We can actually play sd (up to 640x480 MPEG-4 video) video in real time. This is useful for codec variants like DivX3 which we don't currently play. @@ -4479,10 +4270,10 @@ index 27f0bec..fc12bb7 100644 1.9.3 -From b43b2aa700bb684f03c663f50a0f46c868d88696 Mon Sep 17 00:00:00 2001 +From ee0966bd1c125c8cedd651432b2c0765d854ee5f Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 10 Jan 2014 15:37:41 +0000 -Subject: [PATCH 25/83] [players] Use default players rather than hard coded +Subject: [PATCH 24/89] [players] Use default players rather than hard coded DVDPlayer/PAPlayer --- @@ -4541,10 +4332,10 @@ index 57dfcdd..7be9799 100644 1.9.3 -From 9a33b74039f15cedcfe66f99c5ec53356bb1dccb Mon Sep 17 00:00:00 2001 +From 774e8be6922f14e9b1c71b099d860b5bf6b7ac67 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sat, 11 Jan 2014 18:23:42 +0000 -Subject: [PATCH 26/83] [rbp] Don't force dvdplayer for airplay +Subject: [PATCH 25/89] [rbp] Don't force dvdplayer for airplay --- xbmc/network/AirPlayServer.cpp | 2 ++ @@ -4570,10 +4361,10 @@ index 472463d..9f86eb7 100644 1.9.3 -From 1393df3a9e7faf5aa7fbcb3af4d031bd06135f2f Mon Sep 17 00:00:00 2001 +From 273f624c4273386c60d97cb331ab3941b59cecc7 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 13 Jan 2014 13:11:06 +0000 -Subject: [PATCH 27/83] [rbp] Give plugins omxplayer when they request +Subject: [PATCH 26/89] [rbp] Give plugins omxplayer when they request dvdplayer on pi --- @@ -4600,10 +4391,10 @@ index cf6693c..1170189 100644 1.9.3 -From 0a754a6a41a3ee70ef8f750c4856dfb3b88ceb73 Mon Sep 17 00:00:00 2001 +From 01eb0f52e23f5786f018e91690e495a56e784e0e Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 14 Jan 2014 18:04:07 +0000 -Subject: [PATCH 28/83] [rbp] Allow ALSA to be chosen in addition to Pi sink +Subject: [PATCH 27/89] [rbp] Allow ALSA to be chosen in addition to Pi sink Needs --enable-alsa in ./configure step and alsa support on platform --- @@ -4694,10 +4485,10 @@ index e42d973..715b4f1 100644 1.9.3 -From e42fe4dfb5a88a449336aeae4169e277e24d8993 Mon Sep 17 00:00:00 2001 +From 385d77e9e30bec3ec6ac9d9f0faa0e5e2c38f491 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Thu, 16 Jan 2014 01:39:29 +0000 -Subject: [PATCH 29/83] [omxcodec] Add hardware decode to dvdplayer for Pi +Subject: [PATCH 28/89] [omxcodec] Add hardware decode to dvdplayer for Pi Hijack the abandoned OpenMaxVideo codec --- @@ -4838,10 +4629,10 @@ index 6832721..3503988 100644 #ifdef TARGET_DARWIN else if(pic.format == RENDER_FMT_CVBREF) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp b/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp -index 402093d..b61f616 100644 +index f77ac40..5d37395 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp -@@ -269,9 +269,12 @@ CDVDVideoCodec* CDVDFactoryCodec::CreateVideoCodec(CDVDStreamInfo &hint, unsigne +@@ -268,9 +268,12 @@ CDVDVideoCodec* CDVDFactoryCodec::CreateVideoCodec(CDVDStreamInfo &hint, unsigne #endif #if defined(HAVE_LIBOPENMAX) @@ -7578,10 +7369,10 @@ index e06c41d..9079c13 100644 // defined(HAVE_LIBOPENMAX) diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index 8aaef28..744e734 100644 +index 4093974..0634880 100644 --- a/xbmc/cores/dvdplayer/DVDPlayer.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -2979,7 +2979,9 @@ bool CDVDPlayer::OpenVideoStream(int iStream, int source, bool reset) +@@ -2981,7 +2981,9 @@ bool CDVDPlayer::OpenVideoStream(CDVDStreamInfo& hint, bool reset) hint.aspect = aspect; hint.forced_aspect = true; } @@ -7590,12 +7381,12 @@ index 8aaef28..744e734 100644 +#endif } - boost::shared_ptr client; + CDVDInputStream::IMenus* pMenus = dynamic_cast(m_pInputStream); diff --git a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -index 7e88bfc..8649a33 100644 +index 633e333..c6350cd 100644 --- a/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayerVideo.cpp -@@ -322,6 +322,9 @@ void CDVDPlayerVideo::Process() +@@ -324,6 +324,9 @@ void CDVDPlayerVideo::Process() while (!m_bStop) { @@ -7605,7 +7396,7 @@ index 7e88bfc..8649a33 100644 int iQueueTimeOut = (int)(m_stalled ? frametime / 4 : frametime * 10) / 1000; int iPriority = (m_speed == DVD_PLAYSPEED_PAUSE && m_started) ? 1 : 0; -@@ -358,8 +361,10 @@ void CDVDPlayerVideo::Process() +@@ -360,8 +363,10 @@ void CDVDPlayerVideo::Process() OutputPicture(&picture, pts); pts+= frametime; } @@ -7618,7 +7409,7 @@ index 7e88bfc..8649a33 100644 } if (pMsg->IsType(CDVDMsg::GENERAL_SYNCHRONIZE)) -@@ -488,9 +493,12 @@ void CDVDPlayerVideo::Process() +@@ -490,9 +495,12 @@ void CDVDPlayerVideo::Process() if (pMsg->IsType(CDVDMsg::DEMUXER_PACKET)) { @@ -7634,7 +7425,7 @@ index 7e88bfc..8649a33 100644 if (m_stalled) { CLog::Log(LOGINFO, "CDVDPlayerVideo - Stillframe left, switching to normal playback"); -@@ -748,7 +756,8 @@ void CDVDPlayerVideo::Process() +@@ -750,7 +758,8 @@ void CDVDPlayerVideo::Process() } // all data is used by the decoder, we can safely free it now @@ -7753,20 +7544,20 @@ index 1b24fc1..2f1e8a9 100644 1.9.3 -From 36a6a4472ca92275c98dd382f5696f82de6ea505 Mon Sep 17 00:00:00 2001 +From 2ace9db574edaae579b71580e3d6a0dcb0f5d058 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 20 Jan 2014 16:03:40 +0000 -Subject: [PATCH 30/83] [omxcodec] Enable for dvd menus +Subject: [PATCH 29/89] [omxcodec] Enable for dvd menus --- xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp b/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp -index b61f616..526581a 100644 +index 5d37395..6d1810f 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp -@@ -193,6 +193,10 @@ CDVDVideoCodec* CDVDFactoryCodec::CreateVideoCodec(CDVDStreamInfo &hint, unsigne +@@ -192,6 +192,10 @@ CDVDVideoCodec* CDVDFactoryCodec::CreateVideoCodec(CDVDStreamInfo &hint, unsigne CLog::Log(LOGDEBUG, "CDVDFactoryCodec: compiled in hardware support: %s", hwSupport.c_str()); @@ -7781,10 +7572,10 @@ index b61f616..526581a 100644 1.9.3 -From 590614518f6a5cc10017f7b01f5facd006c669d3 Mon Sep 17 00:00:00 2001 +From d05daad4ed96c082c133d10db053afd33b2f9ae5 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 3 Feb 2014 22:27:44 +0000 -Subject: [PATCH 31/83] [omxcodec] Add omx specific texture +Subject: [PATCH 30/89] [omxcodec] Add omx specific texture create/upload/delete functions --- @@ -7862,10 +7653,10 @@ index 5a6a2be..52df291 100644 1.9.3 -From 3df31e476a168116bf6d58d75e676c34418f89af Mon Sep 17 00:00:00 2001 +From 2f66c8f61d8333410f24e5dfc23979449421b08a Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 3 Feb 2014 22:50:43 +0000 -Subject: [PATCH 32/83] [omxcodec] Add shared pointer to delay shutdown of +Subject: [PATCH 31/89] [omxcodec] Add shared pointer to delay shutdown of codec until buffers are returned --- @@ -8046,10 +7837,10 @@ index 9079c13..0975e8a 100644 1.9.3 -From c3ade5c15d8d856914d216a3332409d0bd409d41 Mon Sep 17 00:00:00 2001 +From f23a886b16e05bda02bcf84ee2781f94ee8a1863 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 3 Feb 2014 23:11:31 +0000 -Subject: [PATCH 33/83] [omxcodec] Fix for aspect ratio in non-square pixel +Subject: [PATCH 32/89] [omxcodec] Fix for aspect ratio in non-square pixel modes --- @@ -8138,10 +7929,10 @@ index 0975e8a..9138a20 100644 1.9.3 -From 6e542b9f419797e507a44bc4506d9b790f8d7793 Mon Sep 17 00:00:00 2001 +From 4543da5f385f8499db762274dc874800db260feb Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 3 Feb 2014 23:19:22 +0000 -Subject: [PATCH 34/83] [omxcodec] Report error when codec not enabled +Subject: [PATCH 33/89] [omxcodec] Report error when codec not enabled --- xbmc/cores/dvdplayer/DVDCodecs/Video/OpenMaxVideo.cpp | 10 +++++++++- @@ -8186,10 +7977,10 @@ index 7e23c87..2ae722b 100644 1.9.3 -From 393f56e01f1930f5f56df46fbac757b6194f340f Mon Sep 17 00:00:00 2001 +From 6e1cf9bcbef26c84fed29d3af9689c0fac451135 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 4 Feb 2014 17:29:37 +0000 -Subject: [PATCH 35/83] [omxcodec] Add deinterlace support +Subject: [PATCH 34/89] [omxcodec] Add deinterlace support --- xbmc/cores/VideoRenderers/LinuxRendererGLES.cpp | 2 +- @@ -8426,10 +8217,10 @@ index 9138a20..c8ad4d8 100644 1.9.3 -From 5fb48625e00a18916a2bc169c3c025bae568575f Mon Sep 17 00:00:00 2001 +From 936dec05449679608c6a806e20d5d3cf416ba6fe Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 5 Feb 2014 11:46:33 +0000 -Subject: [PATCH 36/83] [rbp/settings] Allow av sync type to be enabled +Subject: [PATCH 35/89] [rbp/settings] Allow av sync type to be enabled It works for dvdplayer --- @@ -8458,10 +8249,10 @@ index 2b7d0a6..1429256 100644 1.9.3 -From f3927eb3cdfeded159688825e923ea27942dcc9f Mon Sep 17 00:00:00 2001 +From 9b8cf8c70d383412ca234e995726aae28b212574 Mon Sep 17 00:00:00 2001 From: Ben Avison Date: Thu, 1 May 2014 16:28:39 +0100 -Subject: [PATCH 37/83] Improved file buffering in CArchive +Subject: [PATCH 36/89] Improved file buffering in CArchive Even though memcpy is typically inlined by the compiler into byte/word loads and stores (at least for release builds), the frequency with which 1, 2 and 4 @@ -8524,10 +8315,10 @@ index 1618237..d525761 100644 1.9.3 -From a25da3b42496495d104ea9feff59f25ed163b1f0 Mon Sep 17 00:00:00 2001 +From efea9ae500766010b4222b74b0b21909a3f8127c Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sun, 16 Feb 2014 17:38:05 +0000 -Subject: [PATCH 38/83] [omxcodec] Only do essential calls in texture thread +Subject: [PATCH 37/89] [omxcodec] Only do essential calls in texture thread [omxcodec] Fix for files with no valid pts values. [omxcodec] Fix stall on seek/trickplay - need to reset start flag [omxcodec] Make sure we have a valid context when video decode starts before first fanart is decoded @@ -8877,10 +8668,10 @@ index c8ad4d8..f234f6d 100644 1.9.3 -From 761793f70b945ead4ddc0ed54a0ab4363bec18ac Mon Sep 17 00:00:00 2001 +From b6b5f87e54f881882b14f668ff537fcb62623984 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sat, 8 Mar 2014 15:36:06 +0000 -Subject: [PATCH 39/83] [hifiberry] Hack: force it to be recognised as IEC958 +Subject: [PATCH 38/89] [hifiberry] Hack: force it to be recognised as IEC958 capable to enable passthrough options --- @@ -8906,20 +8697,20 @@ index 8cbf6e5..a8ad933 100644 1.9.3 -From eb6d30486a1f2978c043b88efff0d4254f96fde0 Mon Sep 17 00:00:00 2001 +From 6535d554289aa713ead572420de2798c35fffeab Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 11 Mar 2014 18:50:23 +0000 -Subject: [PATCH 40/83] [dvdplayer] Use inexact seeking like omxplayer +Subject: [PATCH 39/89] [dvdplayer] Use inexact seeking like omxplayer --- xbmc/cores/dvdplayer/DVDPlayer.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/xbmc/cores/dvdplayer/DVDPlayer.cpp b/xbmc/cores/dvdplayer/DVDPlayer.cpp -index 744e734..8e6e498 100644 +index 0634880..768f51f 100644 --- a/xbmc/cores/dvdplayer/DVDPlayer.cpp +++ b/xbmc/cores/dvdplayer/DVDPlayer.cpp -@@ -1937,7 +1937,11 @@ void CDVDPlayer::CheckAutoSceneSkip() +@@ -1898,7 +1898,11 @@ void CDVDPlayer::CheckAutoSceneSkip() /* * Seeking is NOT flushed so any content up to the demux point is retained when playing forwards. */ @@ -8931,7 +8722,7 @@ index 744e734..8e6e498 100644 /* * Seek doesn't always work reliably. Last physical seek time is recorded to prevent looping * if there was an error with seeking and it landed somewhere unexpected, perhaps back in the -@@ -1955,7 +1959,11 @@ void CDVDPlayer::CheckAutoSceneSkip() +@@ -1916,7 +1920,11 @@ void CDVDPlayer::CheckAutoSceneSkip() /* * Seeking is NOT flushed so any content up to the demux point is retained when playing forwards. */ @@ -8943,7 +8734,7 @@ index 744e734..8e6e498 100644 /* * Each commercial break is only skipped once so poorly detected commercial breaks can be * manually re-entered. Start and end are recorded to prevent looping and to allow seeking back -@@ -3314,9 +3322,12 @@ void CDVDPlayer::UpdateClockMaster() +@@ -3119,9 +3127,12 @@ void CDVDPlayer::UpdateClockMaster() void CDVDPlayer::FlushBuffers(bool queued, double pts, bool accurate) { double startpts; @@ -8960,879 +8751,10 @@ index 744e734..8e6e498 100644 1.9.3 -From 0501c220d79363c66b3d98ca32dea47d60d4db9d Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 13 Mar 2014 16:08:46 +0000 -Subject: [PATCH 41/83] [omxplayer] Make use of TrueHD fastpath when downmixing - -The TrueHD codec actually works in 3 stages. It decodes the downmixed stereo. It then decodes the differences required to produce 5.1. -It then decodes the differences required to produce 7.1. - -Many users end up downmixing this 7.1 stream back to 2.0. -Much better to tell the codec we only need the 2.0 stream. It saves about 50% of the CPU required ---- - xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp b/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp -index cd4d133..94acfaa 100644 ---- a/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp -+++ b/xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp -@@ -25,6 +25,8 @@ - #include "utils/log.h" - - #include "cores/AudioEngine/Utils/AEUtil.h" -+#include "settings/Settings.h" -+#include "PCMRemap.h" - - // the size of the audio_render output port buffers - #define AUDIO_DECODE_OUTPUT_BUFFER (32*1024) -@@ -86,6 +88,16 @@ bool COMXAudioCodecOMX::Open(CDVDStreamInfo &hints) - m_pCodecContext->block_align = hints.blockalign; - m_pCodecContext->bit_rate = hints.bitrate; - m_pCodecContext->bits_per_coded_sample = hints.bitspersample; -+ enum PCMLayout layout = (enum PCMLayout)std::max(0, CSettings::Get().GetInt("audiooutput.channels")-1); -+ if (hints.codec == AV_CODEC_ID_TRUEHD) -+ { -+ if (layout == PCM_LAYOUT_2_0) -+ m_pCodecContext->request_channel_layout = AV_CH_LAYOUT_STEREO; -+ else if (layout <= PCM_LAYOUT_5_1) -+ m_pCodecContext->request_channel_layout = AV_CH_LAYOUT_5POINT1; -+ } -+ if (m_pCodecContext->request_channel_layout) -+ CLog::Log(LOGNOTICE,"COMXAudioCodecOMX::Open() Requesting channel layout of %d", (unsigned)m_pCodecContext->request_channel_layout); - - // vorbis has variable sized planar output, so skip concatenation - if (hints.codec == AV_CODEC_ID_VORBIS) --- -1.9.3 - - -From 043f20ef539650c6641f7c69af3c130c11f606a5 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 30 Dec 2013 12:02:14 +0000 -Subject: [PATCH 42/83] [rbp] Hardware accelerated resampling - -This replaces the format conversion, up/down mixing and resampling code from ActiveAE with a GPU accelerated version. -Should significantly reduce CPU when using paplayer or dvdplayer. - -Requires updated firmware ---- - .../Engines/ActiveAE/ActiveAEResample.cpp | 5 + - .../Engines/ActiveAE/ActiveAEResample.h | 8 + - .../Engines/ActiveAE/ActiveAEResamplePi.cpp | 593 +++++++++++++++++++++ - .../Engines/ActiveAE/ActiveAEResamplePi.h | 62 +++ - xbmc/cores/AudioEngine/Makefile.in | 1 + - xbmc/linux/OMXCore.cpp | 4 +- - 6 files changed, 671 insertions(+), 2 deletions(-) - create mode 100644 xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp - create mode 100644 xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.h - -diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.cpp -index 8250eef..972e1be 100644 ---- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.cpp -+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.cpp -@@ -18,6 +18,10 @@ - * - */ - -+#include "system.h" -+ -+#if !defined(TARGET_RASPBERRY_PI) -+ - #include "ActiveAEResample.h" - #include "utils/log.h" - -@@ -359,3 +363,4 @@ int CActiveAEResample::GetAVChannelIndex(enum AEChannel aechannel, uint64_t layo - { - return av_get_channel_layout_channel_index(layout, GetAVChannel(aechannel)); - } -+#endif -diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.h b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.h -index a471e02..5d37cc7 100644 ---- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.h -+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.h -@@ -19,6 +19,8 @@ - * - */ - -+#include "system.h" -+ - #include "cores/AudioEngine/Utils/AEChannelInfo.h" - #include "cores/AudioEngine/Utils/AEAudioFormat.h" - #include "cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.h" -@@ -29,6 +31,10 @@ extern "C" { - #include "libswresample/swresample.h" - } - -+#if defined(TARGET_RASPBERRY_PI) -+#include "ActiveAEResamplePi.h" -+#else -+ - namespace ActiveAE - { - -@@ -63,3 +69,5 @@ class CActiveAEResample - }; - - } -+ -+#endif -diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp -new file mode 100644 -index 0000000..ae72dbd ---- /dev/null -+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp -@@ -0,0 +1,593 @@ -+/* -+ * Copyright (C) 2010-2013 Team XBMC -+ * http://xbmc.org -+ * -+ * This Program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2, or (at your option) -+ * any later version. -+ * -+ * This Program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with XBMC; see the file COPYING. If not, see -+ * . -+ * -+ */ -+ -+#include "system.h" -+ -+#if defined(TARGET_RASPBERRY_PI) -+ -+#include "ActiveAEResample.h" -+#include "linux/RBP.h" -+#include "cores/omxplayer/PCMRemap.h" -+#include "settings/Settings.h" -+#include "utils/log.h" -+ -+extern "C" { -+#include "libavutil/channel_layout.h" -+#include "libavutil/opt.h" -+#include "libswresample/swresample.h" -+} -+ -+//#define DEBUG_VERBOSE -+ -+#define CLASSNAME "CActiveAEResamplePi" -+ -+#define BUFFERSIZE (32*1024*2*8) -+ -+//#define BENCHMARKING -+#ifdef BENCHMARKING -+#define LOGTIMEINIT(f) \ -+ struct timespec now; \ -+ uint64_t Start, End; \ -+ clock_gettime(CLOCK_MONOTONIC, &now); \ -+ Start = ((int64_t)now.tv_sec * 1000000000L) + now.tv_nsec; \ -+ const char *_filename = f; -+ -+#define LOGTIME(n) \ -+ clock_gettime(CLOCK_MONOTONIC, &now); \ -+ End = ((int64_t)now.tv_sec * 1000000000L) + now.tv_nsec; \ -+ CLog::Log(LOGNOTICE, "ActiveAE::%s %d - resample %s took %.0fms", __FUNCTION__, n, _filename, (End-Start)*1e-6); \ -+ Start=End; -+#else -+#define LOGTIMEINIT(f) -+#define LOGTIME(n) -+#endif -+ -+using namespace ActiveAE; -+ -+CActiveAEResample::CActiveAEResample() -+{ -+ CLog::Log(LOGINFO, "%s::%s", CLASSNAME, __func__); -+ -+ m_Initialized = false; -+ m_last_src_fmt = AV_SAMPLE_FMT_NONE; -+ m_last_dst_fmt = AV_SAMPLE_FMT_NONE; -+ m_last_src_channels = 0; -+ m_last_dst_channels = 0; -+} -+ -+CActiveAEResample::~CActiveAEResample() -+{ -+ CLog::Log(LOGINFO, "%s::%s", CLASSNAME, __func__); -+ DeInit(); -+} -+ -+void CActiveAEResample::DeInit() -+{ -+ CLog::Log(LOGDEBUG, "%s:%s", CLASSNAME, __func__); -+ if (m_Initialized) -+ { -+ m_omx_mixer.FlushAll(); -+ m_omx_mixer.Deinitialize(); -+ m_Initialized = false; -+ } -+} -+ -+bool CActiveAEResample::Init(uint64_t dst_chan_layout, int dst_channels, int dst_rate, AVSampleFormat dst_fmt, int dst_bits, int dst_dither, uint64_t src_chan_layout, int src_channels, int src_rate, AVSampleFormat src_fmt, int src_bits, int src_dither, bool upmix, bool normalize, CAEChannelInfo *remapLayout, AEQuality quality) -+{ -+ LOGTIMEINIT("x"); -+ -+ CLog::Log(LOGINFO, "%s::%s remap:%p chan:%d->%d rate:%d->%d format:%d->%d bits:%d->%d norm:%d upmix:%d", CLASSNAME, __func__, remapLayout, src_channels, dst_channels, src_rate, dst_rate, src_fmt, dst_fmt, src_bits, dst_bits, normalize, upmix); -+ -+ m_dst_chan_layout = dst_chan_layout; -+ m_dst_channels = dst_channels; -+ m_dst_rate = dst_rate; -+ m_dst_fmt = dst_fmt; -+ m_dst_bits = dst_bits ? dst_bits : 8; -+ m_src_chan_layout = src_chan_layout; -+ m_src_channels = src_channels; -+ m_src_rate = src_rate; -+ m_src_fmt = src_fmt; -+ m_src_bits = src_bits ? src_bits : 8; -+ -+ if (m_dst_chan_layout == 0) -+ m_dst_chan_layout = av_get_default_channel_layout(m_dst_channels); -+ if (m_src_chan_layout == 0) -+ m_src_chan_layout = av_get_default_channel_layout(m_src_channels); -+ -+ OMX_CONFIG_BRCMAUDIODOWNMIXCOEFFICIENTS8x8 mix; -+ OMX_INIT_STRUCTURE(mix); -+ -+ assert(sizeof(mix.coeff)/sizeof(mix.coeff[0]) == 64); -+ -+ LOGTIME(1); -+// this code is just uses ffmpeg to produce the 8x8 mixing matrix -+{ -+ // dummy sample rate and format, as we only care about channel mapping -+ SwrContext *m_pContext = swr_alloc_set_opts(NULL, m_dst_chan_layout, AV_SAMPLE_FMT_FLT, 48000, -+ m_src_chan_layout, AV_SAMPLE_FMT_FLT, 48000, 0, NULL); -+ if (!m_pContext) -+ { -+ CLog::Log(LOGERROR, "CActiveAEResample::Init - create context failed"); -+ return false; -+ } -+ // tell resampler to clamp float values -+ // not required for sink stage (remapLayout == true) -+ if (!remapLayout && normalize) -+ { -+ av_opt_set_double(m_pContext, "rematrix_maxval", 1.0, 0); -+ } -+ -+ if (remapLayout) -+ { -+ // one-to-one mapping of channels -+ // remapLayout is the layout of the sink, if the channel is in our src layout -+ // the channel is mapped by setting coef 1.0 -+ double m_rematrix[AE_CH_MAX][AE_CH_MAX]; -+ memset(m_rematrix, 0, sizeof(m_rematrix)); -+ m_dst_chan_layout = 0; -+ for (unsigned int out=0; outCount(); out++) -+ { -+ m_dst_chan_layout += (uint64_t) (1 << out); -+ int idx = GetAVChannelIndex((*remapLayout)[out], m_src_chan_layout); -+ if (idx >= 0) -+ { -+ m_rematrix[out][idx] = 1.0; -+ } -+ } -+ -+ av_opt_set_int(m_pContext, "out_channel_count", m_dst_channels, 0); -+ av_opt_set_int(m_pContext, "out_channel_layout", m_dst_chan_layout, 0); -+ -+ if (swr_set_matrix(m_pContext, (const double*)m_rematrix, AE_CH_MAX) < 0) -+ { -+ CLog::Log(LOGERROR, "CActiveAEResample::Init - setting channel matrix failed"); -+ return false; -+ } -+ } -+ // stereo upmix -+ else if (upmix && m_src_channels == 2 && m_dst_channels > 2) -+ { -+ double m_rematrix[AE_CH_MAX][AE_CH_MAX]; -+ memset(m_rematrix, 0, sizeof(m_rematrix)); -+ for (int out=0; out%d (%.2f)", CLASSNAME, __func__, src_samples, dst_samples, ratio); -+ #endif -+ if (!m_Initialized) -+ return 0; -+ OMX_ERRORTYPE omx_err = OMX_ErrorNone; -+ -+ const int s_pitch = m_pcm_input.nChannels * m_src_bits >> 3; -+ const int d_pitch = m_pcm_output.nChannels * m_dst_bits >> 3; -+ int sent = 0; -+ int received = 0; -+ while (sent < src_samples) -+ { -+ OMX_BUFFERHEADERTYPE *omx_buffer = NULL; -+ OMX_BUFFERHEADERTYPE *m_encoded_buffer = NULL; -+ -+ omx_buffer = m_omx_mixer.GetInputBuffer(1000); -+ if (omx_buffer == NULL) -+ return false; -+ -+ const int max_src_samples = BUFFERSIZE / s_pitch; -+ const int max_dst_samples = (long long)(BUFFERSIZE/d_pitch) * m_src_rate / (m_dst_rate + m_src_rate-1); -+ int send = std::min(std::min(max_dst_samples, max_src_samples), src_samples - sent); -+ -+ omx_buffer->nOffset = 0; -+ omx_buffer->nFlags = OMX_BUFFERFLAG_EOS; -+ omx_buffer->nFilledLen = send * s_pitch; -+ -+ assert(omx_buffer->nFilledLen > 0 && omx_buffer->nFilledLen <= omx_buffer->nAllocLen); -+ -+ if (omx_buffer->nFilledLen) -+ { -+ memcpy(omx_buffer->pBuffer, src_buffer[0] + sent * s_pitch, omx_buffer->nFilledLen); -+ sent += send; -+ } -+ -+ omx_err = m_omx_mixer.EmptyThisBuffer(omx_buffer); -+ if (omx_err != OMX_ErrorNone) -+ { -+ CLog::Log(LOGERROR, "%s::%s OMX_EmptyThisBuffer() failed with result(0x%x)", CLASSNAME, __func__, omx_err); -+ return false; -+ } -+ -+ m_encoded_buffer = m_omx_mixer.GetOutputBuffer(); -+ -+ if (!m_encoded_buffer) -+ { -+ CLog::Log(LOGERROR, "%s::%s no output buffer", CLASSNAME, __func__); -+ return false; -+ } -+ -+ omx_err = m_omx_mixer.FillThisBuffer(m_encoded_buffer); -+ if (omx_err != OMX_ErrorNone) -+ return false; -+ -+ omx_err = m_omx_mixer.WaitForOutputDone(1000); -+ if (omx_err != OMX_ErrorNone) -+ { -+ CLog::Log(LOGERROR, "%s::%s m_omx_mixer.WaitForOutputDone result(0x%x)", CLASSNAME, __func__, omx_err); -+ return false; -+ } -+ assert(m_encoded_buffer->nFilledLen > 0 && m_encoded_buffer->nFilledLen <= m_encoded_buffer->nAllocLen); -+ -+ if (m_omx_mixer.BadState()) -+ { -+ CLog::Log(LOGERROR, "%s::%s m_omx_mixer.BadState", CLASSNAME, __func__); -+ return false; -+ } -+ -+ if (m_encoded_buffer->nFilledLen) -+ { -+ memcpy(dst_buffer[0] + received * d_pitch, m_encoded_buffer->pBuffer, m_encoded_buffer->nFilledLen); -+ received += m_encoded_buffer->nFilledLen / d_pitch; -+ } -+ } -+ #ifdef DEBUG_VERBOSE -+ CLog::Log(LOGINFO, "%s::%s format:%d->%d rate:%d->%d chan:%d->%d samples %d->%d (%f) %d =%d", CLASSNAME, __func__, -+ (int)m_src_fmt, (int)m_dst_fmt, m_src_rate, m_dst_rate, m_src_channels, m_dst_channels, src_samples, dst_samples, ratio, m_Initialized, received); -+ #endif -+ return received; -+} -+ -+int64_t CActiveAEResample::GetDelay(int64_t base) -+{ -+ int ret = 0; -+ #ifdef DEBUG_VERBOSE -+ CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, ret); -+ #endif -+ return ret; -+} -+ -+int CActiveAEResample::GetBufferedSamples() -+{ -+ int ret = 0; -+ #ifdef DEBUG_VERBOSE -+ CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, ret); -+ #endif -+ return ret; -+} -+ -+int CActiveAEResample::CalcDstSampleCount(int src_samples, int dst_rate, int src_rate) -+{ -+ int ret = ((long long)src_samples * dst_rate + src_rate-1) / src_rate; -+ #ifdef DEBUG_VERBOSE -+ CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, ret); -+ #endif -+ return ret; -+} -+ -+int CActiveAEResample::GetSrcBufferSize(int samples) -+{ -+ int ret = 0; -+ #ifdef DEBUG_VERBOSE -+ CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, ret); -+ #endif -+ return ret; -+} -+ -+int CActiveAEResample::GetDstBufferSize(int samples) -+{ -+ int ret = CalcDstSampleCount(samples, m_dst_rate, m_src_rate); -+ #ifdef DEBUG_VERBOSE -+ CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, ret); -+ #endif -+ return ret; -+} -+ -+uint64_t CActiveAEResample::GetAVChannelLayout(CAEChannelInfo &info) -+{ -+ #ifdef DEBUG_VERBOSE -+ CLog::Log(LOGINFO, "%s::%s", CLASSNAME, __func__); -+ #endif -+ uint64_t channelLayout = 0; -+ if (info.HasChannel(AE_CH_FL)) channelLayout |= AV_CH_FRONT_LEFT; -+ if (info.HasChannel(AE_CH_FR)) channelLayout |= AV_CH_FRONT_RIGHT; -+ if (info.HasChannel(AE_CH_FC)) channelLayout |= AV_CH_FRONT_CENTER; -+ if (info.HasChannel(AE_CH_LFE)) channelLayout |= AV_CH_LOW_FREQUENCY; -+ if (info.HasChannel(AE_CH_BL)) channelLayout |= AV_CH_BACK_LEFT; -+ if (info.HasChannel(AE_CH_BR)) channelLayout |= AV_CH_BACK_RIGHT; -+ if (info.HasChannel(AE_CH_FLOC)) channelLayout |= AV_CH_FRONT_LEFT_OF_CENTER; -+ if (info.HasChannel(AE_CH_FROC)) channelLayout |= AV_CH_FRONT_RIGHT_OF_CENTER; -+ if (info.HasChannel(AE_CH_BC)) channelLayout |= AV_CH_BACK_CENTER; -+ if (info.HasChannel(AE_CH_SL)) channelLayout |= AV_CH_SIDE_LEFT; -+ if (info.HasChannel(AE_CH_SR)) channelLayout |= AV_CH_SIDE_RIGHT; -+ if (info.HasChannel(AE_CH_TC)) channelLayout |= AV_CH_TOP_CENTER; -+ if (info.HasChannel(AE_CH_TFL)) channelLayout |= AV_CH_TOP_FRONT_LEFT; -+ if (info.HasChannel(AE_CH_TFC)) channelLayout |= AV_CH_TOP_FRONT_CENTER; -+ if (info.HasChannel(AE_CH_TFR)) channelLayout |= AV_CH_TOP_FRONT_RIGHT; -+ if (info.HasChannel(AE_CH_TBL)) channelLayout |= AV_CH_TOP_BACK_LEFT; -+ if (info.HasChannel(AE_CH_TBC)) channelLayout |= AV_CH_TOP_BACK_CENTER; -+ if (info.HasChannel(AE_CH_TBR)) channelLayout |= AV_CH_TOP_BACK_RIGHT; -+ -+ return channelLayout; -+} -+ -+AVSampleFormat CActiveAEResample::GetAVSampleFormat(AEDataFormat format) -+{ -+ #ifdef DEBUG_VERBOSE -+ CLog::Log(LOGINFO, "%s::%s", CLASSNAME, __func__); -+ #endif -+ if (format == AE_FMT_U8) return AV_SAMPLE_FMT_U8; -+ else if (format == AE_FMT_S16NE) return AV_SAMPLE_FMT_S16; -+ else if (format == AE_FMT_S32NE) return AV_SAMPLE_FMT_S32; -+ else if (format == AE_FMT_S24NE4) return AV_SAMPLE_FMT_S32; -+ else if (format == AE_FMT_FLOAT) return AV_SAMPLE_FMT_FLT; -+ else if (format == AE_FMT_DOUBLE) return AV_SAMPLE_FMT_DBL; -+ -+ else if (format == AE_FMT_U8P) return AV_SAMPLE_FMT_U8P; -+ else if (format == AE_FMT_S16NEP) return AV_SAMPLE_FMT_S16P; -+ else if (format == AE_FMT_S32NEP) return AV_SAMPLE_FMT_S32P; -+ else if (format == AE_FMT_S24NE4P) return AV_SAMPLE_FMT_S32P; -+ else if (format == AE_FMT_FLOATP) return AV_SAMPLE_FMT_FLTP; -+ else if (format == AE_FMT_DOUBLEP) return AV_SAMPLE_FMT_DBLP; -+ -+ if (AE_IS_PLANAR(format)) -+ return AV_SAMPLE_FMT_FLTP; -+ else -+ return AV_SAMPLE_FMT_FLT; -+} -+ -+AEDataFormat CActiveAEResample::GetAESampleFormat(AVSampleFormat format, int bits) -+{ -+ #ifdef DEBUG_VERBOSE -+ CLog::Log(LOGINFO, "%s::%s", CLASSNAME, __func__); -+ #endif -+ if (format == AV_SAMPLE_FMT_U8) return AE_FMT_U8; -+ else if (format == AV_SAMPLE_FMT_S16) return AE_FMT_S16NE; -+ else if (format == AV_SAMPLE_FMT_S32 && bits == 32) return AE_FMT_S32NE; -+ else if (format == AV_SAMPLE_FMT_S32 && bits == 24) return AE_FMT_S24NE4; -+ else if (format == AV_SAMPLE_FMT_FLT) return AE_FMT_FLOAT; -+ else if (format == AV_SAMPLE_FMT_DBL) return AE_FMT_DOUBLE; -+ -+ else if (format == AV_SAMPLE_FMT_U8P) return AE_FMT_U8P; -+ else if (format == AV_SAMPLE_FMT_S16P) return AE_FMT_S16NEP; -+ else if (format == AV_SAMPLE_FMT_S32P && bits == 32) return AE_FMT_S32NEP; -+ else if (format == AV_SAMPLE_FMT_S32P && bits == 24) return AE_FMT_S24NE4P; -+ else if (format == AV_SAMPLE_FMT_FLTP) return AE_FMT_FLOATP; -+ else if (format == AV_SAMPLE_FMT_DBLP) return AE_FMT_DOUBLEP; -+ -+ CLog::Log(LOGERROR, "CActiveAEResample::GetAESampleFormat - format not supported"); -+ return AE_FMT_INVALID; -+} -+ -+uint64_t CActiveAEResample::GetAVChannel(enum AEChannel aechannel) -+{ -+ #ifdef DEBUG_VERBOSE -+ CLog::Log(LOGINFO, "%s::%s", CLASSNAME, __func__); -+ #endif -+ switch (aechannel) -+ { -+ case AE_CH_FL: return AV_CH_FRONT_LEFT; -+ case AE_CH_FR: return AV_CH_FRONT_RIGHT; -+ case AE_CH_FC: return AV_CH_FRONT_CENTER; -+ case AE_CH_LFE: return AV_CH_LOW_FREQUENCY; -+ case AE_CH_BL: return AV_CH_BACK_LEFT; -+ case AE_CH_BR: return AV_CH_BACK_RIGHT; -+ case AE_CH_FLOC: return AV_CH_FRONT_LEFT_OF_CENTER; -+ case AE_CH_FROC: return AV_CH_FRONT_RIGHT_OF_CENTER; -+ case AE_CH_BC: return AV_CH_BACK_CENTER; -+ case AE_CH_SL: return AV_CH_SIDE_LEFT; -+ case AE_CH_SR: return AV_CH_SIDE_RIGHT; -+ case AE_CH_TC: return AV_CH_TOP_CENTER; -+ case AE_CH_TFL: return AV_CH_TOP_FRONT_LEFT; -+ case AE_CH_TFC: return AV_CH_TOP_FRONT_CENTER; -+ case AE_CH_TFR: return AV_CH_TOP_FRONT_RIGHT; -+ case AE_CH_TBL: return AV_CH_TOP_BACK_LEFT; -+ case AE_CH_TBC: return AV_CH_TOP_BACK_CENTER; -+ case AE_CH_TBR: return AV_CH_TOP_BACK_RIGHT; -+ default: -+ return 0; -+ } -+} -+ -+int CActiveAEResample::GetAVChannelIndex(enum AEChannel aechannel, uint64_t layout) -+{ -+ #ifdef DEBUG_VERBOSE -+ CLog::Log(LOGINFO, "%s::%s", CLASSNAME, __func__); -+ #endif -+ return av_get_channel_layout_channel_index(layout, GetAVChannel(aechannel)); -+} -+ -+#endif -diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.h b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.h -new file mode 100644 -index 0000000..47a9e08 ---- /dev/null -+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.h -@@ -0,0 +1,62 @@ -+#pragma once -+/* -+ * Copyright (C) 2010-2013 Team XBMC -+ * http://xbmc.org -+ * -+ * This Program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2, or (at your option) -+ * any later version. -+ * -+ * This Program 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with XBMC; see the file COPYING. If not, see -+ * . -+ * -+ */ -+ -+#include "linux/OMXCore.h" -+ -+namespace ActiveAE -+{ -+ -+class CActiveAEResample -+{ -+public: -+ CActiveAEResample(); -+ virtual ~CActiveAEResample(); -+ bool Init(uint64_t dst_chan_layout, int dst_channels, int dst_rate, AVSampleFormat dst_fmt, int dst_bits, int dst_dither, uint64_t src_chan_layout, int src_channels, int src_rate, AVSampleFormat src_fmt, int src_bits, int src_dither, bool upmix, bool normalize, CAEChannelInfo *remapLayout, AEQuality quality); -+ int Resample(uint8_t **dst_buffer, int dst_samples, uint8_t **src_buffer, int src_samples, double ratio); -+ int64_t GetDelay(int64_t base); -+ int GetBufferedSamples(); -+ int CalcDstSampleCount(int src_samples, int dst_rate, int src_rate); -+ int GetSrcBufferSize(int samples); -+ int GetDstBufferSize(int samples); -+ static uint64_t GetAVChannelLayout(CAEChannelInfo &info); -+// static CAEChannelInfo GetAEChannelLayout(uint64_t layout); -+ static AVSampleFormat GetAVSampleFormat(AEDataFormat format); -+ static AEDataFormat GetAESampleFormat(AVSampleFormat format, int bits); -+ static uint64_t GetAVChannel(enum AEChannel aechannel); -+ int GetAVChannelIndex(enum AEChannel aechannel, uint64_t layout); -+ -+protected: -+ void DeInit(); -+ uint64_t m_src_chan_layout, m_dst_chan_layout; -+ int m_src_rate, m_dst_rate; -+ int m_src_channels, m_dst_channels; -+ AVSampleFormat m_src_fmt, m_dst_fmt; -+ int m_src_bits, m_dst_bits; -+ -+ OMX_AUDIO_PARAM_PCMMODETYPE m_pcm_input; -+ OMX_AUDIO_PARAM_PCMMODETYPE m_pcm_output; -+ COMXCoreComponent m_omx_mixer; -+ bool m_Initialized; -+ AVSampleFormat m_last_src_fmt, m_last_dst_fmt; -+ int m_last_src_channels, m_last_dst_channels; -+}; -+ -+} -diff --git a/xbmc/cores/AudioEngine/Makefile.in b/xbmc/cores/AudioEngine/Makefile.in -index c27d207..ebc74fa 100644 ---- a/xbmc/cores/AudioEngine/Makefile.in -+++ b/xbmc/cores/AudioEngine/Makefile.in -@@ -31,6 +31,7 @@ SRCS += Engines/ActiveAE/ActiveAESink.cpp - SRCS += Engines/ActiveAE/ActiveAEStream.cpp - SRCS += Engines/ActiveAE/ActiveAESound.cpp - SRCS += Engines/ActiveAE/ActiveAEResample.cpp -+SRCS += Engines/ActiveAE/ActiveAEResamplePi.cpp - SRCS += Engines/ActiveAE/ActiveAEBuffer.cpp - - ifeq (@USE_ANDROID@,1) -diff --git a/xbmc/linux/OMXCore.cpp b/xbmc/linux/OMXCore.cpp -index 99e407a..8d3c86a 100644 ---- a/xbmc/linux/OMXCore.cpp -+++ b/xbmc/linux/OMXCore.cpp -@@ -448,7 +448,7 @@ void COMXCoreComponent::FlushAll() - - void COMXCoreComponent::FlushInput() - { -- if(!m_handle) -+ if(!m_handle || m_resource_error) - return; - - OMX_ERRORTYPE omx_err = OMX_ErrorNone; -@@ -470,7 +470,7 @@ void COMXCoreComponent::FlushInput() - - void COMXCoreComponent::FlushOutput() - { -- if(!m_handle) -+ if(!m_handle || m_resource_error) - return; - - OMX_ERRORTYPE omx_err = OMX_ErrorNone; --- -1.9.3 - - -From c3265e0a36dd74c4d64dc818a5a48de63b894f3f Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Thu, 27 Mar 2014 00:22:05 +0000 -Subject: [PATCH 43/83] [PiResample] Work around AE not providing correct - src_bits - ---- - .../AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp | 13 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - -diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp -index ae72dbd..385c526 100644 ---- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp -+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp -@@ -95,16 +95,25 @@ bool CActiveAEResample::Init(uint64_t dst_chan_layout, int dst_channels, int dst - - CLog::Log(LOGINFO, "%s::%s remap:%p chan:%d->%d rate:%d->%d format:%d->%d bits:%d->%d norm:%d upmix:%d", CLASSNAME, __func__, remapLayout, src_channels, dst_channels, src_rate, dst_rate, src_fmt, dst_fmt, src_bits, dst_bits, normalize, upmix); - -+ if (src_bits == 0) -+ { -+ if (src_fmt == AV_SAMPLE_FMT_U8) src_bits = 8; -+ else if (src_fmt == AV_SAMPLE_FMT_S16) src_bits = 16; -+ else if (src_fmt == AV_SAMPLE_FMT_S32) src_bits = 32; -+ else if (src_fmt == AV_SAMPLE_FMT_FLT) src_bits = 32; -+ } -+ assert(src_bits && dst_bits); -+ - m_dst_chan_layout = dst_chan_layout; - m_dst_channels = dst_channels; - m_dst_rate = dst_rate; - m_dst_fmt = dst_fmt; -- m_dst_bits = dst_bits ? dst_bits : 8; -+ m_dst_bits = dst_bits; - m_src_chan_layout = src_chan_layout; - m_src_channels = src_channels; - m_src_rate = src_rate; - m_src_fmt = src_fmt; -- m_src_bits = src_bits ? src_bits : 8; -+ m_src_bits = src_bits; - - if (m_dst_chan_layout == 0) - m_dst_chan_layout = av_get_default_channel_layout(m_dst_channels); --- -1.9.3 - - -From 5eb748a1b3e596e793bab22e02735ef2652dee1b Mon Sep 17 00:00:00 2001 +From cf31aeb4932a63a7ef29b4357edb9c0105b5014c Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 7 Apr 2014 18:19:32 +0100 -Subject: [PATCH 44/83] [rbp/omxplayer] When opening a stream don't try to +Subject: [PATCH 41/89] [rbp/omxplayer] When opening a stream don't try to update gui so often --- @@ -9859,10 +8781,10 @@ index e9ba7d3..0fdc3c2 100644 1.9.3 -From 22b08e4de22a6d35015e7d56b60d9c4d7581cd48 Mon Sep 17 00:00:00 2001 +From c5548cde659d965aee4fe274c78f76508db1fb0f Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 7 Apr 2014 15:28:57 +0100 -Subject: [PATCH 45/83] [omxcodec] Clamp video texture at edges to avoid image +Subject: [PATCH 42/89] [omxcodec] Clamp video texture at edges to avoid image wrapping --- @@ -9886,1712 +8808,10 @@ index 51f56aa..2929a37 100644 1.9.3 -From 8dbe818fc4cf53e7bcd47c14d0b5898745ee7e93 Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 7 Apr 2014 17:36:19 +0100 -Subject: [PATCH 46/83] [PiSink] Remove unneeded header and use CAEChannelInfo - directly - ---- - .../AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp | 1 - - xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp | 14 +++++++------- - 2 files changed, 7 insertions(+), 8 deletions(-) - -diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp -index 385c526..9a1e549 100644 ---- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp -+++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp -@@ -24,7 +24,6 @@ - - #include "ActiveAEResample.h" - #include "linux/RBP.h" --#include "cores/omxplayer/PCMRemap.h" - #include "settings/Settings.h" - #include "utils/log.h" - -diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp -index 811ea0d..b6076f6 100644 ---- a/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp -+++ b/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp -@@ -78,9 +78,9 @@ static void SetAudioProps(bool stream_channels, uint32_t channel_map) - CLog::Log(LOGDEBUG, "%s:%s hdmi_stream_channels %d hdmi_channel_map %08x", CLASSNAME, __func__, stream_channels, channel_map); - } - --static uint32_t GetChannelMap(AEAudioFormat &format, bool passthrough) -+static uint32_t GetChannelMap(const CAEChannelInfo &channelLayout, bool passthrough) - { -- unsigned int channels = format.m_channelLayout.Count(); -+ unsigned int channels = channelLayout.Count(); - uint32_t channel_map = 0; - if (passthrough) - return 0; -@@ -119,12 +119,12 @@ static uint32_t GetChannelMap(AEAudioFormat &format, bool passthrough) - // According to CEA-861-D only RL and RR are known. In case of a format having SL and SR channels - // but no BR BL channels, we use the wide map in order to open only the num of channels really - // needed. -- if (format.m_channelLayout.HasChannel(AE_CH_BL) && !format.m_channelLayout.HasChannel(AE_CH_SL)) -+ if (channelLayout.HasChannel(AE_CH_BL) && !channelLayout.HasChannel(AE_CH_SL)) - map = map_back; - - for (unsigned int i = 0; i < channels; ++i) - { -- AEChannel c = format.m_channelLayout[i]; -+ AEChannel c = channelLayout[i]; - unsigned int chan = 0; - if ((unsigned int)c < sizeof map_normal / sizeof *map_normal) - chan = map[(unsigned int)c]; -@@ -155,9 +155,9 @@ static uint32_t GetChannelMap(AEAudioFormat &format, bool passthrough) - 0xff, // 7 - 0x13, // 7.1 - }; -- uint8_t cea = format.m_channelLayout.HasChannel(AE_CH_LFE) ? cea_map_lfe[channels] : cea_map[channels]; -+ uint8_t cea = channelLayout.HasChannel(AE_CH_LFE) ? cea_map_lfe[channels] : cea_map[channels]; - if (cea == 0xff) -- CLog::Log(LOGERROR, "%s::%s - Unexpected CEA mapping %d,%d", CLASSNAME, __func__, format.m_channelLayout.HasChannel(AE_CH_LFE), channels); -+ CLog::Log(LOGERROR, "%s::%s - Unexpected CEA mapping %d,%d", CLASSNAME, __func__, channelLayout.HasChannel(AE_CH_LFE), channels); - - channel_map |= cea << 24; - -@@ -189,7 +189,7 @@ bool CAESinkPi::Initialize(AEAudioFormat &format, std::string &device) - format.m_frames = format.m_sampleRate * AUDIO_PLAYBUFFER; - format.m_frameSamples = format.m_frames * channels; - -- SetAudioProps(m_passthrough, GetChannelMap(format, m_passthrough)); -+ SetAudioProps(m_passthrough, GetChannelMap(format.m_channelLayout, m_passthrough)); - - m_format = format; - m_sinkbuffer_sec_per_byte = 1.0 / (double)(m_format.m_frameSize * m_format.m_sampleRate); --- -1.9.3 - - -From e7e795bd378afc84e2bf4b848b923074d358804f Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Mon, 7 Apr 2014 17:37:41 +0100 -Subject: [PATCH 47/83] [omxplayer] Remove PCMRemap and handle multichannel - mixing like ActiveAE does - ---- - xbmc/cores/omxplayer/Makefile.in | 1 - - xbmc/cores/omxplayer/OMXAudio.cpp | 390 ++++++++------ - xbmc/cores/omxplayer/OMXAudio.h | 9 +- - xbmc/cores/omxplayer/OMXAudioCodecOMX.cpp | 39 +- - xbmc/cores/omxplayer/OMXAudioCodecOMX.h | 5 +- - xbmc/cores/omxplayer/OMXPlayerAudio.cpp | 4 +- - xbmc/cores/omxplayer/PCMRemap.cpp | 813 ------------------------------ - xbmc/cores/omxplayer/PCMRemap.h | 151 ------ - xbmc/linux/OMXCore.h | 2 - - 9 files changed, 286 insertions(+), 1128 deletions(-) - delete mode 100644 xbmc/cores/omxplayer/PCMRemap.cpp - delete mode 100644 xbmc/cores/omxplayer/PCMRemap.h - -diff --git a/xbmc/cores/omxplayer/Makefile.in b/xbmc/cores/omxplayer/Makefile.in -index 3163282..e5cad70 100644 ---- a/xbmc/cores/omxplayer/Makefile.in -+++ b/xbmc/cores/omxplayer/Makefile.in -@@ -7,7 +7,6 @@ SRCS += OMXAudioCodecOMX.cpp - SRCS += OMXPlayerAudio.cpp - SRCS += OMXPlayerVideo.cpp - SRCS += OMXImage.cpp --SRCS += PCMRemap.cpp - - LIB = omxplayer.a - -diff --git a/xbmc/cores/omxplayer/OMXAudio.cpp b/xbmc/cores/omxplayer/OMXAudio.cpp -index 757c7a2..353e00e 100644 ---- a/xbmc/cores/omxplayer/OMXAudio.cpp -+++ b/xbmc/cores/omxplayer/OMXAudio.cpp -@@ -29,6 +29,7 @@ - #include "OMXAudio.h" - #include "Application.h" - #include "utils/log.h" -+#include "linux/RBP.h" - - #define CLASSNAME "COMXAudio" - -@@ -42,6 +43,9 @@ - - extern "C" { - #include "libavutil/crc.h" -+#include "libavutil/channel_layout.h" -+#include "libavutil/opt.h" -+#include "libswresample/swresample.h" - } - - using namespace std; -@@ -407,15 +411,134 @@ bool COMXAudio::PortSettingsChanged() - return true; - } - --static unsigned count_bits(int64_t value) -+static uint64_t GetAVChannelLayout(CAEChannelInfo &info) - { -- unsigned bits = 0; -- for(;value;++bits) -- value &= value - 1; -- return bits; -+ #ifdef DEBUG_VERBOSE -+ CLog::Log(LOGINFO, "%s::%s", CLASSNAME, __func__); -+ #endif -+ uint64_t channelLayout = 0; -+ if (info.HasChannel(AE_CH_FL)) channelLayout |= AV_CH_FRONT_LEFT; -+ if (info.HasChannel(AE_CH_FR)) channelLayout |= AV_CH_FRONT_RIGHT; -+ if (info.HasChannel(AE_CH_FC)) channelLayout |= AV_CH_FRONT_CENTER; -+ if (info.HasChannel(AE_CH_LFE)) channelLayout |= AV_CH_LOW_FREQUENCY; -+ if (info.HasChannel(AE_CH_BL)) channelLayout |= AV_CH_BACK_LEFT; -+ if (info.HasChannel(AE_CH_BR)) channelLayout |= AV_CH_BACK_RIGHT; -+ if (info.HasChannel(AE_CH_FLOC)) channelLayout |= AV_CH_FRONT_LEFT_OF_CENTER; -+ if (info.HasChannel(AE_CH_FROC)) channelLayout |= AV_CH_FRONT_RIGHT_OF_CENTER; -+ if (info.HasChannel(AE_CH_BC)) channelLayout |= AV_CH_BACK_CENTER; -+ if (info.HasChannel(AE_CH_SL)) channelLayout |= AV_CH_SIDE_LEFT; -+ if (info.HasChannel(AE_CH_SR)) channelLayout |= AV_CH_SIDE_RIGHT; -+ if (info.HasChannel(AE_CH_TC)) channelLayout |= AV_CH_TOP_CENTER; -+ if (info.HasChannel(AE_CH_TFL)) channelLayout |= AV_CH_TOP_FRONT_LEFT; -+ if (info.HasChannel(AE_CH_TFC)) channelLayout |= AV_CH_TOP_FRONT_CENTER; -+ if (info.HasChannel(AE_CH_TFR)) channelLayout |= AV_CH_TOP_FRONT_RIGHT; -+ if (info.HasChannel(AE_CH_TBL)) channelLayout |= AV_CH_TOP_BACK_LEFT; -+ if (info.HasChannel(AE_CH_TBC)) channelLayout |= AV_CH_TOP_BACK_CENTER; -+ if (info.HasChannel(AE_CH_TBR)) channelLayout |= AV_CH_TOP_BACK_RIGHT; -+ -+ return channelLayout; -+} -+ -+static void SetAudioProps(bool stream_channels, uint32_t channel_map) -+{ -+ char command[80], response[80]; -+ -+ sprintf(command, "hdmi_stream_channels %d", stream_channels ? 1 : 0); -+ vc_gencmd(response, sizeof response, command); -+ -+ sprintf(command, "hdmi_channel_map 0x%08x", channel_map); -+ vc_gencmd(response, sizeof response, command); -+ -+ CLog::Log(LOGDEBUG, "%s:%s hdmi_stream_channels %d hdmi_channel_map %08x", CLASSNAME, __func__, stream_channels, channel_map); - } - --bool COMXAudio::Initialize(AEAudioFormat format, OMXClock *clock, CDVDStreamInfo &hints, uint64_t channelMap, bool bUsePassthrough, bool bUseHWDecode) -+static uint32_t GetChannelMap(const CAEChannelInfo &channelLayout, bool passthrough) -+{ -+ unsigned int channels = channelLayout.Count(); -+ uint32_t channel_map = 0; -+ if (passthrough) -+ return 0; -+ -+ static const unsigned char map_normal[] = -+ { -+ 0, //AE_CH_RAW , -+ 1, //AE_CH_FL -+ 2, //AE_CH_FR -+ 4, //AE_CH_FC -+ 3, //AE_CH_LFE -+ 7, //AE_CH_BL -+ 8, //AE_CH_BR -+ 1, //AE_CH_FLOC, -+ 2, //AE_CH_FROC, -+ 4, //AE_CH_BC, -+ 5, //AE_CH_SL -+ 6, //AE_CH_SR -+ }; -+ static const unsigned char map_back[] = -+ { -+ 0, //AE_CH_RAW , -+ 1, //AE_CH_FL -+ 2, //AE_CH_FR -+ 4, //AE_CH_FC -+ 3, //AE_CH_LFE -+ 5, //AE_CH_BL -+ 6, //AE_CH_BR -+ 1, //AE_CH_FLOC, -+ 2, //AE_CH_FROC, -+ 4, //AE_CH_BC, -+ 5, //AE_CH_SL -+ 6, //AE_CH_SR -+ }; -+ const unsigned char *map = map_normal; -+ // According to CEA-861-D only RL and RR are known. In case of a format having SL and SR channels -+ // but no BR BL channels, we use the wide map in order to open only the num of channels really -+ // needed. -+ if (channelLayout.HasChannel(AE_CH_BL) && !channelLayout.HasChannel(AE_CH_SL)) -+ map = map_back; -+ -+ for (unsigned int i = 0; i < channels; ++i) -+ { -+ AEChannel c = channelLayout[i]; -+ unsigned int chan = 0; -+ if ((unsigned int)c < sizeof map_normal / sizeof *map_normal) -+ chan = map[(unsigned int)c]; -+ if (chan > 0) -+ channel_map |= (chan-1) << (3*i); -+ } -+ // These numbers are from Table 28 Audio InfoFrame Data byte 4 of CEA 861 -+ // and describe the speaker layout -+ static const uint8_t cea_map[] = { -+ 0xff, // 0 -+ 0xff, // 1 -+ 0x00, // 2.0 -+ 0x02, // 3.0 -+ 0x08, // 4.0 -+ 0x0a, // 5.0 -+ 0xff, // 6 -+ 0x12, // 7.0 -+ 0xff, // 8 -+ }; -+ static const uint8_t cea_map_lfe[] = { -+ 0xff, // 0 -+ 0xff, // 1 -+ 0xff, // 2 -+ 0x01, // 2.1 -+ 0x03, // 3.1 -+ 0x09, // 4.1 -+ 0x0b, // 5.1 -+ 0xff, // 7 -+ 0x13, // 7.1 -+ }; -+ uint8_t cea = channelLayout.HasChannel(AE_CH_LFE) ? cea_map_lfe[channels] : cea_map[channels]; -+ if (cea == 0xff) -+ CLog::Log(LOGERROR, "%s::%s - Unexpected CEA mapping %d,%d", CLASSNAME, __func__, channelLayout.HasChannel(AE_CH_LFE), channels); -+ -+ channel_map |= cea << 24; -+ -+ return channel_map; -+} -+ -+bool COMXAudio::Initialize(AEAudioFormat format, OMXClock *clock, CDVDStreamInfo &hints, CAEChannelInfo channelMap, bool bUsePassthrough, bool bUseHWDecode) - { - CSingleLock lock (m_critSection); - OMX_ERRORTYPE omx_err; -@@ -425,7 +548,7 @@ bool COMXAudio::Initialize(AEAudioFormat format, OMXClock *clock, CDVDStreamInfo - m_HWDecode = bUseHWDecode; - m_Passthrough = bUsePassthrough; - -- m_InputChannels = count_bits(channelMap); -+ m_InputChannels = channelMap.Count(); - m_format = format; - - if(m_InputChannels == 0) -@@ -471,26 +594,128 @@ bool COMXAudio::Initialize(AEAudioFormat format, OMXClock *clock, CDVDStreamInfo - - if (!m_Passthrough) - { -- enum PCMChannels inLayout[OMX_AUDIO_MAXCHANNELS]; -- enum PCMChannels outLayout[OMX_AUDIO_MAXCHANNELS]; -- enum PCMLayout layout = (enum PCMLayout)std::max(0, CSettings::Get().GetInt("audiooutput.channels")-1); -+ bool upmix = CSettings::Get().GetBool("audiooutput.stereoupmix"); -+ bool normalize = CSettings::Get().GetBool("audiooutput.normalizelevels"); -+ void *remapLayout = NULL; -+ -+ CAEChannelInfo stdLayout = (enum AEStdChLayout)CSettings::Get().GetInt("audiooutput.channels"); -+ - // ignore layout setting for analogue - if (CSettings::Get().GetBool("audiooutput.dualaudio") || CSettings::Get().GetString("audiooutput.audiodevice") == "PI:Analogue") -- layout = PCM_LAYOUT_2_0; -+ stdLayout = AE_CH_LAYOUT_2_0; - - // force out layout to stereo if input is not multichannel - it gives the receiver a chance to upmix -- if (channelMap == (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT) || channelMap == AV_CH_FRONT_CENTER) -- layout = PCM_LAYOUT_2_0; -- BuildChannelMap(inLayout, channelMap); -- m_OutputChannels = BuildChannelMapCEA(outLayout, GetChannelLayout(layout)); -- CPCMRemap m_remap; -- m_remap.Reset(); -- /*outLayout = */m_remap.SetInputFormat (m_InputChannels, inLayout, CAEUtil::DataFormatToBits(m_format.m_dataFormat) / 8, m_format.m_sampleRate, layout); -- m_remap.SetOutputFormat(m_OutputChannels, outLayout); -- m_remap.GetDownmixMatrix(m_downmix_matrix); -- m_wave_header.dwChannelMask = channelMap; -- BuildChannelMapOMX(m_input_channels, channelMap); -- BuildChannelMapOMX(m_output_channels, GetChannelLayout(layout)); -+ if (m_InputChannels <= 2) -+ stdLayout = AE_CH_LAYOUT_2_0; -+ -+ uint64_t m_dst_chan_layout = GetAVChannelLayout(stdLayout); -+ uint64_t m_src_chan_layout = GetAVChannelLayout(channelMap); -+ m_OutputChannels = stdLayout.Count(); -+ -+ int m_dst_channels = m_OutputChannels; -+ int m_src_channels = m_InputChannels; -+ SetAudioProps(m_Passthrough, GetChannelMap(stdLayout, m_Passthrough)); -+ -+ CLog::Log(LOGINFO, "%s::%s remap:%p chan:%d->%d norm:%d upmix:%d %llx:%llx", CLASSNAME, __func__, remapLayout, m_src_channels, m_dst_channels, normalize, upmix, m_src_chan_layout, m_dst_chan_layout); -+ -+ // this code is just uses ffmpeg to produce the 8x8 mixing matrix -+ // dummy sample rate and format, as we only care about channel mapping -+ SwrContext *m_pContext = swr_alloc_set_opts(NULL, m_dst_chan_layout, AV_SAMPLE_FMT_FLT, 48000, -+ m_src_chan_layout, AV_SAMPLE_FMT_FLT, 48000, 0, NULL); -+ if(!m_pContext) -+ { -+ CLog::Log(LOGERROR, "COMXAudio::Init - create context failed"); -+ return false; -+ } -+ // tell resampler to clamp float values -+ // not required for sink stage (remapLayout == true) -+ if (!remapLayout && normalize) -+ { -+ av_opt_set_double(m_pContext, "rematrix_maxval", 1.0, 0); -+ } -+ -+ // stereo upmix -+ if (upmix && m_src_channels == 2 && m_dst_channels > 2) -+ { -+ double m_rematrix[AE_CH_MAX][AE_CH_MAX]; -+ memset(m_rematrix, 0, sizeof(m_rematrix)); -+ for (int out=0; outblock_align = hints.blockalign; - m_pCodecContext->bit_rate = hints.bitrate; - m_pCodecContext->bits_per_coded_sample = hints.bitspersample; -- enum PCMLayout layout = (enum PCMLayout)std::max(0, CSettings::Get().GetInt("audiooutput.channels")-1); - if (hints.codec == AV_CODEC_ID_TRUEHD) - { -- if (layout == PCM_LAYOUT_2_0) -+ if (CSettings::Get().GetInt("audiooutput.channels") == AE_CH_LAYOUT_2_0) - m_pCodecContext->request_channel_layout = AV_CH_LAYOUT_STEREO; -- else if (layout <= PCM_LAYOUT_5_1) -+ else if (CSettings::Get().GetInt("audiooutput.channels") == AE_CH_LAYOUT_5_1) - m_pCodecContext->request_channel_layout = AV_CH_LAYOUT_5POINT1; - } - if (m_pCodecContext->request_channel_layout) -@@ -314,7 +312,7 @@ int COMXAudioCodecOMX::GetBitRate() - return m_pCodecContext->bit_rate; - } - --static unsigned count_bits(int64_t value) -+static unsigned count_bits(uint64_t value) - { - unsigned bits = 0; - for(;value;++bits) -@@ -322,9 +320,10 @@ static unsigned count_bits(int64_t value) - return bits; - } - --uint64_t COMXAudioCodecOMX::GetChannelMap() -+void COMXAudioCodecOMX::BuildChannelMap() - { - uint64_t layout; -+ - int bits = count_bits(m_pCodecContext->channel_layout); - if (bits == m_pCodecContext->channels) - layout = m_pCodecContext->channel_layout; -@@ -333,5 +332,31 @@ uint64_t COMXAudioCodecOMX::GetChannelMap() - CLog::Log(LOGINFO, "COMXAudioCodecOMX::GetChannelMap - FFmpeg reported %d channels, but the layout contains %d ignoring", m_pCodecContext->channels, bits); - layout = av_get_default_channel_layout(m_pCodecContext->channels); - } -- return layout; -+ -+ m_channelLayout.Reset(); -+ -+ if (layout & AV_CH_FRONT_LEFT ) m_channelLayout += AE_CH_FL ; -+ if (layout & AV_CH_FRONT_RIGHT ) m_channelLayout += AE_CH_FR ; -+ if (layout & AV_CH_FRONT_CENTER ) m_channelLayout += AE_CH_FC ; -+ if (layout & AV_CH_LOW_FREQUENCY ) m_channelLayout += AE_CH_LFE ; -+ if (layout & AV_CH_BACK_LEFT ) m_channelLayout += AE_CH_BL ; -+ if (layout & AV_CH_BACK_RIGHT ) m_channelLayout += AE_CH_BR ; -+ if (layout & AV_CH_FRONT_LEFT_OF_CENTER ) m_channelLayout += AE_CH_FLOC; -+ if (layout & AV_CH_FRONT_RIGHT_OF_CENTER) m_channelLayout += AE_CH_FROC; -+ if (layout & AV_CH_BACK_CENTER ) m_channelLayout += AE_CH_BC ; -+ if (layout & AV_CH_SIDE_LEFT ) m_channelLayout += AE_CH_SL ; -+ if (layout & AV_CH_SIDE_RIGHT ) m_channelLayout += AE_CH_SR ; -+ if (layout & AV_CH_TOP_CENTER ) m_channelLayout += AE_CH_TC ; -+ if (layout & AV_CH_TOP_FRONT_LEFT ) m_channelLayout += AE_CH_TFL ; -+ if (layout & AV_CH_TOP_FRONT_CENTER ) m_channelLayout += AE_CH_TFC ; -+ if (layout & AV_CH_TOP_FRONT_RIGHT ) m_channelLayout += AE_CH_TFR ; -+ if (layout & AV_CH_TOP_BACK_LEFT ) m_channelLayout += AE_CH_BL ; -+ if (layout & AV_CH_TOP_BACK_CENTER ) m_channelLayout += AE_CH_BC ; -+ if (layout & AV_CH_TOP_BACK_RIGHT ) m_channelLayout += AE_CH_BR ; -+} -+ -+CAEChannelInfo COMXAudioCodecOMX::GetChannelMap() -+{ -+ BuildChannelMap(); -+ return m_channelLayout; - } -diff --git a/xbmc/cores/omxplayer/OMXAudioCodecOMX.h b/xbmc/cores/omxplayer/OMXAudioCodecOMX.h -index 080c18f..81fc889 100644 ---- a/xbmc/cores/omxplayer/OMXAudioCodecOMX.h -+++ b/xbmc/cores/omxplayer/OMXAudioCodecOMX.h -@@ -43,7 +43,8 @@ class COMXAudioCodecOMX - int GetData(BYTE** dst, double &dts, double &pts); - void Reset(); - int GetChannels(); -- uint64_t GetChannelMap(); -+ void BuildChannelMap(); -+ CAEChannelInfo GetChannelMap(); - int GetSampleRate(); - int GetBitsPerSample(); - static const char* GetName() { return "FFmpeg"; } -@@ -65,7 +66,7 @@ class COMXAudioCodecOMX - bool m_bOpenedCodec; - - int m_channels; -- -+ CAEChannelInfo m_channelLayout; - bool m_bFirstFrame; - bool m_bGotFrame; - bool m_bNoConcatenate; -diff --git a/xbmc/cores/omxplayer/OMXPlayerAudio.cpp b/xbmc/cores/omxplayer/OMXPlayerAudio.cpp -index a4c11777..d3348ec 100644 ---- a/xbmc/cores/omxplayer/OMXPlayerAudio.cpp -+++ b/xbmc/cores/omxplayer/OMXPlayerAudio.cpp -@@ -567,13 +567,13 @@ bool OMXPlayerAudio::OpenDecoder() - /* GetDataFormat is setting up evrything */ - m_format.m_dataFormat = GetDataFormat(m_hints); - -- uint64_t channelMap = 0; -+ CAEChannelInfo channelMap; - if (m_pAudioCodec && !m_passthrough) - channelMap = m_pAudioCodec->GetChannelMap(); - else if (m_passthrough) - // we just want to get the channel count right to stop OMXAudio.cpp rejecting stream - // the actual layout is not used -- channelMap = (1< --#include --#include --#include -- --//#include "MathUtils.h" --#include "PCMRemap.h" --#include "utils/log.h" --#include "utils/StringUtils.h" --#include "settings/Settings.h" --#include "settings/AdvancedSettings.h" --#ifdef _WIN32 --#include "../win32/PlatformDefs.h" --#endif -- --static enum PCMChannels PCMLayoutMap[PCM_MAX_LAYOUT][PCM_MAX_CH + 1] = --{ -- /* 2.0 */ {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_INVALID}, -- /* 2.1 */ {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_LOW_FREQUENCY, PCM_INVALID}, -- /* 3.0 */ {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_FRONT_CENTER, PCM_INVALID}, -- /* 3.1 */ {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_FRONT_CENTER, PCM_LOW_FREQUENCY, PCM_INVALID}, -- /* 4.0 */ {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_BACK_LEFT, PCM_BACK_RIGHT, PCM_INVALID}, -- /* 4.1 */ {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_BACK_LEFT, PCM_BACK_RIGHT, PCM_LOW_FREQUENCY, PCM_INVALID}, -- /* 5.0 */ {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_FRONT_CENTER, PCM_BACK_LEFT, PCM_BACK_RIGHT, PCM_INVALID}, -- /* 5.1 */ {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_FRONT_CENTER, PCM_BACK_LEFT, PCM_BACK_RIGHT, PCM_LOW_FREQUENCY, PCM_INVALID}, -- /* 7.0 */ {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_FRONT_CENTER, PCM_SIDE_LEFT, PCM_SIDE_RIGHT, PCM_BACK_LEFT, PCM_BACK_RIGHT, PCM_INVALID}, -- /* 7.1 */ {PCM_FRONT_LEFT, PCM_FRONT_RIGHT, PCM_FRONT_CENTER, PCM_SIDE_LEFT, PCM_SIDE_RIGHT, PCM_BACK_LEFT, PCM_BACK_RIGHT, PCM_LOW_FREQUENCY, PCM_INVALID} --}; -- --/* -- map missing output into channel @ volume level -- the order of this table is important, mix tables can not depend on channels that have not been defined yet -- eg, FC can only be mixed into FL, FR as they are the only channels that have been defined --*/ --#define PCM_MAX_MIX 3 --static struct PCMMapInfo PCMDownmixTable[PCM_MAX_CH][PCM_MAX_MIX] = --{ -- /* PCM_FRONT_LEFT */ -- { -- {PCM_INVALID} -- }, -- /* PCM_FRONT_RIGHT */ -- { -- {PCM_INVALID} -- }, -- /* PCM_FRONT_CENTER */ -- { -- {PCM_FRONT_LEFT_OF_CENTER , 1.0}, -- {PCM_FRONT_RIGHT_OF_CENTER, 1.0}, -- {PCM_INVALID} -- }, -- /* PCM_LOW_FREQUENCY */ -- { -- /* -- A/52B 7.8 paragraph 2 recomends +10db -- but due to horrible clipping when normalize -- is disabled we set this to 1.0 -- */ -- {PCM_FRONT_LEFT , 1.0},//3.5}, -- {PCM_FRONT_RIGHT , 1.0},//3.5}, -- {PCM_INVALID} -- }, -- /* PCM_BACK_LEFT */ -- { -- {PCM_FRONT_LEFT , 1.0}, -- {PCM_INVALID} -- }, -- /* PCM_BACK_RIGHT */ -- { -- {PCM_FRONT_RIGHT , 1.0}, -- {PCM_INVALID} -- }, -- /* PCM_FRONT_LEFT_OF_CENTER */ -- { -- {PCM_FRONT_LEFT , 1.0}, -- {PCM_FRONT_CENTER , 1.0, true}, -- {PCM_INVALID} -- }, -- /* PCM_FRONT_RIGHT_OF_CENTER */ -- { -- {PCM_FRONT_RIGHT , 1.0}, -- {PCM_FRONT_CENTER , 1.0, true}, -- {PCM_INVALID} -- }, -- /* PCM_BACK_CENTER */ -- { -- {PCM_BACK_LEFT , 1.0}, -- {PCM_BACK_RIGHT , 1.0}, -- {PCM_INVALID} -- }, -- /* PCM_SIDE_LEFT */ -- { -- {PCM_FRONT_LEFT , 1.0}, -- {PCM_BACK_LEFT , 1.0}, -- {PCM_INVALID} -- }, -- /* PCM_SIDE_RIGHT */ -- { -- {PCM_FRONT_RIGHT , 1.0}, -- {PCM_BACK_RIGHT , 1.0}, -- {PCM_INVALID} -- }, -- /* PCM_TOP_FRONT_LEFT */ -- { -- {PCM_FRONT_LEFT , 1.0}, -- {PCM_INVALID} -- }, -- /* PCM_TOP_FRONT_RIGHT */ -- { -- {PCM_FRONT_RIGHT , 1.0}, -- {PCM_INVALID} -- }, -- /* PCM_TOP_FRONT_CENTER */ -- { -- {PCM_TOP_FRONT_LEFT , 1.0}, -- {PCM_TOP_FRONT_RIGHT , 1.0}, -- {PCM_INVALID} -- }, -- /* PCM_TOP_CENTER */ -- { -- {PCM_TOP_FRONT_LEFT , 1.0}, -- {PCM_TOP_FRONT_RIGHT , 1.0}, -- {PCM_INVALID} -- }, -- /* PCM_TOP_BACK_LEFT */ -- { -- {PCM_BACK_LEFT , 1.0}, -- {PCM_INVALID} -- }, -- /* PCM_TOP_BACK_RIGHT */ -- { -- {PCM_BACK_RIGHT , 1.0}, -- {PCM_INVALID} -- }, -- /* PCM_TOP_BACK_CENTER */ -- { -- {PCM_TOP_BACK_LEFT , 1.0}, -- {PCM_TOP_BACK_RIGHT , 1.0}, -- {PCM_INVALID} -- } --}; -- --CPCMRemap::CPCMRemap() : -- m_inSet (false), -- m_outSet (false), -- m_inChannels (0), -- m_outChannels (0), -- m_inSampleSize(0), -- m_ignoreLayout(false), -- m_buf(NULL), -- m_bufsize(0), -- m_attenuation (1.0), -- m_attenuationInc(0.0), -- m_attenuationMin(1.0), -- m_sampleRate (48000.0), //safe default -- m_holdCounter (0), -- m_limiterEnabled(false) --{ -- Dispose(); --} -- --CPCMRemap::~CPCMRemap() --{ -- Dispose(); --} -- --void CPCMRemap::Dispose() --{ -- free(m_buf); -- m_buf = NULL; -- m_bufsize = 0; --} -- --/* resolves the channels recursively and returns the new index of tablePtr */ --struct PCMMapInfo* CPCMRemap::ResolveChannel(enum PCMChannels channel, float level, bool ifExists, std::vector path, struct PCMMapInfo *tablePtr) --{ -- if (channel == PCM_INVALID) return tablePtr; -- -- /* if its a 1 to 1 mapping, return */ -- if (m_useable[channel]) -- { -- tablePtr->channel = channel; -- tablePtr->level = level; -- -- ++tablePtr; -- tablePtr->channel = PCM_INVALID; -- return tablePtr; -- } else -- if (ifExists) -- level /= 2; -- -- struct PCMMapInfo *info; -- std::vector::iterator itt; -- -- for(info = PCMDownmixTable[channel]; info->channel != PCM_INVALID; ++info) -- { -- /* make sure we are not about to recurse into ourself */ -- bool found = false; -- for(itt = path.begin(); itt != path.end(); ++itt) -- if (*itt == info->channel) -- { -- found = true; -- break; -- } -- -- if (found) -- continue; -- -- path.push_back(channel); -- float l = (info->level * (level / 100)) * 100; -- tablePtr = ResolveChannel(info->channel, l, info->ifExists, path, tablePtr); -- path.pop_back(); -- } -- -- return tablePtr; --} -- --/* -- Builds a lookup table without extra adjustments, useful if we simply -- want to find out which channels are active. -- For final adjustments, BuildMap() is used. --*/ --void CPCMRemap::ResolveChannels() --{ -- unsigned int in_ch, out_ch; -- bool hasSide = false; -- bool hasBack = false; -- -- memset(m_useable, 0, sizeof(m_useable)); -- -- if (!m_outSet) -- { -- /* Output format is not known yet, assume the full configured map. -- * Note that m_ignoreLayout-using callers normally ignore the result of -- * this function when !m_outSet, when it is called only for an advice for -- * the caller of SetInputFormat about the best possible output map, and -- * they can still set their output format arbitrarily in their call to -- * SetOutputFormat. */ -- for (enum PCMChannels *chan = PCMLayoutMap[m_channelLayout]; *chan != PCM_INVALID; ++chan) -- m_useable[*chan] = true; -- } -- else if (m_ignoreLayout) -- { -- for(out_ch = 0; out_ch < m_outChannels; ++out_ch) -- m_useable[m_outMap[out_ch]] = true; -- } -- else -- { -- /* figure out what channels we have and can use */ -- for(enum PCMChannels *chan = PCMLayoutMap[m_channelLayout]; *chan != PCM_INVALID; ++chan) -- { -- for(out_ch = 0; out_ch < m_outChannels; ++out_ch) -- if (m_outMap[out_ch] == *chan) -- { -- m_useable[*chan] = true; -- break; -- } -- } -- } -- -- /* force mono audio to front left and front right */ -- if (!m_ignoreLayout && m_inChannels == 1 && m_inMap[0] == PCM_FRONT_CENTER -- && m_useable[PCM_FRONT_LEFT] && m_useable[PCM_FRONT_RIGHT]) -- { -- CLog::Log(LOGDEBUG, "CPCMRemap: Mapping mono audio to front left and front right"); -- m_useable[PCM_FRONT_CENTER] = false; -- m_useable[PCM_FRONT_LEFT_OF_CENTER] = false; -- m_useable[PCM_FRONT_RIGHT_OF_CENTER] = false; -- } -- -- /* see if our input has side/back channels */ -- for(in_ch = 0; in_ch < m_inChannels; ++in_ch) -- switch(m_inMap[in_ch]) -- { -- case PCM_SIDE_LEFT: -- case PCM_SIDE_RIGHT: -- hasSide = true; -- break; -- -- case PCM_BACK_LEFT: -- case PCM_BACK_RIGHT: -- hasBack = true; -- break; -- -- default:; -- } -- -- /* if our input has side, and not back channels, and our output doesnt have side channels */ -- if (hasSide && !hasBack && (!m_useable[PCM_SIDE_LEFT] || !m_useable[PCM_SIDE_RIGHT])) -- { -- CLog::Log(LOGDEBUG, "CPCMRemap: Forcing side channel map to back channels"); -- for(in_ch = 0; in_ch < m_inChannels; ++in_ch) -- if (m_inMap[in_ch] == PCM_SIDE_LEFT ) m_inMap[in_ch] = PCM_BACK_LEFT; -- else if (m_inMap[in_ch] == PCM_SIDE_RIGHT) m_inMap[in_ch] = PCM_BACK_RIGHT; -- } -- -- /* resolve all the channels */ -- struct PCMMapInfo table[PCM_MAX_CH + 1], *info, *dst; -- std::vector path; -- -- for (int i = 0; i < PCM_MAX_CH + 1; i++) -- { -- for (int j = 0; j < PCM_MAX_CH + 1; j++) -- m_lookupMap[i][j].channel = PCM_INVALID; -- } -- -- memset(m_counts, 0, sizeof(m_counts)); -- for(in_ch = 0; in_ch < m_inChannels; ++in_ch) { -- -- for (int i = 0; i < PCM_MAX_CH + 1; i++) -- table[i].channel = PCM_INVALID; -- -- ResolveChannel(m_inMap[in_ch], 1.0f, false, path, table); -- for(info = table; info->channel != PCM_INVALID; ++info) -- { -- /* find the end of the table */ -- for(dst = m_lookupMap[info->channel]; dst->channel != PCM_INVALID; ++dst); -- -- /* append it to the table and set its input offset */ -- dst->channel = m_inMap[in_ch]; -- dst->in_offset = in_ch * 2; -- dst->level = info->level; -- m_counts[dst->channel]++; -- } -- } --} -- --/* -- builds a lookup table to convert from the input mapping to the output -- mapping, this decreases the amount of work per sample to remap it. --*/ --void CPCMRemap::BuildMap() --{ -- struct PCMMapInfo *dst; -- unsigned int out_ch; -- -- if (!m_inSet || !m_outSet) return; -- -- m_inStride = m_inSampleSize * m_inChannels ; -- m_outStride = m_inSampleSize * m_outChannels; -- -- /* see if we need to normalize the levels */ -- bool dontnormalize = !CSettings::Get().GetBool("audiooutput.normalizelevels"); -- CLog::Log(LOGDEBUG, "CPCMRemap: Downmix normalization is %s", (dontnormalize ? "disabled" : "enabled")); -- -- ResolveChannels(); -- -- /* convert the levels into RMS values */ -- float loudest = 0.0; -- bool hasLoudest = false; -- -- for(out_ch = 0; out_ch < m_outChannels; ++out_ch) -- { -- float scale = 0; -- int count = 0; -- for(dst = m_lookupMap[m_outMap[out_ch]]; dst->channel != PCM_INVALID; ++dst) -- { -- dst->copy = false; -- dst->level = dst->level / sqrt((float)m_counts[dst->channel]); -- scale += dst->level; -- ++count; -- } -- -- /* if there is only 1 channel to mix, and the level is 1.0, then just copy the channel */ -- dst = m_lookupMap[m_outMap[out_ch]]; -- if (count == 1 && dst->level > 0.99 && dst->level < 1.01) -- dst->copy = true; -- -- /* normalize the levels if it is turned on */ -- if (!dontnormalize) -- for(dst = m_lookupMap[m_outMap[out_ch]]; dst->channel != PCM_INVALID; ++dst) -- { -- dst->level /= scale; -- /* find the loudest output level we have that is not 1-1 */ -- if (dst->level < 1.0 && loudest < dst->level) -- { -- loudest = dst->level; -- hasLoudest = true; -- } -- } -- } -- -- /* adjust the channels that are too loud */ -- for(out_ch = 0; out_ch < m_outChannels; ++out_ch) -- { -- CStdString s = "", f; -- for(dst = m_lookupMap[m_outMap[out_ch]]; dst->channel != PCM_INVALID; ++dst) -- { -- if (hasLoudest && dst->copy) -- { -- dst->level = loudest; -- dst->copy = false; -- } -- -- f = StringUtils::Format("%s(%f%s) ", PCMChannelStr(dst->channel).c_str(), dst->level, dst->copy ? "*" : ""); -- s += f; -- } -- CLog::Log(LOGDEBUG, "CPCMRemap: %s = %s\n", PCMChannelStr(m_outMap[out_ch]).c_str(), s.c_str()); -- } --} -- --void CPCMRemap::DumpMap(CStdString info, unsigned int channels, enum PCMChannels *channelMap) --{ -- if (channelMap == NULL) -- { -- CLog::Log(LOGINFO, "CPCMRemap: %s channel map: NULL", info.c_str()); -- return; -- } -- -- CStdString mapping; -- for(unsigned int i = 0; i < channels; ++i) -- mapping += ((i == 0) ? "" : ",") + PCMChannelStr(channelMap[i]); -- -- CLog::Log(LOGINFO, "CPCMRemap: %s channel map: %s\n", info.c_str(), mapping.c_str()); --} -- --void CPCMRemap::Reset() --{ -- m_inSet = false; -- m_outSet = false; -- Dispose(); --} -- --/* sets the input format, and returns the requested channel layout */ --enum PCMChannels *CPCMRemap::SetInputFormat(unsigned int channels, enum PCMChannels *channelMap, unsigned int sampleSize, unsigned int sampleRate, PCMLayout layout) --{ -- m_inChannels = channels; -- m_inSampleSize = sampleSize; -- m_sampleRate = sampleRate; -- m_inSet = channelMap != NULL; -- if (channelMap) -- memcpy(m_inMap, channelMap, sizeof(enum PCMChannels) * channels); -- -- /* get the audio layout, and count the channels in it */ -- m_channelLayout = layout; -- if (m_channelLayout >= PCM_MAX_LAYOUT) m_channelLayout = PCM_LAYOUT_2_0; -- -- -- DumpMap("I", channels, channelMap); -- BuildMap(); -- -- /* now remove the empty channels from PCMLayoutMap; -- * we don't perform upmixing so we want the minimum amount of those */ -- if (channelMap) { -- if (!m_outSet) -- ResolveChannels(); /* Do basic channel resolving to find out the empty channels; -- * If m_outSet == true, this was done already by BuildMap() above */ -- int i = 0; -- for (enum PCMChannels *chan = PCMLayoutMap[m_channelLayout]; *chan != PCM_INVALID; ++chan) -- if (m_lookupMap[*chan][0].channel != PCM_INVALID) { -- /* something is mapped here, so add the channel */ -- m_layoutMap[i++] = *chan; -- } -- m_layoutMap[i] = PCM_INVALID; -- } else -- memcpy(m_layoutMap, PCMLayoutMap[m_channelLayout], sizeof(PCMLayoutMap[m_channelLayout])); -- -- m_attenuation = 1.0; -- m_attenuationInc = 1.0; -- m_holdCounter = 0; -- -- return m_layoutMap; --} -- --/* sets the output format supported by the audio renderer */ --void CPCMRemap::SetOutputFormat(unsigned int channels, enum PCMChannels *channelMap, bool ignoreLayout/* = false */) --{ -- m_outChannels = channels; -- m_outSet = channelMap != NULL; -- m_ignoreLayout = ignoreLayout; -- if (channelMap) -- memcpy(m_outMap, channelMap, sizeof(enum PCMChannels) * channels); -- -- DumpMap("O", channels, channelMap); -- BuildMap(); -- -- m_attenuation = 1.0; -- m_attenuationInc = 1.0; -- m_holdCounter = 0; --} -- --#if 0 --void CPCMRemap::Remap(void *data, void *out, unsigned int samples, long drc) --{ -- float gain = 1.0f; -- if (drc > 0) -- gain = pow(10.0f, (float)drc / 2000.0f); -- -- Remap(data, out, samples, gain); --} -- --/* remap the supplied data into out, which must be pre-allocated */ --void CPCMRemap::Remap(void *data, void *out, unsigned int samples, float gain /*= 1.0f*/) --{ -- CheckBufferSize(samples * m_outChannels * sizeof(float)); -- -- //set output buffer to 0 -- memset(out, 0, samples * m_outChannels * m_inSampleSize); -- -- //set intermediate buffer to 0 -- memset(m_buf, 0, m_bufsize); -- -- ProcessInput(data, out, samples, gain); -- AddGain(m_buf, samples * m_outChannels, gain); -- ProcessLimiter(samples, gain); -- ProcessOutput(out, samples, gain); --} -- --void CPCMRemap::CheckBufferSize(int size) --{ -- if (m_bufsize < size) -- { -- m_bufsize = size; -- m_buf = (float*)realloc(m_buf, m_bufsize); -- } --} -- --void CPCMRemap::ProcessInput(void* data, void* out, unsigned int samples, float gain) --{ -- for (unsigned int ch = 0; ch < m_outChannels; ch++) -- { -- struct PCMMapInfo *info = m_lookupMap[m_outMap[ch]]; -- if (info->channel == PCM_INVALID) -- continue; -- -- if (info->copy && gain == 1.0f) //do direct copy -- { -- uint8_t* src = (uint8_t*)data + info->in_offset; -- uint8_t* dst = (uint8_t*)out + ch * m_inSampleSize; -- uint8_t* dstend = dst + samples * m_outStride; -- while (dst != dstend) -- { -- *(int16_t*)dst = *(int16_t*)src; -- src += m_inStride; -- dst += m_outStride; -- } -- } -- else //needs some volume change or mixing, put into intermediate buffer -- { -- for(; info->channel != PCM_INVALID; info++) -- { -- uint8_t* src = (uint8_t*)data + info->in_offset; -- float* dst = m_buf + ch; -- float* dstend = dst + samples * m_outChannels; -- while (dst != dstend) -- { -- *dst += (float)(*(int16_t*)src) * info->level; -- src += m_inStride; -- dst += m_outChannels; -- } -- } -- } -- } --} -- --void CPCMRemap::AddGain(float* buf, unsigned int samples, float gain) --{ -- if (gain != 1.0f) //needs a gain change -- { -- float* ptr = m_buf; -- float* end = m_buf + samples; -- while (ptr != end) -- *(ptr++) *= gain; -- } --} -- --void CPCMRemap::ProcessLimiter(unsigned int samples, float gain) --{ -- //check total gain for each output channel -- float highestgain = 1.0f; -- for (unsigned int ch = 0; ch < m_outChannels; ch++) -- { -- struct PCMMapInfo *info = m_lookupMap[m_outMap[ch]]; -- if (info->channel == PCM_INVALID) -- continue; -- -- float chgain = 0.0f; -- for(; info->channel != PCM_INVALID; info++) -- chgain += info->level * gain; -- -- if (chgain > highestgain) -- highestgain = chgain; -- } -- -- m_attenuationMin = 1.0f; -- -- //if one of the channels can clip, enable a limiter -- if (highestgain > 1.0001f) -- { -- m_attenuationMin = m_attenuation; -- -- if (!m_limiterEnabled) -- { -- CLog::Log(LOGDEBUG, "CPCMRemap:: max gain: %f, enabling limiter", highestgain); -- m_limiterEnabled = true; -- } -- -- for (unsigned int i = 0; i < samples; i++) -- { -- //for each collection of samples, get the highest absolute value -- float maxAbs = 0.0f; -- for (unsigned int outch = 0; outch < m_outChannels; outch++) -- { -- float absval = fabs(m_buf[i * m_outChannels + outch]) / 32768.0f; -- if (maxAbs < absval) -- maxAbs = absval; -- } -- -- //if attenuatedAbs is higher than 1.0f, audio is clipping -- float attenuatedAbs = maxAbs * m_attenuation; -- if (attenuatedAbs > 1.0f) -- { -- //set m_attenuation so that m_attenuation * sample is the maximum output value -- m_attenuation = 1.0f / maxAbs; -- if (m_attenuation < m_attenuationMin) -- m_attenuationMin = m_attenuation; -- //value to add to m_attenuation to make it 1.0f -- m_attenuationInc = 1.0f - m_attenuation; -- //amount of samples to hold m_attenuation -- m_holdCounter = MathUtils::round_int(m_sampleRate * g_advancedSettings.m_limiterHold); -- } -- else if (m_attenuation < 1.0f && attenuatedAbs > 0.95f) -- { -- //if we're attenuating and we get within 5% of clipping, hold m_attenuation -- m_attenuationInc = 1.0f - m_attenuation; -- m_holdCounter = MathUtils::round_int(m_sampleRate * g_advancedSettings.m_limiterHold); -- } -- -- //apply attenuation -- for (unsigned int outch = 0; outch < m_outChannels; outch++) -- m_buf[i * m_outChannels + outch] *= m_attenuation; -- -- if (m_holdCounter) -- { -- //hold m_attenuation -- m_holdCounter--; -- } -- else if (m_attenuationInc > 0.0f) -- { -- //move m_attenuation to 1.0 in g_advancedSettings.m_limiterRelease seconds -- m_attenuation += m_attenuationInc / m_sampleRate / g_advancedSettings.m_limiterRelease; -- if (m_attenuation > 1.0f) -- { -- m_attenuation = 1.0f; -- m_attenuationInc = 0.0f; -- } -- } -- } -- } -- else -- { -- if (m_limiterEnabled) -- { -- CLog::Log(LOGDEBUG, "CPCMRemap:: max gain: %f, disabling limiter", highestgain); -- m_limiterEnabled = false; -- } -- -- //reset the limiter -- m_attenuation = 1.0f; -- m_attenuationInc = 0.0f; -- m_holdCounter = 0; -- } --} -- --void CPCMRemap::ProcessOutput(void* out, unsigned int samples, float gain) --{ -- //copy from intermediate buffer to output -- for (unsigned int ch = 0; ch < m_outChannels; ch++) -- { -- struct PCMMapInfo *info = m_lookupMap[m_outMap[ch]]; -- if (info->channel == PCM_INVALID) -- continue; -- -- if (!info->copy || gain != 1.0f) -- { -- float* src = m_buf + ch; -- uint8_t* dst = (uint8_t*)out + ch * m_inSampleSize; -- uint8_t* dstend = dst + samples * m_outStride; -- -- while(dst != dstend) -- { -- *(int16_t*)dst = MathUtils::round_int(std::min(std::max(*src, (float)INT16_MIN), (float)INT16_MAX)); -- src += m_outChannels; -- dst += m_outStride; -- } -- } -- } --} -- --bool CPCMRemap::CanRemap() --{ -- return (m_inSet && m_outSet); --} -- --int CPCMRemap::InBytesToFrames(int bytes) --{ -- return bytes / m_inSampleSize / m_inChannels; --} -- --int CPCMRemap::FramesToOutBytes(int frames) --{ -- return frames * m_inSampleSize * m_outChannels; --} -- --int CPCMRemap::FramesToInBytes(int frames) --{ -- return frames * m_inSampleSize * m_inChannels; --} --#endif --CStdString CPCMRemap::PCMChannelStr(enum PCMChannels ename) --{ -- const char* PCMChannelName[] = -- { -- "FL", -- "FR", -- "CE", -- "LFE", -- "BL", -- "BR", -- "FLOC", -- "FROC", -- "BC", -- "SL", -- "SR", -- "TFL", -- "TFR", -- "TFC", -- "TC", -- "TBL", -- "TBR", -- "TBC" -- }; -- -- int namepos = (int)ename; -- CStdString namestr; -- -- if (namepos < 0 || namepos >= (int)(sizeof(PCMChannelName) / sizeof(const char*))) -- namestr = StringUtils::Format("UNKNOWN CHANNEL:%i", namepos); -- else -- namestr = PCMChannelName[namepos]; -- -- return namestr; --} --#if 0 --CStdString CPCMRemap::PCMLayoutStr(enum PCMLayout ename) --{ -- const char* PCMLayoutName[] = -- { -- "2.0", -- "2.1", -- "3.0", -- "3.1", -- "4.0", -- "4.1", -- "5.0", -- "5.1", -- "7.0", -- "7.1" -- }; -- -- int namepos = (int)ename; -- CStdString namestr; -- -- if (namepos < 0 || namepos >= (int)(sizeof(PCMLayoutName) / sizeof(const char*))) -- namestr.Format("UNKNOWN LAYOUT:%i", namepos); -- else -- namestr = PCMLayoutName[namepos]; -- -- return namestr; --} --#endif -- -- --void CPCMRemap::GetDownmixMatrix(float *downmix) --{ -- for (int i=0; i<8*8; i++) -- downmix[i] = 0.0f; -- -- for (unsigned int ch = 0; ch < m_outChannels; ch++) -- { -- struct PCMMapInfo *info = m_lookupMap[m_outMap[ch]]; -- if (info->channel == PCM_INVALID) -- continue; -- -- for(; info->channel != PCM_INVALID; info++) -- downmix[8*ch + (info->in_offset>>1)] = info->level; -- } --} -diff --git a/xbmc/cores/omxplayer/PCMRemap.h b/xbmc/cores/omxplayer/PCMRemap.h -deleted file mode 100644 -index a273cd1..0000000 ---- a/xbmc/cores/omxplayer/PCMRemap.h -+++ /dev/null -@@ -1,151 +0,0 @@ --#ifndef __PCM_REMAP__H__ --#define __PCM_REMAP__H__ -- --/* -- * Copyright (C) 2005-2010 Team XBMC -- * http://xbmc.org -- * -- * This Program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License as published by -- * the Free Software Foundation; either version 2, or (at your option) -- * any later version. -- * -- * This Program 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 General Public License for more details. -- * -- * You should have received a copy of the GNU General Public License -- * along with XBMC; see the file COPYING. If not, write to -- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. -- * http://www.gnu.org/copyleft/gpl.html -- * -- */ -- --#include --#include --#include "utils/StdString.h" -- --#define PCM_MAX_CH 18 --enum PCMChannels --{ -- PCM_INVALID = -1, -- PCM_FRONT_LEFT, -- PCM_FRONT_RIGHT, -- PCM_FRONT_CENTER, -- PCM_LOW_FREQUENCY, -- PCM_BACK_LEFT, -- PCM_BACK_RIGHT, -- PCM_FRONT_LEFT_OF_CENTER, -- PCM_FRONT_RIGHT_OF_CENTER, -- PCM_BACK_CENTER, -- PCM_SIDE_LEFT, -- PCM_SIDE_RIGHT, -- PCM_TOP_FRONT_LEFT, -- PCM_TOP_FRONT_RIGHT, -- PCM_TOP_FRONT_CENTER, -- PCM_TOP_CENTER, -- PCM_TOP_BACK_LEFT, -- PCM_TOP_BACK_RIGHT, -- PCM_TOP_BACK_CENTER --}; -- --#define PCM_MAX_LAYOUT 10 --enum PCMLayout --{ -- PCM_LAYOUT_2_0 = 0, -- PCM_LAYOUT_2_1, -- PCM_LAYOUT_3_0, -- PCM_LAYOUT_3_1, -- PCM_LAYOUT_4_0, -- PCM_LAYOUT_4_1, -- PCM_LAYOUT_5_0, -- PCM_LAYOUT_5_1, -- PCM_LAYOUT_7_0, -- PCM_LAYOUT_7_1 --}; -- --struct PCMMapInfo --{ -- enum PCMChannels channel; -- float level; -- bool ifExists; -- int in_offset; -- bool copy; --}; -- --//! Channels remapper class --/*! -- The usual set-up process: -- - user calls SetInputFormat with the input channels information -- - SetInputFormat responds with a channelmap corresponding to the speaker -- layout that the user has configured, with empty (according to information -- calculated from the input channelmap) channels removed -- - user uses this information to create the desired output channelmap, -- and calls SetOutputFormat to set it (if the channelmap contains channels -- that do not exist in the configured speaker layout, they will contain -- only silence unless ignoreLayout is true) -- */ -- --class CPCMRemap --{ --protected: -- bool m_inSet, m_outSet; -- enum PCMLayout m_channelLayout; -- unsigned int m_inChannels, m_outChannels; -- unsigned int m_inSampleSize; -- enum PCMChannels m_inMap [PCM_MAX_CH]; -- enum PCMChannels m_outMap[PCM_MAX_CH]; -- enum PCMChannels m_layoutMap[PCM_MAX_CH + 1]; -- -- bool m_ignoreLayout; -- bool m_useable [PCM_MAX_CH]; -- int m_inStride, m_outStride; -- struct PCMMapInfo m_lookupMap[PCM_MAX_CH + 1][PCM_MAX_CH + 1]; -- int m_counts[PCM_MAX_CH]; -- -- float* m_buf; -- int m_bufsize; -- float m_attenuation; -- float m_attenuationInc; -- float m_attenuationMin; //lowest attenuation value during a call of Remap(), used for the codec info -- float m_sampleRate; -- unsigned int m_holdCounter; -- bool m_limiterEnabled; -- bool m_dontnormalize; -- -- struct PCMMapInfo* ResolveChannel(enum PCMChannels channel, float level, bool ifExists, std::vector path, struct PCMMapInfo *tablePtr); -- void ResolveChannels(); //!< Partial BuildMap(), just enough to see which output channels are active -- void BuildMap(); -- void DumpMap(CStdString info, int unsigned channels, enum PCMChannels *channelMap); -- void Dispose(); -- CStdString PCMChannelStr(enum PCMChannels ename); -- CStdString PCMLayoutStr(enum PCMLayout ename); -- -- void CheckBufferSize(int size); -- void ProcessInput(void* data, void* out, unsigned int samples, float gain); -- void AddGain(float* buf, unsigned int samples, float gain); -- void ProcessLimiter(unsigned int samples, float gain); -- void ProcessOutput(void* out, unsigned int samples, float gain); -- --public: -- -- CPCMRemap(); -- ~CPCMRemap(); -- -- void Reset(); -- enum PCMChannels *SetInputFormat (unsigned int channels, enum PCMChannels *channelMap, unsigned int sampleSize, unsigned int sampleRate, PCMLayout layout); -- void SetOutputFormat(unsigned int channels, enum PCMChannels *channelMap, bool ignoreLayout = false); --#if 0 -- void Remap(void *data, void *out, unsigned int samples, long drc); -- void Remap(void *data, void *out, unsigned int samples, float gain = 1.0f); -- bool CanRemap(); -- int InBytesToFrames (int bytes ); -- int FramesToOutBytes(int frames); -- int FramesToInBytes (int frames); --#endif -- float GetCurrentAttenuation() { return m_attenuationMin; } -- void GetDownmixMatrix(float *downmix); --}; -- --#endif -diff --git a/xbmc/linux/OMXCore.h b/xbmc/linux/OMXCore.h -index 2f1e8a9..b4c8626 100644 ---- a/xbmc/linux/OMXCore.h -+++ b/xbmc/linux/OMXCore.h -@@ -48,8 +48,6 @@ - (a).nVersion.s.nRevision = OMX_VERSION_REVISION; \ - (a).nVersion.s.nStep = OMX_VERSION_STEP - --#include "libavformat/avformat.h" -- - #define OMX_MAX_PORTS 10 - - typedef struct omx_event { --- -1.9.3 - - -From 87cba44d0bded01df56064376c285b978fbfde9c Mon Sep 17 00:00:00 2001 +From 7f768c96219c9639a68e36c473ff62271ad55fca Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sun, 30 Mar 2014 15:54:34 +0100 -Subject: [PATCH 48/83] [omxplayer] Make the sharpness control act as a +Subject: [PATCH 44/89] [omxplayer] Make the sharpness control act as a sharpness control. This fixes scaling kernel as Mitchell Netravali, and varies sharpness over range B=[5/3,0] C=[-1/3,1/2] @@ -11600,7 +8820,7 @@ This fixes scaling kernel as Mitchell Netravali, and varies sharpness over range 1 file changed, 338 insertions(+) diff --git a/xbmc/cores/omxplayer/OMXPlayer.cpp b/xbmc/cores/omxplayer/OMXPlayer.cpp -index 502df4a..f16743d 100644 +index 49e0fed..12e887e 100644 --- a/xbmc/cores/omxplayer/OMXPlayer.cpp +++ b/xbmc/cores/omxplayer/OMXPlayer.cpp @@ -1051,6 +1051,334 @@ bool COMXPlayer::IsBetterStream(COMXCurrentStream& current, CDemuxStream* stream @@ -11961,7 +9181,7 @@ index 502df4a..f16743d 100644 m_video_fifo = (int)(100.0*(m_omxPlayerVideo.GetDecoderBufferSize()-m_omxPlayerVideo.GetDecoderFreeSpace())/m_omxPlayerVideo.GetDecoderBufferSize()); m_audio_fifo = (int)(100.0*audio_fifo/m_omxPlayerAudio.GetCacheTotal()); -@@ -4569,6 +4906,7 @@ void COMXPlayer::GetRenderFeatures(std::vector &renderFeatures) +@@ -4577,6 +4914,7 @@ void COMXPlayer::GetRenderFeatures(std::vector &renderFeatures) renderFeatures.push_back(RENDERFEATURE_CROP); renderFeatures.push_back(RENDERFEATURE_PIXEL_RATIO); renderFeatures.push_back(RENDERFEATURE_ZOOM); @@ -11973,10 +9193,10 @@ index 502df4a..f16743d 100644 1.9.3 -From e2ebab58d5abbc4befbd2223d33f984017ee84c2 Mon Sep 17 00:00:00 2001 +From a3f2a1afe63778523e250eb5d21a78d6b16bdce4 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 16 Apr 2014 21:18:06 +0100 -Subject: [PATCH 49/83] [omxplayer] Don't propagate 3d flags based on supported +Subject: [PATCH 45/89] [omxplayer] Don't propagate 3d flags based on supported 3d modes --- @@ -12032,10 +9252,10 @@ index 2fdbe18..e6bf2d0 100644 1.9.3 -From 56f27ce396000a153db0f646eff916061dc84b9f Mon Sep 17 00:00:00 2001 +From 8c871c98822e3aa6a25cb8f7103e53473b8aa262 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Thu, 17 Apr 2014 13:00:52 +0100 -Subject: [PATCH 50/83] [graphics] Don't set stereo mode based on resolution +Subject: [PATCH 46/89] [graphics] Don't set stereo mode based on resolution The resolution change should follow stereo mode --- @@ -12079,10 +9299,10 @@ index 5bffdf5..7e4fdd4 100644 1.9.3 -From bdfec31b0077901e7fcc89bae6769400b4919487 Mon Sep 17 00:00:00 2001 +From cc4d72c935c8a9066bc0b5fbc6f41bd273531381 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Thu, 17 Apr 2014 13:01:51 +0100 -Subject: [PATCH 51/83] [graphics] Allow switching to a more suitable 3D +Subject: [PATCH 47/89] [graphics] Allow switching to a more suitable 3D resolution --- @@ -12172,10 +9392,10 @@ index 0a27643..df55e92 100644 1.9.3 -From c5feb5ea893de36563d2d161a757b38fa7f8de25 Mon Sep 17 00:00:00 2001 +From ca8b44667409ab2c39aa284e7cf2c81b53559e6a Mon Sep 17 00:00:00 2001 From: popcornmix Date: Thu, 17 Apr 2014 13:38:55 +0100 -Subject: [PATCH 52/83] [3D] Support switching to 3D resolutions +Subject: [PATCH 48/89] [3D] Support switching to 3D resolutions Include matching 3D flags (SBS/TAB) in the score of a resolution to switch to, to enable switching to 3d modes. Also remove the old code that treated 3D modes differently when assigning a score. @@ -12260,10 +9480,10 @@ index 83c3adb..8076e76 100644 1.9.3 -From d05fd0d1ca93a0c5dd99652913718e85b335dac9 Mon Sep 17 00:00:00 2001 +From 3e81f718f47703c5349612224e1c87eee545da5f Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 23 Apr 2014 00:05:07 +0100 -Subject: [PATCH 53/83] [graphics] Make pixel ratio for 3d modes consistent +Subject: [PATCH 49/89] [graphics] Make pixel ratio for 3d modes consistent Note: Use the stored stereo flags from lists of resolutions. Use current stereo mode for current resolution. @@ -12451,10 +9671,10 @@ index 90b57e1..5b26b20 100644 1.9.3 -From 66cffa709e5f0e408723fbd665b562cec5d9d0da Mon Sep 17 00:00:00 2001 +From f015edb06b8e3e38cfa1f4ed9594a55fef76baf3 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 23 Apr 2014 21:07:51 +0100 -Subject: [PATCH 54/83] [PiSink] More attempts to reduce underrun audio +Subject: [PATCH 50/89] [PiSink] More attempts to reduce underrun audio glitches with multichannl and high samplerate --- @@ -12462,7 +9682,7 @@ Subject: [PATCH 54/83] [PiSink] More attempts to reduce underrun audio 1 file changed, 27 insertions(+), 46 deletions(-) diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp -index b6076f6..2c242d5 100644 +index 811ea0d..7c04919 100644 --- a/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp +++ b/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp @@ -186,7 +186,7 @@ bool CAESinkPi::Initialize(AEAudioFormat &format, std::string &device) @@ -12473,7 +9693,7 @@ index b6076f6..2c242d5 100644 + format.m_frames = format.m_sampleRate * AUDIO_PLAYBUFFER / NUM_OMX_BUFFERS; format.m_frameSamples = format.m_frames * channels; - SetAudioProps(m_passthrough, GetChannelMap(format.m_channelLayout, m_passthrough)); + SetAudioProps(m_passthrough, GetChannelMap(format, m_passthrough)); @@ -232,7 +232,7 @@ bool CAESinkPi::Initialize(AEAudioFormat &format, std::string &device) CLog::Log(LOGERROR, "%s:%s - error get OMX_IndexParamPortDefinition (input) omx_err(0x%08x)", CLASSNAME, __func__, omx_err); @@ -12572,10 +9792,10 @@ index b6076f6..2c242d5 100644 1.9.3 -From a3f259f1884b439a5feb850d3fb36389082e1c3b Mon Sep 17 00:00:00 2001 +From 442f5394004b4ffe2ef43b5b39de4f027a30247a Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 22 Apr 2014 12:23:23 +0100 -Subject: [PATCH 55/83] [omxplayer] Make dvdplayer the default for dvd images +Subject: [PATCH 51/89] [omxplayer] Make dvdplayer the default for dvd images --- xbmc/cores/omxplayer/omxplayer_advancedsettings.xml | 2 +- @@ -12597,10 +9817,10 @@ index 77c6a15..51c0daf 100644 1.9.3 -From b2e7b8c1cb55efc7d1bfa8c9bbc5b4f071672ba0 Mon Sep 17 00:00:00 2001 +From aae984c26dff1d07a0746d27503f67697687be8a Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sat, 26 Apr 2014 17:27:52 +0100 -Subject: [PATCH 56/83] [cec] Don't suspend pi on tv switch off - it can't wake +Subject: [PATCH 52/89] [cec] Don't suspend pi on tv switch off - it can't wake up --- @@ -12624,10 +9844,11 @@ index a906628..9b5271a 100644 1.9.3 -From 20c6601aa04d4130736e2d7236d9e6189a20c425 Mon Sep 17 00:00:00 2001 + +From 3349056f500bb499263f9e32eb16dea5f4cf2968 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Thu, 27 Jun 2013 01:25:57 +0100 -Subject: [PATCH 58/83] [rbp/omxplayer] Do we need discontinuity handling? +Subject: [PATCH 54/89] [rbp/omxplayer] Do we need discontinuity handling? So far I've not seen what this is needed for and it does cause problems for some files. --- @@ -12635,7 +9856,7 @@ So far I've not seen what this is needed for and it does cause problems for some 1 file changed, 1 insertion(+) diff --git a/xbmc/cores/omxplayer/OMXPlayer.cpp b/xbmc/cores/omxplayer/OMXPlayer.cpp -index f16743d..92dd5c5 100644 +index 12e887e..a811169 100644 --- a/xbmc/cores/omxplayer/OMXPlayer.cpp +++ b/xbmc/cores/omxplayer/OMXPlayer.cpp @@ -2395,6 +2395,7 @@ static void UpdateLimits(double& minimum, double& maximum, double dts) @@ -12650,10 +9871,10 @@ index f16743d..92dd5c5 100644 1.9.3 -From 552b46dc19c1fd48b148d61fb5defb5775edd125 Mon Sep 17 00:00:00 2001 +From ed3334648bb82a6c0a5b7afd301201a4fca91b88 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Thu, 24 Oct 2013 00:53:26 +0100 -Subject: [PATCH 59/83] [rbp/omxplayer] Avoid marking non-monotonic timestamps +Subject: [PATCH 55/89] [rbp/omxplayer] Avoid marking non-monotonic timestamps as unknown Following a single spurious timestamp that is in the future, @@ -12695,10 +9916,10 @@ index 353e00e..90a02e1 100644 1.9.3 -From 565ada072fe56007b4b8bbd38071611aa0674e3f Mon Sep 17 00:00:00 2001 +From 51c7cf0d9367497492a041ca04c8df7c1baca488 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 13 Dec 2013 16:25:23 +0000 -Subject: [PATCH 61/83] Add time taken to resample to log +Subject: [PATCH 57/89] Add time taken to resample to log --- xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp | 7 +++++++ @@ -12706,10 +9927,10 @@ Subject: [PATCH 61/83] Add time taken to resample to log 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp -index c9bbfce..650eabe 100644 +index 2f71051..ce74b9d 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp -@@ -2558,7 +2558,14 @@ void CActiveAE::ResampleSounds() +@@ -2586,7 +2586,14 @@ void CActiveAE::ResampleSounds() { if (!(*it)->IsConverted()) { @@ -12742,10 +9963,10 @@ index 9324e1e..4405f66 100644 1.9.3 -From 71ec03a017771950422a1a556ade1c330559995e Mon Sep 17 00:00:00 2001 +From b9065f508525a5a768d0fee6ffcd28cc0d44dfd2 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sat, 14 Dec 2013 16:55:05 +0000 -Subject: [PATCH 62/83] logging: Add microsecond timer to log messages +Subject: [PATCH 58/89] logging: Add microsecond timer to log messages --- xbmc/utils/log.cpp | 12 +++++++++--- @@ -12806,10 +10027,10 @@ index 6d7c6c8..45f68bc 100644 1.9.3 -From cba9612be7f3e763ea2405cab0f93e21df642b4d Mon Sep 17 00:00:00 2001 +From 0b3a3f4f2e347da05b5f8f39d14c47f86a569ae6 Mon Sep 17 00:00:00 2001 From: Jonathan Marshall Date: Sat, 2 Nov 2013 23:49:17 +1300 -Subject: [PATCH 63/83] adds GetTvShowSeasons +Subject: [PATCH 59/89] adds GetTvShowSeasons --- xbmc/video/VideoDatabase.cpp | 30 ++++++++++++++++++++++++------ @@ -12888,10 +10109,10 @@ index 7bf6d85..80334c6 100644 1.9.3 -From d06cff694c9333957485172b005d0c7ed59a60b8 Mon Sep 17 00:00:00 2001 +From 01f98a6f80e1c01433d447ee4cd54c8dc2db4d9f Mon Sep 17 00:00:00 2001 From: Jonathan Marshall Date: Sat, 2 Nov 2013 23:50:10 +1300 -Subject: [PATCH 64/83] move AddSeason() public. +Subject: [PATCH 60/89] move AddSeason() public. --- xbmc/video/VideoDatabase.h | 2 +- @@ -12921,10 +10142,10 @@ index 80334c6..a519620 100644 1.9.3 -From 18c5cd06653c4b04a294b7f9332b2ef0d6a32523 Mon Sep 17 00:00:00 2001 +From d93ba73a9cc70353383b00e52c9226f9602a9179 Mon Sep 17 00:00:00 2001 From: Jonathan Marshall Date: Sat, 2 Nov 2013 23:48:24 +1300 -Subject: [PATCH 65/83] adds GetArt function to (video) scraper, allowing art +Subject: [PATCH 61/89] adds GetArt function to (video) scraper, allowing art to be fetched given the video identifier. --- @@ -13042,10 +10263,10 @@ index 22ac229..75bc341 100644 1.9.3 -From 3796ca7339a09d4a0a1b1af349754cc4cbdfe0ec Mon Sep 17 00:00:00 2001 +From a3064e84bd84d36d2dc54ea264c180c00394e902 Mon Sep 17 00:00:00 2001 From: Jonathan Marshall Date: Sat, 2 Nov 2013 23:53:14 +1300 -Subject: [PATCH 66/83] refresh season art if a new season is found that isn't +Subject: [PATCH 62/89] refresh season art if a new season is found that isn't recorded in the database yet. Fixes #14339 --- @@ -13054,10 +10275,10 @@ Subject: [PATCH 66/83] refresh season art if a new season is found that isn't 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/xbmc/video/VideoInfoScanner.cpp b/xbmc/video/VideoInfoScanner.cpp -index d755c52..76c0926 100644 +index f6ba0aa..1190994 100644 --- a/xbmc/video/VideoInfoScanner.cpp +++ b/xbmc/video/VideoInfoScanner.cpp -@@ -1312,6 +1312,10 @@ namespace VIDEO +@@ -1305,6 +1305,10 @@ namespace VIDEO pDlgProgress->Progress(); } @@ -13068,7 +10289,7 @@ index d755c52..76c0926 100644 EPISODELIST episodes; bool hasEpisodeGuide = false; -@@ -1360,6 +1364,8 @@ namespace VIDEO +@@ -1353,6 +1357,8 @@ namespace VIDEO } if (AddVideo(&item, CONTENT_TVSHOWS, file->isFolder, true, &showInfo) < 0) return INFO_ERROR; @@ -13077,7 +10298,7 @@ index d755c52..76c0926 100644 continue; } -@@ -1489,6 +1495,8 @@ namespace VIDEO +@@ -1482,6 +1488,8 @@ namespace VIDEO if (AddVideo(&item, CONTENT_TVSHOWS, file->isFolder, useLocal, &showInfo) < 0) return INFO_ERROR; @@ -13086,7 +10307,7 @@ index d755c52..76c0926 100644 } else { -@@ -1497,9 +1505,27 @@ namespace VIDEO +@@ -1490,9 +1498,27 @@ namespace VIDEO file->cDate.GetAsLocalizedDate().c_str(), file->strTitle.c_str()); } } @@ -13114,7 +10335,7 @@ index d755c52..76c0926 100644 CStdString CVideoInfoScanner::GetnfoFile(CFileItem *item, bool bGrabAny) const { CStdString nfoFile; -@@ -1720,6 +1746,11 @@ namespace VIDEO +@@ -1713,6 +1739,11 @@ namespace VIDEO } for (int season = -1; season <= maxSeasons; season++) { @@ -13126,7 +10347,7 @@ index d755c52..76c0926 100644 map art; if (useLocal) { -@@ -1773,7 +1804,7 @@ namespace VIDEO +@@ -1766,7 +1797,7 @@ namespace VIDEO art.insert(make_pair(artTypes.front(), image)); } @@ -13152,10 +10373,10 @@ index bb177d4..1ea47fd 100644 1.9.3 -From b9f5c90a5dfde49685dfadce0116e9dad83e76b1 Mon Sep 17 00:00:00 2001 +From d86fdb17e95ae8e2be8578146462a29511316e09 Mon Sep 17 00:00:00 2001 From: Jonathan Marshall Date: Sat, 2 Nov 2013 23:53:34 +1300 -Subject: [PATCH 67/83] REMOVEME: updated thetvdb.com scraper to support art +Subject: [PATCH 63/89] REMOVEME: updated thetvdb.com scraper to support art updates --- @@ -13163,7 +10384,7 @@ Subject: [PATCH 67/83] REMOVEME: updated thetvdb.com scraper to support art 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/addons/metadata.tvdb.com/tvdb.xml b/addons/metadata.tvdb.com/tvdb.xml -index 4e2cc2f..2636c56 100644 +index 39e604d..60a0e96 100644 --- a/addons/metadata.tvdb.com/tvdb.xml +++ b/addons/metadata.tvdb.com/tvdb.xml @@ -99,57 +99,74 @@ @@ -13266,20 +10487,20 @@ index 4e2cc2f..2636c56 100644 1.9.3 -From 69c7b73251f72a97cb41948b9b1f063c76ffddcd Mon Sep 17 00:00:00 2001 +From fe7a5c33226d1f6b933cdb9ea3e883d9cf11b87b Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sat, 22 Mar 2014 16:40:01 +0000 -Subject: [PATCH 68/83] Enable PYTHONOPTIMIZE for Pi +Subject: [PATCH 64/89] Enable PYTHONOPTIMIZE for Pi --- xbmc/interfaces/python/XBPython.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/xbmc/interfaces/python/XBPython.cpp b/xbmc/interfaces/python/XBPython.cpp -index 4cf0f93..9e326b9 100644 +index 0d6dabc..c3fd0f1 100644 --- a/xbmc/interfaces/python/XBPython.cpp +++ b/xbmc/interfaces/python/XBPython.cpp -@@ -436,6 +436,10 @@ bool XBPython::InitializeEngine() +@@ -462,6 +462,10 @@ bool XBPython::InitializeEngine() } #endif @@ -13294,10 +10515,10 @@ index 4cf0f93..9e326b9 100644 1.9.3 -From 84d396ca9db50be5adebefcbe048432f4eb28d33 Mon Sep 17 00:00:00 2001 +From 16797ed092fcc1905c1d4fc53bb32f0b3818d440 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 28 Apr 2014 18:07:45 +0100 -Subject: [PATCH 69/83] [rpi] Make ActiveAE thread higher priority to make +Subject: [PATCH 65/89] [rpi] Make ActiveAE thread higher priority to make audio underrun less likely --- @@ -13305,10 +10526,10 @@ Subject: [PATCH 69/83] [rpi] Make ActiveAE thread higher priority to make 1 file changed, 6 insertions(+) diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp -index 650eabe..5463d30 100644 +index ce74b9d..ddd9b62 100644 --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp -@@ -2116,6 +2116,12 @@ void CActiveAE::LoadSettings() +@@ -2144,6 +2144,12 @@ void CActiveAE::LoadSettings() bool CActiveAE::Initialize() { Create(); @@ -13325,10 +10546,10 @@ index 650eabe..5463d30 100644 1.9.3 -From de60fab11e6df3c0d0a7d8c4e533e96c60dbd910 Mon Sep 17 00:00:00 2001 +From 6728224020ef100d3f174bdd0160980a11a58f85 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 29 Apr 2014 15:23:22 +0100 -Subject: [PATCH 70/83] [ffmpeg] Speed up wtv index creation +Subject: [PATCH 66/89] [ffmpeg] Speed up wtv index creation The index creation is O(N^2) with number of entries (typically thousands). On a Pi this can take more than 60 seconds to execute for a recording of a few hours. @@ -13417,10 +10638,10 @@ index 0000000..8f5f989 1.9.3 -From 76730306b481bfe86d95990f61b9bd2a920db0c3 Mon Sep 17 00:00:00 2001 +From 6205db2bdb12c2d5152e7d6d7788b28e616985b2 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 29 Apr 2014 15:55:28 +0100 -Subject: [PATCH 71/83] [ffmpeg] vc-1: Optimise parser (with special attention +Subject: [PATCH 67/89] [ffmpeg] vc-1: Optimise parser (with special attention to ARM) Backport from upstream ffmpeg @@ -14777,10 +11998,10 @@ index f514ae6..863ee41 100644 1.9.3 -From f532f6417a5362ee606a1acc8bc4ff2cc0c8b9dd Mon Sep 17 00:00:00 2001 +From 1bc0721c1708086c3d8de6aabfd299e4c90b702b Mon Sep 17 00:00:00 2001 From: popcornmix Date: Tue, 29 Apr 2014 16:53:32 +0100 -Subject: [PATCH 72/83] [ffmpeg] truehd: Optimise with special attention to ARM +Subject: [PATCH 68/89] [ffmpeg] truehd: Optimise with special attention to ARM Backport from upstream ffmpeg --- @@ -16821,49 +14042,10 @@ index 863ee41..b56fbdd 100644 1.9.3 -From 53bb6354fe1ed383bd256544f6f38583b8aa7b8f Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 28 May 2014 15:50:17 +0100 -Subject: [PATCH 73/83] [omxplayer] Avoid hang when closing stream with clock - stopped - -Avoids a permanent hang at EOF when using IPTV streams ---- - xbmc/cores/omxplayer/OMXPlayer.cpp | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/xbmc/cores/omxplayer/OMXPlayer.cpp b/xbmc/cores/omxplayer/OMXPlayer.cpp -index 92dd5c5..d447bf6 100644 ---- a/xbmc/cores/omxplayer/OMXPlayer.cpp -+++ b/xbmc/cores/omxplayer/OMXPlayer.cpp -@@ -2583,9 +2583,6 @@ void COMXPlayer::OnExit() - { - CLog::Log(LOGNOTICE, "COMXPlayer::OnExit()"); - -- m_av_clock.OMXStop(); -- m_av_clock.OMXStateIdle(); -- - // set event to inform openfile something went wrong in case openfile is still waiting for this event - SetCaching(CACHESTATE_DONE); - -@@ -2639,6 +2636,9 @@ void COMXPlayer::OnExit() - - m_messenger.End(); - -+ m_av_clock.OMXStop(); -+ m_av_clock.OMXStateIdle(); -+ - m_av_clock.OMXDeinitialize(); - - } --- -1.9.3 - - -From 15fbd9378710804c18a4a2c037b0f68590e93a43 Mon Sep 17 00:00:00 2001 +From 744d4d773772c2af9edc6cfba3b9d59e55e3c4f3 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Sun, 11 May 2014 16:13:45 +0100 -Subject: [PATCH 74/83] [rbp] Add config.txt settings to log file +Subject: [PATCH 69/89] [rbp] Add config.txt settings to log file --- xbmc/linux/RBP.cpp | 8 +++++++- @@ -16896,18 +14078,18 @@ index 49dcbb8..9a5e9cb 100644 1.9.3 -From 19f9911b494592a11bad8c5be7e8cfcac758fc2a Mon Sep 17 00:00:00 2001 +From d381b3d99a6ed4a7ace3f0e772706e19723df0f7 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 12 May 2014 23:06:43 +0100 -Subject: [PATCH 77/83] [omxcodec] Updates to work better with dropping and +Subject: [PATCH 70/89] [omxcodec] Updates to work better with dropping and lateness detection --- .../DVDCodecs/Video/DVDVideoCodecOpenMax.cpp | 5 ++ .../DVDCodecs/Video/DVDVideoCodecOpenMax.h | 1 + - .../dvdplayer/DVDCodecs/Video/OpenMaxVideo.cpp | 95 ++++++++++++++++------ + .../dvdplayer/DVDCodecs/Video/OpenMaxVideo.cpp | 97 +++++++++++++++++----- .../cores/dvdplayer/DVDCodecs/Video/OpenMaxVideo.h | 9 +- - 4 files changed, 84 insertions(+), 26 deletions(-) + 4 files changed, 86 insertions(+), 26 deletions(-) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecOpenMax.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecOpenMax.cpp index ef10555..8323497 100644 @@ -16936,7 +14118,7 @@ index b7c0c1b..4f243df 100644 protected: OpenMaxVideoPtr m_omx_decoder; diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/OpenMaxVideo.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/OpenMaxVideo.cpp -index 71d19af..93cf521 100644 +index 71d19af..612ae21 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/OpenMaxVideo.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/OpenMaxVideo.cpp @@ -37,6 +37,7 @@ @@ -17088,7 +14270,7 @@ index 71d19af..93cf521 100644 return true; } -@@ -970,25 +990,54 @@ bool COpenMaxVideo::ClearPicture(DVDVideoPicture* pDvdVideoPicture) +@@ -970,25 +990,56 @@ bool COpenMaxVideo::ClearPicture(DVDVideoPicture* pDvdVideoPicture) return true; } @@ -17097,8 +14279,10 @@ index 71d19af..93cf521 100644 + pts = m_decoderPts; + droppedPics = m_droppedPics; + m_droppedPics = 0; ++#if defined(OMX_DEBUG_VERBOSE) + CLog::Log(LOGDEBUG, "%s::%s - pts:%.0f droppedPics:%d", CLASSNAME, __func__, pts, droppedPics); -+ return true; ++#endif ++ return true; +} + // DecoderFillBufferDone -- OpenMax output buffer has been filled @@ -17189,10 +14373,10 @@ index f234f6d..adf53b5 100644 1.9.3 -From f23ba67786b8012d1c05060425a2e4c5b3b6e599 Mon Sep 17 00:00:00 2001 +From 46bfdff20492a28bfead92407f5127c0f371c5ff Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 11 Apr 2014 16:12:27 +0100 -Subject: [PATCH 78/83] [omxplayer] Add ability to log more timestamp info in +Subject: [PATCH 71/89] [omxplayer] Add ability to log more timestamp info in extra debug settings --- @@ -17233,7 +14417,7 @@ index 4bf5d83..3fb7cc3 100644 #ifdef __GNUC__ #define ATTRIB_LOG_FORMAT __attribute__((format(printf,3,4))) diff --git a/xbmc/cores/omxplayer/OMXPlayer.cpp b/xbmc/cores/omxplayer/OMXPlayer.cpp -index d447bf6..cdcda0a 100644 +index a811169..d074dbe 100644 --- a/xbmc/cores/omxplayer/OMXPlayer.cpp +++ b/xbmc/cores/omxplayer/OMXPlayer.cpp @@ -1554,27 +1554,28 @@ void COMXPlayer::Process() @@ -17368,10 +14552,10 @@ index 6835504..fde4499 100644 1.9.3 -From 8236a7de50c86e427741d305f5a8d4c89c7c70fd Mon Sep 17 00:00:00 2001 +From 9d85c35229065258e6bb1af0fc268d4ea951b41f Mon Sep 17 00:00:00 2001 From: popcornmix Date: Mon, 7 Apr 2014 23:13:55 +0100 -Subject: [PATCH 79/83] [omxplayer] Add ability to dump out audio/video data +Subject: [PATCH 72/89] [omxplayer] Add ability to dump out audio/video data for later debugging --- @@ -17616,17 +14800,17 @@ index fde4499..06ef2ed 100644 1.9.3 -From 8d4871b75e87ff00e1fd7aba2a05b2d4a538e5da Mon Sep 17 00:00:00 2001 +From 7d7d653b54dad70e0b3d66cd59c6dfe02568ef12 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Wed, 28 May 2014 18:30:51 +0100 -Subject: [PATCH 80/83] [omxcodec] Reduce GPU memory use by 2 video frames +Subject: [PATCH 73/89] [omxcodec] Reduce GPU memory use by 2 video frames --- xbmc/cores/dvdplayer/DVDCodecs/Video/OpenMaxVideo.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Video/OpenMaxVideo.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Video/OpenMaxVideo.cpp -index 93cf521..cc45570 100644 +index 612ae21..494fdf5 100644 --- a/xbmc/cores/dvdplayer/DVDCodecs/Video/OpenMaxVideo.cpp +++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/OpenMaxVideo.cpp @@ -308,6 +308,20 @@ bool COpenMaxVideo::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options, OpenM @@ -17654,49 +14838,11 @@ index 93cf521..cc45570 100644 1.9.3 -From a80a70359765452af894617afdeb7813e5ff63bf Mon Sep 17 00:00:00 2001 -From: popcornmix -Date: Wed, 28 May 2014 23:44:11 +0100 -Subject: [PATCH 81/83] [omxplayer] Fix for mapping of multichannel PCM audio ---- - xbmc/cores/omxplayer/OMXAudio.cpp | 11 ++++++++--- - 1 file changed, 8 insertions(+), 3 deletions(-) - -diff --git a/xbmc/cores/omxplayer/OMXAudio.cpp b/xbmc/cores/omxplayer/OMXAudio.cpp -index bf26287..1bcc53e0 100644 ---- a/xbmc/cores/omxplayer/OMXAudio.cpp -+++ b/xbmc/cores/omxplayer/OMXAudio.cpp -@@ -651,13 +651,18 @@ bool COMXAudio::Initialize(AEAudioFormat format, OMXClock *clock, CDVDStreamInfo - if (m_InputChannels <= 2) - stdLayout = AE_CH_LAYOUT_2_0; - -- uint64_t m_dst_chan_layout = GetAVChannelLayout(stdLayout); -+ -+ CAEChannelInfo resolvedMap = channelMap; -+ resolvedMap.ResolveChannels(stdLayout); -+ uint64_t m_dst_chan_layout = GetAVChannelLayout(resolvedMap); - uint64_t m_src_chan_layout = GetAVChannelLayout(channelMap); -- m_OutputChannels = stdLayout.Count(); -+ -+ m_InputChannels = channelMap.Count(); -+ m_OutputChannels = resolvedMap.Count(); - - int m_dst_channels = m_OutputChannels; - int m_src_channels = m_InputChannels; -- SetAudioProps(m_Passthrough, GetChannelMap(stdLayout, m_Passthrough)); -+ SetAudioProps(m_Passthrough, GetChannelMap(resolvedMap, m_Passthrough)); - - CLog::Log(LOGINFO, "%s::%s remap:%p chan:%d->%d norm:%d upmix:%d %llx:%llx", CLASSNAME, __func__, remapLayout, m_src_channels, m_dst_channels, normalize, upmix, m_src_chan_layout, m_dst_chan_layout); - --- -1.9.3 - - -From 2da39ac18e7f8ac1cd49ffbab8785e652b1f884e Mon Sep 17 00:00:00 2001 +From 359f3fddb698e7d7ab00f090093b8ec2569367d0 Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 30 May 2014 14:15:10 +0100 -Subject: [PATCH 82/83] [pi] Fix for logged resolutions +Subject: [PATCH 75/89] [pi] Fix for logged resolutions --- xbmc/windowing/egl/EGLNativeTypeRaspberryPI.cpp | 15 +++++---------- @@ -17764,10 +14910,10 @@ index 5b26b20..a3edf0e 100644 1.9.3 -From 458a1742105636bdff0071957920e6e2b8c284a4 Mon Sep 17 00:00:00 2001 +From 4f9391a89a8d731122f4037b75910232bd87c12f Mon Sep 17 00:00:00 2001 From: popcornmix Date: Fri, 30 May 2014 14:58:43 +0100 -Subject: [PATCH 83/83] [settings] Experiment: Report DESKTOP resolution in +Subject: [PATCH 76/89] [settings] Experiment: Report DESKTOP resolution in video settings --- @@ -17791,3 +14937,1253 @@ index 246a047..0204839 100644 -- 1.9.3 + +From 4bd99d7fab956351e43bdbe70605a00f5c1298cd Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Sat, 7 Jun 2014 16:55:41 +0100 +Subject: [PATCH 77/89] [omx] Remove logging for texture jobs + +This causes a lot of log spam which hasn't proved useful so far. +--- + xbmc/cores/omxplayer/OMXImage.cpp | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/xbmc/cores/omxplayer/OMXImage.cpp b/xbmc/cores/omxplayer/OMXImage.cpp +index 262a004..d529b20 100644 +--- a/xbmc/cores/omxplayer/OMXImage.cpp ++++ b/xbmc/cores/omxplayer/OMXImage.cpp +@@ -210,13 +210,11 @@ bool COMXImage::SendMessage(bool (*callback)(EGLDisplay egl_display, EGLContext + mess.sync.Reset(); + { + CSingleLock lock(m_texqueue_lock); +- CLog::Log(LOGDEBUG, "%s: texture job: %p:%p", __func__, &mess, mess.callback); + m_texqueue.push(&mess); + m_texqueue_cond.notifyAll(); + } + // wait for function to have finished (in texture thread) + mess.sync.Wait(); +- CLog::Log(LOGDEBUG, "%s: texture job done: %p:%p = %d", __func__, &mess, mess.callback, mess.result); + // need to ensure texture thread has returned from mess.sync.Set() before we exit and free tex + CSingleLock lock(m_texqueue_lock); + return mess.result; +@@ -429,15 +427,12 @@ void COMXImage::Process() + struct callbackinfo *mess = m_texqueue.front(); + m_texqueue.pop(); + lock.Leave(); +- CLog::Log(LOGDEBUG, "%s: texture job: %p:%p:%p", __func__, mess, mess->callback, mess->cookie); + + mess->result = mess->callback(g_Windowing.GetEGLDisplay(), GetEGLContext(), mess->cookie); +- CLog::Log(LOGDEBUG, "%s: texture job about to Set: %p:%p:%p", __func__, mess, mess->callback, mess->cookie); + { + CSingleLock lock(m_texqueue_lock); + mess->sync.Set(); + } +- CLog::Log(LOGDEBUG, "%s: texture job: %p done", __func__, mess); + } + } + } +-- +1.9.3 + + +From a9cb967f2c0a6659ba6a13052ca82cb7b5ae421f Mon Sep 17 00:00:00 2001 +From: Matthias Kortstiege +Date: Sun, 1 Jun 2014 18:47:20 +0200 +Subject: [PATCH 78/89] changed: avoid useless filesytem io while searching for + subtitles + +--- + xbmc/Util.cpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/xbmc/Util.cpp b/xbmc/Util.cpp +index f614f17..d3bac54 100644 +--- a/xbmc/Util.cpp ++++ b/xbmc/Util.cpp +@@ -1980,7 +1980,7 @@ void CUtil::ScanForExternalSubtitles(const CStdString& strMovie, std::vector +Date: Wed, 4 Jun 2014 19:06:44 +0100 +Subject: [PATCH 84/89] AE: Skip visualisation resample when disabled + +--- + xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp +index ddd9b62..cc37b7f 100644 +--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp ++++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAE.cpp +@@ -1906,6 +1906,7 @@ bool CActiveAE::RunStages() + if (out) + { + // viz ++ if (!CSettings::Get().GetString("musicplayer.visualisation").empty()) + { + CSingleLock lock(m_vizLock); + if (m_audioCallback && m_vizBuffers && !m_streams.empty()) +-- +1.9.3 + + +From b2b5cff9eaf9145bfa12cfe33f770bae59093024 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Wed, 4 Jun 2014 19:10:27 +0100 +Subject: [PATCH 85/89] [pisink] Support planar formats + +--- + xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp | 35 ++++++++++++++++++++++++++----- + 1 file changed, 30 insertions(+), 5 deletions(-) + +diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp +index 7c04919..bf9cb7a 100644 +--- a/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp ++++ b/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp +@@ -180,7 +180,9 @@ bool CAESinkPi::Initialize(AEAudioFormat &format, std::string &device) + format.m_channelLayout = AE_CH_LAYOUT_2_0; + + // setup for a 50ms sink feed from SoftAE +- if (format.m_dataFormat != AE_FMT_FLOAT && format.m_dataFormat != AE_FMT_S32LE) ++ if (format.m_dataFormat != AE_FMT_FLOATP && format.m_dataFormat != AE_FMT_FLOAT && ++ format.m_dataFormat != AE_FMT_S32NE && format.m_dataFormat != AE_FMT_S32NEP && format.m_dataFormat != AE_FMT_S32LE && ++ format.m_dataFormat != AE_FMT_S16NE && format.m_dataFormat != AE_FMT_S16NEP && format.m_dataFormat != AE_FMT_S16LE) + format.m_dataFormat = AE_FMT_S16LE; + unsigned int channels = format.m_channelLayout.Count(); + unsigned int sample_size = CAEUtil::DataFormatToBits(format.m_dataFormat) >> 3; +@@ -210,7 +212,13 @@ bool CAESinkPi::Initialize(AEAudioFormat &format, std::string &device) + m_pcm_input.eEndian = OMX_EndianLittle; + m_pcm_input.bInterleaved = OMX_TRUE; + m_pcm_input.nBitPerSample = sample_size * 8; +- m_pcm_input.ePCMMode = m_format.m_dataFormat == AE_FMT_FLOAT ? (OMX_AUDIO_PCMMODETYPE)0x8000 : OMX_AUDIO_PCMModeLinear; ++ // 0x8000 = float, 0x10000 = planar ++ uint32_t flags = 0; ++ if (m_format.m_dataFormat == AE_FMT_FLOAT || m_format.m_dataFormat == AE_FMT_FLOATP) ++ flags |= 0x8000; ++ if (AE_IS_PLANAR(m_format.m_dataFormat)) ++ flags |= 0x10000; ++ m_pcm_input.ePCMMode = flags == 0 ? OMX_AUDIO_PCMModeLinear : (OMX_AUDIO_PCMMODETYPE)flags; + m_pcm_input.nChannels = channels; + m_pcm_input.nSamplingRate = m_format.m_sampleRate; + +@@ -308,14 +316,18 @@ double CAESinkPi::GetCacheTotal() + + unsigned int CAESinkPi::AddPackets(uint8_t **data, unsigned int frames, unsigned int offset) + { +- uint8_t *buffer = data[0]+offset*m_format.m_frameSize; +- + if (!m_Initialized || !frames) + return frames; + + OMX_ERRORTYPE omx_err = OMX_ErrorNone; + OMX_BUFFERHEADERTYPE *omx_buffer = NULL; + ++ unsigned int channels = m_format.m_channelLayout.Count(); ++ unsigned int sample_size = CAEUtil::DataFormatToBits(m_format.m_dataFormat) >> 3; ++ const int planes = AE_IS_PLANAR(m_format.m_dataFormat) ? channels : 1; ++ const int chans = AE_IS_PLANAR(m_format.m_dataFormat) ? 1 : channels; ++ const int pitch = chans * sample_size; ++ + double delay = GetDelay(); + if (delay <= 0.0 && m_submitted) + CLog::Log(LOGNOTICE, "%s:%s Underrun (delay:%.2f frames:%d)", CLASSNAME, __func__, delay, frames); +@@ -332,8 +344,13 @@ unsigned int CAESinkPi::AddPackets(uint8_t **data, unsigned int frames, unsigned + assert(omx_buffer->nFilledLen <= omx_buffer->nAllocLen); + omx_buffer->nTimeStamp = ToOMXTime(0); + omx_buffer->nFlags = OMX_BUFFERFLAG_ENDOFFRAME; +- memcpy(omx_buffer->pBuffer, buffer, omx_buffer->nFilledLen); + ++ if (omx_buffer->nFilledLen) ++ { ++ int planesize = omx_buffer->nFilledLen / planes; ++ for (int i=0; i < planes; i++) ++ memcpy((uint8_t *)omx_buffer->pBuffer + i * planesize, data[i] + offset * pitch, planesize); ++ } + omx_err = m_omx_render.EmptyThisBuffer(omx_buffer); + if (omx_err != OMX_ErrorNone) + CLog::Log(LOGERROR, "%s:%s frames=%d err=%x", CLASSNAME, __func__, frames, omx_err); +@@ -367,8 +384,13 @@ void CAESinkPi::EnumerateDevicesEx(AEDeviceInfoList &list, bool force) + for (unsigned int i=0; i +Date: Mon, 30 Dec 2013 12:02:14 +0000 +Subject: [PATCH 86/89] [rbp] Hardware accelerated resampling + +This replaces the format conversion, up/down mixing and resampling code from ActiveAE with a GPU accelerated version. +Should significantly reduce CPU when using paplayer or dvdplayer. + +Requires updated firmware +--- + .../Engines/ActiveAE/ActiveAEResample.cpp | 5 + + .../Engines/ActiveAE/ActiveAEResample.h | 8 + + .../Engines/ActiveAE/ActiveAEResamplePi.cpp | 601 +++++++++++++++++++++ + .../Engines/ActiveAE/ActiveAEResamplePi.h | 62 +++ + xbmc/cores/AudioEngine/Makefile.in | 1 + + xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp | 14 +- + xbmc/linux/OMXCore.cpp | 4 +- + 7 files changed, 686 insertions(+), 9 deletions(-) + create mode 100644 xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp + create mode 100644 xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.h + +diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.cpp +index 8250eef..972e1be 100644 +--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.cpp ++++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.cpp +@@ -18,6 +18,10 @@ + * + */ + ++#include "system.h" ++ ++#if !defined(TARGET_RASPBERRY_PI) ++ + #include "ActiveAEResample.h" + #include "utils/log.h" + +@@ -359,3 +363,4 @@ int CActiveAEResample::GetAVChannelIndex(enum AEChannel aechannel, uint64_t layo + { + return av_get_channel_layout_channel_index(layout, GetAVChannel(aechannel)); + } ++#endif +diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.h b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.h +index a471e02..5d37cc7 100644 +--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.h ++++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResample.h +@@ -19,6 +19,8 @@ + * + */ + ++#include "system.h" ++ + #include "cores/AudioEngine/Utils/AEChannelInfo.h" + #include "cores/AudioEngine/Utils/AEAudioFormat.h" + #include "cores/AudioEngine/Engines/ActiveAE/ActiveAEBuffer.h" +@@ -29,6 +31,10 @@ extern "C" { + #include "libswresample/swresample.h" + } + ++#if defined(TARGET_RASPBERRY_PI) ++#include "ActiveAEResamplePi.h" ++#else ++ + namespace ActiveAE + { + +@@ -63,3 +69,5 @@ class CActiveAEResample + }; + + } ++ ++#endif +diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp +new file mode 100644 +index 0000000..9a1e549 +--- /dev/null ++++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp +@@ -0,0 +1,601 @@ ++/* ++ * Copyright (C) 2010-2013 Team XBMC ++ * http://xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program 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 General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with XBMC; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#include "system.h" ++ ++#if defined(TARGET_RASPBERRY_PI) ++ ++#include "ActiveAEResample.h" ++#include "linux/RBP.h" ++#include "settings/Settings.h" ++#include "utils/log.h" ++ ++extern "C" { ++#include "libavutil/channel_layout.h" ++#include "libavutil/opt.h" ++#include "libswresample/swresample.h" ++} ++ ++//#define DEBUG_VERBOSE ++ ++#define CLASSNAME "CActiveAEResamplePi" ++ ++#define BUFFERSIZE (32*1024*2*8) ++ ++//#define BENCHMARKING ++#ifdef BENCHMARKING ++#define LOGTIMEINIT(f) \ ++ struct timespec now; \ ++ uint64_t Start, End; \ ++ clock_gettime(CLOCK_MONOTONIC, &now); \ ++ Start = ((int64_t)now.tv_sec * 1000000000L) + now.tv_nsec; \ ++ const char *_filename = f; ++ ++#define LOGTIME(n) \ ++ clock_gettime(CLOCK_MONOTONIC, &now); \ ++ End = ((int64_t)now.tv_sec * 1000000000L) + now.tv_nsec; \ ++ CLog::Log(LOGNOTICE, "ActiveAE::%s %d - resample %s took %.0fms", __FUNCTION__, n, _filename, (End-Start)*1e-6); \ ++ Start=End; ++#else ++#define LOGTIMEINIT(f) ++#define LOGTIME(n) ++#endif ++ ++using namespace ActiveAE; ++ ++CActiveAEResample::CActiveAEResample() ++{ ++ CLog::Log(LOGINFO, "%s::%s", CLASSNAME, __func__); ++ ++ m_Initialized = false; ++ m_last_src_fmt = AV_SAMPLE_FMT_NONE; ++ m_last_dst_fmt = AV_SAMPLE_FMT_NONE; ++ m_last_src_channels = 0; ++ m_last_dst_channels = 0; ++} ++ ++CActiveAEResample::~CActiveAEResample() ++{ ++ CLog::Log(LOGINFO, "%s::%s", CLASSNAME, __func__); ++ DeInit(); ++} ++ ++void CActiveAEResample::DeInit() ++{ ++ CLog::Log(LOGDEBUG, "%s:%s", CLASSNAME, __func__); ++ if (m_Initialized) ++ { ++ m_omx_mixer.FlushAll(); ++ m_omx_mixer.Deinitialize(); ++ m_Initialized = false; ++ } ++} ++ ++bool CActiveAEResample::Init(uint64_t dst_chan_layout, int dst_channels, int dst_rate, AVSampleFormat dst_fmt, int dst_bits, int dst_dither, uint64_t src_chan_layout, int src_channels, int src_rate, AVSampleFormat src_fmt, int src_bits, int src_dither, bool upmix, bool normalize, CAEChannelInfo *remapLayout, AEQuality quality) ++{ ++ LOGTIMEINIT("x"); ++ ++ CLog::Log(LOGINFO, "%s::%s remap:%p chan:%d->%d rate:%d->%d format:%d->%d bits:%d->%d norm:%d upmix:%d", CLASSNAME, __func__, remapLayout, src_channels, dst_channels, src_rate, dst_rate, src_fmt, dst_fmt, src_bits, dst_bits, normalize, upmix); ++ ++ if (src_bits == 0) ++ { ++ if (src_fmt == AV_SAMPLE_FMT_U8) src_bits = 8; ++ else if (src_fmt == AV_SAMPLE_FMT_S16) src_bits = 16; ++ else if (src_fmt == AV_SAMPLE_FMT_S32) src_bits = 32; ++ else if (src_fmt == AV_SAMPLE_FMT_FLT) src_bits = 32; ++ } ++ assert(src_bits && dst_bits); ++ ++ m_dst_chan_layout = dst_chan_layout; ++ m_dst_channels = dst_channels; ++ m_dst_rate = dst_rate; ++ m_dst_fmt = dst_fmt; ++ m_dst_bits = dst_bits; ++ m_src_chan_layout = src_chan_layout; ++ m_src_channels = src_channels; ++ m_src_rate = src_rate; ++ m_src_fmt = src_fmt; ++ m_src_bits = src_bits; ++ ++ if (m_dst_chan_layout == 0) ++ m_dst_chan_layout = av_get_default_channel_layout(m_dst_channels); ++ if (m_src_chan_layout == 0) ++ m_src_chan_layout = av_get_default_channel_layout(m_src_channels); ++ ++ OMX_CONFIG_BRCMAUDIODOWNMIXCOEFFICIENTS8x8 mix; ++ OMX_INIT_STRUCTURE(mix); ++ ++ assert(sizeof(mix.coeff)/sizeof(mix.coeff[0]) == 64); ++ ++ LOGTIME(1); ++// this code is just uses ffmpeg to produce the 8x8 mixing matrix ++{ ++ // dummy sample rate and format, as we only care about channel mapping ++ SwrContext *m_pContext = swr_alloc_set_opts(NULL, m_dst_chan_layout, AV_SAMPLE_FMT_FLT, 48000, ++ m_src_chan_layout, AV_SAMPLE_FMT_FLT, 48000, 0, NULL); ++ if (!m_pContext) ++ { ++ CLog::Log(LOGERROR, "CActiveAEResample::Init - create context failed"); ++ return false; ++ } ++ // tell resampler to clamp float values ++ // not required for sink stage (remapLayout == true) ++ if (!remapLayout && normalize) ++ { ++ av_opt_set_double(m_pContext, "rematrix_maxval", 1.0, 0); ++ } ++ ++ if (remapLayout) ++ { ++ // one-to-one mapping of channels ++ // remapLayout is the layout of the sink, if the channel is in our src layout ++ // the channel is mapped by setting coef 1.0 ++ double m_rematrix[AE_CH_MAX][AE_CH_MAX]; ++ memset(m_rematrix, 0, sizeof(m_rematrix)); ++ m_dst_chan_layout = 0; ++ for (unsigned int out=0; outCount(); out++) ++ { ++ m_dst_chan_layout += (uint64_t) (1 << out); ++ int idx = GetAVChannelIndex((*remapLayout)[out], m_src_chan_layout); ++ if (idx >= 0) ++ { ++ m_rematrix[out][idx] = 1.0; ++ } ++ } ++ ++ av_opt_set_int(m_pContext, "out_channel_count", m_dst_channels, 0); ++ av_opt_set_int(m_pContext, "out_channel_layout", m_dst_chan_layout, 0); ++ ++ if (swr_set_matrix(m_pContext, (const double*)m_rematrix, AE_CH_MAX) < 0) ++ { ++ CLog::Log(LOGERROR, "CActiveAEResample::Init - setting channel matrix failed"); ++ return false; ++ } ++ } ++ // stereo upmix ++ else if (upmix && m_src_channels == 2 && m_dst_channels > 2) ++ { ++ double m_rematrix[AE_CH_MAX][AE_CH_MAX]; ++ memset(m_rematrix, 0, sizeof(m_rematrix)); ++ for (int out=0; out%d (%.2f)", CLASSNAME, __func__, src_samples, dst_samples, ratio); ++ #endif ++ if (!m_Initialized) ++ return 0; ++ OMX_ERRORTYPE omx_err = OMX_ErrorNone; ++ ++ const int s_pitch = m_pcm_input.nChannels * m_src_bits >> 3; ++ const int d_pitch = m_pcm_output.nChannels * m_dst_bits >> 3; ++ int sent = 0; ++ int received = 0; ++ while (sent < src_samples) ++ { ++ OMX_BUFFERHEADERTYPE *omx_buffer = NULL; ++ OMX_BUFFERHEADERTYPE *m_encoded_buffer = NULL; ++ ++ omx_buffer = m_omx_mixer.GetInputBuffer(1000); ++ if (omx_buffer == NULL) ++ return false; ++ ++ const int max_src_samples = BUFFERSIZE / s_pitch; ++ const int max_dst_samples = (long long)(BUFFERSIZE/d_pitch) * m_src_rate / (m_dst_rate + m_src_rate-1); ++ int send = std::min(std::min(max_dst_samples, max_src_samples), src_samples - sent); ++ ++ omx_buffer->nOffset = 0; ++ omx_buffer->nFlags = OMX_BUFFERFLAG_EOS; ++ omx_buffer->nFilledLen = send * s_pitch; ++ ++ assert(omx_buffer->nFilledLen > 0 && omx_buffer->nFilledLen <= omx_buffer->nAllocLen); ++ ++ if (omx_buffer->nFilledLen) ++ { ++ memcpy(omx_buffer->pBuffer, src_buffer[0] + sent * s_pitch, omx_buffer->nFilledLen); ++ sent += send; ++ } ++ ++ omx_err = m_omx_mixer.EmptyThisBuffer(omx_buffer); ++ if (omx_err != OMX_ErrorNone) ++ { ++ CLog::Log(LOGERROR, "%s::%s OMX_EmptyThisBuffer() failed with result(0x%x)", CLASSNAME, __func__, omx_err); ++ return false; ++ } ++ ++ m_encoded_buffer = m_omx_mixer.GetOutputBuffer(); ++ ++ if (!m_encoded_buffer) ++ { ++ CLog::Log(LOGERROR, "%s::%s no output buffer", CLASSNAME, __func__); ++ return false; ++ } ++ ++ omx_err = m_omx_mixer.FillThisBuffer(m_encoded_buffer); ++ if (omx_err != OMX_ErrorNone) ++ return false; ++ ++ omx_err = m_omx_mixer.WaitForOutputDone(1000); ++ if (omx_err != OMX_ErrorNone) ++ { ++ CLog::Log(LOGERROR, "%s::%s m_omx_mixer.WaitForOutputDone result(0x%x)", CLASSNAME, __func__, omx_err); ++ return false; ++ } ++ assert(m_encoded_buffer->nFilledLen > 0 && m_encoded_buffer->nFilledLen <= m_encoded_buffer->nAllocLen); ++ ++ if (m_omx_mixer.BadState()) ++ { ++ CLog::Log(LOGERROR, "%s::%s m_omx_mixer.BadState", CLASSNAME, __func__); ++ return false; ++ } ++ ++ if (m_encoded_buffer->nFilledLen) ++ { ++ memcpy(dst_buffer[0] + received * d_pitch, m_encoded_buffer->pBuffer, m_encoded_buffer->nFilledLen); ++ received += m_encoded_buffer->nFilledLen / d_pitch; ++ } ++ } ++ #ifdef DEBUG_VERBOSE ++ CLog::Log(LOGINFO, "%s::%s format:%d->%d rate:%d->%d chan:%d->%d samples %d->%d (%f) %d =%d", CLASSNAME, __func__, ++ (int)m_src_fmt, (int)m_dst_fmt, m_src_rate, m_dst_rate, m_src_channels, m_dst_channels, src_samples, dst_samples, ratio, m_Initialized, received); ++ #endif ++ return received; ++} ++ ++int64_t CActiveAEResample::GetDelay(int64_t base) ++{ ++ int ret = 0; ++ #ifdef DEBUG_VERBOSE ++ CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, ret); ++ #endif ++ return ret; ++} ++ ++int CActiveAEResample::GetBufferedSamples() ++{ ++ int ret = 0; ++ #ifdef DEBUG_VERBOSE ++ CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, ret); ++ #endif ++ return ret; ++} ++ ++int CActiveAEResample::CalcDstSampleCount(int src_samples, int dst_rate, int src_rate) ++{ ++ int ret = ((long long)src_samples * dst_rate + src_rate-1) / src_rate; ++ #ifdef DEBUG_VERBOSE ++ CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, ret); ++ #endif ++ return ret; ++} ++ ++int CActiveAEResample::GetSrcBufferSize(int samples) ++{ ++ int ret = 0; ++ #ifdef DEBUG_VERBOSE ++ CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, ret); ++ #endif ++ return ret; ++} ++ ++int CActiveAEResample::GetDstBufferSize(int samples) ++{ ++ int ret = CalcDstSampleCount(samples, m_dst_rate, m_src_rate); ++ #ifdef DEBUG_VERBOSE ++ CLog::Log(LOGINFO, "%s::%s = %d", CLASSNAME, __func__, ret); ++ #endif ++ return ret; ++} ++ ++uint64_t CActiveAEResample::GetAVChannelLayout(CAEChannelInfo &info) ++{ ++ #ifdef DEBUG_VERBOSE ++ CLog::Log(LOGINFO, "%s::%s", CLASSNAME, __func__); ++ #endif ++ uint64_t channelLayout = 0; ++ if (info.HasChannel(AE_CH_FL)) channelLayout |= AV_CH_FRONT_LEFT; ++ if (info.HasChannel(AE_CH_FR)) channelLayout |= AV_CH_FRONT_RIGHT; ++ if (info.HasChannel(AE_CH_FC)) channelLayout |= AV_CH_FRONT_CENTER; ++ if (info.HasChannel(AE_CH_LFE)) channelLayout |= AV_CH_LOW_FREQUENCY; ++ if (info.HasChannel(AE_CH_BL)) channelLayout |= AV_CH_BACK_LEFT; ++ if (info.HasChannel(AE_CH_BR)) channelLayout |= AV_CH_BACK_RIGHT; ++ if (info.HasChannel(AE_CH_FLOC)) channelLayout |= AV_CH_FRONT_LEFT_OF_CENTER; ++ if (info.HasChannel(AE_CH_FROC)) channelLayout |= AV_CH_FRONT_RIGHT_OF_CENTER; ++ if (info.HasChannel(AE_CH_BC)) channelLayout |= AV_CH_BACK_CENTER; ++ if (info.HasChannel(AE_CH_SL)) channelLayout |= AV_CH_SIDE_LEFT; ++ if (info.HasChannel(AE_CH_SR)) channelLayout |= AV_CH_SIDE_RIGHT; ++ if (info.HasChannel(AE_CH_TC)) channelLayout |= AV_CH_TOP_CENTER; ++ if (info.HasChannel(AE_CH_TFL)) channelLayout |= AV_CH_TOP_FRONT_LEFT; ++ if (info.HasChannel(AE_CH_TFC)) channelLayout |= AV_CH_TOP_FRONT_CENTER; ++ if (info.HasChannel(AE_CH_TFR)) channelLayout |= AV_CH_TOP_FRONT_RIGHT; ++ if (info.HasChannel(AE_CH_TBL)) channelLayout |= AV_CH_TOP_BACK_LEFT; ++ if (info.HasChannel(AE_CH_TBC)) channelLayout |= AV_CH_TOP_BACK_CENTER; ++ if (info.HasChannel(AE_CH_TBR)) channelLayout |= AV_CH_TOP_BACK_RIGHT; ++ ++ return channelLayout; ++} ++ ++AVSampleFormat CActiveAEResample::GetAVSampleFormat(AEDataFormat format) ++{ ++ #ifdef DEBUG_VERBOSE ++ CLog::Log(LOGINFO, "%s::%s", CLASSNAME, __func__); ++ #endif ++ if (format == AE_FMT_U8) return AV_SAMPLE_FMT_U8; ++ else if (format == AE_FMT_S16NE) return AV_SAMPLE_FMT_S16; ++ else if (format == AE_FMT_S32NE) return AV_SAMPLE_FMT_S32; ++ else if (format == AE_FMT_S24NE4) return AV_SAMPLE_FMT_S32; ++ else if (format == AE_FMT_FLOAT) return AV_SAMPLE_FMT_FLT; ++ else if (format == AE_FMT_DOUBLE) return AV_SAMPLE_FMT_DBL; ++ ++ else if (format == AE_FMT_U8P) return AV_SAMPLE_FMT_U8P; ++ else if (format == AE_FMT_S16NEP) return AV_SAMPLE_FMT_S16P; ++ else if (format == AE_FMT_S32NEP) return AV_SAMPLE_FMT_S32P; ++ else if (format == AE_FMT_S24NE4P) return AV_SAMPLE_FMT_S32P; ++ else if (format == AE_FMT_FLOATP) return AV_SAMPLE_FMT_FLTP; ++ else if (format == AE_FMT_DOUBLEP) return AV_SAMPLE_FMT_DBLP; ++ ++ if (AE_IS_PLANAR(format)) ++ return AV_SAMPLE_FMT_FLTP; ++ else ++ return AV_SAMPLE_FMT_FLT; ++} ++ ++AEDataFormat CActiveAEResample::GetAESampleFormat(AVSampleFormat format, int bits) ++{ ++ #ifdef DEBUG_VERBOSE ++ CLog::Log(LOGINFO, "%s::%s", CLASSNAME, __func__); ++ #endif ++ if (format == AV_SAMPLE_FMT_U8) return AE_FMT_U8; ++ else if (format == AV_SAMPLE_FMT_S16) return AE_FMT_S16NE; ++ else if (format == AV_SAMPLE_FMT_S32 && bits == 32) return AE_FMT_S32NE; ++ else if (format == AV_SAMPLE_FMT_S32 && bits == 24) return AE_FMT_S24NE4; ++ else if (format == AV_SAMPLE_FMT_FLT) return AE_FMT_FLOAT; ++ else if (format == AV_SAMPLE_FMT_DBL) return AE_FMT_DOUBLE; ++ ++ else if (format == AV_SAMPLE_FMT_U8P) return AE_FMT_U8P; ++ else if (format == AV_SAMPLE_FMT_S16P) return AE_FMT_S16NEP; ++ else if (format == AV_SAMPLE_FMT_S32P && bits == 32) return AE_FMT_S32NEP; ++ else if (format == AV_SAMPLE_FMT_S32P && bits == 24) return AE_FMT_S24NE4P; ++ else if (format == AV_SAMPLE_FMT_FLTP) return AE_FMT_FLOATP; ++ else if (format == AV_SAMPLE_FMT_DBLP) return AE_FMT_DOUBLEP; ++ ++ CLog::Log(LOGERROR, "CActiveAEResample::GetAESampleFormat - format not supported"); ++ return AE_FMT_INVALID; ++} ++ ++uint64_t CActiveAEResample::GetAVChannel(enum AEChannel aechannel) ++{ ++ #ifdef DEBUG_VERBOSE ++ CLog::Log(LOGINFO, "%s::%s", CLASSNAME, __func__); ++ #endif ++ switch (aechannel) ++ { ++ case AE_CH_FL: return AV_CH_FRONT_LEFT; ++ case AE_CH_FR: return AV_CH_FRONT_RIGHT; ++ case AE_CH_FC: return AV_CH_FRONT_CENTER; ++ case AE_CH_LFE: return AV_CH_LOW_FREQUENCY; ++ case AE_CH_BL: return AV_CH_BACK_LEFT; ++ case AE_CH_BR: return AV_CH_BACK_RIGHT; ++ case AE_CH_FLOC: return AV_CH_FRONT_LEFT_OF_CENTER; ++ case AE_CH_FROC: return AV_CH_FRONT_RIGHT_OF_CENTER; ++ case AE_CH_BC: return AV_CH_BACK_CENTER; ++ case AE_CH_SL: return AV_CH_SIDE_LEFT; ++ case AE_CH_SR: return AV_CH_SIDE_RIGHT; ++ case AE_CH_TC: return AV_CH_TOP_CENTER; ++ case AE_CH_TFL: return AV_CH_TOP_FRONT_LEFT; ++ case AE_CH_TFC: return AV_CH_TOP_FRONT_CENTER; ++ case AE_CH_TFR: return AV_CH_TOP_FRONT_RIGHT; ++ case AE_CH_TBL: return AV_CH_TOP_BACK_LEFT; ++ case AE_CH_TBC: return AV_CH_TOP_BACK_CENTER; ++ case AE_CH_TBR: return AV_CH_TOP_BACK_RIGHT; ++ default: ++ return 0; ++ } ++} ++ ++int CActiveAEResample::GetAVChannelIndex(enum AEChannel aechannel, uint64_t layout) ++{ ++ #ifdef DEBUG_VERBOSE ++ CLog::Log(LOGINFO, "%s::%s", CLASSNAME, __func__); ++ #endif ++ return av_get_channel_layout_channel_index(layout, GetAVChannel(aechannel)); ++} ++ ++#endif +diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.h b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.h +new file mode 100644 +index 0000000..47a9e08 +--- /dev/null ++++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.h +@@ -0,0 +1,62 @@ ++#pragma once ++/* ++ * Copyright (C) 2010-2013 Team XBMC ++ * http://xbmc.org ++ * ++ * This Program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2, or (at your option) ++ * any later version. ++ * ++ * This Program 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 General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with XBMC; see the file COPYING. If not, see ++ * . ++ * ++ */ ++ ++#include "linux/OMXCore.h" ++ ++namespace ActiveAE ++{ ++ ++class CActiveAEResample ++{ ++public: ++ CActiveAEResample(); ++ virtual ~CActiveAEResample(); ++ bool Init(uint64_t dst_chan_layout, int dst_channels, int dst_rate, AVSampleFormat dst_fmt, int dst_bits, int dst_dither, uint64_t src_chan_layout, int src_channels, int src_rate, AVSampleFormat src_fmt, int src_bits, int src_dither, bool upmix, bool normalize, CAEChannelInfo *remapLayout, AEQuality quality); ++ int Resample(uint8_t **dst_buffer, int dst_samples, uint8_t **src_buffer, int src_samples, double ratio); ++ int64_t GetDelay(int64_t base); ++ int GetBufferedSamples(); ++ int CalcDstSampleCount(int src_samples, int dst_rate, int src_rate); ++ int GetSrcBufferSize(int samples); ++ int GetDstBufferSize(int samples); ++ static uint64_t GetAVChannelLayout(CAEChannelInfo &info); ++// static CAEChannelInfo GetAEChannelLayout(uint64_t layout); ++ static AVSampleFormat GetAVSampleFormat(AEDataFormat format); ++ static AEDataFormat GetAESampleFormat(AVSampleFormat format, int bits); ++ static uint64_t GetAVChannel(enum AEChannel aechannel); ++ int GetAVChannelIndex(enum AEChannel aechannel, uint64_t layout); ++ ++protected: ++ void DeInit(); ++ uint64_t m_src_chan_layout, m_dst_chan_layout; ++ int m_src_rate, m_dst_rate; ++ int m_src_channels, m_dst_channels; ++ AVSampleFormat m_src_fmt, m_dst_fmt; ++ int m_src_bits, m_dst_bits; ++ ++ OMX_AUDIO_PARAM_PCMMODETYPE m_pcm_input; ++ OMX_AUDIO_PARAM_PCMMODETYPE m_pcm_output; ++ COMXCoreComponent m_omx_mixer; ++ bool m_Initialized; ++ AVSampleFormat m_last_src_fmt, m_last_dst_fmt; ++ int m_last_src_channels, m_last_dst_channels; ++}; ++ ++} +diff --git a/xbmc/cores/AudioEngine/Makefile.in b/xbmc/cores/AudioEngine/Makefile.in +index c27d207..ebc74fa 100644 +--- a/xbmc/cores/AudioEngine/Makefile.in ++++ b/xbmc/cores/AudioEngine/Makefile.in +@@ -31,6 +31,7 @@ SRCS += Engines/ActiveAE/ActiveAESink.cpp + SRCS += Engines/ActiveAE/ActiveAEStream.cpp + SRCS += Engines/ActiveAE/ActiveAESound.cpp + SRCS += Engines/ActiveAE/ActiveAEResample.cpp ++SRCS += Engines/ActiveAE/ActiveAEResamplePi.cpp + SRCS += Engines/ActiveAE/ActiveAEBuffer.cpp + + ifeq (@USE_ANDROID@,1) +diff --git a/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp b/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp +index bf9cb7a..277f7b9 100644 +--- a/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp ++++ b/xbmc/cores/AudioEngine/Sinks/AESinkPi.cpp +@@ -78,9 +78,9 @@ static void SetAudioProps(bool stream_channels, uint32_t channel_map) + CLog::Log(LOGDEBUG, "%s:%s hdmi_stream_channels %d hdmi_channel_map %08x", CLASSNAME, __func__, stream_channels, channel_map); + } + +-static uint32_t GetChannelMap(AEAudioFormat &format, bool passthrough) ++static uint32_t GetChannelMap(const CAEChannelInfo &channelLayout, bool passthrough) + { +- unsigned int channels = format.m_channelLayout.Count(); ++ unsigned int channels = channelLayout.Count(); + uint32_t channel_map = 0; + if (passthrough) + return 0; +@@ -119,12 +119,12 @@ static uint32_t GetChannelMap(AEAudioFormat &format, bool passthrough) + // According to CEA-861-D only RL and RR are known. In case of a format having SL and SR channels + // but no BR BL channels, we use the wide map in order to open only the num of channels really + // needed. +- if (format.m_channelLayout.HasChannel(AE_CH_BL) && !format.m_channelLayout.HasChannel(AE_CH_SL)) ++ if (channelLayout.HasChannel(AE_CH_BL) && !channelLayout.HasChannel(AE_CH_SL)) + map = map_back; + + for (unsigned int i = 0; i < channels; ++i) + { +- AEChannel c = format.m_channelLayout[i]; ++ AEChannel c = channelLayout[i]; + unsigned int chan = 0; + if ((unsigned int)c < sizeof map_normal / sizeof *map_normal) + chan = map[(unsigned int)c]; +@@ -155,9 +155,9 @@ static uint32_t GetChannelMap(AEAudioFormat &format, bool passthrough) + 0xff, // 7 + 0x13, // 7.1 + }; +- uint8_t cea = format.m_channelLayout.HasChannel(AE_CH_LFE) ? cea_map_lfe[channels] : cea_map[channels]; ++ uint8_t cea = channelLayout.HasChannel(AE_CH_LFE) ? cea_map_lfe[channels] : cea_map[channels]; + if (cea == 0xff) +- CLog::Log(LOGERROR, "%s::%s - Unexpected CEA mapping %d,%d", CLASSNAME, __func__, format.m_channelLayout.HasChannel(AE_CH_LFE), channels); ++ CLog::Log(LOGERROR, "%s::%s - Unexpected CEA mapping %d,%d", CLASSNAME, __func__, channelLayout.HasChannel(AE_CH_LFE), channels); + + channel_map |= cea << 24; + +@@ -191,7 +191,7 @@ bool CAESinkPi::Initialize(AEAudioFormat &format, std::string &device) + format.m_frames = format.m_sampleRate * AUDIO_PLAYBUFFER / NUM_OMX_BUFFERS; + format.m_frameSamples = format.m_frames * channels; + +- SetAudioProps(m_passthrough, GetChannelMap(format, m_passthrough)); ++ SetAudioProps(m_passthrough, GetChannelMap(format.m_channelLayout, m_passthrough)); + + m_format = format; + m_sinkbuffer_sec_per_byte = 1.0 / (double)(m_format.m_frameSize * m_format.m_sampleRate); +diff --git a/xbmc/linux/OMXCore.cpp b/xbmc/linux/OMXCore.cpp +index 99e407a..8d3c86a 100644 +--- a/xbmc/linux/OMXCore.cpp ++++ b/xbmc/linux/OMXCore.cpp +@@ -448,7 +448,7 @@ void COMXCoreComponent::FlushAll() + + void COMXCoreComponent::FlushInput() + { +- if(!m_handle) ++ if(!m_handle || m_resource_error) + return; + + OMX_ERRORTYPE omx_err = OMX_ErrorNone; +@@ -470,7 +470,7 @@ void COMXCoreComponent::FlushInput() + + void COMXCoreComponent::FlushOutput() + { +- if(!m_handle) ++ if(!m_handle || m_resource_error) + return; + + OMX_ERRORTYPE omx_err = OMX_ErrorNone; +-- +1.9.3 + + +From 8b7127df209b97085c4f8e69f356643bd25e5ce8 Mon Sep 17 00:00:00 2001 +From: popcornmix +Date: Sun, 1 Jun 2014 12:15:17 +0100 +Subject: [PATCH 87/89] [resamplepi] Support planar formats + +--- + .../Engines/ActiveAE/ActiveAEResamplePi.cpp | 101 ++++++++++++--------- + 1 file changed, 59 insertions(+), 42 deletions(-) + +diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp +index 9a1e549..1604030 100644 +--- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp ++++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp +@@ -88,20 +88,36 @@ void CActiveAEResample::DeInit() + } + } + ++static int format_to_bits(AVSampleFormat fmt) ++{ ++ switch (fmt) ++ { ++ case AV_SAMPLE_FMT_U8: ++ case AV_SAMPLE_FMT_U8P: ++ return 8; ++ case AV_SAMPLE_FMT_S16: ++ case AV_SAMPLE_FMT_S16P: ++ return 16; ++ case AV_SAMPLE_FMT_S32: ++ case AV_SAMPLE_FMT_S32P: ++ case AV_SAMPLE_FMT_FLT: ++ case AV_SAMPLE_FMT_FLTP: ++ return 32; ++ default: ++ assert(0); ++ } ++ return 0; ++} ++ + bool CActiveAEResample::Init(uint64_t dst_chan_layout, int dst_channels, int dst_rate, AVSampleFormat dst_fmt, int dst_bits, int dst_dither, uint64_t src_chan_layout, int src_channels, int src_rate, AVSampleFormat src_fmt, int src_bits, int src_dither, bool upmix, bool normalize, CAEChannelInfo *remapLayout, AEQuality quality) + { + LOGTIMEINIT("x"); + + CLog::Log(LOGINFO, "%s::%s remap:%p chan:%d->%d rate:%d->%d format:%d->%d bits:%d->%d norm:%d upmix:%d", CLASSNAME, __func__, remapLayout, src_channels, dst_channels, src_rate, dst_rate, src_fmt, dst_fmt, src_bits, dst_bits, normalize, upmix); + +- if (src_bits == 0) +- { +- if (src_fmt == AV_SAMPLE_FMT_U8) src_bits = 8; +- else if (src_fmt == AV_SAMPLE_FMT_S16) src_bits = 16; +- else if (src_fmt == AV_SAMPLE_FMT_S32) src_bits = 32; +- else if (src_fmt == AV_SAMPLE_FMT_FLT) src_bits = 32; +- } +- assert(src_bits && dst_bits); ++ // replace passed in number of bits with correct ones ++ src_bits = format_to_bits(src_fmt); ++ dst_bits = format_to_bits(dst_fmt); + + m_dst_chan_layout = dst_chan_layout; + m_dst_channels = dst_channels; +@@ -139,7 +155,7 @@ bool CActiveAEResample::Init(uint64_t dst_chan_layout, int dst_channels, int dst + // not required for sink stage (remapLayout == true) + if (!remapLayout && normalize) + { +- av_opt_set_double(m_pContext, "rematrix_maxval", 1.0, 0); ++ av_opt_set_double(m_pContext, "rematrix_maxval", 1.0, 0); + } + + if (remapLayout) +@@ -264,7 +280,13 @@ bool CActiveAEResample::Init(uint64_t dst_chan_layout, int dst_channels, int dst + m_pcm_input.eEndian = OMX_EndianLittle; + m_pcm_input.bInterleaved = OMX_TRUE; + m_pcm_input.nBitPerSample = m_src_bits; +- m_pcm_input.ePCMMode = m_src_fmt == AV_SAMPLE_FMT_FLT ? (OMX_AUDIO_PCMMODETYPE)0x8000 : OMX_AUDIO_PCMModeLinear; ++ // 0x8000 = float, 0x10000 = planar ++ uint32_t flags = 0; ++ if (m_src_fmt == AV_SAMPLE_FMT_FLT || m_src_fmt == AV_SAMPLE_FMT_FLTP) ++ flags |= 0x8000; ++ if (m_src_fmt >= AV_SAMPLE_FMT_U8P) ++ flags |= 0x10000; ++ m_pcm_input.ePCMMode = flags == 0 ? OMX_AUDIO_PCMModeLinear : (OMX_AUDIO_PCMMODETYPE)flags; + m_pcm_input.nChannels = src_channels; + m_pcm_input.nSamplingRate = src_rate; + +@@ -278,7 +300,12 @@ bool CActiveAEResample::Init(uint64_t dst_chan_layout, int dst_channels, int dst + m_pcm_output.eEndian = OMX_EndianLittle; + m_pcm_output.bInterleaved = OMX_TRUE; + m_pcm_output.nBitPerSample = m_dst_bits; +- m_pcm_output.ePCMMode = m_dst_fmt == AV_SAMPLE_FMT_FLT ? (OMX_AUDIO_PCMMODETYPE)0x8000 : OMX_AUDIO_PCMModeLinear; ++ flags = 0; ++ if (m_dst_fmt == AV_SAMPLE_FMT_FLT || m_dst_fmt == AV_SAMPLE_FMT_FLTP) ++ flags |= 0x8000; ++ if (m_dst_fmt >= AV_SAMPLE_FMT_U8P) ++ flags |= 0x10000; ++ m_pcm_output.ePCMMode = flags == 0 ? OMX_AUDIO_PCMModeLinear : (OMX_AUDIO_PCMMODETYPE)flags; + m_pcm_output.nChannels = dst_channels; + m_pcm_output.nSamplingRate = dst_rate; + +@@ -364,8 +391,13 @@ int CActiveAEResample::Resample(uint8_t **dst_buffer, int dst_samples, uint8_t * + return 0; + OMX_ERRORTYPE omx_err = OMX_ErrorNone; + +- const int s_pitch = m_pcm_input.nChannels * m_src_bits >> 3; +- const int d_pitch = m_pcm_output.nChannels * m_dst_bits >> 3; ++ const int s_planes = m_src_fmt >= AV_SAMPLE_FMT_U8P ? m_src_channels : 1; ++ const int d_planes = m_dst_fmt >= AV_SAMPLE_FMT_U8P ? m_dst_channels : 1; ++ const int s_chans = m_src_fmt >= AV_SAMPLE_FMT_U8P ? 1 : m_src_channels; ++ const int d_chans = m_dst_fmt >= AV_SAMPLE_FMT_U8P ? 1 : m_dst_channels; ++ const int s_pitch = s_chans * m_src_bits >> 3; ++ const int d_pitch = d_chans * m_dst_bits >> 3; ++ + int sent = 0; + int received = 0; + while (sent < src_samples) +@@ -377,19 +409,23 @@ int CActiveAEResample::Resample(uint8_t **dst_buffer, int dst_samples, uint8_t * + if (omx_buffer == NULL) + return false; + +- const int max_src_samples = BUFFERSIZE / s_pitch; +- const int max_dst_samples = (long long)(BUFFERSIZE/d_pitch) * m_src_rate / (m_dst_rate + m_src_rate-1); ++ const int s_samplesize = m_src_channels * m_src_bits >> 3; ++ const int d_samplesize = m_dst_channels * m_dst_bits >> 3; ++ const int max_src_samples = BUFFERSIZE / s_samplesize; ++ const int max_dst_samples = (long long)(BUFFERSIZE / d_samplesize) * m_src_rate / (m_dst_rate + m_src_rate-1); + int send = std::min(std::min(max_dst_samples, max_src_samples), src_samples - sent); + + omx_buffer->nOffset = 0; + omx_buffer->nFlags = OMX_BUFFERFLAG_EOS; +- omx_buffer->nFilledLen = send * s_pitch; ++ omx_buffer->nFilledLen = send * s_samplesize; + + assert(omx_buffer->nFilledLen > 0 && omx_buffer->nFilledLen <= omx_buffer->nAllocLen); + + if (omx_buffer->nFilledLen) + { +- memcpy(omx_buffer->pBuffer, src_buffer[0] + sent * s_pitch, omx_buffer->nFilledLen); ++ int planesize = omx_buffer->nFilledLen / s_planes; ++ for (int i=0; i < s_planes; i++) ++ memcpy((uint8_t *)omx_buffer->pBuffer + i * planesize, src_buffer[i] + sent * s_pitch, planesize); + sent += send; + } + +@@ -428,8 +464,10 @@ int CActiveAEResample::Resample(uint8_t **dst_buffer, int dst_samples, uint8_t * + + if (m_encoded_buffer->nFilledLen) + { +- memcpy(dst_buffer[0] + received * d_pitch, m_encoded_buffer->pBuffer, m_encoded_buffer->nFilledLen); +- received += m_encoded_buffer->nFilledLen / d_pitch; ++ int planesize = m_encoded_buffer->nFilledLen / d_planes; ++ for (int i=0; i < d_planes; i++) ++ memcpy(dst_buffer[i] + received * d_pitch, (uint8_t *)m_encoded_buffer->pBuffer + i * planesize, planesize); ++ received += m_encoded_buffer->nFilledLen / d_samplesize; + } + } + #ifdef DEBUG_VERBOSE +@@ -521,6 +559,7 @@ AVSampleFormat CActiveAEResample::GetAVSampleFormat(AEDataFormat format) + else if (format == AE_FMT_S16NE) return AV_SAMPLE_FMT_S16; + else if (format == AE_FMT_S32NE) return AV_SAMPLE_FMT_S32; + else if (format == AE_FMT_S24NE4) return AV_SAMPLE_FMT_S32; ++ else if (format == AE_FMT_S24NE4MSB)return AV_SAMPLE_FMT_S32; + else if (format == AE_FMT_FLOAT) return AV_SAMPLE_FMT_FLT; + else if (format == AE_FMT_DOUBLE) return AV_SAMPLE_FMT_DBL; + +@@ -528,6 +567,7 @@ AVSampleFormat CActiveAEResample::GetAVSampleFormat(AEDataFormat format) + else if (format == AE_FMT_S16NEP) return AV_SAMPLE_FMT_S16P; + else if (format == AE_FMT_S32NEP) return AV_SAMPLE_FMT_S32P; + else if (format == AE_FMT_S24NE4P) return AV_SAMPLE_FMT_S32P; ++ else if (format == AE_FMT_S24NE4MSB)return AV_SAMPLE_FMT_S32; + else if (format == AE_FMT_FLOATP) return AV_SAMPLE_FMT_FLTP; + else if (format == AE_FMT_DOUBLEP) return AV_SAMPLE_FMT_DBLP; + +@@ -537,29 +577,6 @@ AVSampleFormat CActiveAEResample::GetAVSampleFormat(AEDataFormat format) + return AV_SAMPLE_FMT_FLT; + } + +-AEDataFormat CActiveAEResample::GetAESampleFormat(AVSampleFormat format, int bits) +-{ +- #ifdef DEBUG_VERBOSE +- CLog::Log(LOGINFO, "%s::%s", CLASSNAME, __func__); +- #endif +- if (format == AV_SAMPLE_FMT_U8) return AE_FMT_U8; +- else if (format == AV_SAMPLE_FMT_S16) return AE_FMT_S16NE; +- else if (format == AV_SAMPLE_FMT_S32 && bits == 32) return AE_FMT_S32NE; +- else if (format == AV_SAMPLE_FMT_S32 && bits == 24) return AE_FMT_S24NE4; +- else if (format == AV_SAMPLE_FMT_FLT) return AE_FMT_FLOAT; +- else if (format == AV_SAMPLE_FMT_DBL) return AE_FMT_DOUBLE; +- +- else if (format == AV_SAMPLE_FMT_U8P) return AE_FMT_U8P; +- else if (format == AV_SAMPLE_FMT_S16P) return AE_FMT_S16NEP; +- else if (format == AV_SAMPLE_FMT_S32P && bits == 32) return AE_FMT_S32NEP; +- else if (format == AV_SAMPLE_FMT_S32P && bits == 24) return AE_FMT_S24NE4P; +- else if (format == AV_SAMPLE_FMT_FLTP) return AE_FMT_FLOATP; +- else if (format == AV_SAMPLE_FMT_DBLP) return AE_FMT_DOUBLEP; +- +- CLog::Log(LOGERROR, "CActiveAEResample::GetAESampleFormat - format not supported"); +- return AE_FMT_INVALID; +-} +- + uint64_t CActiveAEResample::GetAVChannel(enum AEChannel aechannel) + { + #ifdef DEBUG_VERBOSE +-- +1.9.3