Projects
Multimedia
mythtv
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 5
View file
mythtv.changes
Changed
@@ -1,4 +1,55 @@ ------------------------------------------------------------------- +Sun Feb 05 10:24:48 UTC 2017 - avvissu@yandex.by + +- Update to version 0.28.1+git.20170201.03f4403984: + * Add support for A53 captions. + * Fix QT 5.6.1 seg fault in ~QNetworkConfiguration during exit + from program. + * Prevent out of bound access when table is empty. + * Prevent potential out of bound memory access. + * Fix getting stuck in an infinite loop when undeleting a recording. + * Only delete original recording if explictly set. + * Properly handle stride size when transcoding. + * Properly handle stride size when transcoding in fifo mode. + * Fix FIFO transcoding. + * Fixes transcoding when decoder doesn't ouput YUV420 frame. + * Prevent out of bound access when invalid parameters are provided + * Fix RTjpeg transcoding. + * Make --delete act as an override and ignore global settings. + * Bump ABI version. + * Fix small memory leak caused by commit 89bc8e7 + * let IPTV recorder recognize HTTPS urls + * unbreak JW Player menu item (and three other) in the web frontend + * Fixes #12939 - add compatibility for libcec4 + * Fixes #12945 - Add HEVC to the mpegts parser. + * Fixes #12754 - Fix deadlock in libcec initialization. + * Stop mythfilldatabase from creating duplicate channels just + because they are marked as invisible. + * Fix displaying of input connection display name on 'C' or 'Y'. + * musicscanner: Compare music_directory.path as binary + * MythMusic: increase the probe buffer size to 128K + * Fix issue with find recording rules. + * unbreak one-click-installation of JW Player + * ExternalStreamHandler: Don't issue XOFF unless we are not keeping + up with the data. + * don't translate recording status CSS classes (use RecStatusToClass) + * mythzmserver: fix building the server standalone + * Try to find a .clpi file in the range 00000-00200 to generate a + Bluray bookmark. + * Don't allow an inability to create a serial number to prevent + playback of a Bluray disc. + * ExternalStreamHandler: Try and be a little more tolerant of + slighly miss-baving external recorders. + * Lookup the audio and subtitle languages on Blu-ray discs by the + stream ID instead of the index. + * Hide 'invalid' streams from the user. + * Add missing return in the unlikely case that AvFormatDecoderBD + has no Blu-ray ringbuffer. + * Add more checks before trying to determine language of Blu-ray + streams. + * Fixes #12957 - Add categorytype to Program.pm and mythlink.pl + +------------------------------------------------------------------- Wed Nov 30 09:15:07 UTC 2016 - olaf@aepfle.de - BuildRequire yasm instead of yasm-devel to reduce number
View file
mythtv.spec
Changed
@@ -25,7 +25,7 @@ %define GROUP video %define OGROUP audio Name: mythtv -Version: 0.28+git.20161105.1434df8 +Version: 0.28.1+git.20170201.03f4403984 Release: 0 Summary: A personal video recorder (PVR/DVR) application License: GPL-2.0+
View file
_service
Added
@@ -0,0 +1,16 @@ +<services> + <service name="tar_scm" mode="disabled"> + <param name="scm">git</param> + <param name="url">https://github.com/MythTV/mythtv.git</param> + <param name="revision">fixes/0.28</param> + <param name="filename">mythtv-fixes</param> + <param name="versionformat">%cd.%h</param> + <param name="versionprefix">0.28.1+git</param> + <param name="changesgenerate">enable</param> + </service> + <service name="recompress" mode="disabled"> + <param name="file">*.tar</param> + <param name="compression">gz</param> + </service> + <service name="set_version" mode="disabled"/> +</services>
View file
_servicedata
Added
@@ -0,0 +1,4 @@ +<servicedata> +<service name="tar_scm"> + <param name="url">https://github.com/MythTV/mythtv.git</param> + <param name="changesrevision">03f44039848bd09444ff4baa8dc158bd61454079</param></service></servicedata> \ No newline at end of file
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythplugins/mythmusic/mythmusic/remoteavformatcontext.h -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythplugins/mythmusic/mythmusic/remoteavformatcontext.h
Changed
@@ -53,7 +53,7 @@ if (!m_rf->isOpen()) return false; - const int BUFFER_SIZE = 0x10000; + const int BUFFER_SIZE = 0x20000; if (!m_buffer) { m_buffer = (unsigned char*)av_malloc(BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythplugins/mythzoneminder/mythzmserver/README -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythplugins/mythzoneminder/mythzmserver/README
Changed
@@ -17,9 +17,6 @@ be installed in order to compile or run. It does require the mysql client library but that must already be installed for ZM to run. -It's best to run ./configure in the mythplugins directory before copying the source to -the server machine to make sure the config.h is created properly. - Copy the mythzmserver directory to the machine where you want to run the server. run :- 'make -f Makefile.standalone'
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythplugins/mythzoneminder/mythzmserver/zmserver.cpp -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythplugins/mythzoneminder/mythzmserver/zmserver.cpp
Changed
@@ -33,16 +33,14 @@ #else # include <sys/param.h> # include <sys/mount.h> -# if CONFIG_CYGWIN +# ifdef __CYGWIN__ # include <sys/statfs.h> -# else // if !CONFIG_CYGWIN +# else // if !__CYGWIN__ # include <sys/sysctl.h> -# endif // !CONFIG_CYGWIN +# endif // !__CYGWIN__ #endif -#include "mythtv/mythconfig.h" - -#if CONFIG_DARWIN +#ifdef __APPLE__ #define MSG_NOSIGNAL 0 // Apple also has SO_NOSIGPIPE? #endif
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythplugins/mythzoneminder/mythzoneminder/zmliveplayer.h -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythplugins/mythzoneminder/mythzoneminder/zmliveplayer.h
Changed
@@ -48,8 +48,6 @@ Monitor *getMonitor(void) { return &m_monitor; } private: - void getMonitorList(void); - MythUIImage *m_frameImage; MythUIText *m_statusText; MythUIText *m_cameraText; @@ -76,7 +74,6 @@ protected slots: void updateFrame(void); bool initMonitorLayout(int layout); - void getMonitorList(void); protected: MythUIType* GetMythUIType(const QString &name, bool optional = false);
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/README -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/README
Changed
@@ -53,8 +53,8 @@ See the UPGRADING file for information on upgrading between releases. -Compiling and setup instructions are all in the documentation in the docs/ -subdir (or at http://www.mythtv.org/docs/ ) these days. Read those carefully. +Compiling and setup instructions are all in the wiki these day +https://www.mythtv.org/wiki/MythTV-HOWTO keys.txt has a listing of all the various default key bindings. All keybindings can be changed via MythWeb.
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/VERSION -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/VERSION
Changed
@@ -1,1 +1,1 @@ -SOURCE_VERSION="v0.28" +SOURCE_VERSION="v0.28.1"
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/bindings/perl/MythTV/Program.pm -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/bindings/perl/MythTV/Program.pm
Changed
@@ -346,6 +346,7 @@ ($fields{'S'} = ($self->{'subtitle'} or '')) =~ s/%/%%/g; ($fields{'R'} = ($self->{'description'} or '')) =~ s/%/%%/g; ($fields{'C'} = ($self->{'category'} or '')) =~ s/%/%%/g; + ($fields{'Ct'} = ($self->{'categorytype'} or '')) =~ s/%/%%/g; ($fields{'U'} = ($self->{'recgroup'} or '')) =~ s/%/%%/g; # Misc ($fields{'hn'} = ($self->{'hostname'} or '')) =~ s/%/%%/g;
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/contrib/user_jobs/mythlink.pl -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/contrib/user_jobs/mythlink.pl
Changed
@@ -114,6 +114,7 @@ \%ep = Episode (leading zero) \%in = Internet reference number \%C = Category + \%Ct = Category Type \%U = RecGroup \%hn = Hostname of the machine where the file resides \%c = Channel: MythTV chanid
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/external/FFmpeg/libavformat/mpegts-mythtv.c -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/external/FFmpeg/libavformat/mpegts-mythtv.c
Changed
@@ -717,6 +717,7 @@ { 0x10, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG4 }, { 0x11, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AAC_LATM }, /* LATM syntax */ { 0x1b, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_H264 }, + { 0x24, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_HEVC }, { 0xd1, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_DIRAC }, { 0xea, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_VC1 }, { 0 },
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/html/3rdParty/jwplayer.qsp -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/html/3rdParty/jwplayer.qsp
Changed
@@ -1,3 +1,9 @@ +<html><head> +<script src="/js/utility.js"></script> <!-- ECMA not JS --> +<script src="/js/util.qjs"></script> +<script type="text/javascript" src="/3rdParty/jquery/jquery-2.1.4.min.js"></script> +<script type="text/javascript" src="/3rdParty/jquery/jqueryUI/js/jquery-ui-1.10.3.js"></script> +</head><body> <h3>JW Player™ by LongTail Video</h3> <a href='http://www.longtailvideo.com/players/'>JW Player™</a> is a Flash & HTML5 Video Player for FLV, H.264, MP3 and YouTube Videos.<br> @@ -27,15 +33,15 @@ { %> <h3>JW Player™ is <b>not</b> installed.</h3> -<input type=button value='Install JW Player' onClick='installPackage("jwplayer.zip"); loadContent("/3rdParty/jwplayer.qsp");'><br> +<input type=button value='Install JW Player' onClick='installPackage("jwplayer.zip"); loadFrontendContent("/3rdParty/jwplayer.qsp");'><br> <% } else { %> <h3>JW Player™ is installed.</h3> -<input type=button value='Re-Install JW Player' onClick='installPackage("jwplayer.zip"); loadContent("/3rdParty/jwplayer.qsp");'><br> +<input type=button value='Re-Install JW Player' onClick='installPackage("jwplayer.zip"); loadFrontendContent("/3rdParty/jwplayer.qsp");'><br> <% } %> - +</body></html>
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/html/menu.qsp -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/html/menu.qsp
Changed
@@ -29,7 +29,7 @@ <li><a href='#' onClick="hideMainMenu();loadSetupPage('channeleditor')"><i18n>Channel Editor</i18n></a></li> </ul> </li> - <li><a href='#' onClick="hideMainMenu();loadContent('/misc/placeholder.html')"><i18n>Recording Devices</i18n></a></li> + <li><a href='#' onClick="hideMainMenu();loadFrontendContent('/misc/placeholder.html')"><i18n>Recording Devices</i18n></a></li> <li><a href='#' onClick="hideMainMenu();loadSetupPage('storagegroups')"><i18n>Storage Groups</i18n></a></li> <li><a href='#' onClick="hideMainMenu();loadSetupPage('jobqueue')"><i18n>Job Queue</i18n></a></li> <li><a href='#' onClick="hideMainMenu();loadSetupPage('systemevents')"><i18n>System Events</i18n></a></li> @@ -85,8 +85,8 @@ %> <li><a href='#'><i18n>Server Side Scripting</i18n></a> <ul class="acitem"> - <li><a href='#' onClick="hideMainMenu();loadContent('/samples/serverside.qsp', '/samples/js/samples.js')"><i18n>Overview</i18n></a></li> - <li><a href='#' onClick="hideMainMenu();loadContent('/samples/storagegroups.qsp', '/samples/js/samples.js')"><i18n>GetStorageGroups()</i18n></a></li> + <li><a href='#' onClick="hideMainMenu();loadFrontendContent('/samples/serverside.qsp', '/samples/js/samples.js')"><i18n>Overview</i18n></a></li> + <li><a href='#' onClick="hideMainMenu();loadFrontendContent('/samples/storagegroups.qsp', '/samples/js/samples.js')"><i18n>GetStorageGroups()</i18n></a></li> </ul> </li> <% @@ -96,7 +96,7 @@ </li> <li><a href='#'><i18n>3rd Party Software</i18n></a> <ul class="acitem collapsible"> - <li><a class='menuitem' href='#' onClick="hideMainMenu();loadContent('/3rdParty/jwplayer.qsp')"><i18n>JW Player™</i18n></a></li> + <li><a class='menuitem' href='#' onClick="hideMainMenu();loadFrontendContent('/3rdParty/jwplayer.qsp')"><i18n>JW Player™</i18n></a></li> </ul> </li> </ul>
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/html/tv/guide.qsp -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/html/tv/guide.qsp
Changed
@@ -3,6 +3,7 @@ import "/js/utility.js" import "/tv/js/constants.js" +import "/tv/js/tvutil.qjs" var guideOnly = 0; if (getArg("ListOnly")) @@ -342,8 +343,8 @@ var categoryClass = "category_" + toCapitalCase(escapeHTML(program.Category).replace(/ /g, '')) - var statusStr = dvr.RecStatusToString(program.Recording.Status); - var statusClass = "program" + statusStr.replace(/ /g, ''); + // RecStatusToClass() - /tv/js/tvutil.qjs + var statusClass = RecStatusToClass(program.Recording.Status); var menu = "normalMenu scheduleMenu"; if (program.Recording.Status != 0) @@ -396,4 +397,4 @@ </div> <!-- End guideGrid-container --> </body> -<%}%> \ No newline at end of file +<%}%>
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/libs/libmyth/audio/audiooutput.h -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/libs/libmyth/audio/audiooutput.h
Changed
@@ -177,7 +177,7 @@ /** * MAX_SIZE_BUFFER is the maximum size of a buffer to be used with DecodeAudio */ - static const int MAX_SIZE_BUFFER = 192000; + static const int MAX_SIZE_BUFFER = 384000; protected: void Error(const QString &msg);
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/libs/libmythbase/mythversion.h -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/libs/libmythbase/mythversion.h
Changed
@@ -12,7 +12,7 @@ /// Update this whenever the plug-in ABI changes. /// Including changes in the libmythbase, libmyth, libmythtv, libmythav* and /// libmythui class methods in exported headers. -#define MYTH_BINARY_VERSION "0.28.20160309-1" +#define MYTH_BINARY_VERSION "0.28.20161120-1" /** \brief Increment this whenever the MythTV network protocol changes. * Note that the token currently cannot contain spaces.
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/libs/libmythmetadata/musicfilescanner.cpp -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/libs/libmythmetadata/musicfilescanner.cpp
Changed
@@ -195,7 +195,7 @@ // Load the directory id or insert it and get the id query.prepare("SELECT directory_id FROM music_directories " - "WHERE path = :DIRECTORY ;"); + "WHERE path = BINARY :DIRECTORY ;"); query.bindValue(":DIRECTORY", directory); if (!query.exec()) @@ -785,7 +785,7 @@ query.prepare("SELECT CONCAT_WS('/', path, filename), date_modified " "FROM music_songs LEFT JOIN music_directories ON " "music_songs.directory_id=music_directories.directory_id " - "WHERE filename NOT LIKE ('%://%') " + "WHERE filename NOT LIKE BINARY ('%://%') " "AND hostname = :HOSTNAME"); query.bindValue(":HOSTNAME", gCoreContext->GetHostName());
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/libs/libmythtv/Bluray/avformatdecoderbd.cpp -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/libs/libmythtv/Bluray/avformatdecoderbd.cpp
Changed
@@ -12,6 +12,14 @@ { } +bool AvFormatDecoderBD::IsValidStream(int streamid) +{ + if (ringBuffer && ringBuffer->IsBD()) + return ringBuffer->BD()->IsValidStream(streamid); + else + return AvFormatDecoder::IsValidStream(streamid); +} + void AvFormatDecoderBD::Reset(bool reset_video_data, bool seek_reset, bool reset_file) { AvFormatDecoder::Reset(reset_video_data, seek_reset, reset_file); @@ -64,17 +72,27 @@ int AvFormatDecoderBD::GetSubtitleLanguage(uint subtitle_index, uint stream_index) { - (void)stream_index; - if (ringBuffer && ringBuffer->IsBD()) - return ringBuffer->BD()->GetSubtitleLanguage(subtitle_index); + (void)subtitle_index; + if (ringBuffer && ringBuffer->IsBD() && + stream_index < ic->nb_streams && + ic->streams[stream_index] != nullptr) + { + return ringBuffer->BD()->GetSubtitleLanguage(ic->streams[stream_index]->id); + } + return iso639_str3_to_key("und"); } int AvFormatDecoderBD::GetAudioLanguage(uint audio_index, uint stream_index) { - (void)stream_index; - if (ringBuffer && ringBuffer->IsBD()) - return ringBuffer->BD()->GetAudioLanguage(audio_index); + (void)audio_index; + if (ringBuffer && ringBuffer->IsBD() && + stream_index < ic->nb_streams && + ic->streams[stream_index] != nullptr) + { + return ringBuffer->BD()->GetAudioLanguage(ic->streams[stream_index]->id); + } + return iso639_str3_to_key("und"); }
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/libs/libmythtv/Bluray/avformatdecoderbd.h -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/libs/libmythtv/Bluray/avformatdecoderbd.h
Changed
@@ -11,6 +11,9 @@ virtual void Reset(bool reset_video_data, bool seek_reset, bool reset_file); virtual void UpdateFramesPlayed(void); + protected: + virtual bool IsValidStream(int streamid); + private: virtual bool DoRewindSeek(long long desiredFrame); virtual void DoFastForwardSeek(long long desiredFrame, bool &needflush);
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/libs/libmythtv/Bluray/bdringbuffer.cpp -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/libs/libmythtv/Bluray/bdringbuffer.cpp
Changed
@@ -59,6 +59,7 @@ } BDInfo::BDInfo(const QString &filename) + : m_isValid(true) { BLURAY* bdnav = NULL; @@ -120,6 +121,7 @@ { m_lastError = tr("Could not open Blu-ray device: %1").arg(name); LOG(VB_GENERAL, LOG_ERR, QString("BDInfo: ") + m_lastError); + m_isValid = false; } else { @@ -164,7 +166,7 @@ // Try to find the first clip info file and // use its SHA1 hash as a serial number. - for (uint32_t idx = 0; idx < 100; idx++) + for (uint32_t idx = 0; idx < 200; idx++) { QString clip = QString("BDMV/CLIPINF/%1.clpi").arg(idx, 5, 10, QChar('0')); @@ -1025,16 +1027,24 @@ int BDRingBuffer::GetAudioLanguage(uint streamID) { QMutexLocker locker(&m_infoLock); - if (!m_currentTitleInfo || - streamID >= m_currentTitleInfo->clips->audio_stream_count) - return iso639_str3_to_key("und"); - uint8_t lang[4] = { 0, 0, 0, 0 }; - memcpy(lang, m_currentTitleInfo->clips->audio_streams[streamID].lang, 4); - int code = iso639_key_to_canonical_key((lang[0]<<16)|(lang[1]<<8)|lang[2]); + int code = iso639_str3_to_key("und"); - LOG(VB_GENERAL, LOG_INFO, LOC + QString("Audio Lang: %1 Code: %2") - .arg(code).arg(iso639_key_to_str3(code))); + if (m_currentTitleInfo && m_currentTitleInfo->clip_count > 0) + { + bd_clip& clip = m_currentTitleInfo->clips[0]; + + const BLURAY_STREAM_INFO* stream = FindStream(streamID, clip.audio_streams, clip.audio_stream_count); + + if (stream) + { + const uint8_t* lang = stream->lang; + code = iso639_key_to_canonical_key((lang[0]<<16)|(lang[1]<<8)|lang[2]); + } + } + + LOG(VB_GENERAL, LOG_INFO, LOC + QString("Audio Lang: 0x%1 Code: %2") + .arg(code, 3, 16).arg(iso639_key_to_str3(code))); return code; } @@ -1042,32 +1052,26 @@ int BDRingBuffer::GetSubtitleLanguage(uint streamID) { QMutexLocker locker(&m_infoLock); - if (!m_currentTitleInfo) - return iso639_str3_to_key("und"); - int pgCount = m_currentTitleInfo->clips->pg_stream_count; - uint subCount = 0; - for (int i = 0; i < pgCount; ++i) + int code = iso639_str3_to_key("und"); + + if (m_currentTitleInfo && m_currentTitleInfo->clip_count > 0) { - if (m_currentTitleInfo->clips->pg_streams[i].coding_type >= 0x90 && - m_currentTitleInfo->clips->pg_streams[i].coding_type <= 0x92) + bd_clip& clip = m_currentTitleInfo->clips[0]; + + const BLURAY_STREAM_INFO* stream = FindStream(streamID, clip.pg_streams, clip.pg_stream_count); + + if (stream) { - if (streamID == subCount) - { - uint8_t lang[4] = { 0, 0, 0, 0 }; - memcpy(lang, - m_currentTitleInfo->clips->pg_streams[streamID].lang, 4); - int key = (lang[0]<<16)|(lang[1]<<8)|lang[2]; - int code = iso639_key_to_canonical_key(key); - LOG(VB_GENERAL, LOG_INFO, LOC + - QString("Subtitle Lang: %1 Code: %2") - .arg(code).arg(iso639_key_to_str3(code))); - return code; - } - subCount++; + const uint8_t* lang = stream->lang; + code = iso639_key_to_canonical_key((lang[0]<<16)|(lang[1]<<8)|lang[2]); } } - return iso639_str3_to_key("und"); + + LOG(VB_GENERAL, LOG_INFO, LOC + QString("Subtitle Lang: 0x%1 Code: %2") + .arg(code, 3, 16).arg(iso639_key_to_str3(code))); + + return code; } void BDRingBuffer::PressButton(int32_t key, int64_t pts) @@ -1273,6 +1277,48 @@ return m_stillTime > 0 && m_stillMode != BLURAY_STILL_NONE; } +/** + * \brief Find the stream with the given ID from an array of streams. + * \param streamid The stream ID (pid) to look for + * \param streams Pointer to an array of streams + * \param streamCount Number of streams in the array + * \return Pointer to the matching stream if found, otherwise nullptr. + */ +const BLURAY_STREAM_INFO* BDRingBuffer::FindStream(int streamid, BLURAY_STREAM_INFO* streams, int streamCount) const +{ + const BLURAY_STREAM_INFO* stream = nullptr; + + for(int i = 0; i < streamCount && !stream; i++) + { + if (streams[i].pid == streamid) + stream = &streams[i]; + } + + return stream; +} + +bool BDRingBuffer::IsValidStream(int streamid) +{ + bool valid = false; + + if (m_currentTitleInfo && m_currentTitleInfo->clip_count > 0) + { + bd_clip& clip = m_currentTitleInfo->clips[0]; + if( FindStream(streamid,clip.audio_streams, clip.audio_stream_count) || + FindStream(streamid,clip.video_streams, clip.video_stream_count) || + FindStream(streamid,clip.ig_streams, clip.ig_stream_count) || + FindStream(streamid,clip.pg_streams, clip.pg_stream_count) || + FindStream(streamid,clip.sec_audio_streams, clip.sec_audio_stream_count) || + FindStream(streamid,clip.sec_video_streams, clip.sec_video_stream_count) + ) + { + valid = true; + } + } + + return valid; +} + void BDRingBuffer::WaitForPlayer(void) { if (m_ignorePlayerWait)
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/libs/libmythtv/Bluray/bdringbuffer.h -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/libs/libmythtv/Bluray/bdringbuffer.h
Changed
@@ -22,7 +22,7 @@ public: BDInfo(const QString &filename); ~BDInfo(void); - bool IsValid(void) const { return !m_serialnumber.isEmpty(); } + bool IsValid(void) const { return m_isValid; } bool GetNameAndSerialNum(QString &name, QString &serialnum); QString GetLastError(void) const { return m_lastError; } @@ -37,6 +37,7 @@ QString m_name; QString m_serialnumber; QString m_lastError; + bool m_isValid; }; /** \class BDRingBufferPriv @@ -114,6 +115,7 @@ virtual bool IsInMenu(void) const { return m_inMenu; } virtual bool IsInStillFrame(void) const; bool TitleChanged(void); + bool IsValidStream(int streamid); void GetDescForPos(QString &desc); double GetFrameRate(void); @@ -155,6 +157,8 @@ bool HandleBDEvents(void); void HandleBDEvent(BD_EVENT &event); + const BLURAY_STREAM_INFO* FindStream(int streamid, BLURAY_STREAM_INFO* streams, int streamCount) const; + BLURAY *bdnav; bool m_isHDMVNavigation; bool m_tryHDMVNavigation;
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/libs/libmythtv/avformatdecoder.cpp -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/libs/libmythtv/avformatdecoder.cpp
Changed
@@ -2236,6 +2236,19 @@ continue; } + if (!IsValidStream(ic->streams[i]->id)) + { + /* Hide this stream if it's not valid in this context. + * This can happen, for example, on a Blu-ray disc if there + * are more physical streams than there is metadata about them. + * (e.g. Despicable Me) + */ + LOG(VB_PLAYBACK, LOG_INFO, LOC + + QString("Stream 0x%1 is not valid in this context - skipping") + .arg(ic->streams[i]->id, 4, 16)); + continue; + } + if (enc->codec_type == AVMEDIA_TYPE_SUBTITLE) { bool forced = ic->streams[i]->disposition & AV_DISPOSITION_FORCED; @@ -2997,14 +3010,22 @@ if (len < 2+(3*cc_count)) return; + DecodeCCx08(buf+2, cc_count*3, scte); +} + +void AvFormatDecoder::DecodeCCx08(const uint8_t *buf, uint len, bool scte) +{ + if (len < 3) + return; + bool had_608 = false, had_708 = false; - for (uint cur = 0; cur < cc_count; cur++) + for (uint cur = 0; cur + 3 < len; cur += 3) { - uint cc_code = buf[2+(cur*3)]; + uint cc_code = buf[cur]; bool cc_valid = cc_code & 0x04; - uint data1 = buf[3+(cur*3)]; - uint data2 = buf[4+(cur*3)]; + uint data1 = buf[cur+1]; + uint data2 = buf[cur+2]; uint data = (data2 << 8) | data1; uint cc_type = cc_code & 0x03; uint field; @@ -3677,6 +3698,14 @@ for (uint i = 0; i < cc_len; i += ((cc_buf[i] & 0x1f) * 3) + 2) DecodeDTVCC(cc_buf + i, cc_len - i, scte); + if (cc_len == 0) { + // look for A53 captions + AVFrameSideData *side_data = av_frame_get_side_data(mpa_pic, AV_FRAME_DATA_A53_CC); + if (side_data && (side_data->size > 0)) { + DecodeCCx08(side_data->data, side_data->size, false); + } + } + VideoFrame *picframe = (VideoFrame *)(mpa_pic->opaque); if (FlagIsSet(kDecodeNoDecode))
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/libs/libmythtv/avformatdecoder.h -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/libs/libmythtv/avformatdecoder.h
Changed
@@ -216,6 +216,7 @@ friend int close_avf(URLContext *h); void DecodeDTVCC(const uint8_t *buf, uint buf_size, bool scte); + void DecodeCCx08(const uint8_t *buf, uint buf_size, bool scte); void InitByteContext(bool forceseek = false); void InitVideoCodec(AVStream *stream, AVCodecContext *enc, bool selectedStream = false); @@ -263,6 +264,7 @@ virtual void DoFastForwardSeek(long long desiredFrame, bool &needflush); virtual void StreamChangeCheck(void) { } virtual void PostProcessTracks(void) { } + virtual bool IsValidStream(int streamid) {return true;} int DecodeAudio(AVCodecContext *ctx, uint8_t *buffer, int &data_size, AVPacket *pkt);
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/libs/libmythtv/avformatwriter.cpp -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/libs/libmythtv/avformatwriter.cpp
Changed
@@ -24,6 +24,7 @@ //#include "NuppelVideoRecorder.h" #include "avformatwriter.h" #include "audiooutpututil.h" +#include "mythavutil.h" extern "C" { #if HAVE_BIGENDIAN @@ -31,7 +32,6 @@ #endif #include "libavutil/opt.h" #include "libavutil/samplefmt.h" -#include "libavutil/mem.h" // for av_free } #define LOC QString("AVFW(%1): ").arg(m_filename) @@ -235,24 +235,10 @@ int AVFormatWriter::WriteVideoFrame(VideoFrame *frame) { - //AVCodecContext *c = m_videoStream->codec; - - uint8_t *planes[3]; - unsigned char *buf = frame->buf; int framesEncoded = m_framesWritten + m_bufferedVideoFrameTimes.size(); - planes[0] = buf; - planes[1] = planes[0] + frame->width * frame->height; - planes[2] = planes[1] + (frame->width * frame->height) / - 4; // (pictureFormat == AV_PIX_FMT_YUV422P ? 2 : 4); - av_frame_unref(m_picture); - m_picture->data[0] = planes[0]; - m_picture->data[1] = planes[1]; - m_picture->data[2] = planes[2]; - m_picture->linesize[0] = frame->width; - m_picture->linesize[1] = frame->width / 2; - m_picture->linesize[2] = frame->width / 2; + AVPictureFill(reinterpret_cast<AVPicture*>(m_picture), frame); m_picture->pts = framesEncoded + 1; if ((framesEncoded % m_keyFrameDist) == 0)
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/libs/libmythtv/decoderbase.cpp -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/libs/libmythtv/decoderbase.cpp
Changed
@@ -508,7 +508,7 @@ QString(" --> \n\t\t\t[%1:%2(%3),%4:%5(%6)]") .arg(lower_bound) .arg(empty ? -1 : GetKey(m_positionMap[lower_bound])) - .arg(m_positionMap[lower_bound].pos) + .arg(empty ? -1 : m_positionMap[lower_bound].pos) .arg(upper_bound) .arg(empty ? -1 : GetKey(m_positionMap[upper_bound])) .arg(empty ? -1 : m_positionMap[upper_bound].pos));
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/libs/libmythtv/iptvtuningdata.h -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/libs/libmythtv/iptvtuningdata.h
Changed
@@ -209,9 +209,9 @@ m_protocol = IPTVTuningData::rtp; else if (m_data_url.scheme() == "rtsp") m_protocol = IPTVTuningData::rtsp; - else if ((m_data_url.scheme() == "http") && IsHLSPlaylist()) + else if (((m_data_url.scheme() == "http") || (m_data_url.scheme() == "https")) && IsHLSPlaylist()) m_protocol = IPTVTuningData::http_hls; - else if (m_data_url.scheme() == "http") + else if ((m_data_url.scheme() == "http") || (m_data_url.scheme() == "https")) m_protocol = IPTVTuningData::http_ts; else m_protocol = IPTVTuningData::inValid;
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/libs/libmythtv/libmythtv.pro -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/libs/libmythtv/libmythtv.pro
Changed
@@ -251,7 +251,7 @@ inc.path = $${PREFIX}/include/mythtv/ inc.files = playgroup.h inc.files += mythtvexp.h metadataimagehelper.h -inc.files += mythavutil.h +inc.files += mythavutil.h mythframe.h INSTALLS += inc
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/libs/libmythtv/mythavutil.cpp -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/libs/libmythtv/mythavutil.cpp
Changed
@@ -17,7 +17,7 @@ #include "libavfilter/buffersink.h" } -static AVPixelFormat FrameTypeToPixelFormat(VideoFrameType type) +AVPixelFormat FrameTypeToPixelFormat(VideoFrameType type) { switch (type) { @@ -38,7 +38,7 @@ } } -static VideoFrameType PixelFormatToFrameType(AVPixelFormat fmt) +VideoFrameType PixelFormatToFrameType(AVPixelFormat fmt) { switch (fmt) {
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/libs/libmythtv/mythavutil.h -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/libs/libmythtv/mythavutil.h
Changed
@@ -10,6 +10,7 @@ #define MythTV_mythavutil_h #include "mythtvexp.h" // for MUNUSED +#include "mythframe.h" extern "C" { #include "libavcodec/avcodec.h" } @@ -78,7 +79,6 @@ AVFrame *m_frame; }; -typedef struct VideoFrame_ VideoFrame; class MythAVCopyPrivate; /** @@ -128,6 +128,13 @@ AVPixelFormat fmt = AV_PIX_FMT_NONE); /** + * Convert VideoFrameType into FFmpeg's PixelFormat equivalent and + * vice-versa. + */ +MTV_PUBLIC AVPixelFormat FrameTypeToPixelFormat(VideoFrameType type); +MTV_PUBLIC VideoFrameType PixelFormatToFrameType(AVPixelFormat fmt); + +/** * MythPictureDeinterlacer * simple deinterlacer based on FFmpeg's yadif filter. * Yadif requires 3 frames before starting to return a deinterlaced frame.
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/libs/libmythtv/mythframe.h -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/libs/libmythtv/mythframe.h
Changed
@@ -305,7 +305,9 @@ { adj_w = (width + _aligned - 1) & ~(_aligned - 1); } - return (adj_w * height * bpp + 4/* to round up */) / bpb; + // Calculate rounding as necessary. + uint remainder = (adj_w * height * bpp) % bpb; + return (adj_w * height * bpp) / bpb + (remainder ? 1 : 0); } static inline void copybuffer(VideoFrame *dst, uint8_t *buffer,
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/libs/libmythtv/recorders/ExternalStreamHandler.cpp -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/libs/libmythtv/recorders/ExternalStreamHandler.cpp
Changed
@@ -68,7 +68,7 @@ delete[] m_buffer; } -bool ExternIO::Ready(int fd, int timeout) +bool ExternIO::Ready(int fd, int timeout, const QString & what) { #if !defined( USING_MINGW ) && !defined( _MSC_VER ) struct pollfd m_poll[2]; @@ -80,7 +80,7 @@ if (m_poll[0].revents & POLLHUP) { - m_error = "poll eof (POLLHUP)"; + m_error = what + " poll eof (POLLHUP)"; return false; } else if (m_poll[0].revents & POLLNVAL) @@ -111,8 +111,9 @@ return 0; } - if (!Ready(m_appout, timeout)) + if (!Ready(m_appout, timeout, "data")) return 0; + if (m_bufsize < maxlen) { m_bufsize = maxlen; @@ -150,7 +151,7 @@ return QByteArray(); } - if (!Ready(m_apperr, timeout)) + if (!Ready(m_apperr, timeout, "status")) return QByteArray(); char buffer[2048]; @@ -485,6 +486,7 @@ { LOG(VB_RECORD, LOG_INFO, QString("ExternSH: Closing handler for %1") .arg(devname)); + (*it)->CloseApp(); delete *it; m_handlers.erase(it); } @@ -542,6 +544,9 @@ QByteArray buffer; uint len, read_len; uint empty_cnt = 0; + MythTimer timer; + + timer.start(); RunProlog(); @@ -614,7 +619,7 @@ break; } - if (!_running_desired) + if (!_running_desired || _error) break; if (!_listener_lock.tryLock()) @@ -629,18 +634,38 @@ if (xon) { - if (!m_poll_mode) + if (timer.elapsed() >= 2000) + { + // Since we may never need to send the XOFF + // command, occationally check to see if the + // External recorder needs to report an issue. + if (CheckForError()) + { + buffer.clear(); + RestartStream(); + xon = false; + break; + } + timer.restart(); + } + + if (buffer.size() > TOO_FAST_SIZE) { - ProcessCommand(QString("XOFF"), 50, result); - if (result.startsWith("ERR")) + if (!m_poll_mode) { - LOG(VB_GENERAL, LOG_ERR, LOC + - QString("Aborting: XOFF -> %2") - .arg(result)); - _error = true; + // Data is comming a little too fast, so XOFF + // to give us time to process it. + ProcessCommand(QString("XOFF"), 50, result); + if (result.startsWith("ERR")) + { + LOG(VB_GENERAL, LOG_ERR, LOC + + QString("Aborting: XOFF -> %2") + .arg(result)); + _error = true; + } } + xon = false; } - xon = false; } StreamDataList::const_iterator sit = _stream_data_list.begin(); @@ -677,6 +702,7 @@ LOG(VB_GENERAL, LOG_ERR, LOC + QString("Error from External Recorder: %1") .arg(m_error)); + CloseApp(); break; } } @@ -814,7 +840,7 @@ if (!ok) m_error = result; - else if (!result.startsWith("OK:Terminating")) + if (!result.startsWith("OK:Terminating")) { LOG(VB_RECORD, LOG_INFO, LOC + "CloseRecorder failed, sending kill."); @@ -828,6 +854,43 @@ m_IO_lock.unlock(); } +bool ExternalStreamHandler::RestartStream(void) +{ + bool streaming = (StreamingCount() > 0); + int idx; + + LOG(VB_RECORD, LOG_INFO, LOC + "Restarting stream."); + + if (streaming) + { + for (idx = 0; idx < 5; ++idx) + { + ClearError(); + m_IO->ClearError(); + if (StopStreaming()) + break; + usleep(100000); + } + } + + usleep(500000); + + if (streaming) + { + for (idx = 0; idx < 5; ++idx) + { + ClearError(); + m_IO->ClearError(); + if (StartStreaming(false)) + return true; + usleep(100000); + } + return false; + } + + return true; +} + bool ExternalStreamHandler::StartStreaming(bool flush_buffer) { QString result; @@ -985,7 +1048,7 @@ /* Try to keep in sync, if External app was too slow in responding * to previous query, consume the response before sending new query */ - m_IO->GetStatus(5); + m_IO->GetStatus(0); /* Send new query */ m_IO->Write(buf); @@ -1010,8 +1073,7 @@ else m_io_errcnt = 0; - m_notify |= (!result.startsWith("OK") || - (!cmd.startsWith("SendBytes") && !cmd.startsWith("XO"))); + m_notify |= (!result.startsWith("OK") || !cmd.startsWith("SendBytes")); LOG(VB_RECORD, m_notify ? LOG_INFO : LOG_DEBUG, LOC + QString("ProcessCommand('%1') = '%2'").arg(cmd).arg(result)); m_notify = false; @@ -1019,6 +1081,30 @@ return result.startsWith("OK"); } +bool ExternalStreamHandler::CheckForError(void) +{ + QString result; + + QMutexLocker locker(&m_IO_lock); + + if (!m_IO) + { + m_error = "External I/O not ready!"; + LOG(VB_RECORD, LOG_ERR, LOC + m_error); + return true; + } + + if (m_IO->Error()) + { + LOG(VB_GENERAL, LOG_ERR, "External Recorder in bad state: " + + m_IO->ErrorString()); + return true; + } + + result = m_IO->GetStatus(0); + return (result.startsWith("ERR")); +} + void ExternalStreamHandler::PurgeBuffer(void) { if (m_IO)
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/libs/libmythtv/recorders/ExternalStreamHandler.h -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/libs/libmythtv/recorders/ExternalStreamHandler.h
Changed
@@ -23,7 +23,7 @@ ExternIO(const QString & app, const QStringList & args); ~ExternIO(void); - bool Ready(int fd, int timeout); + bool Ready(int fd, int timeout, const QString & what); int Read(QByteArray & buffer, int maxlen, int timeout = 2500); QString GetStatus(int timeout = 2500); int Write(const QByteArray & buffer); @@ -31,6 +31,7 @@ void Term(bool force = false); bool Error(void) const { return !m_error.isEmpty(); } QString ErrorString(void) const { return m_error; } + void ClearError(void) { m_error.clear(); } private: bool KillIfRunning(const QString & cmd); @@ -52,7 +53,7 @@ class ExternalStreamHandler : public StreamHandler { - enum constants {PACKET_SIZE = 188 * 32768}; + enum constants {PACKET_SIZE = 188 * 32768, TOO_FAST_SIZE = 188 * 4196 }; public: static ExternalStreamHandler *Get(const QString &devicename); @@ -70,12 +71,17 @@ bool HasTuner(void) const { return m_hasTuner; } bool HasPictureAttributes(void) const { return m_hasPictureAttributes; } + bool RestartStream(void); + bool StartStreaming(bool flush_buffer); bool StopStreaming(void); + bool CheckForError(void); + void PurgeBuffer(void); QString ErrorString(void) const { return m_error; } + void ClearError(void) { m_error.clear(); _error = false; } bool ProcessCommand(const QString & cmd, uint timeout, QString & result);
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/libs/libmythtv/recorders/NuppelVideoRecorder.cpp -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/libs/libmythtv/recorders/NuppelVideoRecorder.cpp
Changed
@@ -930,10 +930,9 @@ if (!video_buffer_size) { - if (picture_format == AV_PIX_FMT_YUV422P) - video_buffer_size = w_out * h_out * 2; - else - video_buffer_size = w_out * h_out * 3 / 2; + video_buffer_size = + buffersize(picture_format == AV_PIX_FMT_YUV422P ? FMT_YUV422P : FMT_YV12, + w_out, h_out); } if (width >= 480 || height > 288) @@ -2878,19 +2877,15 @@ lzo_uint out_len = OUT_LEN; struct rtframeheader frameheader; int raw = 0, compressthis = compression; - uint8_t *planes[3]; - int len = frame->size; + uint8_t *planes[3] = { + frame->buf + frame->offsets[0], + frame->buf + frame->offsets[1], + frame->buf + frame->offsets[2] }; int fnum = frame->frameNumber; long long timecode = frame->timecode; - unsigned char *buf = frame->buf; memset(&frameheader, 0, sizeof(frameheader)); - planes[0] = buf; - planes[1] = planes[0] + frame->width * frame->height; - planes[2] = planes[1] + (frame->width * frame->height) / - (picture_format == AV_PIX_FMT_YUV422P ? 2 : 4); - if (lf == 0) { // this will be triggered every new file lf = fnum; @@ -2949,23 +2944,7 @@ if (useavcodec) { MythAVFrame mpa_picture; - - switch (picture_format) - { - case AV_PIX_FMT_YUV420P: - case AV_PIX_FMT_YUV422P: - case AV_PIX_FMT_YUVJ420P: - mpa_picture->linesize[0] = w_out; - mpa_picture->linesize[1] = w_out / 2; - mpa_picture->linesize[2] = w_out / 2; - break; - } - mpa_picture->data[0] = planes[0]; - mpa_picture->data[1] = planes[1]; - mpa_picture->data[2] = planes[2]; - mpa_picture->linesize[0] = frame->width; - mpa_picture->linesize[1] = frame->width / 2; - mpa_picture->linesize[2] = frame->width / 2; + AVPictureFill(mpa_picture, frame); if (wantkeyframe) mpa_picture->pict_type = AV_PICTURE_TYPE_I; @@ -2977,7 +2956,7 @@ AVPacket packet; av_init_packet(&packet); packet.data = (uint8_t *)strm; - packet.size = len; + packet.size = frame->size; int got_packet = 0; @@ -3021,14 +3000,14 @@ tmp = rtjc->Compress(strm, planes); } else - tmp = len; + tmp = frame->size; // here is lzo compression afterwards if (compressthis) { int r = 0; if (raw) - r = lzo1x_1_compress((unsigned char*)buf, len, + r = lzo1x_1_compress((unsigned char*)frame->buf, frame->size, out, &out_len, wrkmem); else r = lzo1x_1_compress((unsigned char *)strm, tmp, out, @@ -3052,16 +3031,16 @@ if (mpa_vidcodec->id == AV_CODEC_ID_RAWVIDEO) { frameheader.comptype = '0'; - frameheader.packetlength = len; + frameheader.packetlength = frame->size; WriteFrameheader(&frameheader); - ringBuffer->Write(buf, len); + ringBuffer->Write(frame->buf, frame->size); } else if (hardware_encode) { frameheader.comptype = '4'; - frameheader.packetlength = len; + frameheader.packetlength = frame->size; WriteFrameheader(&frameheader); - ringBuffer->Write(buf, len); + ringBuffer->Write(frame->buf, frame->size); } else { @@ -3083,9 +3062,9 @@ else { frameheader.comptype = '0'; // raw YUV420 - frameheader.packetlength = len; + frameheader.packetlength = frame->size; WriteFrameheader(&frameheader); - ringBuffer->Write(buf, len); // we write buf directly + ringBuffer->Write(frame->buf, frame->size); // we write buf directly } } else
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/libs/libmythtv/test/test_iptvrecorder/test_iptvrecorder.h -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/libs/libmythtv/test/test_iptvrecorder/test_iptvrecorder.h
Changed
@@ -67,6 +67,11 @@ tuning.SetDataURL(QUrl(QString("http://yourdreambox:8001/1:0:1:488:3FE:22F1:EEEE0000:0:0:0:"))); QVERIFY (tuning.IsValid()); QVERIFY (tuning.IsHTTPTS()); + + /* test url from #12820 with https protocol */ + tuning.SetDataURL(QUrl(QString("https://svt10-lh.akamaihd.net/i/svt10_0@77505/master.m3u8"))); + QVERIFY (tuning.IsValid()); + QVERIFY (tuning.IsHTTPTS()); }
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/libs/libmythtv/tv_play.cpp -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/libs/libmythtv/tv_play.cpp
Changed
@@ -7397,8 +7397,8 @@ delete testrec; } - UpdateOSDInput(ctx); UnpauseLiveTV(ctx); + UpdateOSDInput(ctx); ITVRestart(ctx, true); }
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/libs/libmythui/cecadapter.cpp -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/libs/libmythui/cecadapter.cpp
Changed
@@ -33,17 +33,31 @@ // libcec1's callback parameters are pass-by-ref #define CEC_CALLBACK_PARAM_TYPE & #else -// libcec2's callback parameters are pass-by-value +#if CEC_LIB_VERSION_MAJOR <= 3 +// libcec2 and 3 callback parameters are pass-by-value #define CEC_CALLBACK_PARAM_TYPE #endif +#endif // The libCEC callback functions +#if CEC_LIB_VERSION_MAJOR <= 3 static int CECLogMessageCallback(void *adapter, const cec_log_message CEC_CALLBACK_PARAM_TYPE message); static int CECKeyPressCallback(void *adapter, const cec_keypress CEC_CALLBACK_PARAM_TYPE keypress); static int CECCommandCallback(void *adapter, const cec_command CEC_CALLBACK_PARAM_TYPE command); +#endif +#if CEC_LIB_VERSION_MAJOR >= 4 +static void CECLogMessageCallback(void *adapter, const cec_log_message* message); +static void CECKeyPressCallback(void *adapter, const cec_keypress* keypress); +static void CECCommandCallback(void *adapter, const cec_command* command); +#endif #if CEC_LIB_VERSION_MAJOR >= 2 +#if CEC_LIB_VERSION_MAJOR <= 3 static int CECAlertCallback(void *adapter, const libcec_alert alert, const libcec_parameter CEC_CALLBACK_PARAM_TYPE data); +#endif +#if CEC_LIB_VERSION_MAJOR >= 4 +static void CECAlertCallback(void *adapter, const libcec_alert alert, const libcec_parameter data); +#endif static void CECSourceActivatedCallback(void *adapter, const cec_logical_address address, const uint8_t activated); #endif @@ -107,13 +121,24 @@ } // Set up the callbacks +#if CEC_LIB_VERSION_MAJOR <= 3 callbacks.CBCecLogMessage = &CECLogMessageCallback; callbacks.CBCecKeyPress = &CECKeyPressCallback; callbacks.CBCecCommand = &CECCommandCallback; -#if CEC_LIB_VERSION_MAJOR >= 2 +#endif +#if CEC_LIB_VERSION_MAJOR >= 4 + callbacks.logMessage = &CECLogMessageCallback; + callbacks.keyPress = &CECKeyPressCallback; + callbacks.commandReceived = &CECCommandCallback; +#endif +#if CEC_LIB_VERSION_MAJOR >= 2 && CEC_LIB_VERSION_MAJOR <= 3 callbacks.CBCecAlert = &CECAlertCallback; callbacks.CBCecSourceActivated = &CECSourceActivatedCallback; #endif +#if CEC_LIB_VERSION_MAJOR >= 4 + callbacks.alert = &CECAlertCallback; + callbacks.sourceActivated = &CECSourceActivatedCallback; +#endif configuration.callbackParam = this; configuration.callbacks = &callbacks; @@ -130,8 +155,13 @@ adapter->InitVideoStandalone(); // find adapters +#if CEC_LIB_VERSION_MAJOR >= 4 + cec_adapter_descriptor *devices = new cec_adapter_descriptor[MAX_CEC_DEVICES]; + uint8_t num_devices = adapter->DetectAdapters(devices, MAX_CEC_DEVICES, NULL, true); +#else cec_adapter *devices = new cec_adapter[MAX_CEC_DEVICES]; uint8_t num_devices = adapter->FindAdapters(devices, MAX_CEC_DEVICES, NULL); +#endif if (num_devices < 1) { LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to find any CEC devices."); @@ -146,22 +176,37 @@ .arg(num_devices)); for (uint8_t i = 0; i < num_devices; i++) { +#if CEC_LIB_VERSION_MAJOR >= 4 + QString comm = QString::fromLatin1(devices[i].strComName); + QString path = QString::fromLatin1(devices[i].strComPath); +#else QString comm = QString::fromLatin1(devices[i].comm); + QString path = QString::fromLatin1(devices[i].path); +#endif bool match = find ? (comm == defaultDevice) : (i == 0); devicenum = match ? i : devicenum; LOG(VB_GENERAL, LOG_INFO, LOC + QString("Device %1: path '%2' com port '%3' %4").arg(i + 1) - .arg(QString::fromLatin1(devices[i].path)).arg(comm) + .arg(path).arg(comm) .arg(match ? "SELECTED" : "")); } // open adapter - QString path = QString::fromLatin1(devices[devicenum].path); +#if CEC_LIB_VERSION_MAJOR >= 4 + QString comm = QString::fromLatin1(devices[devicenum].strComName); + QString path = QString::fromLatin1(devices[devicenum].strComPath); +#else QString comm = QString::fromLatin1(devices[devicenum].comm); + QString path = QString::fromLatin1(devices[devicenum].path); +#endif LOG(VB_GENERAL, LOG_INFO, LOC + QString("Trying to open device %1 (%2).") .arg(path).arg(comm)); +#if CEC_LIB_VERSION_MAJOR >= 4 + if (!adapter->Open(devices[devicenum].strComName)) +#else if (!adapter->Open(devices[devicenum].comm)) +#endif { LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to open device."); return false; @@ -169,16 +214,14 @@ LOG(VB_GENERAL, LOG_INFO, LOC + "Opened CEC device."); - // all good to go - valid = true; - // turn on tv (if configured) powerOnTV = powerOnTVOnStart; // switch input (if configured) switchInput = true; - HandleActions(); + // all good to go + valid = true; return true; } @@ -216,6 +259,20 @@ return 1; } + void LogMessage(const cec_log_message* message) + { + QString msg(message->message); + int lvl = LOG_UNKNOWN; + switch (message->level) + { + case CEC_LOG_ERROR: lvl = LOG_ERR; break; + case CEC_LOG_WARNING: lvl = LOG_WARNING; break; + case CEC_LOG_NOTICE: lvl = LOG_INFO; break; + case CEC_LOG_DEBUG: lvl = LOG_DEBUG; break; + } + LOG(VB_GENERAL, lvl, LOC + QString("%1").arg(msg)); + } + // NOTE - libcec2 changes the callbacks // to be pass-by-value. // For simplicity, this function remains as pass-by-ref @@ -253,6 +310,29 @@ return 1; } + void HandleCommand(const cec_command* command) + { + if (!adapter || !valid) + return; + + LOG(VB_GENERAL, LOG_DEBUG, LOC + + QString("Command %1 from '%2' (%3) - destination '%4' (%5)") + .arg(command->opcode) + .arg(adapter->ToString(command->initiator)) + .arg(command->initiator) + .arg(adapter->ToString(command->destination)) + .arg(command->destination)); + + switch (command->opcode) + { + // TODO + default: + break; + } + gCoreContext->SendSystemEvent(QString("CEC_COMMAND_RECEIVED COMMAND %1") + .arg(command->opcode)); + } + int HandleKeyPress(const cec_keypress &key) { if (!adapter || !valid) @@ -587,6 +667,335 @@ return 1; } + void HandleKeyPress(const cec_keypress* key) + { + if (!adapter || !valid) + return; + + // Ignore key down events and wait for the key 'up' + if (key->duration < 1) + return; + + QString code; + int action = 0; + switch (key->keycode) + { + case CEC_USER_CONTROL_CODE_NUMBER0: + action = Qt::Key_0; + code = "0"; + break; + case CEC_USER_CONTROL_CODE_NUMBER1: + action = Qt::Key_1; + code = "1"; + break; + case CEC_USER_CONTROL_CODE_NUMBER2: + action = Qt::Key_2; + code = "2"; + break; + case CEC_USER_CONTROL_CODE_NUMBER3: + action = Qt::Key_3; + code = "3"; + break; + case CEC_USER_CONTROL_CODE_NUMBER4: + action = Qt::Key_4; + code = "4"; + break; + case CEC_USER_CONTROL_CODE_NUMBER5: + action = Qt::Key_5; + code = "5"; + break; + case CEC_USER_CONTROL_CODE_NUMBER6: + action = Qt::Key_6; + code = "6"; + break; + case CEC_USER_CONTROL_CODE_NUMBER7: + action = Qt::Key_7; + code = "7"; + break; + case CEC_USER_CONTROL_CODE_NUMBER8: + action = Qt::Key_8; + code = "8"; + break; + case CEC_USER_CONTROL_CODE_NUMBER9: + action = Qt::Key_9; + code = "9"; + break; + case CEC_USER_CONTROL_CODE_SELECT: + action = Qt::Key_Select; + code = "SELECT"; + break; + case CEC_USER_CONTROL_CODE_ENTER: + action = Qt::Key_Enter; + code = "ENTER"; + break; + case CEC_USER_CONTROL_CODE_UP: + action = Qt::Key_Up; + code = "UP"; + break; + case CEC_USER_CONTROL_CODE_DOWN: + action = Qt::Key_Down; + code = "DOWN"; + break; + case CEC_USER_CONTROL_CODE_LEFT: + action = Qt::Key_Left; + code = "LEFT"; + break; + case CEC_USER_CONTROL_CODE_LEFT_UP: + action = Qt::Key_Left; + code = "LEFT_UP"; + break; + case CEC_USER_CONTROL_CODE_LEFT_DOWN: + action = Qt::Key_Left; + code = "LEFT_DOWN"; + break; + case CEC_USER_CONTROL_CODE_RIGHT: + action = Qt::Key_Right; + code = "RIGHT"; + break; + case CEC_USER_CONTROL_CODE_RIGHT_UP: + action = Qt::Key_Right; + code = "RIGHT_UP"; + break; + case CEC_USER_CONTROL_CODE_RIGHT_DOWN: + action = Qt::Key_Right; + code = "RIGHT_DOWN"; + break; + case CEC_USER_CONTROL_CODE_ROOT_MENU: + action = Qt::Key_M; + code = "ROOT_MENU"; + break; + case CEC_USER_CONTROL_CODE_EXIT: + action = Qt::Key_Escape; + code = "EXIT"; + break; + case CEC_USER_CONTROL_CODE_PREVIOUS_CHANNEL: + action = Qt::Key_H; + code = "PREVIOUS_CHANNEL"; + break; + case CEC_USER_CONTROL_CODE_SOUND_SELECT: + action = Qt::Key_Plus; + code = "SOUND_SELECT"; + break; + case CEC_USER_CONTROL_CODE_VOLUME_UP: + action = Qt::Key_VolumeUp; + code = "VOLUME_UP"; + break; + case CEC_USER_CONTROL_CODE_VOLUME_DOWN: + action = Qt::Key_VolumeDown; + code = "VOLUME_DOWN"; + break; + case CEC_USER_CONTROL_CODE_MUTE: + action = Qt::Key_VolumeMute; + code = "MUTE"; + break; + case CEC_USER_CONTROL_CODE_PLAY: + action = Qt::Key_P; + code = "PLAY"; + break; + case CEC_USER_CONTROL_CODE_PAUSE: + action = Qt::Key_P; // same as play + code = "PAUSE"; + break; + case CEC_USER_CONTROL_CODE_STOP: + action = Qt::Key_Stop; + code = "STOP"; + break; + case CEC_USER_CONTROL_CODE_RECORD: + action = Qt::Key_R; + code = "RECORD"; + break; + case CEC_USER_CONTROL_CODE_CLEAR: + action = Qt::Key_Clear; + code = "CLEAR"; + break; + case CEC_USER_CONTROL_CODE_DISPLAY_INFORMATION: + action = Qt::Key_I; + code = "DISPLAY_INFORMATION"; + break; + case CEC_USER_CONTROL_CODE_PAGE_UP: + action = Qt::Key_PageUp; + code = "PAGE_UP"; + break; + case CEC_USER_CONTROL_CODE_PAGE_DOWN: + action = Qt::Key_PageDown; + code = "PAGE_DOWN"; + break; + case CEC_USER_CONTROL_CODE_EJECT: + action = Qt::Key_Eject; + code = "EJECT"; + break; + case CEC_USER_CONTROL_CODE_FORWARD: + action = Qt::Key_Forward; + code = "FORWARD"; + break; + case CEC_USER_CONTROL_CODE_BACKWARD: + action = Qt::Key_Back; + code = "BACKWARD"; + break; + case CEC_USER_CONTROL_CODE_F1_BLUE: + action = Qt::Key_F5; // NB F1 is help and we normally map blue to F5 + code = "F1_BLUE"; + break; + case CEC_USER_CONTROL_CODE_F2_RED: + action = Qt::Key_F2; + code = "F2_RED"; + break; + case CEC_USER_CONTROL_CODE_F3_GREEN: + action = Qt::Key_F3; + code = "F3_GREEN"; + break; + case CEC_USER_CONTROL_CODE_F4_YELLOW: + action = Qt::Key_F4; + code = "F4_YELLOW"; + break; + case CEC_USER_CONTROL_CODE_SETUP_MENU: + action = Qt::Key_M; // Duplicate of Root Menu + code = "SETUP_MENU"; + break; + case CEC_USER_CONTROL_CODE_CONTENTS_MENU: + action = Qt::Key_M; // Duplicate of Root Menu + code = "CONTENTS_MENU"; + break; + case CEC_USER_CONTROL_CODE_FAVORITE_MENU: + action = Qt::Key_M; // Duplicate of Root Menu + code = "FAVORITE_MENU"; + break; + case CEC_USER_CONTROL_CODE_DOT: + action = Qt::Key_Period; + code = "DOT"; + break; + case CEC_USER_CONTROL_CODE_NEXT_FAVORITE: + action = Qt::Key_Slash; + code = "NEXT_FAVORITE"; + break; + case CEC_USER_CONTROL_CODE_INPUT_SELECT: + action = Qt::Key_C; + code = "INPUT_SELECT"; + break; + case CEC_USER_CONTROL_CODE_HELP: + action = Qt::Key_F1; + code = "HELP"; + break; + case CEC_USER_CONTROL_CODE_STOP_RECORD: + action = Qt::Key_R; // Duplicate of Record + code = "STOP_RECORD"; + break; + case CEC_USER_CONTROL_CODE_SUB_PICTURE: + action = Qt::Key_V; + code = "SUB_PICTURE"; + break; + case CEC_USER_CONTROL_CODE_ELECTRONIC_PROGRAM_GUIDE: + action = Qt::Key_S; + code = "ELECTRONIC_PROGRAM_GUIDE"; + break; + case CEC_USER_CONTROL_CODE_POWER: + action = Qt::Key_PowerOff; + code = "POWER"; + break; + + // these codes have 'non-standard' Qt key mappings to ensure + // each code has a unique key mapping + case CEC_USER_CONTROL_CODE_CHANNEL_DOWN: + action = Qt::Key_F20; // to differentiate from Up + code = "CHANNEL_DOWN"; + break; + case CEC_USER_CONTROL_CODE_CHANNEL_UP: + action = Qt::Key_F21; // to differentiate from Down + code = "CHANNEL_UP"; + break; + case CEC_USER_CONTROL_CODE_REWIND: + action = Qt::Key_F22; // to differentiate from Left + code = "REWIND"; + break; + case CEC_USER_CONTROL_CODE_FAST_FORWARD: + action = Qt::Key_F23; // to differentiate from Right + code = "FAST_FORWARD"; + break; + case CEC_USER_CONTROL_CODE_ANGLE: + action = Qt::Key_F24; + code = "ANGLE"; + break; + case CEC_USER_CONTROL_CODE_F5: + action = Qt::Key_F6; // NB! + code = "F5"; + break; + + // codes with no obvious MythTV action + case CEC_USER_CONTROL_CODE_INITIAL_CONFIGURATION: + code = "INITIAL_CONFIGURATION"; + break; + case CEC_USER_CONTROL_CODE_PAUSE_RECORD: + code = "PAUSE_RECORD"; + break; + case CEC_USER_CONTROL_CODE_VIDEO_ON_DEMAND: + code = "VIDEO_ON_DEMAND"; + break; + case CEC_USER_CONTROL_CODE_TIMER_PROGRAMMING: + code = "TIMER_PROGRAMMING"; + break; + case CEC_USER_CONTROL_CODE_UNKNOWN: + code = "UNKNOWN"; + break; + case CEC_USER_CONTROL_CODE_DATA: + code = "DATA"; + break; + + // Functions aren't implemented (similar to macros?) + case CEC_USER_CONTROL_CODE_POWER_ON_FUNCTION: + code = "POWER_ON_FUNCTION"; + break; + case CEC_USER_CONTROL_CODE_PLAY_FUNCTION: + code = "PLAY_FUNCTION"; + break; + case CEC_USER_CONTROL_CODE_PAUSE_PLAY_FUNCTION: + code = "PAUSE_PLAY_FUNCTION"; + break; + case CEC_USER_CONTROL_CODE_RECORD_FUNCTION: + code = "RECORD_FUNCTION"; + break; + case CEC_USER_CONTROL_CODE_PAUSE_RECORD_FUNCTION: + code = "PAUSE_RECORD_FUNCTION"; + break; + case CEC_USER_CONTROL_CODE_STOP_FUNCTION: + code = "STOP_FUNCTION"; + break; + case CEC_USER_CONTROL_CODE_MUTE_FUNCTION: + code = "MUTE_FUNCTION"; + break; + case CEC_USER_CONTROL_CODE_RESTORE_VOLUME_FUNCTION: + code = "RESTORE_VOLUME_FUNCTION"; + break; + case CEC_USER_CONTROL_CODE_TUNE_FUNCTION: + code = "TUNE_FUNCTION"; + break; + case CEC_USER_CONTROL_CODE_SELECT_MEDIA_FUNCTION: + code = "SELECT_MEDIA_FUNCTION"; + break; + case CEC_USER_CONTROL_CODE_SELECT_AV_INPUT_FUNCTION: + code = "SELECT_AV_INPUT_FUNCTION"; + break; + case CEC_USER_CONTROL_CODE_SELECT_AUDIO_INPUT_FUNCTION: + code = "SELECT_AUDIO_INPUT_FUNCTION"; + break; + case CEC_USER_CONTROL_CODE_POWER_TOGGLE_FUNCTION: + code = "POWER_TOGGLE_FUNCTION"; + break; + case CEC_USER_CONTROL_CODE_POWER_OFF_FUNCTION: + code = "POWER_OFF_FUNCTION"; + break; + } + + LOG(VB_GENERAL, LOG_DEBUG, LOC + QString("Keypress %1 %2") + .arg(code).arg(0 == action ? "(Not actioned)" : "")); + + if (0 == action) + return; + + GetMythUI()->ResetScreensaver(); + QKeyEvent* ke = new QKeyEvent(QEvent::KeyPress, action, Qt::NoModifier); + qApp->postEvent(GetMythMainWindow(), (QEvent*)ke); + } + #if CEC_LIB_VERSION_MAJOR >= 2 int HandleAlert(const libcec_alert alert, const libcec_parameter &data) { @@ -737,6 +1146,11 @@ void CECAdapter::run() { RunProlog(); + // Handle any actions at startup + // This is done outside the lock to handle initial setup - + // we know that nothing else can be calling us this early. + m_priv->HandleActions(); + while (IsValid()) { // Note that a lock is used because the QWaitCondition needs it // None of the other HandleActions callers need the lock because @@ -779,6 +1193,7 @@ gActionsReady->wakeAll(); } +#if CEC_LIB_VERSION_MAJOR <= 3 static int CECLogMessageCallback(void *adapter, const cec_log_message CEC_CALLBACK_PARAM_TYPE message) { return ((CECAdapterPriv*)adapter)->LogMessage(message); @@ -793,13 +1208,37 @@ { return ((CECAdapterPriv*)adapter)->HandleCommand(command); } +#endif +#if CEC_LIB_VERSION_MAJOR >= 4 +static void CECLogMessageCallback(void *adapter, const cec_log_message* message) +{ + ((CECAdapterPriv*)adapter)->LogMessage(message); +} + +static void CECKeyPressCallback(void *adapter, const cec_keypress* keypress) +{ + ((CECAdapterPriv*)adapter)->HandleKeyPress(keypress); +} + +static void CECCommandCallback(void *adapter, const cec_command* command) +{ + ((CECAdapterPriv*)adapter)->HandleCommand(command); +} +#endif #if CEC_LIB_VERSION_MAJOR >= 2 +#if CEC_LIB_VERSION_MAJOR <= 3 static int CECAlertCallback(void *adapter, const libcec_alert alert, const libcec_parameter CEC_CALLBACK_PARAM_TYPE data) { return ((CECAdapterPriv*)adapter)->HandleAlert(alert, data); } - +#endif +#if CEC_LIB_VERSION_MAJOR >= 4 +static void CECAlertCallback(void *adapter, const libcec_alert alert, const libcec_parameter data) +{ + ((CECAdapterPriv*)adapter)->HandleAlert(alert, data); +} +#endif static void CECSourceActivatedCallback(void *adapter, const cec_logical_address address, const uint8_t activated) { ((CECAdapterPriv*)adapter)->HandleSourceActivated(address, activated);
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/libs/libmythui/mythuiwebbrowser.cpp -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/libs/libmythui/mythuiwebbrowser.cpp
Changed
@@ -35,6 +35,7 @@ #include <QKeyEvent> #include <QDomDocument> #include <QNetworkCookieJar> +#include <QNetworkConfiguration> #include <unistd.h> // for usleep() @@ -108,6 +109,10 @@ return networkManager; networkManager = new MythNetworkAccessManager(); +// This next line prevents seg fault at program exit in +// QNetworkConfiguration::~QNetworkConfiguration() +// when destructor is called by DestroyNetworkAccessManager + networkManager->setConfiguration(networkManager->configuration()); LOG(VB_GENERAL, LOG_DEBUG, "Copying DLManager's Cookie Jar"); GetMythDownloadManager()->loadCookieJar(GetConfDir() + "/MythBrowser/cookiejar.txt"); networkManager->setCookieJar(GetMythDownloadManager()->copyCookieJar());
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/programs/mythbackend/scheduler.cpp -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/programs/mythbackend/scheduler.cpp
Changed
@@ -2226,8 +2226,8 @@ "SET oldrecduplicate = -1 " "WHERE rm.recordid = :RECORDID " " AND rm.findid = :FINDID"); - query.bindValue("RECORDID", recordid); - query.bindValue("FINDID", findid); + query.bindValue(":RECORDID", recordid); + query.bindValue(":FINDID", findid); if (!query.exec()) MythDB::DBError("ResetDuplicates2", query); }
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/programs/mythfilldatabase/channeldata.cpp -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/programs/mythfilldatabase/channeldata.cpp
Changed
@@ -124,7 +124,7 @@ result = result.toLower(); // Strip all whitespace result = result.replace(" ", ""); - + return result; } @@ -132,8 +132,8 @@ { QHash<QString, ChannelInfo> retList; - ChannelInfoList channelList = ChannelUtil::GetChannels(sourceId, true); - + ChannelInfoList channelList = ChannelUtil::GetChannels(sourceId, false); + ChannelInfoList::iterator it = channelList.begin(); for ( ; it != channelList.end(); ++it) { @@ -234,7 +234,7 @@ } } } - + ChannelInfo dbChan = FindMatchingChannel(*i, existingChannels); if (dbChan.chanid > 0) // Channel exists, updating {
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/programs/mythfrontend/playbackboxhelper.cpp -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/programs/mythfrontend/playbackboxhelper.cpp
Changed
@@ -217,6 +217,7 @@ QStringList &res = (ok) ? successes : failures; res.push_back(QString::number(recordingID)); + list.pop_front(); } if (!successes.empty()) {
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/programs/mythtranscode/commandlineparser.cpp -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/programs/mythtranscode/commandlineparser.cpp
Changed
@@ -113,5 +113,7 @@ ->SetChildOf("hls"); add("--hlsstreamid", "hlsstreamid", -1, "Stream ID to process", "") ->SetChildOf("hls"); + add(QStringList(QStringList() << "-d" << "--delete" ), "delete", false, + "Delete original after successful transcoding", "") + ->SetGroup("Encoding"); } -
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/programs/mythtranscode/main.cpp -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/programs/mythtranscode/main.cpp
Changed
@@ -34,7 +34,7 @@ static void CompleteJob(int jobID, ProgramInfo *pginfo, bool useCutlist, frm_dir_map_t *deleteMap, int &exitCode, - int resultCode); + int resultCode, bool forceDelete); static int glbl_jobID = -1; static QString recorderOptions = ""; @@ -367,6 +367,8 @@ AudioTrackNo = cmdline.toInt("audiotrack"); if (cmdline.toBool("passthru")) passthru = true; + // Set if we want to delete the original file once conversion succeeded. + bool deleteOriginal = cmdline.toBool("delete"); CleanupGuard callCleanup(cleanup); @@ -732,8 +734,8 @@ exitcode = result; } - if (!cmdline.toBool("hls")) - CompleteJob(jobID, pginfo, useCutlist, &deleteMap, exitcode, result); + if (deleteOriginal || jobID >= 0) + CompleteJob(jobID, pginfo, useCutlist, &deleteMap, exitcode, result, deleteOriginal); transcode->deleteLater(); @@ -858,7 +860,7 @@ } static void CompleteJob(int jobID, ProgramInfo *pginfo, bool useCutlist, - frm_dir_map_t *deleteMap, int &exitCode, int resultCode) + frm_dir_map_t *deleteMap, int &exitCode, int resultCode, bool forceDelete) { int status = JOB_UNKNOWN; if (jobID >= 0) @@ -940,7 +942,7 @@ .arg(tmpfile).arg(newfile) + ENO); } - if (!gCoreContext->GetNumSetting("SaveTranscoding", 0)) + if (!gCoreContext->GetNumSetting("SaveTranscoding", 0) || forceDelete) { int err; bool followLinks =
View file
mythtv-fixes-0.28+git.20161105.1434df8.tar.gz/mythtv/programs/mythtranscode/transcode.cpp -> mythtv-fixes-0.28.1+git.20170201.03f4403984.tar.gz/mythtv/programs/mythtranscode/transcode.cpp
Changed
@@ -38,6 +38,7 @@ #include "libavcodec/avcodec.h" #include "libswscale/swscale.h" } +#include "mythavutil.h" #include <unistd.h> // for unlink() @@ -666,6 +667,11 @@ while (loop < options.size()) { QStringList tokens = options[loop].split("="); + if (tokens.length() < 2) + { + LOG(VB_GENERAL, LOG_ERR, "Transcoding aborted, invalid option settings."); + return REENCODE_ERROR; + } recorderOptionsMap[tokens[0]] = tokens[1]; loop++; @@ -900,21 +906,48 @@ return REENCODE_ERROR; } - int vidSize = 0; - - // 1080i/p video is actually 1088 because of the 16x16 blocks so - // we have to fudge the output size here. nuvexport knows how to handle - // this and as of right now it is the only app that uses the fifo ability. - if (video_height == 1080) - vidSize = (1088 * video_width) * 3 / 2; - else - vidSize = (video_height * video_width) * 3 / 2; - VideoFrame frame; - frame.codec = FMT_YV12; - frame.width = newWidth; - frame.height = newHeight; - frame.size = newWidth * newHeight * 3 / 2; + memset(&frame, 0, sizeof(frame)); + // Do not use padding when compressing to RTjpeg or when in fifomode. + // The RTjpeg compressor doesn't know how to handle strides different to + // video width. + bool nonAligned = vidsetting == "RTjpeg" || !fifodir.isEmpty(); + bool rescale = + (video_width != newWidth) || (video_height != newHeight) + || nonAligned; + + if (rescale) + { + size_t newSize; + if (nonAligned) + { + // Set a stride identical to actual width, to ease fifo post-conversion process. + // 1080i/p video is actually 1088 because of the 16x16 blocks so + // we have to fudge the output size here. nuvexport knows how to handle + // this and as of right now it is the only app that uses the fifo ability. + newSize = buffersize(FMT_YV12, video_width, video_height == 1080 ? 1088 : video_height, 0 /* aligned */); + } + else + { + newSize = buffersize(FMT_YV12, newWidth, newHeight); + } + unsigned char *newFrame = (unsigned char *)av_malloc(newSize); + if (!newFrame) + { + // OOM + return REENCODE_ERROR; + } + if (nonAligned) + { + // Set a stride identical to actual width, to ease fifo post-conversion process. + init(&frame, FMT_YV12, newFrame, video_width, video_height, newSize, NULL, NULL, -1, -1, 0 /* aligned */); + } + else + { + // use default stride size. + init(&frame, FMT_YV12, newFrame, newWidth, newHeight, newSize); + } + } if (!fifodir.isEmpty()) { @@ -991,6 +1024,10 @@ // the actual transcode, so stop here. unlink(outputname.toLocal8Bit().constData()); SetPlayerContext(NULL); + if (rescale) + { + av_freep(&frame.buf); + } delete hls; return REENCODE_OK; } @@ -1003,13 +1040,17 @@ LOG(VB_GENERAL, LOG_INFO, "Enforcing sync on fifos"); fifow = new FIFOWriter(2, framecontrol); - if (!fifow->FIFOInit(0, QString("video"), vidfifo, vidSize, 50) || + if (!fifow->FIFOInit(0, QString("video"), vidfifo, frame.size, 50) || !fifow->FIFOInit(1, QString("audio"), audfifo, audio_size, 25)) { LOG(VB_GENERAL, LOG_ERR, "Error initializing fifo writer. Aborting"); unlink(outputname.toLocal8Bit().constData()); SetPlayerContext(NULL); + if (rescale) + { + av_freep(&frame.buf); + } delete hls; return REENCODE_ERROR; } @@ -1048,8 +1089,6 @@ VideoOutput *videoOutput = GetPlayer()->GetVideoOutput(); bool is_key = 0; bool first_loop = true; - unsigned char *newFrame = (unsigned char *)av_malloc(frame.size); - frame.buf = newFrame; AVPicture imageIn, imageOut; struct SwsContext *scontext = NULL; @@ -1106,7 +1145,18 @@ if (fifow) { - frame.buf = lastDecode->buf; + AVPictureFill(&imageIn, lastDecode); + AVPictureFill(&imageOut, &frame); + + scontext = sws_getCachedContext(scontext, + lastDecode->width, lastDecode->height, FrameTypeToPixelFormat(lastDecode->codec), + frame.width, frame.height, FrameTypeToPixelFormat(frame.codec), + SWS_FAST_BILINEAR, NULL, NULL, NULL); + // Typically, wee aren't rescaling per say, we're just correcting the stride set by the decoder. + // However, it allows to properly handle recordings that see their resolution change half-way. + sws_scale(scontext, imageIn.data, imageIn.linesize, 0, + lastDecode->height, imageOut.data, imageOut.linesize); + totalAudio += arb->GetSamples(frame.timecode); int audbufTime = (int)(totalAudio / rateTimeConv); int auddelta = frame.timecode - audbufTime; @@ -1141,7 +1191,7 @@ while (delta > vidFrameTime) { if (!cutter || !cutter->InhibitDummyFrame()) - fifow->FIFOWrite(0, frame.buf, vidSize); + fifow->FIFOWrite(0, frame.buf, frame.size); count++; delta -= (int)vidFrameTime; @@ -1184,7 +1234,7 @@ if (dropvideo < 0) { if (cutter && cutter->InhibitDropFrame()) - fifow->FIFOWrite(0, frame.buf, vidSize); + fifow->FIFOWrite(0, frame.buf, frame.size); LOG(VB_GENERAL, LOG_INFO, "Dropping video frame"); dropvideo++; @@ -1193,12 +1243,12 @@ else { if (!cutter || !cutter->InhibitUseVideoFrame()) - fifow->FIFOWrite(0, frame.buf, vidSize); + fifow->FIFOWrite(0, frame.buf, frame.size); if (dropvideo) { if (!cutter || !cutter->InhibitDummyFrame()) - fifow->FIFOWrite(0, frame.buf, vidSize); + fifow->FIFOWrite(0, frame.buf, frame.size); curFrameNum++; dropvideo--; @@ -1219,7 +1269,10 @@ "is not in raw audio mode."); unlink(outputname.toLocal8Bit().constData()); - av_free(newFrame); + if (rescale) + { + av_freep(&frame.buf); + } SetPlayerContext(NULL); if (videoBuffer) videoBuffer->stop(); @@ -1298,30 +1351,23 @@ writekeyframe = true; } - if ((video_width == newWidth) && (video_height == newHeight)) + if (rescale) { - frame.buf = lastDecode->buf; - } - else - { - frame.buf = newFrame; - avpicture_fill(&imageIn, lastDecode->buf, AV_PIX_FMT_YUV420P, - video_width, video_height); - avpicture_fill(&imageOut, frame.buf, AV_PIX_FMT_YUV420P, - newWidth, newHeight); - - int bottomBand = (video_height == 1088) ? 8 : 0; - scontext = sws_getCachedContext(scontext, video_width, - video_height, AV_PIX_FMT_YUV420P, newWidth, - newHeight, AV_PIX_FMT_YUV420P, + AVPictureFill(&imageIn, lastDecode); + AVPictureFill(&imageOut, &frame); + + int bottomBand = (lastDecode->height == 1088) ? 8 : 0; + scontext = sws_getCachedContext(scontext, + lastDecode->width, lastDecode->height, FrameTypeToPixelFormat(lastDecode->codec), + frame.width, frame.height, FrameTypeToPixelFormat(frame.codec), SWS_FAST_BILINEAR, NULL, NULL, NULL); sws_scale(scontext, imageIn.data, imageIn.linesize, 0, - video_height - bottomBand, + lastDecode->height - bottomBand, imageOut.data, imageOut.linesize); } - nvr->WriteVideo(&frame, true, writekeyframe); + nvr->WriteVideo(rescale ? &frame : lastDecode, true, writekeyframe); } GetPlayer()->GetCC608Reader()->FlushTxtBuffers(); } @@ -1356,26 +1402,19 @@ .arg(newWidth).arg(newHeight)); } - if ((video_width == newWidth) && (video_height == newHeight)) - { - frame.buf = lastDecode->buf; - } - else + if (rescale) { - frame.buf = newFrame; - avpicture_fill(&imageIn, lastDecode->buf, AV_PIX_FMT_YUV420P, - video_width, video_height); - avpicture_fill(&imageOut, frame.buf, AV_PIX_FMT_YUV420P, - newWidth, newHeight); - - int bottomBand = (video_height == 1088) ? 8 : 0; - scontext = sws_getCachedContext(scontext, video_width, - video_height, AV_PIX_FMT_YUV420P, newWidth, - newHeight, AV_PIX_FMT_YUV420P, + AVPictureFill(&imageIn, lastDecode); + AVPictureFill(&imageOut, &frame); + + int bottomBand = (lastDecode->height == 1088) ? 8 : 0; + scontext = sws_getCachedContext(scontext, + lastDecode->width, lastDecode->height, FrameTypeToPixelFormat(lastDecode->codec), + frame.width, frame.height, FrameTypeToPixelFormat(frame.codec), SWS_FAST_BILINEAR, NULL, NULL, NULL); sws_scale(scontext, imageIn.data, imageIn.linesize, 0, - video_height - bottomBand, + lastDecode->height - bottomBand, imageOut.data, imageOut.linesize); } @@ -1418,7 +1457,10 @@ "Transcode: Encountered irrecoverable error in " "NVR::WriteAudio"); - av_free(newFrame); + if (rescale) + { + av_freep(&frame.buf); + } SetPlayerContext(NULL); if (videoBuffer) videoBuffer->stop(); @@ -1463,7 +1505,7 @@ hlsSegmentFrames = 0; } - if (avfw->WriteVideoFrame(&frame) > 0) + if (avfw->WriteVideoFrame(rescale ? &frame : lastDecode) > 0) { lastWrittenTime = frame.timecode + timecodeOffset; if (hls) @@ -1475,9 +1517,9 @@ else { if (forceKeyFrames) - nvr->WriteVideo(&frame, true, true); + nvr->WriteVideo(rescale ? &frame : lastDecode, true, true); else - nvr->WriteVideo(&frame); + nvr->WriteVideo(rescale ? &frame : lastDecode); lastWrittenTime = frame.timecode + timecodeOffset; } } @@ -1508,7 +1550,10 @@ "Transcoding aborted, cutlist updated"); unlink(outputname.toLocal8Bit().constData()); - av_free(newFrame); + if (rescale) + { + av_freep(&frame.buf); + } SetPlayerContext(NULL); if (videoBuffer) videoBuffer->stop(); @@ -1523,7 +1568,10 @@ "Transcoding STOPped by JobQueue"); unlink(outputname.toLocal8Bit().constData()); - av_free(newFrame); + if (rescale) + { + av_freep(&frame.buf); + } SetPlayerContext(NULL); if (videoBuffer) videoBuffer->stop(); @@ -1624,7 +1672,10 @@ videoBuffer->stop(); } - av_free(newFrame); + if (rescale) + { + av_freep(&frame.buf); + } SetPlayerContext(NULL); return REENCODE_OK;
View file
tmp_service
Deleted
@@ -1,16 +0,0 @@ -<services> - <service name="tar_scm" mode="disabled"> - <param name="scm">git</param> - <param name="url">https://github.com/MythTV/mythtv.git</param> - <param name="revision">fixes/0.28</param> - <param name="filename">mythtv-fixes</param> - <param name="versionformat">%cd.%h</param> - <param name="versionprefix">0.28+git</param> - <param name="changesgenerate">enable</param> - </service> - <service name="recompress" mode="disabled"> - <param name="file">*.tar</param> - <param name="compression">gz</param> - </service> - <service name="set_version" mode="disabled"/> -</services>
View file
tmp_servicedata
Deleted
@@ -1,4 +0,0 @@ -<servicedata> -<service name="tar_scm"> - <param name="url">https://github.com/MythTV/mythtv.git</param> - <param name="changesrevision">1434df8592ad6bf1eae4fd2eb46955e0adedc8aa</param></service></servicedata> \ No newline at end of file
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.