mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Minor Tweaks
This commit is contained in:
parent
58a2ca6083
commit
8d90498f79
3 changed files with 31 additions and 19 deletions
|
|
@ -49,14 +49,16 @@ public class AviExtractor implements Extractor {
|
||||||
static final int IDX1 = 'i' | ('d' << 8) | ('x' << 16) | ('1' << 24);
|
static final int IDX1 = 'i' | ('d' << 8) | ('x' << 16) | ('1' << 24);
|
||||||
|
|
||||||
static final int JUNK = 'J' | ('U' << 8) | ('N' << 16) | ('K' << 24);
|
static final int JUNK = 'J' | ('U' << 8) | ('N' << 16) | ('K' << 24);
|
||||||
|
static final int REC_ = 'r' | ('e' << 8) | ('c' << 16) | (' ' << 24);
|
||||||
|
|
||||||
static final long SEEK_GAP = 2_000_000L; //Time between seek points in micro seconds
|
static final long SEEK_GAP = 2_000_000L; //Time between seek points in micro seconds
|
||||||
|
|
||||||
private int state;
|
private int state;
|
||||||
private ExtractorOutput output;
|
private ExtractorOutput output;
|
||||||
private AviHeaderBox aviHeader;
|
private AviHeaderBox aviHeader;
|
||||||
|
private long durationUs = C.TIME_UNSET;
|
||||||
private SparseArray<AviTrack> idTrackMap = new SparseArray<>();
|
private SparseArray<AviTrack> idTrackMap = new SparseArray<>();
|
||||||
//After the movi position
|
//At the start of the movi tag
|
||||||
private long moviOffset;
|
private long moviOffset;
|
||||||
private long moviEnd;
|
private long moviEnd;
|
||||||
private AviSeekMap aviSeekMap;
|
private AviSeekMap aviSeekMap;
|
||||||
|
|
@ -154,14 +156,9 @@ public class AviExtractor implements Extractor {
|
||||||
}
|
}
|
||||||
return listBox;
|
return listBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
long getDuration() {
|
long getDuration() {
|
||||||
if (aviHeader == null) {
|
return durationUs;
|
||||||
return C.TIME_UNSET;
|
|
||||||
}
|
|
||||||
return aviHeader.getFrames() * (long)aviHeader.getMicroSecPerFrame();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(ExtractorOutput output) {
|
public void init(ExtractorOutput output) {
|
||||||
this.state = STATE_READ_TRACKS;
|
this.state = STATE_READ_TRACKS;
|
||||||
|
|
@ -185,6 +182,8 @@ public class AviExtractor implements Extractor {
|
||||||
if (aviHeader == null) {
|
if (aviHeader == null) {
|
||||||
throw new IOException("AviHeader not found");
|
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.remove(aviHeader);
|
||||||
//headerChildren should only be Stream Lists now
|
//headerChildren should only be Stream Lists now
|
||||||
|
|
||||||
|
|
@ -228,6 +227,7 @@ public class AviExtractor implements Extractor {
|
||||||
idTrackMap.put('0' | (('0' + streamId) << 8) | ('d' << 16) | ('c' << 24),
|
idTrackMap.put('0' | (('0' + streamId) << 8) | ('d' << 16) | ('c' << 24),
|
||||||
new AviTrack(streamId, trackOutput,
|
new AviTrack(streamId, trackOutput,
|
||||||
streamHeader));
|
streamHeader));
|
||||||
|
durationUs = streamHeader.getUsPerSample() * streamHeader.getLength();
|
||||||
} else if (streamHeader.isAudio()) {
|
} else if (streamHeader.isAudio()) {
|
||||||
final AudioFormat audioFormat = streamFormat.getAudioFormat();
|
final AudioFormat audioFormat = streamFormat.getAudioFormat();
|
||||||
final TrackOutput trackOutput = output.track(streamId, C.TRACK_TYPE_AUDIO);
|
final TrackOutput trackOutput = output.track(streamId, C.TRACK_TYPE_AUDIO);
|
||||||
|
|
@ -329,7 +329,9 @@ public class AviExtractor implements Extractor {
|
||||||
final int id = indexByteBuffer.getInt();
|
final int id = indexByteBuffer.getInt();
|
||||||
final AviTrack aviTrack = idTrackMap.get(id);
|
final AviTrack aviTrack = idTrackMap.get(id);
|
||||||
if (aviTrack == null) {
|
if (aviTrack == null) {
|
||||||
Log.w(TAG, "Unknown Track Type: " + AviUtil.toString(id));
|
if (id != AviExtractor.REC_) {
|
||||||
|
Log.w(TAG, "Unknown Track Type: " + AviUtil.toString(id));
|
||||||
|
}
|
||||||
indexByteBuffer.position(indexByteBuffer.position() + 12);
|
indexByteBuffer.position(indexByteBuffer.position() + 12);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -366,14 +368,16 @@ public class AviExtractor implements Extractor {
|
||||||
entry.getValue().pack();
|
entry.getValue().pack();
|
||||||
idFrameArray.put(entry.getKey(), entry.getValue().array);
|
idFrameArray.put(entry.getKey(), entry.getValue().array);
|
||||||
final AviTrack aviTrack = idTrackMap.get(entry.getKey());
|
final AviTrack aviTrack = idTrackMap.get(entry.getKey());
|
||||||
//Sometimes this value is way off
|
//If the index isn't sparse, double check the audio length
|
||||||
long calcUsPerSample = (getDuration()/aviTrack.frame);
|
if (videoTrack.frame == videoTrack.streamHeaderBox.getLength()) {
|
||||||
float deltaPercent = Math.abs(calcUsPerSample - aviTrack.usPerSample) / (float)aviTrack.usPerSample;
|
//Sometimes this value is way off
|
||||||
if (deltaPercent >.01) {
|
long calcUsPerSample = (getDuration()/aviTrack.frame);
|
||||||
aviTrack.usPerSample = getDuration()/aviTrack.frame;
|
float deltaPercent = Math.abs(calcUsPerSample - aviTrack.usPerSample) / (float)aviTrack.usPerSample;
|
||||||
Log.d(TAG, "Frames act=" + getDuration() + " calc=" + (aviTrack.usPerSample * aviTrack.frame));
|
if (deltaPercent >.01) {
|
||||||
|
aviTrack.usPerSample = getDuration()/aviTrack.frame;
|
||||||
|
Log.d(TAG, "Frames act=" + getDuration() + " calc=" + (aviTrack.usPerSample * aviTrack.frame));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
final AviSeekMap seekMap = new AviSeekMap(videoTrack, seekFrameRate, videoSeekOffset.array,
|
final AviSeekMap seekMap = new AviSeekMap(videoTrack, seekFrameRate, videoSeekOffset.array,
|
||||||
idFrameArray, moviOffset, getDuration());
|
idFrameArray, moviOffset, getDuration());
|
||||||
|
|
@ -415,8 +419,9 @@ public class AviExtractor implements Extractor {
|
||||||
}
|
}
|
||||||
return RESULT_SEEK;
|
return RESULT_SEEK;
|
||||||
} else {
|
} else {
|
||||||
//Log.d(TAG, "Sample pos=" + (input.getPosition() - 8) + " size=" + sampleSize + " video=" + sampleTrack.isVideo());
|
//sampleOffset = (int)(input.getPosition() - 8 - moviOffset);
|
||||||
sampleRemaining = sampleSize - sampleTrack.trackOutput.sampleData(input, sampleSize, false);
|
sampleRemaining = sampleSize - sampleTrack.trackOutput.sampleData(input, sampleSize, false);
|
||||||
|
//Log.d(TAG, "Sample pos=" + (input.getPosition() - 8) + " size=" + sampleSize + " video=" + sampleTrack.isVideo());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sampleRemaining != 0) {
|
if (sampleRemaining != 0) {
|
||||||
|
|
@ -424,7 +429,7 @@ public class AviExtractor implements Extractor {
|
||||||
}
|
}
|
||||||
sampleTrack.trackOutput.sampleMetadata(
|
sampleTrack.trackOutput.sampleMetadata(
|
||||||
sampleTrack.getUs(), sampleTrack.isKeyFrame() ? C.BUFFER_FLAG_KEY_FRAME : 0 , sampleSize, 0, null);
|
sampleTrack.getUs(), sampleTrack.isKeyFrame() ? C.BUFFER_FLAG_KEY_FRAME : 0 , sampleSize, 0, null);
|
||||||
//Log.d(TAG, "Frame: " + (sampleTrack.isVideo()? 'V' : 'A') + " us=" + sampleTrack.getUs());
|
//Log.d(TAG, "Frame: " + (sampleTrack.isVideo()? 'V' : 'A') + " us=" + sampleTrack.getUs() + " size=" + sampleSize);
|
||||||
sampleTrack.advance();
|
sampleTrack.advance();
|
||||||
return RESULT_CONTINUE;
|
return RESULT_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,10 @@ public class AviHeaderBox extends ResidentBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
//4 = dwMaxBytesPerSec
|
//4 = dwMaxBytesPerSec
|
||||||
//8 = dwPaddingGranularity
|
//Always 0, but should be 2
|
||||||
|
// int getPaddingGranularity() {
|
||||||
|
// return byteBuffer.getInt(8);
|
||||||
|
// }
|
||||||
|
|
||||||
int getFlags() {
|
int getFlags() {
|
||||||
return byteBuffer.getInt(12);
|
return byteBuffer.getInt(12);
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,11 @@ public class AviTrack {
|
||||||
if (allKeyFrames) {
|
if (allKeyFrames) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return keyFrames != null && Arrays.binarySearch(keyFrames, frame) >= 0;
|
if (keyFrames != null) {
|
||||||
|
return Arrays.binarySearch(keyFrames, frame) >= 0;
|
||||||
|
}
|
||||||
|
//Hack: Exo needs at least one frame before it starts playback
|
||||||
|
return frame == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setKeyFrames(int[] keyFrames) {
|
public void setKeyFrames(int[] keyFrames) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue