Refactor, remove dead code

This commit is contained in:
Dustin 2022-01-18 23:25:42 -07:00
parent 8d90498f79
commit d9afe5105b
8 changed files with 37 additions and 173 deletions

View file

@ -26,8 +26,23 @@ import java.util.Map;
* https://docs.microsoft.com/en-us/windows/win32/directshow/avi-riff-file-reference
*/
public class AviExtractor implements Extractor {
static final long UINT_MASK = 0xffffffffL;
static long getUInt(ByteBuffer byteBuffer) {
return byteBuffer.getInt() & UINT_MASK;
}
@NonNull
static String toString(int tag) {
final StringBuilder sb = new StringBuilder(4);
for (int i=0;i<4;i++) {
sb.append((char)(tag & 0xff));
tag >>=8;
}
return sb.toString();
}
static final String TAG = "AviExtractor";
static final int KEY_FRAME_MASK = Integer.MIN_VALUE;
private static final int PEEK_BYTES = 28;
private static final int STATE_READ_TRACKS = 0;
@ -39,8 +54,8 @@ public class AviExtractor implements Extractor {
private static final int AVIIF_KEYFRAME = 16;
static final int RIFF = AviUtil.toInt(new byte[]{'R','I','F','F'});
static final int AVI_ = AviUtil.toInt(new byte[]{'A','V','I',' '});
static final int RIFF = 'R' | ('I' << 8) | ('F' << 16) | ('F' << 24);
static final int AVI_ = 'A' | ('V' << 8) | ('I' << 16) | (' ' << 24);
//Stream List
static final int STRL = 's' | ('t' << 8) | ('r' << 16) | ('l' << 24);
//movie data box
@ -103,7 +118,7 @@ public class AviExtractor implements Extractor {
if (riff != AviExtractor.RIFF) {
return false;
}
long reportedLen = AviUtil.getUInt(byteBuffer) + byteBuffer.position();
long reportedLen = getUInt(byteBuffer) + byteBuffer.position();
final long inputLen = input.getLength();
if (inputLen != C.LENGTH_UNSET && inputLen != reportedLen) {
Log.w(TAG, "Header length doesn't match stream length");
@ -136,7 +151,7 @@ public class AviExtractor implements Extractor {
if (riff != AviExtractor.RIFF) {
return null;
}
long reportedLen = AviUtil.getUInt(byteBuffer) + byteBuffer.position();
long reportedLen = getUInt(byteBuffer) + byteBuffer.position();
final long inputLen = input.getLength();
if (inputLen != C.LENGTH_UNSET && inputLen != reportedLen) {
Log.w(TAG, "Header length doesn't match stream length");
@ -177,18 +192,15 @@ public class AviExtractor implements Extractor {
if (headerList == null) {
throw new IOException("AVI Header List not found");
}
final List<Box> headerChildren = headerList.getChildren();
aviHeader = AviUtil.getBox(headerChildren, AviHeaderBox.class);
aviHeader = headerList.getChild(AviHeaderBox.class);
if (aviHeader == null) {
throw new IOException("AviHeader not found");
}
//This is usually wrong, so it will be overwritten by video if present
durationUs = aviHeader.getFrames() * (long)aviHeader.getMicroSecPerFrame();
headerChildren.remove(aviHeader);
//headerChildren should only be Stream Lists now
int streamId = 0;
for (Box box : headerChildren) {
for (Box box : headerList.getChildren()) {
if (box instanceof ListBox && ((ListBox) box).getListType() == STRL) {
final ListBox streamList = (ListBox) box;
final List<Box> streamChildren = streamList.getChildren();
@ -238,7 +250,6 @@ public class AviExtractor implements Extractor {
builder.setChannelCount(audioFormat.getChannels());
builder.setSampleRate(audioFormat.getSamplesPerSecond());
if (audioFormat.getFormatTag() == AudioFormat.WAVE_FORMAT_PCM) {
//TODO: Determine if this is LE or BE - Most likely LE
final short bps = audioFormat.getBitsPerSample();
if (bps == 8) {
builder.setPcmEncoding(C.ENCODING_PCM_8BIT);
@ -268,7 +279,7 @@ public class AviExtractor implements Extractor {
ByteBuffer byteBuffer = allocate(12);
input.readFully(byteBuffer.array(), 0,12);
final int tag = byteBuffer.getInt();
final long size = byteBuffer.getInt() & AviUtil.UINT_MASK;
final long size = getUInt(byteBuffer);
final long position = input.getPosition();
//-4 because we over read for the LIST type
long nextBox = position + size - 4;
@ -330,7 +341,7 @@ public class AviExtractor implements Extractor {
final AviTrack aviTrack = idTrackMap.get(id);
if (aviTrack == null) {
if (id != AviExtractor.REC_) {
Log.w(TAG, "Unknown Track Type: " + AviUtil.toString(id));
Log.w(TAG, "Unknown Track Type: " + toString(id));
}
indexByteBuffer.position(indexByteBuffer.position() + 12);
continue;
@ -413,7 +424,7 @@ public class AviExtractor implements Extractor {
} else {
seekPosition.position = input.getPosition() + sampleSize;
if (id != JUNK) {
Log.w(TAG, "Unknown tag=" + AviUtil.toString(id) + " pos=" + (input.getPosition() - 8)
Log.w(TAG, "Unknown tag=" + toString(id) + " pos=" + (input.getPosition() - 8)
+ " size=" + sampleSize + " moviEnd=" + moviEnd);
}
}
@ -470,7 +481,6 @@ public class AviExtractor implements Extractor {
@Override
public void seek(long position, long timeUs) {
Log.d("Test", "Seek: pos=" + position + " us=" + timeUs);
if (position == 0) {
if (moviOffset != 0) {
resetFrames();

View file

@ -12,11 +12,6 @@ public class AviHeaderBox extends ResidentBox {
super(type, size, byteBuffer);
}
@Override
boolean assertType() {
return simpleAssert(AVIH);
}
boolean hasIndex() {
return (getFlags() & AVIF_HASINDEX) > 0;
}

View file

@ -1,68 +0,0 @@
package com.google.android.exoplayer2.extractor.avi;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.extractor.ExtractorInput;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.List;
public class AviUtil {
static final long UINT_MASK = 0xffffffffL;
static int toInt(byte[] bytes) {
int i = 0;
for (int b=bytes.length - 1;b>=0;b--) {
i <<=8;
i |= bytes[b];
}
return i;
}
static long getUInt(ByteBuffer byteBuffer) {
return byteBuffer.getInt() & UINT_MASK;
}
static void copy(ByteBuffer source, ByteBuffer dest, int bytes) {
final int inLimit = source.limit();
source.limit(source.position() + bytes);
dest.put(source);
source.limit(inLimit);
}
static ByteBuffer getByteBuffer(final ByteBuffer source, final int size,
final ExtractorInput input) throws IOException {
final ByteBuffer byteBuffer = AviExtractor.allocate(size);
if (size < source.remaining()) {
copy(source, byteBuffer, size);
} else {
final int copy = source.remaining();
copy(source, byteBuffer, copy);
int remaining = size - copy;
final int offset = byteBuffer.position() + byteBuffer.arrayOffset();
input.readFully(byteBuffer.array(), offset, remaining, false);
}
return byteBuffer;
}
@NonNull
static String toString(int tag) {
final StringBuilder sb = new StringBuilder(4);
for (int i=0;i<4;i++) {
sb.append((char)(tag & 0xff));
tag >>=8;
}
return sb.toString();
}
@Nullable
static <T extends Box> T getBox(List<? extends Box> list, Class<T> clazz) {
for (Box box : list) {
if (box.getClass() == clazz) {
return (T)box;
}
}
return null;
}
}

View file

@ -13,11 +13,7 @@ public class Box {
}
public long getSize() {
return size & AviUtil.UINT_MASK;
}
public int getSizeInt() {
return size;
return size & AviExtractor.UINT_MASK;
}
public int getType() {
@ -28,8 +24,4 @@ public class Box {
return getType() == expected;
}
boolean assertType() {
//Generic box, nothing to assert
return true;
}
}

View file

@ -1,6 +1,5 @@
package com.google.android.exoplayer2.extractor.avi;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.extractor.ExtractorInput;
import java.io.IOException;
import java.nio.ByteBuffer;
@ -16,25 +15,6 @@ public class BoxFactory {
return Arrays.binarySearch(types, type) < 0;
}
@Nullable
public ResidentBox createBox(final int type, final int size, final ByteBuffer byteBuffer) {
final ByteBuffer boxBuffer = AviExtractor.allocate(size);
AviUtil.copy(byteBuffer, boxBuffer, size);
//TODO: Deal with list
switch (type) {
case AviHeaderBox.AVIH:
return new AviHeaderBox(type, size, boxBuffer);
case StreamHeaderBox.STRH:
return new StreamHeaderBox(type, size, boxBuffer);
case StreamFormatBox.STRF:
return new StreamFormatBox(type, size, boxBuffer);
case StreamDataBox.STRD:
return new StreamDataBox(type, size, boxBuffer);
default:
return null;
}
}
private ResidentBox createBoxImpl(final int type, final int size, final ByteBuffer boxBuffer) {
switch (type) {
case AviHeaderBox.AVIH:

View file

@ -1,6 +1,7 @@
package com.google.android.exoplayer2.extractor.avi;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.extractor.ExtractorInput;
import java.io.IOException;
import java.nio.ByteBuffer;
@ -29,26 +30,20 @@ public class ListBox extends Box {
return listType;
}
@Override
boolean assertType() {
return simpleAssert(LIST);
}
@NonNull
public List<Box> getChildren() {
return new ArrayList<>(children);
}
// static List<ResidentBox> realizeChildren(final ByteBuffer byteBuffer, final BoxFactory boxFactory) {
// final List<ResidentBox> list = new ArrayList<>();
// while (byteBuffer.hasRemaining()) {
// final int type = byteBuffer.getInt();
// final int size = byteBuffer.getInt();
// final ResidentBox residentBox = boxFactory.createBox(type, size, byteBuffer);
// list.add(residentBox);
// }
// return list;
// }
@Nullable
public <T extends Box> T getChild(Class<T> c) {
for (Box box : children) {
if (box.getClass() == c) {
return (T)box;
}
}
return null;
}
/**
* Assume the input is pointing to the list type

View file

@ -24,46 +24,6 @@ public class ResidentBox extends Box {
this.byteBuffer = byteBuffer;
}
/**
* List is not yet populated
* @param byteBuffer
* @return
* @throws IOException
*/
@Nullable
public static <T extends ResidentBox> T getInstance(final ByteBuffer byteBuffer,
ExtractorInput input, Class<T> boxClass) throws IOException {
if (byteBuffer.remaining() < 8) {
//Should not happen
throw new BufferUnderflowException();
}
final int type = byteBuffer.getInt();
final long size = AviUtil.getUInt(byteBuffer);
if (size > MAX_RESIDENT) {
throw new BufferOverflowException();
}
final ByteBuffer boxBuffer = AviUtil.getByteBuffer(byteBuffer, (int)size, input);
return newInstance(type, (int)size, boxBuffer, boxClass);
}
@Nullable
private static <T extends ResidentBox> T newInstance(int type, int size, ByteBuffer boxBuffer,
Class<T> boxClass) {
try {
final Constructor<T> constructor =
boxClass.getDeclaredConstructor(int.class, int.class, ByteBuffer.class);
T box = constructor.newInstance(type, size, boxBuffer);
if (!box.assertType()) {
Log.e(TAG, "Expected " + AviUtil.toString(type) + " got " + AviUtil.toString(box.getType()));
return null;
}
return box;
} catch (Exception e) {
Log.e(TAG, "Create box failed " + AviUtil.toString(type));
return null;
}
}
/**
* Returns shallow copy of this ByteBuffer with the position at 0
* @return

View file

@ -90,7 +90,7 @@ public class StreamHeaderBox extends ResidentBox {
return byteBuffer.getInt(28);
}
public long getLength() {
return byteBuffer.getInt(32) & AviUtil.UINT_MASK;
return byteBuffer.getInt(32) & AviExtractor.UINT_MASK;
}
//36 - dwSuggestedBufferSize
//40 - dwQuality