use of com.google.android.exoplayer2.Format in project ExoPlayer by google.
the class Ac4Reader method parseHeader.
/**
* Parses the sample header.
*/
@RequiresNonNull("output")
private void parseHeader() {
headerScratchBits.setPosition(0);
SyncFrameInfo frameInfo = Ac4Util.parseAc4SyncframeInfo(headerScratchBits);
if (format == null || frameInfo.channelCount != format.channelCount || frameInfo.sampleRate != format.sampleRate || !MimeTypes.AUDIO_AC4.equals(format.sampleMimeType)) {
format = new Format.Builder().setId(formatId).setSampleMimeType(MimeTypes.AUDIO_AC4).setChannelCount(frameInfo.channelCount).setSampleRate(frameInfo.sampleRate).setLanguage(language).build();
output.format(format);
}
sampleSize = frameInfo.frameSize;
// In this class a sample is an AC-4 sync frame, but Format#sampleRate specifies the number of
// PCM audio samples per second.
sampleDurationUs = C.MICROS_PER_SECOND * frameInfo.sampleCount / format.sampleRate;
}
use of com.google.android.exoplayer2.Format in project ExoPlayer by google.
the class H263Reader method parseCsdBuffer.
/**
* Parses a codec-specific data buffer, returning the {@link Format} of the media.
*
* @param csdBuffer The buffer to parse.
* @param volStartPosition The byte offset of the start of the video object layer in the buffer.
* @param formatId The ID for the generated format.
* @return The {@link Format} of the media represented in the buffer.
*/
private static Format parseCsdBuffer(CsdBuffer csdBuffer, int volStartPosition, String formatId) {
byte[] csdData = Arrays.copyOf(csdBuffer.data, csdBuffer.length);
ParsableBitArray buffer = new ParsableBitArray(csdData);
buffer.skipBytes(volStartPosition);
// Parse the video object layer defined in ISO 14496-2 (2001) subsection 6.2.3.
// video_object_layer_start_code
buffer.skipBytes(4);
// random_accessible_vol
buffer.skipBit();
// video_object_type_indication
buffer.skipBits(8);
if (buffer.readBit()) {
// is_object_layer_identifier
// video_object_layer_verid
buffer.skipBits(4);
// video_object_layer_priority
buffer.skipBits(3);
}
float pixelWidthHeightRatio;
int aspectRatioInfo = buffer.readBits(4);
if (aspectRatioInfo == 0x0F) {
// extended_PAR
int parWidth = buffer.readBits(8);
int parHeight = buffer.readBits(8);
if (parHeight == 0) {
Log.w(TAG, "Invalid aspect ratio");
pixelWidthHeightRatio = 1f;
} else {
pixelWidthHeightRatio = (float) parWidth / parHeight;
}
} else if (aspectRatioInfo < PIXEL_WIDTH_HEIGHT_RATIO_BY_ASPECT_RATIO_INFO.length) {
pixelWidthHeightRatio = PIXEL_WIDTH_HEIGHT_RATIO_BY_ASPECT_RATIO_INFO[aspectRatioInfo];
} else {
Log.w(TAG, "Invalid aspect ratio");
pixelWidthHeightRatio = 1f;
}
if (buffer.readBit()) {
// vol_control_parameters
// chroma_format
buffer.skipBits(2);
// low_delay
buffer.skipBits(1);
if (buffer.readBit()) {
// vbv_parameters
// first_half_bit_rate
buffer.skipBits(15);
// marker_bit
buffer.skipBit();
// latter_half_bit_rate
buffer.skipBits(15);
// marker_bit
buffer.skipBit();
// first_half_vbv_buffer_size
buffer.skipBits(15);
// marker_bit
buffer.skipBit();
// latter_half_vbv_buffer_size
buffer.skipBits(3);
// first_half_vbv_occupancy
buffer.skipBits(11);
// marker_bit
buffer.skipBit();
// latter_half_vbv_occupancy
buffer.skipBits(15);
// marker_bit
buffer.skipBit();
}
}
int videoObjectLayerShape = buffer.readBits(2);
if (videoObjectLayerShape != VIDEO_OBJECT_LAYER_SHAPE_RECTANGULAR) {
Log.w(TAG, "Unhandled video object layer shape");
}
// marker_bit
buffer.skipBit();
int vopTimeIncrementResolution = buffer.readBits(16);
// marker_bit
buffer.skipBit();
if (buffer.readBit()) {
// fixed_vop_rate
if (vopTimeIncrementResolution == 0) {
Log.w(TAG, "Invalid vop_increment_time_resolution");
} else {
vopTimeIncrementResolution--;
int numBits = 0;
while (vopTimeIncrementResolution > 0) {
++numBits;
vopTimeIncrementResolution >>= 1;
}
// fixed_vop_time_increment
buffer.skipBits(numBits);
}
}
// marker_bit
buffer.skipBit();
int videoObjectLayerWidth = buffer.readBits(13);
// marker_bit
buffer.skipBit();
int videoObjectLayerHeight = buffer.readBits(13);
// marker_bit
buffer.skipBit();
// interlaced
buffer.skipBit();
return new Format.Builder().setId(formatId).setSampleMimeType(MimeTypes.VIDEO_MP4V).setWidth(videoObjectLayerWidth).setHeight(videoObjectLayerHeight).setPixelWidthHeightRatio(pixelWidthHeightRatio).setInitializationData(Collections.singletonList(csdData)).build();
}
use of com.google.android.exoplayer2.Format in project ExoPlayer by google.
the class SeiReader method createTracks.
public void createTracks(ExtractorOutput extractorOutput, TrackIdGenerator idGenerator) {
for (int i = 0; i < outputs.length; i++) {
idGenerator.generateNewId();
TrackOutput output = extractorOutput.track(idGenerator.getTrackId(), C.TRACK_TYPE_TEXT);
Format channelFormat = closedCaptionFormats.get(i);
@Nullable String channelMimeType = channelFormat.sampleMimeType;
Assertions.checkArgument(MimeTypes.APPLICATION_CEA608.equals(channelMimeType) || MimeTypes.APPLICATION_CEA708.equals(channelMimeType), "Invalid closed caption mime type provided: " + channelMimeType);
String formatId = channelFormat.id != null ? channelFormat.id : idGenerator.getFormatId();
output.format(new Format.Builder().setId(formatId).setSampleMimeType(channelMimeType).setSelectionFlags(channelFormat.selectionFlags).setLanguage(channelFormat.language).setAccessibilityChannel(channelFormat.accessibilityChannel).setInitializationData(channelFormat.initializationData).build());
outputs[i] = output;
}
}
use of com.google.android.exoplayer2.Format in project ExoPlayer by google.
the class WavHeaderReader method readFormat.
/**
* Reads and returns a {@code WavFormat}.
*
* @param input Input stream to read the WAV format from. The position should point to the byte
* following the ds64 chunk if present, or to the byte following the WAVE tag otherwise.
* @throws IOException If reading from the input fails.
* @return A new {@code WavFormat} read from {@code input}.
*/
public static WavFormat readFormat(ExtractorInput input) throws IOException {
// Allocate a scratch buffer large enough to store the format chunk.
ParsableByteArray scratch = new ParsableByteArray(16);
// Skip chunks until we find the format chunk.
ChunkHeader chunkHeader = skipToChunk(/* chunkId= */
WavUtil.FMT_FOURCC, input, scratch);
Assertions.checkState(chunkHeader.size >= 16);
input.peekFully(scratch.getData(), 0, 16);
scratch.setPosition(0);
int audioFormatType = scratch.readLittleEndianUnsignedShort();
int numChannels = scratch.readLittleEndianUnsignedShort();
int frameRateHz = scratch.readLittleEndianUnsignedIntToInt();
int averageBytesPerSecond = scratch.readLittleEndianUnsignedIntToInt();
int blockSize = scratch.readLittleEndianUnsignedShort();
int bitsPerSample = scratch.readLittleEndianUnsignedShort();
int bytesLeft = (int) chunkHeader.size - 16;
byte[] extraData;
if (bytesLeft > 0) {
extraData = new byte[bytesLeft];
input.peekFully(extraData, 0, bytesLeft);
} else {
extraData = Util.EMPTY_BYTE_ARRAY;
}
input.skipFully((int) (input.getPeekPosition() - input.getPosition()));
return new WavFormat(audioFormatType, numChannels, frameRateHz, averageBytesPerSecond, blockSize, bitsPerSample, extraData);
}
use of com.google.android.exoplayer2.Format in project ExoPlayer by google.
the class RawCcExtractorTest method rawCcSample.
@Test
public void rawCcSample() throws Exception {
Format format = new Format.Builder().setSampleMimeType(MimeTypes.APPLICATION_CEA608).setCodecs("cea608").setAccessibilityChannel(1).build();
ExtractorAsserts.assertBehavior(() -> new RawCcExtractor(format), "media/rawcc/sample.rawcc", simulationConfig);
}
Aggregations