OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/formats/mp2t/es_adapter_video.h" | 5 #include "media/formats/mp2t/es_adapter_video.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include "media/base/timestamp_constants.h" | 9 #include "media/base/timestamp_constants.h" |
10 #include "media/base/video_decoder_config.h" | 10 #include "media/base/video_decoder_config.h" |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 void EsAdapterVideo::OnConfigChanged( | 68 void EsAdapterVideo::OnConfigChanged( |
69 const VideoDecoderConfig& video_decoder_config) { | 69 const VideoDecoderConfig& video_decoder_config) { |
70 config_list_.push_back( | 70 config_list_.push_back( |
71 ConfigEntry(buffer_index_ + buffer_list_.size(), video_decoder_config)); | 71 ConfigEntry(buffer_index_ + buffer_list_.size(), video_decoder_config)); |
72 has_valid_config_ = true; | 72 has_valid_config_ = true; |
73 ProcessPendingBuffers(false); | 73 ProcessPendingBuffers(false); |
74 } | 74 } |
75 | 75 |
76 bool EsAdapterVideo::OnNewBuffer( | 76 bool EsAdapterVideo::OnNewBuffer( |
77 const scoped_refptr<StreamParserBuffer>& stream_parser_buffer) { | 77 const scoped_refptr<StreamParserBuffer>& stream_parser_buffer) { |
78 if (stream_parser_buffer->timestamp() == kNoTimestamp()) { | 78 if (stream_parser_buffer->timestamp() == kNoTimestamp) { |
79 if (has_valid_frame_) { | 79 if (has_valid_frame_) { |
80 // There is currently no error concealment for a missing timestamp | 80 // There is currently no error concealment for a missing timestamp |
81 // in the middle of the stream. | 81 // in the middle of the stream. |
82 DVLOG(1) << "Missing timestamp in the middle of the stream"; | 82 DVLOG(1) << "Missing timestamp in the middle of the stream"; |
83 return false; | 83 return false; |
84 } | 84 } |
85 | 85 |
86 if (!has_valid_initial_timestamp_) { | 86 if (!has_valid_initial_timestamp_) { |
87 // MPEG-2 TS requires the first access unit to be given a timestamp. | 87 // MPEG-2 TS requires the first access unit to be given a timestamp. |
88 // However, some streams do not comply with this requirement. | 88 // However, some streams do not comply with this requirement. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 // Signal a config change, just before emitting the corresponding frame. | 136 // Signal a config change, just before emitting the corresponding frame. |
137 if (!config_list_.empty() && config_list_.front().first == buffer_index_) { | 137 if (!config_list_.empty() && config_list_.front().first == buffer_index_) { |
138 new_video_config_cb_.Run(config_list_.front().second); | 138 new_video_config_cb_.Run(config_list_.front().second); |
139 config_list_.pop_front(); | 139 config_list_.pop_front(); |
140 } | 140 } |
141 | 141 |
142 scoped_refptr<StreamParserBuffer> buffer = buffer_list_.front(); | 142 scoped_refptr<StreamParserBuffer> buffer = buffer_list_.front(); |
143 buffer_list_.pop_front(); | 143 buffer_list_.pop_front(); |
144 buffer_index_++; | 144 buffer_index_++; |
145 | 145 |
146 if (buffer->duration() == kNoTimestamp()) { | 146 if (buffer->duration() == kNoTimestamp) { |
147 base::TimeDelta next_frame_pts = GetNextFramePts(buffer->timestamp()); | 147 base::TimeDelta next_frame_pts = GetNextFramePts(buffer->timestamp()); |
148 if (next_frame_pts == kNoTimestamp()) { | 148 if (next_frame_pts == kNoTimestamp) { |
149 // This can happen when emitting the very last buffer | 149 // This can happen when emitting the very last buffer |
150 // or if the stream do not meet the assumption behind |kHistorySize|. | 150 // or if the stream do not meet the assumption behind |kHistorySize|. |
151 DVLOG(LOG_LEVEL_ES) << "Using last frame duration: " | 151 DVLOG(LOG_LEVEL_ES) << "Using last frame duration: " |
152 << last_frame_duration_.InMilliseconds(); | 152 << last_frame_duration_.InMilliseconds(); |
153 buffer->set_duration(last_frame_duration_); | 153 buffer->set_duration(last_frame_duration_); |
154 } else { | 154 } else { |
155 base::TimeDelta duration = next_frame_pts - buffer->timestamp(); | 155 base::TimeDelta duration = next_frame_pts - buffer->timestamp(); |
156 DVLOG(LOG_LEVEL_ES) << "Frame duration: " << duration.InMilliseconds(); | 156 DVLOG(LOG_LEVEL_ES) << "Frame duration: " << duration.InMilliseconds(); |
157 buffer->set_duration(duration); | 157 buffer->set_duration(duration); |
158 } | 158 } |
159 } | 159 } |
160 | 160 |
161 emitted_pts_.push_back(buffer->timestamp()); | 161 emitted_pts_.push_back(buffer->timestamp()); |
162 if (emitted_pts_.size() > kHistorySize) | 162 if (emitted_pts_.size() > kHistorySize) |
163 emitted_pts_.pop_front(); | 163 emitted_pts_.pop_front(); |
164 | 164 |
165 last_frame_duration_ = buffer->duration(); | 165 last_frame_duration_ = buffer->duration(); |
166 emit_buffer_cb_.Run(buffer); | 166 emit_buffer_cb_.Run(buffer); |
167 } | 167 } |
168 } | 168 } |
169 | 169 |
170 base::TimeDelta EsAdapterVideo::GetNextFramePts(base::TimeDelta current_pts) { | 170 base::TimeDelta EsAdapterVideo::GetNextFramePts(base::TimeDelta current_pts) { |
171 base::TimeDelta next_pts = kNoTimestamp(); | 171 base::TimeDelta next_pts = kNoTimestamp; |
172 | 172 |
173 // Consider the timestamps of future frames (in decode order). | 173 // Consider the timestamps of future frames (in decode order). |
174 // Note: the next frame is not enough when the GOP includes some B frames. | 174 // Note: the next frame is not enough when the GOP includes some B frames. |
175 for (BufferQueue::const_iterator it = buffer_list_.begin(); | 175 for (BufferQueue::const_iterator it = buffer_list_.begin(); |
176 it != buffer_list_.end(); ++it) { | 176 it != buffer_list_.end(); ++it) { |
177 if ((*it)->timestamp() < current_pts) | 177 if ((*it)->timestamp() < current_pts) |
178 continue; | 178 continue; |
179 if (next_pts == kNoTimestamp() || next_pts > (*it)->timestamp()) | 179 if (next_pts == kNoTimestamp || next_pts > (*it)->timestamp()) |
180 next_pts = (*it)->timestamp(); | 180 next_pts = (*it)->timestamp(); |
181 } | 181 } |
182 | 182 |
183 // Consider the timestamps of previous frames (in decode order). | 183 // Consider the timestamps of previous frames (in decode order). |
184 // In a simple GOP structure with B frames, the frame next to the last B | 184 // In a simple GOP structure with B frames, the frame next to the last B |
185 // frame (in presentation order) is located before in decode order. | 185 // frame (in presentation order) is located before in decode order. |
186 for (std::list<base::TimeDelta>::const_iterator it = emitted_pts_.begin(); | 186 for (std::list<base::TimeDelta>::const_iterator it = emitted_pts_.begin(); |
187 it != emitted_pts_.end(); ++it) { | 187 it != emitted_pts_.end(); ++it) { |
188 if (*it < current_pts) | 188 if (*it < current_pts) |
189 continue; | 189 continue; |
190 if (next_pts == kNoTimestamp() || next_pts > *it) | 190 if (next_pts == kNoTimestamp || next_pts > *it) |
191 next_pts = *it; | 191 next_pts = *it; |
192 } | 192 } |
193 | 193 |
194 return next_pts; | 194 return next_pts; |
195 } | 195 } |
196 | 196 |
197 void EsAdapterVideo::ReplaceDiscardedFrames( | 197 void EsAdapterVideo::ReplaceDiscardedFrames( |
198 const scoped_refptr<StreamParserBuffer>& stream_parser_buffer) { | 198 const scoped_refptr<StreamParserBuffer>& stream_parser_buffer) { |
199 DCHECK_GT(discarded_frame_count_, 0); | 199 DCHECK_GT(discarded_frame_count_, 0); |
200 DCHECK(stream_parser_buffer->is_key_frame()); | 200 DCHECK(stream_parser_buffer->is_key_frame()); |
(...skipping 27 matching lines...) Expand all Loading... |
228 frame->set_duration(pts_delta); | 228 frame->set_duration(pts_delta); |
229 buffer_list_.push_back(frame); | 229 buffer_list_.push_back(frame); |
230 pts += pts_delta; | 230 pts += pts_delta; |
231 dts += dts_delta; | 231 dts += dts_delta; |
232 } | 232 } |
233 discarded_frame_count_ = 0; | 233 discarded_frame_count_ = 0; |
234 } | 234 } |
235 | 235 |
236 } // namespace mp2t | 236 } // namespace mp2t |
237 } // namespace media | 237 } // namespace media |
OLD | NEW |