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 VideoFrame* video_frame = new VideoFrame(); | 126 |
| 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 |
127 // FFmpeg expects the initial allocation to be zero-initialized according to | 130 // FFmpeg expects the initial allocation to be zero-initialized according to |
128 // http://crbug.com/390941. Our pool is set up to zero-initialize new buffers. | 131 // http://crbug.com/390941. Our pool is set up to zero-initialize new buffers. |
129 video_frame->set_video_frame_buffer( | 132 VideoFrame* video_frame = new VideoFrame( |
130 decoder->pool_.CreateBuffer(width, height)); | 133 decoder->pool_.CreateBuffer(width, height), |
| 134 0 /* timestamp */, 0 /* render_time_ms */, kVideoRotation_0); |
| 135 |
131 // DCHECK that we have a continuous buffer as is required. | 136 // DCHECK that we have a continuous buffer as is required. |
132 RTC_DCHECK_EQ(video_frame->video_frame_buffer()->DataU(), | 137 RTC_DCHECK_EQ(video_frame->video_frame_buffer()->DataU(), |
133 video_frame->video_frame_buffer()->DataY() + | 138 video_frame->video_frame_buffer()->DataY() + |
134 video_frame->allocated_size(kYPlane)); | 139 video_frame->allocated_size(kYPlane)); |
135 RTC_DCHECK_EQ(video_frame->video_frame_buffer()->DataV(), | 140 RTC_DCHECK_EQ(video_frame->video_frame_buffer()->DataV(), |
136 video_frame->video_frame_buffer()->DataU() + | 141 video_frame->video_frame_buffer()->DataU() + |
137 video_frame->allocated_size(kUPlane)); | 142 video_frame->allocated_size(kUPlane)); |
138 int total_size = video_frame->allocated_size(kYPlane) + | 143 int total_size = video_frame->allocated_size(kYPlane) + |
139 video_frame->allocated_size(kUPlane) + | 144 video_frame->allocated_size(kUPlane) + |
140 video_frame->allocated_size(kVPlane); | 145 video_frame->allocated_size(kVPlane); |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 av_buffer_get_opaque(av_frame_->buf[0])); | 353 av_buffer_get_opaque(av_frame_->buf[0])); |
349 RTC_DCHECK(video_frame); | 354 RTC_DCHECK(video_frame); |
350 RTC_CHECK_EQ(av_frame_->data[kYPlane], | 355 RTC_CHECK_EQ(av_frame_->data[kYPlane], |
351 video_frame->video_frame_buffer()->DataY()); | 356 video_frame->video_frame_buffer()->DataY()); |
352 RTC_CHECK_EQ(av_frame_->data[kUPlane], | 357 RTC_CHECK_EQ(av_frame_->data[kUPlane], |
353 video_frame->video_frame_buffer()->DataU()); | 358 video_frame->video_frame_buffer()->DataU()); |
354 RTC_CHECK_EQ(av_frame_->data[kVPlane], | 359 RTC_CHECK_EQ(av_frame_->data[kVPlane], |
355 video_frame->video_frame_buffer()->DataV()); | 360 video_frame->video_frame_buffer()->DataV()); |
356 video_frame->set_timestamp(input_image._timeStamp); | 361 video_frame->set_timestamp(input_image._timeStamp); |
357 | 362 |
| 363 int32_t ret; |
| 364 |
358 // The decoded image may be larger than what is supposed to be visible, see | 365 // The decoded image may be larger than what is supposed to be visible, see |
359 // |AVGetBuffer2|'s use of |avcodec_align_dimensions|. This crops the image | 366 // |AVGetBuffer2|'s use of |avcodec_align_dimensions|. This crops the image |
360 // without copying the underlying buffer. | 367 // without copying the underlying buffer. |
361 rtc::scoped_refptr<VideoFrameBuffer> buf = video_frame->video_frame_buffer(); | 368 rtc::scoped_refptr<VideoFrameBuffer> buf = video_frame->video_frame_buffer(); |
362 if (av_frame_->width != buf->width() || av_frame_->height != buf->height()) { | 369 if (av_frame_->width != buf->width() || av_frame_->height != buf->height()) { |
363 video_frame->set_video_frame_buffer( | 370 rtc::scoped_refptr<VideoFrameBuffer> cropped_buf( |
364 new rtc::RefCountedObject<WrappedI420Buffer>( | 371 new rtc::RefCountedObject<WrappedI420Buffer>( |
365 av_frame_->width, av_frame_->height, | 372 av_frame_->width, av_frame_->height, |
366 buf->DataY(), buf->StrideY(), | 373 buf->DataY(), buf->StrideY(), |
367 buf->DataU(), buf->StrideU(), | 374 buf->DataU(), buf->StrideU(), |
368 buf->DataV(), buf->StrideV(), | 375 buf->DataV(), buf->StrideV(), |
369 rtc::KeepRefUntilDone(buf))); | 376 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); |
370 } | 386 } |
371 | |
372 // Return decoded frame. | |
373 int32_t ret = decoded_image_callback_->Decoded(*video_frame); | |
374 // Stop referencing it, possibly freeing |video_frame|. | 387 // Stop referencing it, possibly freeing |video_frame|. |
375 av_frame_unref(av_frame_.get()); | 388 av_frame_unref(av_frame_.get()); |
376 video_frame = nullptr; | 389 video_frame = nullptr; |
377 | 390 |
378 if (ret) { | 391 if (ret) { |
379 LOG(LS_WARNING) << "DecodedImageCallback::Decoded returned " << ret; | 392 LOG(LS_WARNING) << "DecodedImageCallback::Decoded returned " << ret; |
380 return ret; | 393 return ret; |
381 } | 394 } |
382 return WEBRTC_VIDEO_CODEC_OK; | 395 return WEBRTC_VIDEO_CODEC_OK; |
383 } | 396 } |
(...skipping 14 matching lines...) Expand all Loading... |
398 void H264DecoderImpl::ReportError() { | 411 void H264DecoderImpl::ReportError() { |
399 if (has_reported_error_) | 412 if (has_reported_error_) |
400 return; | 413 return; |
401 RTC_HISTOGRAM_ENUMERATION("WebRTC.Video.H264DecoderImpl.Event", | 414 RTC_HISTOGRAM_ENUMERATION("WebRTC.Video.H264DecoderImpl.Event", |
402 kH264DecoderEventError, | 415 kH264DecoderEventError, |
403 kH264DecoderEventMax); | 416 kH264DecoderEventMax); |
404 has_reported_error_ = true; | 417 has_reported_error_ = true; |
405 } | 418 } |
406 | 419 |
407 } // namespace webrtc | 420 } // namespace webrtc |
OLD | NEW |