@@ -53,9 +53,11 @@ static const int64_t kAAHBufferTimeUs = 1000000LL;
5353const int64_t AAH_TXPlayer::kAAHRetryKeepAroundTimeNs =
5454 kAAHBufferTimeUs * 1100 ;
5555
56+ const int AAH_TXPlayer::kEOSResendTimeoutMsec = 100 ;
5657const int AAH_TXPlayer::kPauseTSUpdateResendTimeoutMsec = 250 ;
5758const int32_t AAH_TXPlayer::kInvokeGetCNCPort = 0xB33977 ;
5859
60+
5961sp<MediaPlayerBase> createAAH_TXPlayer () {
6062 sp<MediaPlayerBase> ret = new AAH_TXPlayer ();
6163 return ret;
@@ -523,8 +525,9 @@ status_t AAH_TXPlayer::play_l() {
523525
524526status_t AAH_TXPlayer::stop () {
525527 status_t ret = pause ();
528+ mEOSResendTimeout .setTimeout (-1 );
526529 mPauseTSUpdateResendTimeout .setTimeout (-1 );
527- sendEOS_l ();
530+ sendFlush_l ();
528531 return ret;
529532}
530533
@@ -592,7 +595,9 @@ void AAH_TXPlayer::updateClockTransform_l(bool pause) {
592595 sendTSUpdateNop_l ();
593596
594597 // if we are paused, schedule a periodic resend of the TS update, JiC the
595- // receiveing client misses it.
598+ // receiveing client misses it. Don't bother setting the timer if we have
599+ // hit EOS; the EOS message will carry the update for us and serve the same
600+ // purpose as the pause updates.
596601 if (mPlayRateIsPaused ) {
597602 mPauseTSUpdateResendTimeout .setTimeout (kPauseTSUpdateResendTimeoutMsec );
598603 } else {
@@ -604,12 +609,32 @@ void AAH_TXPlayer::sendEOS_l() {
604609 if (mAAH_TXGroup != NULL ) {
605610 sp<TRTPControlPacket> packet = new TRTPControlPacket ();
606611 if (packet != NULL ) {
612+ if (mCurrentClockTransformValid ) {
613+ packet->setClockTransform (mCurrentClockTransform );
614+ }
607615 packet->setCommandID (TRTPControlPacket::kCommandEOS );
608616 sendPacket_l (packet);
609617 } else {
610618 LOGD (" Failed to allocate TRTP packet at %s:%d" , __FILE__, __LINE__);
611619 }
612620 }
621+
622+ // While we are waiting to reach the end of the actual presentation and have
623+ // the app clean us up, periodically resend the EOS message, just it case it
624+ // was dropped.
625+ mEOSResendTimeout .setTimeout (kEOSResendTimeoutMsec );
626+ }
627+
628+ void AAH_TXPlayer::sendFlush_l () {
629+ if (mAAH_TXGroup != NULL ) {
630+ sp<TRTPControlPacket> packet = new TRTPControlPacket ();
631+ if (packet != NULL ) {
632+ packet->setCommandID (TRTPControlPacket::kCommandFlush );
633+ sendPacket_l (packet);
634+ } else {
635+ LOGD (" Failed to allocate TRTP packet at %s:%d" , __FILE__, __LINE__);
636+ }
637+ }
613638}
614639
615640void AAH_TXPlayer::sendTSUpdateNop_l () {
@@ -641,21 +666,13 @@ status_t AAH_TXPlayer::seekTo(int msec) {
641666
642667status_t AAH_TXPlayer::seekTo_l (int64_t timeUs) {
643668 mIsSeeking = true ;
669+ mEOSResendTimeout .setTimeout (-1 );
644670 mSeekTimeUs = timeUs;
645671
646672 mCurrentClockTransformValid = false ;
647673 mLastQueuedMediaTimePTSValid = false ;
648674
649- // send a flush command packet
650- if (mAAH_TXGroup != NULL ) {
651- sp<TRTPControlPacket> packet = new TRTPControlPacket ();
652- if (packet != NULL ) {
653- packet->setCommandID (TRTPControlPacket::kCommandFlush );
654- sendPacket_l (packet);
655- } else {
656- LOGD (" Failed to allocate TRTP packet at %s:%d" , __FILE__, __LINE__);
657- }
658- }
675+ sendFlush_l ();
659676
660677 return OK;
661678}
@@ -748,7 +765,7 @@ void AAH_TXPlayer::reset_l() {
748765
749766 cancelPlayerEvents ();
750767
751- sendEOS_l ();
768+ sendFlush_l ();
752769
753770 mCachedSource .clear ();
754771
@@ -769,6 +786,7 @@ void AAH_TXPlayer::reset_l() {
769786 mIsSeeking = false ;
770787 mSeekTimeUs = 0 ;
771788
789+ mEOSResendTimeout .setTimeout (-1 );
772790 mPauseTSUpdateResendTimeout .setTimeout (-1 );
773791
774792 mUri .setTo (" " );
@@ -1161,6 +1179,39 @@ void AAH_TXPlayer::onPumpAudio() {
11611179 }
11621180 }
11631181
1182+ // If we have hit EOS, then we will have an EOS resend timeout set.
1183+ int msecTillEOSResend = mEOSResendTimeout .msecTillTimeout ();
1184+ if (msecTillEOSResend >= 0 ) {
1185+ // Resend the EOS message if its time.
1186+ if (!msecTillEOSResend) {
1187+ sendEOS_l ();
1188+ }
1189+
1190+ // Declare playback complete to the app level if we have passed the
1191+ // PTS of the last sample queued, then cancel the EOS resend timer.
1192+ if (mediaTimeNowValid &&
1193+ mLastQueuedMediaTimePTSValid &&
1194+ ((mLastQueuedMediaTimePTS - mediaTimeNow) <= 0 )) {
1195+ LOGI (" Sending playback complete" );
1196+ pause_l (false );
1197+ notifyListener_l (MEDIA_PLAYBACK_COMPLETE);
1198+ mEOSResendTimeout .setTimeout (-1 );
1199+
1200+ // Return directly from here to avoid rescheduling ourselves.
1201+ return ;
1202+ }
1203+
1204+ // Once we have hit EOS, we are done until we seek or are reset.
1205+ break ;
1206+ }
1207+
1208+ // Stop if we have reached our buffer threshold.
1209+ if (mediaTimeNowValid &&
1210+ mLastQueuedMediaTimePTSValid &&
1211+ (mediaTimeNow + kAAHBufferTimeUs - mLastQueuedMediaTimePTS ) <= 0 ) {
1212+ break ;
1213+ }
1214+
11641215 // Stop if we have reached our buffer threshold.
11651216 if (mediaTimeNowValid &&
11661217 mLastQueuedMediaTimePTSValid &&
@@ -1177,11 +1228,34 @@ void AAH_TXPlayer::onPumpAudio() {
11771228 status_t err = mAudioSource ->read (&mediaBuffer, &options);
11781229 if (err != NO_ERROR) {
11791230 if (err == ERROR_END_OF_STREAM) {
1180- LOGI (" *** %s reached end of stream" , __PRETTY_FUNCTION__ );
1181- notifyListener_l (MEDIA_BUFFERING_UPDATE, 100 );
1182- notifyListener_l (MEDIA_PLAYBACK_COMPLETE);
1183- pause_l ( false );
1231+ LOGI (" Demux reached reached end of stream. " );
1232+
1233+ // Send an EOS message to our receivers so that they know there
1234+ // is no more data coming and can behave appropriately.
11841235 sendEOS_l ();
1236+
1237+ // One way or the other, we are "completely buffered" at this
1238+ // point since we have hit the end of stream.
1239+ notifyListener_l (MEDIA_BUFFERING_UPDATE, 100 );
1240+
1241+ // Do not send the playback complete message yet. Instead, wait
1242+ // until we pass the presentation time of the last sample we
1243+ // queued to report playback complete up to the higher levels of
1244+ // code.
1245+ //
1246+ // It would be very odd to not have a last PTS at this point in
1247+ // time, but if we don't (for whatever reason), just go ahead
1248+ // and send the playback complete right now so we don't end up
1249+ // stuck.
1250+ if (!mLastQueuedMediaTimePTSValid ) {
1251+ LOGW (" Sending playback complete (no valid last PTS)" );
1252+ pause_l (false );
1253+ notifyListener_l (MEDIA_PLAYBACK_COMPLETE);
1254+ mEOSResendTimeout .setTimeout (-1 );
1255+ } else {
1256+ // Break out of the loop to reschude ourselves.
1257+ break ;
1258+ }
11851259 } else {
11861260 LOGE (" *** %s read failed err=%d" , __PRETTY_FUNCTION__, err);
11871261 }
0 commit comments