| 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 |