Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • videolan/vlc
  • chouquette/vlc
  • bakiewicz.marek122/vlc
  • devnexen/vlc
  • rohanrajpal/vlc
  • blurrrb/vlc
  • gsoc/gsoc2019/darkapex/vlc
  • b1ue/vlc
  • fkuehne/vlc
  • magsoft/vlc
  • chub/vlc
  • cramiro9/vlc
  • robUx4/vlc
  • rom1v/vlc
  • akshayaky/vlc
  • tmk907/vlc
  • akymaster/vlc
  • govind.sharma/vlc
  • psilokos/vlc
  • xjbeta/vlc
  • jahan/vlc
  • 1480c1/vlc
  • amanchande/vlc
  • aaqib/vlc
  • rist/vlc
  • apol/vlc
  • mindfreeze/vlc
  • alexandre-janniaux/vlc
  • sandsmark/vlc
  • jagannatharjun/vlc
  • gsoc/gsoc2020/matiaslgonzalez/vlc
  • gsoc/gsoc2020/jagannatharjun/vlc
  • mstorsjo/vlc
  • gsoc/gsoc2020/vedenta/vlc
  • gsoc/gsoc2020/arnav-ishaan/vlc
  • gsoc/gsoc2020/andreduong/vlc
  • fuzun/vlc
  • gsoc/gsoc2020/vatsin/vlc
  • gsoc/gsoc2020/sagid/vlc
  • yaron/vlc
  • Phoenix/vlc
  • Garf/vlc
  • ePiratWorkarounds/vlc
  • tguillem/vlc
  • jnqnfe/vlc
  • mdc/vlc
  • Vedaa/vlc
  • rasa/vlc
  • quink/vlc
  • yealo/vlc
  • aleksey_ak/vlc
  • ePirat/vlc
  • ilya.yanok/vlc
  • asenat/vlc
  • m/vlc
  • bunjee/vlc
  • BLumia/vlc
  • sagudev/vlc
  • hamedmonji30/vlc
  • nullgemm/vlc
  • DivyamAhuja/vlc
  • thesamesam/vlc
  • dag7/vlc
  • snehil101/vlc
  • haasn/vlc
  • jbk/vlc
  • ValZapod/vlc
  • mfkl/vlc
  • WangChuan/vlc
  • core1024/vlc
  • GhostVaibhav/vlc
  • dfuhrmann/vlc
  • davide.prade/vlc
  • tmatth/vlc
  • Courmisch/vlc
  • zouya/vlc
  • hpi/vlc
  • EwoutH/vlc
  • aleung27/vlc
  • hengwu0/vlc
  • saladin/vlc
  • ashuio/vlc
  • richselwood/vlc
  • verma16Ayush/vlc
  • chemicalflash/vlc
  • PoignardAzur/vlc
  • huangjieNT/vlc
  • Blake-Haydon/vlc
  • AnuthaDev/vlc
  • gsoc/gsoc2021/mpd/vlc
  • nicolas_lequec/vlc
  • sambassaly/vlc
  • thresh/vlc
  • bonniegong/vlc
  • myaashish/vlc
  • stavros.vagionitis/vlc
  • ileoo/vlc
  • louis-santucci/vlc
  • cchristiansen/vlc
  • sabyasachi07/vlc
  • AbduAmeen/vlc
  • ashishb0410/vlc
  • urbanhusky/vlc
  • davidepietrasanta/vlc
  • riksleutelstad/vlc
  • jeremyVignelles/vlc
  • komh/vlc
  • iamjithinjohn/vlc
  • JohannesKauffmann/vlc2
  • kunglao/vlc
  • natzberg/vlc
  • jill/vlc
  • cwendling/vlc
  • adufou/vlc
  • ErwanAirone/vlc
  • HasinduDilshan10/vlc
  • vagrantc/vlc
  • rafiv/macos-bigsur-icon
  • Aymeriic/vlc
  • saranshg20/vlc
  • metzlove24/vlc
  • linkfanel/vlc
  • Ds886/vlc
  • metehan-arslan/vlc
  • Skantes/vlc
  • kgsandundananjaya96/vlc
  • mitchcapper/vlc
  • advaitgupta/vlc
  • StefanBruens/vlc
  • ratajs/vlc
  • T.M.F.B.3761/vlc
  • m222059/vlc
  • casemerrick/vlc
  • joshuaword2alt/vlc
  • sjwaddy/vlc
  • dima/vlc
  • Ybalrid/vlc
  • umxprime/vlc
  • eschmidt/vlc
  • vannieuwenhuysenmichelle/vlc
  • badcf00d/vlc
  • wesinator/vlc
  • louis/vlc
  • xqq/vlc
  • EmperorYP7/vlc
  • NicoLiam/vlc
  • loveleen/vlc
  • rofferom/vlc
  • rbultje/vlc
  • TheUnamed/vlc
  • pratiksharma341/vlc
  • Saurab17/vlc
  • purist.coder/vlc
  • Shuicheng/vlc
  • mdrrubel292/vlc
  • silverbleu00/vlc
  • metif12/vlc
  • asher-m/vlc
  • jeffk/vlc
  • Brandonbr1/vlc
  • beautyyuyanli/vlc
  • rego21/vlc
  • muyangren907/vlc
  • collectionbylawrencejason/vlc
  • evelez/vlc
  • GSMgeeth/vlc
  • Oneric/vlc
  • TJ5/vlc
  • XuanTung95/vlc
  • darrenjenny21/vlc
  • Trenly/vlc
  • RockyTDR/vlc
  • mjakubowski/vlc
  • caprica/vlc
  • ForteFrankie/vlc
  • seannamiller19/vlc
  • junlon2006/vlc
  • kiwiren6666/vlc
  • iuseiphonexs/vlc
  • fenngtun/vlc
  • Rajdutt999/vlc
  • typx/vlc
  • leon.vitanos/vlc
  • robertogarci0938/vlc
  • gsoc/gsoc2022/luc65r/vlc-mpd
  • skeller/vlc
  • MCJack123/vlc
  • luc65r/vlc-mpd
  • popov895/vlc
  • claucambra/vlc
  • brad/vlc
  • matthewmurua88/vlc
  • Tomas8874/vlc
  • philenotfound/vlc
  • makita-do3/vlc
  • LZXCorp/vlc
  • mar0x/vlc
  • senojetkennedy0102/vlc
  • shaneb243/vlc
  • ahmadbader/vlc
  • rajduttcse26/vlc-audio-filters
  • Juniorzito8415/vlc
  • achernyakov/vlc
  • lucasjetgroup/vlc
  • pupdoggy666/vlc
  • gmde9363/vlc
  • alexnwayne/vlc
  • bahareebrahimi781/vlc
  • hamad633666/vlc
  • umghof3112/vlc
  • joe0199771874/vlc
  • Octocats66666666/vlc
  • jjm_223/vlc
  • btech10110.19/vlc
  • sunnykfc028/vlc-audio-filters
  • loic/vlc
  • nguyenminhducmx1/vlc
  • JanekKrueger/vlc
  • bstubbington2/vlc
  • rcombs/vlc
  • Ordissimo/vlc
  • king7532/vlc
  • noobsauce101/vlc
  • schong0525/vlc
  • myQwil/vlc
  • apisbg91/vlc
  • geeboy0101017/vlc
  • kim.faughey/vlc
  • nurupo/vlc
  • yyusea/vlc
  • 0711235879.khco/vlc
  • ialo/vlc
  • iloveyeye2/vlc
  • gdtdftdqtd/vlc
  • leandroconsiglio/vlc
  • AndyHTML2012/vlc
  • ncz/vlc
  • lucenticus/vlc
  • knr1931/vlc
  • kjoonlee/vlc
  • chandrakant100/vlc-qt
  • johge42/vlc
  • polter/vlc
  • hexchain/vlc
  • Tushwrld/vlc
  • mztea928/vlc
  • jbelloncastro/vlc
  • alvinhochun/vlc
  • ghostpiratecrow/vlc
  • ujjwaltwitx/vlc
  • alexsonarin06/vlc
  • adrianbon76/vlc
  • altsod/vlc
  • damien.lucas44/vlc
  • dmytrivtaisa/vlc
  • utk202/vlc
  • aaxhrj/vlc
  • thomas.hermes/vlc
  • structurenewworldorder/vlc
  • slomo/vlc
  • wantlamy/vlc
  • musc.o3cminc/vlc
  • thebarshablog/vlc
  • kerrick/vlc
  • kratos142518/vlc
  • leogps/vlc
  • vacantron/vlc
  • luna_koly/vlc
  • Ratio2/vlc
  • anuoshemohammad/vlc
  • apsun/vlc
  • aaa1115910/vlc
  • alimotmoyo/vlc
  • Ambossmann/vlc
  • Sam-LearnsToCode/vlc
  • Chilledheart/vlc
  • Labnann/vlc
  • ktcoooot1/vlc
  • mohit-marathe/vlc
  • johnddx/vlc
  • manstabuk/vlc
  • Omar-ahmed314/vlc
  • vineethkm/vlc
  • 9Enemi86/vlc
  • radoslav.m.panteleev/vlc
  • ashishami2002/vlc
  • Corbax/vlc
  • firnasahmed/vlc
  • pelayarmalam4/vlc
  • c0ff330k/vlc
  • shikhindahikar/vlc
  • l342723951/vlc
  • christianschwandner/vlc
  • douniwan5788/vlc
  • 7damian7/vlc
  • ferdnyc/vlc
  • f.ales1/vlc
  • pandagby/vlc
  • BaaBaa/vlc
  • jewe37/vlc
  • w00drow/vlc
  • russelltg/vlc
  • ironicallygod/vlc
  • soumyaDghosh/vlc
  • linzihao1999/vlc
  • deyayush6/vlc
  • mibi88/vlc
  • newabdallah10/vlc
  • jhorbincolombia/vlc
  • rimvihaqueshupto/vlc
  • andrewkhon98/vlc
  • fab78/vlc
  • lapaz17/vlc
  • amanna13/vlc
  • mdakram28/vlc
  • 07jw1980/vlc
  • sohamgupta/vlc
  • Eson-Jia1/vlc
  • Sumou/vlc
  • vikram-kangotra/vlc
  • chalice191/vlc
  • olivercalder/vlc
  • aaasg4001/vlc
  • zipdox/vlc
  • kwizart/vlc
  • Dragon-S/vlc
  • jdemeule/vlc
  • gabriel_lt/vlc
  • locutusofborg/vlc
  • sammirata/vlc-librist
  • another/vlc
  • Benjamin_Loison/vlc
  • ahmedmoselhi/vlc
  • petergaal/vlc
  • huynhsontung/vlc
  • dariusmihut/vlc
  • tvermaashutosh/vlc
  • buti/vlc
  • Niram7777/vlc
  • rohan-here/vlc
  • balaji-sivasakthi/vlc
  • rlindner81/vlc
  • Kakadus/vlc
  • djain/vlc
  • ABBurmeister/vlc
  • craighuggins/vlc
  • orbea/vlc
  • maxos/vlc
  • aakarshmj/vlc
  • kblaschke/vlc
  • ankitm/vlc
  • advait-0/vlc
  • mohak2003/vlc
  • yselkowitz/vlc
  • AZM999/vlc-azm
  • andrey.turkin/vlc
  • Disha-Baghel/vlc
  • nowrep/vlc
  • Apeng/vlc
  • Choucroute_melba/vlc
  • autra/vlc
  • eclipseo/vlc
  • fhuber/vlc
  • olafhering/vlc
  • sdasda7777/vlc
  • 1div0/vlc
  • skosnits/vlc-extended-playlist-support
  • dnicolson/vlc
  • Timshel/vlc
  • octopols/vlc
  • MangalK/vlc
  • nima64/vlc
  • misawai/vlc
  • Alexander-Wilms/vlc
  • Maxime2/vlc-fork-for-visualizer
  • ww/vlc
  • jeske/vlc
  • sgross-emlix/vlc
  • morenonatural/vlc
  • freakingLovesVLC/vlc
  • borisgolovnev/vlc
  • mpromonet/vlc
  • diogo.simao-marques/vlc
  • masstock/vlc
  • pratikpatel8982/vlc
  • hugok79/vlc
  • longervision/vlc
  • abhiudaysurya/vlc
  • rishabhgarg/vlc
  • tumic/vlc
  • cart/vlc
  • shubham442/vlc
  • Aditya692005/vlc
  • sammirata/vlc4
  • syrykh/vlc
  • Vvorcun/macos-new-icon
  • AyaanshC/vlc
  • nasso/vlc
  • Quark/vlc
  • sebastinas/vlc
  • rhstone/vlc
  • talregev/vlc
  • Managor/vlc
403 results
Show changes
Commits on Source (30)
From be17e6084a151c901c3946ec7b37afabc3b84f5f Mon Sep 17 00:00:00 2001
From: Francois Cartegnie <fcvlcdev@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
7e369faa5e3c6c6401052b7a19e35b0cf8c1e5ed9597053ac731a7718791d5d4803d1b18a93e903ec8c3fc6cb92e34d9616daa2ae4d326965d4c4d5624dcdaba taglib-1.12.tar.gz
986231ee62caa975afead7e94630d58acaac25a38bc33d4493d51bd635d79336e81bba60586d7355ebc0670e31f28d32da3ecceaf33292e4bc240c64bf00f35b taglib-1.13.1.tar.gz
# 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
......
......@@ -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()) )
{
......