Skip to content

Commit

Permalink
Add segment buffer
Browse files Browse the repository at this point in the history
  • Loading branch information
jedekar committed Mar 15, 2024
1 parent 45c8d21 commit c31d405
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 53 deletions.
20 changes: 17 additions & 3 deletions include/packager/live_packager.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,20 @@ class SegmentData final : public Segment {
const size_t size_ = 0;
};

class SegmentBuffer final : public Segment {
public:
SegmentBuffer() = default;
~SegmentBuffer() = default;

void AppendData(const uint8_t* data, size_t size);

virtual const uint8_t* Data() const override;
virtual size_t Size() const override;

private:
std::vector<uint8_t> buffer_;
};

class FullSegmentBuffer final : public Segment {
public:
FullSegmentBuffer() = default;
Expand Down Expand Up @@ -115,7 +129,7 @@ class LivePackager {
/// @param init_segment contains the init segment data.
/// @param output contains the packaged init segment data.
/// @return OK on success, an appropriate error code on failure.
Status PackageInit(const Segment& init_segment, FullSegmentBuffer& output);
Status PackageInit(const Segment& init_segment, SegmentBuffer& output);

/// Performs packaging of segment data.
/// @param init_segment contains the init segment data.
Expand All @@ -124,10 +138,10 @@ class LivePackager {
/// @return OK on success, an appropriate error code on failure.
Status Package(const Segment& init_segment,
const Segment& media_segment,
FullSegmentBuffer& output);
SegmentBuffer& output);

Status PackageTimedText(const Segment& media_segment,
FullSegmentBuffer& output);
SegmentBuffer& output);

LivePackager(const LivePackager&) = delete;
LivePackager& operator=(const LivePackager&) = delete;
Expand Down
17 changes: 14 additions & 3 deletions include/packager/live_packager_export.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ extern "C"
{
#endif

#include <stdbool.h>
#include <stdint.h>

typedef enum OutputFormat {
Expand Down Expand Up @@ -50,14 +51,24 @@ typedef struct LivePackagerConfig {
int64_t timed_text_decode_time;
} LivePackagerConfig_t;


typedef struct LivePackager_buffer_s* LivePackagerBuffer_t;

LivePackagerBuffer_t livepackager_buf_new();
void livepackager_buf_free(LivePackagerBuffer_t buf);

const uint8_t* livepackager_buf_data(LivePackagerBuffer_t buf);
size_t livepackager_buf_size(LivePackagerBuffer_t buf);


typedef struct LivePackager_instance_s* LivePackager_t;

LivePackager_t livepackager_new(LivePackagerConfig_t cfg);
void livepackager_free(LivePackager_t lp);

size_t livepackager_package_init(LivePackager_t lp, uint8_t* init, size_t init_len, uint8_t* dest);
size_t livepackager_package(LivePackager_t lp, uint8_t* init, size_t init_len, uint8_t* seg, size_t seg_len, uint8_t* dest);
size_t livepackager_package_timedtext(LivePackager_t lp, uint8_t* seg, size_t seg_len, uint8_t* dest);
bool livepackager_package_init(LivePackager_t lp, uint8_t* init, size_t init_len, LivePackagerBuffer_t dest);
bool livepackager_package(LivePackager_t lp, uint8_t* init, size_t init_len, uint8_t* media, size_t media_len, LivePackagerBuffer_t dest);
bool livepackager_package_timedtext(LivePackager_t lp, uint8_t* seg, size_t seg_len, LivePackagerBuffer_t dest);

#ifdef __cplusplus
}
Expand Down
105 changes: 58 additions & 47 deletions packager/live_packager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ class SegmentManager {
virtual int64_t OnSegmentWrite(const std::string& name,
const void* buffer,
uint64_t size,
FullSegmentBuffer& out);
SegmentBuffer& out);

virtual Status InitializeEncryption(const LiveConfig& config,
EncryptionParams& encryption_params);
Expand All @@ -202,7 +202,7 @@ class Aes128EncryptedSegmentManager : public SegmentManager {
int64_t OnSegmentWrite(const std::string& name,
const void* buffer,
uint64_t size,
FullSegmentBuffer& out) override;
SegmentBuffer& out) override;

Status InitializeEncryption(const LiveConfig& config,
EncryptionParams& encryption_params) override;
Expand All @@ -226,6 +226,18 @@ size_t SegmentData::Size() const {
return size_;
}

void SegmentBuffer::AppendData(const uint8_t* data, size_t size) {
std::copy(data, data + size, std::back_inserter(buffer_));
}

size_t SegmentBuffer::Size() const {
return buffer_.size();
}

const uint8_t* SegmentBuffer::Data() const {
return buffer_.data();
}

void FullSegmentBuffer::SetInitSegment(const uint8_t* data, size_t size) {
buffer_.clear();
std::copy(data, data + size, std::back_inserter(buffer_));
Expand Down Expand Up @@ -280,7 +292,7 @@ LivePackager::LivePackager(const LiveConfig& config)
LivePackager::~LivePackager() = default;

Status LivePackager::PackageInit(const Segment& init_segment,
FullSegmentBuffer& output) {
SegmentBuffer& output) {
SegmentDataReader reader(init_segment);

shaka::BufferCallbackParams callback_params;
Expand All @@ -289,18 +301,18 @@ Status LivePackager::PackageInit(const Segment& init_segment,
return reader.Read(buffer, size);
};

callback_params.write_func = [&output](const std::string& name,
callback_params.write_func = [](const std::string& name,
const void* data, uint64_t size) {
output.AppendData(reinterpret_cast<const uint8_t*>(data), size);
// output.AppendData(reinterpret_cast<const uint8_t*>(data), size);
return size;
};

shaka::BufferCallbackParams init_callback_params;
init_callback_params.write_func = [&output](const std::string& name,
const void* data, uint64_t size) {
if (output.InitSegmentSize() == 0) {
if (output.Size() == 0) {
LOG(INFO) << "init segment callback, name: " << name << " size: " << size;
output.SetInitSegment(reinterpret_cast<const uint8_t*>(data), size);
output.AppendData(reinterpret_cast<const uint8_t*>(data), size);
}
return size;
};
Expand Down Expand Up @@ -340,7 +352,7 @@ Status LivePackager::PackageInit(const Segment& init_segment,

Status LivePackager::Package(const Segment& init_segment,
const Segment& media_segment,
FullSegmentBuffer& out) {
SegmentBuffer& out) {
MultiSegmentDataReader reader(init_segment, media_segment);
shaka::BufferCallbackParams callback_params;
callback_params.read_func = [&reader](const std::string& name, void* buffer,
Expand All @@ -354,17 +366,17 @@ Status LivePackager::Package(const Segment& init_segment,
};

shaka::BufferCallbackParams init_callback_params;
init_callback_params.write_func = [&out](const std::string& name,
init_callback_params.write_func = [](const std::string& name,
const void* data, uint64_t size) {
// For live packaging it is observed that the init segment callback is
// invoked more than once. The initial callback does not contain the MEHD
// box data and furthermore does not contain fragment duration.
// If an MP4 file is created in real-time, such as used in live-streaming,
// it is not likely that the fragment_duration is known in advance and this
// box may be omitted.
if (out.InitSegmentSize() == 0) {
out.SetInitSegment(reinterpret_cast<const uint8_t*>(data), size);
}
//if (out.InitSegmentSize() == 0) {
// out.SetInitSegment(reinterpret_cast<const uint8_t*>(data), size);
//}
return size;
};

Expand Down Expand Up @@ -403,7 +415,7 @@ Status LivePackager::Package(const Segment& init_segment,
}

Status LivePackager::PackageTimedText(const Segment& in,
FullSegmentBuffer& out) {
SegmentBuffer& out) {
SegmentDataReader reader(in);
shaka::BufferCallbackParams callback_params;
callback_params.read_func = [&reader](const std::string& name, void* buffer,
Expand All @@ -418,11 +430,11 @@ Status LivePackager::PackageTimedText(const Segment& in,
};

shaka::BufferCallbackParams init_callback_params;
init_callback_params.write_func = [&out](const std::string& name,
init_callback_params.write_func = [](const std::string& name,
const void* data, uint64_t size) {
if (out.InitSegmentSize() == 0) {
out.SetInitSegment(reinterpret_cast<const uint8_t*>(data), size);
}
//if (out.InitSegmentSize() == 0) {
// out.SetInitSegment(reinterpret_cast<const uint8_t*>(data), size);
//}
return size;
};

Expand Down Expand Up @@ -453,7 +465,7 @@ SegmentManager::SegmentManager() = default;
int64_t SegmentManager::OnSegmentWrite(const std::string& name,
const void* buffer,
uint64_t size,
FullSegmentBuffer& out) {
SegmentBuffer& out) {
out.AppendData(reinterpret_cast<const uint8_t*>(buffer), size);
return size;
}
Expand Down Expand Up @@ -506,7 +518,7 @@ Aes128EncryptedSegmentManager::~Aes128EncryptedSegmentManager() = default;
int64_t Aes128EncryptedSegmentManager::OnSegmentWrite(const std::string& name,
const void* buffer,
uint64_t size,
FullSegmentBuffer& out) {
SegmentBuffer& out) {
// if (!encryptor_->InitializeWithIv(key_, iv_)) {
// LOG(WARNING) << "failed to initialize encryptor with key and iv";
// // Negative size will trigger a status error within the packager
Expand Down Expand Up @@ -671,39 +683,38 @@ void livepackager_free(LivePackager_t lp) {
delete lp;
}

size_t livepackager_package_init(LivePackager_t lp, uint8_t* init, size_t init_len, uint8_t* dest) {
shaka::SegmentData input(init, init_len);
shaka::FullSegmentBuffer output;
shaka::Status status = lp->inner->PackageInit(input, output);
if (!status.ok()) {
return -1;
}
struct LivePackager_buffer_s {
std::unique_ptr<shaka::SegmentBuffer> inner;
};

std::memcpy(dest, output.InitSegmentData(), output.InitSegmentSize());
return output.InitSegmentSize();
LivePackagerBuffer_t livepackager_buf_new() {
return new LivePackager_buffer_s{std::make_unique<shaka::SegmentBuffer>()};
}

size_t livepackager_package(LivePackager_t lp, uint8_t* init, size_t init_len, uint8_t* seg, size_t seg_len, uint8_t* dest) {
shaka::SegmentData input_init(init, init_len);
shaka::SegmentData input_seg(seg, seg_len);
shaka::FullSegmentBuffer output;
shaka::Status status = lp->inner->Package(input_init, input_seg, output);
if (!status.ok()) {
return -1;
}
void livepackager_buf_free(LivePackagerBuffer_t buf) {
delete buf;
}

std::memcpy(dest, output.SegmentData(), output.SegmentSize());
return output.SegmentSize();
const uint8_t* livepackager_buf_data(LivePackagerBuffer_t buf) {
return buf->inner->Data();
}

size_t livepackager_package_timedtext(LivePackager_t lp, uint8_t* seg, size_t seg_len, uint8_t* dest) {
shaka::SegmentData input_seg(seg, seg_len);
shaka::FullSegmentBuffer output;
shaka::Status status = lp->inner->PackageTimedText(input_seg, output);
if (!status.ok()) {
return -1;
}
size_t livepackager_buf_size(LivePackagerBuffer_t buf) {
return buf->inner->Size();
}

std::memcpy(dest, output.SegmentData(), output.SegmentSize());
return output.SegmentSize();
bool livepackager_package_init(LivePackager_t lp, uint8_t* init, size_t init_len, LivePackagerBuffer_t dest) {
shaka::SegmentData input(init, init_len);
return lp->inner->PackageInit(input, *dest->inner).ok();
}

bool livepackager_package(LivePackager_t lp, uint8_t* init, size_t init_len, uint8_t* media, size_t media_len, LivePackagerBuffer_t dest) {
shaka::SegmentData input_init(init, init_len);
shaka::SegmentData input_media(media, media_len);
return lp->inner->Package(input_init, input_media, *dest->inner).ok();
}

bool livepackager_package_timedtext(LivePackager_t lp, uint8_t* seg, size_t seg_len, LivePackagerBuffer_t dest) {
shaka::SegmentData input_seg(seg, seg_len);
return lp->inner->PackageTimedText(input_seg, *dest->inner).ok();
}

0 comments on commit c31d405

Please sign in to comment.