Fixed handling of 0 byte large chunks.
Rewrote error checking during file parsing, parsing now aborts immediately after the first error. Disabled all TRACEing, added ERROR fprintf for real errors. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6991 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,12 +1,15 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "OpenDMLFile.h"
|
#include "OpenDMLFile.h"
|
||||||
|
|
||||||
#if 0
|
//#define TRACE_ODML_FILE
|
||||||
|
#ifdef TRACE_ODML_FILE
|
||||||
#define TRACE printf
|
#define TRACE printf
|
||||||
#else
|
#else
|
||||||
#define TRACE(a...)
|
#define TRACE(a...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define ERROR(a...) fprintf(stderr, a)
|
||||||
|
|
||||||
#define INDEX_CHUNK_SIZE 32768
|
#define INDEX_CHUNK_SIZE 32768
|
||||||
|
|
||||||
struct OpenDMLFile::stream_data
|
struct OpenDMLFile::stream_data
|
||||||
@@ -66,10 +69,13 @@ OpenDMLFile::SetTo(BPositionIO *source)
|
|||||||
delete fParser;
|
delete fParser;
|
||||||
fSource = source;
|
fSource = source;
|
||||||
fParser = new OpenDMLParser;
|
fParser = new OpenDMLParser;
|
||||||
fParser->Parse(source);
|
|
||||||
|
if (!fParser->Parse(source)) {
|
||||||
|
ERROR("OpenDMLFile::SetTo: warning, file parsing failed\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (!fParser->AviMainHeader()) {
|
if (!fParser->AviMainHeader()) {
|
||||||
TRACE("OpenDMLFile::SetTo: avi main header not found\n");
|
ERROR("OpenDMLFile::SetTo: avi main header not found\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +89,7 @@ OpenDMLFile::SetTo(BPositionIO *source)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found_odml_index) {
|
if (!found_odml_index) {
|
||||||
TRACE("OpenDMLFile::SetTo file has no standard avi index, and no OpenDML track index found\n");
|
ERROR("OpenDMLFile::SetTo file has no standard avi index, and no OpenDML track index found\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,6 +121,8 @@ OpenDMLFile::InitData()
|
|||||||
standard_index_entry_size = 16;
|
standard_index_entry_size = 16;
|
||||||
standard_index_entry_count = fParser->StandardIndexSize() / 16;
|
standard_index_entry_count = fParser->StandardIndexSize() / 16;
|
||||||
} else {
|
} else {
|
||||||
|
standard_index_start = -1;
|
||||||
|
standard_index_entry_size = 0;
|
||||||
standard_index_entry_count = 0;
|
standard_index_entry_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,12 +168,12 @@ OpenDMLFile::InitData()
|
|||||||
((odml_superindex_entry *)fStreamData[stream].odml_superindex)->duration = 0;
|
((odml_superindex_entry *)fStreamData[stream].odml_superindex)->duration = 0;
|
||||||
fStreamData[stream].has_odml_index = true;
|
fStreamData[stream].has_odml_index = true;
|
||||||
} else if (h.index_type == AVI_INDEX_IS_DATA){
|
} else if (h.index_type == AVI_INDEX_IS_DATA){
|
||||||
TRACE("OpenDMLFile::InitData: AVI_INDEX_IS_DATA not supported\n");
|
ERROR("OpenDMLFile::InitData: AVI_INDEX_IS_DATA not supported\n");
|
||||||
fStreamData[stream].odml_superindex = 0;
|
fStreamData[stream].odml_superindex = 0;
|
||||||
fStreamData[stream].odml_superindex_entry_count = 0;
|
fStreamData[stream].odml_superindex_entry_count = 0;
|
||||||
fStreamData[stream].odml_superindex_entry_pos = 0;
|
fStreamData[stream].odml_superindex_entry_pos = 0;
|
||||||
} else {
|
} else {
|
||||||
TRACE("OpenDMLFile::InitData: index type not recongnized\n");
|
ERROR("OpenDMLFile::InitData: index type not recongnized\n");
|
||||||
fStreamData[stream].odml_superindex = 0;
|
fStreamData[stream].odml_superindex = 0;
|
||||||
fStreamData[stream].odml_superindex_entry_count = 0;
|
fStreamData[stream].odml_superindex_entry_count = 0;
|
||||||
fStreamData[stream].odml_superindex_entry_pos = 0;
|
fStreamData[stream].odml_superindex_entry_pos = 0;
|
||||||
@@ -220,7 +228,7 @@ OpenDMLFile::OdmlReadIndexInfo(int stream_index)
|
|||||||
odml_chunk_index_header chunk_index_header;
|
odml_chunk_index_header chunk_index_header;
|
||||||
|
|
||||||
if (sizeof(chunk_index_header) != fSource->ReadAt(entry->start + 8, &chunk_index_header, sizeof(chunk_index_header))) {
|
if (sizeof(chunk_index_header) != fSource->ReadAt(entry->start + 8, &chunk_index_header, sizeof(chunk_index_header))) {
|
||||||
TRACE("read error\n");
|
ERROR("OpenDMLFile::OdmlReadIndexInfo: read error\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,7 +268,7 @@ OpenDMLFile::OdmlReadIndexChunk(int stream_index)
|
|||||||
stream_index, data->index_chunk_entry_count, size, start);
|
stream_index, data->index_chunk_entry_count, size, start);
|
||||||
|
|
||||||
if (size != fSource->ReadAt(start, data->index_chunk, size)) {
|
if (size != fSource->ReadAt(start, data->index_chunk, size)) {
|
||||||
TRACE("read error\n");
|
ERROR("OpenDMLFile::OdmlReadIndexChunk read error\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,7 +296,7 @@ OpenDMLFile::OdmlGetNextChunkInfo(int stream_index, int64 *start, uint32 *size,
|
|||||||
|
|
||||||
data->index_chunk_entry_pos++;
|
data->index_chunk_entry_pos++;
|
||||||
|
|
||||||
printf("OpenDMLFile::GetNextChunkInfo: stream %d: start %15Ld, size %6d%s\n",
|
printf("OpenDMLFile::GetNextChunkInfo: stream %d: start %15Ld, size %6ld%s\n",
|
||||||
stream_index, *start, *size, *keyframe ? ", keyframe" : "");
|
stream_index, *start, *size, *keyframe ? ", keyframe" : "");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -309,7 +317,7 @@ OpenDMLFile::AviGetNextChunkInfo(int stream_index, int64 *start, uint32 *size, b
|
|||||||
TRACE("OpenDMLFile::AviGetNextChunkInfo: stream %d, index_chunk_entry_count %d, size %d, start %lu\n",
|
TRACE("OpenDMLFile::AviGetNextChunkInfo: stream %d, index_chunk_entry_count %d, size %d, start %lu\n",
|
||||||
stream_index, data->index_chunk_entry_count, size, start);
|
stream_index, data->index_chunk_entry_count, size, start);
|
||||||
if (size != fSource->ReadAt(start, data->index_chunk, size)) {
|
if (size != fSource->ReadAt(start, data->index_chunk, size)) {
|
||||||
TRACE("OpenDMLFile::AviGetNextChunkInfo: read error\n");
|
ERROR("OpenDMLFile::AviGetNextChunkInfo: read error\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,15 @@
|
|||||||
#include "OpenDMLParser.h"
|
#include "OpenDMLParser.h"
|
||||||
#include "avi.h"
|
#include "avi.h"
|
||||||
|
|
||||||
#if 1
|
//#define TRACE_ODML_PARSER
|
||||||
|
#ifdef TRACE_ODML_PARSER
|
||||||
#define TRACE printf
|
#define TRACE printf
|
||||||
#else
|
#else
|
||||||
#define TRACE(a...)
|
#define TRACE(a...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define ERROR(a...) fprintf(stderr, a)
|
||||||
|
|
||||||
struct movie_chunk
|
struct movie_chunk
|
||||||
{
|
{
|
||||||
movie_chunk * next;
|
movie_chunk * next;
|
||||||
@@ -109,7 +112,9 @@ OpenDMLParser::CreateNewStreamInfo()
|
|||||||
fCurrentStream = info;
|
fCurrentStream = info;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
// this function returns false to indicate that an error occured,
|
||||||
|
// but the object is correctly initialized anyway.
|
||||||
|
bool
|
||||||
OpenDMLParser::Parse(BPositionIO *source)
|
OpenDMLParser::Parse(BPositionIO *source)
|
||||||
{
|
{
|
||||||
TRACE("OpenDMLParser::Parse\n");
|
TRACE("OpenDMLParser::Parse\n");
|
||||||
@@ -118,8 +123,8 @@ OpenDMLParser::Parse(BPositionIO *source)
|
|||||||
fSize = source->Seek(0, SEEK_END);
|
fSize = source->Seek(0, SEEK_END);
|
||||||
|
|
||||||
if (fSize < 32) {
|
if (fSize < 32) {
|
||||||
TRACE("OpenDMLParser::Parse: file to small\n");
|
ERROR("OpenDMLParser::Parse: file to small\n");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 pos = 0;
|
uint64 pos = 0;
|
||||||
@@ -130,49 +135,51 @@ OpenDMLParser::Parse(BPositionIO *source)
|
|||||||
uint32 size;
|
uint32 size;
|
||||||
|
|
||||||
if (sizeof(temp) != fSource->ReadAt(pos, &temp, sizeof(temp))) {
|
if (sizeof(temp) != fSource->ReadAt(pos, &temp, sizeof(temp))) {
|
||||||
TRACE("OpenDMLParser::Parse: read error at pos %llu\n", pos);
|
ERROR("OpenDMLParser::Parse: read error at pos %llu\n", pos);
|
||||||
goto err;
|
return false;
|
||||||
}
|
}
|
||||||
pos += 4;
|
pos += 4;
|
||||||
fourcc = AVI_UINT32(temp);
|
fourcc = AVI_UINT32(temp);
|
||||||
|
|
||||||
if (sizeof(temp) != fSource->ReadAt(pos, &temp, sizeof(temp))) {
|
if (sizeof(temp) != fSource->ReadAt(pos, &temp, sizeof(temp))) {
|
||||||
TRACE("OpenDMLParser::Parse: read error at pos %llu\n", pos);
|
ERROR("OpenDMLParser::Parse: read error at pos %llu\n", pos);
|
||||||
goto err;
|
return false;
|
||||||
}
|
}
|
||||||
pos += 4;
|
pos += 4;
|
||||||
size = AVI_UINT32(temp);
|
size = AVI_UINT32(temp);
|
||||||
|
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
TRACE("OpenDMLParser::Parse: Error: chunk of size 0 found\n");
|
ERROR("OpenDMLParser::Parse: Error: chunk of size 0 found\n");
|
||||||
goto err;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fourcc == FOURCC('J','U','N','K')) {
|
if (fourcc == FOURCC('J','U','N','K')) {
|
||||||
TRACE("OpenDMLParser::Parse: JUNK chunk ignored, size: %lu bytes\n", size);
|
ERROR("OpenDMLParser::Parse: JUNK chunk ignored, size: %lu bytes\n", size);
|
||||||
goto cont;
|
goto cont;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fourcc != FOURCC('R','I','F','F')) {
|
if (fourcc != FOURCC('R','I','F','F')) {
|
||||||
if (riff_chunk_number == 0) {
|
if (riff_chunk_number == 0) {
|
||||||
TRACE("OpenDMLParser::Parse: not a RIFF file\n");
|
ERROR("OpenDMLParser::Parse: not a RIFF file\n");
|
||||||
|
return false;
|
||||||
} else {
|
} else {
|
||||||
TRACE("OpenDMLParser::Parse: unknown chunk '"FOURCC_FORMAT"' (expected 'RIFF'), size = %lu ignored\n", FOURCC_PARAM(fourcc), size);
|
TRACE("OpenDMLParser::Parse: unknown chunk '"FOURCC_FORMAT"' (expected 'RIFF'), size = %lu ignored\n", FOURCC_PARAM(fourcc), size);
|
||||||
goto cont;
|
goto cont;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("OpenDMLParser::Parse: RIFF chunk %d size: %lu bytes\n", riff_chunk_number, size);
|
TRACE("OpenDMLParser::Parse: RIFF chunk %d size: %lu bytes\n", riff_chunk_number, size);
|
||||||
|
|
||||||
if (sizeof(temp) != fSource->ReadAt(pos, &temp, sizeof(temp))) {
|
if (sizeof(temp) != fSource->ReadAt(pos, &temp, sizeof(temp))) {
|
||||||
TRACE("OpenDMLParser::Parse: read error at pos %llu\n", pos);
|
ERROR("OpenDMLParser::Parse: read error at pos %llu\n", pos);
|
||||||
goto err;
|
return false;
|
||||||
}
|
}
|
||||||
fourcc = AVI_UINT32(temp);
|
fourcc = AVI_UINT32(temp);
|
||||||
|
|
||||||
if (riff_chunk_number == 0 && fourcc != FOURCC('A','V','I',' ')) {
|
if (riff_chunk_number == 0 && fourcc != FOURCC('A','V','I',' ')) {
|
||||||
TRACE("OpenDMLParser::Parse: not a AVI file\n");
|
ERROR("OpenDMLParser::Parse: not a AVI file\n");
|
||||||
goto err;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fourcc != FOURCC('A','V','I',' ') && fourcc != FOURCC('A','V','I','X')) {
|
if (fourcc != FOURCC('A','V','I',' ') && fourcc != FOURCC('A','V','I','X')) {
|
||||||
@@ -180,19 +187,17 @@ OpenDMLParser::Parse(BPositionIO *source)
|
|||||||
goto cont;
|
goto cont;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParseChunk_AVI(riff_chunk_number, pos + 4, size - 4);
|
if (!ParseChunk_AVI(riff_chunk_number, pos + 4, size - 4))
|
||||||
|
return false;
|
||||||
|
|
||||||
cont:
|
cont:
|
||||||
pos += (size) + (size & 1);
|
pos += (size) + (size & 1);
|
||||||
riff_chunk_number++;
|
riff_chunk_number++;
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
|
|
||||||
err:
|
|
||||||
fStreamCount = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
OpenDMLParser::ParseChunk_AVI(int number, uint64 start, uint32 size)
|
OpenDMLParser::ParseChunk_AVI(int number, uint64 start, uint32 size)
|
||||||
{
|
{
|
||||||
TRACE("OpenDMLParser::ParseChunk_AVI\n");
|
TRACE("OpenDMLParser::ParseChunk_AVI\n");
|
||||||
@@ -205,37 +210,45 @@ OpenDMLParser::ParseChunk_AVI(int number, uint64 start, uint32 size)
|
|||||||
uint32 Chunksize;
|
uint32 Chunksize;
|
||||||
|
|
||||||
if (sizeof(temp) != fSource->ReadAt(pos, &temp, sizeof(temp))) {
|
if (sizeof(temp) != fSource->ReadAt(pos, &temp, sizeof(temp))) {
|
||||||
TRACE("OpenDMLParser::ParseChunk_AVI: read error at pos %llu\n",pos);
|
ERROR("OpenDMLParser::ParseChunk_AVI: read error at pos %llu\n",pos);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
pos += 4;
|
pos += 4;
|
||||||
Chunkfcc = AVI_UINT32(temp);
|
Chunkfcc = AVI_UINT32(temp);
|
||||||
|
|
||||||
if (sizeof(temp) != fSource->ReadAt(pos, &temp, sizeof(temp))) {
|
if (sizeof(temp) != fSource->ReadAt(pos, &temp, sizeof(temp))) {
|
||||||
TRACE("OpenDMLParser::ParseChunk_AVI: read error at pos %llu\n",pos);
|
ERROR("OpenDMLParser::ParseChunk_AVI: read error at pos %llu\n",pos);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
pos += 4;
|
pos += 4;
|
||||||
Chunksize = AVI_UINT32(temp);
|
Chunksize = AVI_UINT32(temp);
|
||||||
|
|
||||||
TRACE("OpenDMLParser::ParseChunk_AVI: chunk '"FOURCC_FORMAT"', size = %lu\n", FOURCC_PARAM(Chunkfcc), Chunksize);
|
TRACE("OpenDMLParser::ParseChunk_AVI: chunk '"FOURCC_FORMAT"', size = %lu\n", FOURCC_PARAM(Chunkfcc), Chunksize);
|
||||||
|
|
||||||
if (Chunkfcc == FOURCC('J','U','N','K'))
|
if (Chunksize == 0) {
|
||||||
goto cont;
|
ERROR("OpenDMLParser::ParseChunk_AVI: Error: chunk of size 0 found\n");
|
||||||
else if (Chunkfcc == FOURCC('L','I','S','T'))
|
return false;
|
||||||
ParseChunk_LIST(pos, Chunksize);
|
}
|
||||||
else if (Chunkfcc == FOURCC('i','d','x','1')) {
|
|
||||||
ParseChunk_idx1(pos, Chunksize);
|
if (Chunkfcc == FOURCC('L','I','S','T')) {
|
||||||
|
if (!ParseChunk_LIST(pos, Chunksize))
|
||||||
|
return false;
|
||||||
|
} else if (Chunkfcc == FOURCC('i','d','x','1')) {
|
||||||
|
if (!ParseChunk_idx1(pos, Chunksize))
|
||||||
|
return false;
|
||||||
|
} else if (Chunkfcc == FOURCC('J','U','N','K')) {
|
||||||
|
; // do nothing
|
||||||
} else {
|
} else {
|
||||||
TRACE("OpenDMLParser::ParseChunk_AVI: unknown chunk ignored\n");
|
TRACE("OpenDMLParser::ParseChunk_AVI: unknown chunk ignored\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
cont:
|
|
||||||
pos += (Chunksize) + (Chunksize & 1);
|
pos += (Chunksize) + (Chunksize & 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
OpenDMLParser::ParseChunk_LIST(uint64 start, uint32 size)
|
OpenDMLParser::ParseChunk_LIST(uint64 start, uint32 size)
|
||||||
{
|
{
|
||||||
TRACE("OpenDMLParser::ParseChunk_LIST\n");
|
TRACE("OpenDMLParser::ParseChunk_LIST\n");
|
||||||
@@ -243,49 +256,59 @@ OpenDMLParser::ParseChunk_LIST(uint64 start, uint32 size)
|
|||||||
uint32 fourcc;
|
uint32 fourcc;
|
||||||
|
|
||||||
if (sizeof(temp) != fSource->ReadAt(start, &temp, sizeof(temp))) {
|
if (sizeof(temp) != fSource->ReadAt(start, &temp, sizeof(temp))) {
|
||||||
TRACE("OpenDMLParser::ParseChunk_LIST: read error at pos %llu\n", start);
|
ERROR("OpenDMLParser::ParseChunk_LIST: read error at pos %llu\n", start);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
fourcc = AVI_UINT32(temp);
|
fourcc = AVI_UINT32(temp);
|
||||||
|
|
||||||
TRACE("OpenDMLParser::ParseChunk_LIST: type '"FOURCC_FORMAT"'\n", FOURCC_PARAM(fourcc));
|
TRACE("OpenDMLParser::ParseChunk_LIST: type '"FOURCC_FORMAT"'\n", FOURCC_PARAM(fourcc));
|
||||||
|
|
||||||
if (fourcc == FOURCC('m','o','v','i'))
|
if (fourcc == FOURCC('m','o','v','i')) {
|
||||||
ParseList_movi(start + 4, size - 4);
|
if (!ParseList_movi(start + 4, size - 4))
|
||||||
else if (fourcc == FOURCC('r','e','c',' '))
|
return false;
|
||||||
ParseList_movi(start + 4, size - 4); //XXX parse rec simliar to movi???
|
} else if (fourcc == FOURCC('r','e','c',' ')) {
|
||||||
else if (fourcc == FOURCC('h','d','r','l'))
|
if (!ParseList_movi(start + 4, size - 4)) //XXX parse rec simliar to movi???
|
||||||
ParseList_generic(start + 4, size - 4);
|
return false;
|
||||||
else if (fourcc == FOURCC('s','t','r','l'))
|
} else if (fourcc == FOURCC('h','d','r','l')) {
|
||||||
ParseList_strl(start + 4, size - 4);
|
if (!ParseList_generic(start + 4, size - 4))
|
||||||
else if (fourcc == FOURCC('o','d','m','l'))
|
return false;
|
||||||
ParseList_generic(start + 4, size - 4);
|
} else if (fourcc == FOURCC('s','t','r','l')) {
|
||||||
else
|
if (!ParseList_strl(start + 4, size - 4))
|
||||||
|
return false;
|
||||||
|
} else if (fourcc == FOURCC('o','d','m','l')) {
|
||||||
|
if (!ParseList_generic(start + 4, size - 4))
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
TRACE("OpenDMLParser::ParseChunk_LIST: unknown list type ignored\n");
|
TRACE("OpenDMLParser::ParseChunk_LIST: unknown list type ignored\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
OpenDMLParser::ParseChunk_idx1(uint64 start, uint32 size)
|
OpenDMLParser::ParseChunk_idx1(uint64 start, uint32 size)
|
||||||
{
|
{
|
||||||
TRACE("OpenDMLParser::ParseChunk_idx1\n");
|
TRACE("OpenDMLParser::ParseChunk_idx1\n");
|
||||||
|
|
||||||
if (fStandardIndexSize != 0) {
|
if (fStandardIndexSize != 0) {
|
||||||
TRACE("OpenDMLParser::ParseChunk_idx1: found a second chunk\n");
|
TRACE("OpenDMLParser::ParseChunk_idx1: found a second chunk\n");
|
||||||
return;
|
return true; // just ignore, no error
|
||||||
}
|
}
|
||||||
|
|
||||||
fStandardIndexStart = start;
|
fStandardIndexStart = start;
|
||||||
fStandardIndexSize = size;
|
fStandardIndexSize = size;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
OpenDMLParser::ParseChunk_avih(uint64 start, uint32 size)
|
OpenDMLParser::ParseChunk_avih(uint64 start, uint32 size)
|
||||||
{
|
{
|
||||||
TRACE("OpenDMLParser::ParseChunk_avih\n");
|
TRACE("OpenDMLParser::ParseChunk_avih\n");
|
||||||
|
|
||||||
if (fAviMainHeaderValid) {
|
if (fAviMainHeaderValid) {
|
||||||
TRACE("OpenDMLParser::ParseChunk_avih: found a second chunk\n");
|
TRACE("OpenDMLParser::ParseChunk_avih: found a second chunk\n");
|
||||||
return;
|
return true; // just ignore, no error
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size < sizeof(fAviMainHeader)) {
|
if (size < sizeof(fAviMainHeader)) {
|
||||||
@@ -295,8 +318,8 @@ OpenDMLParser::ParseChunk_avih(uint64 start, uint32 size)
|
|||||||
memset(&fAviMainHeader, 0, sizeof(fAviMainHeader));
|
memset(&fAviMainHeader, 0, sizeof(fAviMainHeader));
|
||||||
size = min_c(size, sizeof(fAviMainHeader));
|
size = min_c(size, sizeof(fAviMainHeader));
|
||||||
if ((ssize_t)size != fSource->ReadAt(start, &fAviMainHeader, size)) {
|
if ((ssize_t)size != fSource->ReadAt(start, &fAviMainHeader, size)) {
|
||||||
TRACE("OpenDMLParser::ParseChunk_avih: read error at pos %llu\n", start);
|
ERROR("OpenDMLParser::ParseChunk_avih: read error at pos %llu\n", start);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if B_HOST_IS_BENDIAN
|
#if B_HOST_IS_BENDIAN
|
||||||
@@ -325,21 +348,23 @@ OpenDMLParser::ParseChunk_avih(uint64 start, uint32 size)
|
|||||||
TRACE("suggested_buffer_size = %lu\n", fAviMainHeader.suggested_buffer_size);
|
TRACE("suggested_buffer_size = %lu\n", fAviMainHeader.suggested_buffer_size);
|
||||||
TRACE("width = %lu\n", fAviMainHeader.width);
|
TRACE("width = %lu\n", fAviMainHeader.width);
|
||||||
TRACE("height = %lu\n", fAviMainHeader.height);
|
TRACE("height = %lu\n", fAviMainHeader.height);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
OpenDMLParser::ParseChunk_strh(uint64 start, uint32 size)
|
OpenDMLParser::ParseChunk_strh(uint64 start, uint32 size)
|
||||||
{
|
{
|
||||||
TRACE("OpenDMLParser::ParseChunk_strh\n");
|
TRACE("OpenDMLParser::ParseChunk_strh\n");
|
||||||
|
|
||||||
if (fCurrentStream == 0) {
|
if (fCurrentStream == 0) {
|
||||||
TRACE("OpenDMLParser::ParseChunk_strh: error, no Stream info\n");
|
ERROR("OpenDMLParser::ParseChunk_strh: error, no Stream info\n");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fCurrentStream->stream_header_valid) {
|
if (fCurrentStream->stream_header_valid) {
|
||||||
TRACE("OpenDMLParser::ParseChunk_strh: error, already have stream header\n");
|
TRACE("OpenDMLParser::ParseChunk_strh: error, already have stream header\n");
|
||||||
return;
|
return true; // just ignore, no error
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size < sizeof(fCurrentStream->stream_header)) {
|
if (size < sizeof(fCurrentStream->stream_header)) {
|
||||||
@@ -350,8 +375,8 @@ OpenDMLParser::ParseChunk_strh(uint64 start, uint32 size)
|
|||||||
|
|
||||||
size = min_c(size, sizeof(fCurrentStream->stream_header));
|
size = min_c(size, sizeof(fCurrentStream->stream_header));
|
||||||
if ((ssize_t)size != fSource->ReadAt(start, &fCurrentStream->stream_header, size)) {
|
if ((ssize_t)size != fSource->ReadAt(start, &fCurrentStream->stream_header, size)) {
|
||||||
TRACE("OpenDMLParser::ParseChunk_strh: read error at pos %llu\n", start);
|
ERROR("OpenDMLParser::ParseChunk_strh: read error at pos %llu\n", start);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if B_HOST_IS_BENDIAN
|
#if B_HOST_IS_BENDIAN
|
||||||
@@ -397,23 +422,25 @@ OpenDMLParser::ParseChunk_strh(uint64 start, uint32 size)
|
|||||||
TRACE("rect_top = %d\n", fCurrentStream->stream_header.rect_top);
|
TRACE("rect_top = %d\n", fCurrentStream->stream_header.rect_top);
|
||||||
TRACE("rect_right = %d\n", fCurrentStream->stream_header.rect_right );
|
TRACE("rect_right = %d\n", fCurrentStream->stream_header.rect_right );
|
||||||
TRACE("rect_bottom = %d\n", fCurrentStream->stream_header.rect_bottom);
|
TRACE("rect_bottom = %d\n", fCurrentStream->stream_header.rect_bottom);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
OpenDMLParser::ParseChunk_strf(uint64 start, uint32 size)
|
OpenDMLParser::ParseChunk_strf(uint64 start, uint32 size)
|
||||||
{
|
{
|
||||||
TRACE("OpenDMLParser::ParseChunk_strf, size %lu\n", size);
|
TRACE("OpenDMLParser::ParseChunk_strf, size %lu\n", size);
|
||||||
|
|
||||||
if (fCurrentStream == 0) {
|
if (fCurrentStream == 0) {
|
||||||
TRACE("OpenDMLParser::ParseChunk_strf: error, no Stream info\n");
|
ERROR("OpenDMLParser::ParseChunk_strf: error, no Stream info\n");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fCurrentStream->is_audio) {
|
if (fCurrentStream->is_audio) {
|
||||||
|
|
||||||
if (fCurrentStream->audio_format) {
|
if (fCurrentStream->audio_format) {
|
||||||
TRACE("OpenDMLParser::ParseChunk_strf: error, already have audio format header\n");
|
TRACE("OpenDMLParser::ParseChunk_strf: error, already have audio format header\n");
|
||||||
return;
|
return true; // just ignore, no error
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (size < sizeof(fCurrentStream->audio_format)) {
|
// if (size < sizeof(fCurrentStream->audio_format)) {
|
||||||
@@ -427,11 +454,11 @@ OpenDMLParser::ParseChunk_strf(uint64 start, uint32 size)
|
|||||||
memset(size + (char *)fCurrentStream->audio_format, 0, fCurrentStream->audio_format_size - size);
|
memset(size + (char *)fCurrentStream->audio_format, 0, fCurrentStream->audio_format_size - size);
|
||||||
|
|
||||||
if ((ssize_t)size != fSource->ReadAt(start, fCurrentStream->audio_format, size)) {
|
if ((ssize_t)size != fSource->ReadAt(start, fCurrentStream->audio_format, size)) {
|
||||||
TRACE("OpenDMLParser::ParseChunk_strf: read error at pos %llu\n", start);
|
ERROR("OpenDMLParser::ParseChunk_strf: read error at pos %llu\n", start);
|
||||||
delete [] fCurrentStream->audio_format;
|
delete [] fCurrentStream->audio_format;
|
||||||
fCurrentStream->audio_format_size = 0;
|
fCurrentStream->audio_format_size = 0;
|
||||||
fCurrentStream->audio_format = 0;
|
fCurrentStream->audio_format = 0;
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if B_HOST_IS_BENDIAN
|
#if B_HOST_IS_BENDIAN
|
||||||
@@ -459,7 +486,7 @@ OpenDMLParser::ParseChunk_strf(uint64 start, uint32 size)
|
|||||||
|
|
||||||
if (fCurrentStream->video_format_valid) {
|
if (fCurrentStream->video_format_valid) {
|
||||||
TRACE("OpenDMLParser::ParseChunk_strf: error, already have video format header\n");
|
TRACE("OpenDMLParser::ParseChunk_strf: error, already have video format header\n");
|
||||||
return;
|
return true; // just ignore, no error
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (size < sizeof(fCurrentStream->video_format)) {
|
// if (size < sizeof(fCurrentStream->video_format)) {
|
||||||
@@ -470,8 +497,8 @@ OpenDMLParser::ParseChunk_strf(uint64 start, uint32 size)
|
|||||||
|
|
||||||
size = min_c(size, sizeof(fCurrentStream->video_format));
|
size = min_c(size, sizeof(fCurrentStream->video_format));
|
||||||
if ((ssize_t)size != fSource->ReadAt(start, &fCurrentStream->video_format, size)) {
|
if ((ssize_t)size != fSource->ReadAt(start, &fCurrentStream->video_format, size)) {
|
||||||
TRACE("OpenDMLParser::ParseChunk_strf: read error at pos %llu\n", start);
|
ERROR("OpenDMLParser::ParseChunk_strf: read error at pos %llu\n", start);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if B_HOST_IS_BENDIAN
|
#if B_HOST_IS_BENDIAN
|
||||||
@@ -504,32 +531,36 @@ OpenDMLParser::ParseChunk_strf(uint64 start, uint32 size)
|
|||||||
TRACE("clr_important = %lu\n", fCurrentStream->video_format.clr_important);
|
TRACE("clr_important = %lu\n", fCurrentStream->video_format.clr_important);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
TRACE("OpenDMLParser::ParseChunk_strf: error, unknown Stream type\n");
|
ERROR("OpenDMLParser::ParseChunk_strf: error, unknown Stream type\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
OpenDMLParser::ParseChunk_indx(uint64 start, uint32 size)
|
OpenDMLParser::ParseChunk_indx(uint64 start, uint32 size)
|
||||||
{
|
{
|
||||||
TRACE("OpenDMLParser::ParseChunk_indx\n");
|
TRACE("OpenDMLParser::ParseChunk_indx\n");
|
||||||
|
|
||||||
if (fCurrentStream == 0) {
|
if (fCurrentStream == 0) {
|
||||||
TRACE("OpenDMLParser::ParseChunk_indx: error, no stream info\n");
|
ERROR("OpenDMLParser::ParseChunk_indx: error, no stream info\n");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
// XXX
|
// XXX
|
||||||
fCurrentStream->odml_index_start = start;
|
fCurrentStream->odml_index_start = start;
|
||||||
fCurrentStream->odml_index_size = size;
|
fCurrentStream->odml_index_size = size;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
OpenDMLParser::ParseChunk_dmlh(uint64 start, uint32 size)
|
OpenDMLParser::ParseChunk_dmlh(uint64 start, uint32 size)
|
||||||
{
|
{
|
||||||
TRACE("OpenDMLParser::ParseChunk_dmlh\n");
|
TRACE("OpenDMLParser::ParseChunk_dmlh\n");
|
||||||
|
|
||||||
if (fOdmlExtendedHeaderValid) {
|
if (fOdmlExtendedHeaderValid) {
|
||||||
TRACE("OpenDMLParser::ParseChunk_dmlh: found a second chunk\n");
|
TRACE("OpenDMLParser::ParseChunk_dmlh: found a second chunk\n");
|
||||||
return;
|
return true; // just ignore it, no error
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size < sizeof(fOdmlExtendedHeader)) {
|
if (size < sizeof(fOdmlExtendedHeader)) {
|
||||||
@@ -539,8 +570,8 @@ OpenDMLParser::ParseChunk_dmlh(uint64 start, uint32 size)
|
|||||||
memset(&fOdmlExtendedHeader, 0, sizeof(fOdmlExtendedHeader));
|
memset(&fOdmlExtendedHeader, 0, sizeof(fOdmlExtendedHeader));
|
||||||
size = min_c(size, sizeof(fOdmlExtendedHeader));
|
size = min_c(size, sizeof(fOdmlExtendedHeader));
|
||||||
if ((ssize_t)size != fSource->ReadAt(start, &fOdmlExtendedHeader, size)) {
|
if ((ssize_t)size != fSource->ReadAt(start, &fOdmlExtendedHeader, size)) {
|
||||||
TRACE("OpenDMLParser::ParseChunk_dmlh: read error at pos %llu\n", start);
|
ERROR("OpenDMLParser::ParseChunk_dmlh: read error at pos %llu\n", start);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if B_HOST_IS_BENDIAN
|
#if B_HOST_IS_BENDIAN
|
||||||
@@ -551,9 +582,11 @@ OpenDMLParser::ParseChunk_dmlh(uint64 start, uint32 size)
|
|||||||
|
|
||||||
TRACE("fOdmlExtendedHeader:\n");
|
TRACE("fOdmlExtendedHeader:\n");
|
||||||
TRACE("total_frames = %ld\n", fOdmlExtendedHeader.total_frames);
|
TRACE("total_frames = %ld\n", fOdmlExtendedHeader.total_frames);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
OpenDMLParser::ParseList_strl(uint64 start, uint32 size)
|
OpenDMLParser::ParseList_strl(uint64 start, uint32 size)
|
||||||
{
|
{
|
||||||
TRACE("OpenDMLParser::ParseList_strl\n");
|
TRACE("OpenDMLParser::ParseList_strl\n");
|
||||||
@@ -561,10 +594,10 @@ OpenDMLParser::ParseList_strl(uint64 start, uint32 size)
|
|||||||
CreateNewStreamInfo();
|
CreateNewStreamInfo();
|
||||||
fStreamCount++;
|
fStreamCount++;
|
||||||
|
|
||||||
ParseList_generic(start, size);
|
return ParseList_generic(start, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
OpenDMLParser::ParseList_generic(uint64 start, uint32 size)
|
OpenDMLParser::ParseList_generic(uint64 start, uint32 size)
|
||||||
{
|
{
|
||||||
TRACE("OpenDMLParser::ParseList_generic\n");
|
TRACE("OpenDMLParser::ParseList_generic\n");
|
||||||
@@ -577,44 +610,56 @@ OpenDMLParser::ParseList_generic(uint64 start, uint32 size)
|
|||||||
uint32 Chunksize;
|
uint32 Chunksize;
|
||||||
|
|
||||||
if (sizeof(temp) != fSource->ReadAt(pos, &temp, sizeof(temp))) {
|
if (sizeof(temp) != fSource->ReadAt(pos, &temp, sizeof(temp))) {
|
||||||
TRACE("OpenDMLParser::ParseList_generic: read error at pos %llu\n",pos);
|
ERROR("OpenDMLParser::ParseList_generic: read error at pos %llu\n",pos);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
pos += 4;
|
pos += 4;
|
||||||
Chunkfcc = AVI_UINT32(temp);
|
Chunkfcc = AVI_UINT32(temp);
|
||||||
|
|
||||||
if (sizeof(temp) != fSource->ReadAt(pos, &temp, sizeof(temp))) {
|
if (sizeof(temp) != fSource->ReadAt(pos, &temp, sizeof(temp))) {
|
||||||
TRACE("OpenDMLParser::ParseList_generic: read error at pos %llu\n",pos);
|
ERROR("OpenDMLParser::ParseList_generic: read error at pos %llu\n",pos);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
pos += 4;
|
pos += 4;
|
||||||
Chunksize = AVI_UINT32(temp);
|
Chunksize = AVI_UINT32(temp);
|
||||||
|
|
||||||
TRACE("OpenDMLParser::ParseList_generic: chunk '"FOURCC_FORMAT"', size = %ld\n", FOURCC_PARAM(Chunkfcc), Chunksize);
|
TRACE("OpenDMLParser::ParseList_generic: chunk '"FOURCC_FORMAT"', size = %ld\n", FOURCC_PARAM(Chunkfcc), Chunksize);
|
||||||
|
|
||||||
if (Chunkfcc == FOURCC('J','U','N','K'))
|
if (Chunksize == 0) {
|
||||||
goto cont;
|
ERROR("OpenDMLParser::ParseList_generic: Error: chunk of size 0 found\n");
|
||||||
else if (Chunkfcc == FOURCC('a','v','i','h'))
|
return false;
|
||||||
ParseChunk_avih(pos, Chunksize);
|
}
|
||||||
else if (Chunkfcc == FOURCC('L','I','S','T'))
|
|
||||||
ParseChunk_LIST(pos, Chunksize);
|
if (Chunkfcc == FOURCC('a','v','i','h')) {
|
||||||
else if (Chunkfcc == FOURCC('s','t','r','h'))
|
if (!ParseChunk_avih(pos, Chunksize))
|
||||||
ParseChunk_strh(pos, Chunksize);
|
return false;
|
||||||
else if (Chunkfcc == FOURCC('s','t','r','f'))
|
} else if (Chunkfcc == FOURCC('L','I','S','T')) {
|
||||||
ParseChunk_strf(pos, Chunksize);
|
if (!ParseChunk_LIST(pos, Chunksize))
|
||||||
else if (Chunkfcc == FOURCC('i','n','d','x'))
|
return false;
|
||||||
ParseChunk_indx(pos, Chunksize);
|
} else if (Chunkfcc == FOURCC('s','t','r','h')) {
|
||||||
else if (Chunkfcc == FOURCC('d','m','l','h'))
|
if (!ParseChunk_strh(pos, Chunksize))
|
||||||
ParseChunk_dmlh(pos, Chunksize);
|
return false;
|
||||||
else
|
} else if (Chunkfcc == FOURCC('s','t','r','f')) {
|
||||||
TRACE("OpenDMLParser::ParseList_generic: unknown chunk ignored\n");
|
if (!ParseChunk_strf(pos, Chunksize))
|
||||||
|
return false;
|
||||||
|
} else if (Chunkfcc == FOURCC('i','n','d','x')) {
|
||||||
|
if (!ParseChunk_indx(pos, Chunksize))
|
||||||
|
return false;
|
||||||
|
} else if (Chunkfcc == FOURCC('d','m','l','h')) {
|
||||||
|
if (!ParseChunk_dmlh(pos, Chunksize))
|
||||||
|
return false;
|
||||||
|
} else if (Chunkfcc == FOURCC('J','U','N','K')) {
|
||||||
|
; // do nothing
|
||||||
|
} else {
|
||||||
|
TRACE("OpenDMLParser::ParseList_generic: unknown chunk ignored\n");
|
||||||
|
}
|
||||||
|
|
||||||
cont:
|
|
||||||
pos += (Chunksize) + (Chunksize & 1);
|
pos += (Chunksize) + (Chunksize & 1);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
OpenDMLParser::ParseList_movi(uint64 start, uint32 size)
|
OpenDMLParser::ParseList_movi(uint64 start, uint32 size)
|
||||||
{
|
{
|
||||||
TRACE("OpenDMLParser::ParseList_movi\n");
|
TRACE("OpenDMLParser::ParseList_movi\n");
|
||||||
@@ -623,6 +668,6 @@ OpenDMLParser::ParseList_movi(uint64 start, uint32 size)
|
|||||||
fMovieListStart = start;
|
fMovieListStart = start;
|
||||||
|
|
||||||
fMovieChunkCount++;
|
fMovieChunkCount++;
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class OpenDMLParser
|
|||||||
public:
|
public:
|
||||||
OpenDMLParser();
|
OpenDMLParser();
|
||||||
~OpenDMLParser();
|
~OpenDMLParser();
|
||||||
void Parse(BPositionIO *source);
|
bool Parse(BPositionIO *source);
|
||||||
|
|
||||||
int StreamCount();
|
int StreamCount();
|
||||||
|
|
||||||
@@ -39,17 +39,17 @@ public:
|
|||||||
const odml_extended_header * OdmlExtendedHeader();
|
const odml_extended_header * OdmlExtendedHeader();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ParseChunk_AVI(int number, uint64 start, uint32 size);
|
bool ParseChunk_AVI(int number, uint64 start, uint32 size);
|
||||||
void ParseChunk_LIST(uint64 start, uint32 size);
|
bool ParseChunk_LIST(uint64 start, uint32 size);
|
||||||
void ParseChunk_idx1(uint64 start, uint32 size);
|
bool ParseChunk_idx1(uint64 start, uint32 size);
|
||||||
void ParseChunk_indx(uint64 start, uint32 size);
|
bool ParseChunk_indx(uint64 start, uint32 size);
|
||||||
void ParseChunk_avih(uint64 start, uint32 size);
|
bool ParseChunk_avih(uint64 start, uint32 size);
|
||||||
void ParseChunk_strh(uint64 start, uint32 size);
|
bool ParseChunk_strh(uint64 start, uint32 size);
|
||||||
void ParseChunk_strf(uint64 start, uint32 size);
|
bool ParseChunk_strf(uint64 start, uint32 size);
|
||||||
void ParseChunk_dmlh(uint64 start, uint32 size);
|
bool ParseChunk_dmlh(uint64 start, uint32 size);
|
||||||
void ParseList_movi(uint64 start, uint32 size);
|
bool ParseList_movi(uint64 start, uint32 size);
|
||||||
void ParseList_generic(uint64 start, uint32 size);
|
bool ParseList_generic(uint64 start, uint32 size);
|
||||||
void ParseList_strl(uint64 start, uint32 size);
|
bool ParseList_strl(uint64 start, uint32 size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CreateNewStreamInfo();
|
void CreateNewStreamInfo();
|
||||||
|
|||||||
Reference in New Issue
Block a user