46
49
DataBuffer * DataBuffer::Clone()
48
binary *ClonedData = (binary *)malloc(mySize * sizeof(binary));
49
assert(ClonedData != NULL);
50
memcpy(ClonedData, myBuffer ,mySize );
51
binary *ClonedData = (binary *)malloc(mySize * sizeof(binary));
52
assert(ClonedData != NULL);
53
memcpy(ClonedData, myBuffer ,mySize );
52
SimpleDataBuffer * result = new SimpleDataBuffer(ClonedData, mySize, 0);
53
result->bValidValue = bValidValue;
55
SimpleDataBuffer * result = new SimpleDataBuffer(ClonedData, mySize, 0);
56
result->bValidValue = bValidValue;
57
60
SimpleDataBuffer::SimpleDataBuffer(const SimpleDataBuffer & ToClone)
58
:DataBuffer((binary *)malloc(ToClone.mySize * sizeof(binary)), ToClone.mySize, myFreeBuffer)
61
:DataBuffer((binary *)malloc(ToClone.mySize * sizeof(binary)), ToClone.mySize, myFreeBuffer)
60
assert(myBuffer != NULL);
61
memcpy(myBuffer, ToClone.myBuffer ,mySize );
62
bValidValue = ToClone.bValidValue;
63
assert(myBuffer != NULL);
64
memcpy(myBuffer, ToClone.myBuffer ,mySize );
65
bValidValue = ToClone.bValidValue;
65
68
bool KaxInternalBlock::ValidateSize() const
67
return (GetSize() >= 4); /// for the moment
70
return (GetSize() >= 4); /// for the moment
70
73
KaxInternalBlock::~KaxInternalBlock()
75
78
KaxInternalBlock::KaxInternalBlock(const KaxInternalBlock & ElementToClone)
76
:EbmlBinary(ElementToClone)
77
,myBuffers(ElementToClone.myBuffers.size())
78
,Timecode(ElementToClone.Timecode)
79
,LocalTimecode(ElementToClone.LocalTimecode)
80
,bLocalTimecodeUsed(ElementToClone.bLocalTimecodeUsed)
81
,TrackNumber(ElementToClone.TrackNumber)
82
,ParentCluster(ElementToClone.ParentCluster) ///< \todo not exactly
79
:EbmlBinary(ElementToClone)
80
,myBuffers(ElementToClone.myBuffers.size())
81
,Timecode(ElementToClone.Timecode)
82
,LocalTimecode(ElementToClone.LocalTimecode)
83
,bLocalTimecodeUsed(ElementToClone.bLocalTimecodeUsed)
84
,TrackNumber(ElementToClone.TrackNumber)
85
,ParentCluster(ElementToClone.ParentCluster) ///< \todo not exactly
84
// add a clone of the list
85
std::vector<DataBuffer *>::const_iterator Itr = ElementToClone.myBuffers.begin();
86
std::vector<DataBuffer *>::iterator myItr = myBuffers.begin();
87
while (Itr != ElementToClone.myBuffers.end())
89
*myItr = (*Itr)->Clone();
87
// add a clone of the list
88
std::vector<DataBuffer *>::const_iterator Itr = ElementToClone.myBuffers.begin();
89
std::vector<DataBuffer *>::iterator myItr = myBuffers.begin();
90
while (Itr != ElementToClone.myBuffers.end()) {
91
*myItr = (*Itr)->Clone();
95
97
KaxBlockGroup::~KaxBlockGroup()
97
//NOTE("KaxBlockGroup::~KaxBlockGroup");
99
//NOTE("KaxBlockGroup::~KaxBlockGroup");
100
102
KaxBlockGroup::KaxBlockGroup(EBML_EXTRA_DEF)
101
:EbmlMaster(EBML_CLASS_SEMCONTEXT(KaxBlockGroup) EBML_DEF_SEP EBML_EXTRA_CALL)
103
:EbmlMaster(EBML_CLASS_SEMCONTEXT(KaxBlockGroup) EBML_DEF_SEP EBML_EXTRA_CALL)
108
\todo hardcoded limit of the number of frames in a lace should be a parameter
109
\return true if more frames can be added to this Block
110
\todo hardcoded limit of the number of frames in a lace should be a parameter
111
\return true if more frames can be added to this Block
111
113
bool KaxInternalBlock::AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, LacingType lacing, bool invisible)
114
if (myBuffers.size() == 0) {
117
TrackNumber = track.TrackNumber();
118
mInvisible = invisible;
121
myBuffers.push_back(&buffer);
123
// we don't allow more than 8 frames in a Block because the overhead improvement is minimal
124
if (myBuffers.size() >= 8 || lacing == LACING_NONE)
127
if (lacing == LACING_XIPH)
128
// decide wether a new frame can be added or not
129
// a frame in a lace is not efficient when the place necessary to code it in a lace is bigger
130
// than the size of a simple Block. That means more than 6 bytes (4 in struct + 2 for EBML) to code the size
131
return (buffer.Size() < 6*0xFF);
116
if (myBuffers.size() == 0) {
119
TrackNumber = track.TrackNumber();
120
mInvisible = invisible;
123
myBuffers.push_back(&buffer);
125
// we don't allow more than 8 frames in a Block because the overhead improvement is minimal
126
if (myBuffers.size() >= 8 || lacing == LACING_NONE)
129
if (lacing == LACING_XIPH)
130
// decide wether a new frame can be added or not
131
// a frame in a lace is not efficient when the place necessary to code it in a lace is bigger
132
// than the size of a simple Block. That means more than 6 bytes (4 in struct + 2 for EBML) to code the size
133
return (buffer.Size() < 6*0xFF);
137
\return Returns the lacing type that produces the smallest footprint.
139
\return Returns the lacing type that produces the smallest footprint.
139
141
LacingType KaxInternalBlock::GetBestLacingType() const {
140
int XiphLacingSize, EbmlLacingSize, i;
141
bool SameSize = true;
143
if (myBuffers.size() <= 1)
146
XiphLacingSize = 1; // Number of laces is stored in 1 byte.
148
for (i = 0; i < (int)myBuffers.size() - 1; i++) {
149
if (myBuffers[i]->Size() != myBuffers[i + 1]->Size())
151
XiphLacingSize += myBuffers[i]->Size() / 255 + 1;
153
EbmlLacingSize += CodedSizeLength(myBuffers[0]->Size(), 0, IsFiniteSize());
154
for (i = 1; i < (int)myBuffers.size() - 1; i++)
155
EbmlLacingSize += CodedSizeLengthSigned(int64(myBuffers[i]->Size()) - int64(myBuffers[i - 1]->Size()), 0);
158
else if (XiphLacingSize < EbmlLacingSize)
142
int XiphLacingSize, EbmlLacingSize, i;
143
bool SameSize = true;
145
if (myBuffers.size() <= 1)
148
XiphLacingSize = 1; // Number of laces is stored in 1 byte.
150
for (i = 0; i < (int)myBuffers.size() - 1; i++) {
151
if (myBuffers[i]->Size() != myBuffers[i + 1]->Size())
153
XiphLacingSize += myBuffers[i]->Size() / 255 + 1;
155
EbmlLacingSize += CodedSizeLength(myBuffers[0]->Size(), 0, IsFiniteSize());
156
for (i = 1; i < (int)myBuffers.size() - 1; i++)
157
EbmlLacingSize += CodedSizeLengthSigned(int64(myBuffers[i]->Size()) - int64(myBuffers[i - 1]->Size()), 0);
160
else if (XiphLacingSize < EbmlLacingSize)
164
166
filepos_t KaxInternalBlock::UpdateSize(bool /* bSaveDefault */, bool /* bForceRender */)
166
LacingType LacingHere;
167
assert(EbmlBinary::GetBuffer() == NULL); // Data is not used for KaxInternalBlock
168
assert(TrackNumber < 0x4000); // no more allowed for the moment
171
// compute the final size of the data
172
switch (myBuffers.size()) {
177
SetSize_(4 + myBuffers[0]->Size());
180
SetSize_(4 + 1); // 1 for the lacing head
181
if (mLacing == LACING_AUTO)
182
LacingHere = GetBestLacingType();
184
LacingHere = mLacing;
188
for (i=0; i<myBuffers.size()-1; i++) {
189
SetSize_(GetSize() + myBuffers[i]->Size() + (myBuffers[i]->Size() / 0xFF + 1));
193
SetSize_(GetSize() + myBuffers[0]->Size() + CodedSizeLength(myBuffers[0]->Size(), 0, IsFiniteSize()));
194
for (i=1; i<myBuffers.size()-1; i++) {
195
SetSize_(GetSize() + myBuffers[i]->Size() + CodedSizeLengthSigned(int64(myBuffers[i]->Size()) - int64(myBuffers[i-1]->Size()), 0));
199
for (i=0; i<myBuffers.size()-1; i++) {
200
SetSize_(GetSize() + myBuffers[i]->Size());
207
// Size of the last frame (not in lace)
208
SetSize_(GetSize() + myBuffers[i]->Size());
212
if (TrackNumber >= 0x80)
213
SetSize_(GetSize() + 1); // the size will be coded with one more octet
168
LacingType LacingHere;
169
assert(EbmlBinary::GetBuffer() == NULL); // Data is not used for KaxInternalBlock
170
assert(TrackNumber < 0x4000); // no more allowed for the moment
173
// compute the final size of the data
174
switch (myBuffers.size()) {
179
SetSize_(4 + myBuffers[0]->Size());
182
SetSize_(4 + 1); // 1 for the lacing head
183
if (mLacing == LACING_AUTO)
184
LacingHere = GetBestLacingType();
186
LacingHere = mLacing;
187
switch (LacingHere) {
189
for (i=0; i<myBuffers.size()-1; i++) {
190
SetSize_(GetSize() + myBuffers[i]->Size() + (myBuffers[i]->Size() / 0xFF + 1));
194
SetSize_(GetSize() + myBuffers[0]->Size() + CodedSizeLength(myBuffers[0]->Size(), 0, IsFiniteSize()));
195
for (i=1; i<myBuffers.size()-1; i++) {
196
SetSize_(GetSize() + myBuffers[i]->Size() + CodedSizeLengthSigned(int64(myBuffers[i]->Size()) - int64(myBuffers[i-1]->Size()), 0));
200
for (i=0; i<myBuffers.size()-1; i++) {
201
SetSize_(GetSize() + myBuffers[i]->Size());
208
// Size of the last frame (not in lace)
209
SetSize_(GetSize() + myBuffers[i]->Size());
213
if (TrackNumber >= 0x80)
214
SetSize_(GetSize() + 1); // the size will be coded with one more octet
218
219
#if MATROSKA_VERSION >= 2
219
220
KaxBlockVirtual::KaxBlockVirtual(const KaxBlockVirtual & ElementToClone)
220
:EbmlBinary(ElementToClone)
221
,Timecode(ElementToClone.Timecode)
222
,TrackNumber(ElementToClone.TrackNumber)
223
,ParentCluster(ElementToClone.ParentCluster) ///< \todo not exactly
221
:EbmlBinary(ElementToClone)
222
,Timecode(ElementToClone.Timecode)
223
,TrackNumber(ElementToClone.TrackNumber)
224
,ParentCluster(ElementToClone.ParentCluster) ///< \todo not exactly
225
SetBuffer(DataBlock,sizeof(DataBlock));
226
SetValueIsSet(false);
226
SetBuffer(DataBlock,sizeof(DataBlock));
227
SetValueIsSet(false);
229
230
KaxBlockVirtual::KaxBlockVirtual(EBML_EXTRA_DEF)
230
:EBML_DEF_BINARY(KaxBlockVirtual)EBML_DEF_SEP ParentCluster(NULL)
231
:EBML_DEF_BINARY(KaxBlockVirtual)EBML_DEF_SEP ParentCluster(NULL)
232
SetBuffer(DataBlock,sizeof(DataBlock));
233
SetValueIsSet(false);
233
SetBuffer(DataBlock,sizeof(DataBlock));
234
SetValueIsSet(false);
236
237
KaxBlockVirtual::~KaxBlockVirtual()
238
if(GetBuffer() == DataBlock)
239
SetBuffer( NULL, 0 );
239
if(GetBuffer() == DataBlock)
240
SetBuffer( NULL, 0 );
242
243
filepos_t KaxBlockVirtual::UpdateSize(bool /* bSaveDefault */, bool /* bForceRender */)
244
assert(TrackNumber < 0x4000);
245
binary *cursor = EbmlBinary::GetBuffer();
247
if (TrackNumber < 0x80) {
248
assert(GetSize() >= 4);
249
*cursor++ = TrackNumber | 0x80; // set the first bit to 1
251
assert(GetSize() >= 5);
252
*cursor++ = (TrackNumber >> 8) | 0x40; // set the second bit to 1
253
*cursor++ = TrackNumber & 0xFF;
256
assert(ParentCluster != NULL);
257
int16 ActualTimecode = ParentCluster->GetBlockLocalTimecode(Timecode);
258
big_int16 b16(ActualTimecode);
262
*cursor++ = 0; // flags
245
assert(TrackNumber < 0x4000);
246
binary *cursor = EbmlBinary::GetBuffer();
248
if (TrackNumber < 0x80) {
249
assert(GetSize() >= 4);
250
*cursor++ = TrackNumber | 0x80; // set the first bit to 1
252
assert(GetSize() >= 5);
253
*cursor++ = (TrackNumber >> 8) | 0x40; // set the second bit to 1
254
*cursor++ = TrackNumber & 0xFF;
257
assert(ParentCluster != NULL);
258
int16 ActualTimecode = ParentCluster->GetBlockLocalTimecode(Timecode);
259
big_int16 b16(ActualTimecode);
263
*cursor++ = 0; // flags
266
267
#endif // MATROSKA_VERSION
269
\todo more optimisation is possible (render the Block head and don't copy the buffer in memory, care should be taken with the allocation of Data)
270
\todo the actual timecode to write should be retrieved from the Cluster from here
270
\todo more optimisation is possible (render the Block head and don't copy the buffer in memory, care should be taken with the allocation of Data)
271
\todo the actual timecode to write should be retrieved from the Cluster from here
272
273
filepos_t KaxInternalBlock::RenderData(IOCallback & output, bool /* bForceRender */, bool /* bSaveDefault */)
274
if (myBuffers.size() == 0) {
277
assert(TrackNumber < 0x4000);
278
binary BlockHead[5], *cursor = BlockHead;
281
if (myBuffers.size() == 1) {
283
mLacing = LACING_NONE;
285
if (mLacing == LACING_NONE)
286
mLacing = LACING_EBML; // supposedly the best of all
287
SetSize_(4 + 1); // 1 for the lacing head (number of laced elements)
289
if (TrackNumber > 0x80)
290
SetSize_(GetSize() + 1);
293
if (TrackNumber < 0x80) {
294
*cursor++ = TrackNumber | 0x80; // set the first bit to 1
296
*cursor++ = (TrackNumber >> 8) | 0x40; // set the second bit to 1
297
*cursor++ = TrackNumber & 0xFF;
300
assert(ParentCluster != NULL);
301
int16 ActualTimecode = ParentCluster->GetBlockLocalTimecode(Timecode);
302
big_int16 b16(ActualTimecode);
306
*cursor = 0; // flags
308
if (mLacing == LACING_AUTO) {
309
mLacing = GetBestLacingType();
341
output.writeFully(BlockHead, 4 + ((TrackNumber > 0x80) ? 1 : 0));
348
tmpValue = myBuffers.size()-1;
349
output.writeFully(&tmpValue, 1);
351
// set the size of each member in the lace
352
for (i=0; i<myBuffers.size()-1; i++) {
354
uint16 tmpSize = myBuffers[i]->Size();
355
while (tmpSize >= 0xFF) {
356
output.writeFully(&tmpValue, 1);
357
SetSize_(GetSize() + 1);
360
tmpValue = binary(tmpSize);
361
output.writeFully(&tmpValue, 1);
362
SetSize_(GetSize() + 1);
367
tmpValue = myBuffers.size()-1;
368
output.writeFully(&tmpValue, 1);
373
binary _FinalHead[8]; // 64 bits max coded size
375
_Size = myBuffers[0]->Size();
377
_CodedSize = CodedSizeLength(_Size, 0, IsFiniteSize());
379
// first size in the lace is not a signed
380
CodedValueLength(_Size, _CodedSize, _FinalHead);
381
output.writeFully(_FinalHead, _CodedSize);
382
SetSize_(GetSize() + _CodedSize);
384
// set the size of each member in the lace
385
for (i=1; i<myBuffers.size()-1; i++) {
386
_Size = int64(myBuffers[i]->Size()) - int64(myBuffers[i-1]->Size());
387
_CodedSize = CodedSizeLengthSigned(_Size, 0);
388
CodedValueLengthSigned(_Size, _CodedSize, _FinalHead);
389
output.writeFully(_FinalHead, _CodedSize);
390
SetSize_(GetSize() + _CodedSize);
396
tmpValue = myBuffers.size()-1;
397
output.writeFully(&tmpValue, 1);
405
// put the data of each frame
406
for (i=0; i<myBuffers.size(); i++) {
407
output.writeFully(myBuffers[i]->Buffer(), myBuffers[i]->Size());
408
SetSize_(GetSize() + myBuffers[i]->Size());
275
if (myBuffers.size() == 0) {
278
assert(TrackNumber < 0x4000);
279
binary BlockHead[5], *cursor = BlockHead;
282
if (myBuffers.size() == 1) {
284
mLacing = LACING_NONE;
286
if (mLacing == LACING_NONE)
287
mLacing = LACING_EBML; // supposedly the best of all
288
SetSize_(4 + 1); // 1 for the lacing head (number of laced elements)
290
if (TrackNumber > 0x80)
291
SetSize_(GetSize() + 1);
294
if (TrackNumber < 0x80) {
295
*cursor++ = TrackNumber | 0x80; // set the first bit to 1
297
*cursor++ = (TrackNumber >> 8) | 0x40; // set the second bit to 1
298
*cursor++ = TrackNumber & 0xFF;
301
assert(ParentCluster != NULL);
302
int16 ActualTimecode = ParentCluster->GetBlockLocalTimecode(Timecode);
303
big_int16 b16(ActualTimecode);
307
*cursor = 0; // flags
309
if (mLacing == LACING_AUTO) {
310
mLacing = GetBestLacingType();
341
output.writeFully(BlockHead, 4 + ((TrackNumber > 0x80) ? 1 : 0));
347
tmpValue = myBuffers.size()-1;
348
output.writeFully(&tmpValue, 1);
350
// set the size of each member in the lace
351
for (i=0; i<myBuffers.size()-1; i++) {
353
uint16 tmpSize = myBuffers[i]->Size();
354
while (tmpSize >= 0xFF) {
355
output.writeFully(&tmpValue, 1);
356
SetSize_(GetSize() + 1);
359
tmpValue = binary(tmpSize);
360
output.writeFully(&tmpValue, 1);
361
SetSize_(GetSize() + 1);
366
tmpValue = myBuffers.size()-1;
367
output.writeFully(&tmpValue, 1);
371
binary _FinalHead[8]; // 64 bits max coded size
373
_Size = myBuffers[0]->Size();
375
_CodedSize = CodedSizeLength(_Size, 0, IsFiniteSize());
377
// first size in the lace is not a signed
378
CodedValueLength(_Size, _CodedSize, _FinalHead);
379
output.writeFully(_FinalHead, _CodedSize);
380
SetSize_(GetSize() + _CodedSize);
382
// set the size of each member in the lace
383
for (i=1; i<myBuffers.size()-1; i++) {
384
_Size = int64(myBuffers[i]->Size()) - int64(myBuffers[i-1]->Size());
385
_CodedSize = CodedSizeLengthSigned(_Size, 0);
386
CodedValueLengthSigned(_Size, _CodedSize, _FinalHead);
387
output.writeFully(_FinalHead, _CodedSize);
388
SetSize_(GetSize() + _CodedSize);
394
tmpValue = myBuffers.size()-1;
395
output.writeFully(&tmpValue, 1);
403
// put the data of each frame
404
for (i=0; i<myBuffers.size(); i++) {
405
output.writeFully(myBuffers[i]->Buffer(), myBuffers[i]->Size());
406
SetSize_(GetSize() + myBuffers[i]->Size());
415
413
uint64 KaxInternalBlock::ReadInternalHead(IOCallback & input)
417
binary Buffer[5], *cursor = Buffer;
418
uint64 Result = input.read(cursor, 4);
422
// update internal values
423
TrackNumber = *cursor++;
424
if ((TrackNumber & 0x80) == 0) {
425
// there is extra data
426
if ((TrackNumber & 0x40) == 0) {
427
// We don't support track numbers that large !
430
Result += input.read(&Buffer[4], 1);
431
TrackNumber = (TrackNumber & 0x3F) << 8;
432
TrackNumber += *cursor++;
440
assert(ParentCluster != NULL);
441
Timecode = ParentCluster->GetBlockGlobalTimecode(int16(b16));
442
bLocalTimecodeUsed = false;
415
binary Buffer[5], *cursor = Buffer;
416
uint64 Result = input.read(cursor, 4);
420
// update internal values
421
TrackNumber = *cursor++;
422
if ((TrackNumber & 0x80) == 0) {
423
// there is extra data
424
if ((TrackNumber & 0x40) == 0) {
425
// We don't support track numbers that large !
428
Result += input.read(&Buffer[4], 1);
429
TrackNumber = (TrackNumber & 0x3F) << 8;
430
TrackNumber += *cursor++;
438
assert(ParentCluster != NULL);
439
Timecode = ParentCluster->GetBlockGlobalTimecode(int16(b16));
440
bLocalTimecodeUsed = false;
449
\todo better zero copy handling
447
\todo better zero copy handling
451
449
filepos_t KaxInternalBlock::ReadData(IOCallback & input, ScopeMode ReadFully)
455
FirstFrameLocation = input.getFilePointer(); // will be updated accordingly below
457
if (ReadFully == SCOPE_ALL_DATA)
459
Result = EbmlBinary::ReadData(input, ReadFully);
460
binary *cursor = EbmlBinary::GetBuffer();
461
uint8 BlockHeadSize = 4;
463
// update internal values
464
TrackNumber = *cursor++;
465
if ((TrackNumber & 0x80) == 0) {
466
// there is extra data
467
if ((TrackNumber & 0x40) == 0) {
468
// We don't support track numbers that large !
471
TrackNumber = (TrackNumber & 0x3F) << 8;
472
TrackNumber += *cursor++;
480
LocalTimecode = int16(b16);
481
bLocalTimecodeUsed = true;
484
if (EbmlId(*this) == EBML_ID(KaxSimpleBlock)) {
485
bIsKeyframe = (*cursor & 0x80) != 0;
486
bIsDiscardable = (*cursor & 0x01) != 0;
488
mInvisible = (*cursor & 0x08) >> 3;
489
mLacing = LacingType((*cursor++ & 0x06) >> 1);
491
// put all Frames in the list
492
if (mLacing == LACING_NONE) {
493
FirstFrameLocation += cursor - EbmlBinary::GetBuffer();
494
DataBuffer * soloFrame = new DataBuffer(cursor, GetSize() - BlockHeadSize);
495
myBuffers.push_back(soloFrame);
497
SizeList[0] = GetSize() - BlockHeadSize;
499
// read the number of frames in the lace
500
uint32 LastBufferSize = GetSize() - BlockHeadSize - 1; // 1 for number of frame
501
uint8 FrameNum = *cursor++; // number of frames in the lace - 1
502
// read the list of frame sizes
508
SizeList.resize(FrameNum + 1);
513
for (Index=0; Index<FrameNum; Index++) {
514
// get the size of the frame
517
FrameSize += uint8(*cursor);
519
} while (*cursor++ == 0xFF);
520
SizeList[Index] = FrameSize;
521
LastBufferSize -= FrameSize;
523
SizeList[Index] = LastBufferSize;
526
SizeRead = LastBufferSize;
527
FrameSize = ReadCodedSizeValue(cursor, SizeRead, SizeUnknown);
528
SizeList[0] = FrameSize;
530
LastBufferSize -= FrameSize + SizeRead;
532
for (Index=1; Index<FrameNum; Index++) {
533
// get the size of the frame
534
SizeRead = LastBufferSize;
535
FrameSize += ReadCodedSizeSignedValue(cursor, SizeRead, SizeUnknown);
536
SizeList[Index] = FrameSize;
538
LastBufferSize -= FrameSize + SizeRead;
540
SizeList[Index] = LastBufferSize;
543
for (Index=0; Index<=FrameNum; Index++) {
544
// get the size of the frame
545
SizeList[Index] = LastBufferSize / (FrameNum + 1);
548
default: // other lacing not supported
552
FirstFrameLocation += cursor - EbmlBinary::GetBuffer();
554
for (Index=0; Index<=FrameNum; Index++) {
555
DataBuffer * lacedFrame = new DataBuffer(cursor, SizeList[Index]);
556
myBuffers.push_back(lacedFrame);
557
cursor += SizeList[Index];
562
else if (ReadFully == SCOPE_PARTIAL_DATA)
565
Result = input.read(_TempHead, 5);
566
binary *cursor = _TempHead;
568
uint8 BlockHeadSize = 4;
570
// update internal values
571
TrackNumber = *cursor++;
572
if ((TrackNumber & 0x80) == 0) {
573
// there is extra data
574
if ((TrackNumber & 0x40) == 0) {
575
// We don't support track numbers that large !
578
TrackNumber = (TrackNumber & 0x3F) << 8;
579
TrackNumber += *cursor++;
587
LocalTimecode = int16(b16);
588
bLocalTimecodeUsed = true;
591
if (EbmlId(*this) == EBML_ID(KaxSimpleBlock)) {
592
bIsKeyframe = (*cursor & 0x80) != 0;
593
bIsDiscardable = (*cursor & 0x01) != 0;
595
mInvisible = (*cursor & 0x08) >> 3;
596
mLacing = LacingType((*cursor++ & 0x06) >> 1);
597
if (cursor == &_TempHead[4])
599
_TempHead[0] = _TempHead[4];
601
Result += input.read(_TempHead, 1);
604
FirstFrameLocation += cursor - _TempHead;
606
// put all Frames in the list
607
if (mLacing != LACING_NONE) {
608
// read the number of frames in the lace
609
uint32 LastBufferSize = GetSize() - BlockHeadSize - 1; // 1 for number of frame
610
uint8 FrameNum = _TempHead[0]; // number of frames in the lace - 1
611
// read the list of frame sizes
617
SizeList.resize(FrameNum + 1);
622
for (Index=0; Index<FrameNum; Index++) {
623
// get the size of the frame
626
Result += input.read(_TempHead, 1);
627
FrameSize += uint8(_TempHead[0]);
630
FirstFrameLocation++;
631
} while (_TempHead[0] == 0xFF);
633
FirstFrameLocation++;
634
SizeList[Index] = FrameSize;
635
LastBufferSize -= FrameSize;
637
SizeList[Index] = LastBufferSize;
640
SizeRead = LastBufferSize;
641
cursor = _tmpBuf = new binary[FrameNum*4]; /// \warning assume the mean size will be coded in less than 4 bytes
642
Result += input.read(cursor, FrameNum*4);
643
FrameSize = ReadCodedSizeValue(cursor, SizeRead, SizeUnknown);
644
SizeList[0] = FrameSize;
646
LastBufferSize -= FrameSize + SizeRead;
648
for (Index=1; Index<FrameNum; Index++) {
649
// get the size of the frame
650
SizeRead = LastBufferSize;
651
FrameSize += ReadCodedSizeSignedValue(cursor, SizeRead, SizeUnknown);
652
SizeList[Index] = FrameSize;
654
LastBufferSize -= FrameSize + SizeRead;
657
FirstFrameLocation += cursor - _tmpBuf;
659
SizeList[Index] = LastBufferSize;
663
for (Index=0; Index<=FrameNum; Index++) {
664
// get the size of the frame
665
SizeList[Index] = LastBufferSize / (FrameNum + 1);
668
default: // other lacing not supported
673
SizeList[0] = GetSize() - BlockHeadSize;
675
SetValueIsSet(false);
678
SetValueIsSet(false);
453
FirstFrameLocation = input.getFilePointer(); // will be updated accordingly below
455
SetValueIsSet(false);
458
if (ReadFully == SCOPE_ALL_DATA) {
459
Result = EbmlBinary::ReadData(input, ReadFully);
460
if (Result != GetSize())
461
throw SafeReadIOCallback::EndOfStreamX(GetSize() - Result);
463
binary *BufferStart = EbmlBinary::GetBuffer();
465
SafeReadIOCallback Mem(*this);
466
uint8 BlockHeadSize = 4;
468
// update internal values
469
TrackNumber = Mem.GetUInt8();
470
if ((TrackNumber & 0x80) == 0) {
471
// there is extra data
472
if ((TrackNumber & 0x40) == 0) {
473
// We don't support track numbers that large !
474
throw SafeReadIOCallback::EndOfStreamX(0);
476
TrackNumber = (TrackNumber & 0x3F) << 8;
477
TrackNumber += Mem.GetUInt8();
483
LocalTimecode = int16(Mem.GetUInt16BE());
484
bLocalTimecodeUsed = true;
486
uint8 Flags = Mem.GetUInt8();
487
if (EbmlId(*this) == EBML_ID(KaxSimpleBlock)) {
488
bIsKeyframe = (Flags & 0x80) != 0;
489
bIsDiscardable = (Flags & 0x01) != 0;
491
mInvisible = (Flags & 0x08) >> 3;
492
mLacing = LacingType((Flags & 0x06) >> 1);
494
// put all Frames in the list
495
if (mLacing == LACING_NONE) {
496
FirstFrameLocation += Mem.GetPosition();
497
DataBuffer * soloFrame = new DataBuffer(BufferStart + Mem.GetPosition(), GetSize() - BlockHeadSize);
498
myBuffers.push_back(soloFrame);
500
SizeList[0] = GetSize() - BlockHeadSize;
502
// read the number of frames in the lace
503
uint32 LastBufferSize = GetSize() - BlockHeadSize - 1; // 1 for number of frame
504
uint8 FrameNum = Mem.GetUInt8(); // number of frames in the lace - 1
505
// read the list of frame sizes
511
SizeList.resize(FrameNum + 1);
515
for (Index=0; Index<FrameNum; Index++) {
516
// get the size of the frame
520
Value = Mem.GetUInt8();
523
} while (Value == 0xFF);
524
SizeList[Index] = FrameSize;
525
LastBufferSize -= FrameSize;
527
SizeList[Index] = LastBufferSize;
530
SizeRead = LastBufferSize;
531
FrameSize = ReadCodedSizeValue(BufferStart + Mem.GetPosition(), SizeRead, SizeUnknown);
532
SizeList[0] = FrameSize;
534
LastBufferSize -= FrameSize + SizeRead;
536
for (Index=1; Index<FrameNum; Index++) {
537
// get the size of the frame
538
SizeRead = LastBufferSize;
539
FrameSize += ReadCodedSizeSignedValue(BufferStart + Mem.GetPosition(), SizeRead, SizeUnknown);
540
SizeList[Index] = FrameSize;
542
LastBufferSize -= FrameSize + SizeRead;
544
if (Index <= FrameNum) // Safety check if FrameNum == 0
545
SizeList[Index] = LastBufferSize;
548
for (Index=0; Index<=FrameNum; Index++) {
549
// get the size of the frame
550
SizeList[Index] = LastBufferSize / (FrameNum + 1);
553
default: // other lacing not supported
557
FirstFrameLocation += Mem.GetPosition();
559
for (Index=0; Index<=FrameNum; Index++) {
560
DataBuffer * lacedFrame = new DataBuffer(BufferStart + Mem.GetPosition(), SizeList[Index]);
561
myBuffers.push_back(lacedFrame);
562
Mem.Skip(SizeList[Index]);
566
binary *BufferEnd = BufferStart + GetSize();
567
size_t NumFrames = myBuffers.size();
569
// Sanity checks for frame pointers and boundaries.
570
for (size_t Index = 0; Index < NumFrames; ++Index) {
571
binary *FrameStart = myBuffers[Index]->Buffer();
572
binary *FrameEnd = FrameStart + myBuffers[Index]->Size();
573
binary *ExpectedEnd = (Index + 1) < NumFrames ? myBuffers[Index + 1]->Buffer() : BufferEnd;
575
if ((FrameStart < BufferStart) || (FrameEnd > BufferEnd) || (FrameEnd != ExpectedEnd))
576
throw SafeReadIOCallback::EndOfStreamX(0);
580
} else if (ReadFully == SCOPE_PARTIAL_DATA) {
582
Result = input.read(_TempHead, 5);
584
throw SafeReadIOCallback::EndOfStreamX(0);
585
binary *cursor = _TempHead;
587
uint8 BlockHeadSize = 4;
589
// update internal values
590
TrackNumber = *cursor++;
591
if ((TrackNumber & 0x80) == 0) {
592
// there is extra data
593
if ((TrackNumber & 0x40) == 0) {
594
// We don't support track numbers that large !
597
TrackNumber = (TrackNumber & 0x3F) << 8;
598
TrackNumber += *cursor++;
606
LocalTimecode = int16(b16);
607
bLocalTimecodeUsed = true;
610
if (EbmlId(*this) == EBML_ID(KaxSimpleBlock)) {
611
bIsKeyframe = (*cursor & 0x80) != 0;
612
bIsDiscardable = (*cursor & 0x01) != 0;
614
mInvisible = (*cursor & 0x08) >> 3;
615
mLacing = LacingType((*cursor++ & 0x06) >> 1);
616
if (cursor == &_TempHead[4]) {
617
_TempHead[0] = _TempHead[4];
619
Result += input.read(_TempHead, 1);
622
FirstFrameLocation += cursor - _TempHead;
624
// put all Frames in the list
625
if (mLacing != LACING_NONE) {
626
// read the number of frames in the lace
627
uint32 LastBufferSize = GetSize() - BlockHeadSize - 1; // 1 for number of frame
628
uint8 FrameNum = _TempHead[0]; // number of frames in the lace - 1
629
// read the list of frame sizes
635
SizeList.resize(FrameNum + 1);
639
for (Index=0; Index<FrameNum; Index++) {
640
// get the size of the frame
643
Result += input.read(_TempHead, 1);
644
FrameSize += uint8(_TempHead[0]);
647
FirstFrameLocation++;
648
} while (_TempHead[0] == 0xFF);
650
FirstFrameLocation++;
651
SizeList[Index] = FrameSize;
652
LastBufferSize -= FrameSize;
654
SizeList[Index] = LastBufferSize;
657
SizeRead = LastBufferSize;
658
cursor = _tmpBuf = new binary[FrameNum*4]; /// \warning assume the mean size will be coded in less than 4 bytes
659
Result += input.read(cursor, FrameNum*4);
660
FrameSize = ReadCodedSizeValue(cursor, SizeRead, SizeUnknown);
661
SizeList[0] = FrameSize;
663
LastBufferSize -= FrameSize + SizeRead;
665
for (Index=1; Index<FrameNum; Index++) {
666
// get the size of the frame
667
SizeRead = LastBufferSize;
668
FrameSize += ReadCodedSizeSignedValue(cursor, SizeRead, SizeUnknown);
669
SizeList[Index] = FrameSize;
671
LastBufferSize -= FrameSize + SizeRead;
674
FirstFrameLocation += cursor - _tmpBuf;
676
SizeList[Index] = LastBufferSize;
680
for (Index=0; Index<=FrameNum; Index++) {
681
// get the size of the frame
682
SizeList[Index] = LastBufferSize / (FrameNum + 1);
685
default: // other lacing not supported
690
SizeList[0] = GetSize() - BlockHeadSize;
692
SetValueIsSet(false);
695
SetValueIsSet(false);
699
} catch (SafeReadIOCallback::EndOfStreamX &) {
700
SetValueIsSet(false);
702
std::memset(EbmlBinary::GetBuffer(), 0, GetSize());
708
bLocalTimecodeUsed = false;
709
FirstFrameLocation = 0;
685
717
bool KaxBlockGroup::AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, LacingType lacing)
687
KaxBlock & theBlock = GetChild<KaxBlock>(*this);
688
assert(ParentCluster != NULL);
689
theBlock.SetParent(*ParentCluster);
690
ParentTrack = &track;
691
return theBlock.AddFrame(track, timecode, buffer, lacing);
719
KaxBlock & theBlock = GetChild<KaxBlock>(*this);
720
assert(ParentCluster != NULL);
721
theBlock.SetParent(*ParentCluster);
722
ParentTrack = &track;
723
return theBlock.AddFrame(track, timecode, buffer, lacing);
694
726
bool KaxBlockGroup::AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, const KaxBlockGroup & PastBlock, LacingType lacing)
696
// assert(past_timecode < 0);
698
KaxBlock & theBlock = GetChild<KaxBlock>(*this);
699
assert(ParentCluster != NULL);
700
theBlock.SetParent(*ParentCluster);
701
ParentTrack = &track;
702
bool bRes = theBlock.AddFrame(track, timecode, buffer, lacing);
704
KaxReferenceBlock & thePastRef = GetChild<KaxReferenceBlock>(*this);
705
thePastRef.SetReferencedBlock(PastBlock);
706
thePastRef.SetParentBlock(*this);
728
// assert(past_timecode < 0);
730
KaxBlock & theBlock = GetChild<KaxBlock>(*this);
731
assert(ParentCluster != NULL);
732
theBlock.SetParent(*ParentCluster);
733
ParentTrack = &track;
734
bool bRes = theBlock.AddFrame(track, timecode, buffer, lacing);
736
KaxReferenceBlock & thePastRef = GetChild<KaxReferenceBlock>(*this);
737
thePastRef.SetReferencedBlock(PastBlock);
738
thePastRef.SetParentBlock(*this);
711
743
bool KaxBlockGroup::AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, const KaxBlockGroup & PastBlock, const KaxBlockGroup & ForwBlock, LacingType lacing)
713
// assert(past_timecode < 0);
715
// assert(forw_timecode > 0);
717
KaxBlock & theBlock = GetChild<KaxBlock>(*this);
718
assert(ParentCluster != NULL);
719
theBlock.SetParent(*ParentCluster);
720
ParentTrack = &track;
721
bool bRes = theBlock.AddFrame(track, timecode, buffer, lacing);
723
KaxReferenceBlock & thePastRef = GetChild<KaxReferenceBlock>(*this);
724
thePastRef.SetReferencedBlock(PastBlock);
725
thePastRef.SetParentBlock(*this);
727
KaxReferenceBlock & theFutureRef = AddNewChild<KaxReferenceBlock>(*this);
728
theFutureRef.SetReferencedBlock(ForwBlock);
729
theFutureRef.SetParentBlock(*this);
745
// assert(past_timecode < 0);
747
// assert(forw_timecode > 0);
749
KaxBlock & theBlock = GetChild<KaxBlock>(*this);
750
assert(ParentCluster != NULL);
751
theBlock.SetParent(*ParentCluster);
752
ParentTrack = &track;
753
bool bRes = theBlock.AddFrame(track, timecode, buffer, lacing);
755
KaxReferenceBlock & thePastRef = GetChild<KaxReferenceBlock>(*this);
756
thePastRef.SetReferencedBlock(PastBlock);
757
thePastRef.SetParentBlock(*this);
759
KaxReferenceBlock & theFutureRef = AddNewChild<KaxReferenceBlock>(*this);
760
theFutureRef.SetReferencedBlock(ForwBlock);
761
theFutureRef.SetParentBlock(*this);
734
766
bool KaxBlockGroup::AddFrame(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, const KaxBlockBlob * PastBlock, const KaxBlockBlob * ForwBlock, LacingType lacing)
736
KaxBlock & theBlock = GetChild<KaxBlock>(*this);
737
assert(ParentCluster != NULL);
738
theBlock.SetParent(*ParentCluster);
739
ParentTrack = &track;
740
bool bRes = theBlock.AddFrame(track, timecode, buffer, lacing);
742
if (PastBlock != NULL)
744
KaxReferenceBlock & thePastRef = GetChild<KaxReferenceBlock>(*this);
745
thePastRef.SetReferencedBlock(PastBlock);
746
thePastRef.SetParentBlock(*this);
749
if (ForwBlock != NULL)
751
KaxReferenceBlock & theFutureRef = AddNewChild<KaxReferenceBlock>(*this);
752
theFutureRef.SetReferencedBlock(ForwBlock);
753
theFutureRef.SetParentBlock(*this);
768
KaxBlock & theBlock = GetChild<KaxBlock>(*this);
769
assert(ParentCluster != NULL);
770
theBlock.SetParent(*ParentCluster);
771
ParentTrack = &track;
772
bool bRes = theBlock.AddFrame(track, timecode, buffer, lacing);
774
if (PastBlock != NULL) {
775
KaxReferenceBlock & thePastRef = GetChild<KaxReferenceBlock>(*this);
776
thePastRef.SetReferencedBlock(PastBlock);
777
thePastRef.SetParentBlock(*this);
780
if (ForwBlock != NULL) {
781
KaxReferenceBlock & theFutureRef = AddNewChild<KaxReferenceBlock>(*this);
782
theFutureRef.SetReferencedBlock(ForwBlock);
783
theFutureRef.SetParentBlock(*this);
760
\todo we may cache the reference to the timecode block
790
\todo we may cache the reference to the timecode block
762
792
uint64 KaxBlockGroup::GlobalTimecode() const
764
assert(ParentCluster != NULL); // impossible otherwise
765
KaxInternalBlock & MyBlock = *static_cast<KaxBlock *>(this->FindElt(EBML_INFO(KaxBlock)));
766
return MyBlock.GlobalTimecode();
794
assert(ParentCluster != NULL); // impossible otherwise
795
KaxInternalBlock & MyBlock = *static_cast<KaxBlock *>(this->FindElt(EBML_INFO(KaxBlock)));
796
return MyBlock.GlobalTimecode();
770
800
uint16 KaxBlockGroup::TrackNumber() const
772
KaxInternalBlock & MyBlock = *static_cast<KaxBlock *>(this->FindElt(EBML_INFO(KaxBlock)));
773
return MyBlock.TrackNum();
802
KaxInternalBlock & MyBlock = *static_cast<KaxBlock *>(this->FindElt(EBML_INFO(KaxBlock)));
803
return MyBlock.TrackNum();
776
806
uint64 KaxBlockGroup::ClusterPosition() const
778
assert(ParentCluster != NULL); // impossible otherwise
779
return ParentCluster->GetPosition();
808
assert(ParentCluster != NULL); // impossible otherwise
809
return ParentCluster->GetPosition();
782
812
uint64 KaxInternalBlock::ClusterPosition() const
784
assert(ParentCluster != NULL); // impossible otherwise
785
return ParentCluster->GetPosition();
814
assert(ParentCluster != NULL); // impossible otherwise
815
return ParentCluster->GetPosition();
788
818
unsigned int KaxBlockGroup::ReferenceCount() const
790
unsigned int Result = 0;
791
KaxReferenceBlock * MyBlockAdds = static_cast<KaxReferenceBlock *>(FindFirstElt(EBML_INFO(KaxReferenceBlock)));
792
if (MyBlockAdds != NULL) {
794
while ((MyBlockAdds = static_cast<KaxReferenceBlock *>(FindNextElt(*MyBlockAdds))) != NULL)
820
unsigned int Result = 0;
821
KaxReferenceBlock * MyBlockAdds = static_cast<KaxReferenceBlock *>(FindFirstElt(EBML_INFO(KaxReferenceBlock)));
822
if (MyBlockAdds != NULL) {
824
while ((MyBlockAdds = static_cast<KaxReferenceBlock *>(FindNextElt(*MyBlockAdds))) != NULL) {
802
831
const KaxReferenceBlock & KaxBlockGroup::Reference(unsigned int Index) const
804
KaxReferenceBlock * MyBlockAdds = static_cast<KaxReferenceBlock *>(FindFirstElt(EBML_INFO(KaxReferenceBlock)));
805
assert(MyBlockAdds != NULL); // call of a non existing reference
808
MyBlockAdds = static_cast<KaxReferenceBlock *>(FindNextElt(*MyBlockAdds));
809
assert(MyBlockAdds != NULL);
833
KaxReferenceBlock * MyBlockAdds = static_cast<KaxReferenceBlock *>(FindFirstElt(EBML_INFO(KaxReferenceBlock)));
834
assert(MyBlockAdds != NULL); // call of a non existing reference
837
MyBlockAdds = static_cast<KaxReferenceBlock *>(FindNextElt(*MyBlockAdds));
838
assert(MyBlockAdds != NULL);
815
844
void KaxBlockGroup::ReleaseFrames()
817
KaxInternalBlock & MyBlock = *static_cast<KaxBlock *>(this->FindElt(EBML_INFO(KaxBlock)));
818
MyBlock.ReleaseFrames();
846
KaxInternalBlock & MyBlock = *static_cast<KaxBlock *>(this->FindElt(EBML_INFO(KaxBlock)));
847
MyBlock.ReleaseFrames();
821
850
void KaxInternalBlock::ReleaseFrames()
823
// free the allocated Frames
825
for (i=myBuffers.size()-1; i>=0; i--) {
826
if (myBuffers[i] != NULL) {
827
myBuffers[i]->FreeBuffer(*myBuffers[i]);
852
// free the allocated Frames
854
for (i=myBuffers.size()-1; i>=0; i--) {
855
if (myBuffers[i] != NULL) {
856
myBuffers[i]->FreeBuffer(*myBuffers[i]);
834
863
void KaxBlockGroup::SetBlockDuration(uint64 TimeLength)
836
assert(ParentTrack != NULL);
837
int64 scale = ParentTrack->GlobalTimecodeScale();
838
KaxBlockDuration & myDuration = *static_cast<KaxBlockDuration *>(FindFirstElt(EBML_INFO(KaxBlockDuration), true));
839
*(static_cast<EbmlUInteger *>(&myDuration)) = TimeLength / uint64(scale);
865
assert(ParentTrack != NULL);
866
int64 scale = ParentTrack->GlobalTimecodeScale();
867
KaxBlockDuration & myDuration = *static_cast<KaxBlockDuration *>(FindFirstElt(EBML_INFO(KaxBlockDuration), true));
868
*(static_cast<EbmlUInteger *>(&myDuration)) = TimeLength / uint64(scale);
842
871
bool KaxBlockGroup::GetBlockDuration(uint64 &TheTimecode) const
844
KaxBlockDuration * myDuration = static_cast<KaxBlockDuration *>(FindElt(EBML_INFO(KaxBlockDuration)));
845
if (myDuration == NULL) {
873
KaxBlockDuration * myDuration = static_cast<KaxBlockDuration *>(FindElt(EBML_INFO(KaxBlockDuration)));
874
if (myDuration == NULL) {
849
assert(ParentTrack != NULL);
850
TheTimecode = uint64(*myDuration) * ParentTrack->GlobalTimecodeScale();
878
assert(ParentTrack != NULL);
879
TheTimecode = uint64(*myDuration) * ParentTrack->GlobalTimecodeScale();
854
883
KaxBlockGroup::operator KaxInternalBlock &() {
855
KaxBlock & theBlock = GetChild<KaxBlock>(*this);
884
KaxBlock & theBlock = GetChild<KaxBlock>(*this);
859
888
void KaxBlockGroup::SetParent(KaxCluster & aParentCluster) {
860
ParentCluster = &aParentCluster;
861
KaxBlock & theBlock = GetChild<KaxBlock>(*this);
862
theBlock.SetParent( aParentCluster );
889
ParentCluster = &aParentCluster;
890
KaxBlock & theBlock = GetChild<KaxBlock>(*this);
891
theBlock.SetParent( aParentCluster );
865
894
void KaxSimpleBlock::SetParent(KaxCluster & aParentCluster) {
866
KaxInternalBlock::SetParent( aParentCluster );
895
KaxInternalBlock::SetParent( aParentCluster );
869
898
void KaxInternalBlock::SetParent(KaxCluster & aParentCluster)
871
ParentCluster = &aParentCluster;
872
if (bLocalTimecodeUsed) {
873
Timecode = aParentCluster.GetBlockGlobalTimecode(LocalTimecode);
874
bLocalTimecodeUsed = false;
900
ParentCluster = &aParentCluster;
901
if (bLocalTimecodeUsed) {
902
Timecode = aParentCluster.GetBlockGlobalTimecode(LocalTimecode);
903
bLocalTimecodeUsed = false;
878
907
int64 KaxInternalBlock::GetDataPosition(size_t FrameNumber)
882
if (ValueIsSet() && FrameNumber < SizeList.size())
884
_Result = FirstFrameLocation;
889
_Result += SizeList[_Idx++];
911
if (ValueIsSet() && FrameNumber < SizeList.size()) {
912
_Result = FirstFrameLocation;
915
while(FrameNumber--) {
916
_Result += SizeList[_Idx++];
896
923
int64 KaxInternalBlock::GetFrameSize(size_t FrameNumber)
900
if (/*bValueIsSet &&*/ FrameNumber < SizeList.size())
902
_Result = SizeList[FrameNumber];
927
if (/*bValueIsSet &&*/ FrameNumber < SizeList.size()) {
928
_Result = SizeList[FrameNumber];
908
934
KaxBlockBlob::operator KaxBlockGroup &()
910
assert(!bUseSimpleBlock);
936
assert(!bUseSimpleBlock);
915
941
KaxBlockBlob::operator const KaxBlockGroup &() const
917
assert(!bUseSimpleBlock);
943
assert(!bUseSimpleBlock);
922
948
KaxBlockBlob::operator KaxInternalBlock &()
925
951
#if MATROSKA_VERSION >= 2
927
return *Block.simpleblock;
953
return *Block.simpleblock;
933
959
KaxBlockBlob::operator const KaxInternalBlock &() const
936
962
#if MATROSKA_VERSION >= 2
938
return *Block.simpleblock;
964
return *Block.simpleblock;
944
970
#if MATROSKA_VERSION >= 2
945
971
KaxBlockBlob::operator KaxSimpleBlock &()
947
assert(bUseSimpleBlock);
948
assert(Block.simpleblock);
949
return *Block.simpleblock;
973
assert(bUseSimpleBlock);
974
assert(Block.simpleblock);
975
return *Block.simpleblock;
953
979
bool KaxBlockBlob::AddFrameAuto(const KaxTrackEntry & track, uint64 timecode, DataBuffer & buffer, LacingType lacing, const KaxBlockBlob * PastBlock, const KaxBlockBlob * ForwBlock)
955
bool bResult = false;
981
bool bResult = false;
956
982
#if MATROSKA_VERSION >= 2
957
if ((SimpleBlockMode == BLOCK_BLOB_ALWAYS_SIMPLE) || (SimpleBlockMode == BLOCK_BLOB_SIMPLE_AUTO && PastBlock == NULL && ForwBlock == NULL)) {
958
assert(bUseSimpleBlock == true);
959
if (Block.simpleblock == NULL) {
960
Block.simpleblock = new KaxSimpleBlock();
961
Block.simpleblock->SetParent(*ParentCluster);
983
if ((SimpleBlockMode == BLOCK_BLOB_ALWAYS_SIMPLE) || (SimpleBlockMode == BLOCK_BLOB_SIMPLE_AUTO && PastBlock == NULL && ForwBlock == NULL)) {
984
assert(bUseSimpleBlock == true);
985
if (Block.simpleblock == NULL) {
986
Block.simpleblock = new KaxSimpleBlock();
987
Block.simpleblock->SetParent(*ParentCluster);
964
bResult = Block.simpleblock->AddFrame(track, timecode, buffer, lacing);
965
if (PastBlock == NULL && ForwBlock == NULL) {
966
Block.simpleblock->SetKeyframe(true);
967
Block.simpleblock->SetDiscardable(false);
969
Block.simpleblock->SetKeyframe(false);
970
if ((ForwBlock == NULL || ((const KaxInternalBlock &)*ForwBlock).GlobalTimecode() <= timecode) &&
971
(PastBlock == NULL || ((const KaxInternalBlock &)*PastBlock).GlobalTimecode() <= timecode))
972
Block.simpleblock->SetDiscardable(false);
974
Block.simpleblock->SetDiscardable(true);
990
bResult = Block.simpleblock->AddFrame(track, timecode, buffer, lacing);
991
if (PastBlock == NULL && ForwBlock == NULL) {
992
Block.simpleblock->SetKeyframe(true);
993
Block.simpleblock->SetDiscardable(false);
995
Block.simpleblock->SetKeyframe(false);
996
if ((ForwBlock == NULL || ((const KaxInternalBlock &)*ForwBlock).GlobalTimecode() <= timecode) &&
997
(PastBlock == NULL || ((const KaxInternalBlock &)*PastBlock).GlobalTimecode() <= timecode))
998
Block.simpleblock->SetDiscardable(false);
1000
Block.simpleblock->SetDiscardable(true);
980
if (ReplaceSimpleByGroup()) {
981
bResult = Block.group->AddFrame(track, timecode, buffer, PastBlock, ForwBlock, lacing);
1005
if (ReplaceSimpleByGroup())
1006
bResult = Block.group->AddFrame(track, timecode, buffer, PastBlock, ForwBlock, lacing);
988
1011
void KaxBlockBlob::SetParent(KaxCluster & parent_clust)
990
ParentCluster = &parent_clust;
1013
ParentCluster = &parent_clust;
993
1016
void KaxBlockBlob::SetBlockDuration(uint64 TimeLength)
995
if (ReplaceSimpleByGroup())
996
Block.group->SetBlockDuration(TimeLength);
1018
if (ReplaceSimpleByGroup())
1019
Block.group->SetBlockDuration(TimeLength);
999
1022
bool KaxBlockBlob::ReplaceSimpleByGroup()
1001
if (SimpleBlockMode== BLOCK_BLOB_ALWAYS_SIMPLE)
1024
if (SimpleBlockMode== BLOCK_BLOB_ALWAYS_SIMPLE)
1004
if (!bUseSimpleBlock) {
1005
if (Block.group == NULL) {
1006
Block.group = new KaxBlockGroup();
1027
if (!bUseSimpleBlock) {
1028
if (Block.group == NULL) {
1029
Block.group = new KaxBlockGroup();
1009
1032
#if MATROSKA_VERSION >= 2
1013
if (Block.simpleblock != NULL) {
1014
KaxSimpleBlock *old_simpleblock = Block.simpleblock;
1015
Block.group = new KaxBlockGroup();
1016
// _TODO_ : move all the data to the blockgroup
1018
// -> while(frame) AddFrame(myBuffer)
1019
delete old_simpleblock;
1021
Block.group = new KaxBlockGroup();
1035
if (Block.simpleblock != NULL) {
1036
KaxSimpleBlock *old_simpleblock = Block.simpleblock;
1037
Block.group = new KaxBlockGroup();
1038
// _TODO_ : move all the data to the blockgroup
1040
// -> while(frame) AddFrame(myBuffer)
1041
delete old_simpleblock;
1043
Block.group = new KaxBlockGroup();
1025
if (ParentCluster != NULL)
1026
Block.group->SetParent(*ParentCluster);
1047
if (ParentCluster != NULL)
1048
Block.group->SetParent(*ParentCluster);
1028
bUseSimpleBlock = false;
1050
bUseSimpleBlock = false;
1032
1054
void KaxBlockBlob::SetBlockGroup( KaxBlockGroup &BlockRef )
1034
assert(!bUseSimpleBlock);
1035
Block.group = &BlockRef;
1056
assert(!bUseSimpleBlock);
1057
Block.group = &BlockRef;
1038
1060
filepos_t KaxBlockVirtual::ReadData(IOCallback & input, ScopeMode /* ReadFully */)
1040
input.setFilePointer(SizePosition + CodedSizeLength(Size, SizeLength, bSizeIsFinite) + Size, seek_beginning);
1062
input.setFilePointer(SizePosition + CodedSizeLength(Size, SizeLength, bSizeIsFinite) + Size, seek_beginning);
1044
1066
END_LIBMATROSKA_NAMESPACE