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#ifdef WEBRTC_MODULE_UTILITY_VIDEO
12
13#include "webrtc/modules/utility/source/video_coder.h"
14
15namespace webrtc {
16VideoCoder::VideoCoder() : _vcm(VideoCodingModule::Create()), _decodedVideo(0) {
17    _vcm->InitializeSender();
18    _vcm->InitializeReceiver();
19
20    _vcm->RegisterTransportCallback(this);
21    _vcm->RegisterReceiveCallback(this);
22}
23
24VideoCoder::~VideoCoder()
25{
26    VideoCodingModule::Destroy(_vcm);
27}
28
29int32_t VideoCoder::SetEncodeCodec(VideoCodec& videoCodecInst,
30                                   uint32_t numberOfCores,
31                                   uint32_t maxPayloadSize)
32{
33    if(_vcm->RegisterSendCodec(&videoCodecInst, numberOfCores,
34                               maxPayloadSize) != VCM_OK)
35    {
36        return -1;
37    }
38    return 0;
39}
40
41
42int32_t VideoCoder::SetDecodeCodec(VideoCodec& videoCodecInst,
43                                   int32_t numberOfCores)
44{
45    if (videoCodecInst.plType == 0)
46    {
47        int8_t plType = DefaultPayloadType(videoCodecInst.plName);
48        if (plType == -1)
49        {
50            return -1;
51        }
52        videoCodecInst.plType = plType;
53    }
54
55    if(_vcm->RegisterReceiveCodec(&videoCodecInst, numberOfCores) != VCM_OK)
56    {
57        return -1;
58    }
59    return 0;
60}
61
62int32_t VideoCoder::Decode(I420VideoFrame& decodedVideo,
63                           const EncodedVideoData& encodedData)
64{
65    decodedVideo.ResetSize();
66    if(encodedData.payloadSize <= 0)
67    {
68        return -1;
69    }
70
71    _decodedVideo = &decodedVideo;
72    return 0;
73}
74
75
76int32_t VideoCoder::Encode(const I420VideoFrame& videoFrame,
77                           EncodedVideoData& videoEncodedData)
78{
79    // The AddVideoFrame(..) call will (indirectly) call SendData(). Store a
80    // pointer to videoFrame so that it can be updated.
81    _videoEncodedData = &videoEncodedData;
82    videoEncodedData.payloadSize = 0;
83    if(_vcm->AddVideoFrame(videoFrame) != VCM_OK)
84    {
85        return -1;
86    }
87    return 0;
88}
89
90int8_t VideoCoder::DefaultPayloadType(const char* plName)
91{
92    VideoCodec tmpCodec;
93    int32_t numberOfCodecs = _vcm->NumberOfCodecs();
94    for (uint8_t i = 0; i < numberOfCodecs; i++)
95    {
96        _vcm->Codec(i, &tmpCodec);
97        if(strncmp(tmpCodec.plName, plName, kPayloadNameSize) == 0)
98        {
99            return tmpCodec.plType;
100        }
101    }
102    return -1;
103}
104
105int32_t VideoCoder::FrameToRender(I420VideoFrame& videoFrame)
106{
107    return _decodedVideo->CopyFrame(videoFrame);
108}
109
110int32_t VideoCoder::SendData(
111    const FrameType frameType,
112    const uint8_t  payloadType,
113    const uint32_t timeStamp,
114    int64_t capture_time_ms,
115    const uint8_t* payloadData,
116    uint32_t payloadSize,
117    const RTPFragmentationHeader& fragmentationHeader,
118    const RTPVideoHeader* /*rtpVideoHdr*/)
119{
120    // Store the data in _videoEncodedData which is a pointer to videoFrame in
121    // Encode(..)
122    _videoEncodedData->VerifyAndAllocate(payloadSize);
123    _videoEncodedData->frameType = frameType;
124    _videoEncodedData->payloadType = payloadType;
125    _videoEncodedData->timeStamp = timeStamp;
126    _videoEncodedData->fragmentationHeader.CopyFrom(fragmentationHeader);
127    memcpy(_videoEncodedData->payloadData, payloadData,
128           sizeof(uint8_t) * payloadSize);
129    _videoEncodedData->payloadSize = payloadSize;
130    return 0;
131}
132}  // namespace webrtc
133#endif // WEBRTC_MODULE_UTILITY_VIDEO
134