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