Carriage Implementations
Last updated
Was this helpful?
Last updated
Was this helpful?
In this section, we will provide a brief description of the carriages’ implementation with a focus on the standards-based solutions, in a few well-known player applications.
V-Nova maintains a public fork of the AndroidX Media3 media player SDK (formerly known as ExoPlayer) in which the default decoder (MediaCodecAdapter) can be replaced by a wrapper (LcevcMediaCodecAdapter) that has the additional functionality to detect and decode LCEVC-encoded media. This fork is available here:
In this fork, functionality is also added to support the dual-track delivery mechanism for base and LCEVC enhancement, as described in Section 3.1.2 above. The relative code changes are shown in this commit:
https://github.com/v-novaltd/lcevc-androidx-media/commit/762cf0b4f4c73e9404c36f1972a54a408ffc7d58
Media decoding in Android is provided by the MediaCodec class, which interfaces encoding and decoding services implemented in native code. MediaCodec is a one-input-one-output block, therefore, input from two different streams is not supported out of the box. To circumvent this limitation a “joiner” solution has been used. The joiner prepends each sample of the LCEVC Enhancement track to the corresponding sample of the Base track, thus resulting in a single flow of samples, each new sample being the LCEVC sample followed by the base sample, to the reader and ultimately to MediaCodec. The design of the LCEVC NAL units allows a legacy reader (e.g., the MediaCodec implementation of a base decoder) to interpret them as “reserved” or “unspecified” and thus discard them, which results in the joiner not hindering the decoding of the base component.
The above-linked commit reveals all the code changes. In principle, the joiner solution can be described briefly as:
Modifying the SampleQueue class to:
Add an enhancedSampleQueue
, default null, as a link to a parallel queue for the samples from the enhancement (LCEVC) track;
Add a method attachEnhancement()
to allow setting the enhancedSampleQueue
;
Add a method isEnhancement()
to allow a client to know if the queue is of a base or an enhancement;
Prepend the data read from the linked enhancement queue, if present, to the data read from the queue in the read()
method, effectively performing the join operation;
Adding logic to recognise the presence of the LCEVC track, implementing the signalling as defined in ISO/IEC 14496-15:2024;
LcevcConfig class
Parsable Atoms
Sbas atom and setting of scalableId (as is of the base track)
Adding logic to process main and enhanced tracks in MP4, fragmented MP4, HLS segments, and DASH chunks;
Adding logic to attach the enhancement SampleQueue
to the base SampleQueue
, based on the presence of tref/sbas signalling in MP4;
Note: the current solution maintains the MIME type of the joined stream as the base one.