Some better error handling if the packet length is < 12 bytes. Packets with incredibly high timestamps are discarded.

This commit is contained in:
Moritz Bunkus 2003-07-14 07:39:42 +00:00
parent db63e0b122
commit 35006f6825
2 changed files with 55 additions and 5 deletions

View File

@ -449,19 +449,43 @@ real_demuxer_t *real_reader_c::find_demuxer(int id) {
return NULL;
}
int real_reader_c::finish() {
int i;
real_demuxer_t *dmx;
for (i = 0; i < demuxers.size(); i++) {
dmx = demuxers[i];
if ((dmx->type == 'a') && (dmx->c_data != NULL)) {
int64_t dur = dmx->c_timecode / dmx->c_numpackets;
dmx->packetizer->process(dmx->c_data, dmx->c_len, dmx->c_timecode + dur,
dur);
}
}
done = true;
return 0;
}
int real_reader_c::read() {
uint32_t object_version, length, id, timestamp, flags, object_id;
unsigned char *chunk;
real_demuxer_t *dmx;
int64_t fpos;
if (done)
return 0;
try {
fpos = io->getFilePointer();
object_version = io->read_uint16_be();
length = io->read_uint16_be();
object_id = object_version << 16 + length;
if (object_id == FOURCC('I', 'N', 'D', 'X'))
return 0;
return finish();
if (object_id == FOURCC('D', 'A', 'T', 'A')) {
io->skip(2); // object_version
io->skip(4); // num_packets
@ -475,6 +499,14 @@ int real_reader_c::read() {
io->skip(1); // reserved
flags = io->read_uint8();
if (length < 12) {
mxprint(stdout, "real_reader: %s: Data packet length is too small: %u. "
"Other values: object_version: 0x%04x, id: 0x%04x, "
"timestamp: %u, flags: 0x%02x. File position: %lld. Aborting.\n",
ti->fname, length, object_version, id, timestamp, flags, fpos);
return finish();
}
dmx = find_demuxer(id);
if (dmx == NULL) {
@ -487,18 +519,30 @@ int real_reader_c::read() {
chunk = (unsigned char *)safemalloc(length);
if (io->read(chunk, length) != length) {
safefree(chunk);
return 0;
return finish();
}
if (dmx->type == 'v')
assemble_packet(dmx, chunk, length, timestamp, (flags & 2) == 2);
else
dmx->packetizer->process(chunk, length, timestamp);
else {
if ((timestamp - last_timestamp) <= (5 * 60 * 1000)) {
if (dmx->c_data != NULL)
dmx->packetizer->process(dmx->c_data, dmx->c_len, timestamp,
timestamp - dmx->c_timecode);
dmx->c_data = chunk;
dmx->c_len = length;
dmx->c_timecode = timestamp;
dmx->c_numpackets++;
} else {
timestamp = last_timestamp;
safefree(chunk);
}
}
last_timestamp = timestamp;
} catch (exception &ex) {
return 0;
return finish();
}
return EMOREDATA;

View File

@ -52,6 +52,10 @@ typedef struct {
unsigned char *last_packet;
int last_seq, last_len, ctb_len, kf_last_timecode;
bool keyframe;
unsigned char *c_data;
int c_len, c_numpackets;
int64_t c_timecode;
} real_demuxer_t;
class real_reader_c: public generic_reader_c {
@ -60,6 +64,7 @@ private:
vector<real_demuxer_t *> demuxers;
int act_wchar;
int64_t file_size, last_timestamp;
bool done;
public:
real_reader_c(track_info_t *nti) throw (error_c);
@ -80,6 +85,7 @@ private:
virtual real_demuxer_t *find_demuxer(int id);
virtual void assemble_packet(real_demuxer_t *dmx, unsigned char *p, int size,
int64_t timecode, bool keyframe);
virtual int finish();
};
#endif // __R_REAL_H