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), has_video_(false),
header_written_(false), header_written_(false),
last_timestamp_(0), last_timestamp_(0),
max_cluster_duration_(0), max_cluster_duration_(30000000000),
max_cluster_size_(0), max_cluster_size_(0),
mode_(kFile), mode_(kFile),
new_cluster_(true), new_cluster_(true),
@@ -1252,35 +1252,9 @@ bool Segment::AddFrame(uint8* frame,
bool is_key) { bool is_key) {
assert(frame); assert(frame);
if (!header_written_) { if (!CheckHeaderInfo())
if (!WriteSegmentHeader())
return false; 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 the segment has a video track hold onto audio frames to make sure the // 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 // audio that is associated with the start time of a video key-frame is
// muxed into the same cluster. // muxed into the same cluster.
@@ -1472,6 +1446,38 @@ bool Segment::WriteSegmentHeader() {
return true; 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) { bool Segment::AddCuePoint(uint64 timestamp) {
assert(cluster_list_size_ > 0); assert(cluster_list_size_ > 0);
const Cluster* const cluster = cluster_list_[cluster_list_size_-1]; 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. // nanoseconds of the cue's time. Returns true on success.
bool AddCuePoint(uint64 timestamp); 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. // Adds the frame to our frame array.
bool QueueFrame(Frame* frame); bool QueueFrame(Frame* frame);
@@ -648,8 +653,8 @@ class Segment {
uint64 last_timestamp_; uint64 last_timestamp_;
// Maximum time in nanoseconds for a cluster duration. This variable is a // Maximum time in nanoseconds for a cluster duration. This variable is a
// guideline and some clusters may have a longer duration. Default is 0 // guideline and some clusters may have a longer duration. Default is 30
// which signifies that the muxer will decide. // seconds.
uint64 max_cluster_duration_; uint64 max_cluster_duration_;
// Maximum size in bytes for a cluster. This variable is a guideline and // 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(" 0 puts the muxer into file mode\n");
printf(" -output_cues <int> >0 outputs cues element\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_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(" 0 outputs cues on audio track\n");
printf(" -max_cluster_duration <double> in seconds\n"); printf(" -max_cluster_duration <double> in seconds\n");
printf(" -max_cluster_size <int> in bytes\n"); printf(" -max_cluster_size <int> in bytes\n");
@@ -59,6 +60,7 @@ int main(int argc, char* argv[]) {
bool live_mode = false; bool live_mode = false;
bool output_cues = true; bool output_cues = true;
bool cues_on_video_track = true; bool cues_on_video_track = true;
bool cues_on_audio_track = true;
uint64 max_cluster_duration = 0; uint64 max_cluster_duration = 0;
uint64 max_cluster_size = 0; uint64 max_cluster_size = 0;
bool switch_tracks = false; bool switch_tracks = false;
@@ -89,6 +91,8 @@ int main(int argc, char* argv[]) {
output_cues = strtol(argv[++i], &end, 10) == 0 ? false : true; output_cues = strtol(argv[++i], &end, 10) == 0 ? false : true;
} else if (!strcmp("-cues_on_video_track", argv[i])) { } else if (!strcmp("-cues_on_video_track", argv[i])) {
cues_on_video_track = strtol(argv[++i], &end, 10) == 0 ? false : true; 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])) { } else if (!strcmp("-max_cluster_duration", argv[i])) {
const double seconds = strtod(argv[++i], &end); const double seconds = strtod(argv[++i], &end);
max_cluster_duration = max_cluster_duration =
@@ -278,7 +282,8 @@ int main(int argc, char* argv[]) {
if (cues_on_video_track) { if (cues_on_video_track) {
if (vid_track) if (vid_track)
muxer_segment.CuesTrack(vid_track); muxer_segment.CuesTrack(vid_track);
} else { }
if (cues_on_audio_track) {
if (aud_track) if (aud_track)
muxer_segment.CuesTrack(aud_track); muxer_segment.CuesTrack(aud_track);
} }