1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
11026e6b63725deadacbecd23e1d37c95fbf402970mikhal@webrtc.org#include "webrtc/video_engine/test/libvietest/include/tb_I420_codec.h"
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <assert.h>
14281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include <stdio.h>
15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
16026e6b63725deadacbecd23e1d37c95fbf402970mikhal@webrtc.org#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTbI420Encoder::TbI420Encoder() :
19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _inited(false), _encodedImage(), _encodedCompleteCallback(NULL)
20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //
22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    memset(&_functionCalls, 0, sizeof(_functionCalls));
23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTbI420Encoder::~TbI420Encoder()
26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _inited = false;
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_encodedImage._buffer != NULL)
29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delete[] _encodedImage._buffer;
31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _encodedImage._buffer = NULL;
32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
3567879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t TbI420Encoder::Release()
36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _functionCalls.Release++;
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // should allocate an encoded frame and then release it here, for that we
39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // actaully need an init flag
40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_encodedImage._buffer != NULL)
41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delete[] _encodedImage._buffer;
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _encodedImage._buffer = NULL;
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _inited = false;
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return WEBRTC_VIDEO_CODEC_OK;
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
4967879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t TbI420Encoder::SetChannelParameters(uint32_t packetLoss, int rtt) {
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  _functionCalls.SetChannelParameters++;
51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return WEBRTC_VIDEO_CODEC_OK;
52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
5467879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t TbI420Encoder::InitEncode(const webrtc::VideoCodec* inst,
5567879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org                                  int32_t /*numberOfCores*/,
5667879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org                                  uint32_t /*maxPayloadSize */)
57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _functionCalls.InitEncode++;
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (inst == NULL)
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (inst->width < 1 || inst->height < 1)
64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // allocating encoded memory
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_encodedImage._buffer != NULL)
70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delete[] _encodedImage._buffer;
72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _encodedImage._buffer = NULL;
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _encodedImage._size = 0;
74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
7567879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org    const uint32_t newSize = (3 * inst->width * inst->height) >> 1;
7667879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org    uint8_t* newBuffer = new uint8_t[newSize];
77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (newBuffer == NULL)
78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return WEBRTC_VIDEO_CODEC_MEMORY;
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodedImage._size = newSize;
82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodedImage._buffer = newBuffer;
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // if no memeory allocation, no point to init
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _inited = true;
86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return WEBRTC_VIDEO_CODEC_OK;
87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
8967879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t TbI420Encoder::Encode(
903bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    const webrtc::I420VideoFrame& inputImage,
91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    const webrtc::CodecSpecificInfo* /*codecSpecificInfo*/,
92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    const std::vector<webrtc::VideoFrameType>* /*frameTypes*/)
93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _functionCalls.Encode++;
95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_inited)
96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_encodedCompleteCallback == NULL)
100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodedImage._frameType = webrtc::kKeyFrame; // no coding
1053bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    _encodedImage._timeStamp = inputImage.timestamp();
1063bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    _encodedImage._encodedHeight = inputImage.height();
1073bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    _encodedImage._encodedWidth = inputImage.width();
1083bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    unsigned int reqSize = webrtc::CalcBufferSize(webrtc::kI420,
1093bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                                                  _encodedImage._encodedWidth,
1103bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                                                  _encodedImage._encodedHeight);
1113bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    if (reqSize > _encodedImage._size)
112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // allocating encoded memory
115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (_encodedImage._buffer != NULL)
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            delete[] _encodedImage._buffer;
118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _encodedImage._buffer = NULL;
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _encodedImage._size = 0;
120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
12167879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org        uint8_t* newBuffer = new uint8_t[reqSize];
122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (newBuffer == NULL)
123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            return WEBRTC_VIDEO_CODEC_MEMORY;
125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
1263bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org        _encodedImage._size = reqSize;
127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _encodedImage._buffer = newBuffer;
128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1293bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    if (ExtractBuffer(inputImage, _encodedImage._size,
1303bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org                      _encodedImage._buffer) < 0) {
1313bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org      return -1;
1323bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    }
1333bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org
1343bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    _encodedImage._length = reqSize;
135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodedCompleteCallback->Encoded(_encodedImage);
136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return WEBRTC_VIDEO_CODEC_OK;
137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
13967879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t TbI420Encoder::RegisterEncodeCompleteCallback(
140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    webrtc::EncodedImageCallback* callback)
141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _functionCalls.RegisterEncodeCompleteCallback++;
143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _encodedCompleteCallback = callback;
144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return WEBRTC_VIDEO_CODEC_OK;
145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
14767879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t TbI420Encoder::SetRates(uint32_t newBitRate, uint32_t frameRate)
148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _functionCalls.SetRates++;
150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return WEBRTC_VIDEO_CODEC_OK;
151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
15367879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t TbI420Encoder::SetPeriodicKeyFrames(bool enable)
154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _functionCalls.SetPeriodicKeyFrames++;
156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return WEBRTC_VIDEO_CODEC_ERROR;
157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
15967879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t TbI420Encoder::CodecConfigParameters(uint8_t* /*buffer*/,
16067879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org                                             int32_t /*size*/)
161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _functionCalls.CodecConfigParameters++;
163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return WEBRTC_VIDEO_CODEC_ERROR;
164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTbI420Encoder::FunctionCalls TbI420Encoder::GetFunctionCalls()
166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return _functionCalls;
168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTbI420Decoder::TbI420Decoder():
171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _decodedImage(), _width(0), _height(0), _inited(false),
172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _decodeCompleteCallback(NULL)
173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    memset(&_functionCalls, 0, sizeof(_functionCalls));
175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTbI420Decoder::~TbI420Decoder()
178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    Release();
180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
18267879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t TbI420Decoder::Reset()
183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _functionCalls.Reset++;
185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return WEBRTC_VIDEO_CODEC_OK;
186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
18867879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t TbI420Decoder::InitDecode(const webrtc::VideoCodec* inst,
18967879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org                                  int32_t /*numberOfCores */)
190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _functionCalls.InitDecode++;
192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (inst == NULL)
193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else if (inst->width < 1 || inst->height < 1)
197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _width = inst->width;
201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _height = inst->height;
202026e6b63725deadacbecd23e1d37c95fbf402970mikhal@webrtc.org    int half_width = (_width + 1 ) / 2 ;
203026e6b63725deadacbecd23e1d37c95fbf402970mikhal@webrtc.org    _decodedImage.CreateEmptyFrame(_width, _height,
204026e6b63725deadacbecd23e1d37c95fbf402970mikhal@webrtc.org                                   _width, half_width, half_width);
205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _inited = true;
206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return WEBRTC_VIDEO_CODEC_OK;
207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
20967879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t TbI420Decoder::Decode(
210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    const webrtc::EncodedImage& inputImage,
211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool /*missingFrames*/,
212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    const webrtc::RTPFragmentationHeader* /*fragmentation*/,
213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    const webrtc::CodecSpecificInfo* /*codecSpecificInfo*/,
21467879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org    int64_t /*renderTimeMs*/)
215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _functionCalls.Decode++;
217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (inputImage._buffer == NULL)
218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_decodeCompleteCallback == NULL)
222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (inputImage._length <= 0)
226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_inited)
230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
234e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    // Only send complete frames.
235e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    if (static_cast<int>(inputImage._length) !=
236e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org        webrtc::CalcBufferSize(webrtc::kI420,_width,_height)) {
237e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org      return WEBRTC_VIDEO_CODEC_ERROR;
238e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org    }
239e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org
240026e6b63725deadacbecd23e1d37c95fbf402970mikhal@webrtc.org    int ret = ConvertToI420(webrtc::kI420, inputImage._buffer, 0, 0,
241026e6b63725deadacbecd23e1d37c95fbf402970mikhal@webrtc.org                           _width, _height,
242026e6b63725deadacbecd23e1d37c95fbf402970mikhal@webrtc.org                           0, webrtc::kRotateNone, &_decodedImage);
243026e6b63725deadacbecd23e1d37c95fbf402970mikhal@webrtc.org
2443bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    if (ret < 0)
2453bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org      return WEBRTC_VIDEO_CODEC_ERROR;
246e2e033adc5f58b3ffe6c3c7e67b245ee66e1a607mikhal@webrtc.org
2473bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org    _decodedImage.set_timestamp(inputImage._timeStamp);
248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _decodeCompleteCallback->Decoded(_decodedImage);
250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return WEBRTC_VIDEO_CODEC_OK;
251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
25367879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t TbI420Decoder::RegisterDecodeCompleteCallback(
254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    webrtc::DecodedImageCallback* callback)
255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _functionCalls.RegisterDecodeCompleteCallback++;
257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _decodeCompleteCallback = callback;
258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return WEBRTC_VIDEO_CODEC_OK;
259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
26167879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.orgint32_t TbI420Decoder::Release()
262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _functionCalls.Release++;
264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _inited = false;
265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return WEBRTC_VIDEO_CODEC_OK;
266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTbI420Decoder::FunctionCalls TbI420Decoder::GetFunctionCalls()
269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return _functionCalls;
271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
272