shaka-packager/packager/hls/base/media_playlist.h

209 lines
7.5 KiB
C
Raw Normal View History

// Copyright 2016 Google Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
#ifndef PACKAGER_HLS_BASE_MEDIA_PLAYLIST_H_
#define PACKAGER_HLS_BASE_MEDIA_PLAYLIST_H_
#include <list>
#include <memory>
#include <string>
#include "packager/base/macros.h"
#include "packager/mpd/base/media_info.pb.h"
namespace shaka {
namespace media {
class File;
} // namespace media
namespace hls {
class HlsEntry {
public:
enum class EntryType {
kExtInf,
kExtKey,
kExtDiscontinuity,
};
virtual ~HlsEntry();
EntryType type() const { return type_; }
virtual std::string ToString() = 0;
protected:
explicit HlsEntry(EntryType type);
private:
EntryType type_;
};
/// Methods are virtual for mocking.
class MediaPlaylist {
public:
enum class MediaPlaylistType {
kVod,
kEvent,
kLive,
};
enum class MediaPlaylistStreamType {
kPlaylistUnknown,
kPlayListAudio,
kPlayListVideo,
kPlayListSubtitle,
};
enum class EncryptionMethod {
kNone, // No encryption, i.e. clear.
kAes128, // Completely encrypted using AES-CBC.
kSampleAes, // Encrypted using SAMPLE-AES method.
kSampleAesCenc, // 'cenc' encrypted content.
};
/// @param type is the type of this media playlist.
/// @param time_shift_buffer_depth determines the duration of the time
/// shifting buffer, only for live HLS.
/// @param file_name is the file name of this media playlist.
/// @param name is the name of this playlist. In other words this is the
/// value of the NAME attribute for EXT-X-MEDIA. This is not
/// necessarily the same as @a file_name.
/// @param group_id is the group ID for this playlist. This is the value of
/// GROUP-ID attribute for EXT-X-MEDIA.
MediaPlaylist(MediaPlaylistType playlist_type,
double time_shift_buffer_depth,
const std::string& file_name,
const std::string& name,
const std::string& group_id);
virtual ~MediaPlaylist();
const std::string& file_name() const { return file_name_; }
const std::string& name() const { return name_; }
const std::string& group_id() const { return group_id_; }
MediaPlaylistStreamType stream_type() const { return stream_type_; }
const std::string& codec() const { return codec_; }
/// For testing only.
void SetStreamTypeForTesting(MediaPlaylistStreamType stream_type);
/// For testing only.
void SetCodecForTesting(const std::string& codec);
/// This must succeed before calling any other public methods.
/// @param media_info is the info of the segments that are going to be added
/// to this playlist.
/// @return true on success, false otherwise.
virtual bool SetMediaInfo(const MediaInfo& media_info);
/// Segments must be added in order.
/// @param file_name is the file name of the segment.
/// @param start_time is in terms of the timescale of the media.
/// @param duration is in terms of the timescale of the media.
/// @param start_byte_offset is the offset of where the subsegment starts.
/// This must be 0 if the whole segment is a subsegment.
/// @param size is size in bytes.
virtual void AddSegment(const std::string& file_name,
uint64_t start_time,
uint64_t duration,
uint64_t start_byte_offset,
uint64_t size);
/// All segments added after calling this method must be decryptable with
/// the key that can be fetched from |url|, until calling this again.
/// @param method is the encryption method.
/// @param url specifies where the key is i.e. the value of the URI attribute.
/// #param key_id is the default key ID for the encrypted segements.
/// @param iv is the initialization vector in human readable format, i.e. the
/// value for IV attribute. This may be empty.
/// @param key_format is the key format, i.e. the KEYFORMAT value. This may be
/// empty.
/// @param key_format_versions is the KEYFORMATVERIONS value. This may be
/// empty.
virtual void AddEncryptionInfo(EncryptionMethod method,
const std::string& url,
const std::string& key_id,
const std::string& iv,
const std::string& key_format,
const std::string& key_format_versions);
/// Write the playlist to |file_path|.
/// This does not close the file.
/// If target duration is not set expliticly, this will try to find the target
/// duration. Note that target duration cannot be changed. So calling this
/// without explicitly setting the target duration and before adding any
/// segments will end up setting the target duration to 0 and will always
/// generate an invalid playlist.
/// @param file_path is the output file path accepted by the File
/// implementation.
/// @return true on success, false otherwise.
virtual bool WriteToFile(const std::string& file_path);
/// If bitrate is specified in MediaInfo then it will use that value.
/// Otherwise, returns the max bitrate.
/// @return the bitrate (in bits per second) of this MediaPlaylist.
virtual uint64_t Bitrate() const;
/// @return the longest segments duration. This will return 0 if no
/// segments have been added.
virtual double GetLongestSegmentDuration() const;
/// Set the target duration of this MediaPlaylist.
/// In other words this is the value for EXT-X-TARGETDURATION.
/// If this is not called before calling Write(), it will estimate the best
/// target duration.
/// The spec does not allow changing EXT-X-TARGETDURATION. However, this class
/// has no control over the input source.
/// @param target_duration is the target duration for this playlist.
virtual void SetTargetDuration(uint32_t target_duration);
/// @return the language of the media, as an ISO language tag in its shortest
/// form. May be an empty string for video.
virtual std::string GetLanguage() const;
/// @return true if |width| and |height| have been set with a valid
/// resolution values.
virtual bool GetResolution(uint32_t* width, uint32_t* height) const;
private:
// Remove elements from |entries_| for live profile. Increments
// |sequence_number_| by the number of segments removed.
void SlideWindow();
const MediaPlaylistType playlist_type_;
const double time_shift_buffer_depth_;
// Mainly for MasterPlaylist to use these values.
const std::string file_name_;
const std::string name_;
const std::string group_id_;
MediaInfo media_info_;
MediaPlaylistStreamType stream_type_ =
MediaPlaylistStreamType::kPlaylistUnknown;
std::string codec_;
int media_sequence_number_ = 0;
bool inserted_discontinuity_tag_ = false;
int discontinuity_sequence_number_ = 0;
double longest_segment_duration_ = 0.0;
uint32_t time_scale_ = 0;
uint64_t max_bitrate_ = 0;
// Cache the previous calls AddSegment() end offset. This is used to construct
// SegmentInfoEntry.
uint64_t previous_segment_end_offset_ = 0;
// See SetTargetDuration() comments.
bool target_duration_set_ = false;
uint32_t target_duration_ = 0;
std::list<std::unique_ptr<HlsEntry>> entries_;
DISALLOW_COPY_AND_ASSIGN(MediaPlaylist);
};
} // namespace hls
} // namespace shaka
#endif // PACKAGER_HLS_BASE_MEDIA_PLAYLIST_H_