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/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/numerics/safe_conversions.h" | 9 #include "base/numerics/safe_conversions.h" |
10 #include "media/base/buffers.h" | 10 #include "media/base/buffers.h" |
11 #include "media/base/stream_parser_buffer.h" | 11 #include "media/base/stream_parser_buffer.h" |
12 #include "media/base/video_frame.h" | 12 #include "media/base/video_frame.h" |
13 #include "media/filters/h264_parser.h" | 13 #include "media/filters/h264_parser.h" |
14 #include "media/formats/common/offset_byte_queue.h" | 14 #include "media/formats/common/offset_byte_queue.h" |
| 15 #include "media/formats/mp2t/es_adapter_video.h" |
15 #include "media/formats/mp2t/mp2t_common.h" | 16 #include "media/formats/mp2t/mp2t_common.h" |
16 #include "ui/gfx/rect.h" | 17 #include "ui/gfx/rect.h" |
17 #include "ui/gfx/size.h" | 18 #include "ui/gfx/size.h" |
18 | 19 |
19 namespace media { | 20 namespace media { |
20 namespace mp2t { | 21 namespace mp2t { |
21 | 22 |
22 // An AUD NALU is at least 4 bytes: | 23 // An AUD NALU is at least 4 bytes: |
23 // 3 bytes for the start code + 1 byte for the NALU type. | 24 // 3 bytes for the start code + 1 byte for the NALU type. |
24 const int kMinAUDSize = 4; | 25 const int kMinAUDSize = 4; |
25 | 26 |
26 EsParserH264::EsParserH264( | 27 EsParserH264::EsParserH264( |
27 const NewVideoConfigCB& new_video_config_cb, | 28 const NewVideoConfigCB& new_video_config_cb, |
28 const EmitBufferCB& emit_buffer_cb) | 29 const EmitBufferCB& emit_buffer_cb) |
29 : new_video_config_cb_(new_video_config_cb), | 30 : es_adapter_(new_video_config_cb, emit_buffer_cb), |
30 emit_buffer_cb_(emit_buffer_cb), | 31 es_queue_(new media::OffsetByteQueue()), |
31 es_queue_(new media::OffsetByteQueue()), | 32 h264_parser_(new H264Parser()), |
32 h264_parser_(new H264Parser()), | 33 current_access_unit_pos_(0), |
33 current_access_unit_pos_(0), | 34 next_access_unit_pos_(0) { |
34 next_access_unit_pos_(0) { | |
35 } | 35 } |
36 | 36 |
37 EsParserH264::~EsParserH264() { | 37 EsParserH264::~EsParserH264() { |
38 } | 38 } |
39 | 39 |
40 bool EsParserH264::Parse(const uint8* buf, int size, | 40 bool EsParserH264::Parse(const uint8* buf, int size, |
41 base::TimeDelta pts, | 41 base::TimeDelta pts, |
42 base::TimeDelta dts) { | 42 base::TimeDelta dts) { |
43 // Note: Parse is invoked each time a PES packet has been reassembled. | 43 // Note: Parse is invoked each time a PES packet has been reassembled. |
44 // Unfortunately, a PES packet does not necessarily map | 44 // Unfortunately, a PES packet does not necessarily map |
(...skipping 23 matching lines...) Expand all Loading... |
68 void EsParserH264::Flush() { | 68 void EsParserH264::Flush() { |
69 DVLOG(1) << "EsParserH264::Flush"; | 69 DVLOG(1) << "EsParserH264::Flush"; |
70 if (!FindAUD(¤t_access_unit_pos_)) | 70 if (!FindAUD(¤t_access_unit_pos_)) |
71 return; | 71 return; |
72 | 72 |
73 // Simulate an additional AUD to force emitting the last access unit | 73 // Simulate an additional AUD to force emitting the last access unit |
74 // which is assumed to be complete at this point. | 74 // which is assumed to be complete at this point. |
75 uint8 aud[] = { 0x00, 0x00, 0x01, 0x09 }; | 75 uint8 aud[] = { 0x00, 0x00, 0x01, 0x09 }; |
76 es_queue_->Push(aud, sizeof(aud)); | 76 es_queue_->Push(aud, sizeof(aud)); |
77 ParseInternal(); | 77 ParseInternal(); |
| 78 |
| 79 es_adapter_.Flush(); |
78 } | 80 } |
79 | 81 |
80 void EsParserH264::Reset() { | 82 void EsParserH264::Reset() { |
81 DVLOG(1) << "EsParserH264::Reset"; | 83 DVLOG(1) << "EsParserH264::Reset"; |
82 es_queue_.reset(new media::OffsetByteQueue()); | 84 es_queue_.reset(new media::OffsetByteQueue()); |
83 h264_parser_.reset(new H264Parser()); | 85 h264_parser_.reset(new H264Parser()); |
84 current_access_unit_pos_ = 0; | 86 current_access_unit_pos_ = 0; |
85 next_access_unit_pos_ = 0; | 87 next_access_unit_pos_ = 0; |
86 timing_desc_list_.clear(); | 88 timing_desc_list_.clear(); |
87 last_video_decoder_config_ = VideoDecoderConfig(); | 89 last_video_decoder_config_ = VideoDecoderConfig(); |
| 90 es_adapter_.Reset(); |
88 } | 91 } |
89 | 92 |
90 bool EsParserH264::FindAUD(int64* stream_pos) { | 93 bool EsParserH264::FindAUD(int64* stream_pos) { |
91 while (true) { | 94 while (true) { |
92 const uint8* es; | 95 const uint8* es; |
93 int size; | 96 int size; |
94 es_queue_->PeekAt(*stream_pos, &es, &size); | 97 es_queue_->PeekAt(*stream_pos, &es, &size); |
95 | 98 |
96 // Find a start code and move the stream to the start code parser position. | 99 // Find a start code and move the stream to the start code parser position. |
97 off_t start_code_offset; | 100 off_t start_code_offset; |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 // type and allow multiple video tracks. See https://crbug.com/341581. | 269 // type and allow multiple video tracks. See https://crbug.com/341581. |
267 scoped_refptr<StreamParserBuffer> stream_parser_buffer = | 270 scoped_refptr<StreamParserBuffer> stream_parser_buffer = |
268 StreamParserBuffer::CopyFrom( | 271 StreamParserBuffer::CopyFrom( |
269 es, | 272 es, |
270 access_unit_size, | 273 access_unit_size, |
271 is_key_frame, | 274 is_key_frame, |
272 DemuxerStream::VIDEO, | 275 DemuxerStream::VIDEO, |
273 0); | 276 0); |
274 stream_parser_buffer->SetDecodeTimestamp(current_timing_desc.dts); | 277 stream_parser_buffer->SetDecodeTimestamp(current_timing_desc.dts); |
275 stream_parser_buffer->set_timestamp(current_timing_desc.pts); | 278 stream_parser_buffer->set_timestamp(current_timing_desc.pts); |
276 emit_buffer_cb_.Run(stream_parser_buffer); | 279 es_adapter_.OnNewBuffer(stream_parser_buffer); |
277 return true; | 280 return true; |
278 } | 281 } |
279 | 282 |
280 bool EsParserH264::UpdateVideoDecoderConfig(const H264SPS* sps) { | 283 bool EsParserH264::UpdateVideoDecoderConfig(const H264SPS* sps) { |
281 // Set the SAR to 1 when not specified in the H264 stream. | 284 // Set the SAR to 1 when not specified in the H264 stream. |
282 int sar_width = (sps->sar_width == 0) ? 1 : sps->sar_width; | 285 int sar_width = (sps->sar_width == 0) ? 1 : sps->sar_width; |
283 int sar_height = (sps->sar_height == 0) ? 1 : sps->sar_height; | 286 int sar_height = (sps->sar_height == 0) ? 1 : sps->sar_height; |
284 | 287 |
285 // TODO(damienv): a MAP unit can be either 16 or 32 pixels. | 288 // TODO(damienv): a MAP unit can be either 16 or 32 pixels. |
286 // although it's 16 pixels for progressive non MBAFF frames. | 289 // although it's 16 pixels for progressive non MBAFF frames. |
(...skipping 27 matching lines...) Expand all Loading... |
314 if (!video_decoder_config.Matches(last_video_decoder_config_)) { | 317 if (!video_decoder_config.Matches(last_video_decoder_config_)) { |
315 DVLOG(1) << "Profile IDC: " << sps->profile_idc; | 318 DVLOG(1) << "Profile IDC: " << sps->profile_idc; |
316 DVLOG(1) << "Level IDC: " << sps->level_idc; | 319 DVLOG(1) << "Level IDC: " << sps->level_idc; |
317 DVLOG(1) << "Pic width: " << coded_size.width(); | 320 DVLOG(1) << "Pic width: " << coded_size.width(); |
318 DVLOG(1) << "Pic height: " << coded_size.height(); | 321 DVLOG(1) << "Pic height: " << coded_size.height(); |
319 DVLOG(1) << "log2_max_frame_num_minus4: " | 322 DVLOG(1) << "log2_max_frame_num_minus4: " |
320 << sps->log2_max_frame_num_minus4; | 323 << sps->log2_max_frame_num_minus4; |
321 DVLOG(1) << "SAR: width=" << sps->sar_width | 324 DVLOG(1) << "SAR: width=" << sps->sar_width |
322 << " height=" << sps->sar_height; | 325 << " height=" << sps->sar_height; |
323 last_video_decoder_config_ = video_decoder_config; | 326 last_video_decoder_config_ = video_decoder_config; |
324 new_video_config_cb_.Run(video_decoder_config); | 327 es_adapter_.OnConfigChanged(video_decoder_config); |
325 } | 328 } |
326 | 329 |
327 return true; | 330 return true; |
328 } | 331 } |
329 | 332 |
330 } // namespace mp2t | 333 } // namespace mp2t |
331 } // namespace media | 334 } // namespace media |
332 | 335 |
OLD | NEW |