OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 * | 9 * |
10 */ | 10 */ |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 int ret = av_image_check_size(static_cast<unsigned int>(width), | 116 int ret = av_image_check_size(static_cast<unsigned int>(width), |
117 static_cast<unsigned int>(height), 0, nullptr); | 117 static_cast<unsigned int>(height), 0, nullptr); |
118 if (ret < 0) { | 118 if (ret < 0) { |
119 LOG(LS_ERROR) << "Invalid picture size " << width << "x" << height; | 119 LOG(LS_ERROR) << "Invalid picture size " << width << "x" << height; |
120 decoder->ReportError(); | 120 decoder->ReportError(); |
121 return ret; | 121 return ret; |
122 } | 122 } |
123 | 123 |
124 // The video frame is stored in |video_frame|. |av_frame| is FFmpeg's version | 124 // The video frame is stored in |video_frame|. |av_frame| is FFmpeg's version |
125 // of a video frame and will be set up to reference |video_frame|'s buffers. | 125 // of a video frame and will be set up to reference |video_frame|'s buffers. |
126 | 126 VideoFrame* video_frame = new VideoFrame(); |
127 // TODO(nisse): The VideoFrame's timestamp and rotation info is not used. | |
128 // Refactor to do not use a VideoFrame object at all. | |
129 | |
130 // FFmpeg expects the initial allocation to be zero-initialized according to | 127 // FFmpeg expects the initial allocation to be zero-initialized according to |
131 // http://crbug.com/390941. Our pool is set up to zero-initialize new buffers. | 128 // http://crbug.com/390941. Our pool is set up to zero-initialize new buffers. |
132 VideoFrame* video_frame = new VideoFrame( | 129 video_frame->set_video_frame_buffer( |
133 decoder->pool_.CreateBuffer(width, height), | 130 decoder->pool_.CreateBuffer(width, height)); |
134 0 /* timestamp */, 0 /* render_time_ms */, kVideoRotation_0); | |
135 | |
136 // DCHECK that we have a continuous buffer as is required. | 131 // DCHECK that we have a continuous buffer as is required. |
137 RTC_DCHECK_EQ(video_frame->video_frame_buffer()->DataU(), | 132 RTC_DCHECK_EQ(video_frame->video_frame_buffer()->DataU(), |
138 video_frame->video_frame_buffer()->DataY() + | 133 video_frame->video_frame_buffer()->DataY() + |
139 video_frame->allocated_size(kYPlane)); | 134 video_frame->allocated_size(kYPlane)); |
140 RTC_DCHECK_EQ(video_frame->video_frame_buffer()->DataV(), | 135 RTC_DCHECK_EQ(video_frame->video_frame_buffer()->DataV(), |
141 video_frame->video_frame_buffer()->DataU() + | 136 video_frame->video_frame_buffer()->DataU() + |
142 video_frame->allocated_size(kUPlane)); | 137 video_frame->allocated_size(kUPlane)); |
143 int total_size = video_frame->allocated_size(kYPlane) + | 138 int total_size = video_frame->allocated_size(kYPlane) + |
144 video_frame->allocated_size(kUPlane) + | 139 video_frame->allocated_size(kUPlane) + |
145 video_frame->allocated_size(kVPlane); | 140 video_frame->allocated_size(kVPlane); |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 av_buffer_get_opaque(av_frame_->buf[0])); | 348 av_buffer_get_opaque(av_frame_->buf[0])); |
354 RTC_DCHECK(video_frame); | 349 RTC_DCHECK(video_frame); |
355 RTC_CHECK_EQ(av_frame_->data[kYPlane], | 350 RTC_CHECK_EQ(av_frame_->data[kYPlane], |
356 video_frame->video_frame_buffer()->DataY()); | 351 video_frame->video_frame_buffer()->DataY()); |
357 RTC_CHECK_EQ(av_frame_->data[kUPlane], | 352 RTC_CHECK_EQ(av_frame_->data[kUPlane], |
358 video_frame->video_frame_buffer()->DataU()); | 353 video_frame->video_frame_buffer()->DataU()); |
359 RTC_CHECK_EQ(av_frame_->data[kVPlane], | 354 RTC_CHECK_EQ(av_frame_->data[kVPlane], |
360 video_frame->video_frame_buffer()->DataV()); | 355 video_frame->video_frame_buffer()->DataV()); |
361 video_frame->set_timestamp(input_image._timeStamp); | 356 video_frame->set_timestamp(input_image._timeStamp); |
362 | 357 |
363 int32_t ret; | |
364 | |
365 // The decoded image may be larger than what is supposed to be visible, see | 358 // The decoded image may be larger than what is supposed to be visible, see |
366 // |AVGetBuffer2|'s use of |avcodec_align_dimensions|. This crops the image | 359 // |AVGetBuffer2|'s use of |avcodec_align_dimensions|. This crops the image |
367 // without copying the underlying buffer. | 360 // without copying the underlying buffer. |
368 rtc::scoped_refptr<VideoFrameBuffer> buf = video_frame->video_frame_buffer(); | 361 rtc::scoped_refptr<VideoFrameBuffer> buf = video_frame->video_frame_buffer(); |
369 if (av_frame_->width != buf->width() || av_frame_->height != buf->height()) { | 362 if (av_frame_->width != buf->width() || av_frame_->height != buf->height()) { |
370 rtc::scoped_refptr<VideoFrameBuffer> cropped_buf( | 363 video_frame->set_video_frame_buffer( |
371 new rtc::RefCountedObject<WrappedI420Buffer>( | 364 new rtc::RefCountedObject<WrappedI420Buffer>( |
372 av_frame_->width, av_frame_->height, | 365 av_frame_->width, av_frame_->height, |
373 buf->DataY(), buf->StrideY(), | 366 buf->DataY(), buf->StrideY(), |
374 buf->DataU(), buf->StrideU(), | 367 buf->DataU(), buf->StrideU(), |
375 buf->DataV(), buf->StrideV(), | 368 buf->DataV(), buf->StrideV(), |
376 rtc::KeepRefUntilDone(buf))); | 369 rtc::KeepRefUntilDone(buf))); |
377 VideoFrame cropped_frame( | |
378 cropped_buf, video_frame->timestamp(), video_frame->render_time_ms(), | |
379 video_frame->rotation()); | |
380 // TODO(nisse): Timestamp and rotation are all zero here. Change decoder | |
381 // interface to pass a VideoFrameBuffer instead of a VideoFrame? | |
382 ret = decoded_image_callback_->Decoded(cropped_frame); | |
383 } else { | |
384 // Return decoded frame. | |
385 ret = decoded_image_callback_->Decoded(*video_frame); | |
386 } | 370 } |
| 371 |
| 372 // Return decoded frame. |
| 373 int32_t ret = decoded_image_callback_->Decoded(*video_frame); |
387 // Stop referencing it, possibly freeing |video_frame|. | 374 // Stop referencing it, possibly freeing |video_frame|. |
388 av_frame_unref(av_frame_.get()); | 375 av_frame_unref(av_frame_.get()); |
389 video_frame = nullptr; | 376 video_frame = nullptr; |
390 | 377 |
391 if (ret) { | 378 if (ret) { |
392 LOG(LS_WARNING) << "DecodedImageCallback::Decoded returned " << ret; | 379 LOG(LS_WARNING) << "DecodedImageCallback::Decoded returned " << ret; |
393 return ret; | 380 return ret; |
394 } | 381 } |
395 return WEBRTC_VIDEO_CODEC_OK; | 382 return WEBRTC_VIDEO_CODEC_OK; |
396 } | 383 } |
(...skipping 14 matching lines...) Expand all Loading... |
411 void H264DecoderImpl::ReportError() { | 398 void H264DecoderImpl::ReportError() { |
412 if (has_reported_error_) | 399 if (has_reported_error_) |
413 return; | 400 return; |
414 RTC_HISTOGRAM_ENUMERATION("WebRTC.Video.H264DecoderImpl.Event", | 401 RTC_HISTOGRAM_ENUMERATION("WebRTC.Video.H264DecoderImpl.Event", |
415 kH264DecoderEventError, | 402 kH264DecoderEventError, |
416 kH264DecoderEventMax); | 403 kH264DecoderEventMax); |
417 has_reported_error_ = true; | 404 has_reported_error_ = true; |
418 } | 405 } |
419 | 406 |
420 } // namespace webrtc | 407 } // namespace webrtc |
OLD | NEW |