Fix for video frame corruption which occurred when PES packet payloads

are not a size multiple of 16 bytes.

Change-Id: I6e7f524ef17177a1e293cb22e52afa59abacd0de
This commit is contained in:
Thomas Inskip 2014-11-25 13:42:16 -08:00
parent fe9c4201f3
commit fedf9b4233
2 changed files with 36 additions and 29 deletions

View File

@ -82,26 +82,28 @@ namespace edash_packager {
namespace media { namespace media {
namespace wvm { namespace wvm {
WvmMediaParser::WvmMediaParser() : is_initialized_(false), WvmMediaParser::WvmMediaParser()
parse_state_(StartCode1), : is_initialized_(false),
is_psm_needed_(true), parse_state_(StartCode1),
skip_bytes_(0), is_psm_needed_(true),
metadata_is_complete_(false), skip_bytes_(0),
current_program_id_(0), metadata_is_complete_(false),
pes_stream_id_(0), current_program_id_(0),
prev_pes_stream_id_(0), pes_stream_id_(0),
pes_packet_bytes_(0), prev_pes_stream_id_(0),
pes_flags_1_(0), pes_packet_bytes_(0),
pes_flags_2_(0), pes_flags_1_(0),
prev_pes_flags_1_(0), pes_flags_2_(0),
pes_header_data_bytes_(0), prev_pes_flags_1_(0),
timestamp_(0), pes_header_data_bytes_(0),
pts_(0), timestamp_(0),
dts_(0), pts_(0),
index_program_id_(0), dts_(0),
media_sample_(NULL), index_program_id_(0),
stream_id_count_(0), media_sample_(NULL),
decryption_key_source_(NULL) { crypto_unit_start_pos_(0),
stream_id_count_(0),
decryption_key_source_(NULL) {
} }
WvmMediaParser::~WvmMediaParser() {} WvmMediaParser::~WvmMediaParser() {}
@ -725,9 +727,19 @@ bool WvmMediaParser::ParseIndexEntry() {
} }
bool WvmMediaParser::DemuxNextPes(uint8_t* read_ptr, bool is_program_end) { bool WvmMediaParser::DemuxNextPes(uint8_t* read_ptr, bool is_program_end) {
if (!sample_data_.empty() && (prev_pes_flags_1_ & kScramblingBitsMask)) {
// Decrypt crypto unit.
if (!content_decryptor_) {
LOG(ERROR) << "Source content is encrypted, but decryption not enabled";
return false;
}
content_decryptor_->Decrypt(&sample_data_[crypto_unit_start_pos_],
sample_data_.size() - crypto_unit_start_pos_,
&sample_data_[crypto_unit_start_pos_]);
}
// Demux media sample if we are at program end or if we are not at a // Demux media sample if we are at program end or if we are not at a
// continuation PES. // continuation PES.
if (is_program_end || (pes_flags_2_ & kPesOptPts)) { if ((pes_flags_2_ & kPesOptPts) || is_program_end) {
if (!sample_data_.empty()) { if (!sample_data_.empty()) {
if (!Output()) { if (!Output()) {
return false; return false;
@ -735,6 +747,8 @@ bool WvmMediaParser::DemuxNextPes(uint8_t* read_ptr, bool is_program_end) {
} }
StartMediaSampleDemux(read_ptr); StartMediaSampleDemux(read_ptr);
} }
crypto_unit_start_pos_ = sample_data_.size();
return true; return true;
} }
@ -749,14 +763,6 @@ void WvmMediaParser::StartMediaSampleDemux(uint8_t* read_ptr) {
} }
bool WvmMediaParser::Output() { bool WvmMediaParser::Output() {
// Check decrypted sample data.
if (prev_pes_flags_1_ & kScramblingBitsMask) {
if (!content_decryptor_) {
LOG(ERROR) << "Source content is encrypted, but decryption not enabled";
return false;
}
content_decryptor_->Decrypt(sample_data_, &sample_data_);
}
if ((prev_pes_stream_id_ & kPesStreamIdVideoMask) == kPesStreamIdVideo) { if ((prev_pes_stream_id_ & kPesStreamIdVideoMask) == kPesStreamIdVideo) {
// Set data on the video stream from the NalUnitStream. // Set data on the video stream from the NalUnitStream.
std::vector<uint8_t> nal_unit_stream; std::vector<uint8_t> nal_unit_stream;

View File

@ -236,6 +236,7 @@ class WvmMediaParser : public MediaParser {
uint64_t dts_; uint64_t dts_;
uint8_t index_program_id_; uint8_t index_program_id_;
scoped_refptr<MediaSample> media_sample_; scoped_refptr<MediaSample> media_sample_;
uint32_t crypto_unit_start_pos_;
PrevSampleData prev_media_sample_data_; PrevSampleData prev_media_sample_data_;
H264ByteToUnitStreamConverter byte_to_unit_stream_converter_; H264ByteToUnitStreamConverter byte_to_unit_stream_converter_;