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