Skip to content

Commit

Permalink
[common][fmp4] Refactor for better design and performance
Browse files Browse the repository at this point in the history
  • Loading branch information
aldenml committed Mar 28, 2016
1 parent a1836fd commit c60541d
Show file tree
Hide file tree
Showing 14 changed files with 251 additions and 219 deletions.
21 changes: 19 additions & 2 deletions common/src/main/java/com/frostwire/fmp4/Box.java
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ public final <T extends Box> LinkedList<T> find(int type) {
}

public final <T extends Box> T findFirst(int type) {
return Box.<T>findFirst(boxes, type);
return boxes != null ? Box.<T>findFirst(boxes, type) : null;
}

@Override
Expand Down Expand Up @@ -195,7 +195,24 @@ static <T extends Box> LinkedList<T> find(LinkedList<Box> boxes, int type) {
}

static <T extends Box> T findFirst(LinkedList<Box> boxes, int type) {
return Box.<T>find(boxes, type).peekFirst();
T r = null;

for (Box b : boxes) {
if (b.type == type) {
return (T) b;
}
}

for (Box b : boxes) {
if (b.boxes != null) {
T t = findFirst(b.boxes, type);
if (t != null) {
return t;
}
}
}

return null;
}

static Box empty(int type) throws IOException {
Expand Down
36 changes: 36 additions & 0 deletions common/src/main/java/com/frostwire/fmp4/BoxEntry.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Created by Angel Leon (@gubatron), Alden Torres (aldenml)
* Copyright (c) 2011-2016, FrostWire(R). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.frostwire.fmp4;

import java.io.IOException;
import java.nio.ByteBuffer;

/**
* @author gubatron
* @author aldenml
*/
public class BoxEntry {

void get(ByteBuffer buf) throws IOException {
throw new UnsupportedOperationException();
}

void put(ByteBuffer buf) throws IOException {
throw new UnsupportedOperationException();
}
}
21 changes: 14 additions & 7 deletions common/src/main/java/com/frostwire/fmp4/ChunkLargeOffsetBox.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ void read(InputChannel ch, ByteBuffer buf) throws IOException {
for (int i = 0; i < entry_count; i++) {
Entry e = new Entry();
IO.read(ch, 8, buf);
e.chunk_offset = buf.getLong();
e.get(buf);
entries[i] = e;
}
}
Expand All @@ -54,11 +54,7 @@ void write(OutputChannel ch, ByteBuffer buf) throws IOException {

buf.putInt(entry_count);
IO.write(ch, 4, buf);
for (int i = 0; i < entry_count; i++) {
Entry e = entries[i];
buf.putLong(e.chunk_offset);
IO.write(ch, 8, buf);
}
IsoMedia.write(ch, entry_count, 8, entries, buf);
}

@Override
Expand All @@ -70,7 +66,18 @@ void update() {
length(s);
}

public static final class Entry {
public static final class Entry extends BoxEntry {

public long chunk_offset;

@Override
void get(ByteBuffer buf) throws IOException {
chunk_offset = buf.getLong();
}

@Override
void put(ByteBuffer buf) throws IOException {
buf.putLong(chunk_offset);
}
}
}
38 changes: 18 additions & 20 deletions common/src/main/java/com/frostwire/fmp4/ChunkOffsetBox.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
* @author gubatron
* @author aldenml
*/
public final class ChunkOffsetBox extends EntryBaseBox {
public final class ChunkOffsetBox extends FullBox {

protected int entry_count;
protected Entry[] entries;
Expand All @@ -43,31 +43,18 @@ void read(InputChannel ch, ByteBuffer buf) throws IOException {
for (int i = 0; i < entry_count; i++) {
Entry e = new Entry();
IO.read(ch, 4, buf);
e.chunk_offset = buf.getInt();
e.get(buf);
entries[i] = e;
}
}

@Override
void writeFields(OutputChannel ch, ByteBuffer buf) throws IOException {
void write(OutputChannel ch, ByteBuffer buf) throws IOException {
super.write(ch, buf);

buf.putInt(entry_count);
IO.write(ch, 4, buf);
}

@Override
int entryCount() {
return entry_count;
}

@Override
int entrySize() {
return 4;
}

@Override
void putEntry(int i, ByteBuffer buf) {
Entry e = entries[i];
buf.putInt(e.chunk_offset);
IsoMedia.write(ch, entry_count, 4, entries, buf);
}

@Override
Expand All @@ -79,7 +66,18 @@ void update() {
length(s);
}

public static final class Entry {
public static final class Entry extends BoxEntry {

public int chunk_offset;

@Override
void get(ByteBuffer buf) throws IOException {
chunk_offset = buf.getInt();
}

@Override
void put(ByteBuffer buf) throws IOException {
buf.putInt(chunk_offset);
}
}
}
25 changes: 16 additions & 9 deletions common/src/main/java/com/frostwire/fmp4/CompositionOffsetBox.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ void read(InputChannel ch, ByteBuffer buf) throws IOException {
for (int i = 0; i < entry_count; i++) {
Entry e = new Entry();
IO.read(ch, 8, buf);
e.sample_count = buf.getInt();
e.sample_offset = buf.getInt();
e.get(buf);
entries[i] = e;
}
}
Expand All @@ -55,12 +54,7 @@ void write(OutputChannel ch, ByteBuffer buf) throws IOException {

buf.putInt(entry_count);
IO.write(ch, 4, buf);
for (int i = 0; i < entry_count; i++) {
Entry e = entries[i];
buf.putInt(e.sample_count);
buf.putInt(e.sample_offset);
IO.write(ch, 8, buf);
}
IsoMedia.write(ch, entry_count, 8, entries, buf);
}

@Override
Expand All @@ -72,8 +66,21 @@ void update() {
length(s);
}

public static final class Entry {
public static final class Entry extends BoxEntry {

public int sample_count;
public int sample_offset;

@Override
void get(ByteBuffer buf) throws IOException {
sample_count = buf.getInt();
sample_offset = buf.getInt();
}

@Override
void put(ByteBuffer buf) throws IOException {
buf.putInt(sample_count);
buf.putInt(sample_offset);
}
}
}
69 changes: 0 additions & 69 deletions common/src/main/java/com/frostwire/fmp4/EntryBaseBox.java

This file was deleted.

47 changes: 35 additions & 12 deletions common/src/main/java/com/frostwire/fmp4/IsoMedia.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
*/
public final class IsoMedia {

private static final int DEFAULT_BUFFER_SIZE = 10 * 1014; // 10K

private IsoMedia() {
}

Expand Down Expand Up @@ -104,7 +106,8 @@ public static boolean read(InputChannel ch, long len, Box p, OnBoxListener l, By

public static void read(InputChannel ch, OnBoxListener l) throws IOException {
try {
read(ch, -1, null, l, ByteBuffer.allocate(10 * 1024));
ByteBuffer buf = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE);
read(ch, -1, null, l, buf);
} catch (EOFException e) {
// ignore, it's the end
}
Expand All @@ -116,24 +119,29 @@ public static LinkedList<Box> head(RandomAccessFile in, ByteBuffer buf) throws I
final InputChannel ch = new InputChannel(in.getChannel());
final LinkedList<Box> boxes = new LinkedList<>();

read(ch, -1, null, new OnBoxListener() {
@Override
public boolean onBox(Box b) {
if (b.parent == null) {
boxes.add(b);
}
try {
read(ch, -1, null, new OnBoxListener() {
@Override
public boolean onBox(Box b) {
if (b.parent == null) {
boxes.add(b);
}

return b.type != Box.mdat;
}
}, buf);
return b.type != Box.mdat;
}
}, buf);
} catch (EOFException e) {
// ignore, it's the end
}

in.seek(0);

return boxes;
}

public static LinkedList<Box> head(RandomAccessFile in) throws IOException {
return head(in, ByteBuffer.allocate(10 * 1024));
ByteBuffer buf = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE);
return head(in, buf);
}

public static boolean write(OutputChannel ch, LinkedList<Box> boxes, OnBoxListener l, ByteBuffer buf) throws IOException {
Expand Down Expand Up @@ -181,7 +189,22 @@ public static boolean write(OutputChannel ch, LinkedList<Box> boxes, OnBoxListen
}

public static void write(OutputChannel ch, LinkedList<Box> boxes, OnBoxListener l) throws IOException {
write(ch, boxes, l, ByteBuffer.allocate(10 * 1024));
ByteBuffer buf = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE);
write(ch, boxes, l, buf);
}

static void write(OutputChannel ch, int count, int size, BoxEntry[] entries, ByteBuffer buf) throws IOException {
if (count > 0) {
for (int i = 0; i < count; i++) {
if (buf.position() > 0 && buf.remaining() < size) {
IO.write(ch, buf.position(), buf);
}
entries[i].put(buf);
}
if (buf.position() > 0) {
IO.write(ch, buf.position(), buf);
}
}
}

public interface OnBoxListener {
Expand Down

0 comments on commit c60541d

Please sign in to comment.