webm2pes: Restore frame fragmentation support.

Cap packet payload at 32 kB. Update test to expect non-zero
packet length.

Change-Id: Ibb68a4ef8d32c049c492ae546c631ef6376e3ffd
This commit is contained in:
Tom Finegan
2016-07-18 10:37:23 -07:00
parent f8bb7149f5
commit 448af971d2
3 changed files with 94 additions and 21 deletions

View File

@@ -18,6 +18,30 @@
#include "mkvparser/mkvparser.h"
#include "mkvparser/mkvreader.h"
// Webm2pes
//
// Webm2pes consumes a WebM file containing a VP8 or VP9 video stream and
// outputs a PES stream suitable for inclusion in a MPEG2 Transport Stream.
//
// In the simplest case the PES stream output by Webm2pes consists of a sequence
// of PES packets with the following structure:
// | PES Header w/PTS | BCMV Header | Payload (VPx frame) |
//
// More typically the output will look like the following due to the PES
// payload size limitations caused by the format of the PES header.
// The PES header contains only 2 bytes of storage for expressing payload size.
// VPx PES streams containing fragmented packets look like this:
//
// | PH PTS | BCMV | Payload fragment 1 | PH | Payload fragment 2 | ...
//
// PH = PES Header
// PH PTS = PES Header with PTS
// BCMV = BCMV Header
//
// Note that start codes are properly escaped by Webm2pes, and start code
// emulation prevention bytes must be stripped from the output stream before
// it can be parsed.
namespace libwebm {
// Stores a value and its size in bits for writing into a PES Optional Header.
@@ -149,7 +173,7 @@ struct PesHeader {
std::uint16_t packet_length = 0; // Number of bytes _after_ this field.
PesOptionalHeader optional_header;
std::size_t size() const {
return optional_header.size_in_bytes() + BCMVHeader::size() +
return optional_header.size_in_bytes() +
6 /* start_code + packet_length */ + packet_length;
}
@@ -172,6 +196,7 @@ class PacketReceiverInterface {
class Webm2Pes {
public:
enum VideoCodec { VP8, VP9 };
const std::size_t kMaxPayloadSize = 32768;
Webm2Pes(const std::string& input_file, const std::string& output_file)
: input_file_name_(input_file), output_file_name_(output_file) {}
@@ -188,9 +213,10 @@ class Webm2Pes {
bool ConvertToFile();
// Converts the VPx video stream to a sequence of PES packets, and calls the
// PacketReceiverInterface::ReceivePacket() once for each PES packet. Returns
// only after full conversion or error. Returns true for success, and false
// when an error occurs.
// PacketReceiverInterface::ReceivePacket() once for each VPx frame. The
// packet sent to the receiver may contain multiple PES packets. Returns only
// after full conversion or error. Returns true for success, and false when
// an error occurs.
bool ConvertToPacketReceiver();
private:
@@ -232,7 +258,7 @@ class Webm2Pes {
// 0x00 0x00 0x01 => 0x00 0x00 0x03 0x01
// 0x00 0x00 0x03 => 0x00 0x00 0x03 0x03
bool CopyAndEscapeStartCodes(const std::uint8_t* raw_input,
int raw_input_length,
std::size_t raw_input_length,
PacketDataBuffer* packet_buffer);
} // namespace libwebm