[vlc-commits] [Git][videolan/vlc][3.0.x] 30 commits: taglib: .m4v are already registered as MP4 files

Steve Lhomme (@robUx4) gitlab at videolan.org
Thu Sep 19 09:55:40 UTC 2024



Steve Lhomme pushed to branch 3.0.x at VideoLAN / VLC


Commits:
109d2ac2 by Hugo Beauzée-Luyssen at 2024-09-19T08:44:02+00:00
taglib: .m4v are already registered as MP4 files

https://github.com/taglib/taglib/pull/662
(cherry picked from commit 84962e474bfefa242527f7c3ddffe6ed4f697fbe) (rebased)

- - - - -
09b558dd by François Cartegnie at 2024-09-19T08:44:02+00:00
modules: taglib: simplify reading embedded art

(cherry picked from commit 3533f90eb44398abe6cff1b14ece757654449acf) (rebased)
rebased:
- 294cbdbaee0209bc88ca7bec9164da8da4ac44ef has been merged above

- - - - -
db09e821 by Hugo Beauzée-Luyssen at 2024-09-19T08:44:02+00:00
taglib: IOStream: Return the url as fileName

Since the only part that matters to taglib is the filename, and more
specifically the extension part.

(cherry picked from commit 026a76066efa78f1934ab2c177669a2e6a519cff)

- - - - -
df406faf by Steve Lhomme at 2024-09-19T08:44:02+00:00
taglib: Always use IOStream to read the media

(cherry picked from commit 4bc7607f31f80264b5e61fbd187f2f8d2f3bb604) (edited)
edited:
- keep the support for taglib older than 1.11 which doesn't have the
  proper FileRef constructor to use it
- the aacresolver is only called for Taglib 1.11+ on 3.0
- 4.0 doesn't make a difference for UWP or regular Windows

- - - - -
c2ca6c30 by Hugo Beauzée-Luyssen at 2024-09-19T08:44:02+00:00
taglib: Enable prefetch/cache on the IOStream

We can't do it through vlc_stream_NewURL as it will include the
skiptags filter

(cherry picked from commit 976cd219465a72daa02d22e60c9ac4c704c0b18b)

- - - - -
3720cf2c by Alexandre Janniaux at 2024-09-19T08:44:02+00:00
taglib: fix -Wdeprecated-copy warnings

Warnings were happening because we were using copy operator= as the
assigned object was already initialized. This patch use the copy
constructor or move constructor instead if available.

Those warnings were:

../../modules/meta_engine/taglib.cpp: In function ‘void ReadMetaFromXiph(TagLib::Ogg::XiphComment*, demux_meta_t*, vlc_meta_t*)’:
../../modules/meta_engine/taglib.cpp:672:39: warning: implicitly-declared ‘TagLib::StringList& TagLib::StringList::operator=(const TagLib::StringList&)’ is deprecated [-Wdeprecated-copy]
  672 |     list = tag->fieldListMap()[keyName];                                       \
      |                                       ^
../../modules/meta_engine/taglib.cpp:681:5: note: in expansion of macro ‘SET’
  681 |     SET( "COPYRIGHT", Copyright );
      |     ^~~
In file included from /usr/include/taglib/fileref.h:30,
                 from ../../modules/meta_engine/taglib.cpp:58:
/usr/include/taglib/tstringlist.h:59:5: note: because ‘TagLib::StringList’ has user-provided ‘TagLib::StringList::StringList(const TagLib::StringList&)’
   59 |     StringList(const StringList &l);
      |     ^~~~~~~~~~

Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>
(cherry picked from commit be4f907a0e834c10277b8217520f745238da1c13)

- - - - -
630b2f68 by François Cartegnie at 2024-09-19T08:44:02+00:00
contribs: patch taglib to avoid full/infinite streams read

(cherry picked from commit 3257bb4a84e60fd60e83ba7c938485e71ba12188) (rebased)
rebased:
- 3.0 already switched to 1.12 with less patches

- - - - -
88149ff4 by Hugo Beauzée-Luyssen at 2024-09-19T08:44:02+00:00
contrib: Bump taglib to 1.12

fix #26309

(cherry picked from commit c651b10d33dc0fb7b9670208f93f94f850ba8ca4) (edited)
edited:
- only contains the patches to 0001-Implement-ID3v2-readStyle-avoid-worst-case.patch
  which were not properly backported in 1353e52693d8deb4e629e153d9c73d7dc69afc13

- - - - -
3a4b557a by François Cartegnie at 2024-09-19T08:44:02+00:00
meta_engine: taglib: increment VlcIostream readpos

(cherry picked from commit 0cbcf504b43a02ddb7ecc1c65c0c1e82f39b4f1c)

- - - - -
00cbfcce by François Cartegnie at 2024-09-19T08:44:02+00:00
meta_engine: taglib: reject read on failed seek

(cherry picked from commit 837b583e4e4e531ff8b11f13300c7cbc565beb9f) (rebased)
rebased:
- 3.0 already has 1.11 ifdef

- - - - -
625675cd by François Cartegnie at 2024-09-19T08:44:02+00:00
meta_engine: taglib: add sequential read limit on VlcIostream

(cherry picked from commit d375284a144e6b18896deda3a86b9560bc04f3d8) (rebased)
rebased:
- 3.0 already has 1.11 ifdef

- - - - -
88e4dc19 by François Cartegnie at 2024-09-19T08:44:02+00:00
meta_engine: taglib: restrict unlimited reads on streams

taglib reads unlimited if no IDv3 or MPEG header is found at the
beginning.

(cherry picked from commit 8ec8b0d2add84b6d6b0c043e1c4f241998915ecd) (rebased)
rebased:
- only used with Taglib 1.11+ which is not always the case with 3.0

- - - - -
f036afb7 by François Cartegnie at 2024-09-19T08:44:02+00:00
meta: taglib: reject non expected schemes

refs #25035

(cherry picked from commit 8191ac5727a3525a6bee99e1674167a7894f9ccb) (rebased)
rebased:
- 3.0 already has a26e2ba370d898dda04c718176af7d2e329dab7a above

- - - - -
e60dd2df by Steve Lhomme at 2024-09-19T08:44:02+00:00
taglib: fix variable shadowing

list is already a different local list defined earlier in the function.

(cherry picked from commit 34ca2a286edda76a9718cfa1e50bd3e4ea51702c)

- - - - -
fc401e9b by Hugo Beauzée-Luyssen at 2024-09-19T08:44:02+00:00
taglib: Don't convert base64 strings to UTF8

The convertion will incur a cost which we don't want to pay since the
art needs to be encoded in base64, which doesn't include anything
outside of ASCII

(cherry picked from commit 65dfe0cdc97bbb98ad34a690989636d40f326e32)

- - - - -
7c09325e by Hugo Beauzée-Luyssen at 2024-09-19T08:44:02+00:00
taglib: ByteVector::null is now deprecated

(cherry picked from commit d2663d6c3fe3af76bdefd58367b4a45c598b83e4)

- - - - -
72446e87 by Hugo Beauzée-Luyssen at 2024-09-19T08:44:02+00:00
taglib: Remove usages of deprecated itemListMap

contains() was added in 1.10 and item() is supported since 1.9

(cherry picked from commit ac59d0ba59ba800c52c0a92ec1d9576d2653dbe2)

- - - - -
230edbcc by Hugo Beauzée-Luyssen at 2024-09-19T08:44:02+00:00
taglib: Remove use of deprecated String::isNull

(cherry picked from commit c404fdb24183031a419667639846edddca3401f8) (edited)
edited:
- 294cbdbaee0209bc88ca7bec9164da8da4ac44ef was merged before this patch

- - - - -
7b2f1d35 by Hugo Beauzée-Luyssen at 2024-09-19T08:44:02+00:00
taglib: Remove explicit invocation of default constructor

This is already done implicitly

(cherry picked from commit 93842f650548d6f29ec13cf0679bf49cf5ce107c)

- - - - -
d226e0c6 by Hugo Beauzée-Luyssen at 2024-09-19T08:44:02+00:00
contrib: taglib: Fix custom resolvers with IOStream

upstreamed at: https://github.com/taglib/taglib/pull/1040
Fix #26602

(cherry picked from commit 2f82d6b9280c8e56b1ad7247ea9ffbe2a4df95a4)

- - - - -
6a14f299 by Hugo Beauzée-Luyssen at 2024-09-19T08:44:02+00:00
taglib: Implement new StreamTypeResolver interface when available

refs #26602

(cherry picked from commit 268b5b8bc1f1109c4fc69b22e53095c6d81faa76) (rebased)

- - - - -
ba858385 by Hugo Beauzée-Luyssen at 2024-09-19T08:44:02+00:00
taglib: Use nullptr instead of 0 for pointers

(cherry picked from commit 89e20ea0d87f414f763ce38ff5579aec61f71b42)

- - - - -
01c9003d by Hugo Beauzée-Luyssen at 2024-09-19T08:44:02+00:00
taglib: Fix invalid version check

(cherry picked from commit 53260ca5ae906f1e35791d14e4b588d25c04e51b)

- - - - -
286d843d by Marvin Scholz at 2024-09-19T08:44:02+00:00
meta: taglib: use std::min

(cherry picked from commit 584fd17a9445d8d5f7d692b7416eec09b9240b0e)

- - - - -
651da62c by Steve Lhomme at 2024-09-19T08:44:02+00:00
taglib: don't cast the file st_size to a possibly smaller type

We can just use auto and always get the proper type.

(cherry picked from commit 7413126744e0b494856ba9acc5ae3c27ce4af625)

- - - - -
97f309a7 by Hugo Beauzée-Luyssen at 2024-09-19T08:44:02+00:00
contrib: taglib: Update patch from upstream

This is the version that was merged upstream so it makes sense to use it
to facilitate future rebases
upstream PR: https://github.com/taglib/taglib/pull/1040

(cherry picked from commit c5893a223668fd9d0085c03998ceb9055a7ccede)

- - - - -
78af081d by Johannes Kauffmann at 2024-09-19T08:44:02+00:00
contrib: taglib: update to 1.13

(cherry picked from commit 436526ec6a05aa3acb75d888b4baaa649cf8b87d) (rebased)

- - - - -
6da0cba6 by Johannes Kauffmann at 2024-09-19T08:44:02+00:00
taglib: remove VLC path define check

It is no longer needed with contribs taglib updated to 1.13.

(cherry picked from commit c5851fd495ed6de1d3712e64a2b1cc1e4e9059f4)

- - - - -
e69ef263 by Steve Lhomme at 2024-09-19T08:44:02+00:00
contrib: Bump taglib to 1.13.1

Changelog: https://github.com/taglib/taglib/releases/tag/v1.13.1
(cherry picked from commit c7cceca69ba1fc96fc6d29d9750c6dcfb4ef44aa)

- - - - -
5ee481af by Vikram Kangotra at 2024-09-19T08:44:02+00:00
Taglib: Use ID3v2Tag() instead of tag() for RIFF::WAV::File

`WriteMetaToId3v2` expects a `ID3v2::Tag` instead of `Tag`, but Since TagLib v2.0,
`RIFF::WAV::File::tag()` returns a `Tag` instead of `ID3v2::Tag`, hence replace
the usage of `tag()` method with `ID3v2Tag()`.

https://github.com/taglib/taglib/blob/master/taglib/riff/wav/wavfile.h#L124

Additionally, to resolve the compilation error, the function signatures of
`insert` and `removeBlock` have been adjusted to align with the base class
functions.

(cherry picked from commit ec29dfca1e59530dd412d779e0b045079b72ffb6)

- - - - -


4 changed files:

- + contrib/src/taglib/0001-Implement-ID3v2-readStyle-avoid-worst-case.patch
- contrib/src/taglib/SHA512SUMS
- contrib/src/taglib/rules.mak
- modules/meta_engine/taglib.cpp


Changes:

=====================================
contrib/src/taglib/0001-Implement-ID3v2-readStyle-avoid-worst-case.patch
=====================================
@@ -0,0 +1,148 @@
+From be17e6084a151c901c3946ec7b37afabc3b84f5f Mon Sep 17 00:00:00 2001
+From: Francois Cartegnie <fcvlcdev at free.fr>
+Date: Tue, 11 Aug 2020 10:53:31 +0200
+Subject: [PATCH] Implement ID3v2 readStyle, avoid worst case
+
+---
+ taglib/mpeg/mpegfile.cpp | 22 +++++++++++++---------
+ taglib/mpeg/mpegfile.h   | 13 ++++++++-----
+ taglib/toolkit/taglib.h  |  3 +++
+ 3 files changed, 24 insertions(+), 14 deletions(-)
+
+diff --git a/taglib/mpeg/mpegfile.cpp b/taglib/mpeg/mpegfile.cpp
+index 5f14e49d..30124e0d 100644
+--- a/taglib/mpeg/mpegfile.cpp
++++ b/taglib/mpeg/mpegfile.cpp
+@@ -132,30 +132,31 @@ bool MPEG::File::isSupported(IOStream *stream)
+ // public members
+ ////////////////////////////////////////////////////////////////////////////////
+ 
+-MPEG::File::File(FileName file, bool readProperties, Properties::ReadStyle) :
++MPEG::File::File(FileName file,
++                 bool readProperties, Properties::ReadStyle readStyle) :
+   TagLib::File(file),
+   d(new FilePrivate())
+ {
+   if(isOpen())
+-    read(readProperties);
++    read(readProperties, readStyle);
+ }
+ 
+ MPEG::File::File(FileName file, ID3v2::FrameFactory *frameFactory,
+-                 bool readProperties, Properties::ReadStyle) :
++                 bool readProperties, Properties::ReadStyle readStyle) :
+   TagLib::File(file),
+   d(new FilePrivate(frameFactory))
+ {
+   if(isOpen())
+-    read(readProperties);
++    read(readProperties, readStyle);
+ }
+ 
+ MPEG::File::File(IOStream *stream, ID3v2::FrameFactory *frameFactory,
+-                 bool readProperties, Properties::ReadStyle) :
++                 bool readProperties, Properties::ReadStyle readStyle) :
+   TagLib::File(stream),
+   d(new FilePrivate(frameFactory))
+ {
+   if(isOpen())
+-    read(readProperties);
++    read(readProperties, readStyle);
+ }
+ 
+ MPEG::File::~File()
+@@ -498,11 +499,11 @@ bool MPEG::File::hasAPETag() const
+ // private members
+ ////////////////////////////////////////////////////////////////////////////////
+ 
+-void MPEG::File::read(bool readProperties)
++void MPEG::File::read(bool readProperties, Properties::ReadStyle readStyle)
+ {
+   // Look for an ID3v2 tag
+ 
+-  d->ID3v2Location = findID3v2();
++  d->ID3v2Location = findID3v2(readStyle);
+ 
+   if(d->ID3v2Location >= 0) {
+     d->tag.set(ID3v2Index, new ID3v2::Tag(this, d->ID3v2Location, d->ID3v2FrameFactory));
+@@ -535,7 +536,7 @@ void MPEG::File::read(bool readProperties)
+   ID3v1Tag(true);
+ }
+ 
+-long MPEG::File::findID3v2()
++long MPEG::File::findID3v2(Properties::ReadStyle readStyle)
+ {
+   if(!isValid())
+     return -1;
+@@ -558,6 +559,9 @@ long MPEG::File::findID3v2()
+   ByteVector tagHeaderBytes(3, '\0');
+   long position = 0;
+ 
++  if(readStyle < Properties::Accurate)
++    return -1;
++
+   while(true) {
+     seek(position);
+     const ByteVector buffer = readBlock(bufferSize());
+diff --git a/taglib/mpeg/mpegfile.h b/taglib/mpeg/mpegfile.h
+index 3fcb7272..22a282d9 100644
+--- a/taglib/mpeg/mpegfile.h
++++ b/taglib/mpeg/mpegfile.h
+@@ -76,7 +76,8 @@ namespace TagLib {
+        * Constructs an MPEG file from \a file.  If \a readProperties is true the
+        * file's audio properties will also be read.
+        *
+-       * \note In the current implementation, \a propertiesStyle is ignored.
++       * If \a propertiesStyle is Accurate, the file will be scanned
++       * completely if no ID3v2 tag or MPEG sync code is found at the start.
+        *
+        * \deprecated This constructor will be dropped in favor of the one below
+        * in a future version.
+@@ -91,7 +92,8 @@ namespace TagLib {
+        * If this file contains and ID3v2 tag the frames will be created using
+        * \a frameFactory.
+        *
+-       * \note In the current implementation, \a propertiesStyle is ignored.
++       * If \a propertiesStyle is Accurate, the file will be scanned
++       * completely if no ID3v2 tag or MPEG sync code is found at the start.
+        */
+       // BIC: merge with the above constructor
+       File(FileName file, ID3v2::FrameFactory *frameFactory,
+@@ -108,7 +110,8 @@ namespace TagLib {
+        * If this file contains and ID3v2 tag the frames will be created using
+        * \a frameFactory.
+        *
+-       * \note In the current implementation, \a propertiesStyle is ignored.
++       * If \a propertiesStyle is Accurate, the file will be scanned
++       * completely if no ID3v2 tag or MPEG sync code is found at the start.
+        */
+       File(IOStream *stream, ID3v2::FrameFactory *frameFactory,
+            bool readProperties = true,
+@@ -375,8 +378,8 @@ namespace TagLib {
+       File(const File &);
+       File &operator=(const File &);
+ 
+-      void read(bool readProperties);
+-      long findID3v2();
++      void read(bool readProperties, Properties::ReadStyle);
++      long findID3v2(Properties::ReadStyle);
+ 
+       class FilePrivate;
+       FilePrivate *d;
+diff --git a/taglib/toolkit/taglib.h b/taglib/toolkit/taglib.h
+index ffce61f7..38fee5d1 100644
+--- a/taglib/toolkit/taglib.h
++++ b/taglib/toolkit/taglib.h
+@@ -54,6 +54,9 @@
+ #define TAGLIB_DEPRECATED
+ #endif
+ 
++/* VLC Specific patches implementations */
++#define VLC_PATCHED_TAGLIB_ID3V2_READSTYLE
++
+ #include <string>
+ 
+ //! A namespace for all TagLib related classes and functions
+-- 
+2.33.0
+


=====================================
contrib/src/taglib/SHA512SUMS
=====================================
@@ -1 +1 @@
-7e369faa5e3c6c6401052b7a19e35b0cf8c1e5ed9597053ac731a7718791d5d4803d1b18a93e903ec8c3fc6cb92e34d9616daa2ae4d326965d4c4d5624dcdaba  taglib-1.12.tar.gz
+986231ee62caa975afead7e94630d58acaac25a38bc33d4493d51bd635d79336e81bba60586d7355ebc0670e31f28d32da3ecceaf33292e4bc240c64bf00f35b  taglib-1.13.1.tar.gz


=====================================
contrib/src/taglib/rules.mak
=====================================
@@ -1,6 +1,6 @@
 # TagLib
 
-TAGLIB_VERSION := 1.12
+TAGLIB_VERSION := 1.13.1
 TAGLIB_URL := https://taglib.org/releases/taglib-$(TAGLIB_VERSION).tar.gz
 
 PKGS += taglib
@@ -15,6 +15,7 @@ $(TARBALLS)/taglib-$(TAGLIB_VERSION).tar.gz:
 
 taglib: taglib-$(TAGLIB_VERSION).tar.gz .sum-taglib
 	$(UNPACK)
+	$(APPLY) $(SRC)/taglib/0001-Implement-ID3v2-readStyle-avoid-worst-case.patch
 	$(MOVE)
 
 .taglib: taglib toolchain.cmake


=====================================
modules/meta_engine/taglib.cpp
=====================================
@@ -99,16 +99,28 @@ using namespace TagLib;
 
 
 #include <algorithm>
+#include <limits>
+
+#if TAGLIB_VERSION >= VERSION_INT(1, 13, 0)
+#define USE_IOSTREAM_RESOLVER 1
+#endif
 
 namespace VLCTagLib
 {
     template <class T>
+#ifdef USE_IOSTREAM_RESOLVER
+    class ExtResolver : public FileRef::StreamTypeResolver
+#else
     class ExtResolver : public FileRef::FileTypeResolver
+#endif
     {
         public:
             ExtResolver(const std::string &);
             ~ExtResolver() {}
             virtual File *createFile(FileName, bool, AudioProperties::ReadStyle) const;
+#ifdef USE_IOSTREAM_RESOLVER
+            virtual File *createFileFromStream(IOStream*, bool, AudioProperties::ReadStyle) const;
+#endif
 
         protected:
             std::string ext;
@@ -116,7 +128,7 @@ namespace VLCTagLib
 }
 
 template <class T>
-VLCTagLib::ExtResolver<T>::ExtResolver(const std::string & ext) : FileTypeResolver()
+VLCTagLib::ExtResolver<T>::ExtResolver(const std::string & ext)
 {
     this->ext = ext;
     std::transform(this->ext.begin(), this->ext.end(), this->ext.begin(), ::toupper);
@@ -125,7 +137,11 @@ VLCTagLib::ExtResolver<T>::ExtResolver(const std::string & ext) : FileTypeResolv
 template <class T>
 File *VLCTagLib::ExtResolver<T>::createFile(FileName fileName, bool, AudioProperties::ReadStyle) const
 {
+#if defined(_WIN32) && TAGLIB_VERSION >= VERSION_INT(2, 0, 0)
+    std::string filename = fileName.toString().to8Bit(true);
+#else
     std::string filename = std::string(fileName);
+#endif
     std::size_t namesize = filename.size();
 
     if (namesize > ext.length())
@@ -136,13 +152,35 @@ File *VLCTagLib::ExtResolver<T>::createFile(FileName fileName, bool, AudioProper
             return new T(fileName, false, AudioProperties::Fast);
     }
 
-    return 0;
+    return nullptr;
 }
 
+#ifdef USE_IOSTREAM_RESOLVER
+template<class T>
+File* VLCTagLib::ExtResolver<T>::createFileFromStream(IOStream* s, bool, AudioProperties::ReadStyle) const
+{
+#if defined(_WIN32) && TAGLIB_VERSION >= VERSION_INT(2, 0, 0)
+    std::string filename = s->name().toString().to8Bit(true);
+#else
+    std::string filename = std::string(s->name());
+#endif
+    std::size_t namesize = filename.size();
+
+    if (namesize > ext.length())
+    {
+        std::string fext = filename.substr(namesize - ext.length(), ext.length());
+        std::transform(fext.begin(), fext.end(), fext.begin(), ::toupper);
+        if(fext == ext)
+            return new T(s, ID3v2::FrameFactory::instance(), false, AudioProperties::Fast);
+    }
+
+    return nullptr;
+}
+#endif
+
 #if TAGLIB_VERSION >= TAGLIB_VERSION_1_11
 static VLCTagLib::ExtResolver<MPEG::File> aacresolver(".aac");
 #endif
-static VLCTagLib::ExtResolver<MP4::File> m4vresolver(".m4v");
 static bool b_extensions_registered = false;
 
 // taglib is not thread safe
@@ -167,6 +205,9 @@ public:
     VlcIostream(stream_t* p_stream)
         : m_stream( p_stream )
         , m_previousPos( 0 )
+        , m_borked( false )
+        , m_seqReadLength( 0 )
+        , m_seqReadLimit( std::numeric_limits<long>::max() )
     {
     }
 
@@ -177,17 +218,27 @@ public:
 
     FileName name() const
     {
-        return m_stream->psz_location;
+        // Taglib only cares about the file name part, so it doesn't matter
+        // whether we include the mrl scheme or not
+        return m_stream->psz_url;
     }
 
+#if TAGLIB_VERSION >= VERSION_INT(2, 0, 0)
+    ByteVector readBlock(size_t length)
+#else
     ByteVector readBlock(ulong length)
+#endif
     {
+        if(m_borked || m_seqReadLength >= m_seqReadLimit)
+            return {};
         ByteVector res(length, 0);
         ssize_t i_read = vlc_stream_Read( m_stream, res.data(), length);
         if (i_read < 0)
-            return ByteVector::null;
+            return {};
         else if ((size_t)i_read != length)
             res.resize(i_read);
+        m_previousPos += i_read;
+        m_seqReadLength += i_read;
         return res;
     }
 
@@ -196,11 +247,19 @@ public:
         // Let's stay Read-Only for now
     }
 
+#if TAGLIB_VERSION >= VERSION_INT(2, 0, 0)
+    void insert(const ByteVector&, offset_t, size_t)
+#else
     void insert(const ByteVector&, ulong, ulong)
+#endif
     {
     }
 
+#if TAGLIB_VERSION >= VERSION_INT(2, 0, 0)
+    void removeBlock(offset_t, size_t)
+#else
     void removeBlock(ulong, ulong)
+#endif
     {
     }
 
@@ -214,22 +273,43 @@ public:
         return true;
     }
 
+    void setMaxSequentialRead(long s)
+    {
+        m_seqReadLimit = s;
+    }
+
+#if TAGLIB_VERSION >= VERSION_INT(2, 0, 0)
+    void seek(offset_t offset, Position p)
+#else
     void seek(long offset, Position p)
+#endif
     {
         uint64_t pos = 0;
+        long len;
         switch (p)
         {
             case Current:
                 pos = m_previousPos;
                 break;
             case End:
-                pos = length();
+                len = length();
+                if(len > -1)
+                {
+                    pos = len;
+                }
+                else
+                {
+                    m_borked = true;
+                    return;
+                }
                 break;
             default:
                 break;
         }
-        if (vlc_stream_Seek( m_stream, pos + offset ) == 0)
+        m_borked = (vlc_stream_Seek( m_stream, pos + offset ) != 0);
+        if(!m_borked)
             m_previousPos = pos + offset;
+        m_seqReadLength = 0;
     }
 
     void clear()
@@ -237,12 +317,20 @@ public:
         return;
     }
 
+#if TAGLIB_VERSION >= VERSION_INT(2, 0, 0)
+    offset_t tell() const
+#else
     long tell() const
+#endif
     {
         return m_previousPos;
     }
 
+#if TAGLIB_VERSION >= VERSION_INT(2, 0, 0)
+    offset_t length()
+#else
     long length()
+#endif
     {
         uint64_t i_size;
         if (vlc_stream_GetSize( m_stream, &i_size ) != VLC_SUCCESS)
@@ -250,13 +338,20 @@ public:
         return i_size;
     }
 
+#if TAGLIB_VERSION >= VERSION_INT(2, 0, 0)
+    void truncate(offset_t)
+#else
     void truncate(long)
+#endif
     {
     }
 
 private:
     stream_t* m_stream;
     int64_t m_previousPos;
+    bool m_borked;
+    long m_seqReadLength;
+    long m_seqReadLimit;
 };
 #endif /* TAGLIB_VERSION_1_11 */
 
@@ -461,11 +556,119 @@ static void ReadMetaFromASF( ASF::Tag* tag, demux_meta_t* p_demux_meta, vlc_meta
     }
 }
 
+/**
+ * Fills attachments list from ID3 APIC tags
+ * @param tag: the APIC tags list
+ * @param p_demux_meta: the demuxer meta
+ * @param p_meta: the meta
+ */
+static void ProcessAPICListFromId3v2( const ID3v2::FrameList &list,
+                                      demux_meta_t* p_demux_meta, vlc_meta_t* p_meta )
+{
+    /* Preferred type of image
+     * The 21 types are defined in id3v2 standard:
+     * http://www.id3.org/id3v2.4.0-frames */
+    static const uint8_t scores[] = {
+        0,  /* Other */
+        5,  /* 32x32 PNG image that should be used as the file icon */
+        4,  /* File icon of a different size or format. */
+        20, /* Front cover image of the album. */
+        19, /* Back cover image of the album. */
+        13, /* Inside leaflet page of the album. */
+        18, /* Image from the album itself. */
+        17, /* Picture of the lead artist or soloist. */
+        16, /* Picture of the artist or performer. */
+        14, /* Picture of the conductor. */
+        15, /* Picture of the band or orchestra. */
+        9,  /* Picture of the composer. */
+        8,  /* Picture of the lyricist or text writer. */
+        7,  /* Picture of the recording location or studio. */
+        10, /* Picture of the artists during recording. */
+        11, /* Picture of the artists during performance. */
+        6,  /* Picture from a movie or video related to the track. */
+        1,  /* Picture of a large, coloured fish. */
+        12, /* Illustration related to the track. */
+        3,  /* Logo of the band or performer. */
+        2   /* Logo of the publisher (record company). */
+    };
+
+    const ID3v2::AttachedPictureFrame *defaultPic = nullptr;
+    for( auto iter = list.begin(); iter != list.end(); ++iter )
+    {
+        const ID3v2::AttachedPictureFrame* p =
+                dynamic_cast<const ID3v2::AttachedPictureFrame*>(*iter);
+        if( !p )
+            continue;
+        if(defaultPic == nullptr)
+        {
+            defaultPic = p;
+        }
+        else
+        {
+            int scorea = defaultPic->type() >= ARRAY_SIZE(scores) ? 0 : scores[defaultPic->type()];
+            int scoreb = p->type() >= ARRAY_SIZE(scores) ? 0 : scores[p->type()];
+            if(scoreb > scorea)
+                defaultPic = p;
+        }
+    }
+
+    for( auto iter = list.begin(); iter != list.end(); ++iter )
+    {
+        const ID3v2::AttachedPictureFrame* p =
+                dynamic_cast<const ID3v2::AttachedPictureFrame*>(*iter);
+        if( !p )
+            continue;
+        // Get the mime and description of the image.
+        String description = p->description();
+        String mimeType = p->mimeType();
+
+        /* some old iTunes version not only sets incorrectly the mime type
+         * or the description of the image,
+         * but also embeds incorrectly the image.
+         * Recent versions seem to behave correctly */
+        if( mimeType == "PNG" || description == "\xC2\x89PNG" )
+        {
+            msg_Warn( p_demux_meta, "Invalid picture embedded by broken iTunes version" );
+            continue;
+        }
+
+        char *psz_name;
+        if( asprintf( &psz_name, "%i", p_demux_meta->i_attachments ) == -1 )
+            continue;
+
+        input_attachment_t *p_attachment =
+                vlc_input_attachment_New( psz_name,
+                                          mimeType.toCString(),
+                                          description.toCString(),
+                                          p->picture().data(),
+                                          p->picture().size() );
+        free( psz_name );
+        if( !p_attachment )
+            continue;
+
+        msg_Dbg( p_demux_meta, "Found embedded art: %s (%zu bytes)",
+                 p_attachment->psz_mime, p_attachment->i_data );
+
+        TAB_APPEND_CAST( (input_attachment_t**),
+                         p_demux_meta->i_attachments, p_demux_meta->attachments,
+                         p_attachment );
+
+        if( p == defaultPic )
+        {
+            char *psz_url;
+            if( asprintf( &psz_url, "attachment://%s",
+                          p_attachment->psz_name ) == -1 )
+                continue;
+            vlc_meta_SetArtURL( p_meta, psz_url );
+            free( psz_url );
+        }
+    }
+}
 
 static void ReadMetaFromBasicTag(const Tag* tag, vlc_meta_t *dest)
 {
 #define SET( accessor, meta )                                                  \
-    if( !tag->accessor().isNull() && !tag->accessor().isEmpty() )              \
+    if( !tag->accessor().isEmpty() )                                           \
         vlc_meta_Set##meta( dest, tag->accessor().toCString(true) )
 #define SETINT( accessor, meta )                                               \
     if( tag->accessor() )                                                      \
@@ -511,7 +714,7 @@ static void ReadMetaFromId3v2( ID3v2::Tag* tag, demux_meta_t* p_demux_meta, vlc_
              * but in our case it will be a '\0'
              * terminated string */
             char psz_ufid[64];
-            int max_size = __MIN( p_ufid->identifier().size(), 63);
+            int max_size = std::min<unsigned>( p_ufid->identifier().size(), 63);
             strncpy( psz_ufid, p_ufid->identifier().data(), max_size );
             psz_ufid[max_size] = '\0';
             vlc_meta_SetTrackID( p_meta, psz_ufid );
@@ -580,115 +783,12 @@ static void ReadMetaFromId3v2( ID3v2::Tag* tag, demux_meta_t* p_demux_meta, vlc_
                 vlc_meta_DiscNumber, vlc_meta_DiscTotal );
     }
 
-    /* Preferred type of image
-     * The 21 types are defined in id3v2 standard:
-     * http://www.id3.org/id3v2.4.0-frames */
-    static const int pi_cover_score[] = {
-        0,  /* Other */
-        5,  /* 32x32 PNG image that should be used as the file icon */
-        4,  /* File icon of a different size or format. */
-        20, /* Front cover image of the album. */
-        19, /* Back cover image of the album. */
-        13, /* Inside leaflet page of the album. */
-        18, /* Image from the album itself. */
-        17, /* Picture of the lead artist or soloist. */
-        16, /* Picture of the artist or performer. */
-        14, /* Picture of the conductor. */
-        15, /* Picture of the band or orchestra. */
-        9,  /* Picture of the composer. */
-        8,  /* Picture of the lyricist or text writer. */
-        7,  /* Picture of the recording location or studio. */
-        10, /* Picture of the artists during recording. */
-        11, /* Picture of the artists during performance. */
-        6,  /* Picture from a movie or video related to the track. */
-        1,  /* Picture of a large, coloured fish. */
-        12, /* Illustration related to the track. */
-        3,  /* Logo of the band or performer. */
-        2   /* Logo of the publisher (record company). */
-    };
-    #define PI_COVER_SCORE_SIZE (sizeof (pi_cover_score) / sizeof (pi_cover_score[0]))
-    int i_score = -1;
-
     // Try now to get embedded art
     list = tag->frameListMap()[ "APIC" ];
-    if( list.isEmpty() )
-        return;
-
-    for( iter = list.begin(); iter != list.end(); iter++ )
-    {
-        ID3v2::AttachedPictureFrame* p_apic =
-            dynamic_cast<ID3v2::AttachedPictureFrame*>(*iter);
-        if( !p_apic )
-            continue;
-        input_attachment_t *p_attachment;
-
-        const char *psz_mime;
-        char *psz_name, *psz_description;
-
-        // Get the mime and description of the image.
-        // If the description is empty, take the type as a description
-        psz_mime = p_apic->mimeType().toCString( true );
-        if( p_apic->description().size() > 0 )
-            psz_description = strdup( p_apic->description().toCString( true ) );
-        else
-        {
-            if( asprintf( &psz_description, "%i", p_apic->type() ) == -1 )
-                psz_description = NULL;
-        }
-
-        if( !psz_description )
-            continue;
-        psz_name = psz_description;
-
-        /* some old iTunes version not only sets incorrectly the mime type
-         * or the description of the image,
-         * but also embeds incorrectly the image.
-         * Recent versions seem to behave correctly */
-        if( !strncmp( psz_mime, "PNG", 3 ) ||
-            !strncmp( psz_name, "\xC2\x89PNG", 5 ) )
-        {
-            msg_Warn( p_demux_meta, "Invalid picture embedded by broken iTunes version" );
-            free( psz_description );
-            continue;
-        }
-
-        const ByteVector picture = p_apic->picture();
-        const char *p_data = picture.data();
-        const unsigned i_data = picture.size();
-
-        msg_Dbg( p_demux_meta, "Found embedded art: %s (%s) is %u bytes",
-                 psz_name, psz_mime, i_data );
-
-        p_attachment = vlc_input_attachment_New( psz_name, psz_mime,
-                                psz_description, p_data, i_data );
-        if( !p_attachment )
-        {
-            free( psz_description );
-            continue;
-        }
-        TAB_APPEND_CAST( (input_attachment_t**),
-                         p_demux_meta->i_attachments, p_demux_meta->attachments,
-                         p_attachment );
-        free( psz_description );
-
-        unsigned i_pic_type = p_apic->type();
-        if( i_pic_type >= PI_COVER_SCORE_SIZE )
-            i_pic_type = 0; // Defaults to "Other"
-
-        if( pi_cover_score[i_pic_type] > i_score )
-        {
-            i_score = pi_cover_score[i_pic_type];
-            char *psz_url;
-            if( asprintf( &psz_url, "attachment://%s",
-                          p_attachment->psz_name ) == -1 )
-                continue;
-            vlc_meta_SetArtURL( p_meta, psz_url );
-            free( psz_url );
-        }
-    }
+    if( !list.isEmpty() )
+        ProcessAPICListFromId3v2( list, p_demux_meta, p_meta );
 }
 
-
 /**
  * Read the meta information from XiphComments
  * @param tag: the Xiph Comment
@@ -697,17 +797,20 @@ static void ReadMetaFromId3v2( ID3v2::Tag* tag, demux_meta_t* p_demux_meta, vlc_
  */
 static void ReadMetaFromXiph( Ogg::XiphComment* tag, demux_meta_t* p_demux_meta, vlc_meta_t* p_meta )
 {
-    StringList list;
     bool hasTrackTotal = false;
-#define SET( keyName, metaName )                                               \
-    list = tag->fieldListMap()[keyName];                                       \
-    if( !list.isEmpty() )                                                      \
-        vlc_meta_Set##metaName( p_meta, (*list.begin()).toCString( true ) );
+#define SET( keyName, metaName ) \
+    { \
+        StringList tmp_list { tag->fieldListMap()[keyName] }; \
+        if( !tmp_list.isEmpty() ) \
+            vlc_meta_Set##metaName( p_meta, (*tmp_list.begin()).toCString( true ) ); \
+    }
 
 #define SET_EXTRA( keyName, metaName ) \
-    list = tag->fieldListMap()[keyName]; \
-    if( !list.isEmpty() ) \
-        vlc_meta_AddExtra( p_meta, keyName, (*list.begin()).toCString( true ) );
+    { \
+        StringList tmp_list = tag->fieldListMap()[keyName]; \
+        if( !tmp_list.isEmpty() ) \
+            vlc_meta_AddExtra( p_meta, keyName, (*tmp_list.begin()).toCString( true ) ); \
+    }
 
     SET( "COPYRIGHT", Copyright );
     SET( "ORGANIZATION", Publisher );
@@ -723,25 +826,31 @@ static void ReadMetaFromXiph( Ogg::XiphComment* tag, demux_meta_t* p_demux_meta,
 #undef SET
 #undef SET_EXTRA
 
-    list = tag->fieldListMap()["TRACKNUMBER"];
-    if( !list.isEmpty() )
+    StringList track_number_list = tag->fieldListMap()["TRACKNUMBER"];
+    if( !track_number_list.isEmpty() )
     {
-        int i_values = ExtractCoupleNumberValues( p_meta, (*list.begin()).toCString( true ),
+        int i_values = ExtractCoupleNumberValues( p_meta, (*track_number_list.begin()).toCString( true ),
                  vlc_meta_TrackNumber, vlc_meta_TrackTotal );
         hasTrackTotal = i_values == 2;
     }
     if( !hasTrackTotal )
     {
-        list = tag->fieldListMap()["TRACKTOTAL"];
-        if( list.isEmpty() )
-            list = tag->fieldListMap()["TOTALTRACKS"];
-        if( !list.isEmpty() )
-            vlc_meta_SetTrackTotal( p_meta, (*list.begin()).toCString( true ) );
+        StringList track_total_list { tag->fieldListMap()["TRACKTOTAL"] };
+        if( track_total_list.isEmpty() )
+        {
+            StringList total_tracks_list { tag->fieldListMap()["TOTALTRACKS"] };
+            if( !total_tracks_list.isEmpty() )
+                vlc_meta_SetTrackTotal( p_meta, (*total_tracks_list.begin()).toCString( true ) );
+        }
+        else
+        {
+            vlc_meta_SetTrackTotal( p_meta, (*track_total_list.begin()).toCString( true ) );
+        }
     }
 
     // Try now to get embedded art
-    StringList mime_list = tag->fieldListMap()[ "COVERARTMIME" ];
-    StringList art_list = tag->fieldListMap()[ "COVERART" ];
+    StringList mime_list { tag->fieldListMap()[ "COVERARTMIME" ] };
+    StringList art_list { tag->fieldListMap()[ "COVERART" ] };
 
     input_attachment_t *p_attachment;
 
@@ -757,7 +866,7 @@ static void ReadMetaFromXiph( Ogg::XiphComment* tag, demux_meta_t* p_demux_meta,
         const char* psz_description = "cover";
 
         uint8_t *p_data;
-        int i_data = vlc_b64_decode_binary( &p_data, art_list[0].toCString(true) );
+        int i_data = vlc_b64_decode_binary( &p_data, art_list[0].toCString(false) );
 
         msg_Dbg( p_demux_meta, "Found embedded art: %s (%s) is %i bytes",
                 psz_name, psz_mime, i_data );
@@ -768,14 +877,14 @@ static void ReadMetaFromXiph( Ogg::XiphComment* tag, demux_meta_t* p_demux_meta,
     }
     else
     {
-        art_list = tag->fieldListMap()[ "METADATA_BLOCK_PICTURE" ];
-        if( art_list.size() == 0 )
+        StringList block_picture_list { tag->fieldListMap()[ "METADATA_BLOCK_PICTURE" ] };
+        if( block_picture_list.size() == 0 )
             return;
 
         uint8_t *p_data;
         int i_cover_score;
         int i_cover_idx;
-        int i_data = vlc_b64_decode_binary( &p_data, art_list[0].toCString(true) );
+        int i_data = vlc_b64_decode_binary( &p_data, block_picture_list[0].toCString(false) );
         i_cover_score = i_cover_idx = 0;
         /* TODO: Use i_cover_score / i_cover_idx to select the picture. */
         p_attachment = ParseFlacPicture( p_data, i_data, 0,
@@ -806,15 +915,15 @@ static void ReadMetaFromMP4( MP4::Tag* tag, demux_meta_t *p_demux_meta, vlc_meta
 {
     MP4::Item list;
 #define SET( keyName, metaName )                                                             \
-    if( tag->itemListMap().contains(keyName) )                                               \
+    if( tag->contains(keyName) )                                                             \
     {                                                                                        \
-        list = tag->itemListMap()[keyName];                                                  \
+        list = tag->item(keyName);                                                           \
         vlc_meta_Set##metaName( p_meta, list.toStringList().front().toCString( true ) );     \
     }
 #define SET_EXTRA( keyName, metaName )                                                   \
-    if( tag->itemListMap().contains(keyName) )                                  \
-    {                                                                                \
-        list = tag->itemListMap()[keyName];                                     \
+    if( tag->contains(keyName) )                                                         \
+    {                                                                                    \
+        list = tag->item(keyName);                                                       \
         vlc_meta_AddExtra( p_meta, metaName, list.toStringList().front().toCString( true ) ); \
     }
 
@@ -824,17 +933,17 @@ static void ReadMetaFromMP4( MP4::Tag* tag, demux_meta_t *p_demux_meta, vlc_meta
 #undef SET
 #undef SET_EXTRA
 
-    if( tag->itemListMap().contains("covr") )
+    if( tag->contains("covr") )
     {
-        MP4::CoverArtList list = tag->itemListMap()["covr"].toCoverArtList();
-        const char *psz_format = list[0].format() == MP4::CoverArt::PNG ? "image/png" : "image/jpeg";
+        MP4::CoverArtList cover_list = tag->item("covr").toCoverArtList();
+        const char *psz_format = cover_list[0].format() == MP4::CoverArt::PNG ? "image/png" : "image/jpeg";
 
         msg_Dbg( p_demux_meta, "Found embedded art (%s) is %i bytes",
-                 psz_format, list[0].data().size() );
+                 psz_format, cover_list[0].data().size() );
 
         input_attachment_t *p_attachment =
                 vlc_input_attachment_New( "cover", psz_format, "cover",
-                                          list[0].data().data(), list[0].data().size() );
+                                          cover_list[0].data().data(), cover_list[0].data().size() );
         if( p_attachment )
         {
             TAB_APPEND_CAST( (input_attachment_t**),
@@ -867,6 +976,23 @@ static int ReadWAVMeta( const RIFF::WAV::File *wav, demux_meta_t *demux_meta )
     return VLC_SUCCESS;
 }
 
+static bool isSchemeCompatible( const char *psz_uri )
+{
+    const char *p = strstr( psz_uri, "://" );
+    if( p == NULL )
+        return false;
+
+    size_t i_len = p - psz_uri;
+    const char * compatibleschemes[] =
+    {
+        "file", "smb",
+    };
+    for( size_t i=0; i<ARRAY_SIZE(compatibleschemes); i++ )
+        if( !strncasecmp( psz_uri, compatibleschemes[i], i_len ) )
+            return true;
+    return false;
+}
+
 /**
  * Get the tags from the file using TagLib
  * @param p_this: the demux object
@@ -885,36 +1011,44 @@ static int ReadMeta( vlc_object_t* p_this)
     if( unlikely(psz_uri == NULL) )
         return VLC_ENOMEM;
 
-    char *psz_path = vlc_uri2path( psz_uri );
-#if VLC_WINSTORE_APP && TAGLIB_VERSION >= TAGLIB_VERSION_1_11
-    if( psz_path == NULL )
+    if( !isSchemeCompatible( psz_uri ) )
     {
         free( psz_uri );
         return VLC_EGENERIC;
     }
-    free( psz_path );
 
+    if( !b_extensions_registered )
+    {
+#if TAGLIB_VERSION >= TAGLIB_VERSION_1_11
+        FileRef::addFileTypeResolver( &aacresolver );
+#endif
+        b_extensions_registered = true;
+    }
+
+#if TAGLIB_VERSION >= TAGLIB_VERSION_1_11
     stream_t *p_stream = vlc_access_NewMRL( p_this, psz_uri );
     free( psz_uri );
     if( p_stream == NULL )
         return VLC_EGENERIC;
+    stream_t* p_filter = vlc_stream_FilterNew( p_stream, "prefetch,cache" );
+    if( p_filter )
+        p_stream = p_filter;
 
     VlcIostream s( p_stream );
-    f = FileRef( &s );
-#else /* VLC_WINSTORE_APP */
+#ifndef VLC_PATCHED_TAGLIB_ID3V2_READSTYLE
+    uint64_t dummy;
+    if( vlc_stream_GetSize( p_stream, &dummy ) != VLC_SUCCESS )
+        s.setMaxSequentialRead( 2048 );
+    else
+        s.setMaxSequentialRead( 1024 * 2048 );
+#endif
+    f = FileRef( &s, false, AudioProperties::ReadStyle::Fast );
+#else // !TAGLIB_VERSION_1_11
+    char *psz_path = vlc_uri2path( psz_uri );
     free( psz_uri );
     if( psz_path == NULL )
         return VLC_EGENERIC;
 
-    if( !b_extensions_registered )
-    {
-#if TAGLIB_VERSION >= TAGLIB_VERSION_1_11
-        FileRef::addFileTypeResolver( &aacresolver );
-#endif
-        FileRef::addFileTypeResolver( &m4vresolver );
-        b_extensions_registered = true;
-    }
-
 #if defined(_WIN32)
     wchar_t *wpath = ToWide( psz_path );
     if( wpath == NULL )
@@ -922,23 +1056,13 @@ static int ReadMeta( vlc_object_t* p_this)
         free( psz_path );
         return VLC_EGENERIC;
     }
-#if TAGLIB_VERSION >= TAGLIB_VERSION_1_11
-    FileStream stream( wpath, true );
-    f = FileRef( &stream );
-#else /* TAGLIB_VERSION */
     f = FileRef( wpath );
-#endif /* TAGLIB_VERSION */
     free( wpath );
 #else /* _WIN32 */
-#if TAGLIB_VERSION >= TAGLIB_VERSION_1_11
-    FileStream stream( psz_path, true );
-    f = FileRef( &stream );
-#else /* TAGLIB_VERSION */
     f = FileRef( psz_path );
-#endif /* TAGLIB_VERSION */
 #endif /* _WIN32 */
     free( psz_path );
-#endif /* VLC_WINSTORE_APP */
+#endif // !TAGLIB_VERSION_1_11
 
     if( f.isNull() )
         return VLC_EGENERIC;
@@ -1144,7 +1268,7 @@ static void WriteMetaToId3v2( ID3v2::Tag* tag, input_item_t* p_item )
         fclose( p_file );
         return;
     }
-    off_t file_size = st.st_size;
+    auto file_size = st.st_size;
 
     free( psz_path );
 
@@ -1337,7 +1461,11 @@ static int WriteMeta( vlc_object_t *p_this )
         if( RIFF::AIFF::File* riff_aiff = dynamic_cast<RIFF::AIFF::File*>(f.file()) )
             WriteMetaToId3v2( riff_aiff->tag(), p_item );
         else if( RIFF::WAV::File* riff_wav = dynamic_cast<RIFF::WAV::File*>(f.file()) )
+#if TAGLIB_VERSION >= VERSION_INT(2, 0, 0)
+            WriteMetaToId3v2( riff_wav->ID3v2Tag(), p_item );
+#else
             WriteMetaToId3v2( riff_wav->tag(), p_item );
+#endif
     }
     else if( TrueAudio::File* trueaudio = dynamic_cast<TrueAudio::File*>(f.file()) )
     {



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/1f265fe0b460300d0ffebb261246a971c41dd45e...5ee481afa798f281304754b001572dfe5dc0078e

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/1f265fe0b460300d0ffebb261246a971c41dd45e...5ee481afa798f281304754b001572dfe5dc0078e
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list