webm2pes: Move frame read out of PES packet write method.
Makes writing tests easier by allowing caller to pass data for packetizing directly into the method. Change-Id: I553fa8c1636041c4a5ff043862918a5cdc9163ba
This commit is contained in:
parent
448af971d2
commit
8f840ddaa3
@ -235,12 +235,18 @@ bool Webm2Pes::ConvertToFile() {
|
||||
|
||||
// Walk frames in block.
|
||||
for (int frame_num = 0; frame_num < frame_count; ++frame_num) {
|
||||
const mkvparser::Block::Frame& frame = block->GetFrame(frame_num);
|
||||
const mkvparser::Block::Frame& mkvparser_frame =
|
||||
block->GetFrame(frame_num);
|
||||
|
||||
// Write frame out as PES packet(s), storing them in |packet_data_|.
|
||||
const bool pes_status = WritePesPacket(
|
||||
frame, static_cast<double>(block->GetTime(cluster)));
|
||||
if (pes_status != true) {
|
||||
// Read the frame.
|
||||
VpxFrame vpx_frame(block->GetTime(cluster));
|
||||
if (ReadVpxFrame(mkvparser_frame, &vpx_frame) == false) {
|
||||
fprintf(stderr, "Webm2Pes: frame read failed.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write frame out as PES packet(s).
|
||||
if (WritePesPacket(vpx_frame) == false) {
|
||||
std::fprintf(stderr, "Webm2Pes: WritePesPacket failed.\n");
|
||||
return false;
|
||||
}
|
||||
@ -297,12 +303,18 @@ bool Webm2Pes::ConvertToPacketReceiver() {
|
||||
|
||||
// Walk frames in block.
|
||||
for (int frame_num = 0; frame_num < frame_count; ++frame_num) {
|
||||
const mkvparser::Block::Frame& frame = block->GetFrame(frame_num);
|
||||
const mkvparser::Block::Frame& mkvparser_frame =
|
||||
block->GetFrame(frame_num);
|
||||
|
||||
// Read the frame.
|
||||
VpxFrame vpx_frame(block->GetTime(cluster));
|
||||
if (ReadVpxFrame(mkvparser_frame, &vpx_frame) == false) {
|
||||
fprintf(stderr, "Webm2Pes: frame read failed.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Write frame out as PES packet(s).
|
||||
const bool pes_status = WritePesPacket(
|
||||
frame, static_cast<double>(block->GetTime(cluster)));
|
||||
if (pes_status != true) {
|
||||
if (WritePesPacket(vpx_frame) == false) {
|
||||
std::fprintf(stderr, "Webm2Pes: WritePesPacket failed.\n");
|
||||
return false;
|
||||
}
|
||||
@ -384,35 +396,44 @@ bool Webm2Pes::InitWebmParser() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Webm2Pes::WritePesPacket(const mkvparser::Block::Frame& vpx_frame,
|
||||
double nanosecond_pts) {
|
||||
// Read the input frame.
|
||||
std::unique_ptr<uint8_t[]> frame_data(new (std::nothrow)
|
||||
uint8_t[vpx_frame.len]);
|
||||
if (frame_data.get() == nullptr) {
|
||||
bool Webm2Pes::ReadVpxFrame(const mkvparser::Block::Frame& mkvparser_frame,
|
||||
VpxFrame* frame) {
|
||||
if (mkvparser_frame.len < 1 || frame == nullptr)
|
||||
return false;
|
||||
|
||||
frame->length = mkvparser_frame.len;
|
||||
frame->data.reset(new (std::nothrow) uint8_t[mkvparser_frame.len]);
|
||||
if (frame->data.get() == nullptr) {
|
||||
std::fprintf(stderr, "Webm2Pes: Out of memory.\n");
|
||||
return false;
|
||||
}
|
||||
if (vpx_frame.Read(&webm_reader_, frame_data.get()) != 0) {
|
||||
if (mkvparser_frame.Read(&webm_reader_, frame->data.get()) != 0) {
|
||||
std::fprintf(stderr, "Webm2Pes: Error reading VPx frame!\n");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Webm2Pes::WritePesPacket(const VpxFrame& vpx_frame) {
|
||||
if (vpx_frame.data.get() == nullptr || vpx_frame.length < 1)
|
||||
return false;
|
||||
|
||||
Ranges frame_ranges;
|
||||
if (codec_ == VP9) {
|
||||
bool has_superframe_index =
|
||||
ParseVP9SuperFrameIndex(frame_data.get(), vpx_frame.len, &frame_ranges);
|
||||
const bool has_superframe_index = ParseVP9SuperFrameIndex(
|
||||
vpx_frame.data.get(), vpx_frame.length, &frame_ranges);
|
||||
if (has_superframe_index == false) {
|
||||
frame_ranges.push_back(Range(0, vpx_frame.len));
|
||||
frame_ranges.push_back(Range(0, vpx_frame.length));
|
||||
}
|
||||
} else {
|
||||
frame_ranges.push_back(Range(0, vpx_frame.len));
|
||||
frame_ranges.push_back(Range(0, vpx_frame.length));
|
||||
}
|
||||
|
||||
///
|
||||
/// TODO: DEBUG/REMOVE
|
||||
///
|
||||
printf("-FRAME TOTAL LENGTH %ld--\n", vpx_frame.len);
|
||||
printf("-FRAME TOTAL LENGTH %u\n",
|
||||
static_cast<unsigned int>(vpx_frame.length));
|
||||
for (const Range& frame_range : frame_ranges) {
|
||||
printf("--frame range: off:%u len:%u\n",
|
||||
static_cast<unsigned int>(frame_range.offset),
|
||||
@ -420,7 +441,7 @@ bool Webm2Pes::WritePesPacket(const mkvparser::Block::Frame& vpx_frame,
|
||||
}
|
||||
|
||||
const std::int64_t khz90_pts =
|
||||
NanosecondsTo90KhzTicks(static_cast<std::int64_t>(nanosecond_pts));
|
||||
NanosecondsTo90KhzTicks(vpx_frame.nanosecond_pts);
|
||||
PesHeader header;
|
||||
header.optional_header.SetPtsBits(khz90_pts);
|
||||
|
||||
@ -447,7 +468,7 @@ bool Webm2Pes::WritePesPacket(const mkvparser::Block::Frame& vpx_frame,
|
||||
|
||||
// Insert the payload at the end of |packet_data_|.
|
||||
const std::uint8_t* payload_start =
|
||||
frame_data.get() + packet_payload_range.offset;
|
||||
vpx_frame.data.get() + packet_payload_range.offset;
|
||||
|
||||
const std::size_t bytes_to_copy = packet_payload_range.length - extra_bytes;
|
||||
if (CopyAndEscapeStartCodes(payload_start, bytes_to_copy, &packet_data_) ==
|
||||
|
@ -189,6 +189,16 @@ class PacketReceiverInterface {
|
||||
virtual bool ReceivePacket(const PacketDataBuffer& packet) = 0;
|
||||
};
|
||||
|
||||
struct VpxFrame {
|
||||
VpxFrame() = default;
|
||||
~VpxFrame() = default;
|
||||
explicit VpxFrame(std::int64_t pts_in_nanoseconds)
|
||||
: nanosecond_pts(pts_in_nanoseconds) {}
|
||||
std::unique_ptr<std::uint8_t[]> data;
|
||||
std::size_t length = 0;
|
||||
std::int64_t nanosecond_pts = 0;
|
||||
};
|
||||
|
||||
// Converts the VP9 track of a WebM file to a Packetized Elementary Stream
|
||||
// suitable for use in a MPEG2TS.
|
||||
// https://en.wikipedia.org/wiki/Packetized_elementary_stream
|
||||
@ -221,8 +231,9 @@ class Webm2Pes {
|
||||
|
||||
private:
|
||||
bool InitWebmParser();
|
||||
bool WritePesPacket(const mkvparser::Block::Frame& vpx_frame,
|
||||
double nanosecond_pts);
|
||||
bool ReadVpxFrame(const mkvparser::Block::Frame& mkvparser_frame,
|
||||
VpxFrame* vpx_frame);
|
||||
bool WritePesPacket(const VpxFrame& vpx_frame);
|
||||
|
||||
const std::string input_file_name_;
|
||||
const std::string output_file_name_;
|
||||
|
Loading…
x
Reference in New Issue
Block a user