| /* |
| * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #include "i420.h" |
| #include <string.h> |
| |
| namespace webrtc |
| { |
| |
| I420Encoder::I420Encoder(): |
| _inited(false), |
| _encodedImage(), |
| _encodedCompleteCallback(NULL) |
| { |
| // |
| } |
| |
| I420Encoder::~I420Encoder() |
| { |
| _inited = false; |
| if (_encodedImage._buffer != NULL) |
| { |
| delete [] _encodedImage._buffer; |
| _encodedImage._buffer = NULL; |
| } |
| } |
| |
| WebRtc_Word32 |
| I420Encoder::VersionStatic(WebRtc_Word8* version, WebRtc_Word32 length) |
| { |
| const WebRtc_Word8* str= "I420 version 1.1.0\n"; |
| WebRtc_Word32 verLen = (WebRtc_Word32)strlen(str); |
| if(verLen > length) |
| { |
| return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
| } |
| strncpy(version, str,length); |
| return verLen; |
| } |
| |
| WebRtc_Word32 |
| I420Encoder::Version(WebRtc_Word8 *version, WebRtc_Word32 length) const |
| { |
| return VersionStatic(version, length); |
| } |
| |
| |
| |
| WebRtc_Word32 |
| I420Encoder::Release() |
| { |
| // should allocate an encoded frame and then release it here, for that we actaully need an init flag |
| if (_encodedImage._buffer != NULL) |
| { |
| delete [] _encodedImage._buffer; |
| _encodedImage._buffer = NULL; |
| } |
| _inited = false; |
| return WEBRTC_VIDEO_CODEC_OK; |
| } |
| |
| WebRtc_Word32 |
| I420Encoder::Reset() |
| { |
| if (!_inited) |
| { |
| return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
| } |
| return WEBRTC_VIDEO_CODEC_OK; |
| |
| } |
| |
| WebRtc_Word32 |
| I420Encoder::InitEncode(const VideoCodec* codecSettings, |
| WebRtc_Word32 /*numberOfCores*/, |
| WebRtc_UWord32 /*maxPayloadSize */) |
| { |
| if (codecSettings == NULL) |
| { |
| return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
| } |
| if (codecSettings->width < 1 || codecSettings->height < 1) |
| { |
| return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
| } |
| |
| // allocating encoded memory |
| |
| if (_encodedImage._buffer != NULL) |
| { |
| delete [] _encodedImage._buffer; |
| _encodedImage._buffer = NULL; |
| _encodedImage._size = 0; |
| } |
| const WebRtc_UWord32 newSize = (3 * codecSettings->width * |
| codecSettings->height) >> 1; |
| WebRtc_UWord8* newBuffer = new WebRtc_UWord8[newSize]; |
| if (newBuffer == NULL) |
| { |
| return WEBRTC_VIDEO_CODEC_MEMORY; |
| } |
| _encodedImage._size = newSize; |
| _encodedImage._buffer = newBuffer; |
| |
| // if no memory allocation, no point to init |
| _inited = true; |
| return WEBRTC_VIDEO_CODEC_OK; |
| } |
| |
| |
| |
| WebRtc_Word32 |
| I420Encoder::Encode(const RawImage& inputImage, |
| const CodecSpecificInfo* /*codecSpecificInfo*/, |
| const VideoFrameType* /*frameTypes*/) |
| { |
| if (!_inited) |
| { |
| return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
| } |
| if (_encodedCompleteCallback == NULL) |
| { |
| return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
| } |
| |
| _encodedImage._frameType = kKeyFrame; // no coding |
| _encodedImage._timeStamp = inputImage._timeStamp; |
| _encodedImage._encodedHeight = inputImage._height; |
| _encodedImage._encodedWidth = inputImage._width; |
| if (inputImage._length > _encodedImage._size) |
| { |
| |
| // allocating encoded memory |
| if (_encodedImage._buffer != NULL) |
| { |
| delete [] _encodedImage._buffer; |
| _encodedImage._buffer = NULL; |
| _encodedImage._size = 0; |
| } |
| const WebRtc_UWord32 newSize = (3 * _encodedImage._encodedWidth * _encodedImage._encodedHeight) >> 1; |
| WebRtc_UWord8* newBuffer = new WebRtc_UWord8[newSize]; |
| if (newBuffer == NULL) |
| { |
| return WEBRTC_VIDEO_CODEC_MEMORY; |
| } |
| _encodedImage._size = newSize; |
| _encodedImage._buffer = newBuffer; |
| } |
| memcpy(_encodedImage._buffer, inputImage._buffer, inputImage._length); |
| _encodedImage._length = inputImage._length; |
| _encodedCompleteCallback->Encoded(_encodedImage); |
| return WEBRTC_VIDEO_CODEC_OK; |
| } |
| |
| |
| WebRtc_Word32 |
| I420Encoder::RegisterEncodeCompleteCallback(EncodedImageCallback* callback) |
| { |
| _encodedCompleteCallback = callback; |
| return WEBRTC_VIDEO_CODEC_OK; |
| } |
| |
| |
| I420Decoder::I420Decoder(): |
| _decodedImage(), |
| _width(0), |
| _height(0), |
| _inited(false), |
| _decodeCompleteCallback(NULL) |
| { |
| // |
| } |
| |
| I420Decoder::~I420Decoder() |
| { |
| Release(); |
| } |
| |
| WebRtc_Word32 |
| I420Decoder::Reset() |
| { |
| return WEBRTC_VIDEO_CODEC_OK; |
| } |
| |
| |
| WebRtc_Word32 |
| I420Decoder::InitDecode(const VideoCodec* codecSettings, WebRtc_Word32 /*numberOfCores */) |
| { |
| if (codecSettings == NULL) |
| { |
| return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
| } |
| else if (codecSettings->width < 1 || codecSettings->height < 1) |
| { |
| return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
| } |
| _width = codecSettings->width; |
| _height = codecSettings->height; |
| _inited = true; |
| return WEBRTC_VIDEO_CODEC_OK; |
| } |
| |
| WebRtc_Word32 |
| I420Decoder::Decode(const EncodedImage& inputImage, |
| bool /*missingFrames*/, |
| const RTPFragmentationHeader* /*fragmentation*/, |
| const CodecSpecificInfo* /*codecSpecificInfo*/, |
| WebRtc_Word64 /*renderTimeMs*/) |
| { |
| if (inputImage._buffer == NULL) |
| { |
| return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
| } |
| if (_decodeCompleteCallback == NULL) |
| { |
| return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
| } |
| if (inputImage._length <= 0) |
| { |
| return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
| } |
| if (!_inited) |
| { |
| return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
| } |
| |
| //Allocate memory for decoded image |
| |
| if (_decodedImage._buffer != NULL) |
| { |
| delete [] _decodedImage._buffer; |
| _decodedImage._buffer = NULL; |
| _decodedImage._size = 0; |
| } |
| if (_decodedImage._buffer == NULL) |
| { |
| const WebRtc_UWord32 newSize = (3*_width*_height) >> 1; |
| WebRtc_UWord8* newBuffer = new WebRtc_UWord8[newSize]; |
| if (newBuffer == NULL) |
| { |
| return WEBRTC_VIDEO_CODEC_MEMORY; |
| } |
| _decodedImage._size = newSize; |
| _decodedImage._buffer = newBuffer; |
| } |
| |
| // Set decoded image parameters |
| _decodedImage._height = _height; |
| _decodedImage._width = _width; |
| _decodedImage._timeStamp = inputImage._timeStamp; |
| memcpy(_decodedImage._buffer, inputImage._buffer, inputImage._length); |
| _decodedImage._length = inputImage._length; |
| //_decodedImage._buffer = inputImage._buffer; |
| |
| _decodeCompleteCallback->Decoded(_decodedImage); |
| return WEBRTC_VIDEO_CODEC_OK; |
| } |
| |
| WebRtc_Word32 |
| I420Decoder::RegisterDecodeCompleteCallback(DecodedImageCallback* callback) |
| { |
| _decodeCompleteCallback = callback; |
| return WEBRTC_VIDEO_CODEC_OK; |
| } |
| |
| WebRtc_Word32 |
| I420Decoder::Release() |
| { |
| if (_decodedImage._buffer != NULL) |
| { |
| delete [] _decodedImage._buffer; |
| _decodedImage._buffer = NULL; |
| } |
| _inited = false; |
| return WEBRTC_VIDEO_CODEC_OK; |
| } |
| |
| } |