1 | play media to end when eof detected |
---|
2 | |
---|
3 | From: Mark Spieth <mspieth@digivation.com.au> |
---|
4 | |
---|
5 | |
---|
6 | --- |
---|
7 | mythtv/libs/libmythtv/mythplayer.cpp | 52 +++++++++++++++++---------- |
---|
8 | mythtv/libs/libmythtv/mythplayer.h | 14 ++++++- |
---|
9 | mythtv/programs/mythtranscode/transcode.cpp | 1 + |
---|
10 | 3 files changed, 44 insertions(+), 23 deletions(-) |
---|
11 | |
---|
12 | diff --git a/mythtv/libs/libmythtv/mythplayer.cpp b/mythtv/libs/libmythtv/mythplayer.cpp |
---|
13 | index d13d741..e2cdc9b 100644 |
---|
14 | --- a/mythtv/libs/libmythtv/mythplayer.cpp |
---|
15 | +++ b/mythtv/libs/libmythtv/mythplayer.cpp |
---|
16 | @@ -174,7 +174,7 @@ MythPlayer::MythPlayer(bool muted) |
---|
17 | bufferPaused(false), videoPaused(false), |
---|
18 | allpaused(false), playing(false), |
---|
19 | |
---|
20 | - eof(false), |
---|
21 | + eof(kEofStateNone), |
---|
22 | m_double_framerate(false), m_double_process(false), |
---|
23 | m_can_double(false), m_deint_possible(true), |
---|
24 | livetv(false), |
---|
25 | @@ -1005,7 +1005,7 @@ int MythPlayer::OpenFile(uint retries, bool allow_libmpeg2) |
---|
26 | noVideoTracks = !decoder->GetTrackCount(kTrackTypeVideo); |
---|
27 | |
---|
28 | |
---|
29 | - eof = false; |
---|
30 | + eof = kEofStateNone; |
---|
31 | |
---|
32 | // Set 'no_video_decode' to true for audio only decodeing |
---|
33 | bool no_video_decode = false; |
---|
34 | @@ -1972,6 +1972,7 @@ bool MythPlayer::PrebufferEnoughFrames(bool pause_audio, int min_buffers) |
---|
35 | |
---|
36 | bool was_buffering = buffering; |
---|
37 | if (!(min_buffers ? (videoOutput->ValidVideoFrames() >= min_buffers) : |
---|
38 | + (eof != kEofStateNone) || |
---|
39 | (videoOutput->hasHWAcceleration() ? |
---|
40 | videoOutput->EnoughPrebufferedFrames() : |
---|
41 | videoOutput->EnoughDecodedFrames()))) |
---|
42 | @@ -2287,7 +2288,7 @@ void MythPlayer::SwitchToProgram(void) |
---|
43 | { |
---|
44 | OpenDummy(); |
---|
45 | ResetPlaying(); |
---|
46 | - eof = false; |
---|
47 | + eof = kEofStateNone; |
---|
48 | delete pginfo; |
---|
49 | return; |
---|
50 | } |
---|
51 | @@ -2301,13 +2302,13 @@ void MythPlayer::SwitchToProgram(void) |
---|
52 | QString("(card type: %1).") |
---|
53 | .arg(player_ctx->tvchain->GetCardType(newid))); |
---|
54 | VERBOSE(VB_IMPORTANT, QString("\n") + player_ctx->tvchain->toString()); |
---|
55 | - eof = true; |
---|
56 | + eof = kEofStateImmediate; |
---|
57 | SetErrored(QObject::tr("Error opening switch program buffer")); |
---|
58 | delete pginfo; |
---|
59 | return; |
---|
60 | } |
---|
61 | |
---|
62 | - if (eof) |
---|
63 | + if (eof != kEofStateNone) |
---|
64 | { |
---|
65 | discontinuity = true; |
---|
66 | ResetCaptions(); |
---|
67 | @@ -2345,7 +2346,7 @@ void MythPlayer::SwitchToProgram(void) |
---|
68 | if (IsErrored()) |
---|
69 | { |
---|
70 | VERBOSE(VB_IMPORTANT, LOC_ERR + "SwitchToProgram failed."); |
---|
71 | - eof = true; |
---|
72 | + eof = kEofStateDelayed; |
---|
73 | return; |
---|
74 | } |
---|
75 | |
---|
76 | @@ -2360,7 +2361,7 @@ void MythPlayer::SwitchToProgram(void) |
---|
77 | forcePositionMapSync = true; |
---|
78 | } |
---|
79 | |
---|
80 | - eof = false; |
---|
81 | + eof = kEofStateNone; |
---|
82 | Play(); |
---|
83 | VERBOSE(VB_PLAYBACK, LOC + "SwitchToProgram - end"); |
---|
84 | } |
---|
85 | @@ -2377,7 +2378,7 @@ void MythPlayer::FileChangedCallback(void) |
---|
86 | player_ctx->buffer->Reset(false, true, true); |
---|
87 | Play(); |
---|
88 | |
---|
89 | - eof = false; |
---|
90 | + eof = kEofStateNone; |
---|
91 | |
---|
92 | player_ctx->SetPlayerChangingBuffers(false); |
---|
93 | |
---|
94 | @@ -2415,7 +2416,7 @@ void MythPlayer::JumpToProgram(void) |
---|
95 | { |
---|
96 | OpenDummy(); |
---|
97 | ResetPlaying(); |
---|
98 | - eof = false; |
---|
99 | + eof = kEofStateNone; |
---|
100 | delete pginfo; |
---|
101 | return; |
---|
102 | } |
---|
103 | @@ -2432,7 +2433,7 @@ void MythPlayer::JumpToProgram(void) |
---|
104 | .arg(player_ctx->tvchain->GetCardType(newid))); |
---|
105 | VERBOSE(VB_IMPORTANT, QString("\n") + player_ctx->tvchain->toString()); |
---|
106 | |
---|
107 | - eof = true; |
---|
108 | + eof = kEofStateImmediate; |
---|
109 | SetErrored(QObject::tr("Error opening jump program file buffer")); |
---|
110 | delete pginfo; |
---|
111 | return; |
---|
112 | @@ -2476,7 +2477,7 @@ void MythPlayer::JumpToProgram(void) |
---|
113 | if (nextpos > 10) |
---|
114 | DoFastForward(nextpos, true, false); |
---|
115 | |
---|
116 | - eof = false; |
---|
117 | + eof = kEofStateNone; |
---|
118 | player_ctx->SetPlayerChangingBuffers(false); |
---|
119 | VERBOSE(VB_PLAYBACK, LOC + "JumpToProgram - end"); |
---|
120 | } |
---|
121 | @@ -2608,7 +2609,7 @@ void MythPlayer::EventLoop(void) |
---|
122 | player_ctx->tvchain->JumpToNext(true, 1); |
---|
123 | JumpToProgram(); |
---|
124 | } |
---|
125 | - else if ((!allpaused || eof) && player_ctx->tvchain && |
---|
126 | + else if ((!allpaused || (eof != kEofStateNone)) && player_ctx->tvchain && |
---|
127 | (decoder && !decoder->GetWaitForChange())) |
---|
128 | { |
---|
129 | // Switch to the next program in livetv |
---|
130 | @@ -2659,7 +2660,7 @@ void MythPlayer::EventLoop(void) |
---|
131 | } |
---|
132 | |
---|
133 | // Handle end of file |
---|
134 | - if (eof) |
---|
135 | + if (eof != kEofStateNone) |
---|
136 | { |
---|
137 | if (player_ctx->tvchain) |
---|
138 | { |
---|
139 | @@ -2672,8 +2673,17 @@ void MythPlayer::EventLoop(void) |
---|
140 | } |
---|
141 | else if (!allpaused) |
---|
142 | { |
---|
143 | - SetPlaying(false); |
---|
144 | - return; |
---|
145 | + if (eof == kEofStateImmediate) |
---|
146 | + { |
---|
147 | + SetPlaying(false); |
---|
148 | + return; |
---|
149 | + } |
---|
150 | + VERBOSE(VB_PLAYBACK, "waiting for no video frames " << videoOutput->ValidVideoFrames()); |
---|
151 | + if (videoOutput && videoOutput->ValidVideoFrames() < 3) |
---|
152 | + { |
---|
153 | + SetPlaying(false); |
---|
154 | + return; |
---|
155 | + } |
---|
156 | } |
---|
157 | } |
---|
158 | |
---|
159 | @@ -2692,7 +2702,7 @@ void MythPlayer::EventLoop(void) |
---|
160 | if (fftime > 0) |
---|
161 | { |
---|
162 | DoFastForward(fftime); |
---|
163 | - if (eof) |
---|
164 | + if (eof != kEofStateNone) |
---|
165 | return; |
---|
166 | } |
---|
167 | } |
---|
168 | @@ -2754,7 +2764,7 @@ void MythPlayer::EventLoop(void) |
---|
169 | && !player_ctx->IsPIP() && |
---|
170 | player_ctx->GetState() == kState_WatchingPreRecorded)) |
---|
171 | { |
---|
172 | - eof = true; |
---|
173 | + eof = kEofStateDelayed; |
---|
174 | } |
---|
175 | } |
---|
176 | else |
---|
177 | @@ -2886,7 +2896,9 @@ void MythPlayer::DecoderLoop(bool pause) |
---|
178 | decoderSeekLock.unlock(); |
---|
179 | } |
---|
180 | |
---|
181 | - bool obey_eof = eof && !(eof && player_ctx->tvchain && !allpaused); |
---|
182 | + // eofstate |
---|
183 | + // playtoend MRS |
---|
184 | + bool obey_eof = (eof != kEofStateNone) && !((eof != kEofStateNone) && player_ctx->tvchain && !allpaused); |
---|
185 | if (isDummy || ((decoderPaused || ffrew_skip == 0 || obey_eof) && |
---|
186 | !decodeOneFrame)) |
---|
187 | { |
---|
188 | @@ -4201,7 +4213,7 @@ bool MythPlayer::TranscodeGetNextFrame( |
---|
189 | if (!decoder->GetFrame(kDecodeAV)) |
---|
190 | return false; |
---|
191 | |
---|
192 | - if (eof) |
---|
193 | + if (eof != kEofStateNone) |
---|
194 | return false; |
---|
195 | |
---|
196 | if (honorCutList && !deleteMap.IsEmpty()) |
---|
197 | @@ -4226,7 +4238,7 @@ bool MythPlayer::TranscodeGetNextFrame( |
---|
198 | did_ff = 1; |
---|
199 | } |
---|
200 | } |
---|
201 | - if (eof) |
---|
202 | + if (eof != kEofStateNone) |
---|
203 | return false; |
---|
204 | is_key = decoder->isLastFrameKey(); |
---|
205 | return true; |
---|
206 | diff --git a/mythtv/libs/libmythtv/mythplayer.h b/mythtv/libs/libmythtv/mythplayer.h |
---|
207 | index 4cb7b56..c808569 100644 |
---|
208 | --- a/mythtv/libs/libmythtv/mythplayer.h |
---|
209 | +++ b/mythtv/libs/libmythtv/mythplayer.h |
---|
210 | @@ -110,6 +110,14 @@ class DecoderThread : public QThread |
---|
211 | bool m_start_paused; |
---|
212 | }; |
---|
213 | |
---|
214 | +// Eof States |
---|
215 | +typedef enum |
---|
216 | +{ |
---|
217 | + kEofStateNone, |
---|
218 | + kEofStateDelayed, |
---|
219 | + kEofStateImmediate |
---|
220 | +} EofState; |
---|
221 | + |
---|
222 | class MPUBLIC MythPlayer |
---|
223 | { |
---|
224 | // Do NOT add a decoder class to this list |
---|
225 | @@ -138,7 +146,7 @@ class MPUBLIC MythPlayer |
---|
226 | void SetLength(int len) { totalLength = len; } |
---|
227 | void SetFramesPlayed(uint64_t played) { framesPlayed = played; } |
---|
228 | void SetVideoFilters(const QString &override); |
---|
229 | - void SetEof(void) { eof = true; } |
---|
230 | + void SetEof(void) { eof = kEofStateDelayed; } |
---|
231 | void SetPIPActive(bool is_active) { pip_active = is_active; } |
---|
232 | void SetPIPVisible(bool is_visible) { pip_visible = is_visible; } |
---|
233 | |
---|
234 | @@ -188,7 +196,7 @@ class MPUBLIC MythPlayer |
---|
235 | // Bool Gets |
---|
236 | bool GetRawAudioState(void) const; |
---|
237 | bool GetLimitKeyRepeat(void) const { return limitKeyRepeat; } |
---|
238 | - bool GetEof(void) const { return eof; } |
---|
239 | + bool GetEof(void) const { return eof != kEofStateNone; } |
---|
240 | bool IsErrored(void) const; |
---|
241 | bool IsPlaying(uint wait_ms = 0, bool wait_for = true) const; |
---|
242 | bool AtNormalSpeed(void) const { return next_normal_speed; } |
---|
243 | @@ -560,7 +568,7 @@ class MPUBLIC MythPlayer |
---|
244 | mutable QWaitCondition playingWaitCond; |
---|
245 | mutable QMutex vidExitLock; |
---|
246 | mutable QMutex playingLock; |
---|
247 | - bool eof; ///< At end of file/ringbuffer |
---|
248 | + EofState eof; ///< At end of file/ringbuffer |
---|
249 | bool m_double_framerate;///< Output fps is double Video (input) rate |
---|
250 | bool m_double_process;///< Output filter must processed at double rate |
---|
251 | bool m_can_double; ///< VideoOutput capable of doubling frame rate |
---|
252 | diff --git a/mythtv/programs/mythtranscode/transcode.cpp b/mythtv/programs/mythtranscode/transcode.cpp |
---|
253 | index 35f54e6..2bdd56f 100644 |
---|
254 | --- a/mythtv/programs/mythtranscode/transcode.cpp |
---|
255 | +++ b/mythtv/programs/mythtranscode/transcode.cpp |
---|
256 | @@ -75,6 +75,7 @@ class AudioReencodeBuffer : public AudioOutput |
---|
257 | } |
---|
258 | |
---|
259 | virtual void SetBlocking(bool block) { (void)block; } |
---|
260 | + virtual void SetTimedBlocking(bool block) { (void)block; } |
---|
261 | virtual void Reset(void) |
---|
262 | { |
---|
263 | audiobuffer_len = 0; |
---|