Fix a bug discovered while working on adding unicast mode to the TX/RX
players. Also some general cleanup/consolidation regarding timeout
code.
The bug went like this. When a TX player had hit EOS, it would send
an EOS command payload to its receivers. Later, when application
level code shutdown and cleaned up the player, it would send another.
In situations where there is massive packet loss, there is a chance
that not only did both of the EOS packets get dropped, but that they
never got filled in by the retry algorithm because the receiver gave
up on the RTP gap due to an aboutToUnderflow situation in at least one
of its active substreams.
When this happens, there are two major problems. First, all of the
substreams associated with the TX player which has now gone away have
become effectively leaked. They will only get cleaned up if the
entire RTP stream (the TX Group) goes away for 10 seconds or more, or
when the RX Player itself is reset by application level code or a
fatal error. These substreams are holding decoder and renderer
resources which are probably in very short supply, which is a Bad
Thing.
Second, there is now at least one substream in the RX player which is
never going to receive another payload (its TX player source is gone),
but is still considered to be active by the rx player. Assuming that
this substream's program was in the play state when the track ended,
there is now at least one substream which is always
"aboutToUnderflow". From here on out, when the retry algorithm is
attempting to decide whether or not it has the time to attempt to fill
in a gap in the muxed RTP sequence, it always decides that it does not
have the time because of the orphaned substream which is stuck in its
about to underflow state. This effectively means that the retry
algorithm is completely shut off until the rx player gets reset
somehow (something which does not happen during normal operation).
Since the environment had to be extremely lossy to trigger this chain
of events in the first place, and its probably no better now, your
playback is just going to be chock full of gaps which produces
horrible stuttering in the presentation stage of the system.
Two new failsafes have been introduced to keep the double EOS drop
from causing this. First, a timeout has been introduced on the
substream level, in addition to the already existing RTP level
timeout. If a substream fails to receive an activity for 10 seconds
(same timeout as the master RTP timeout), it will be automatically
flushed and purged.
Second, the nature of the master RTP timeout on the transmitter side
has been changed. Instead of just sending an empty NOP command packet
to indicate that the main RTP stream is still alive, the transmitter
now sends a new time of command packet; the Active Program Update
packet. This packet contains a list of all the active program ID
attached to this TX group. Upon receiving one of these APU packets,
RX players reset the inactivity timers for all substreams which are
members of the programs listed in the packet, but they also
immediately purge any substreams associated with programs not present
in the APU.
Between the two of these, no matter how nasty and selective the packet
smashing gremlins in your system happen to be, substreams will always
eventually clean up and avoid getting stuck in a perma-stutter
situation.
Also in this CL:
+ Extract some common utility code into a utils.cpp file so that it
can be shared across the library.
+ Stop using custom timeout logic in the RXPlayer. Instead, use the
common Timeout helper class in utils.cpp.
Signed-off-by: John Grossman <johngro@google.com>
Change-Id: I350869942074f2cae020f719c2911d9092ba8055
Significantly refactor the TXGroup code to allow transmit groups to
operate in a unicast fanout mode in addition to the traditional pure
multicast mode. Important changes include...
+ Each transmit group active in the system now has its own socket to
send and receive traffic on. In the past, this socket was used to
listen for retry requests from clients. Now it is also used to
listen for group membership reports (IGMPv3 style) from unicast
clients. Having an individual socket per transmit group allows
unicast clients to join the group needing only the IP address and
port of the transmitters socket, and not needing any additional
"group id" to be sent to the client beforehand.
+ Setup for the transmitter is now slightly different. As before, to
setup for multicast mode, a user can call setRetransmitEndpoint
passing an IPv4 multicast address and specific port to transmit to.
It used to also be the case that a user could pass a specific
unicast address and port to transmit to as well. This is no longer
allowed. Instead, to operate in unicast mode, a user passes 0.0.0.0
(IPADDR_ANY) as the IP address. In addition, they need to pass
either 0 for a port to create a new unicast mode TX group, or they
need to pass a specific port to cause the player to attempt to use
an existing unicast mode TX group. The specific port should be the
command and control port of the TX group which was bound to when the
group was originally created.
+ A magic invoke was added to allow clients to fetch the command and
control port on which a TX Player's TX Group is listening.
The API described above is most likely temporary and should eventually
be replaced with one where TX groups are formal top level objects with
their own independent interface and life-cycle management.
Signed-off-by: John Grossman <johngro@google.com>
Change-Id: Ib4e9737c10660d36c50f1825c9824fff5390b1c7
Rename AAH_TXSender to AAH_TXGroup in preparation for refactoring to
support unicast retransmission.
Signed-off-by: John Grossman <johngro@google.com>
Change-Id: I3984db27d1c61c6155d5d7cb9c38eead421b9249
Move in the direction of a more publishable API for configuring a
media player for retransmission. It used to be that we used a custom
invoke and a modified URL (prefixed with aahTX://). There are many
issues with this technique and it was never meant to stand the test of
time.
This CL gets rid of all that. A new (but currently hidden) method was
introduced to the java level MediaPlayer API, called
setRetransmitTarget(InetSocketAddress), which allows an app writer to
set the retransmit target. For now, this method needs to be called
before a call to setDataSource (which is pretty unusual for the
MediaPlayer API) because this mid level code uses this as a cue to
instantiate an aahTX player instead of relying on the data source to
select a player. When retranmit functionality becomes part of the
existing android player implemenation, this
set-retrans-before-set-data-source behavior can go away, along with
the aahTX player itself.
Change-Id: I6ab07d89b2eeb0650e634b8c3b7a0b36aba4e7dd
Change the CCHelper class to be an instanced instead of a static
pattern. The CCHelper instances all share an interface to the common
clock service and register/unregister a callback handler in response
to there being CCHelper instance in the system or not. This brings
usage of the CCHelper into like with the new auto-disable
functionality of the common time service. For any given process,
whenever there are CCHelper instances active, the process will
maintain a callback target to the common clock service and will be
considered to be an active client.
Also change all of the users of the CCHelper interface to manage the
lifecycle of their new CCHelper instances.
Change-Id: I7c28c5d70d9b07ba7407b4ac706e7e7d7253001b
Bulk name change to remove references to Android@Home from the common time
service in preparation for cleanup and up-integration into the master
branch. Basically, aah_timesrv is now common_time.
Change-Id: I3d3db212f96e8ba171aa36b9c58e27e4a336cb0a
* Added a MediaPlayer.setMediaPlayerType API that be called to specify the
desired media player implementation before calling setDataSource
* Implemented setDataSource(fd) in the AAH_TxPlayer
Change-Id: I359075d9c7d6fd699dda14eb85ec50da19307639
Introduce a heartbeat timeout for TX senders. If none of the TX
sender's clients send any packets for this timeout period (10 minutes
right now), then the sender will stop sending keep-alive heartbeats.
This should cause RX clients to release any held media resources,
including any timed audio track. Releasing timeed audio tracks allows
the audio system to go into its idle state, which allows the power amp
in Tungsten to power all of the way down, saving both heat and power.
Change-Id: Ib7a96d334e1064ddea3f07a6b21e6efedefc549a
Signed-off-by: John Grossman <johngro@google.com>
First, clear an issue which was causing an assert to fire. Basically,
once a decoder pump had entered the error state and was shutdown, it
was not clearing its status, and when a substream attempt to recycle
the pump, startup was failing an assert (no thread had been created,
meaning that the system was not initialized, yet status indicated an
error). This was a small one-liner in aah_decoder_pump.cpp.
Second, try to become a little nuanced about how we handle errors in
the decoder pump. A comment in the code pretty much says it all, but
the summary is that we don't want to completely abort playback because
a single chunk of ES failed to decode, but if nothing is decoding and
we are making no progress at all, we probably need to put the
MediaPlayer instance into the fatal Error state and signal the app
level so that further action can be taken (automatic recovery attempts
followed by bug reports and signalling the user if those fail).
This is to address the fallout of http://b/issue?id=5498460, where
something at the OMX decoder level becomes unhappy about not being
able to obtain an output buffer which eventually unwinds to this
assert which results in a dead mediaserver. After this change, the
mediaserver will no longer crash, and may even recover (depending on
whether or not the OMX unhappiness is transient or not), but the
primary issue (unhappy OMX) is probably still around. It is quite
difficult to reproduce, I will probably need to open a different bug
to track that issue.
Change-Id: I5b65b818378a5ae9c915e91b7db7129f0bda6837
Signed-off-by: John Grossman <johngro@google.com>
Music2 would prefer a configuration interface that takes a single
blob of data passed in from the RPC client and then passes it
opaquely to the media player. This eliminates the need for Music2
to rev their application if we add more configuration options to
the TX player.
Change-Id: Ia2daea3ff2502f91f8a5a82b898752c435279a0f
Previously, sequence numbers for audio packets were assigned by the
TX player before packets were queued to the sender. This caused a
race between assignment of sequence numbers on audio packets and
sequence numbers on heartbeat packets. A heartbeat could get queued
and added to the retry buffer before an audio packet with an earlier
sequence number got queued.
This CL centralizes packet sequence number assignment and insertion
into the retry buffer inside AAH_TXSender::doSendPacket_l. It also
makes explicit what operations can be done on a TRTPPacket before
and after packing.
Change-Id: I6d02eae81061983e4def4f1b3dd7c1625467b151
RTP library used to broadcast media from one device to a collection
of listeners. Handles failures/retries/etc.
This is a squashed merge from master-tungsten of the following changes:
commit e1a5101fe627d71739a7c4263bb3a65c7bc44385
Author: Jason Simmons <jsimmons@google.com>
Date: Fri Aug 12 13:24:21 2011 -0700
Hold ThreadWrapper in a ref-counting pointer
Change-Id: Iaf3343182e37bcc0ca99fbaf8f9bbb8c4984072a
commit 89b90d62e164ff3db27c9cba85255fc476d2dd96
Author: Jason Simmons <jsimmons@google.com>
Date: Wed Aug 10 13:08:25 2011 -0700
Update the Tungsten TX player to use HTTPBase
Change-Id: I9f7ecf1b4b496cec1815284dbcdb958a43284169
commit 43be3231034ff8537fdd84422a7954780038671f
Author: John Grossman <johngro@google.com>
Date: Mon Jun 27 18:59:12 2011 -0700
Move libaah_rtp over from the vendor directory.
Also move factor PipeEvent out into utils.
Change-Id: Id3877c66efe22d771cf3ef4877107e431b828e37
Change-Id: I5fe1ea941c09204d7b33f15f4e2b2ab320dc468b
Signed-off-by: Mike J. Chen <mjchen@google.com>
Signed-off-by: John Grossman <johngro@google.com>
Signed-off-by: Jason Simmons <jsimmons@google.com>