Add support for setting track numbers.

When adding tracks to the muxer the application can set the
track number.

Change-Id: Id4dbbfec5cd541b1354c03361a40a3d2d7f921b9
This commit is contained in:
Frank Galligan 2011-08-14 12:33:30 -04:00
parent a09f15f00e
commit 2d3461b4b3
3 changed files with 77 additions and 17 deletions

View File

@ -662,7 +662,18 @@ Tracks::~Tracks() {
}
}
bool Tracks::AddTrack(Track* track) {
bool Tracks::AddTrack(Track* track, int32 number) {
if (number < 0)
return false;
int32 track_num = number;
// Check to make sure a track does not already have |track_num|.
for (uint32 i = 0; i < track_entries_size_; ++i) {
if (track_entries_[i]->number() == track_num)
return false;
}
const uint32 count = track_entries_size_ + 1;
Track** const track_entries = new (std::nothrow) Track*[count];
@ -675,7 +686,24 @@ bool Tracks::AddTrack(Track* track) {
delete [] track_entries_;
track->set_number(count);
// Find the lowest availible track number > 0.
if (track_num == 0) {
track_num = count;
// Check to make sure a track does not already have |track_num|.
bool exit = false;
do {
exit = true;
for (uint32 i = 0; i < track_entries_size_; ++i) {
if (track_entries[i]->number() == track_num) {
track_num++;
exit = false;
break;
}
}
} while (!exit);
}
track->set_number(track_num);
track_entries_ = track_entries;
track_entries_[track_entries_size_] = track;
@ -1128,7 +1156,7 @@ Segment::Segment(IMkvWriter* writer)
has_video_(false),
header_written_(false),
last_timestamp_(0),
max_cluster_duration_(30000000000),
max_cluster_duration_(kDefaultMaxClusterDuration),
max_cluster_size_(0),
mode_(kFile),
new_cluster_(true),
@ -1215,6 +1243,10 @@ bool Segment::Finalize() {
}
uint64 Segment::AddVideoTrack(int32 width, int32 height) {
return AddVideoTrack(width, height, 0);
}
uint64 Segment::AddVideoTrack(int32 width, int32 height, int32 number) {
VideoTrack* const vid_track = new (std::nothrow) VideoTrack();
if (!vid_track)
return 0;
@ -1224,13 +1256,19 @@ uint64 Segment::AddVideoTrack(int32 width, int32 height) {
vid_track->set_width(width);
vid_track->set_height(height);
tracks_.AddTrack(vid_track);
tracks_.AddTrack(vid_track, number);
has_video_ = true;
return vid_track->number();
}
uint64 Segment::AddAudioTrack(int32 sample_rate, int32 channels) {
return AddAudioTrack(sample_rate, channels, 0);
}
uint64 Segment::AddAudioTrack(int32 sample_rate,
int32 channels,
int32 number) {
AudioTrack* const aud_track = new (std::nothrow) AudioTrack();
if (!aud_track)
return 0;
@ -1240,7 +1278,7 @@ uint64 Segment::AddAudioTrack(int32 sample_rate, int32 channels) {
aud_track->set_sample_rate(sample_rate);
aud_track->set_channels(channels);
tracks_.AddTrack(aud_track);
tracks_.AddTrack(aud_track, number);
return aud_track->number();
}

View File

@ -335,8 +335,10 @@ class Tracks {
~Tracks();
// Adds a Track element to the Tracks object. |track| will be owned and
// deleted by the Tracks object. Returns true on success.
bool AddTrack(Track* track);
// deleted by the Tracks object. Returns true on success. |number| is the
// number to use for the track. |number| must be >= 0. If |number| == 0
// then the muxer will decide on the track number.
bool AddTrack(Track* track, int32 number);
// Returns the track by index. Returns NULL if there is no track match.
const Track* GetTrackByIndex(uint32 idx) const;
@ -525,6 +527,8 @@ class Segment {
kFile = 0x2
};
const static uint64 kDefaultMaxClusterDuration = 30000000000ULL;
explicit Segment(IMkvWriter* writer);
virtual ~Segment();
@ -532,6 +536,12 @@ class Segment {
// success, 0 on error.
uint64 AddAudioTrack(int32 sample_rate, int32 channels);
// Adds an audio track to the segment. Returns the number of the track on
// success, 0 on error. |number| is the number to use for the audio track.
// |number| must be >= 0. If |number| == 0 then the muxer will decide on
// the track number.
uint64 AddAudioTrack(int32 sample_rate, int32 channels, int32 number);
// Adds a frame to be output in the file. Returns true on success.
// Inputs:
// frame: Pointer to the data
@ -550,6 +560,12 @@ class Segment {
// success, 0 on error.
uint64 AddVideoTrack(int32 width, int32 height);
// 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.
// |number| must be >= 0. If |number| == 0 then the muxer will decide on
// the track number.
uint64 AddVideoTrack(int32 width, int32 height, int32 number);
// Sets which track to use for the Cues element. Must have added the track
// before calling this function. Returns true on success. |track_number| is
// returned by the Add track functions.

View File

@ -36,6 +36,8 @@ void Usage() {
printf(" -max_cluster_duration <double> in seconds\n");
printf(" -max_cluster_size <int> in bytes\n");
printf(" -switch_tracks <int> >0 switches tracks in output\n");
printf(" -audio_track_number <int> >0 Changes the audio track number\n");
printf(" -video_track_number <int> >0 Changes the video track number\n");
printf("\n");
printf("Video options:\n");
printf(" -display_width <int> Display width in pixels\n");
@ -64,6 +66,8 @@ int main(int argc, char* argv[]) {
uint64 max_cluster_duration = 0;
uint64 max_cluster_size = 0;
bool switch_tracks = false;
int audio_track_number = 0; // 0 tells muxer to decide.
int video_track_number = 0; // 0 tells muxer to decide.
bool output_cues_block_number = true;
@ -101,6 +105,10 @@ int main(int argc, char* argv[]) {
max_cluster_size = strtol(argv[++i], &end, 10);
} else if (!strcmp("-switch_tracks", argv[i])) {
switch_tracks = strtol(argv[++i], &end, 10) == 0 ? false : true;
} else if (!strcmp("-audio_track_number", argv[i])) {
audio_track_number = strtol(argv[++i], &end, 10);
} else if (!strcmp("-video_track_number", argv[i])) {
video_track_number = strtol(argv[++i], &end, 10);
} else if (!strcmp("-display_width", argv[i])) {
display_width = strtol(argv[++i], &end, 10);
} else if (!strcmp("-display_height", argv[i])) {
@ -206,7 +214,8 @@ int main(int argc, char* argv[]) {
// Add the video track to the muxer
vid_track = muxer_segment.AddVideoTrack(static_cast<int>(width),
static_cast<int>(height));
static_cast<int>(height),
video_track_number);
if (!vid_track) {
printf("\n Could not add video track.\n");
return -1;
@ -243,7 +252,8 @@ int main(int argc, char* argv[]) {
// Add the audio track to the muxer
aud_track = muxer_segment.AddAudioTrack(static_cast<int>(sample_rate),
static_cast<int>(channels));
static_cast<int>(channels),
audio_track_number);
if (!aud_track) {
printf("\n Could not add audio track.\n");
return -1;
@ -279,14 +289,10 @@ int main(int argc, char* argv[]) {
// Set Cues element attributes
mkvmuxer::Cues* const cues = muxer_segment.GetCues();
cues->set_output_block_number(output_cues_block_number);
if (cues_on_video_track) {
if (vid_track)
if (cues_on_video_track && vid_track)
muxer_segment.CuesTrack(vid_track);
}
if (cues_on_audio_track) {
if (aud_track)
if (cues_on_audio_track && aud_track)
muxer_segment.CuesTrack(aud_track);
}
// Write clusters
unsigned char* data = NULL;