Changed es_parser_h264 to wait for initial I-frame to start emitting samples.
Change-Id: I7b9ca4a73a8765501a1c29e467e877e1eee5f9d9
This commit is contained in:
parent
f609b2947c
commit
fc85154bca
|
@ -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_);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
Loading…
Reference in New Issue