RIM proprietary video format (RIMM streaming file)
The RIM proprietary
video format consists of a header, a list of frames, and a footer. When parsing
this file, all values of type
int or
short are little-endian.
Header
|
Field
|
Value
|
Size
|
|
ID tag
|
RIMM
|
4 B
|
|
version
|
0
|
3 B
|
|
descriptor location
|
- 0 if recording
to a file
- 1 if recording
to a stream
|
1 B
|
|
descriptor
|
descriptor values
|
- 75 B if
recording to a file
- 0 B if recording
to a stream
|
Frames
|
Field
|
Value
|
Size
|
|
stream type
|
- 0 if this is a
frame of audio
- 1 if this is a
frame of video
|
1 B
|
|
key frame
|
- 1 if this is a
key frame
- 0 otherwise
|
1 b
|
|
config frame
|
- 1 if this is a
config frame
- 0 otherwise
|
1 b
|
|
size
|
frame size, in bytes
|
30 b
|
|
duration
|
length of video, in milliseconds
|
2 B
|
|
data
|
the actual frame data
|
<size> B
|
|
stream type
|
- 0 if this is a
frame of audio
- 1 if this is a
frame of video
|
1 B
|
|
key frame
|
- 1 if this is a
key frame
- 0 otherwise
|
1 b
|
|
config frame
|
- 1 if this is a
config frame
- 0 otherwise
|
1 b
|
|
size
|
frame size, in bytes
|
30 b
|
|
duration
|
length of video, in milliseconds
|
2 B
|
Note: The key frame, config frame, and size fields are stored in one
32-bit
int with the key frame and config frame fields
stored in the first two bits.
Footer
|
Field
|
Value
|
Size
|
|
Descriptor
|
descriptor values
|
- 75 bytes if
recording to a stream
- 0 bytes if
recording to a file
|
Descriptor
|
Field
|
Value
|
Size
|
|
audio frames
|
number of audio frames
|
4 B
|
|
video frames
|
number of video frames
|
4 B
|
|
audio key frames
|
number of audio key frames
|
4 B
|
|
video key frames
|
number of video key frames
|
4 B
|
|
audio frame rates
|
number of audio frame rates (number of frame rate changes +
1)
|
4 B
|
|
video frame rates
|
number of video frame rates (number of frame rate changes +
1)
|
4 B
|
|
audio size
|
size of audio stream in bytes
|
4 B
|
|
video size
|
size of video stream in bytes
|
4 B
|
|
video frame rate
|
the initial video frame rate, in frames per second
|
4 B
|
|
video max frame size
|
size of largest video frame, in bytes
|
4 B
|
|
audio duration
|
length of audio stream, in milliseconds
|
4 B
|
|
video duration
|
length of video stream, in milliseconds
|
4 B
|
|
RESERVED
|
undefined
|
20 B
|
|
width
|
the width of the video, in pixels
|
2 B
|
|
height
|
the height of the video, in pixels
|
2 B
|
|
video codec
|
- 2 if this video
codec is mpeg4
- 5 if this video
codec is H.263
- 6 if this video
codec is H.264
|
2 B
|
|
audio codec
|
- 0 if this audio
codec is PCM
- 7 if this audio
codec is AMR
- 0xA if this
audio codec is AAC
|
1 B
|
Buffer and play streamed media
You can use the Multimedia API to create a custom class that extends
javax.microedition.media.protocol.DataSource to
customize how data is read from your application to the
BlackBerry® device media
player.
DataSource provides a
SourceStream implementation which uses
SourceStream.read() to transfer data.
-
Import the required classes and interfaces.
import java.lang.Thread;
import java.io.InputStream;
import java.io.OutputStream;
import javax.microedition.media.protocol.DataSource;
import javax.microedition.media.protocol.SourceStream;
import javax.microedition.io.ContentConnection;
import javax.microedition.io.file.FileConnection;
import net.rim.device.api.io.SharedInputStream;
-
Create a custom class that extends the abstract
javax.microedition.media.protocol.DataSource class.
public final class LimitedRateStreamingSource extends DataSource {
-
Declare instance fields that you will need for your
DataSource implementation. The following fields were
taken from the sample bufferedplaybackdemo project.
/** The stream connection over which media content is passed */
private ContentConnection _contentConnection;
/** An input stream shared between several readers */
private SharedInputStream _readAhead;
/** A stream to the buffered resource */
private LimitedRateSourceStream _feedToPlayer;
/** The MIME type of the remote media file */
private String _forcedContentType;
/** The thread which retrieves the remote media file */
private ConnectionThread _loaderThread;
/** The local save file into which the remote file is written */
private FileConnection _saveFile;
/** A stream for the local save file */
private OutputStream _saveStream;
-
Create a constructor for your custom class.
LimitedRateStreamingSource(String locator) {
super(locator);
}
-
Implement
javax.microedition.media.protocol.DataSource.connect().
This method is used to open a connection to the source described by the locator
and initiate communication. Please refer to the the sample bufferedplaybackdemo
project for additional details.
public void connect() throws IOException {
-
Implement
javax.microedition.media.protocol.DataSource.disconnect().
This method is used to close the connection to the source described by the
locator and free resources used to maintain the connection. Please refer to the
the sample bufferedplaybackdemo project for additional details.
public void disconnect() {
-
Implement
javax.microedition.media.protocol.DataSource.getContentType().
This method is used to retrieve a String that describes the content-type of the
media that the source is providing. Please refer to the the sample
bufferedplaybackdemo project for additional details.
public String getContentType() {
return _feedToPlayer.getContentDescriptor().getContentType();
}
-
Implement
javax.microedition.media.protocol.DataSource.getStreams().
This method is used to retrieve a collection of streams that this source
manages. Please refer to the the sample bufferedplaybackdemo project for
additional details.
public SourceStream[] getStreams() {
return new SourceStream[] { _feedToPlayer };
}
-
Implement
javax.microedition.media.protocol.DataSource.start().
This method is used to initiate data-transfer and must be called before data is
available for reading. Please refer to the the sample bufferedplaybackdemo
project for additional details.
public void start() throws IOException {
if (_saveStream != null) {
_loaderThread = new ConnectionThread();
_loaderThread.start();
}
}
-
Implement
javax.microedition.media.protocol.DataSource.stop().
This method is used to stop the data-transfer. Please refer to the the sample
bufferedplaybackdemo project for additional details.
public void stop() throws IOException {
// Set the boolean flag to stop the thread
_stop = true;
}
-
Create an class that implements
javax.microedition.media.protocol.SourceStream. In
this example, an inner class is used to provide a stream to the buffered media
resource. Please refer to the the sample bufferedplaybackdemo project for
additional details.
private final class LimitedRateSourceStream implements SourceStream {
-
Implement getSeekType() to return if media is seekable or not
during playback.
public int getSeekType() {
return SEEKABLE_TO_START;
}
-
Within this inner class, implement
javax.microedition.media.protocol.SourceStream.read().
This method is used to reads data from the input stream into an array of bytes.
Please refer to the the sample bufferedplaybackdemo project for additional
details.
public int read(byte[] bytes, int off, int len) throws IOException {
-
Within this inner class, you may also want to implement
seek(),
tell(), and
close(). Please refer to the the sample
bufferedplaybackdemo project for additional details.
-
Close off the inner class and create another inner class that
extends
java.lang.Thread. Use this when creating a thread to
download the remote file and write it to the local file. Please refer to the
the sample bufferedplaybackdemo project for additional details.
private final class ConnectionThread extends Thread {
Was this information helpful? Send us your comments.