Skip to content

Commit

Permalink
Add support for H.263 and MPEG-4 Part 2 in TS
Browse files Browse the repository at this point in the history
The new reader is named H263Reader as it handles H.263 streams, but
MPEG-4 Part 2 streams are also intended to be handled. The reader's
output format MIME type is video/mp4v as the H.263 streams can be
decoded by decoders supporting this MIME type.

The implementation is based on the framework implementation for
extracting MPEG-4 video in MPEG-TS
(https://cs.android.com/android/platform/superproject/+/master:frameworks/av/media/libstagefright/mpeg2ts/ESQueue.cpp;l=1825;drc=86e363c1fac27302ca4ae33e73296f7797672995)
and is similar to the existing H262Reader.

Issue: #1603
Issue: #5107
PiperOrigin-RevId: 320565337
  • Loading branch information
andrewlewis authored and kim-vde committed Jul 13, 2020
1 parent a8f1cdc commit 1e2ed51
Showing 12 changed files with 913 additions and 5 deletions.
3 changes: 3 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
@@ -212,6 +212,9 @@
headers mime type in `DefaultExtractorsFactory`.
* Add support for partially fragmented MP4s
([#7308](https://github.com/google/ExoPlayer/issues/7308)).
* Add support for MPEG-4 Part 2 and H.263 in MPEG-TS
([#1603](https://github.com/google/ExoPlayer/issues/1603),
[#5107](https://github.com/google/ExoPlayer/issues/5107)).
* Testing
* Add `TestExoPlayer`, a utility class with APIs to create
`SimpleExoPlayer` instances with fake components for testing.
Original file line number Diff line number Diff line change
@@ -165,6 +165,8 @@ public TsPayloadReader createPayloadReader(int streamType, EsInfo esInfo) {
return new PesReader(new DtsReader(esInfo.language));
case TsExtractor.TS_STREAM_TYPE_H262:
return new PesReader(new H262Reader(buildUserDataReader(esInfo)));
case TsExtractor.TS_STREAM_TYPE_H263:
return new PesReader(new H263Reader(buildUserDataReader(esInfo)));
case TsExtractor.TS_STREAM_TYPE_H264:
return isSet(FLAG_IGNORE_H264_STREAM) ? null
: new PesReader(new H264Reader(buildSeiReader(esInfo),
Original file line number Diff line number Diff line change
@@ -15,14 +15,16 @@
*/
package com.google.android.exoplayer2.extractor.ts;

import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Assertions.checkStateNotNull;

import android.util.Pair;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.extractor.ExtractorOutput;
import com.google.android.exoplayer2.extractor.TrackOutput;
import com.google.android.exoplayer2.extractor.ts.TsPayloadReader.TrackIdGenerator;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.NalUnitUtil;
import com.google.android.exoplayer2.util.ParsableByteArray;
@@ -118,7 +120,7 @@ public void packetStarted(long pesTimeUs, @TsPayloadReader.Flags int flags) {

@Override
public void consume(ParsableByteArray data) {
Assertions.checkStateNotNull(output); // Asserts that createTracks has been called.
checkStateNotNull(output); // Asserts that createTracks has been called.
int offset = data.getPosition();
int limit = data.limit();
byte[] dataArray = data.data;
@@ -156,7 +158,7 @@ public void consume(ParsableByteArray data) {
int bytesAlreadyPassed = lengthToStartCode < 0 ? -lengthToStartCode : 0;
if (csdBuffer.onStartCode(startCodeValue, bytesAlreadyPassed)) {
// The csd data is complete, so we can decode and output the media format.
Pair<Format, Long> result = parseCsdBuffer(csdBuffer, formatId);
Pair<Format, Long> result = parseCsdBuffer(csdBuffer, checkNotNull(formatId));
output.format(result.first);
frameDurationUs = result.second;
hasOutputFormat = true;
@@ -215,11 +217,11 @@ public void packetFinished() {
* Parses the {@link Format} and frame duration from a csd buffer.
*
* @param csdBuffer The csd buffer.
* @param formatId The id for the generated format. May be null.
* @param formatId The id for the generated format.
* @return A pair consisting of the {@link Format} and the frame duration in microseconds, or 0 if
* the duration could not be determined.
*/
private static Pair<Format, Long> parseCsdBuffer(CsdBuffer csdBuffer, @Nullable String formatId) {
private static Pair<Format, Long> parseCsdBuffer(CsdBuffer csdBuffer, String formatId) {
byte[] csdData = Arrays.copyOf(csdBuffer.data, csdBuffer.length);

int firstByte = csdData[4] & 0xFF;
Loading

0 comments on commit 1e2ed51

Please sign in to comment.