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_parser_h264.h" | 5 #include "media/formats/mp2t/es_parser_h264.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/numerics/safe_conversions.h" | 8 #include "base/numerics/safe_conversions.h" |
9 #include "media/base/stream_parser_buffer.h" | 9 #include "media/base/stream_parser_buffer.h" |
10 #include "media/base/timestamp_constants.h" | 10 #include "media/base/timestamp_constants.h" |
(...skipping 23 matching lines...) Expand all Loading... |
34 EsParserH264::~EsParserH264() { | 34 EsParserH264::~EsParserH264() { |
35 } | 35 } |
36 | 36 |
37 void EsParserH264::Flush() { | 37 void EsParserH264::Flush() { |
38 DVLOG(1) << __FUNCTION__; | 38 DVLOG(1) << __FUNCTION__; |
39 if (!FindAUD(¤t_access_unit_pos_)) | 39 if (!FindAUD(¤t_access_unit_pos_)) |
40 return; | 40 return; |
41 | 41 |
42 // Simulate an additional AUD to force emitting the last access unit | 42 // Simulate an additional AUD to force emitting the last access unit |
43 // which is assumed to be complete at this point. | 43 // which is assumed to be complete at this point. |
44 uint8 aud[] = { 0x00, 0x00, 0x01, 0x09 }; | 44 uint8_t aud[] = {0x00, 0x00, 0x01, 0x09}; |
45 es_queue_->Push(aud, sizeof(aud)); | 45 es_queue_->Push(aud, sizeof(aud)); |
46 ParseFromEsQueue(); | 46 ParseFromEsQueue(); |
47 | 47 |
48 es_adapter_.Flush(); | 48 es_adapter_.Flush(); |
49 } | 49 } |
50 | 50 |
51 void EsParserH264::ResetInternal() { | 51 void EsParserH264::ResetInternal() { |
52 DVLOG(1) << __FUNCTION__; | 52 DVLOG(1) << __FUNCTION__; |
53 h264_parser_.reset(new H264Parser()); | 53 h264_parser_.reset(new H264Parser()); |
54 current_access_unit_pos_ = 0; | 54 current_access_unit_pos_ = 0; |
55 next_access_unit_pos_ = 0; | 55 next_access_unit_pos_ = 0; |
56 last_video_decoder_config_ = VideoDecoderConfig(); | 56 last_video_decoder_config_ = VideoDecoderConfig(); |
57 es_adapter_.Reset(); | 57 es_adapter_.Reset(); |
58 } | 58 } |
59 | 59 |
60 bool EsParserH264::FindAUD(int64* stream_pos) { | 60 bool EsParserH264::FindAUD(int64_t* stream_pos) { |
61 while (true) { | 61 while (true) { |
62 const uint8* es; | 62 const uint8_t* es; |
63 int size; | 63 int size; |
64 es_queue_->PeekAt(*stream_pos, &es, &size); | 64 es_queue_->PeekAt(*stream_pos, &es, &size); |
65 | 65 |
66 // Find a start code and move the stream to the start code parser position. | 66 // Find a start code and move the stream to the start code parser position. |
67 off_t start_code_offset; | 67 off_t start_code_offset; |
68 off_t start_code_size; | 68 off_t start_code_size; |
69 bool start_code_found = H264Parser::FindStartCode( | 69 bool start_code_found = H264Parser::FindStartCode( |
70 es, size, &start_code_offset, &start_code_size); | 70 es, size, &start_code_offset, &start_code_size); |
71 *stream_pos += start_code_offset; | 71 *stream_pos += start_code_offset; |
72 | 72 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 next_access_unit_pos_ = current_access_unit_pos_ + kMinAUDSize; | 113 next_access_unit_pos_ = current_access_unit_pos_ + kMinAUDSize; |
114 DCHECK_LE(next_access_unit_pos_, es_queue_->tail()); | 114 DCHECK_LE(next_access_unit_pos_, es_queue_->tail()); |
115 } | 115 } |
116 if (!FindAUD(&next_access_unit_pos_)) | 116 if (!FindAUD(&next_access_unit_pos_)) |
117 return true; | 117 return true; |
118 | 118 |
119 // At this point, we know we have a full access unit. | 119 // At this point, we know we have a full access unit. |
120 bool is_key_frame = false; | 120 bool is_key_frame = false; |
121 int pps_id_for_access_unit = -1; | 121 int pps_id_for_access_unit = -1; |
122 | 122 |
123 const uint8* es; | 123 const uint8_t* es; |
124 int size; | 124 int size; |
125 es_queue_->PeekAt(current_access_unit_pos_, &es, &size); | 125 es_queue_->PeekAt(current_access_unit_pos_, &es, &size); |
126 int access_unit_size = base::checked_cast<int, int64>( | 126 int access_unit_size = base::checked_cast<int, int64_t>( |
127 next_access_unit_pos_ - current_access_unit_pos_); | 127 next_access_unit_pos_ - current_access_unit_pos_); |
128 DCHECK_LE(access_unit_size, size); | 128 DCHECK_LE(access_unit_size, size); |
129 h264_parser_->SetStream(es, access_unit_size); | 129 h264_parser_->SetStream(es, access_unit_size); |
130 | 130 |
131 while (true) { | 131 while (true) { |
132 bool is_eos = false; | 132 bool is_eos = false; |
133 H264NALU nalu; | 133 H264NALU nalu; |
134 switch (h264_parser_->AdvanceToNextNALU(&nalu)) { | 134 switch (h264_parser_->AdvanceToNextNALU(&nalu)) { |
135 case H264Parser::kOk: | 135 case H264Parser::kOk: |
136 break; | 136 break; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 | 188 |
189 // Emit a frame and move the stream to the next AUD position. | 189 // Emit a frame and move the stream to the next AUD position. |
190 RCHECK(EmitFrame(current_access_unit_pos_, access_unit_size, | 190 RCHECK(EmitFrame(current_access_unit_pos_, access_unit_size, |
191 is_key_frame, pps_id_for_access_unit)); | 191 is_key_frame, pps_id_for_access_unit)); |
192 current_access_unit_pos_ = next_access_unit_pos_; | 192 current_access_unit_pos_ = next_access_unit_pos_; |
193 es_queue_->Trim(current_access_unit_pos_); | 193 es_queue_->Trim(current_access_unit_pos_); |
194 | 194 |
195 return true; | 195 return true; |
196 } | 196 } |
197 | 197 |
198 bool EsParserH264::EmitFrame(int64 access_unit_pos, int access_unit_size, | 198 bool EsParserH264::EmitFrame(int64_t access_unit_pos, |
199 bool is_key_frame, int pps_id) { | 199 int access_unit_size, |
| 200 bool is_key_frame, |
| 201 int pps_id) { |
200 // Get the access unit timing info. | 202 // Get the access unit timing info. |
201 // Note: |current_timing_desc.pts| might be |kNoTimestamp()| at this point | 203 // Note: |current_timing_desc.pts| might be |kNoTimestamp()| at this point |
202 // if: | 204 // if: |
203 // - the stream is not fully MPEG-2 compliant. | 205 // - the stream is not fully MPEG-2 compliant. |
204 // - or if the stream relies on H264 VUI parameters to compute the timestamps. | 206 // - or if the stream relies on H264 VUI parameters to compute the timestamps. |
205 // See H.222 spec: section 2.7.5 "Conditional coding of timestamps". | 207 // See H.222 spec: section 2.7.5 "Conditional coding of timestamps". |
206 // This part is not yet implemented in EsParserH264. | 208 // This part is not yet implemented in EsParserH264. |
207 // |es_adapter_| will take care of the missing timestamps. | 209 // |es_adapter_| will take care of the missing timestamps. |
208 TimingDesc current_timing_desc = GetTimingDescriptor(access_unit_pos); | 210 TimingDesc current_timing_desc = GetTimingDescriptor(access_unit_pos); |
209 DVLOG_IF(1, current_timing_desc.pts == kNoTimestamp()) | 211 DVLOG_IF(1, current_timing_desc.pts == kNoTimestamp()) |
(...skipping 19 matching lines...) Expand all Loading... |
229 const H264SPS* sps = h264_parser_->GetSPS(pps->seq_parameter_set_id); | 231 const H264SPS* sps = h264_parser_->GetSPS(pps->seq_parameter_set_id); |
230 if (!sps) | 232 if (!sps) |
231 return false; | 233 return false; |
232 RCHECK(UpdateVideoDecoderConfig(sps)); | 234 RCHECK(UpdateVideoDecoderConfig(sps)); |
233 } | 235 } |
234 | 236 |
235 // Emit a frame. | 237 // Emit a frame. |
236 DVLOG(LOG_LEVEL_ES) << "Emit frame: stream_pos=" << current_access_unit_pos_ | 238 DVLOG(LOG_LEVEL_ES) << "Emit frame: stream_pos=" << current_access_unit_pos_ |
237 << " size=" << access_unit_size; | 239 << " size=" << access_unit_size; |
238 int es_size; | 240 int es_size; |
239 const uint8* es; | 241 const uint8_t* es; |
240 es_queue_->PeekAt(current_access_unit_pos_, &es, &es_size); | 242 es_queue_->PeekAt(current_access_unit_pos_, &es, &es_size); |
241 CHECK_GE(es_size, access_unit_size); | 243 CHECK_GE(es_size, access_unit_size); |
242 | 244 |
243 // TODO(wolenetz/acolwell): Validate and use a common cross-parser TrackId | 245 // TODO(wolenetz/acolwell): Validate and use a common cross-parser TrackId |
244 // type and allow multiple video tracks. See https://crbug.com/341581. | 246 // type and allow multiple video tracks. See https://crbug.com/341581. |
245 scoped_refptr<StreamParserBuffer> stream_parser_buffer = | 247 scoped_refptr<StreamParserBuffer> stream_parser_buffer = |
246 StreamParserBuffer::CopyFrom( | 248 StreamParserBuffer::CopyFrom( |
247 es, | 249 es, |
248 access_unit_size, | 250 access_unit_size, |
249 is_key_frame, | 251 is_key_frame, |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 << " height=" << sps->sar_height; | 296 << " height=" << sps->sar_height; |
295 last_video_decoder_config_ = video_decoder_config; | 297 last_video_decoder_config_ = video_decoder_config; |
296 es_adapter_.OnConfigChanged(video_decoder_config); | 298 es_adapter_.OnConfigChanged(video_decoder_config); |
297 } | 299 } |
298 | 300 |
299 return true; | 301 return true; |
300 } | 302 } |
301 | 303 |
302 } // namespace mp2t | 304 } // namespace mp2t |
303 } // namespace media | 305 } // namespace media |
OLD | NEW |