Skip to content

Commit

Permalink
[common][fmp4] Important optimization to write entry based boxes in c…
Browse files Browse the repository at this point in the history
…hunks (less actual disk write)
  • Loading branch information
aldenml committed Mar 27, 2016
1 parent ae28ce1 commit 3bccfcf
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 41 deletions.
27 changes: 18 additions & 9 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 FullBox {
public final class ChunkOffsetBox extends EntryBaseBox {

protected int entry_count;
protected Entry[] entries;
Expand All @@ -49,16 +49,25 @@ void read(InputChannel ch, ByteBuffer buf) throws IOException {
}

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

void writeFields(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.chunk_offset);
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);
}

@Override
Expand Down
69 changes: 69 additions & 0 deletions common/src/main/java/com/frostwire/fmp4/EntryBaseBox.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* 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 EntryBaseBox extends FullBox {

EntryBaseBox(int type) {
super(type);
}

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

writeFields(ch, buf);
int entry_count = entryCount();
int entry_size = entrySize();

if (entry_count > 0) {
for (int i = 0; i < entry_count; i++) {
if (buf.position() > 0 && buf.remaining() < entry_size) {
IO.write(ch, buf.position(), buf);

This comment has been minimized.

Copy link
@gubatron

gubatron Mar 28, 2016

Collaborator

never writes the byte at [0] ?

This comment has been minimized.

Copy link
@aldenml

aldenml Mar 28, 2016

Author Collaborator

After the for, if anything is written to the buf, it's then written to the channel. Do you see something weird here?

This comment has been minimized.

Copy link
@gubatron

gubatron Mar 28, 2016

Collaborator

yes, It looks as if the buffer is like this:

[24, 144, 256, 45, ...]

it only writes from offset 1 (144) and skips the value at 0, but I haven't read the code on IO.write I might be wrong, or you might be purposefully skpping that 1st byte.

This comment has been minimized.

Copy link
@gubatron

gubatron Mar 28, 2016

Collaborator

but maybe this never happens because you have that call above:
writeFields(ch, buf);

which might move the buf's position.

This comment has been minimized.

Copy link
@aldenml

aldenml Mar 28, 2016

Author Collaborator

IO.write second argument is the length of bytes to write, always starts at 0 or the current buffer mark

}
putEntry(i, buf);
}
if (buf.position() > 0) {
IO.write(ch, buf.position(), buf);
}
}
}

void writeFields(OutputChannel ch, ByteBuffer buf) throws IOException {
throw new UnsupportedOperationException(Bits.make4cc(type));
}

int entryCount() {
throw new UnsupportedOperationException(Bits.make4cc(type));
}

int entrySize() {
throw new UnsupportedOperationException(Bits.make4cc(type));
}

void putEntry(int i, ByteBuffer buf) {
throw new UnsupportedOperationException(Bits.make4cc(type));
}
}
29 changes: 18 additions & 11 deletions common/src/main/java/com/frostwire/fmp4/SampleSizeBox.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
* @author gubatron
* @author aldenml
*/
public final class SampleSizeBox extends FullBox {
public final class SampleSizeBox extends EntryBaseBox {

protected int sample_size;
protected int sample_count;
Expand Down Expand Up @@ -53,19 +53,26 @@ void read(InputChannel ch, ByteBuffer buf) throws IOException {
}

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

void writeFields(OutputChannel ch, ByteBuffer buf) throws IOException {
buf.putInt(sample_size);
buf.putInt(sample_count);
IO.write(ch, 8, buf);
if (entries != null) {
for (int i = 0; i < sample_count; i++) {
Entry e = entries[i];
buf.putInt(e.entry_size);
IO.write(ch, 4, buf);
}
}
}

@Override
int entryCount() {
return entries != null ? sample_count : 0;
}

@Override
int entrySize() {
return 4;
}

@Override
void putEntry(int i, ByteBuffer buf) {
Entry e = entries[i];
buf.putInt(e.entry_size);
}

@Override
Expand Down
31 changes: 20 additions & 11 deletions common/src/main/java/com/frostwire/fmp4/SampleToChunkBox.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
* @author gubatron
* @author aldenml
*/
public final class SampleToChunkBox extends FullBox {
public final class SampleToChunkBox extends EntryBaseBox {

protected int entry_count;
protected Entry[] entries;
Expand All @@ -51,18 +51,27 @@ void read(InputChannel ch, ByteBuffer buf) throws IOException {
}

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

void writeFields(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.first_chunk);
buf.putInt(e.samples_per_chunk);
buf.putInt(e.sample_description_index);
IO.write(ch, 12, buf);
}
}

@Override
int entryCount() {
return entry_count;
}

@Override
int entrySize() {
return 12;
}

@Override
void putEntry(int i, ByteBuffer buf) {
Entry e = entries[i];
buf.putInt(e.first_chunk);
buf.putInt(e.samples_per_chunk);
buf.putInt(e.sample_description_index);
}

@Override
Expand Down
29 changes: 19 additions & 10 deletions common/src/main/java/com/frostwire/fmp4/TimeToSampleBox.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
* @author gubatron
* @author aldenml
*/
public final class TimeToSampleBox extends FullBox {
public final class TimeToSampleBox extends EntryBaseBox {

protected int entry_count;
protected Entry[] entries;
Expand All @@ -50,17 +50,26 @@ void read(InputChannel ch, ByteBuffer buf) throws IOException {
}

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

void writeFields(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_delta);
IO.write(ch, 8, buf);
}
}

@Override
int entryCount() {
return entry_count;
}

@Override
int entrySize() {
return 8;
}

@Override
void putEntry(int i, ByteBuffer buf) {
Entry e = entries[i];
buf.putInt(e.sample_count);
buf.putInt(e.sample_delta);
}

@Override
Expand Down

0 comments on commit 3bccfcf

Please sign in to comment.