Merge "Elements and functions to support BlockAdditional"
This commit is contained in:
committed by
Gerrit Code Review
commit
05912e8a96
173
mkvmuxer.cpp
173
mkvmuxer.cpp
@@ -460,6 +460,7 @@ Track::Track(unsigned int* seed)
|
|||||||
: codec_id_(NULL),
|
: codec_id_(NULL),
|
||||||
codec_private_(NULL),
|
codec_private_(NULL),
|
||||||
language_(NULL),
|
language_(NULL),
|
||||||
|
max_block_additional_id_(0),
|
||||||
name_(NULL),
|
name_(NULL),
|
||||||
number_(0),
|
number_(0),
|
||||||
type_(0),
|
type_(0),
|
||||||
@@ -535,6 +536,8 @@ uint64 Track::PayloadSize() const {
|
|||||||
size += EbmlElementSize(kMkvLanguage, language_);
|
size += EbmlElementSize(kMkvLanguage, language_);
|
||||||
if (name_)
|
if (name_)
|
||||||
size += EbmlElementSize(kMkvName, name_);
|
size += EbmlElementSize(kMkvName, name_);
|
||||||
|
if (max_block_additional_id_)
|
||||||
|
size += EbmlElementSize(kMkvMaxBlockAdditionID, max_block_additional_id_);
|
||||||
|
|
||||||
if (content_encoding_entries_size_ > 0) {
|
if (content_encoding_entries_size_ > 0) {
|
||||||
uint64 content_encodings_size = 0;
|
uint64 content_encodings_size = 0;
|
||||||
@@ -581,6 +584,8 @@ bool Track::Write(IMkvWriter* writer) const {
|
|||||||
size += EbmlElementSize(kMkvLanguage, language_);
|
size += EbmlElementSize(kMkvLanguage, language_);
|
||||||
if (name_)
|
if (name_)
|
||||||
size += EbmlElementSize(kMkvName, name_);
|
size += EbmlElementSize(kMkvName, name_);
|
||||||
|
if (max_block_additional_id_)
|
||||||
|
size += EbmlElementSize(kMkvMaxBlockAdditionID, max_block_additional_id_);
|
||||||
|
|
||||||
const int64 payload_position = writer->Position();
|
const int64 payload_position = writer->Position();
|
||||||
if (payload_position < 0)
|
if (payload_position < 0)
|
||||||
@@ -592,6 +597,11 @@ bool Track::Write(IMkvWriter* writer) const {
|
|||||||
return false;
|
return false;
|
||||||
if (!WriteEbmlElement(writer, kMkvTrackType, type_))
|
if (!WriteEbmlElement(writer, kMkvTrackType, type_))
|
||||||
return false;
|
return false;
|
||||||
|
if (max_block_additional_id_)
|
||||||
|
if (!WriteEbmlElement(writer,
|
||||||
|
kMkvMaxBlockAdditionID,
|
||||||
|
max_block_additional_id_))
|
||||||
|
return false;
|
||||||
if (codec_id_) {
|
if (codec_id_) {
|
||||||
if (!WriteEbmlElement(writer, kMkvCodecID, codec_id_))
|
if (!WriteEbmlElement(writer, kMkvCodecID, codec_id_))
|
||||||
return false;
|
return false;
|
||||||
@@ -719,6 +729,7 @@ VideoTrack::VideoTrack(unsigned int* seed)
|
|||||||
frame_rate_(0.0),
|
frame_rate_(0.0),
|
||||||
height_(0),
|
height_(0),
|
||||||
stereo_mode_(0),
|
stereo_mode_(0),
|
||||||
|
alpha_mode_(0),
|
||||||
width_(0) {
|
width_(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -737,6 +748,15 @@ bool VideoTrack::SetStereoMode(uint64 stereo_mode) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VideoTrack::SetAlphaMode(uint64 alpha_mode) {
|
||||||
|
if (alpha_mode != kNoAlpha &&
|
||||||
|
alpha_mode != kAlpha)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
alpha_mode_ = alpha_mode;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
uint64 VideoTrack::PayloadSize() const {
|
uint64 VideoTrack::PayloadSize() const {
|
||||||
const uint64 parent_size = Track::PayloadSize();
|
const uint64 parent_size = Track::PayloadSize();
|
||||||
|
|
||||||
@@ -772,6 +792,9 @@ bool VideoTrack::Write(IMkvWriter* writer) const {
|
|||||||
if (stereo_mode_ > kMono)
|
if (stereo_mode_ > kMono)
|
||||||
if (!WriteEbmlElement(writer, kMkvStereoMode, stereo_mode_))
|
if (!WriteEbmlElement(writer, kMkvStereoMode, stereo_mode_))
|
||||||
return false;
|
return false;
|
||||||
|
if (alpha_mode_ > kNoAlpha)
|
||||||
|
if (!WriteEbmlElement(writer, kMkvAlphaMode, alpha_mode_))
|
||||||
|
return false;
|
||||||
if (frame_rate_ > 0.0)
|
if (frame_rate_ > 0.0)
|
||||||
if (!WriteEbmlElement(writer,
|
if (!WriteEbmlElement(writer,
|
||||||
kMkvFrameRate,
|
kMkvFrameRate,
|
||||||
@@ -795,6 +818,8 @@ uint64 VideoTrack::VideoPayloadSize() const {
|
|||||||
size += EbmlElementSize(kMkvDisplayHeight, display_height_);
|
size += EbmlElementSize(kMkvDisplayHeight, display_height_);
|
||||||
if (stereo_mode_ > kMono)
|
if (stereo_mode_ > kMono)
|
||||||
size += EbmlElementSize(kMkvStereoMode, stereo_mode_);
|
size += EbmlElementSize(kMkvStereoMode, stereo_mode_);
|
||||||
|
if (alpha_mode_ > kNoAlpha)
|
||||||
|
size += EbmlElementSize(kMkvAlphaMode, alpha_mode_);
|
||||||
if (frame_rate_ > 0.0)
|
if (frame_rate_ > 0.0)
|
||||||
size += EbmlElementSize(kMkvFrameRate, static_cast<float>(frame_rate_));
|
size += EbmlElementSize(kMkvFrameRate, static_cast<float>(frame_rate_));
|
||||||
|
|
||||||
@@ -1395,6 +1420,25 @@ bool Cluster::AddFrame(const uint8* frame,
|
|||||||
&WriteSimpleBlock);
|
&WriteSimpleBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Cluster::AddFrameWithAdditional(const uint8* frame,
|
||||||
|
uint64 length,
|
||||||
|
const uint8* additional,
|
||||||
|
uint64 additional_length,
|
||||||
|
uint64 add_id,
|
||||||
|
uint64 track_number,
|
||||||
|
uint64 abs_timecode,
|
||||||
|
bool is_key) {
|
||||||
|
return DoWriteBlockWithAdditional(frame,
|
||||||
|
length,
|
||||||
|
additional,
|
||||||
|
additional_length,
|
||||||
|
add_id,
|
||||||
|
track_number,
|
||||||
|
abs_timecode,
|
||||||
|
is_key ? 1 : 0,
|
||||||
|
&WriteBlockWithAdditional);
|
||||||
|
}
|
||||||
|
|
||||||
bool Cluster::AddMetadata(const uint8* frame,
|
bool Cluster::AddMetadata(const uint8* frame,
|
||||||
uint64 length,
|
uint64 length,
|
||||||
uint64 track_number,
|
uint64 track_number,
|
||||||
@@ -1494,6 +1538,66 @@ bool Cluster::DoWriteBlock(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Cluster::DoWriteBlockWithAdditional(
|
||||||
|
const uint8* frame,
|
||||||
|
uint64 length,
|
||||||
|
const uint8* additional,
|
||||||
|
uint64 additional_length,
|
||||||
|
uint64 add_id,
|
||||||
|
uint64 track_number,
|
||||||
|
uint64 abs_timecode,
|
||||||
|
uint64 generic_arg,
|
||||||
|
WriteBlockAdditional write_block) {
|
||||||
|
if (frame == NULL || length == 0 ||
|
||||||
|
additional == NULL || additional_length == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// To simplify things, we require that there be fewer than 127
|
||||||
|
// tracks -- this allows us to serialize the track number value for
|
||||||
|
// a stream using a single byte, per the Matroska encoding.
|
||||||
|
|
||||||
|
if (track_number == 0 || track_number > 0x7E)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const int64 cluster_timecode = this->Cluster::timecode();
|
||||||
|
const int64 rel_timecode =
|
||||||
|
static_cast<int64>(abs_timecode) - cluster_timecode;
|
||||||
|
|
||||||
|
if (rel_timecode < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (rel_timecode > kMaxBlockTimecode)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (write_block == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (finalized_)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!header_written_)
|
||||||
|
if (!WriteClusterHeader())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const uint64 element_size = (*write_block)(writer_,
|
||||||
|
frame,
|
||||||
|
length,
|
||||||
|
additional,
|
||||||
|
additional_length,
|
||||||
|
add_id,
|
||||||
|
track_number,
|
||||||
|
rel_timecode,
|
||||||
|
generic_arg);
|
||||||
|
|
||||||
|
if (element_size == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
AddPayloadSize(element_size);
|
||||||
|
blocks_added_++;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool Cluster::WriteClusterHeader() {
|
bool Cluster::WriteClusterHeader() {
|
||||||
if (finalized_)
|
if (finalized_)
|
||||||
return false;
|
return false;
|
||||||
@@ -2100,6 +2204,75 @@ bool Segment::AddFrame(const uint8* frame,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Segment::AddFrameWithAdditional(const uint8* frame,
|
||||||
|
uint64 length,
|
||||||
|
const uint8* additional,
|
||||||
|
uint64 additional_length,
|
||||||
|
uint64 add_id,
|
||||||
|
uint64 track_number,
|
||||||
|
uint64 timestamp,
|
||||||
|
bool is_key) {
|
||||||
|
if (!frame || !additional)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!CheckHeaderInfo())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Check for non-monotonically increasing timestamps.
|
||||||
|
if (timestamp < last_timestamp_)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// If the segment has a video track hold onto audio frames to make sure the
|
||||||
|
// audio that is associated with the start time of a video key-frame is
|
||||||
|
// muxed into the same cluster.
|
||||||
|
if (has_video_ && tracks_.TrackIsAudio(track_number) && !force_new_cluster_) {
|
||||||
|
Frame* const new_frame = new Frame();
|
||||||
|
if (!new_frame->Init(frame, length))
|
||||||
|
return false;
|
||||||
|
new_frame->set_track_number(track_number);
|
||||||
|
new_frame->set_timestamp(timestamp);
|
||||||
|
new_frame->set_is_key(is_key);
|
||||||
|
|
||||||
|
if (!QueueFrame(new_frame))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DoNewClusterProcessing(track_number, timestamp, is_key))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (cluster_list_size_ < 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Cluster* const cluster = cluster_list_[cluster_list_size_ - 1];
|
||||||
|
if (!cluster)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const uint64 timecode_scale = segment_info_.timecode_scale();
|
||||||
|
const uint64 abs_timecode = timestamp / timecode_scale;
|
||||||
|
|
||||||
|
if (!cluster->AddFrameWithAdditional(frame,
|
||||||
|
length,
|
||||||
|
additional,
|
||||||
|
additional_length,
|
||||||
|
add_id,
|
||||||
|
track_number,
|
||||||
|
abs_timecode,
|
||||||
|
is_key))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (new_cuepoint_ && cues_track_ == track_number) {
|
||||||
|
if (!AddCuePoint(timestamp, cues_track_))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timestamp > last_timestamp_)
|
||||||
|
last_timestamp_ = timestamp;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool Segment::AddMetadata(const uint8* frame,
|
bool Segment::AddMetadata(const uint8* frame,
|
||||||
uint64 length,
|
uint64 length,
|
||||||
uint64 track_number,
|
uint64 track_number,
|
||||||
|
|||||||
69
mkvmuxer.hpp
69
mkvmuxer.hpp
@@ -296,6 +296,10 @@ class Track {
|
|||||||
const uint8* codec_private() const { return codec_private_; }
|
const uint8* codec_private() const { return codec_private_; }
|
||||||
void set_language(const char* language);
|
void set_language(const char* language);
|
||||||
const char* language() const { return language_; }
|
const char* language() const { return language_; }
|
||||||
|
void set_max_block_additional_id(uint64 max_block_additional_id) {
|
||||||
|
max_block_additional_id_ = max_block_additional_id;
|
||||||
|
}
|
||||||
|
uint64 max_block_additional_id() const { return max_block_additional_id_; }
|
||||||
void set_name(const char* name);
|
void set_name(const char* name);
|
||||||
const char* name() const { return name_; }
|
const char* name() const { return name_; }
|
||||||
void set_number(uint64 number) { number_ = number; }
|
void set_number(uint64 number) { number_ = number; }
|
||||||
@@ -314,6 +318,7 @@ class Track {
|
|||||||
char* codec_id_;
|
char* codec_id_;
|
||||||
uint8* codec_private_;
|
uint8* codec_private_;
|
||||||
char* language_;
|
char* language_;
|
||||||
|
uint64 max_block_additional_id_;
|
||||||
char* name_;
|
char* name_;
|
||||||
uint64 number_;
|
uint64 number_;
|
||||||
uint64 type_;
|
uint64 type_;
|
||||||
@@ -344,6 +349,11 @@ class VideoTrack : public Track {
|
|||||||
kSideBySideRightIsFirst = 11
|
kSideBySideRightIsFirst = 11
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum AlphaMode {
|
||||||
|
kNoAlpha = 0,
|
||||||
|
kAlpha = 1
|
||||||
|
};
|
||||||
|
|
||||||
// The |seed| parameter is used to synthesize a UID for the track.
|
// The |seed| parameter is used to synthesize a UID for the track.
|
||||||
explicit VideoTrack(unsigned int* seed);
|
explicit VideoTrack(unsigned int* seed);
|
||||||
virtual ~VideoTrack();
|
virtual ~VideoTrack();
|
||||||
@@ -358,6 +368,9 @@ class VideoTrack : public Track {
|
|||||||
// Sets the video's stereo mode. Returns true on success.
|
// Sets the video's stereo mode. Returns true on success.
|
||||||
bool SetStereoMode(uint64 stereo_mode);
|
bool SetStereoMode(uint64 stereo_mode);
|
||||||
|
|
||||||
|
// Sets the video's alpha mode. Returns true on success.
|
||||||
|
bool SetAlphaMode(uint64 alpha_mode);
|
||||||
|
|
||||||
void set_display_height(uint64 height) { display_height_ = height; }
|
void set_display_height(uint64 height) { display_height_ = height; }
|
||||||
uint64 display_height() const { return display_height_; }
|
uint64 display_height() const { return display_height_; }
|
||||||
void set_display_width(uint64 width) { display_width_ = width; }
|
void set_display_width(uint64 width) { display_width_ = width; }
|
||||||
@@ -367,6 +380,7 @@ class VideoTrack : public Track {
|
|||||||
void set_height(uint64 height) { height_ = height; }
|
void set_height(uint64 height) { height_ = height; }
|
||||||
uint64 height() const { return height_; }
|
uint64 height() const { return height_; }
|
||||||
uint64 stereo_mode() { return stereo_mode_; }
|
uint64 stereo_mode() { return stereo_mode_; }
|
||||||
|
uint64 alpha_mode() { return alpha_mode_; }
|
||||||
void set_width(uint64 width) { width_ = width; }
|
void set_width(uint64 width) { width_ = width; }
|
||||||
uint64 width() const { return width_; }
|
uint64 width() const { return width_; }
|
||||||
|
|
||||||
@@ -380,6 +394,7 @@ class VideoTrack : public Track {
|
|||||||
double frame_rate_;
|
double frame_rate_;
|
||||||
uint64 height_;
|
uint64 height_;
|
||||||
uint64 stereo_mode_;
|
uint64 stereo_mode_;
|
||||||
|
uint64 alpha_mode_;
|
||||||
uint64 width_;
|
uint64 width_;
|
||||||
|
|
||||||
LIBWEBM_DISALLOW_COPY_AND_ASSIGN(VideoTrack);
|
LIBWEBM_DISALLOW_COPY_AND_ASSIGN(VideoTrack);
|
||||||
@@ -661,6 +676,28 @@ class Cluster {
|
|||||||
uint64 timecode, // timecode units (absolute)
|
uint64 timecode, // timecode units (absolute)
|
||||||
bool is_key);
|
bool is_key);
|
||||||
|
|
||||||
|
// Adds a frame to be output in the file. The frame is written out through
|
||||||
|
// |writer_| if successful. Returns true on success.
|
||||||
|
// Inputs:
|
||||||
|
// frame: Pointer to the data
|
||||||
|
// length: Length of the data
|
||||||
|
// additional: Pointer to the additional data
|
||||||
|
// additional_length: Length of the additional data
|
||||||
|
// add_id: Value of BlockAddID element
|
||||||
|
// track_number: Track to add the data to. Value returned by Add track
|
||||||
|
// functions. The range of allowed values is [1, 126].
|
||||||
|
// abs_timecode: Absolute (not relative to cluster) timestamp of the
|
||||||
|
// frame, expressed in timecode units.
|
||||||
|
// is_key: Flag telling whether or not this frame is a key frame.
|
||||||
|
bool AddFrameWithAdditional(const uint8* frame,
|
||||||
|
uint64 length,
|
||||||
|
const uint8* additional,
|
||||||
|
uint64 additional_length,
|
||||||
|
uint64 add_id,
|
||||||
|
uint64 track_number,
|
||||||
|
uint64 abs_timecode,
|
||||||
|
bool is_key);
|
||||||
|
|
||||||
// Writes a frame of metadata to the output medium; returns true on
|
// Writes a frame of metadata to the output medium; returns true on
|
||||||
// success.
|
// success.
|
||||||
// Inputs:
|
// Inputs:
|
||||||
@@ -706,6 +743,18 @@ class Cluster {
|
|||||||
int64 timecode,
|
int64 timecode,
|
||||||
uint64 generic_arg);
|
uint64 generic_arg);
|
||||||
|
|
||||||
|
// Signature that matches WriteBlockWithAdditional
|
||||||
|
// in the muxer utilities package.
|
||||||
|
typedef uint64 (*WriteBlockAdditional)(IMkvWriter* writer,
|
||||||
|
const uint8* data,
|
||||||
|
uint64 length,
|
||||||
|
const uint8* additional,
|
||||||
|
uint64 add_id,
|
||||||
|
uint64 additional_length,
|
||||||
|
uint64 track_number,
|
||||||
|
int64 timecode,
|
||||||
|
uint64 is_key);
|
||||||
|
|
||||||
// Used to implement AddFrame and AddMetadata.
|
// Used to implement AddFrame and AddMetadata.
|
||||||
bool DoWriteBlock(const uint8* frame,
|
bool DoWriteBlock(const uint8* frame,
|
||||||
uint64 length,
|
uint64 length,
|
||||||
@@ -714,6 +763,17 @@ class Cluster {
|
|||||||
uint64 generic_arg,
|
uint64 generic_arg,
|
||||||
WriteBlock write_block);
|
WriteBlock write_block);
|
||||||
|
|
||||||
|
// Used to implement AddFrameWithAdditional
|
||||||
|
bool DoWriteBlockWithAdditional(const uint8* frame,
|
||||||
|
uint64 length,
|
||||||
|
const uint8* additional,
|
||||||
|
uint64 additional_length,
|
||||||
|
uint64 add_id,
|
||||||
|
uint64 track_number,
|
||||||
|
uint64 absolute_timecode,
|
||||||
|
uint64 generic_arg,
|
||||||
|
WriteBlockAdditional write_block);
|
||||||
|
|
||||||
// Outputs the Cluster header to |writer_|. Returns true on success.
|
// Outputs the Cluster header to |writer_|. Returns true on success.
|
||||||
bool WriteClusterHeader();
|
bool WriteClusterHeader();
|
||||||
|
|
||||||
@@ -908,6 +968,15 @@ class Segment {
|
|||||||
uint64 timestamp_ns,
|
uint64 timestamp_ns,
|
||||||
uint64 duration_ns);
|
uint64 duration_ns);
|
||||||
|
|
||||||
|
bool AddFrameWithAdditional(const uint8* frame,
|
||||||
|
uint64 length,
|
||||||
|
const uint8* additional,
|
||||||
|
uint64 additional_length,
|
||||||
|
uint64 add_id,
|
||||||
|
uint64 track_number,
|
||||||
|
uint64 timestamp,
|
||||||
|
bool is_key);
|
||||||
|
|
||||||
// Adds a video track to the segment. Returns the number of the track on
|
// Adds a video track to the segment. Returns the number of the track on
|
||||||
// success, 0 on error. |number| is the number to use for the video track.
|
// success, 0 on error. |number| is the number to use for the video track.
|
||||||
// |number| must be >= 0. If |number| == 0 then the muxer will decide on
|
// |number| must be >= 0. If |number| == 0 then the muxer will decide on
|
||||||
|
|||||||
@@ -464,6 +464,95 @@ uint64 WriteMetadataBlock(IMkvWriter* writer,
|
|||||||
return blockg_elem_size;
|
return blockg_elem_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Writes a WebM Block with Additional. The structure is as follows
|
||||||
|
// Indentation shows sub-levels
|
||||||
|
// BlockGroup
|
||||||
|
// Block
|
||||||
|
// Data
|
||||||
|
// BlockAdditions
|
||||||
|
// BlockMore
|
||||||
|
// BlockAddID
|
||||||
|
// 1 (Denotes Alpha)
|
||||||
|
// BlockAdditional
|
||||||
|
// Data
|
||||||
|
uint64 WriteBlockWithAdditional(IMkvWriter* writer,
|
||||||
|
const uint8* data,
|
||||||
|
uint64 length,
|
||||||
|
const uint8* additional,
|
||||||
|
uint64 additional_length,
|
||||||
|
uint64 add_id,
|
||||||
|
uint64 track_number,
|
||||||
|
int64 timecode,
|
||||||
|
uint64 is_key) {
|
||||||
|
if (!data || !additional || length < 1 || additional_length < 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
const uint64 block_payload_size = 4 + length;
|
||||||
|
const uint64 block_elem_size = EbmlMasterElementSize(kMkvBlock,
|
||||||
|
block_payload_size) +
|
||||||
|
block_payload_size;
|
||||||
|
const uint64 block_additional_elem_size = EbmlElementSize(kMkvBlockAdditional,
|
||||||
|
additional,
|
||||||
|
additional_length);
|
||||||
|
const uint64 block_addid_elem_size = EbmlElementSize(kMkvBlockAddID, add_id);
|
||||||
|
|
||||||
|
const uint64 block_more_payload_size = block_addid_elem_size +
|
||||||
|
block_additional_elem_size;
|
||||||
|
const uint64 block_more_elem_size = EbmlMasterElementSize(
|
||||||
|
kMkvBlockMore,
|
||||||
|
block_more_payload_size) +
|
||||||
|
block_more_payload_size;
|
||||||
|
const uint64 block_additions_payload_size = block_more_elem_size;
|
||||||
|
const uint64 block_additions_elem_size = EbmlMasterElementSize(
|
||||||
|
kMkvBlockMore,
|
||||||
|
block_additions_payload_size) +
|
||||||
|
block_additions_payload_size;
|
||||||
|
const uint64 block_group_payload_size = block_elem_size +
|
||||||
|
block_additions_elem_size;
|
||||||
|
const uint64 block_group_elem_size = EbmlMasterElementSize(
|
||||||
|
kMkvBlockGroup,
|
||||||
|
block_group_payload_size) +
|
||||||
|
block_group_payload_size;
|
||||||
|
|
||||||
|
if (!WriteEbmlMasterElement(writer, kMkvBlockGroup,
|
||||||
|
block_group_payload_size))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!WriteEbmlMasterElement(writer, kMkvBlock, block_payload_size))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (WriteUInt(writer, track_number))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (SerializeInt(writer, timecode, 2))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
uint64 flags = 0;
|
||||||
|
if (is_key)
|
||||||
|
flags |= 0x80;
|
||||||
|
if (SerializeInt(writer, flags, 1))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (writer->Write(data, static_cast<uint32>(length)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!WriteEbmlMasterElement(writer, kMkvBlockAdditions,
|
||||||
|
block_additions_payload_size))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!WriteEbmlMasterElement(writer, kMkvBlockMore, block_more_payload_size))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!WriteEbmlElement(writer, kMkvBlockAddID, add_id))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!WriteEbmlElement(writer, kMkvBlockAdditional,
|
||||||
|
additional, additional_length))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return block_group_elem_size;
|
||||||
|
}
|
||||||
|
|
||||||
uint64 WriteVoidElement(IMkvWriter* writer, uint64 size) {
|
uint64 WriteVoidElement(IMkvWriter* writer, uint64 size) {
|
||||||
if (!writer)
|
if (!writer)
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -88,6 +88,29 @@ uint64 WriteMetadataBlock(IMkvWriter* writer,
|
|||||||
int64 timecode,
|
int64 timecode,
|
||||||
uint64 duration_timecode);
|
uint64 duration_timecode);
|
||||||
|
|
||||||
|
// Output an Mkv Block with BlockAdditional data.
|
||||||
|
// Inputs:
|
||||||
|
// data: Pointer to the data.
|
||||||
|
// length: Length of the data.
|
||||||
|
// additional: Pointer to the additional data
|
||||||
|
// additional_length: Length of the additional data.
|
||||||
|
// add_id: Value of BlockAddID element.
|
||||||
|
// track_number: Track to add the data to. Value returned by Add track
|
||||||
|
// functions. Only values in the range [1, 126] are
|
||||||
|
// permitted.
|
||||||
|
// timecode: Relative timecode of the Block. Only values in the
|
||||||
|
// range [0, 2^15) are permitted.
|
||||||
|
// is_key: Non-zero value specifies that frame is a key frame.
|
||||||
|
uint64 WriteBlockWithAdditional(IMkvWriter* writer,
|
||||||
|
const uint8* data,
|
||||||
|
uint64 length,
|
||||||
|
const uint8* additional,
|
||||||
|
uint64 additional_length,
|
||||||
|
uint64 add_id,
|
||||||
|
uint64 track_number,
|
||||||
|
int64 timecode,
|
||||||
|
uint64 is_key);
|
||||||
|
|
||||||
// Output a void element. |size| must be the entire size in bytes that will be
|
// Output a void element. |size| must be the entire size in bytes that will be
|
||||||
// void. The function will calculate the size of the void header and subtract
|
// void. The function will calculate the size of the void header and subtract
|
||||||
// it from |size|.
|
// it from |size|.
|
||||||
|
|||||||
@@ -53,6 +53,10 @@ enum MkvId {
|
|||||||
kMkvReferenceBlock = 0xFB,
|
kMkvReferenceBlock = 0xFB,
|
||||||
kMkvLaceNumber = 0xCC,
|
kMkvLaceNumber = 0xCC,
|
||||||
kMkvSimpleBlock = 0xA3,
|
kMkvSimpleBlock = 0xA3,
|
||||||
|
kMkvBlockAdditions = 0x75A1,
|
||||||
|
kMkvBlockMore = 0xA6,
|
||||||
|
kMkvBlockAddID = 0xEE,
|
||||||
|
kMkvBlockAdditional = 0xA5,
|
||||||
//Track
|
//Track
|
||||||
kMkvTracks = 0x1654AE6B,
|
kMkvTracks = 0x1654AE6B,
|
||||||
kMkvTrackEntry = 0xAE,
|
kMkvTrackEntry = 0xAE,
|
||||||
@@ -69,10 +73,12 @@ enum MkvId {
|
|||||||
kMkvCodecID = 0x86,
|
kMkvCodecID = 0x86,
|
||||||
kMkvCodecPrivate = 0x63A2,
|
kMkvCodecPrivate = 0x63A2,
|
||||||
kMkvCodecName = 0x258688,
|
kMkvCodecName = 0x258688,
|
||||||
|
kMkvMaxBlockAdditionID = 0x55EE,
|
||||||
//video
|
//video
|
||||||
kMkvVideo = 0xE0,
|
kMkvVideo = 0xE0,
|
||||||
kMkvFlagInterlaced = 0x9A,
|
kMkvFlagInterlaced = 0x9A,
|
||||||
kMkvStereoMode = 0x53B8,
|
kMkvStereoMode = 0x53B8,
|
||||||
|
kMkvAlphaMode = 0x53C0,
|
||||||
kMkvPixelWidth = 0xB0,
|
kMkvPixelWidth = 0xB0,
|
||||||
kMkvPixelHeight = 0xBA,
|
kMkvPixelHeight = 0xBA,
|
||||||
kMkvPixelCropBottom = 0x54AA,
|
kMkvPixelCropBottom = 0x54AA,
|
||||||
|
|||||||
Reference in New Issue
Block a user