diff -rup mythtv.orig/libs/libavcodec/avcodec.h mythtv/libs/libavcodec/avcodec.h --- mythtv.orig/libs/libavcodec/avcodec.h 2008-03-03 13:28:28.000000000 -0500 +++ mythtv/libs/libavcodec/avcodec.h 2008-03-09 16:44:25.000000000 -0400 @@ -289,6 +289,9 @@ enum CodecID { /* DSMCC codec */ CODEC_ID_DSMCC_B, + /* Private Data */ + CODEC_ID_DVB_PRIVSEC= 0x18000, + CODEC_ID_MPEG2TS= 0x20000, /* _FAKE_ codec to indicate a raw MPEG-2 TS * stream (only used by libavformat) */ }; diff -rup mythtv.orig/libs/libavcodec/myth_utils.c mythtv/libs/libavcodec/myth_utils.c --- mythtv.orig/libs/libavcodec/myth_utils.c 2008-03-03 13:28:28.000000000 -0500 +++ mythtv/libs/libavcodec/myth_utils.c 2008-03-09 15:51:46.000000000 -0400 @@ -203,6 +203,9 @@ const char *codec_id_string(enum CodecID case CODEC_ID_DSMCC_B: return "DSMCC_B"; + /* private data codecs */ + case CODEC_ID_DVB_PRIVSEC: return "DVB_PRIVSEC"; + case CODEC_ID_MPEG2TS: return "MPEG2TS"; } return "Unknown Codec ID"; diff -rup mythtv.orig/libs/libavformat/mpegts.c mythtv/libs/libavformat/mpegts.c --- mythtv.orig/libs/libavformat/mpegts.c 2008-03-03 13:28:30.000000000 -0500 +++ mythtv/libs/libavformat/mpegts.c 2008-03-12 14:53:18.000000000 -0400 @@ -866,6 +866,7 @@ static int is_desired_stream(int stream_ case STREAM_TYPE_AUDIO_AAC: case STREAM_TYPE_AUDIO_AC3: case STREAM_TYPE_AUDIO_DTS: + case STREAM_TYPE_PRIVATE_SECTION: case STREAM_TYPE_PRIVATE_DATA: case STREAM_TYPE_VBI_DVB: case STREAM_TYPE_SUBTITLE_DVB: @@ -1454,6 +1455,10 @@ static void init_stream(AVStream *st, in codec_type = CODEC_TYPE_DATA; codec_id = CODEC_ID_DSMCC_B; break; + case STREAM_TYPE_PRIVATE_SECTION: + codec_type = CODEC_TYPE_DATA; + codec_id = CODEC_ID_DVB_PRIVSEC; + break; case STREAM_TYPE_PRIVATE_DATA: default: if (code >= 0x1c0 && code <= 0x1df) { @@ -1553,6 +1558,15 @@ static void mpegts_push_data(void *opaqu if (pes->total_size) pes->total_size += 6; pes->pes_header_size = pes->header[8] + 9; + } else if (pes->header[0] == 0x00 && pes->header[1] == 0xd3 && + pes->header[2] == 0xb0) { + /* it must be a generic data stream */ + if (!pes->st) { + /* allocate stream */ + new_pes_av_stream(pes, code); + } + + pes->state = MPEGTS_PAYLOAD; } else { /* otherwise, it should be a table */ /* skip packet */ diff -rup mythtv.orig/libs/libmythtv/NuppelVideoPlayer.cpp mythtv/libs/libmythtv/NuppelVideoPlayer.cpp --- mythtv.orig/libs/libmythtv/NuppelVideoPlayer.cpp 2008-03-06 20:41:41.000000000 -0500 +++ mythtv/libs/libmythtv/NuppelVideoPlayer.cpp 2008-03-12 22:40:47.000000000 -0400 @@ -201,6 +201,7 @@ NuppelVideoPlayer::NuppelVideoPlayer(QSt // OSD stuff osd(NULL), timedisplay(NULL), dialogname(""), dialogtype(0), + now_playing_changed(false), // Audio stuff audioOutput(NULL), audio_main_device(QString::null), @@ -274,6 +275,8 @@ NuppelVideoPlayer::NuppelVideoPlayer(QSt itvEnabled = gContext->GetNumSetting("EnableMHEG", 0); db_prefer708 = gContext->GetNumSetting("Prefer708Captions", 1); + osd_prog_info_timeout= gContext->GetNumSetting("OSDProgramInfoTimeout", 3); + lastIgnoredManualSkip = QDateTime::currentDateTime().addSecs(-10); bzero(&txtbuffers, sizeof(txtbuffers)); @@ -2926,6 +2929,8 @@ void NuppelVideoPlayer::DisplayNormalFra ExpireSubtitles(); } + DisplayNowPlaying(); + // handle scan type changes AutoDeint(frame); @@ -7056,6 +7061,34 @@ void NuppelVideoPlayer::DisplayTextSubti osd->ClearTextSubtitles(); } +/** \fn NuppelVideoPlayer::DisplayNowPlaying(void) + * \brief Displays Now Playing text + */ +void NuppelVideoPlayer::DisplayNowPlaying(bool anyway) +{ + QMutexLocker locker(&nowPlayingLock); + + if (!now_playing_changed && !anyway) + return; + + QString text; + + // Skip if the first section is empty + QString t = now_playing[0].simplifyWhiteSpace(); + if (t.isEmpty()) + return; + + for (QStringList::Iterator it = now_playing.begin(); + it != now_playing.end(); ++it ) { + if (!(*it).isEmpty()) + text.append(*it + " "); + } + + osd->SetNowPlaying(text, osd_prog_info_timeout); + + now_playing_changed = false; +} + /** \fn NuppelVideoPlayer::ExpireSubtitles(void) * \brief Discard non-displayed subtitles. */ @@ -7145,6 +7178,18 @@ void NuppelVideoPlayer::AddAVSubtitle(co subtitleLock.unlock(); } +/** \fn void NuppelVideoPlayer::SetNowPlaying(const QStringList playing&) + * \brief Set the Now Playing text in the OSD. + */ +void NuppelVideoPlayer::SetNowPlaying(const QStringList &playing) +{ + nowPlayingLock.lock(); + now_playing = QDeepCopy(playing); + nowPlayingLock.unlock(); + + now_playing_changed = true; +} + /** \fn NuppelVideoPlayer::SetDecoder(DecoderBase*) * \brief Sets the stream decoder, deleting any existing recorder. */ diff -rup mythtv.orig/libs/libmythtv/NuppelVideoPlayer.h mythtv/libs/libmythtv/NuppelVideoPlayer.h --- mythtv.orig/libs/libmythtv/NuppelVideoPlayer.h 2008-03-05 18:59:28.000000000 -0500 +++ mythtv/libs/libmythtv/NuppelVideoPlayer.h 2008-03-12 22:46:44.000000000 -0400 @@ -304,6 +304,10 @@ class MPUBLIC NuppelVideoPlayer : public long long timecode, char type); void AddAVSubtitle(const AVSubtitle& subtitle); + // Now Playing data + void SetNowPlaying(const QStringList &playing); + void DisplayNowPlaying(bool anyway=false); + // Closed caption and teletext stuff uint GetCaptionMode(void) const { return textDisplayMode; } void ResetCaptions(uint mode_override = 0); @@ -648,6 +652,7 @@ class MPUBLIC NuppelVideoPlayer : public // Support for captions, teletext, etc. decoded by libav QMutex subtitleLock; + QMutex nowPlayingLock; /// This allows us to enable captions/subtitles later if the streams /// are not immediately available when the video starts playing. bool textDesired; @@ -735,6 +740,8 @@ class MPUBLIC NuppelVideoPlayer : public long long lastCommSkipStart; time_t lastSkipTime; + int osd_prog_info_timeout; + long long deleteframe; bool hasdeletetable; bool hasblanktable; @@ -810,6 +817,10 @@ class MPUBLIC NuppelVideoPlayer : public AdjustFillMode detectLetterboxDefaultMode; int detectLetterboxCounter; int detectLetterboxLimit; + + // Now Playing + QStringList now_playing; + bool now_playing_changed; }; #endif diff -rup mythtv.orig/libs/libmythtv/avformatdecoder.cpp mythtv/libs/libmythtv/avformatdecoder.cpp --- mythtv.orig/libs/libmythtv/avformatdecoder.cpp 2008-03-08 12:14:37.000000000 -0500 +++ mythtv/libs/libmythtv/avformatdecoder.cpp 2008-03-12 21:23:09.000000000 -0400 @@ -1924,6 +1924,8 @@ int AvFormatDecoder::ScanStreams(bool no } case CODEC_TYPE_DATA: { + if (enc->bit_rate == 0) + enc->bit_rate = 500; ScanTeletextCaptions(i); bitrate += enc->bit_rate; VERBOSE(VB_PLAYBACK, LOC + QString("data codec (%1)") @@ -2692,6 +2694,32 @@ void AvFormatDecoder::H264PreProcessPkt( } } +void AvFormatDecoder::ProcessPrivSecDataPacket(const AVPacket *pkt) +{ + QStringList sections; + bool changed = false; + + QString text = (const char*)pkt->data; + + for (int i = 0; i < text.contains(0x0a); i++) { + QString section = text.section(0x0a, i, i); + if (section == "") section = " "; + + if ((i > now_playing.size()) || + now_playing[i].compare(section)) + { + sections << section; + changed = true; + } + } + + if (changed) + { + now_playing = sections; + GetNVP()->SetNowPlaying(sections); + } +} + /** \fn AvFormatDecoder::ProcessVBIDataPacket(const AVStream*, const AVPacket*) * \brief Process ivtv proprietary embedded vertical blanking * interval captions. @@ -3583,6 +3611,16 @@ bool AvFormatDecoder::GetFrame(int onlyv continue; } + if (len > 0 && + curstream->codec->codec_type == CODEC_TYPE_DATA && + curstream->codec->codec_id == CODEC_ID_DVB_PRIVSEC) + { + ProcessPrivSecDataPacket(pkt); + + av_free_packet(pkt); + continue; + } + // we don't care about other data streams if (curstream->codec->codec_type == CODEC_TYPE_DATA) { diff -rup mythtv.orig/libs/libmythtv/avformatdecoder.h mythtv/libs/libmythtv/avformatdecoder.h --- mythtv.orig/libs/libmythtv/avformatdecoder.h 2008-03-03 13:28:21.000000000 -0500 +++ mythtv/libs/libmythtv/avformatdecoder.h 2008-03-12 20:22:03.000000000 -0400 @@ -187,6 +187,7 @@ class AvFormatDecoder : public DecoderBa void MpegPreProcessPkt(AVStream *stream, AVPacket *pkt); void H264PreProcessPkt(AVStream *stream, AVPacket *pkt); + void ProcessPrivSecDataPacket(const AVPacket *pkt); void ProcessVBIDataPacket(const AVStream *stream, const AVPacket *pkt); void ProcessDVBDataPacket(const AVStream *stream, const AVPacket *pkt); void ProcessDSMCCPacket(const AVStream *stream, const AVPacket *pkt); @@ -278,6 +279,8 @@ class AvFormatDecoder : public DecoderBa bool mpeg_seq_end_seen; /// \brief contains last dvd still frame decoded AVPacket *lastDVDStillFrame; + + QStringList now_playing; }; #endif diff -rup mythtv.orig/libs/libmythtv/osd.cpp mythtv/libs/libmythtv/osd.cpp --- mythtv.orig/libs/libmythtv/osd.cpp 2008-03-03 13:28:21.000000000 -0500 +++ mythtv/libs/libmythtv/osd.cpp 2008-03-12 21:44:57.000000000 -0400 @@ -1939,6 +1939,24 @@ void OSD::EndStatus(void) osdlock.unlock(); } +void OSD::SetNowPlaying(const QString &playing, int length) +{ + osdlock.lock(); + OSDSet *container = GetSet("program_info"); + if (container) + { + OSDTypeText *type = (OSDTypeText *)container->GetType("now_playing"); + if (type) + type->SetText(playing); + + container->DisplayFor(length * 1000000); + m_setsvisible = true; + changed = true; + } + + osdlock.unlock(); +} + void OSD::SetChannumText(const QString &text, int length) { osdlock.lock(); diff -rup mythtv.orig/libs/libmythtv/osd.h mythtv/libs/libmythtv/osd.h --- mythtv.orig/libs/libmythtv/osd.h 2008-03-03 13:28:20.000000000 -0500 +++ mythtv/libs/libmythtv/osd.h 2008-03-12 19:51:27.000000000 -0400 @@ -80,6 +80,7 @@ class OSD : public QObject const QString &callsign, const QString &iconpath, int length); void SetChannumText(const QString &text, int length); + void SetNowPlaying(const QString &playing, int length); // CC-608 and DVB text captions (not DVB/DVD subtitles). void AddCCText(const QString &text, int x, int y, int color, diff -rup mythtv.orig/libs/libmythtv/tv_play.cpp mythtv/libs/libmythtv/tv_play.cpp --- mythtv.orig/libs/libmythtv/tv_play.cpp 2008-03-08 11:11:29.000000000 -0500 +++ mythtv/libs/libmythtv/tv_play.cpp 2008-03-12 22:45:34.000000000 -0400 @@ -5433,6 +5433,8 @@ void TV::UpdateOSDProgInfo(const char *w osd->ClearAllText(whichInfo); osd->HideAll(); osd->SetText(whichInfo, infoMap, osd_prog_info_timeout); + + nvp->DisplayNowPlaying(true); } void TV::UpdateOSDSeekMessage(const QString &mesg, int disptime)