MpdNotifier and simple MpdNotifier implementation for VOD
This is the MPD side of the bridge between MpdBuilder and Muxer. Change-Id: I4ca7436914e008b3c65399cced1f689abd82d085
This commit is contained in:
parent
cde567c14c
commit
d36091cf65
|
@ -0,0 +1,49 @@
|
||||||
|
// MpdNotifier is responsible for notifying the MpdBuilder class to generate an
|
||||||
|
// MPD file.
|
||||||
|
#ifndef MPD_BASE_MPD_NOTIFIER_H_
|
||||||
|
#define MPD_BASE_MPD_NOTIFIER_H_
|
||||||
|
|
||||||
|
#include "base/basictypes.h"
|
||||||
|
#include "mpd/base/media_info.pb.h"
|
||||||
|
|
||||||
|
namespace dash_packager {
|
||||||
|
|
||||||
|
class ContentProtectionElement;
|
||||||
|
class MediaInfo;
|
||||||
|
|
||||||
|
class MpdNotifier {
|
||||||
|
public:
|
||||||
|
MpdNotifier() {};
|
||||||
|
virtual ~MpdNotifier() {};
|
||||||
|
|
||||||
|
// Initializes the notifier. For example, if this notifier uses a network for
|
||||||
|
// notification, then this would setup connection with the remote host.
|
||||||
|
virtual bool Init() = 0;
|
||||||
|
|
||||||
|
// Notifies the MpdBuilder that there is a new container along with
|
||||||
|
// |media_info|. Live may have multiple "files" but those should be notified
|
||||||
|
// via NotifyNewSegment().
|
||||||
|
// On success this populates |container_id| for the container and returns true,
|
||||||
|
// otherwise returns false.
|
||||||
|
virtual bool NotifyNewContainer(const MediaInfo& media_info,
|
||||||
|
uint32* container_id) = 0;
|
||||||
|
|
||||||
|
// Only for Live. Notifies MpdBuilder that there is a new segment ready that
|
||||||
|
// starts from |start_time| for |duration|.
|
||||||
|
// |container_id| must be an ID number populated by calling
|
||||||
|
// NotifyNewContainer().
|
||||||
|
virtual bool NotifyNewSegment(uint32 container_id,
|
||||||
|
uint64 start_time,
|
||||||
|
uint64 duration) = 0;
|
||||||
|
|
||||||
|
// Adds content protection information to the MPD.
|
||||||
|
// |container_id| must be an ID number populated by calling
|
||||||
|
// NotifyNewContainer().
|
||||||
|
virtual bool AddContentProtectionElement(
|
||||||
|
uint32 container_id,
|
||||||
|
const ContentProtectionElement& content_protection_element) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dash_packager
|
||||||
|
|
||||||
|
#endif // MPD_BASE_MPD_NOTIFIER_H_
|
|
@ -0,0 +1,100 @@
|
||||||
|
#include "mpd/base/simple_vod_mpd_notifier.h"
|
||||||
|
|
||||||
|
#include "base/stl_util.h"
|
||||||
|
#include "mpd/base/content_protection_element.h"
|
||||||
|
#include "mpd/base/media_info.pb.h"
|
||||||
|
|
||||||
|
namespace dash_packager {
|
||||||
|
|
||||||
|
SimpleVodMpdNotifier::SimpleVodMpdNotifier(MpdBuilder* mpd_builder)
|
||||||
|
: mpd_builder_(mpd_builder),
|
||||||
|
video_adaptation_set_(NULL),
|
||||||
|
audio_adaptation_set_(NULL),
|
||||||
|
representation_(NULL) {
|
||||||
|
DCHECK(mpd_builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleVodMpdNotifier::~SimpleVodMpdNotifier() {}
|
||||||
|
|
||||||
|
bool SimpleVodMpdNotifier::Init() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SimpleVodMpdNotifier::NotifyNewContainer(const MediaInfo& media_info,
|
||||||
|
uint32* container_id) {
|
||||||
|
DCHECK(container_id);
|
||||||
|
|
||||||
|
if (media_info.video_info_size() > 0 && media_info.audio_info_size() > 0) {
|
||||||
|
LOG(ERROR) << "SimpleVodMpdNotifier cannot handle media container with "
|
||||||
|
"both video and audio";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ContainerType container_type = kVideo;
|
||||||
|
if (media_info.video_info_size() > 0) {
|
||||||
|
container_type = kVideo;
|
||||||
|
} else if (media_info.audio_info_size() > 0) {
|
||||||
|
container_type = kAudio;
|
||||||
|
} else {
|
||||||
|
LOG(ERROR) << "Either video_info or audio_info must be populated.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!AddNewRepresentation(container_type, media_info, container_id))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return mpd_builder_->WriteMpd();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SimpleVodMpdNotifier::NotifyNewSegment(uint32 container_id,
|
||||||
|
uint64 start_time,
|
||||||
|
uint64 duration) {
|
||||||
|
DLOG(INFO) << "VOD does not support this operation.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SimpleVodMpdNotifier::AddContentProtectionElement(
|
||||||
|
uint32 container_id,
|
||||||
|
const ContentProtectionElement& content_protection_element) {
|
||||||
|
if (!ContainsKey(id_to_representation_, container_id))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Representation* representation = id_to_representation_[container_id];
|
||||||
|
|
||||||
|
DCHECK(representation);
|
||||||
|
representation->AddContentProtectionElement(content_protection_element);
|
||||||
|
return mpd_builder_->WriteMpd();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SimpleVodMpdNotifier::AddNewRepresentation(ContainerType type,
|
||||||
|
const MediaInfo& media_info,
|
||||||
|
uint32* container_id) {
|
||||||
|
// Use pointer-pointer to set {video,audio}_adaptation_set_.
|
||||||
|
AdaptationSet** adaptation_set_pp = NULL;
|
||||||
|
if (type == kVideo) {
|
||||||
|
adaptation_set_pp = &video_adaptation_set_;
|
||||||
|
} else if (type == kAudio){
|
||||||
|
adaptation_set_pp = &audio_adaptation_set_;
|
||||||
|
} else {
|
||||||
|
NOTREACHED() << "Unknown container type: " << type;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!*adaptation_set_pp)
|
||||||
|
*adaptation_set_pp = mpd_builder_->AddAdaptationSet();
|
||||||
|
|
||||||
|
AdaptationSet* const adaptation_set = *adaptation_set_pp;
|
||||||
|
Representation* new_representation =
|
||||||
|
adaptation_set->AddRepresentation(media_info);
|
||||||
|
|
||||||
|
if (!new_representation)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const uint32 representation_id = new_representation->id();
|
||||||
|
id_to_representation_[representation_id] = new_representation;
|
||||||
|
*container_id = representation_id;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dash_packager
|
|
@ -0,0 +1,73 @@
|
||||||
|
// Very simple implementation of MpdNotifier. Holds an instance of MpdBuilder
|
||||||
|
// and calls methods on the object directly.
|
||||||
|
#ifndef MPD_BASE_SIMPLE_MPD_NOTIFIER_H_
|
||||||
|
#define MPD_BASE_SIMPLE_MPD_NOTIFIER_H_
|
||||||
|
|
||||||
|
#include "mpd/base/mpd_notifier.h"
|
||||||
|
|
||||||
|
#include "mpd/base/mpd_builder.h"
|
||||||
|
|
||||||
|
namespace dash_packager {
|
||||||
|
|
||||||
|
// This assumes that MpdBuilder is for VOD. This class also assumes that all the
|
||||||
|
// container is for an AdaptationSet.
|
||||||
|
class SimpleVodMpdNotifier : public MpdNotifier {
|
||||||
|
public:
|
||||||
|
// TODO(rkuroiwa): Take File pointer for MPD output.
|
||||||
|
// MpdBuilder must be initialized before passing a pointer to this object.
|
||||||
|
// The ownership of |mpd_builder| does not transfer to this object and it must
|
||||||
|
// be non-NULL.
|
||||||
|
explicit SimpleVodMpdNotifier(MpdBuilder* mpd_builder);
|
||||||
|
virtual ~SimpleVodMpdNotifier();
|
||||||
|
|
||||||
|
// MpdNotifier implementation.
|
||||||
|
// This should be called only once.
|
||||||
|
virtual bool Init() OVERRIDE;
|
||||||
|
|
||||||
|
// Notifies MpdBuilder to add a container. The container must have audio
|
||||||
|
// (logical exclusive) or video, IOW it cannot have both audio and video nor
|
||||||
|
// can both audio and video be empty.
|
||||||
|
// On success this writes out MPD and returns true, otherwise returns false.
|
||||||
|
virtual bool NotifyNewContainer(const MediaInfo& media_info,
|
||||||
|
uint32* id) OVERRIDE;
|
||||||
|
|
||||||
|
// As documented in MpdNotifier. This is Live only feature. This will return
|
||||||
|
// false.
|
||||||
|
virtual bool NotifyNewSegment(uint32 id,
|
||||||
|
uint64 start_time,
|
||||||
|
uint64 duration) OVERRIDE;
|
||||||
|
|
||||||
|
// Adds content protection information to the container added via
|
||||||
|
// NotifyNewContainer(). This will fail if |id| is not a value populated by
|
||||||
|
// calling NotifyNewContainer().
|
||||||
|
// On success this writes out MPD and returns true, otherwise returns false.
|
||||||
|
virtual bool AddContentProtectionElement(
|
||||||
|
uint32 id,
|
||||||
|
const ContentProtectionElement& content_protection_element) OVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum ContainerType {
|
||||||
|
kVideo,
|
||||||
|
kAudio
|
||||||
|
};
|
||||||
|
|
||||||
|
// Adds new Representation to mpd_builder_ on success.
|
||||||
|
// Sets {audio,video}_adaptation_set_ depending on |type|, if it is NULL.
|
||||||
|
bool AddNewRepresentation(ContainerType type,
|
||||||
|
const MediaInfo& media_info,
|
||||||
|
uint32* id);
|
||||||
|
|
||||||
|
// None of these are owned by this object.
|
||||||
|
MpdBuilder* const mpd_builder_;
|
||||||
|
AdaptationSet* audio_adaptation_set_;
|
||||||
|
AdaptationSet* video_adaptation_set_;
|
||||||
|
Representation* representation_;
|
||||||
|
|
||||||
|
std::map<uint32, Representation*> id_to_representation_;
|
||||||
|
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(SimpleVodMpdNotifier);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dash_packager
|
||||||
|
|
||||||
|
#endif // MPD_BASE_SIMPLE_MPD_NOTIFIER_H_
|
Loading…
Reference in New Issue