Changed all extractors' handle_block() function to take a memory_cptr for the memory buffer, a couple of boolean flags and only handle one frame each (and not a complete block group). This is a preparation for easier simpleblock support.

This commit is contained in:
Moritz Bunkus 2005-10-19 16:52:55 +00:00
parent a3b0ee0816
commit 4987608d83
21 changed files with 377 additions and 353 deletions

View File

@ -195,7 +195,7 @@ handle_blockgroup(KaxBlockGroup &blockgroup,
kadditions = FINDFIRST(&blockgroup, KaxBlockAdditions);
// Pass the block to the extractor.
extractor->handle_block(*block, kadditions, block->GlobalTimecode(),
extractor->handle_block_v1(*block, kadditions, block->GlobalTimecode(),
duration, bref, fref);
}

View File

@ -82,17 +82,17 @@ xtr_aac_c::create_file(xtr_base_c *_master,
}
void
xtr_aac_c::handle_block(KaxBlock &block,
xtr_aac_c::handle_frame(memory_cptr &frame,
KaxBlockAdditions *additions,
int64_t timecode,
int64_t duration,
int64_t bref,
int64_t fref) {
int64_t fref,
bool keyframe,
bool discardable,
bool references_valid) {
char adts[56 / 8];
int i, len;
for (i = 0; i < block.NumberFrames(); i++) {
DataBuffer &data = block.GetBuffer(i);
int len;
// Recreate the ADTS headers. What a fun. Like runing headlong into
// a solid wall. But less painful. Well such is life, you know.
@ -133,7 +133,7 @@ xtr_aac_c::handle_block(KaxBlock &block,
// copyright id start, 1 bit = 0 (ASSUMPTION!)
// frame length, 13 bits
len = data.Size() + 7;
len = frame->get_size() + 7;
adts[3] |= len >> 11;
adts[4] = (len >> 3) & 0xff;
adts[5] = (len & 7) << 5;
@ -146,6 +146,5 @@ xtr_aac_c::handle_block(KaxBlock &block,
// Write the ADTS header and the data itself.
out->write(adts, 56 / 8);
out->write(data.Buffer(), data.Size());
}
out->write(frame->get(), frame->get_size());
}

View File

@ -27,9 +27,10 @@ public:
xtr_aac_c(const string &_codec_id, int64_t _tid, track_spec_t &tspec);
virtual void create_file(xtr_base_c *_master, KaxTrackEntry &track);
virtual void handle_block(KaxBlock &block, KaxBlockAdditions *additions,
virtual void handle_frame(memory_cptr &frame, KaxBlockAdditions *additions,
int64_t timecode, int64_t duration, int64_t bref,
int64_t fref);
int64_t fref, bool keyframe, bool discardable,
bool references_valid);
};
#endif

View File

@ -77,18 +77,19 @@ xtr_avc_c::create_file(xtr_base_c *_master,
}
void
xtr_avc_c::handle_block(KaxBlock &block,
xtr_avc_c::handle_frame(memory_cptr &frame,
KaxBlockAdditions *additions,
int64_t timecode,
int64_t duration,
int64_t bref,
int64_t fref) {
int i, pos;
int64_t fref,
bool keyframe,
bool discardable,
bool references_valid) {
int pos;
binary *buf = (binary *)frame->get();
for (i = pos = 0; block.NumberFrames() > i; i++) {
DataBuffer &data = block.GetBuffer(i);
binary *buf = data.Buffer();
while (data.Size() > pos)
write_nal(buf, pos, data.Size(), nal_size_size);
}
pos = 0;
while (frame->get_size() > pos)
write_nal(buf, pos, frame->get_size(), nal_size_size);
}

View File

@ -27,9 +27,10 @@ public:
xtr_avc_c(const string &_codec_id, int64_t _tid, track_spec_t &tspec);
virtual void create_file(xtr_base_c *_master, KaxTrackEntry &track);
virtual void handle_block(KaxBlock &block, KaxBlockAdditions *additions,
virtual void handle_frame(memory_cptr &frame, KaxBlockAdditions *additions,
int64_t timecode, int64_t duration, int64_t bref,
int64_t fref);
int64_t fref, bool keyframe, bool discardable,
bool references_valid);
void write_nal(const binary *data, int &pos, int data_size,
int nal_size_size);
};

View File

@ -73,22 +73,20 @@ xtr_avi_c::create_file(xtr_base_c *_master,
}
void
xtr_avi_c::handle_block(KaxBlock &block,
xtr_avi_c::handle_frame(memory_cptr &frame,
KaxBlockAdditions *additions,
int64_t timecode,
int64_t duration,
int64_t bref,
int64_t fref) {
int i;
int64_t fref,
bool keyframe,
bool discardable,
bool references_valid) {
if (references_valid)
keyframe = bref == 0;
if (0 >= duration)
duration = default_duration;
AVI_write_frame(avi, (char *)frame->get(), frame->get_size(), keyframe);
for (i = 0; i < block.NumberFrames(); i++) {
DataBuffer &data = block.GetBuffer(i);
AVI_write_frame(avi, (char *)data.Buffer(), data.Size(),
bref != 0 ? 0 : 1);
if (((double)duration / 1000000.0 - (1000.0 / fps)) >= 1.5) {
int k, nfr;
@ -97,7 +95,6 @@ xtr_avi_c::handle_block(KaxBlock &block,
AVI_write_frame(avi, "", 0, 0);
}
}
}
void
xtr_avi_c::finish_file() {

View File

@ -33,9 +33,10 @@ public:
xtr_avi_c(const string &_codec_id, int64_t _tid, track_spec_t &tspec);
virtual void create_file(xtr_base_c *_master, KaxTrackEntry &track);
virtual void handle_block(KaxBlock &block, KaxBlockAdditions *additions,
virtual void handle_frame(memory_cptr &frame, KaxBlockAdditions *additions,
int64_t timecode, int64_t duration, int64_t bref,
int64_t fref);
int64_t fref, bool keyframe, bool discardable,
bool references_valid);
virtual void finish_file();
};

View File

@ -69,7 +69,7 @@ xtr_base_c::create_file(xtr_base_c *_master,
}
void
xtr_base_c::handle_block(KaxBlock &block,
xtr_base_c::handle_block_v1(KaxBlock &block,
KaxBlockAdditions *additions,
int64_t timecode,
int64_t duration,
@ -77,11 +77,42 @@ xtr_base_c::handle_block(KaxBlock &block,
int64_t fref) {
int i;
if (0 == block.NumberFrames())
return;
if (0 > duration)
duration = default_duration * block.NumberFrames();
for (i = 0; i < block.NumberFrames(); i++) {
DataBuffer &data = block.GetBuffer(i);
out->write(data.Buffer(), data.Size());
bytes_written += data.Size();
int64_t this_timecode, this_duration;
if (0 > duration) {
this_timecode = timecode;
this_duration = duration;
} else {
this_timecode = timecode + i * duration / block.NumberFrames();
this_duration = duration / block.NumberFrames();
}
DataBuffer &data = block.GetBuffer(i);
memory_cptr frame(new memory_c(data.Buffer(), data.Size(), false));
handle_frame(frame, additions, this_timecode, this_duration, bref, fref,
false, false, true);
}
}
void
xtr_base_c::handle_frame(memory_cptr &frame,
KaxBlockAdditions *additions,
int64_t timecode,
int64_t duration,
int64_t bref,
int64_t fref,
bool keyframe,
bool discardable,
bool references_valid) {
out->write(frame->get(), frame->get_size());
bytes_written += frame->get_size();
}
void

View File

@ -45,9 +45,13 @@ public:
virtual ~xtr_base_c();
virtual void create_file(xtr_base_c *_master, KaxTrackEntry &track);
virtual void handle_block(KaxBlock &block, KaxBlockAdditions *additions,
virtual void handle_block_v1(KaxBlock &block, KaxBlockAdditions *additions,
int64_t timecode, int64_t duration, int64_t bref,
int64_t fref);
virtual void handle_frame(memory_cptr &frame, KaxBlockAdditions *additions,
int64_t timecode, int64_t duration, int64_t bref,
int64_t fref, bool keyframe, bool discardable,
bool references_valid);
virtual void finish_track();
virtual void finish_file();

View File

@ -50,7 +50,7 @@ xtr_oggbase_c::xtr_oggbase_c(const string &_codec_id,
int64_t _tid,
track_spec_t &tspec):
xtr_base_c(_codec_id, _tid, tspec),
packetno(2), buffered_data(NULL), buffered_size(0), previous_end(0) {
packetno(2), previous_end(0) {
}
void
@ -67,40 +67,31 @@ xtr_oggbase_c::create_file(xtr_base_c *_master,
}
void
xtr_oggbase_c::handle_block(KaxBlock &block,
xtr_oggbase_c::handle_frame(memory_cptr &frame,
KaxBlockAdditions *additions,
int64_t timecode,
int64_t duration,
int64_t bref,
int64_t fref) {
int i;
if (-1 == duration)
duration = default_duration * block.NumberFrames();
for (i = 0; i < block.NumberFrames(); i++) {
DataBuffer &data = block.GetBuffer(i);
if (NULL != buffered_data) {
int64_t fref,
bool keyframe,
bool discardable,
bool references_valid) {
if (NULL != buffered_data.get()) {
ogg_packet op;
op.b_o_s = 0;
op.e_o_s = 0;
op.packetno = packetno;
op.packet = buffered_data;
op.bytes = buffered_size;
// op.granulepos = (timecode / 1000000) * sfreq / 1000;
op.granulepos = (timecode + i * duration / block.NumberFrames()) *
sfreq / 1000000000;
op.packet = buffered_data->get();
op.bytes = buffered_data->get_size();
op.granulepos = timecode * sfreq / 1000000000;
ogg_stream_packetin(&os, &op);
write_pages();
safefree(buffered_data);
packetno++;
}
buffered_data = (unsigned char *)safememdup(data.Buffer(), data.Size());
buffered_size = data.Size();
}
buffered_data = memory_cptr(frame->clone());
previous_end = timecode + duration;
}
@ -108,7 +99,7 @@ void
xtr_oggbase_c::finish_file() {
ogg_packet op;
if (NULL == buffered_data)
if (NULL == buffered_data.get())
return;
// Set the "end of stream" marker on the last packet, handle it
@ -116,12 +107,11 @@ xtr_oggbase_c::finish_file() {
op.b_o_s = 0;
op.e_o_s = 1;
op.packetno = packetno;
op.packet = buffered_data;
op.bytes = buffered_size;
op.packet = buffered_data->get();
op.bytes = buffered_data->get_size();
// op.granulepos = (previous_end / 1000000) * sfreq / 1000;
op.granulepos = previous_end * sfreq / 1000000000;
ogg_stream_packetin(&os, &op);
safefree(buffered_data);
flush_pages();
ogg_stream_clear(&os);
}

View File

@ -32,8 +32,7 @@ class xtr_oggbase_c: public xtr_base_c {
public:
ogg_stream_state os;
int packetno;
unsigned char *buffered_data;
int buffered_size;
memory_cptr buffered_data;
int sfreq;
int64_t previous_end;
@ -41,9 +40,10 @@ public:
xtr_oggbase_c(const string &_codec_id, int64_t _tid, track_spec_t &tspec);
virtual void create_file(xtr_base_c *_master, KaxTrackEntry &track);
virtual void handle_block(KaxBlock &block, KaxBlockAdditions *additions,
virtual void handle_frame(memory_cptr &frame, KaxBlockAdditions *additions,
int64_t timecode, int64_t duration, int64_t bref,
int64_t fref);
int64_t fref, bool keyframe, bool discardable,
bool references_valid);
virtual void finish_file();
virtual void write_pages();

View File

@ -61,31 +61,31 @@ xtr_rmff_c::create_file(xtr_base_c *_master,
}
void
xtr_rmff_c::handle_block(KaxBlock &block,
xtr_rmff_c::handle_frame(memory_cptr &frame,
KaxBlockAdditions *additions,
int64_t timecode,
int64_t duration,
int64_t bref,
int64_t fref) {
int i;
rmff_frame_t *frame;
int64_t fref,
bool keyframe,
bool discardable,
bool references_valid) {
rmff_frame_t *rmff_frame;
for (i = 0; i < block.NumberFrames(); i++) {
DataBuffer &data = block.GetBuffer(i);
frame = rmff_allocate_frame(data.Size(), data.Buffer());
if (frame == NULL)
rmff_frame = rmff_allocate_frame(frame->get_size(), frame->get());
if (rmff_frame == NULL)
mxerror("Memory for a RealAudio/RealVideo frame could not be "
"allocated.\n");
frame->timecode = timecode / 1000000;
if (0 == bref)
frame->flags = RMFF_FRAME_FLAG_KEYFRAME;
rmff_frame->timecode = timecode / 1000000;
if (references_valid)
keyframe = 0 == bref;
if (keyframe)
rmff_frame->flags = RMFF_FRAME_FLAG_KEYFRAME;
if ('V' == codec_id[0])
rmff_write_packed_video_frame(rmtrack, frame);
rmff_write_packed_video_frame(rmtrack, rmff_frame);
else
rmff_write_frame(rmtrack, frame);
rmff_release_frame(frame);
}
rmff_write_frame(rmtrack, rmff_frame);
rmff_release_frame(rmff_frame);
}
void

View File

@ -30,9 +30,10 @@ public:
xtr_rmff_c(const string &_codec_id, int64_t _tid, track_spec_t &tspec);
virtual void create_file(xtr_base_c *_master, KaxTrackEntry &track);
virtual void handle_block(KaxBlock &block, KaxBlockAdditions *additions,
virtual void handle_frame(memory_cptr &frame, KaxBlockAdditions *additions,
int64_t timecode, int64_t duration, int64_t bref,
int64_t fref);
int64_t fref, bool keyframe, bool discardable,
bool references_valid);
virtual void finish_file();
virtual void headers_done();
};

View File

@ -44,12 +44,15 @@ xtr_srt_c::create_file(xtr_base_c *_master,
#define LLD03 "%03" PRId64
void
xtr_srt_c::handle_block(KaxBlock &block,
xtr_srt_c::handle_frame(memory_cptr &frame,
KaxBlockAdditions *additions,
int64_t timecode,
int64_t duration,
int64_t bref,
int64_t fref) {
int64_t fref,
bool keyframe,
bool discardable,
bool references_valid) {
char *text;
int64_t start, end;
string buffer;
@ -60,15 +63,13 @@ xtr_srt_c::handle_block(KaxBlock &block,
duration = 1000000000;
}
DataBuffer &data = block.GetBuffer(0);
start = timecode / 1000000;
end = start + duration / 1000000;
++num_entries;
text = new char[data.Size() + 1];
memcpy(text, data.Buffer(), data.Size());
text[data.Size()] = 0;
text = new char[frame->get_size() + 1];
memcpy(text, frame->get(), frame->get_size());
text[frame->get_size()] = 0;
buffer = mxsprintf("%d\n"
LLD02 ":" LLD02 ":" LLD02 "," LLD03 " --> "
LLD02 ":" LLD02 ":" LLD02 "," LLD03 "\n"
@ -177,12 +178,15 @@ xtr_ssa_c::create_file(xtr_base_c *_master,
}
void
xtr_ssa_c::handle_block(KaxBlock &block,
xtr_ssa_c::handle_frame(memory_cptr &frame,
KaxBlockAdditions *additions,
int64_t timecode,
int64_t duration,
int64_t bref,
int64_t fref) {
int64_t fref,
bool keyframe,
bool discardable,
bool references_valid) {
int i, k, num;
char *s;
vector<string> fields;
@ -199,11 +203,10 @@ xtr_ssa_c::handle_block(KaxBlock &block,
start = timecode / 1000000;
end = start + duration / 1000000;
DataBuffer &data = block.GetBuffer(0);
s = (char *)safemalloc(data.Size() + 1);
s = (char *)safemalloc(frame->get_size() + 1);
memory_c af_s((unsigned char *)s, 0, true);
memcpy(s, data.Buffer(), data.Size());
s[data.Size()] = 0;
memcpy(s, frame->get(), frame->get_size());
s[frame->get_size()] = 0;
// Split the line into the fields.
// Specs say that the following fields are to put into the block:
@ -374,21 +377,18 @@ xtr_usf_c::create_file(xtr_base_c *_master,
}
void
xtr_usf_c::handle_block(KaxBlock &block,
xtr_usf_c::handle_frame(memory_cptr &frame,
KaxBlockAdditions *additions,
int64_t timecode,
int64_t duration,
int64_t bref,
int64_t fref) {
if (0 == block.NumberFrames())
return;
DataBuffer &data_buffer = block.GetBuffer(0);
int64_t fref,
bool keyframe,
bool discardable,
bool references_valid) {
usf_entry_t entry("", timecode, timecode + duration);
memory_cptr data(new memory_c(data_buffer.Buffer(), data_buffer.Size(),
false));
content_decoder.reverse(data, CONTENT_ENCODING_SCOPE_BLOCK);
entry.m_text.append((const char *)data->get(), data->get_size());
content_decoder.reverse(frame, CONTENT_ENCODING_SCOPE_BLOCK);
entry.m_text.append((const char *)frame->get(), frame->get_size());
m_entries.push_back(entry);
}

View File

@ -36,9 +36,10 @@ public:
xtr_srt_c(const string &_codec_id, int64_t _tid, track_spec_t &tspec);
virtual void create_file(xtr_base_c *_master, KaxTrackEntry &track);
virtual void handle_block(KaxBlock &block, KaxBlockAdditions *additions,
virtual void handle_frame(memory_cptr &frame, KaxBlockAdditions *additions,
int64_t timecode, int64_t duration, int64_t bref,
int64_t fref);
int64_t fref, bool keyframe, bool discardable,
bool references_valid);
};
class xtr_ssa_c: public xtr_base_c {
@ -65,9 +66,10 @@ public:
xtr_ssa_c(const string &_codec_id, int64_t _tid, track_spec_t &tspec);
virtual void create_file(xtr_base_c *_master, KaxTrackEntry &track);
virtual void handle_block(KaxBlock &block, KaxBlockAdditions *additions,
virtual void handle_frame(memory_cptr &frame, KaxBlockAdditions *additions,
int64_t timecode, int64_t duration, int64_t bref,
int64_t fref);
int64_t fref, bool keyframe, bool discardable,
bool references_valid);
virtual void finish_file();
};
@ -89,9 +91,10 @@ public:
xtr_usf_c(const string &_codec_id, int64_t _tid, track_spec_t &tspec);
virtual void create_file(xtr_base_c *_master, KaxTrackEntry &track);
virtual void handle_block(KaxBlock &block, KaxBlockAdditions *additions,
virtual void handle_frame(memory_cptr &frame, KaxBlockAdditions *additions,
int64_t timecode, int64_t duration, int64_t bref,
int64_t fref);
int64_t fref, bool keyframe, bool discardable,
bool references_valid);
virtual void finish_track();
virtual void finish_file();
};

View File

@ -48,20 +48,17 @@ xtr_tta_c::create_file(xtr_base_c *_master,
}
void
xtr_tta_c::handle_block(KaxBlock &block,
xtr_tta_c::handle_frame(memory_cptr &frame,
KaxBlockAdditions *additions,
int64_t timecode,
int64_t duration,
int64_t bref,
int64_t fref) {
int i;
for (i = 0; i < block.NumberFrames(); i++) {
DataBuffer &data = block.GetBuffer(i);
frame_sizes.push_back(data.Size());
out->write(data.Buffer(), data.Size());
}
int64_t fref,
bool keyframe,
bool discardable,
bool references_valid) {
frame_sizes.push_back(frame->get_size());
out->write(frame->get(), frame->get_size());
if (0 < duration)
last_duration = duration;

View File

@ -32,9 +32,10 @@ public:
xtr_tta_c(const string &_codec_id, int64_t _tid, track_spec_t &tspec);
virtual void create_file(xtr_base_c *_master, KaxTrackEntry &track);
virtual void handle_block(KaxBlock &block, KaxBlockAdditions *additions,
virtual void handle_frame(memory_cptr &frame, KaxBlockAdditions *additions,
int64_t timecode, int64_t duration, int64_t bref,
int64_t fref);
int64_t fref, bool keyframe, bool discardable,
bool references_valid);
virtual void finish_file();
};

View File

@ -115,35 +115,32 @@ xtr_vobsub_c::create_file(xtr_base_c *_master,
}
void
xtr_vobsub_c::handle_block(KaxBlock &block,
xtr_vobsub_c::handle_frame(memory_cptr &frame,
KaxBlockAdditions *additions,
int64_t timecode,
int64_t duration,
int64_t bref,
int64_t fref) {
int64_t fref,
bool keyframe,
bool discardable,
bool references_valid) {
static unsigned char padding_data[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff};
mpeg_es_header_t es;
mpeg_ps_header_t ps;
uint64_t c;
int i;
uint32_t size, padding, first;
xtr_vobsub_c *vmaster;
unsigned char *data;
if (NULL == master)
vmaster = this;
else
vmaster = static_cast<xtr_vobsub_c *>(master);
for (i = 0; i < block.NumberFrames(); i++) {
uint32_t size, padding, first;
DataBuffer &data_buffer = block.GetBuffer(i);
memory_cptr data_m(new memory_c(data_buffer.Buffer(), data_buffer.Size(),
false));
unsigned char *data;
content_decoder.reverse(data_m, CONTENT_ENCODING_SCOPE_BLOCK);
data = data_m->get();
size = data_m->get_size();
content_decoder.reverse(frame, CONTENT_ENCODING_SCOPE_BLOCK);
data = frame->get();
size = frame->get_size();
positions.push_back(vmaster->out->getFilePointer());
timecodes.push_back(timecode);
@ -233,7 +230,6 @@ xtr_vobsub_c::handle_block(KaxBlock &block,
}
}
}
}
void
xtr_vobsub_c::finish_file() {

View File

@ -33,9 +33,10 @@ public:
xtr_vobsub_c(const string &_codec_id, int64_t _tid, track_spec_t &tspec);
virtual void create_file(xtr_base_c *_master, KaxTrackEntry &track);
virtual void handle_block(KaxBlock &block, KaxBlockAdditions *additions,
virtual void handle_frame(memory_cptr &frame, KaxBlockAdditions *additions,
int64_t timecode, int64_t duration, int64_t bref,
int64_t fref);
int64_t fref, bool keyframe, bool discardable,
bool references_valid);
virtual void finish_file();
virtual void write_idx(mm_io_c &idx, int index);
};

View File

@ -110,19 +110,19 @@ xtr_wavpack4_c::create_file(xtr_base_c *_master,
}
void
xtr_wavpack4_c::handle_block(KaxBlock &block,
xtr_wavpack4_c::handle_frame(memory_cptr &frame,
KaxBlockAdditions *additions,
int64_t timecode,
int64_t duration,
int64_t bref,
int64_t fref) {
int64_t fref,
bool keyframe,
bool discardable,
bool references_valid) {
binary wv_header[32], *mybuffer;
int i, data_size;
int data_size;
vector<uint32_t> flags;
for (i = 0; i < block.NumberFrames(); i++) {
DataBuffer &data = block.GetBuffer(i);
// build the main header
wv_header[0] = 'w';
@ -137,8 +137,8 @@ xtr_wavpack4_c::handle_block(KaxBlock &block,
wv_header[14] = 0xFF;
wv_header[15] = 0xFF;
put_uint32_le(&wv_header[16], number_of_samples); // block_index
mybuffer = data.Buffer();
data_size = data.Size();
mybuffer = frame->get();
data_size = frame->get_size();
number_of_samples += get_uint32_le(mybuffer);
// rest of the header:
@ -177,11 +177,11 @@ xtr_wavpack4_c::handle_block(KaxBlock &block,
KaxBlockMore *block_more = FINDFIRST(additions, KaxBlockMore);
if (block_more == NULL)
break;
return;
KaxBlockAdditional *block_addition =
FINDFIRST(block_more, KaxBlockAdditional);
if (block_addition == NULL)
break;
return;
data_size = block_addition->GetSize();
mybuffer = block_addition->GetBuffer();
@ -208,7 +208,6 @@ xtr_wavpack4_c::handle_block(KaxBlock &block,
}
}
}
}
void
xtr_wavpack4_c::finish_file() {

View File

@ -42,9 +42,10 @@ public:
xtr_wavpack4_c(const string &_codec_id, int64_t _tid, track_spec_t &tspec);
virtual void create_file(xtr_base_c *_master, KaxTrackEntry &track);
virtual void handle_block(KaxBlock &block, KaxBlockAdditions *additions,
virtual void handle_frame(memory_cptr &frame, KaxBlockAdditions *additions,
int64_t timecode, int64_t duration, int64_t bref,
int64_t fref);
int64_t fref, bool keyframe, bool discardable,
bool references_valid);
virtual void finish_file();
};