Better support for audio only webm files.

Changed max_cluster_duration to 30 seconds so default command line
will not crash on audio only WebM files. Added support to the sample
muxer to output cues on the audio track. Created a muxer helper
function to clean up the code a little.

Change-Id: I2871836b64cef7defd10aa51a209b4abd9046832
This commit is contained in:
Frank Galligan 2011-08-14 10:49:50 -04:00
parent 6d99850e7c
commit a09f15f00e
3 changed files with 48 additions and 32 deletions

View File

@ -1128,7 +1128,7 @@ Segment::Segment(IMkvWriter* writer)
has_video_(false),
header_written_(false),
last_timestamp_(0),
max_cluster_duration_(0),
max_cluster_duration_(30000000000),
max_cluster_size_(0),
mode_(kFile),
new_cluster_(true),
@ -1252,34 +1252,8 @@ bool Segment::AddFrame(uint8* frame,
bool is_key) {
assert(frame);
if (!header_written_) {
if (!WriteSegmentHeader())
return false;
if (!seek_head_.AddSeekEntry(kMkvCluster,
writer_->Position() - payload_pos_))
return false;
if (output_cues_ && cues_track_ == 0) {
// Check for a video track
for (uint32 i = 0; i < tracks_.track_entries_size(); ++i) {
const Track* const track = tracks_.GetTrackByIndex(i);
assert(track);
if (tracks_.TrackIsVideo(track->number())) {
cues_track_ = track->number();
break;
}
}
// Set first track found
if (cues_track_ == 0) {
const Track* const track = tracks_.GetTrackByIndex(0);
assert(track);
cues_track_ = track->number();
}
}
}
if (!CheckHeaderInfo())
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
@ -1472,6 +1446,38 @@ bool Segment::WriteSegmentHeader() {
return true;
}
bool Segment::CheckHeaderInfo() {
if (!header_written_) {
if (!WriteSegmentHeader())
return false;
if (!seek_head_.AddSeekEntry(kMkvCluster,
writer_->Position() - payload_pos_))
return false;
if (output_cues_ && cues_track_ == 0) {
// Check for a video track
for (uint32 i = 0; i < tracks_.track_entries_size(); ++i) {
const Track* const track = tracks_.GetTrackByIndex(i);
assert(track);
if (tracks_.TrackIsVideo(track->number())) {
cues_track_ = track->number();
break;
}
}
// Set first track found
if (cues_track_ == 0) {
const Track* const track = tracks_.GetTrackByIndex(0);
assert(track);
cues_track_ = track->number();
}
}
}
return true;
}
bool Segment::AddCuePoint(uint64 timestamp) {
assert(cluster_list_size_ > 0);
const Cluster* const cluster = cluster_list_[cluster_list_size_-1];

View File

@ -592,6 +592,11 @@ class Segment {
// nanoseconds of the cue's time. Returns true on success.
bool AddCuePoint(uint64 timestamp);
// Checks if header information has been output and initialized. If not it
// will output the Segment element and initialize the SeekHead elment and
// Cues elements.
bool CheckHeaderInfo();
// Adds the frame to our frame array.
bool QueueFrame(Frame* frame);
@ -648,8 +653,8 @@ class Segment {
uint64 last_timestamp_;
// Maximum time in nanoseconds for a cluster duration. This variable is a
// guideline and some clusters may have a longer duration. Default is 0
// which signifies that the muxer will decide.
// guideline and some clusters may have a longer duration. Default is 30
// seconds.
uint64 max_cluster_duration_;
// Maximum size in bytes for a cluster. This variable is a guideline and

View File

@ -31,6 +31,7 @@ void Usage() {
printf(" 0 puts the muxer into file mode\n");
printf(" -output_cues <int> >0 outputs cues element\n");
printf(" -cues_on_video_track <int> >0 outputs cues on video track\n");
printf(" -cues_on_audio_track <int> >0 outputs cues on audio track\n");
printf(" 0 outputs cues on audio track\n");
printf(" -max_cluster_duration <double> in seconds\n");
printf(" -max_cluster_size <int> in bytes\n");
@ -59,6 +60,7 @@ int main(int argc, char* argv[]) {
bool live_mode = false;
bool output_cues = true;
bool cues_on_video_track = true;
bool cues_on_audio_track = true;
uint64 max_cluster_duration = 0;
uint64 max_cluster_size = 0;
bool switch_tracks = false;
@ -89,6 +91,8 @@ int main(int argc, char* argv[]) {
output_cues = strtol(argv[++i], &end, 10) == 0 ? false : true;
} else if (!strcmp("-cues_on_video_track", argv[i])) {
cues_on_video_track = strtol(argv[++i], &end, 10) == 0 ? false : true;
} else if (!strcmp("-cues_on_audio_track", argv[i])) {
cues_on_audio_track = strtol(argv[++i], &end, 10) == 0 ? false : true;
} else if (!strcmp("-max_cluster_duration", argv[i])) {
const double seconds = strtod(argv[++i], &end);
max_cluster_duration =
@ -278,7 +282,8 @@ int main(int argc, char* argv[]) {
if (cues_on_video_track) {
if (vid_track)
muxer_segment.CuesTrack(vid_track);
} else {
}
if (cues_on_audio_track) {
if (aud_track)
muxer_segment.CuesTrack(aud_track);
}