diff --git a/DllAvUtil.h b/DllAvUtil.h index add11662..b75bcf7c 100644 --- a/DllAvUtil.h +++ b/DllAvUtil.h @@ -112,6 +112,7 @@ class DllAvUtilInterface virtual int av_get_bytes_per_sample(enum AVSampleFormat p1) = 0; virtual AVDictionaryEntry *av_dict_get(AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags) = 0; virtual int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)=0; + virtual int av_dict_parse_string(AVDictionary **pm, const char *str, const char *key_val_sep, const char *pairs_sep, int flags)=0; virtual void av_dict_free(AVDictionary **pm) = 0; virtual int av_samples_get_buffer_size (int *linesize, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align) = 0; virtual int64_t av_get_default_channel_layout(int nb_channels)=0; @@ -163,6 +164,7 @@ class DllAvUtilBase : public DllDynamic, DllAvUtilInterface { return ::av_get_bytes_per_sample(p1); } virtual AVDictionaryEntry *av_dict_get(AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags){ return ::av_dict_get(m, key, prev, flags); } virtual int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags) { return ::av_dict_set(pm, key, value, flags); } + virtual int av_dict_parse_string(AVDictionary **pm, const char *str, const char *key_val_sep, const char *pairs_sep, int flags) { return ::av_dict_parse_string(pm, str, key_val_sep, pairs_sep, flags); } virtual void av_dict_free(AVDictionary **pm) { ::av_dict_free(pm); } virtual int av_samples_get_buffer_size (int *linesize, int nb_channels, int nb_samples, enum AVSampleFormat sample_fmt, int align) { return ::av_samples_get_buffer_size(linesize, nb_channels, nb_samples, sample_fmt, align); } @@ -224,6 +226,7 @@ class DllAvUtilBase : public DllDynamic, DllAvUtilInterface DEFINE_METHOD1(int, av_get_bytes_per_sample, (enum AVSampleFormat p1)) DEFINE_METHOD4(AVDictionaryEntry *, av_dict_get, (AVDictionary *p1, const char *p2, const AVDictionaryEntry *p3, int p4)) DEFINE_METHOD4(int, av_dict_set, (AVDictionary **p1, const char *p2, const char *p3, int p4)); + DEFINE_METHOD5(int, av_dict_parse_string, (AVDictionary **p1, const char *p2, const char *p3, const char *p4, int p5)); DEFINE_METHOD1(void, av_dict_free, (AVDictionary **p1)); DEFINE_METHOD5(int, av_samples_get_buffer_size, (int *p1, int p2, int p3, enum AVSampleFormat p4, int p5)) DEFINE_METHOD1(int64_t, av_get_default_channel_layout, (int p1)) @@ -266,6 +269,7 @@ class DllAvUtilBase : public DllDynamic, DllAvUtilInterface RESOLVE_METHOD(av_get_bytes_per_sample) RESOLVE_METHOD(av_dict_get) RESOLVE_METHOD(av_dict_set) + RESOLVE_METHOD(av_dict_parse_string) RESOLVE_METHOD(av_dict_free) RESOLVE_METHOD(av_samples_get_buffer_size) RESOLVE_METHOD(av_get_default_channel_layout) diff --git a/OMXReader.cpp b/OMXReader.cpp index 72eeebb6..121f5379 100644 --- a/OMXReader.cpp +++ b/OMXReader.cpp @@ -134,7 +134,7 @@ static offset_t dvd_file_seek(void *h, offset_t pos, int whence) return pFile->Seek(pos, whence & ~AVSEEK_FORCE); } -bool OMXReader::Open(std::string filename, bool dump_format, bool live /* =false */, float timeout /* = 0.0f */, std::string cookie /* = "" */, std::string user_agent /* = "" */, std::string lavfdopts /* = "" */) +bool OMXReader::Open(std::string filename, bool dump_format, bool live /* =false */, float timeout /* = 0.0f */, std::string cookie /* = "" */, std::string user_agent /* = "" */, std::string lavfdopts /* = "" */, std::string avdict /* = "" */) { if (!m_dllAvUtil.Load() || !m_dllAvCodec.Load() || !m_dllAvFormat.Load()) return false; @@ -169,6 +169,16 @@ bool OMXReader::Open(std::string filename, bool dump_format, bool live /* =false return false; } + AVDictionary *d = NULL; + result = m_dllAvUtil.av_dict_parse_string(&d, avdict.c_str(), ":", ",", 0); + + if (result < 0) + { + CLog::Log(LOGERROR, "COMXPlayer::OpenFile - invalid avdict %s ", avdict.c_str()); + Close(); + return false; + } + // set the interrupt callback, appeared in libavformat 53.15.0 m_pFormatContext->interrupt_callback = int_cb; @@ -195,7 +205,6 @@ bool OMXReader::Open(std::string filename, bool dump_format, bool live /* =false if(idx != string::npos) m_filename = m_filename.substr(0, idx); - AVDictionary *d = NULL; // Enable seeking if http, ftp if(!live && (m_filename.substr(0,7) == "http://" || m_filename.substr(0,6) == "ftp://" || m_filename.substr(0,7) == "sftp://" || m_filename.substr(0,6) == "smb://")) @@ -256,7 +265,8 @@ bool OMXReader::Open(std::string filename, bool dump_format, bool live /* =false } m_pFormatContext->pb = m_ioContext; - result = m_dllAvFormat.avformat_open_input(&m_pFormatContext, m_filename.c_str(), iformat, NULL); + result = m_dllAvFormat.avformat_open_input(&m_pFormatContext, m_filename.c_str(), iformat, &d); + av_dict_free(&d); if(result < 0) { Close(); diff --git a/OMXReader.h b/OMXReader.h index 9ebf6acb..6aa2d032 100644 --- a/OMXReader.h +++ b/OMXReader.h @@ -132,7 +132,7 @@ class OMXReader public: OMXReader(); ~OMXReader(); - bool Open(std::string filename, bool dump_format, bool live = false, float timeout = 0.0f, std::string cookie = "", std::string user_agent = "", std::string lavfdopts = ""); + bool Open(std::string filename, bool dump_format, bool live = false, float timeout = 0.0f, std::string cookie = "", std::string user_agent = "", std::string lavfdopts = "", std::string avdict = ""); void ClearStreams(); bool Close(); //void FlushRead(); diff --git a/README.md b/README.md index 6962552e..eba8a4d3 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,7 @@ Usage: omxplayer [OPTIONS] [FILE] --cookie 'cookie' Send specified cookie as part of HTTP requests --user-agent 'ua' Send specified User-Agent as part of HTTP requests --lavfdopts 'opts' Options passed to libavformat, e.g. 'probesize:250000,...' + --avdict 'opts' Options passed to demuxer, e.g., 'rtsp_transport:tcp,...' For example: diff --git a/omxplayer.cpp b/omxplayer.cpp index 0626e2e7..69529534 100644 --- a/omxplayer.cpp +++ b/omxplayer.cpp @@ -527,6 +527,7 @@ int main(int argc, char *argv[]) std::string m_cookie = ""; std::string m_user_agent = ""; std::string m_lavfdopts = ""; + std::string m_avdict = ""; const int font_opt = 0x100; const int italic_font_opt = 0x201; @@ -567,6 +568,7 @@ int main(int argc, char *argv[]) const int http_cookie_opt = 0x300; const int http_user_agent_opt = 0x301; const int lavfdopts_opt = 0x400; + const int avdict_opt = 0x401; struct option longopts[] = { { "info", no_argument, NULL, 'i' }, @@ -628,6 +630,7 @@ int main(int argc, char *argv[]) { "cookie", required_argument, NULL, http_cookie_opt }, { "user-agent", required_argument, NULL, http_user_agent_opt }, { "lavfdopts", required_argument, NULL, lavfdopts_opt }, + { "avdict", required_argument, NULL, avdict_opt }, { 0, 0, 0, 0 } }; @@ -882,9 +885,12 @@ int main(int argc, char *argv[]) case http_user_agent_opt: m_user_agent = optarg; break; - case lavfdopts_opt: + case lavfdopts_opt: m_lavfdopts = optarg; break; + case avdict_opt: + m_avdict = optarg; + break; case 0: break; case 'h': @@ -1004,7 +1010,7 @@ int main(int argc, char *argv[]) m_keyboard->setDbusName(m_dbus_name); } - if(!m_omx_reader.Open(m_filename.c_str(), m_dump_format, m_config_audio.is_live, m_timeout, m_cookie.c_str(), m_user_agent.c_str(), m_lavfdopts.c_str())) + if(!m_omx_reader.Open(m_filename.c_str(), m_dump_format, m_config_audio.is_live, m_timeout, m_cookie.c_str(), m_user_agent.c_str(), m_lavfdopts.c_str(), m_avdict.c_str())) goto do_exit; if (m_dump_format_exit)