OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/filters/vpx_video_decoder.h" | 5 #include "media/filters/vpx_video_decoder.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <string> | 8 #include <string> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 public base::trace_event::MemoryDumpProvider { | 104 public base::trace_event::MemoryDumpProvider { |
105 public: | 105 public: |
106 MemoryPool(); | 106 MemoryPool(); |
107 | 107 |
108 // Callback that will be called by libvpx when it needs a frame buffer. | 108 // Callback that will be called by libvpx when it needs a frame buffer. |
109 // Parameters: | 109 // Parameters: |
110 // |user_priv| Private data passed to libvpx (pointer to memory pool). | 110 // |user_priv| Private data passed to libvpx (pointer to memory pool). |
111 // |min_size| Minimum size needed by libvpx to decompress the next frame. | 111 // |min_size| Minimum size needed by libvpx to decompress the next frame. |
112 // |fb| Pointer to the frame buffer to update. | 112 // |fb| Pointer to the frame buffer to update. |
113 // Returns 0 on success. Returns < 0 on failure. | 113 // Returns 0 on success. Returns < 0 on failure. |
114 static int32 GetVP9FrameBuffer(void* user_priv, size_t min_size, | 114 static int32_t GetVP9FrameBuffer(void* user_priv, |
115 vpx_codec_frame_buffer* fb); | 115 size_t min_size, |
| 116 vpx_codec_frame_buffer* fb); |
116 | 117 |
117 // Callback that will be called by libvpx when the frame buffer is no longer | 118 // Callback that will be called by libvpx when the frame buffer is no longer |
118 // being used by libvpx. Parameters: | 119 // being used by libvpx. Parameters: |
119 // |user_priv| Private data passed to libvpx (pointer to memory pool). | 120 // |user_priv| Private data passed to libvpx (pointer to memory pool). |
120 // |fb| Pointer to the frame buffer that's being released. | 121 // |fb| Pointer to the frame buffer that's being released. |
121 static int32 ReleaseVP9FrameBuffer(void* user_priv, | 122 static int32_t ReleaseVP9FrameBuffer(void* user_priv, |
122 vpx_codec_frame_buffer* fb); | 123 vpx_codec_frame_buffer* fb); |
123 | 124 |
124 // Generates a "no_longer_needed" closure that holds a reference to this pool. | 125 // Generates a "no_longer_needed" closure that holds a reference to this pool. |
125 base::Closure CreateFrameCallback(void* fb_priv_data); | 126 base::Closure CreateFrameCallback(void* fb_priv_data); |
126 | 127 |
127 // base::MemoryDumpProvider. | 128 // base::MemoryDumpProvider. |
128 bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, | 129 bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, |
129 base::trace_event::ProcessMemoryDump* pmd) override; | 130 base::trace_event::ProcessMemoryDump* pmd) override; |
130 | 131 |
131 int NumberOfFrameBuffersInUseByDecoder() const; | 132 int NumberOfFrameBuffersInUseByDecoder() const; |
132 int NumberOfFrameBuffersInUseByDecoderAndVideoFrame() const; | 133 int NumberOfFrameBuffersInUseByDecoderAndVideoFrame() const; |
133 | 134 |
134 private: | 135 private: |
135 friend class base::RefCountedThreadSafe<VpxVideoDecoder::MemoryPool>; | 136 friend class base::RefCountedThreadSafe<VpxVideoDecoder::MemoryPool>; |
136 ~MemoryPool() override; | 137 ~MemoryPool() override; |
137 | 138 |
138 // Reference counted frame buffers used for VP9 decoding. Reference counting | 139 // Reference counted frame buffers used for VP9 decoding. Reference counting |
139 // is done manually because both chromium and libvpx has to release this | 140 // is done manually because both chromium and libvpx has to release this |
140 // before a buffer can be re-used. | 141 // before a buffer can be re-used. |
141 struct VP9FrameBuffer { | 142 struct VP9FrameBuffer { |
142 VP9FrameBuffer() : ref_cnt(0) {} | 143 VP9FrameBuffer() : ref_cnt(0) {} |
143 std::vector<uint8> data; | 144 std::vector<uint8_t> data; |
144 uint32 ref_cnt; | 145 uint32_t ref_cnt; |
145 }; | 146 }; |
146 | 147 |
147 // Gets the next available frame buffer for use by libvpx. | 148 // Gets the next available frame buffer for use by libvpx. |
148 VP9FrameBuffer* GetFreeFrameBuffer(size_t min_size); | 149 VP9FrameBuffer* GetFreeFrameBuffer(size_t min_size); |
149 | 150 |
150 // Method that gets called when a VideoFrame that references this pool gets | 151 // Method that gets called when a VideoFrame that references this pool gets |
151 // destroyed. | 152 // destroyed. |
152 void OnVideoFrameDestroyed(VP9FrameBuffer* frame_buffer); | 153 void OnVideoFrameDestroyed(VP9FrameBuffer* frame_buffer); |
153 | 154 |
154 // Frame buffers to be used by libvpx for VP9 Decoding. | 155 // Frame buffers to be used by libvpx for VP9 Decoding. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 // Create a new frame buffer. | 187 // Create a new frame buffer. |
187 frame_buffers_.push_back(new VP9FrameBuffer()); | 188 frame_buffers_.push_back(new VP9FrameBuffer()); |
188 } | 189 } |
189 | 190 |
190 // Resize the frame buffer if necessary. | 191 // Resize the frame buffer if necessary. |
191 if (frame_buffers_[i]->data.size() < min_size) | 192 if (frame_buffers_[i]->data.size() < min_size) |
192 frame_buffers_[i]->data.resize(min_size); | 193 frame_buffers_[i]->data.resize(min_size); |
193 return frame_buffers_[i]; | 194 return frame_buffers_[i]; |
194 } | 195 } |
195 | 196 |
196 int32 VpxVideoDecoder::MemoryPool::GetVP9FrameBuffer( | 197 int32_t VpxVideoDecoder::MemoryPool::GetVP9FrameBuffer( |
197 void* user_priv, size_t min_size, vpx_codec_frame_buffer* fb) { | 198 void* user_priv, |
| 199 size_t min_size, |
| 200 vpx_codec_frame_buffer* fb) { |
198 DCHECK(user_priv); | 201 DCHECK(user_priv); |
199 DCHECK(fb); | 202 DCHECK(fb); |
200 | 203 |
201 VpxVideoDecoder::MemoryPool* memory_pool = | 204 VpxVideoDecoder::MemoryPool* memory_pool = |
202 static_cast<VpxVideoDecoder::MemoryPool*>(user_priv); | 205 static_cast<VpxVideoDecoder::MemoryPool*>(user_priv); |
203 | 206 |
204 VP9FrameBuffer* fb_to_use = memory_pool->GetFreeFrameBuffer(min_size); | 207 VP9FrameBuffer* fb_to_use = memory_pool->GetFreeFrameBuffer(min_size); |
205 if (fb_to_use == NULL) | 208 if (fb_to_use == NULL) |
206 return -1; | 209 return -1; |
207 | 210 |
208 fb->data = &fb_to_use->data[0]; | 211 fb->data = &fb_to_use->data[0]; |
209 fb->size = fb_to_use->data.size(); | 212 fb->size = fb_to_use->data.size(); |
210 ++fb_to_use->ref_cnt; | 213 ++fb_to_use->ref_cnt; |
211 ++memory_pool->in_use_by_decoder_; | 214 ++memory_pool->in_use_by_decoder_; |
212 | 215 |
213 // Set the frame buffer's private data to point at the external frame buffer. | 216 // Set the frame buffer's private data to point at the external frame buffer. |
214 fb->priv = static_cast<void*>(fb_to_use); | 217 fb->priv = static_cast<void*>(fb_to_use); |
215 return 0; | 218 return 0; |
216 } | 219 } |
217 | 220 |
218 int32 VpxVideoDecoder::MemoryPool::ReleaseVP9FrameBuffer( | 221 int32_t VpxVideoDecoder::MemoryPool::ReleaseVP9FrameBuffer( |
219 void* user_priv, | 222 void* user_priv, |
220 vpx_codec_frame_buffer* fb) { | 223 vpx_codec_frame_buffer* fb) { |
221 DCHECK(user_priv); | 224 DCHECK(user_priv); |
222 DCHECK(fb); | 225 DCHECK(fb); |
223 VP9FrameBuffer* frame_buffer = static_cast<VP9FrameBuffer*>(fb->priv); | 226 VP9FrameBuffer* frame_buffer = static_cast<VP9FrameBuffer*>(fb->priv); |
224 --frame_buffer->ref_cnt; | 227 --frame_buffer->ref_cnt; |
225 | 228 |
226 VpxVideoDecoder::MemoryPool* memory_pool = | 229 VpxVideoDecoder::MemoryPool* memory_pool = |
227 static_cast<VpxVideoDecoder::MemoryPool*>(user_priv); | 230 static_cast<VpxVideoDecoder::MemoryPool*>(user_priv); |
228 --memory_pool->in_use_by_decoder_; | 231 --memory_pool->in_use_by_decoder_; |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 delete vpx_codec_alpha_; | 432 delete vpx_codec_alpha_; |
430 vpx_codec_alpha_ = nullptr; | 433 vpx_codec_alpha_ = nullptr; |
431 } | 434 } |
432 } | 435 } |
433 | 436 |
434 bool VpxVideoDecoder::VpxDecode(const scoped_refptr<DecoderBuffer>& buffer, | 437 bool VpxVideoDecoder::VpxDecode(const scoped_refptr<DecoderBuffer>& buffer, |
435 scoped_refptr<VideoFrame>* video_frame) { | 438 scoped_refptr<VideoFrame>* video_frame) { |
436 DCHECK(video_frame); | 439 DCHECK(video_frame); |
437 DCHECK(!buffer->end_of_stream()); | 440 DCHECK(!buffer->end_of_stream()); |
438 | 441 |
439 int64 timestamp = buffer->timestamp().InMicroseconds(); | 442 int64_t timestamp = buffer->timestamp().InMicroseconds(); |
440 void* user_priv = reinterpret_cast<void*>(×tamp); | 443 void* user_priv = reinterpret_cast<void*>(×tamp); |
441 { | 444 { |
442 TRACE_EVENT1("video", "vpx_codec_decode", "timestamp", timestamp); | 445 TRACE_EVENT1("video", "vpx_codec_decode", "timestamp", timestamp); |
443 vpx_codec_err_t status = | 446 vpx_codec_err_t status = |
444 vpx_codec_decode(vpx_codec_, buffer->data(), buffer->data_size(), | 447 vpx_codec_decode(vpx_codec_, buffer->data(), buffer->data_size(), |
445 user_priv, 0 /* deadline */); | 448 user_priv, 0 /* deadline */); |
446 if (status != VPX_CODEC_OK) { | 449 if (status != VPX_CODEC_OK) { |
447 DLOG(ERROR) << "vpx_codec_decode() error: " | 450 DLOG(ERROR) << "vpx_codec_decode() error: " |
448 << vpx_codec_err_to_string(status); | 451 << vpx_codec_err_to_string(status); |
449 return false; | 452 return false; |
(...skipping 28 matching lines...) Expand all Loading... |
478 (*video_frame) | 481 (*video_frame) |
479 ->metadata() | 482 ->metadata() |
480 ->SetInteger(VideoFrameMetadata::COLOR_SPACE, color_space); | 483 ->SetInteger(VideoFrameMetadata::COLOR_SPACE, color_space); |
481 | 484 |
482 if (!vpx_codec_alpha_) | 485 if (!vpx_codec_alpha_) |
483 return true; | 486 return true; |
484 | 487 |
485 if (buffer->side_data_size() < 8) { | 488 if (buffer->side_data_size() < 8) { |
486 // TODO(mcasas): Is this a warning or an error? | 489 // TODO(mcasas): Is this a warning or an error? |
487 DLOG(WARNING) << "Making Alpha channel opaque due to missing input"; | 490 DLOG(WARNING) << "Making Alpha channel opaque due to missing input"; |
488 const uint32 kAlphaOpaqueValue = 255; | 491 const uint32_t kAlphaOpaqueValue = 255; |
489 libyuv::SetPlane((*video_frame)->visible_data(VideoFrame::kAPlane), | 492 libyuv::SetPlane((*video_frame)->visible_data(VideoFrame::kAPlane), |
490 (*video_frame)->stride(VideoFrame::kAPlane), | 493 (*video_frame)->stride(VideoFrame::kAPlane), |
491 (*video_frame)->visible_rect().width(), | 494 (*video_frame)->visible_rect().width(), |
492 (*video_frame)->visible_rect().height(), | 495 (*video_frame)->visible_rect().height(), |
493 kAlphaOpaqueValue); | 496 kAlphaOpaqueValue); |
494 return true; | 497 return true; |
495 } | 498 } |
496 | 499 |
497 // First 8 bytes of side data is |side_data_id| in big endian. | 500 // First 8 bytes of side data is |side_data_id| in big endian. |
498 const uint64 side_data_id = base::NetToHost64( | 501 const uint64_t side_data_id = base::NetToHost64( |
499 *(reinterpret_cast<const uint64*>(buffer->side_data()))); | 502 *(reinterpret_cast<const uint64_t*>(buffer->side_data()))); |
500 if (side_data_id != 1) | 503 if (side_data_id != 1) |
501 return true; | 504 return true; |
502 | 505 |
503 // Try and decode buffer->side_data() minus the first 8 bytes as a full frame. | 506 // Try and decode buffer->side_data() minus the first 8 bytes as a full frame. |
504 int64 timestamp_alpha = buffer->timestamp().InMicroseconds(); | 507 int64_t timestamp_alpha = buffer->timestamp().InMicroseconds(); |
505 void* user_priv_alpha = reinterpret_cast<void*>(×tamp_alpha); | 508 void* user_priv_alpha = reinterpret_cast<void*>(×tamp_alpha); |
506 { | 509 { |
507 TRACE_EVENT1("video", "vpx_codec_decode_alpha", "timestamp_alpha", | 510 TRACE_EVENT1("video", "vpx_codec_decode_alpha", "timestamp_alpha", |
508 timestamp_alpha); | 511 timestamp_alpha); |
509 vpx_codec_err_t status = vpx_codec_decode( | 512 vpx_codec_err_t status = vpx_codec_decode( |
510 vpx_codec_alpha_, buffer->side_data() + 8, buffer->side_data_size() - 8, | 513 vpx_codec_alpha_, buffer->side_data() + 8, buffer->side_data_size() - 8, |
511 user_priv_alpha, 0 /* deadline */); | 514 user_priv_alpha, 0 /* deadline */); |
512 if (status != VPX_CODEC_OK) { | 515 if (status != VPX_CODEC_OK) { |
513 DLOG(ERROR) << "vpx_codec_decode() failed for the alpha: " | 516 DLOG(ERROR) << "vpx_codec_decode() failed for the alpha: " |
514 << vpx_codec_error(vpx_codec_); | 517 << vpx_codec_error(vpx_codec_); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
613 (*video_frame)->visible_data(VideoFrame::kUPlane), | 616 (*video_frame)->visible_data(VideoFrame::kUPlane), |
614 (*video_frame)->stride(VideoFrame::kUPlane), | 617 (*video_frame)->stride(VideoFrame::kUPlane), |
615 (*video_frame)->visible_data(VideoFrame::kVPlane), | 618 (*video_frame)->visible_data(VideoFrame::kVPlane), |
616 (*video_frame)->stride(VideoFrame::kVPlane), coded_size.width(), | 619 (*video_frame)->stride(VideoFrame::kVPlane), coded_size.width(), |
617 coded_size.height()); | 620 coded_size.height()); |
618 | 621 |
619 return true; | 622 return true; |
620 } | 623 } |
621 | 624 |
622 } // namespace media | 625 } // namespace media |
OLD | NEW |