Chromium Code Reviews| Index: media/formats/mp2t/es_parser_h264.cc |
| diff --git a/media/formats/mp2t/es_parser_h264.cc b/media/formats/mp2t/es_parser_h264.cc |
| index 691678ce81ebd49fb9b3a099c306de3412f11e99..a617b88fcb5ad259b416114960443e0753ef1c75 100644 |
| --- a/media/formats/mp2t/es_parser_h264.cc |
| +++ b/media/formats/mp2t/es_parser_h264.cc |
| @@ -23,6 +23,12 @@ namespace mp2t { |
| // 3 bytes for the start code + 1 byte for the NALU type. |
| const int kMinAUDSize = 4; |
| +// Default video frame duration. |
| +const base::TimeDelta kDefaultFrameDuration( |
|
acolwell GONE FROM CHROMIUM
2014/07/03 00:50:58
nit: Please add a comment saying why you picked 25
|
| + base::TimeDelta::FromMilliseconds(40)); |
| + |
| +const size_t kMaxPtsHistoryLength = 16; |
|
acolwell GONE FROM CHROMIUM
2014/07/03 00:50:58
nit: I'm assuming this is derived based on the max
|
| + |
| EsParserH264::EsParserH264( |
| const NewVideoConfigCB& new_video_config_cb, |
| const EmitBufferCB& emit_buffer_cb) |
| @@ -85,6 +91,7 @@ void EsParserH264::Reset() { |
| next_access_unit_pos_ = 0; |
| timing_desc_list_.clear(); |
| last_video_decoder_config_ = VideoDecoderConfig(); |
| + frame_pts_history_.clear(); |
| } |
| bool EsParserH264::FindAUD(int64* stream_pos) { |
| @@ -237,6 +244,32 @@ bool EsParserH264::EmitFrame(int64 access_unit_pos, int access_unit_size, |
| if (current_timing_desc.pts == kNoTimestamp()) |
| return false; |
| + // In Mpeg2 TS, there is no notion of frame duration. |
| + // Only try to get an estimate of the frame duration. |
| + // TODO(damienv): when the H264 stream has SEI timing information, |
| + // we could get more accurate information about the frame duration. |
| + if (!frame_pts_history_.empty() && |
| + frame_pts_history_.back() > current_timing_desc.pts) { |
| + // To estimate the frame duration, B frames are assigned the same PTS |
| + // as the last non-B frame. |
| + frame_pts_history_.push_back(frame_pts_history_.back()); |
| + } else { |
| + frame_pts_history_.push_back(current_timing_desc.pts); |
| + } |
| + if (frame_pts_history_.size() > kMaxPtsHistoryLength) |
| + frame_pts_history_.pop_front(); |
| + |
| + base::TimeDelta frame_duration = kDefaultFrameDuration; |
| + int pts_count = frame_pts_history_.size(); |
| + if (pts_count > 2) { |
| + base::TimeDelta avg_frame_duration = |
| + (frame_pts_history_.back() - frame_pts_history_.front()) / |
| + (pts_count - 1); |
| + frame_duration = |
| + ((kMaxPtsHistoryLength - pts_count) * kDefaultFrameDuration + |
|
acolwell GONE FROM CHROMIUM
2014/07/03 00:50:58
I'm assuming that you are trying to smooth out the
damienv1
2014/07/07 17:26:34
- In theory, to get the frame duration accurately,
|
| + pts_count * avg_frame_duration) / kMaxPtsHistoryLength; |
| + } |
| + |
| // Update the video decoder configuration if needed. |
| const H264PPS* pps = h264_parser_->GetPPS(pps_id); |
| if (!pps) { |
| @@ -273,6 +306,7 @@ bool EsParserH264::EmitFrame(int64 access_unit_pos, int access_unit_size, |
| 0); |
| stream_parser_buffer->SetDecodeTimestamp(current_timing_desc.dts); |
| stream_parser_buffer->set_timestamp(current_timing_desc.pts); |
| + stream_parser_buffer->set_duration(frame_duration); |
| emit_buffer_cb_.Run(stream_parser_buffer); |
| return true; |
| } |