initial support for reading OpenDML AVI files
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6256 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,609 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "OpenDMLParser.h"
|
||||
#include "avi.h"
|
||||
|
||||
#define TRACE_THIS 1
|
||||
#if TRACE_THIS
|
||||
#define TRACE printf
|
||||
#else
|
||||
#define TRACE(a...)
|
||||
#endif
|
||||
|
||||
struct movie_chunk
|
||||
{
|
||||
movie_chunk * next;
|
||||
int64 start;
|
||||
uint32 size;
|
||||
};
|
||||
|
||||
OpenDMLParser::OpenDMLParser()
|
||||
: fSource(0),
|
||||
fSize(0),
|
||||
fStandardIndexStart(0),
|
||||
fStandardIndexSize(0),
|
||||
fStreamCount(0),
|
||||
fMovieChunkCount(0),
|
||||
fAviMainHeaderValid(false),
|
||||
fOdmlExtendedHeaderValid(false),
|
||||
fStreams(0),
|
||||
fCurrentStream(0)
|
||||
{
|
||||
}
|
||||
|
||||
OpenDMLParser::~OpenDMLParser()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
OpenDMLParser::StreamCount()
|
||||
{
|
||||
return fStreamCount;
|
||||
}
|
||||
|
||||
const stream_info *
|
||||
OpenDMLParser::StreamInfo(int index)
|
||||
{
|
||||
if (index < 0 || index >= fStreamCount)
|
||||
return 0;
|
||||
|
||||
stream_info *info = fStreams;
|
||||
while (index--)
|
||||
info = info->next;
|
||||
return info;
|
||||
}
|
||||
|
||||
int64
|
||||
OpenDMLParser::StandardIndexStart()
|
||||
{
|
||||
return fStandardIndexStart;
|
||||
}
|
||||
|
||||
uint32
|
||||
OpenDMLParser::StandardIndexSize()
|
||||
{
|
||||
return fStandardIndexSize;
|
||||
}
|
||||
|
||||
const avi_main_header *
|
||||
OpenDMLParser::AviMainHeader()
|
||||
{
|
||||
return fAviMainHeaderValid ? &fAviMainHeader : 0;
|
||||
}
|
||||
|
||||
const odml_extended_header *
|
||||
OpenDMLParser::OdmlExtendedHeader()
|
||||
{
|
||||
return fOdmlExtendedHeaderValid ? &fOdmlExtendedHeader : 0;
|
||||
}
|
||||
|
||||
void
|
||||
OpenDMLParser::CreateNewStreamInfo()
|
||||
{
|
||||
stream_info *info = new stream_info;
|
||||
info->next = 0;
|
||||
info->is_audio = false;
|
||||
info->is_video = false;
|
||||
info->stream_header_valid = false;
|
||||
info->audio_format_valid = false;
|
||||
info->video_format_valid = false;
|
||||
info->odml_index_start = 0;
|
||||
info->odml_index_size = 0;
|
||||
|
||||
// append the new stream_info to the fStreams list and point fCurrentStream to it
|
||||
if (fStreams) {
|
||||
stream_info *cur = fStreams;
|
||||
while (cur->next)
|
||||
cur = cur->next;
|
||||
cur->next = info;
|
||||
} else {
|
||||
fStreams = info;
|
||||
}
|
||||
fCurrentStream = info;
|
||||
}
|
||||
|
||||
void
|
||||
OpenDMLParser::Parse(BPositionIO *source)
|
||||
{
|
||||
TRACE("OpenDMLParser::Parse\n");
|
||||
|
||||
fSource = source;
|
||||
fSize = source->Seek(0, SEEK_END);
|
||||
|
||||
if (fSize < 32) {
|
||||
TRACE("OpenDMLParser::Parse: file to small\n");
|
||||
return;
|
||||
}
|
||||
|
||||
uint64 pos = 0;
|
||||
int riff_chunk_number = 0;
|
||||
while (pos < (uint64)fSize) {
|
||||
uint32 temp;
|
||||
uint32 fourcc;
|
||||
uint32 size;
|
||||
|
||||
if (sizeof(temp) != fSource->ReadAt(pos, &temp, sizeof(temp))) {
|
||||
TRACE("OpenDMLParser::Parse: read error at pos %llu\n", pos);
|
||||
goto err;
|
||||
}
|
||||
pos += 4;
|
||||
fourcc = AVI_UINT32(temp);
|
||||
|
||||
if (sizeof(temp) != fSource->ReadAt(pos, &temp, sizeof(temp))) {
|
||||
TRACE("OpenDMLParser::Parse: read error at pos %llu\n", pos);
|
||||
goto err;
|
||||
}
|
||||
pos += 4;
|
||||
size = AVI_UINT32(temp);
|
||||
|
||||
if (fourcc == FOURCC('J','U','N','K')) {
|
||||
TRACE("OpenDMLParser::Parse: JUNK chunk ignored, size: %lu bytes\n", size);
|
||||
goto cont;
|
||||
}
|
||||
|
||||
if (fourcc != FOURCC('R','I','F','F')) {
|
||||
if (riff_chunk_number == 0) {
|
||||
TRACE("OpenDMLParser::Parse: not a RIFF file\n");
|
||||
} else {
|
||||
TRACE("OpenDMLParser::Parse: unknown chunk '"FOURCC_FORMAT"' (expected 'RIFF'), size = %lu ignored\n", FOURCC_PARAM(fourcc), size);
|
||||
goto cont;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("OpenDMLParser::Parse: RIFF chunk %d size: %lu bytes\n", riff_chunk_number, size);
|
||||
|
||||
if (sizeof(temp) != fSource->ReadAt(pos, &temp, sizeof(temp))) {
|
||||
TRACE("OpenDMLParser::Parse: read error at pos %llu\n", pos);
|
||||
goto err;
|
||||
}
|
||||
fourcc = AVI_UINT32(temp);
|
||||
|
||||
if (riff_chunk_number == 0 && fourcc != FOURCC('A','V','I',' ')) {
|
||||
TRACE("OpenDMLParser::Parse: not a AVI file\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (fourcc != FOURCC('A','V','I',' ') && fourcc != FOURCC('A','V','I','X')) {
|
||||
TRACE("OpenDMLParser::Parse: unknown chunk '"FOURCC_FORMAT"' , size = %lu ignored\n", FOURCC_PARAM(fourcc), size);
|
||||
goto cont;
|
||||
}
|
||||
|
||||
ParseChunk_AVI(riff_chunk_number, pos + 4, size - 4);
|
||||
|
||||
cont:
|
||||
pos += (size) + (size & 1);
|
||||
riff_chunk_number++;
|
||||
}
|
||||
return;
|
||||
|
||||
err:
|
||||
fStreamCount = 0;
|
||||
}
|
||||
|
||||
void
|
||||
OpenDMLParser::ParseChunk_AVI(int number, uint64 start, uint32 size)
|
||||
{
|
||||
TRACE("OpenDMLParser::ParseChunk_AVI\n");
|
||||
uint64 pos = start;
|
||||
uint64 end = start + size;
|
||||
|
||||
while (pos < end) {
|
||||
uint32 temp;
|
||||
uint32 Chunkfcc;
|
||||
uint32 Chunksize;
|
||||
|
||||
if (sizeof(temp) != fSource->ReadAt(pos, &temp, sizeof(temp))) {
|
||||
TRACE("OpenDMLParser::ParseChunk_AVI: read error at pos %llu\n",pos);
|
||||
return;
|
||||
}
|
||||
pos += 4;
|
||||
Chunkfcc = AVI_UINT32(temp);
|
||||
|
||||
if (sizeof(temp) != fSource->ReadAt(pos, &temp, sizeof(temp))) {
|
||||
TRACE("OpenDMLParser::ParseChunk_AVI: read error at pos %llu\n",pos);
|
||||
return;
|
||||
}
|
||||
pos += 4;
|
||||
Chunksize = AVI_UINT32(temp);
|
||||
|
||||
TRACE("OpenDMLParser::ParseChunk_AVI: chunk '"FOURCC_FORMAT"', size = %lu\n", FOURCC_PARAM(Chunkfcc), Chunksize);
|
||||
|
||||
if (Chunkfcc == FOURCC('J','U','N','K'))
|
||||
goto cont;
|
||||
else if (Chunkfcc == FOURCC('L','I','S','T'))
|
||||
ParseChunk_LIST(pos, Chunksize);
|
||||
else if (Chunkfcc == FOURCC('i','d','x','1')) {
|
||||
ParseChunk_idx1(pos, Chunksize);
|
||||
} else {
|
||||
TRACE("OpenDMLParser::ParseChunk_AVI: unknown chunk ignored\n");
|
||||
}
|
||||
|
||||
cont:
|
||||
pos += (Chunksize) + (Chunksize & 1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OpenDMLParser::ParseChunk_LIST(uint64 start, uint32 size)
|
||||
{
|
||||
TRACE("OpenDMLParser::ParseChunk_LIST\n");
|
||||
uint32 temp;
|
||||
uint32 fourcc;
|
||||
|
||||
if (sizeof(temp) != fSource->ReadAt(start, &temp, sizeof(temp))) {
|
||||
TRACE("OpenDMLParser::ParseChunk_LIST: read error at pos %llu\n", start);
|
||||
return;
|
||||
}
|
||||
fourcc = AVI_UINT32(temp);
|
||||
|
||||
TRACE("OpenDMLParser::ParseChunk_LIST: type '"FOURCC_FORMAT"'\n", FOURCC_PARAM(fourcc));
|
||||
|
||||
if (fourcc == FOURCC('m','o','v','i'))
|
||||
ParseList_movi(start + 4, size - 4);
|
||||
else if (fourcc == FOURCC('r','e','c',' '))
|
||||
ParseList_movi(start + 4, size - 4); //XXX parse rec simliar to movi???
|
||||
else if (fourcc == FOURCC('h','d','r','l'))
|
||||
ParseList_generic(start + 4, size - 4);
|
||||
else if (fourcc == FOURCC('s','t','r','l'))
|
||||
ParseList_strl(start + 4, size - 4);
|
||||
else if (fourcc == FOURCC('o','d','m','l'))
|
||||
ParseList_generic(start + 4, size - 4);
|
||||
else
|
||||
TRACE("OpenDMLParser::ParseChunk_LIST: unknown list type ignored\n");
|
||||
}
|
||||
|
||||
void
|
||||
OpenDMLParser::ParseChunk_idx1(uint64 start, uint32 size)
|
||||
{
|
||||
TRACE("OpenDMLParser::ParseChunk_idx1\n");
|
||||
|
||||
if (fStandardIndexSize != 0) {
|
||||
TRACE("OpenDMLParser::ParseChunk_idx1: found a second chunk\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fStandardIndexStart = start;
|
||||
fStandardIndexSize = size;
|
||||
}
|
||||
|
||||
void
|
||||
OpenDMLParser::ParseChunk_avih(uint64 start, uint32 size)
|
||||
{
|
||||
TRACE("OpenDMLParser::ParseChunk_avih\n");
|
||||
|
||||
if (fAviMainHeaderValid) {
|
||||
TRACE("OpenDMLParser::ParseChunk_avih: found a second chunk\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (size < sizeof(fAviMainHeader)) {
|
||||
TRACE("OpenDMLParser::ParseChunk_avih: warning, avi header chunk too small\n");
|
||||
}
|
||||
|
||||
memset(&fAviMainHeader, 0, sizeof(fAviMainHeader));
|
||||
size = min_c(size, sizeof(fAviMainHeader));
|
||||
if ((ssize_t)size != fSource->ReadAt(start, &fAviMainHeader, size)) {
|
||||
TRACE("OpenDMLParser::ParseChunk_avih: read error at pos %llu\n", start);
|
||||
return;
|
||||
}
|
||||
|
||||
#if B_HOST_IS_BENDIAN
|
||||
B_SWAP_INT32(&fAviMainHeader.micro_sec_per_frame);
|
||||
B_SWAP_INT32(&fAviMainHeader.max_bytes_per_sec);
|
||||
B_SWAP_INT32(&fAviMainHeader.padding_granularity);
|
||||
B_SWAP_INT32(&fAviMainHeader.flags);
|
||||
B_SWAP_INT32(&fAviMainHeader.total_frames);
|
||||
B_SWAP_INT32(&fAviMainHeader.initial_frames);
|
||||
B_SWAP_INT32(&fAviMainHeader.streams);
|
||||
B_SWAP_INT32(&fAviMainHeader.suggested_buffer_size);
|
||||
B_SWAP_INT32(&fAviMainHeader.width);
|
||||
B_SWAP_INT32(&fAviMainHeader.height);
|
||||
#endif
|
||||
|
||||
fAviMainHeaderValid = true;
|
||||
|
||||
TRACE("fAviMainHeader:\n");
|
||||
TRACE("micro_sec_per_frame = %lu\n", fAviMainHeader.micro_sec_per_frame);
|
||||
TRACE("max_bytes_per_sec = %lu\n", fAviMainHeader.max_bytes_per_sec);
|
||||
TRACE("padding_granularity = %lu\n", fAviMainHeader.padding_granularity);
|
||||
TRACE("flags = 0x%lx\n", fAviMainHeader.flags);
|
||||
TRACE("total_frames = %lu\n", fAviMainHeader.total_frames);
|
||||
TRACE("initial_frames = %lu\n", fAviMainHeader.initial_frames);
|
||||
TRACE("streams = %lu\n", fAviMainHeader.streams);
|
||||
TRACE("suggested_buffer_size = %lu\n", fAviMainHeader.suggested_buffer_size);
|
||||
TRACE("width = %lu\n", fAviMainHeader.width);
|
||||
TRACE("height = %lu\n", fAviMainHeader.height);
|
||||
}
|
||||
|
||||
void
|
||||
OpenDMLParser::ParseChunk_strh(uint64 start, uint32 size)
|
||||
{
|
||||
TRACE("OpenDMLParser::ParseChunk_strh\n");
|
||||
|
||||
if (fCurrentStream == 0) {
|
||||
TRACE("OpenDMLParser::ParseChunk_strh: error, no Stream info\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (fCurrentStream->stream_header_valid) {
|
||||
TRACE("OpenDMLParser::ParseChunk_strh: error, already have stream header\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (size < sizeof(fCurrentStream->stream_header)) {
|
||||
TRACE("OpenDMLParser::ParseChunk_strh: warning, avi stream header chunk too small\n");
|
||||
}
|
||||
|
||||
memset(&fCurrentStream->stream_header, 0, sizeof(fCurrentStream->stream_header));
|
||||
|
||||
size = min_c(size, sizeof(fCurrentStream->stream_header));
|
||||
if ((ssize_t)size != fSource->ReadAt(start, &fCurrentStream->stream_header, size)) {
|
||||
TRACE("OpenDMLParser::ParseChunk_strh: read error at pos %llu\n", start);
|
||||
return;
|
||||
}
|
||||
|
||||
#if B_HOST_IS_BENDIAN
|
||||
B_SWAP_INT32(&fCurrentStream->stream_header.fourcc_type);
|
||||
B_SWAP_INT32(&fCurrentStream->stream_header.fourcc_handler);
|
||||
B_SWAP_INT32(&fCurrentStream->stream_header.flags);
|
||||
B_SWAP_INT16(&fCurrentStream->stream_header.priority);
|
||||
B_SWAP_INT16(&fCurrentStream->stream_header.language);
|
||||
B_SWAP_INT32(&fCurrentStream->stream_header.initial_frames);
|
||||
B_SWAP_INT32(&fCurrentStream->stream_header.scale);
|
||||
B_SWAP_INT32(&fCurrentStream->stream_header.rate);
|
||||
B_SWAP_INT32(&fCurrentStream->stream_header.start);
|
||||
B_SWAP_INT32(&fCurrentStream->stream_header.length);
|
||||
B_SWAP_INT32(&fCurrentStream->stream_header.suggested_buffer_size);
|
||||
B_SWAP_INT32(&fCurrentStream->stream_header.quality);
|
||||
B_SWAP_INT32(&fCurrentStream->stream_header.sample_size);
|
||||
B_SWAP_INT16(&fCurrentStream->stream_header.rect_left);
|
||||
B_SWAP_INT16(&fCurrentStream->stream_header.rect_top);
|
||||
B_SWAP_INT16(&fCurrentStream->stream_header.rect_right);
|
||||
B_SWAP_INT16(&fCurrentStream->stream_header.rect_bottom);
|
||||
#endif
|
||||
|
||||
fCurrentStream->stream_header_valid = true;
|
||||
fCurrentStream->is_audio = fCurrentStream->stream_header.fourcc_type == FOURCC('a','u','d','s');
|
||||
fCurrentStream->is_video = fCurrentStream->stream_header.fourcc_type == FOURCC('v','i','d','s');
|
||||
|
||||
TRACE("stream_header, Stream %d, is_audio %d, is_video %d:\n", fStreamCount - 1, fCurrentStream->is_audio, fCurrentStream->is_video);
|
||||
TRACE("fourcc_type = '"FOURCC_FORMAT"'\n",FOURCC_PARAM(fCurrentStream->stream_header.fourcc_type));
|
||||
TRACE("fourcc_handler = '"FOURCC_FORMAT"'\n",FOURCC_PARAM(fCurrentStream->stream_header.fourcc_handler));
|
||||
TRACE("flags = 0x%lx\n", fCurrentStream->stream_header.flags);
|
||||
TRACE("priority = %u\n", fCurrentStream->stream_header.priority);
|
||||
TRACE("language = %u\n", fCurrentStream->stream_header.language);
|
||||
TRACE("initial_frames = %lu\n", fCurrentStream->stream_header.initial_frames);
|
||||
TRACE("scale = %lu\n", fCurrentStream->stream_header.scale);
|
||||
TRACE("rate = %lu\n", fCurrentStream->stream_header.rate);
|
||||
TRACE("frames/sec = %.3f\n", fCurrentStream->stream_header.rate / (float)fCurrentStream->stream_header.scale);
|
||||
TRACE("start = %lu\n", fCurrentStream->stream_header.start);
|
||||
TRACE("length = %lu\n", fCurrentStream->stream_header.length);
|
||||
TRACE("suggested_buffer_size = %lu\n", fCurrentStream->stream_header.suggested_buffer_size);
|
||||
TRACE("quality = %lu\n", fCurrentStream->stream_header.quality);
|
||||
TRACE("sample_size = %lu\n", fCurrentStream->stream_header.sample_size);
|
||||
TRACE("rect_left = %d\n", fCurrentStream->stream_header.rect_left);
|
||||
TRACE("rect_top = %d\n", fCurrentStream->stream_header.rect_top);
|
||||
TRACE("rect_right = %d\n", fCurrentStream->stream_header.rect_right );
|
||||
TRACE("rect_bottom = %d\n", fCurrentStream->stream_header.rect_bottom);
|
||||
}
|
||||
|
||||
void
|
||||
OpenDMLParser::ParseChunk_strf(uint64 start, uint32 size)
|
||||
{
|
||||
TRACE("OpenDMLParser::ParseChunk_strf\n");
|
||||
|
||||
if (fCurrentStream == 0) {
|
||||
TRACE("OpenDMLParser::ParseChunk_strf: error, no Stream info\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (fCurrentStream->is_audio) {
|
||||
|
||||
if (fCurrentStream->audio_format_valid) {
|
||||
TRACE("OpenDMLParser::ParseChunk_strf: error, already have audio format header\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// if (size < sizeof(fCurrentStream->audio_format)) {
|
||||
// TRACE("OpenDMLParser::ParseChunk_strf: warning, avi audio header chunk too small\n");
|
||||
// }
|
||||
|
||||
memset(&fCurrentStream->audio_format, 0, sizeof(fCurrentStream->audio_format));
|
||||
|
||||
size = min_c(size, sizeof(fCurrentStream->audio_format));
|
||||
if ((ssize_t)size != fSource->ReadAt(start, &fCurrentStream->audio_format, size)) {
|
||||
TRACE("OpenDMLParser::ParseChunk_strf: read error at pos %llu\n", start);
|
||||
return;
|
||||
}
|
||||
|
||||
#if B_HOST_IS_BENDIAN
|
||||
B_SWAP_INT16(&fCurrentStream->audio_format.format_tag);
|
||||
B_SWAP_INT16(&fCurrentStream->audio_format.channels);
|
||||
B_SWAP_INT32(&fCurrentStream->audio_format.frames_per_sec);
|
||||
B_SWAP_INT32(&fCurrentStream->audio_format.avg_bytes_per_sec);
|
||||
B_SWAP_INT32(&fCurrentStream->audio_format.block_align);
|
||||
B_SWAP_INT32(&fCurrentStream->audio_format.bits_per_sample);
|
||||
B_SWAP_INT32(&fCurrentStream->audio_format.extra_size);
|
||||
#endif
|
||||
|
||||
fCurrentStream->audio_format_valid = true;
|
||||
|
||||
TRACE("audio_format:\n");
|
||||
TRACE("format_tag = 0x%x\n", fCurrentStream->audio_format.format_tag);
|
||||
TRACE("channels = %u\n", fCurrentStream->audio_format.channels);
|
||||
TRACE("frames_per_sec = %lu\n", fCurrentStream->audio_format.frames_per_sec);
|
||||
TRACE("avg_bytes_per_sec = %lu\n", fCurrentStream->audio_format.avg_bytes_per_sec);
|
||||
TRACE("block_align = %u\n", fCurrentStream->audio_format.block_align);
|
||||
TRACE("bits_per_sample = %u\n", fCurrentStream->audio_format.bits_per_sample);
|
||||
TRACE("extra_size = %u\n", fCurrentStream->audio_format.extra_size);
|
||||
|
||||
// XXX read extra data
|
||||
|
||||
} else if (fCurrentStream->is_video) {
|
||||
|
||||
if (fCurrentStream->video_format_valid) {
|
||||
TRACE("OpenDMLParser::ParseChunk_strf: error, already have video format header\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// if (size < sizeof(fCurrentStream->video_format)) {
|
||||
// TRACE("OpenDMLParser::ParseChunk_strf: warning, avi video header chunk too small\n");
|
||||
// }
|
||||
|
||||
memset(&fCurrentStream->video_format, 0, sizeof(fCurrentStream->video_format));
|
||||
|
||||
size = min_c(size, sizeof(fCurrentStream->video_format));
|
||||
if ((ssize_t)size != fSource->ReadAt(start, &fCurrentStream->video_format, size)) {
|
||||
TRACE("OpenDMLParser::ParseChunk_strf: read error at pos %llu\n", start);
|
||||
return;
|
||||
}
|
||||
|
||||
#if B_HOST_IS_BENDIAN
|
||||
B_SWAP_INT32(&fCurrentStream->video_format.size);
|
||||
B_SWAP_INT32(&fCurrentStream->video_format.width);
|
||||
B_SWAP_INT32(&fCurrentStream->video_format.height);
|
||||
B_SWAP_INT16(&fCurrentStream->video_format.planes);
|
||||
B_SWAP_INT16(&fCurrentStream->video_format.bit_count);
|
||||
B_SWAP_INT32(&fCurrentStream->video_format.compression);
|
||||
B_SWAP_INT32(&fCurrentStream->video_format.image_size);
|
||||
B_SWAP_INT32(&fCurrentStream->video_format.x_pels_per_meter);
|
||||
B_SWAP_INT32(&fCurrentStream->video_format.y_pels_per_meter);
|
||||
B_SWAP_INT32(&fCurrentStream->video_format.clr_used);
|
||||
B_SWAP_INT32(&fCurrentStream->video_format.clr_important);
|
||||
#endif
|
||||
|
||||
fCurrentStream->video_format_valid = true;
|
||||
|
||||
TRACE("audio_format:\n");
|
||||
TRACE("size = %lu\n", fCurrentStream->video_format.size);
|
||||
TRACE("width = %lu\n", fCurrentStream->video_format.width);
|
||||
TRACE("height = %lu\n", fCurrentStream->video_format.height);
|
||||
TRACE("planes = %u\n", fCurrentStream->video_format.planes);
|
||||
TRACE("bit_count = %u\n", fCurrentStream->video_format.bit_count);
|
||||
TRACE("compression = 0x%08lx\n", fCurrentStream->video_format.compression);
|
||||
TRACE("image_size = %lu\n", fCurrentStream->video_format.image_size);
|
||||
TRACE("x_pels_per_meter = %lu\n", fCurrentStream->video_format.x_pels_per_meter);
|
||||
TRACE("y_pels_per_meter = %lu\n", fCurrentStream->video_format.y_pels_per_meter);
|
||||
TRACE("clr_used = %lu\n", fCurrentStream->video_format.clr_used);
|
||||
TRACE("clr_important = %lu\n", fCurrentStream->video_format.clr_important);
|
||||
|
||||
} else {
|
||||
TRACE("OpenDMLParser::ParseChunk_strf: error, unknown Stream type\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OpenDMLParser::ParseChunk_indx(uint64 start, uint32 size)
|
||||
{
|
||||
TRACE("OpenDMLParser::ParseChunk_indx\n");
|
||||
|
||||
if (fCurrentStream == 0) {
|
||||
TRACE("OpenDMLParser::ParseChunk_indx: error, no stream info\n");
|
||||
return;
|
||||
}
|
||||
// XXX
|
||||
fCurrentStream->odml_index_start = start;
|
||||
fCurrentStream->odml_index_size = size;
|
||||
}
|
||||
|
||||
void
|
||||
OpenDMLParser::ParseChunk_dmlh(uint64 start, uint32 size)
|
||||
{
|
||||
TRACE("OpenDMLParser::ParseChunk_dmlh\n");
|
||||
|
||||
if (fOdmlExtendedHeaderValid) {
|
||||
TRACE("OpenDMLParser::ParseChunk_dmlh: found a second chunk\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (size < sizeof(fOdmlExtendedHeader)) {
|
||||
TRACE("OpenDMLParser::ParseChunk_dmlh: warning, avi header chunk too small\n");
|
||||
}
|
||||
|
||||
memset(&fOdmlExtendedHeader, 0, sizeof(fOdmlExtendedHeader));
|
||||
size = min_c(size, sizeof(fOdmlExtendedHeader));
|
||||
if ((ssize_t)size != fSource->ReadAt(start, &fOdmlExtendedHeader, size)) {
|
||||
TRACE("OpenDMLParser::ParseChunk_dmlh: read error at pos %llu\n", start);
|
||||
return;
|
||||
}
|
||||
|
||||
#if B_HOST_IS_BENDIAN
|
||||
B_SWAP_INT32(&fOdmlExtendedHeader.total_frames);
|
||||
#endif
|
||||
|
||||
fOdmlExtendedHeaderValid = true;
|
||||
|
||||
TRACE("fOdmlExtendedHeader:\n");
|
||||
TRACE("total_frames = %ld\n", fOdmlExtendedHeader.total_frames);
|
||||
}
|
||||
|
||||
void
|
||||
OpenDMLParser::ParseList_strl(uint64 start, uint32 size)
|
||||
{
|
||||
TRACE("OpenDMLParser::ParseList_strl\n");
|
||||
|
||||
CreateNewStreamInfo();
|
||||
fStreamCount++;
|
||||
|
||||
ParseList_generic(start, size);
|
||||
}
|
||||
|
||||
void
|
||||
OpenDMLParser::ParseList_generic(uint64 start, uint32 size)
|
||||
{
|
||||
TRACE("OpenDMLParser::ParseList_generic\n");
|
||||
uint64 pos = start;
|
||||
uint64 end = start + size;
|
||||
|
||||
while (pos < end) {
|
||||
uint32 temp;
|
||||
uint32 Chunkfcc;
|
||||
uint32 Chunksize;
|
||||
|
||||
if (sizeof(temp) != fSource->ReadAt(pos, &temp, sizeof(temp))) {
|
||||
TRACE("OpenDMLParser::ParseList_generic: read error at pos %llu\n",pos);
|
||||
return;
|
||||
}
|
||||
pos += 4;
|
||||
Chunkfcc = AVI_UINT32(temp);
|
||||
|
||||
if (sizeof(temp) != fSource->ReadAt(pos, &temp, sizeof(temp))) {
|
||||
TRACE("OpenDMLParser::ParseList_generic: read error at pos %llu\n",pos);
|
||||
return;
|
||||
}
|
||||
pos += 4;
|
||||
Chunksize = AVI_UINT32(temp);
|
||||
|
||||
TRACE("OpenDMLParser::ParseList_generic: chunk '"FOURCC_FORMAT"', size = %ld\n", FOURCC_PARAM(Chunkfcc), Chunksize);
|
||||
|
||||
if (Chunkfcc == FOURCC('J','U','N','K'))
|
||||
goto cont;
|
||||
else if (Chunkfcc == FOURCC('a','v','i','h'))
|
||||
ParseChunk_avih(pos, Chunksize);
|
||||
else if (Chunkfcc == FOURCC('L','I','S','T'))
|
||||
ParseChunk_LIST(pos, Chunksize);
|
||||
else if (Chunkfcc == FOURCC('s','t','r','h'))
|
||||
ParseChunk_strh(pos, Chunksize);
|
||||
else if (Chunkfcc == FOURCC('s','t','r','f'))
|
||||
ParseChunk_strf(pos, Chunksize);
|
||||
else if (Chunkfcc == FOURCC('i','n','d','x'))
|
||||
ParseChunk_indx(pos, Chunksize);
|
||||
else if (Chunkfcc == FOURCC('d','m','l','h'))
|
||||
ParseChunk_dmlh(pos, Chunksize);
|
||||
else
|
||||
TRACE("OpenDMLParser::ParseList_generic: unknown chunk ignored\n");
|
||||
|
||||
cont:
|
||||
pos += (Chunksize) + (Chunksize & 1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OpenDMLParser::ParseList_movi(uint64 start, uint32 size)
|
||||
{
|
||||
TRACE("OpenDMLParser::ParseList_movi\n");
|
||||
|
||||
fMovieChunkCount++;
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user