@@ -649,6 +649,8 @@ bool cSoftHdDevice::SetPlayMode(ePlayMode play_mode)
649649 m_externalPlayerActive = false ;
650650 }
651651
652+ m_draining = false ;
653+
652654 switch (play_mode) {
653655 case pmNone:
654656 OnEventReceived (StopEvent{});
@@ -810,6 +812,8 @@ void cSoftHdDevice::Clear(void)
810812 m_pAudio->ResetHwDelayBaseline ();
811813 FlushAudio ();
812814
815+ m_draining = false ;
816+
813817 SetState (BUFFERING );
814818
815819 m_pRender->Resume ();
@@ -888,7 +892,7 @@ void cSoftHdDevice::HandleStillPicture(const uchar *data, int size)
888892
889893 m_pVideoStream->PushAvPacket (m_videoReassemblyBuffer.PopAvPacket ());
890894 m_pVideoStream->ResetInputPts (); // stillpicture shouldn't trigger having video data
891- m_pVideoStream->Flush ();
895+ m_pVideoStream->Drain ();
892896}
893897
894898/* *
@@ -917,26 +921,41 @@ bool cSoftHdDevice::Poll(__attribute__ ((unused)) cPoller & poller, int timeoutM
917921 return false ;
918922}
919923
924+ #if APIVERSNUM >= 30014
920925/* *
921- * Flush the device output buffers.
926+ * Force a decoder drain and return true, if all buffers have been played out
922927 *
923- * @param timeoutMs timeout in ms to become ready
928+ * @return true, if the buffers are empty, false otherwise
924929 */
925- bool cSoftHdDevice::Flush ( int timeoutMs )
930+ bool cSoftHdDevice::Drain ( void )
926931{
927932 if (IsDetached ())
928933 return true ;
929934
930- LOGDEBUG (" device: %s: timeout %d ms" , __FUNCTION__, timeoutMs);
931- if (m_pVideoStream->GetAvPacketsFilled ()) {
932- if (timeoutMs) { // let display thread work
933- usleep (timeoutMs * 1000 );
934- }
935- return !m_pVideoStream->GetAvPacketsFilled ();
935+ // enter drain mode once
936+ if (!m_draining) {
937+ LOGDEBUG (" device: %s: start draining" , __FUNCTION__);
938+ m_draining = true ;
939+ if (!m_videoReassemblyBuffer.IsEmpty ())
940+ m_pVideoStream->PushAvPacket (m_videoReassemblyBuffer.PopAvPacket ());
941+ m_pVideoStream->Drain ();
936942 }
937943
944+ const auto buffersEmpty = [&]() {
945+ return m_playbackMode == AUDIO_ONLY
946+ ? m_pAudio->IsBufferEmpty ()
947+ : m_pVideoStream->BuffersEmpty ();
948+ };
949+
950+ if (!buffersEmpty ())
951+ return false ;
952+
953+ LOGDEBUG (" device: %s: drained, buffers are empty" , __FUNCTION__);
954+ m_draining = false ;
955+
938956 return true ;
939957}
958+ #endif
940959
941960/* *
942961 * Sets the video display format
0 commit comments