mirror of
https://github.com/androidx/media.git
synced 2025-05-03 21:57:46 +08:00
Adjust SEF slow motion parsing to base data type off name.
PiperOrigin-RevId: 342050008
This commit is contained in:
parent
99b87139df
commit
55afddf05c
@ -16,10 +16,8 @@
|
||||
package com.google.android.exoplayer2.extractor.mp4;
|
||||
|
||||
import static com.google.android.exoplayer2.extractor.Extractor.RESULT_SEEK;
|
||||
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.ParserException;
|
||||
import com.google.android.exoplayer2.extractor.Extractor;
|
||||
@ -34,7 +32,6 @@ import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -80,15 +77,20 @@ import java.util.List;
|
||||
|
||||
private static final String TAG = "SefReader";
|
||||
|
||||
// Hex representation of `SEFT` (in ASCII). This is the last byte of a file that has Samsung
|
||||
// Extension Format (SEF) data.
|
||||
/**
|
||||
* Hex representation of `SEFT` (in ASCII).
|
||||
*
|
||||
* <p>This is the last 4 bytes of a file that has Samsung Extension Format (SEF) data.
|
||||
*/
|
||||
private static final int SAMSUNG_TAIL_SIGNATURE = 0x53454654;
|
||||
|
||||
// Start signature (4 bytes), SEF version (4 bytes), SDR count (4 bytes).
|
||||
/** Start signature (4 bytes), SEF version (4 bytes), SDR count (4 bytes). */
|
||||
private static final int TAIL_HEADER_LENGTH = 12;
|
||||
// Tail offset (4 bytes), tail signature (4 bytes).
|
||||
/** Tail offset (4 bytes), tail signature (4 bytes). */
|
||||
private static final int TAIL_FOOTER_LENGTH = 8;
|
||||
|
||||
private static final int LENGTH_OF_ONE_SDR = 12;
|
||||
private static final Splitter COLON_SPLITTER = Splitter.on(':');
|
||||
private static final Splitter ASTERISK_SPLITTER = Splitter.on('*');
|
||||
|
||||
private final List<DataReference> dataReferences;
|
||||
@State private int readerState;
|
||||
@ -145,7 +147,7 @@ import java.util.List;
|
||||
return;
|
||||
}
|
||||
|
||||
// input.getPosition is at the very end of the tail, so jump forward by sefTailLength, but
|
||||
// input.getPosition is at the very end of the tail, so jump forward by tailLength, but
|
||||
// account for the tail header, which needs to be ignored.
|
||||
seekPosition.position = input.getPosition() - (tailLength - TAIL_HEADER_LENGTH);
|
||||
readerState = STATE_READING_SDRS;
|
||||
@ -182,29 +184,52 @@ import java.util.List;
|
||||
return;
|
||||
}
|
||||
|
||||
Collections.sort(dataReferences, (o1, o2) -> Long.compare(o1.startOffset, o2.startOffset));
|
||||
readerState = STATE_READING_SEF_DATA;
|
||||
seekPosition.position = dataReferences.get(0).startOffset;
|
||||
}
|
||||
|
||||
private void readSefData(ExtractorInput input, List<Metadata.Entry> slowMotionMetadataEntries)
|
||||
throws IOException {
|
||||
checkNotNull(dataReferences);
|
||||
Splitter splitter = Splitter.on(':');
|
||||
long dataStartOffset = input.getPosition();
|
||||
int totalDataLength = (int) (input.getLength() - input.getPosition() - tailLength);
|
||||
ParsableByteArray scratch = new ParsableByteArray(/* limit= */ totalDataLength);
|
||||
input.readFully(scratch.getData(), 0, totalDataLength);
|
||||
ParsableByteArray data = new ParsableByteArray(/* limit= */ totalDataLength);
|
||||
input.readFully(data.getData(), 0, totalDataLength);
|
||||
|
||||
int totalDataReferenceBytesConsumed = 0;
|
||||
for (int i = 0; i < dataReferences.size(); i++) {
|
||||
DataReference dataReference = dataReferences.get(i);
|
||||
if (dataReference.dataType == TYPE_SLOW_MOTION_DATA) {
|
||||
scratch.skipBytes(23); // data type (2), data sub info (2), name len (4), name (15).
|
||||
int intendedPosition = (int) (dataReference.startOffset - dataStartOffset);
|
||||
data.setPosition(intendedPosition);
|
||||
|
||||
// The data type is derived from the name because the SEF format has inconsistent data type
|
||||
// values.
|
||||
data.skipBytes(4); // data type (2), data sub info (2).
|
||||
int nameLength = data.readLittleEndianInt();
|
||||
String name = data.readString(nameLength);
|
||||
@DataType int dataType = nameToDataType(name);
|
||||
|
||||
int remainingDataLength = dataReference.size - (8 + nameLength);
|
||||
switch (dataType) {
|
||||
case TYPE_SLOW_MOTION_DATA:
|
||||
slowMotionMetadataEntries.add(readSlowMotionData(data, remainingDataLength));
|
||||
break;
|
||||
case TYPE_SUPER_SLOW_MOTION_DATA:
|
||||
case TYPE_SUPER_SLOW_MOTION_BGM:
|
||||
case TYPE_SUPER_SLOW_MOTION_EDIT_DATA:
|
||||
case TYPE_SUPER_SLOW_DEFLICKERING_ON:
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static SlowMotionData readSlowMotionData(ParsableByteArray data, int dataLength)
|
||||
throws ParserException {
|
||||
List<SlowMotionData.Segment> segments = new ArrayList<>();
|
||||
int dataReferenceEndPosition = totalDataReferenceBytesConsumed + dataReference.size;
|
||||
while (scratch.getPosition() < dataReferenceEndPosition) {
|
||||
@Nullable String data = scratch.readDelimiterTerminatedString('*');
|
||||
List<String> values = splitter.splitToList(checkNotNull(data));
|
||||
String dataString = data.readString(dataLength);
|
||||
List<String> segmentStrings = ASTERISK_SPLITTER.splitToList(dataString);
|
||||
for (int i = 0; i < segmentStrings.size(); i++) {
|
||||
List<String> values = COLON_SPLITTER.splitToList(segmentStrings.get(i));
|
||||
if (values.size() != 3) {
|
||||
throw new ParserException();
|
||||
}
|
||||
@ -218,10 +243,7 @@ import java.util.List;
|
||||
throw new ParserException(e);
|
||||
}
|
||||
}
|
||||
totalDataReferenceBytesConsumed += dataReference.size;
|
||||
slowMotionMetadataEntries.add(new SlowMotionData(segments));
|
||||
}
|
||||
}
|
||||
return new SlowMotionData(segments);
|
||||
}
|
||||
|
||||
@DataType
|
||||
|
Loading…
x
Reference in New Issue
Block a user