Changed es_parser_h264 to wait for initial I-frame to start emitting samples.

Change-Id: I7b9ca4a73a8765501a1c29e467e877e1eee5f9d9
This commit is contained in:
Thomas Inskip 2014-06-30 12:53:56 -07:00 committed by Gerrit Code Review
parent f609b2947c
commit fc85154bca
5 changed files with 43 additions and 9 deletions

View File

@ -39,7 +39,8 @@ EsParserH264::EsParserH264(
next_access_unit_pos_(0),
stream_converter_(new H264ByteToUnitStreamConverter),
decoder_config_check_pending_(false),
pending_sample_duration_(0) {
pending_sample_duration_(0),
waiting_for_key_frame_(true) {
}
EsParserH264::~EsParserH264() {
@ -102,6 +103,7 @@ void EsParserH264::Reset() {
decoder_config_check_pending_ = false;
pending_sample_ = scoped_refptr<MediaSample>();
pending_sample_duration_ = 0;
waiting_for_key_frame_ = true;
}
bool EsParserH264::FindAUD(int64* stream_pos) {
@ -233,9 +235,14 @@ bool EsParserH264::ParseInternal() {
}
}
// Emit a frame and move the stream to the next AUD position.
RCHECK(EmitFrame(current_access_unit_pos_, access_unit_size,
is_key_frame, pps_id_for_access_unit));
if (waiting_for_key_frame_) {
waiting_for_key_frame_ = !is_key_frame;
}
if (!waiting_for_key_frame_) {
// Emit a frame and move the stream to the next AUD position.
RCHECK(EmitFrame(current_access_unit_pos_, access_unit_size,
is_key_frame, pps_id_for_access_unit));
}
current_access_unit_pos_ = next_access_unit_pos_;
es_queue_->Trim(current_access_unit_pos_);

View File

@ -94,6 +94,9 @@ class EsParserH264 : public EsParser {
// Frame for which we do not yet have a duration.
scoped_refptr<MediaSample> pending_sample_;
uint64 pending_sample_duration_;
// Indicates whether waiting for first key frame.
bool waiting_for_key_frame_;
};
} // namespace mp2t

View File

@ -117,20 +117,24 @@ void AppendAUD(
class EsParserH264Test : public testing::Test {
public:
EsParserH264Test() : sample_count_(0) {
}
EsParserH264Test()
: sample_count_(0),
first_frame_is_key_frame_(false) {}
void LoadStream(const char* filename);
void ProcessPesPackets(const std::vector<Packet>& pes_packets);
void EmitSample(uint32 pid, scoped_refptr<MediaSample>& sample) {
sample_count_++;
if (sample_count_ == 1)
first_frame_is_key_frame_ = sample->is_key_frame();
}
void NewVideoConfig(scoped_refptr<StreamInfo>& config) {
}
size_t sample_count() const { return sample_count_; }
bool first_frame_is_key_frame() { return first_frame_is_key_frame_; }
// Stream with AUD NALUs.
std::vector<uint8> stream_;
@ -140,6 +144,7 @@ class EsParserH264Test : public testing::Test {
protected:
size_t sample_count_;
bool first_frame_is_key_frame_;
};
void EsParserH264Test::LoadStream(const char* filename) {
@ -204,7 +209,8 @@ TEST_F(EsParserH264Test, OneAccessUnitPerPes) {
// Process each PES packet.
ProcessPesPackets(pes_packets);
ASSERT_EQ(sample_count(), access_units_.size());
EXPECT_EQ(sample_count(), access_units_.size());
EXPECT_TRUE(first_frame_is_key_frame());
}
TEST_F(EsParserH264Test, NonAlignedPesPacket) {
@ -228,7 +234,8 @@ TEST_F(EsParserH264Test, NonAlignedPesPacket) {
// Process each PES packet.
ProcessPesPackets(pes_packets);
ASSERT_EQ(sample_count(), access_units_.size());
EXPECT_EQ(sample_count(), access_units_.size());
EXPECT_TRUE(first_frame_is_key_frame());
}
TEST_F(EsParserH264Test, SeveralPesPerAccessUnit) {
@ -258,7 +265,21 @@ TEST_F(EsParserH264Test, SeveralPesPerAccessUnit) {
// Process each PES packet.
ProcessPesPackets(pes_packets);
ASSERT_EQ(sample_count(), access_units_.size());
EXPECT_EQ(sample_count(), access_units_.size());
EXPECT_TRUE(first_frame_is_key_frame());
}
TEST_F(EsParserH264Test, NonIFrameStart) {
LoadStream("bear_no_iframe_start.h264");
// One to one equivalence between PES packets and access units.
std::vector<Packet> pes_packets(access_units_);
// Process each PES packet.
ProcessPesPackets(pes_packets);
// Ensure samples were emitted, but fewer than number of AUDs.
EXPECT_LT(sample_count(), access_units_.size());
EXPECT_TRUE(first_frame_is_key_frame());
}
} // namespace mp2t

View File

@ -75,5 +75,8 @@ bear.h264:
ffmpeg -i bear.mp4 -vcodec copy -vbsf h264_mp4toannexb \
-an bear.h264
bear_no_i_frame_start.h264
Derived from bear.h264. Consists of 29-non-I-frames, followed by a single I-frame, and 29 non-I-frames.
avc-byte-stream-frame.h264 - Single IDR frame extracted from test-25fps.h264 in Annex B byte stream format.
avc-unit-stream-frame.h264 - Single IDR frame from avc-byte-stream-frame.h264 converted to unit stream format.

Binary file not shown.