blob: bdd1dde2e5392c379b58cd7f306734eb0b6f48c1 [file] [log] [blame]
/*
* Copyright (c) 2011 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "media_group.h"
#include <iostream>
#include <map>
#include <sstream>
#include "indent.h"
#include "media.h"
using std::cout;
using std::endl;
using indent_webm::Indent;
namespace adaptive_manifest {
MediaGroup::MediaGroup(const string& id)
: codec_(),
id_(id),
lang_(),
duration_(0.0) {
}
MediaGroup::~MediaGroup() {
vector<Media*>::iterator iter;
for( iter = media_.begin(); iter != media_.end(); ++iter ) {
Media* m = *iter;
delete m;
}
}
bool MediaGroup::Init() {
vector<Media*>::iterator iter;
for( iter = media_.begin(); iter != media_.end(); ++iter ) {
if ((*iter)->Init() == false)
return false;
}
// Check to see if all the codecs match.
iter = media_.begin();
codec_ = (*iter)->GetCodec();
for(iter = media_.begin()+1; iter != media_.end(); ++iter ) {
if ((*iter)->GetCodec() != codec_) {
cout << "Media id:" << (*iter)->id() << " codec: ";
cout << (*iter)->GetCodec() << " does not match in MediaGroup id:";
cout << id_ << endl;
return false;
}
}
// Get max duration. All of the streams should have a duration that is close.
// TODO: Add a check to make sure the durations are close.
for( iter = media_.begin(); iter != media_.end(); ++iter ) {
double duration = (*iter)->GetDurationNanoseconds() / 1000000000.0;
if (duration > duration_)
duration_ = duration;
}
// Check that media ids do not match. Using the map to check if the string
// has been inserted.
std::map<string,int> test_map;
std::pair<std::map<string,int>::iterator,bool> ret;
for( iter = media_.begin(); iter != media_.end(); ++iter ) {
string id = (*iter)->id();
ret = test_map.insert(std::pair<string,int>(id, 0));
if (ret.second==false) {
cout << "Media id:" << id << " is duplicate in MediaGroup id:";
cout << id_ << endl;
return false;
}
}
return true;
}
void MediaGroup::AddMedia() {
std::ostringstream temp;
temp << media_.size();
const string id = temp.str();
media_.push_back(new Media(id));
}
Media* MediaGroup::CurrentMedia() {
vector<Media*>::iterator iter_curr(media_.end());
if (iter_curr == media_.begin())
return NULL;
--iter_curr;
return *iter_curr;
return NULL;
}
const Media* MediaGroup::FindMedia(const string& id) const {
vector<Media*>::const_iterator iter;
for( iter = media_.begin(); iter != media_.end(); ++iter ) {
if ((*iter)->id() == id)
return *iter;
}
return NULL;
}
void MediaGroup::OutputPrototypeManifest(std::ostream& o, Indent& indt) {
indt.Adjust(2);
o << indt << "<MediaGroup id=\"" << id_ << "\"";
o << " mimetype=\"video/webm; codecs=" << codec_ << "\"";
if (!lang_.empty()) {
o << " lang=\"" << lang_ << "\"";
}
const bool alignment = Alignment();
if (alignment)
o << " alignment=\"true\"";
else
o << " alignment=\"false\"";
o << " >" << endl;
vector<Media*>::const_iterator iter;
for( iter = media_.begin(); iter != media_.end(); ++iter ) {
(*iter)->OutputPrototypeManifest(o, indt);
}
o << indt << "</MediaGroup>" << endl;
indt.Adjust(-2);
}
bool MediaGroup::Alignment() {
vector<Media*>::const_iterator golden_iter(media_.begin());
vector<Media*>::const_iterator iter;
if (media_.size() <= 1)
return false;
for( iter = media_.begin()+1; iter != media_.end(); ++iter ) {
Media* m = *iter;
if (!m->CheckAlignement(**golden_iter))
return false;
}
return true;
}
std::ostream& operator<< (std::ostream &o, const MediaGroup &mg)
{
o << " MediaGroup" << endl;
o << " id_:" << mg.id_ << endl;
o << " lang_:" << mg.lang_ << endl;
vector<Media*>::const_iterator iter;
for( iter = mg.media_.begin(); iter != mg.media_.end(); ++iter ) {
Media* m = *iter;
o << *m;
}
return o;
}
} // namespace adaptive_manifest