Skip to content
This repository has been archived by the owner on Oct 2, 2024. It is now read-only.

Commit

Permalink
Merge pull request #121 from openmonk/master
Browse files Browse the repository at this point in the history
Get supported media types from gstreamer to avoid hardcoding extensions
  • Loading branch information
anonbeat authored Mar 15, 2021
2 parents 46cd022 + db92043 commit 37840c1
Show file tree
Hide file tree
Showing 18 changed files with 420 additions and 145 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ for the icon and splash designed for guayadeque.

---

# Extra audio playback support
## Extra audio playback support

Various formats support (like `DSD/DSF`) requires ``gstreamer1.0-libav`` package:

Expand Down
4 changes: 0 additions & 4 deletions po/de/guayadeque.po
Original file line number Diff line number Diff line change
Expand Up @@ -1360,10 +1360,6 @@ msgstr "TTA-Dateien"
msgid "mpc files"
msgstr "MPC-Dateien"

#: ImportFiles.cpp:241
msgid "dsd files"
msgstr "DSD-Dateien"

#: ImportFiles.cpp:317 MediaViewer.cpp:1363 MediaViewer.cpp:1382
#: MediaViewer.cpp:1397 Preferences.cpp:947
msgid "track"
Expand Down
4 changes: 0 additions & 4 deletions po/it/guayadeque.po
Original file line number Diff line number Diff line change
Expand Up @@ -1357,10 +1357,6 @@ msgstr "file tta"
msgid "mpc files"
msgstr "file mpc"

#: ImportFiles.cpp:241
msgid "dsd files"
msgstr "file dsd"

#: ImportFiles.cpp:317 MediaViewer.cpp:1363 MediaViewer.cpp:1382
#: MediaViewer.cpp:1397 Preferences.cpp:947
msgid "track"
Expand Down
4 changes: 0 additions & 4 deletions po/nl/guayadeque.po
Original file line number Diff line number Diff line change
Expand Up @@ -1357,10 +1357,6 @@ msgstr "TTA-bestanden"
msgid "mpc files"
msgstr "MPC-bestanden"

#: ImportFiles.cpp:241
msgid "dsd files"
msgstr "DSD-bestanden"

#: ImportFiles.cpp:317 MediaViewer.cpp:1363 MediaViewer.cpp:1382
#: MediaViewer.cpp:1397 Preferences.cpp:947
msgid "track"
Expand Down
4 changes: 0 additions & 4 deletions po/pl/guayadeque.po
Original file line number Diff line number Diff line change
Expand Up @@ -1360,10 +1360,6 @@ msgstr "pliki tta"
msgid "mpc files"
msgstr "pliki mpc"

#: ImportFiles.cpp:241
msgid "dsd files"
msgstr "pliki dsd"

#: ImportFiles.cpp:317 MediaViewer.cpp:1363 MediaViewer.cpp:1382
#: MediaViewer.cpp:1397 Preferences.cpp:947
msgid "track"
Expand Down
231 changes: 231 additions & 0 deletions src/audio/GstTypeFinder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@

#include "GstTypeFinder.h"

namespace Guayadeque {

// -------------------------------------------------------------------------------- //
// guMediaFileExtensions
// -------------------------------------------------------------------------------- //
guMediaFileExtensions::guMediaFileExtensions() : guMediaFileExtensionsHashMap()
{
// do nothing
}

// -------------------------------------------------------------------------------- //
void guMediaFileExtensions::join(guMediaFileExtensions what)
{
guMediaFileExtensions::iterator it;
for( it = what.begin(); it != what.end(); ++it )
{
wxString key = it->first;
wxArrayString arr = it->second;
wxArrayString * myptr = &( this->operator[]( key ) );
for( size_t i=0; i<arr.Count(); i++ )
{
wxString larri = arr[i].Lower();
if( myptr->Index( larri ) == wxNOT_FOUND )
myptr->Add( larri );
}
}
}

// -------------------------------------------------------------------------------- //
// guGstTypeFinder
// -------------------------------------------------------------------------------- //
guGstTypeFinder::guGstTypeFinder()
{
FetchMedia();
}


// -------------------------------------------------------------------------------- //
bool guGstTypeFinder::FetchMedia( void )
{

if( READY )
return true;

if( !gst_is_initialized() )
return false;

m_MediaMutex.Lock();

GList *iter, *plugin_features = gst_registry_get_feature_list(
gst_registry_get(),
GST_TYPE_TYPE_FIND_FACTORY );

for( iter=plugin_features; iter != NULL; iter=iter->next )
{
if( iter->data != NULL )
{
GstPluginFeature *p_feature = GST_PLUGIN_FEATURE( iter->data );
GstTypeFindFactory *factory;
const gchar *const *extensions;
factory = GST_TYPE_FIND_FACTORY( p_feature );
wxArrayString t_value;
extensions = gst_type_find_factory_get_extensions( factory );
if( extensions != NULL )
for( guint i = 0; extensions[i]; i++ )
{
wxString ext = extensions[i];
t_value.Add( ext.Lower() );
}
wxString t_name = gst_plugin_feature_get_name( p_feature );
m_Media[ t_name.Lower() ] = t_value;
}
}
gst_plugin_feature_list_free(plugin_features);
READY = !m_Media.empty();
if( READY )
InitMediaTypes();
m_MediaMutex.Unlock();
return READY;
}

// -------------------------------------------------------------------------------- //
guMediaFileExtensions guGstTypeFinder::GetMediaByPrefix( const wxString& media_type_prefix )
{
FetchMedia();
guMediaFileExtensions res;
guMediaFileExtensions::iterator it;
for( it = m_Media.begin(); it != m_Media.end(); ++it )
{
wxString key = it->first;

if( media_type_prefix.IsNull() || key.StartsWith( media_type_prefix ) )
res[key] = it->second;
}
return res;
}

// -------------------------------------------------------------------------------- //
guMediaFileExtensions guGstTypeFinder::GetMedia( void )
{
guMediaFileExtensions res;
for( size_t i = 0; i<m_MediaTypePrefixes.Count(); ++i )
res.join( GetMediaByPrefix( m_MediaTypePrefixes[i] ) );
return res;
}

// -------------------------------------------------------------------------------- //
wxArrayString guGstTypeFinder::GetMediaTypes( void )
{
wxArrayString res;
for( size_t i = 0; i<m_MediaTypePrefixes.Count(); ++i )
{
wxArrayString sub = GetMediaTypesByPrefix(m_MediaTypePrefixes[i]);
for( size_t j = 0; j<sub.Count(); ++j )
res.Add(sub[j]);

}
return res;
}

// -------------------------------------------------------------------------------- //
wxArrayString guGstTypeFinder::GetMediaTypesByPrefix( const wxString &media_type_prefix )
{
wxArrayString res;
guMediaFileExtensions med = GetMediaByPrefix(media_type_prefix);
guMediaFileExtensions::iterator it;
for( it = med.begin(); it != med.end(); ++it )
res.Add(it->first);
return res;
}

// -------------------------------------------------------------------------------- //
wxArrayString guGstTypeFinder::GetExtensions( void )
{
wxArrayString res;
for( size_t i = 0; i<m_MediaTypePrefixes.Count(); ++i )
{
wxArrayString sub = GetExtensionsByPrefix(m_MediaTypePrefixes[i]);
for( size_t j = 0; j<sub.Count(); ++j )
res.Add(sub[j]);

}
return res;
}

// -------------------------------------------------------------------------------- //
wxArrayString guGstTypeFinder::GetExtensionsByPrefix( const wxString &media_type_prefix )
{
FetchMedia();
wxArrayString res;
guMediaFileExtensions med = GetMediaByPrefix(media_type_prefix);
guMediaFileExtensions::iterator it;
for( it = med.begin(); it != med.end(); ++it )
{
wxArrayString arr = it->second;
for( size_t i = 0; i<arr.Count(); i++)
res.Add(arr[i]);
}
return res;
}

// -------------------------------------------------------------------------------- //
void guGstTypeFinder::AddMediaTypePrefix( const wxString &media_type_prefix )
{
if( m_MediaTypePrefixes.Index( media_type_prefix ) == wxNOT_FOUND )
m_MediaTypePrefixes.Add(media_type_prefix);
}

// -------------------------------------------------------------------------------- //
bool guGstTypeFinder::HasPrefixes( void )
{
return m_MediaTypePrefixes.Count() > 0;
}

void guGstTypeFinder::AddMediaExtension( const wxString &media_type, const wxString &extension )
{
AddMediaTypePrefix(media_type);
if( m_Media.count( media_type ) )
m_Media[ media_type ].Add( extension );
else
{
wxArrayString addme;
addme.Add(extension);
m_Media[ media_type ] = addme;
}
}


void guGstTypeFinder::InitMediaTypes( void )
{

// supported media types
//
AddMediaTypePrefix( "audio/" ); // all gstreamer audio
AddMediaTypePrefix( "video/" ); // all gstreamer video
AddMediaTypePrefix( "avtype_" ); // additional gstreamer formats from libav
AddMediaTypePrefix( "application/mxf" ); // Material Exchange Format
AddMediaTypePrefix( "application/ogg" ); // OGG formats
AddMediaTypePrefix( "application/sdp" ); // SDP mediastream file
AddMediaTypePrefix( "application/smil" ); // Synchronized Multimedia Integration Language
AddMediaTypePrefix( "application/vnd.rn-realmedia" ); // RealMedia
AddMediaTypePrefix( "application/x-pn-realaudio" ); // RealAudio
AddMediaTypePrefix( "application/x-3gp" ); // 3GP video
AddMediaTypePrefix( "application/x-ape" ); // APE
AddMediaTypePrefix( "application/x-hls" ); // UTF8 M3U
AddMediaTypePrefix( "application/x-ogm-audio" ); // sounds like something with sound :)
AddMediaTypePrefix( "application/x-yuv4mpeg" ); // sounds like something with sound :)

// some gstreamer supported formats (DSD & exotic tracker audio)
// are not listed as GST_TYPE_FIND_FACTORY for some reason
// but those are tested to work with gstreamer-libav 1.16.2
//
AddMediaExtension( "application/x-gst-av-dsf", "dsf" ); // DSD
AddMediaExtension( "application/x-gst-av-iff", "maud" ); // Amiga MAUD audio format
AddMediaExtension( "audio/x-ay", "emul" ); // AY Emul
AddMediaExtension( "audio/x-mod", "mmd1" ); // OctaMED MMD1
AddMediaExtension( "audio/x-mod", "mptm" ); // OpenMPT
AddMediaExtension( "audio/x-mod", "okta" ); // Oktalyzer
AddMediaExtension( "audio/x-sid", "psid" ); // PlaySID
AddMediaExtension( "audio/x-svx", "8svx" ); // 8-Bit Sampled Voice
AddMediaExtension( "audio/x-vgm", "vgz" ); // Video Game Music - Sega Megadrive (somtimes only after gunzip)

}

}

// the end :)

69 changes: 69 additions & 0 deletions src/audio/GstTypeFinder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@

#ifndef __GSTTYPEFINDER_H__
#define __GSTTYPEFINDER_H__

#include <gst/gst.h>

#include <wx/string.h>
#include <wx/arrstr.h>
#include <wx/thread.h>
#include <wx/hashmap.h>


namespace Guayadeque {

WX_DECLARE_STRING_HASH_MAP( wxArrayString, guMediaFileExtensionsHashMap );

//
// hashmap to keep stuff
//
class guMediaFileExtensions : public guMediaFileExtensionsHashMap
{
public:
guMediaFileExtensions();
void join(guMediaFileExtensions what);
};

//
// lazy & safe singleton object with some mutex-based sync
// ...otherwise gstreamer crashes the player on me :}
//
class guGstTypeFinder
{
private:
guGstTypeFinder();
guGstTypeFinder(guGstTypeFinder const &copy);
guGstTypeFinder& operator=(guGstTypeFinder const &copy);

protected:

guMediaFileExtensions m_Media;
wxMutex m_MediaMutex;

wxArrayString m_MediaTypePrefixes;

bool READY = false;

void AddMediaExtension( const wxString &media_type, const wxString &extension = wxEmptyString );
bool FetchMedia( void );
void InitMediaTypes( void );
guMediaFileExtensions GetMediaByPrefix( const wxString &media_type_prefix = wxEmptyString );
wxArrayString GetExtensionsByPrefix( const wxString &media_type_prefix = wxEmptyString );
wxArrayString GetMediaTypesByPrefix( const wxString &media_type_prefix = wxEmptyString );
void AddMediaTypePrefix( const wxString &media_type_prefix );

public:

static guGstTypeFinder& getGTF() { static guGstTypeFinder inst; return inst; }

bool HasPrefixes( void );

wxArrayString GetExtensions( void );
wxArrayString GetMediaTypes( void );
guMediaFileExtensions GetMedia( void );

};

}

#endif
Loading

0 comments on commit 37840c1

Please sign in to comment.