mkvmuxer: fix DiscardPadding
DiscardPadding is a signed int. this change fixes 2 things: - allows negative values for discard padding - fixes cases where an unsigned value would be written such that on read the sign would be flipped Change-Id: I9418da7a22c09768e02d5b61da8d01c2bccb5dee
This commit is contained in:
10
mkvmuxer.cpp
10
mkvmuxer.cpp
@@ -1636,7 +1636,7 @@ bool Cluster::DoWriteBlockWithDiscardPadding(
|
|||||||
const uint8* frame, uint64 length, int64 discard_padding,
|
const uint8* frame, uint64 length, int64 discard_padding,
|
||||||
uint64 track_number, uint64 abs_timecode, uint64 generic_arg,
|
uint64 track_number, uint64 abs_timecode, uint64 generic_arg,
|
||||||
WriteBlockDiscardPadding write_block) {
|
WriteBlockDiscardPadding write_block) {
|
||||||
if (frame == NULL || length == 0 || discard_padding <= 0)
|
if (frame == NULL || length == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!IsValidTrackNumber(track_number))
|
if (!IsValidTrackNumber(track_number))
|
||||||
@@ -2430,7 +2430,7 @@ bool Segment::AddFrameWithDiscardPadding(const uint8* frame, uint64 length,
|
|||||||
int64 discard_padding,
|
int64 discard_padding,
|
||||||
uint64 track_number, uint64 timestamp,
|
uint64 track_number, uint64 timestamp,
|
||||||
bool is_key) {
|
bool is_key) {
|
||||||
if (frame == NULL || discard_padding <= 0)
|
if (frame == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!CheckHeaderInfo())
|
if (!CheckHeaderInfo())
|
||||||
@@ -2547,7 +2547,7 @@ bool Segment::AddGenericFrame(const Frame* frame) {
|
|||||||
frame->frame(), frame->length(), frame->additional(),
|
frame->frame(), frame->length(), frame->additional(),
|
||||||
frame->additional_length(), frame->add_id(), frame->track_number(),
|
frame->additional_length(), frame->add_id(), frame->track_number(),
|
||||||
frame->timestamp(), frame->is_key());
|
frame->timestamp(), frame->is_key());
|
||||||
} else if (frame->discard_padding() > 0) {
|
} else if (frame->discard_padding() != 0) {
|
||||||
return AddFrameWithDiscardPadding(
|
return AddFrameWithDiscardPadding(
|
||||||
frame->frame(), frame->length(), frame->discard_padding(),
|
frame->frame(), frame->length(), frame->discard_padding(),
|
||||||
frame->track_number(), frame->timestamp(), frame->is_key());
|
frame->track_number(), frame->timestamp(), frame->is_key());
|
||||||
@@ -3025,7 +3025,7 @@ int Segment::WriteFramesAll() {
|
|||||||
const uint64 frame_timestamp = frame->timestamp(); // ns
|
const uint64 frame_timestamp = frame->timestamp(); // ns
|
||||||
const uint64 frame_timecode = frame_timestamp / timecode_scale;
|
const uint64 frame_timecode = frame_timestamp / timecode_scale;
|
||||||
|
|
||||||
if (frame->discard_padding() > 0) {
|
if (frame->discard_padding() != 0) {
|
||||||
if (!cluster->AddFrameWithDiscardPadding(
|
if (!cluster->AddFrameWithDiscardPadding(
|
||||||
frame->frame(), frame->length(), frame->discard_padding(),
|
frame->frame(), frame->length(), frame->discard_padding(),
|
||||||
frame->track_number(), frame_timecode, frame->is_key())) {
|
frame->track_number(), frame_timecode, frame->is_key())) {
|
||||||
@@ -3085,7 +3085,7 @@ bool Segment::WriteFramesLessThan(uint64 timestamp) {
|
|||||||
const uint64 frame_timecode = frame_timestamp / timecode_scale;
|
const uint64 frame_timecode = frame_timestamp / timecode_scale;
|
||||||
const int64 discard_padding = frame_prev->discard_padding();
|
const int64 discard_padding = frame_prev->discard_padding();
|
||||||
|
|
||||||
if (discard_padding > 0) {
|
if (discard_padding != 0) {
|
||||||
if (!cluster->AddFrameWithDiscardPadding(
|
if (!cluster->AddFrameWithDiscardPadding(
|
||||||
frame_prev->frame(), frame_prev->length(), discard_padding,
|
frame_prev->frame(), frame_prev->length(), discard_padding,
|
||||||
frame_prev->track_number(), frame_timecode,
|
frame_prev->track_number(), frame_timecode,
|
||||||
|
|||||||
@@ -72,6 +72,13 @@ int32 GetUIntSize(uint64 value) {
|
|||||||
return 8;
|
return 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32 GetIntSize(int64 value) {
|
||||||
|
// Doubling the requested value ensures positive values with their high bit
|
||||||
|
// set are written with 0-padding to avoid flipping the signedness.
|
||||||
|
const uint64 v = (value < 0) ? value ^ -1LL : value;
|
||||||
|
return GetUIntSize(2 * v);
|
||||||
|
}
|
||||||
|
|
||||||
uint64 EbmlMasterElementSize(uint64 type, uint64 value) {
|
uint64 EbmlMasterElementSize(uint64 type, uint64 value) {
|
||||||
// Size of EBML ID
|
// Size of EBML ID
|
||||||
int32 ebml_size = GetUIntSize(type);
|
int32 ebml_size = GetUIntSize(type);
|
||||||
@@ -83,7 +90,16 @@ uint64 EbmlMasterElementSize(uint64 type, uint64 value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint64 EbmlElementSize(uint64 type, int64 value) {
|
uint64 EbmlElementSize(uint64 type, int64 value) {
|
||||||
return EbmlElementSize(type, static_cast<uint64>(value));
|
// Size of EBML ID
|
||||||
|
int32 ebml_size = GetUIntSize(type);
|
||||||
|
|
||||||
|
// Datasize
|
||||||
|
ebml_size += GetIntSize(value);
|
||||||
|
|
||||||
|
// Size of Datasize
|
||||||
|
ebml_size++;
|
||||||
|
|
||||||
|
return ebml_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 EbmlElementSize(uint64 type, uint64 value) {
|
uint64 EbmlElementSize(uint64 type, uint64 value) {
|
||||||
@@ -592,7 +608,7 @@ uint64 WriteBlockWithDiscardPadding(IMkvWriter* writer, const uint8* data,
|
|||||||
uint64 length, int64 discard_padding,
|
uint64 length, int64 discard_padding,
|
||||||
uint64 track_number, int64 timecode,
|
uint64 track_number, int64 timecode,
|
||||||
uint64 is_key) {
|
uint64 is_key) {
|
||||||
if (!data || length < 1 || discard_padding <= 0)
|
if (!data || length < 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
const uint64 block_payload_size = 4 + length;
|
const uint64 block_payload_size = 4 + length;
|
||||||
@@ -630,7 +646,7 @@ uint64 WriteBlockWithDiscardPadding(IMkvWriter* writer, const uint8* data,
|
|||||||
if (WriteID(writer, kMkvDiscardPadding))
|
if (WriteID(writer, kMkvDiscardPadding))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
const uint64 size = GetUIntSize(discard_padding);
|
const uint64 size = GetIntSize(discard_padding);
|
||||||
if (WriteUInt(writer, size))
|
if (WriteUInt(writer, size))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user