LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/video_coding/codecs/i420 - i420.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 124 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 16 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
       3             :  *
       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
       6             :  *  tree. An additional intellectual property rights grant can be found
       7             :  *  in the file PATENTS.  All contributing project authors may
       8             :  *  be found in the AUTHORS file in the root of the source tree.
       9             :  */
      10             : 
      11             : #include "webrtc/modules/video_coding/codecs/i420/include/i420.h"
      12             : 
      13             : #include <limits>
      14             : #include <string>
      15             : 
      16             : #include "webrtc/api/video/i420_buffer.h"
      17             : #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
      18             : 
      19             : namespace {
      20             : const size_t kI420HeaderSize = 4;
      21             : }
      22             : 
      23             : namespace webrtc {
      24             : 
      25           0 : I420Encoder::I420Encoder()
      26           0 :     : _inited(false), _encodedImage(), _encodedCompleteCallback(NULL) {}
      27             : 
      28           0 : I420Encoder::~I420Encoder() {
      29           0 :   _inited = false;
      30           0 :   delete[] _encodedImage._buffer;
      31           0 : }
      32             : 
      33           0 : int I420Encoder::Release() {
      34             :   // Should allocate an encoded frame and then release it here, for that we
      35             :   // actually need an init flag.
      36           0 :   if (_encodedImage._buffer != NULL) {
      37           0 :     delete[] _encodedImage._buffer;
      38           0 :     _encodedImage._buffer = NULL;
      39             :   }
      40           0 :   _inited = false;
      41           0 :   return WEBRTC_VIDEO_CODEC_OK;
      42             : }
      43             : 
      44           0 : int I420Encoder::InitEncode(const VideoCodec* codecSettings,
      45             :                             int /*numberOfCores*/,
      46             :                             size_t /*maxPayloadSize */) {
      47           0 :   if (codecSettings == NULL) {
      48           0 :     return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
      49             :   }
      50           0 :   if (codecSettings->width < 1 || codecSettings->height < 1) {
      51           0 :     return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
      52             :   }
      53             : 
      54             :   // Allocating encoded memory.
      55           0 :   if (_encodedImage._buffer != NULL) {
      56           0 :     delete[] _encodedImage._buffer;
      57           0 :     _encodedImage._buffer = NULL;
      58           0 :     _encodedImage._size = 0;
      59             :   }
      60             :   const size_t newSize =
      61           0 :       CalcBufferSize(kI420, codecSettings->width, codecSettings->height) +
      62           0 :       kI420HeaderSize;
      63           0 :   uint8_t* newBuffer = new uint8_t[newSize];
      64           0 :   if (newBuffer == NULL) {
      65           0 :     return WEBRTC_VIDEO_CODEC_MEMORY;
      66             :   }
      67           0 :   _encodedImage._size = newSize;
      68           0 :   _encodedImage._buffer = newBuffer;
      69             : 
      70             :   // If no memory allocation, no point to init.
      71           0 :   _inited = true;
      72           0 :   return WEBRTC_VIDEO_CODEC_OK;
      73             : }
      74             : 
      75           0 : int I420Encoder::Encode(const VideoFrame& inputImage,
      76             :                         const CodecSpecificInfo* /*codecSpecificInfo*/,
      77             :                         const std::vector<FrameType>* /*frame_types*/) {
      78           0 :   if (!_inited) {
      79           0 :     return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
      80             :   }
      81           0 :   if (_encodedCompleteCallback == NULL) {
      82           0 :     return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
      83             :   }
      84             : 
      85           0 :   _encodedImage._frameType = kVideoFrameKey;
      86           0 :   _encodedImage._timeStamp = inputImage.timestamp();
      87           0 :   _encodedImage._encodedHeight = inputImage.height();
      88           0 :   _encodedImage._encodedWidth = inputImage.width();
      89             : 
      90           0 :   int width = inputImage.width();
      91           0 :   if (width > std::numeric_limits<uint16_t>::max()) {
      92           0 :     return WEBRTC_VIDEO_CODEC_ERR_SIZE;
      93             :   }
      94           0 :   int height = inputImage.height();
      95           0 :   if (height > std::numeric_limits<uint16_t>::max()) {
      96           0 :     return WEBRTC_VIDEO_CODEC_ERR_SIZE;
      97             :   }
      98             : 
      99             :   size_t req_length =
     100           0 :       CalcBufferSize(kI420, inputImage.width(), inputImage.height()) +
     101           0 :       kI420HeaderSize;
     102           0 :   if (_encodedImage._size > req_length) {
     103             :     // Reallocate buffer.
     104           0 :     delete[] _encodedImage._buffer;
     105             : 
     106           0 :     _encodedImage._buffer = new uint8_t[req_length];
     107           0 :     _encodedImage._size = req_length;
     108             :   }
     109             : 
     110           0 :   uint8_t* buffer = _encodedImage._buffer;
     111             : 
     112           0 :   buffer = InsertHeader(buffer, width, height);
     113             : 
     114             :   int ret_length =
     115           0 :       ExtractBuffer(inputImage, req_length - kI420HeaderSize, buffer);
     116           0 :   if (ret_length < 0)
     117           0 :     return WEBRTC_VIDEO_CODEC_MEMORY;
     118           0 :   _encodedImage._length = ret_length + kI420HeaderSize;
     119             : 
     120           0 :   _encodedCompleteCallback->OnEncodedImage(_encodedImage, nullptr, nullptr);
     121             : 
     122           0 :   return WEBRTC_VIDEO_CODEC_OK;
     123             : }
     124             : 
     125           0 : uint8_t* I420Encoder::InsertHeader(uint8_t* buffer,
     126             :                                    uint16_t width,
     127             :                                    uint16_t height) {
     128           0 :   *buffer++ = static_cast<uint8_t>(width >> 8);
     129           0 :   *buffer++ = static_cast<uint8_t>(width & 0xFF);
     130           0 :   *buffer++ = static_cast<uint8_t>(height >> 8);
     131           0 :   *buffer++ = static_cast<uint8_t>(height & 0xFF);
     132           0 :   return buffer;
     133             : }
     134             : 
     135           0 : int I420Encoder::RegisterEncodeCompleteCallback(
     136             :     EncodedImageCallback* callback) {
     137           0 :   _encodedCompleteCallback = callback;
     138           0 :   return WEBRTC_VIDEO_CODEC_OK;
     139             : }
     140             : 
     141           0 : I420Decoder::I420Decoder()
     142             :     : _width(0),
     143             :       _height(0),
     144             :       _inited(false),
     145           0 :       _decodeCompleteCallback(NULL) {}
     146             : 
     147           0 : I420Decoder::~I420Decoder() {
     148           0 :   Release();
     149           0 : }
     150             : 
     151           0 : int I420Decoder::InitDecode(const VideoCodec* codecSettings,
     152             :                             int /*numberOfCores */) {
     153           0 :   if (codecSettings == NULL) {
     154           0 :     return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
     155           0 :   } else if (codecSettings->width < 1 || codecSettings->height < 1) {
     156           0 :     return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
     157             :   }
     158           0 :   _width = codecSettings->width;
     159           0 :   _height = codecSettings->height;
     160           0 :   _inited = true;
     161           0 :   return WEBRTC_VIDEO_CODEC_OK;
     162             : }
     163             : 
     164           0 : int I420Decoder::Decode(const EncodedImage& inputImage,
     165             :                         bool /*missingFrames*/,
     166             :                         const RTPFragmentationHeader* /*fragmentation*/,
     167             :                         const CodecSpecificInfo* /*codecSpecificInfo*/,
     168             :                         int64_t /*renderTimeMs*/) {
     169           0 :   if (inputImage._buffer == NULL) {
     170           0 :     return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
     171             :   }
     172           0 :   if (_decodeCompleteCallback == NULL) {
     173           0 :     return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
     174             :   }
     175           0 :   if (inputImage._length <= 0) {
     176           0 :     return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
     177             :   }
     178           0 :   if (inputImage._completeFrame == false) {
     179           0 :     return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
     180             :   }
     181           0 :   if (!_inited) {
     182           0 :     return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
     183             :   }
     184           0 :   if (inputImage._length < kI420HeaderSize) {
     185           0 :     return WEBRTC_VIDEO_CODEC_ERROR;
     186             :   }
     187             : 
     188           0 :   const uint8_t* buffer = inputImage._buffer;
     189             :   uint16_t width, height;
     190             : 
     191           0 :   buffer = ExtractHeader(buffer, &width, &height);
     192           0 :   _width = width;
     193           0 :   _height = height;
     194             : 
     195             :   // Verify that the available length is sufficient:
     196           0 :   size_t req_length = CalcBufferSize(kI420, _width, _height) + kI420HeaderSize;
     197             : 
     198           0 :   if (req_length > inputImage._length) {
     199           0 :     return WEBRTC_VIDEO_CODEC_ERROR;
     200             :   }
     201             :   // Set decoded image parameters.
     202           0 :   int half_width = (_width + 1) / 2;
     203             :   rtc::scoped_refptr<webrtc::I420Buffer> frame_buffer =
     204           0 :       I420Buffer::Create(_width, _height, _width, half_width, half_width);
     205             : 
     206             :   // Converting from raw buffer I420Buffer.
     207           0 :   int ret = ConvertToI420(kI420, buffer, 0, 0, _width, _height, 0,
     208           0 :                           kVideoRotation_0, frame_buffer.get());
     209           0 :   if (ret < 0) {
     210           0 :     return WEBRTC_VIDEO_CODEC_MEMORY;
     211             :   }
     212             : 
     213           0 :   VideoFrame decoded_image(frame_buffer, inputImage._timeStamp, 0,
     214           0 :                            webrtc::kVideoRotation_0);
     215           0 :   _decodeCompleteCallback->Decoded(decoded_image);
     216           0 :   return WEBRTC_VIDEO_CODEC_OK;
     217             : }
     218             : 
     219           0 : const uint8_t* I420Decoder::ExtractHeader(const uint8_t* buffer,
     220             :                                           uint16_t* width,
     221             :                                           uint16_t* height) {
     222           0 :   *width = static_cast<uint16_t>(*buffer++) << 8;
     223           0 :   *width |= *buffer++;
     224           0 :   *height = static_cast<uint16_t>(*buffer++) << 8;
     225           0 :   *height |= *buffer++;
     226             : 
     227           0 :   return buffer;
     228             : }
     229             : 
     230           0 : int I420Decoder::RegisterDecodeCompleteCallback(
     231             :     DecodedImageCallback* callback) {
     232           0 :   _decodeCompleteCallback = callback;
     233           0 :   return WEBRTC_VIDEO_CODEC_OK;
     234             : }
     235             : 
     236           0 : int I420Decoder::Release() {
     237           0 :   _inited = false;
     238           0 :   return WEBRTC_VIDEO_CODEC_OK;
     239             : }
     240             : }  // namespace webrtc

Generated by: LCOV version 1.13