diff --git a/modules/video_coding/codecs/interface/video_image.h b/common_video/interface/video_image.h similarity index 87% rename from modules/video_coding/codecs/interface/video_image.h rename to common_video/interface/video_image.h index 916a8f8112..82e7b15e78 100644 --- a/modules/video_coding/codecs/interface/video_image.h +++ b/common_video/interface/video_image.h @@ -8,8 +8,8 @@ * be found in the AUTHORS file in the root of the source tree. */ -#ifndef VIDEO_IMAGE_H -#define VIDEO_IMAGE_H +#ifndef COMMON_VIDEO_INTERFACE_VIDEO_IMAGE_H +#define COMMON_VIDEO_INTERFACE_VIDEO_IMAGE_H #include "typedefs.h" #include @@ -33,7 +33,7 @@ public: _length(0), _size(0) {} RawImage(WebRtc_UWord8* buffer, WebRtc_UWord32 length, - WebRtc_UWord32 size) : + WebRtc_UWord32 size) : _width(0), _height(0), _timeStamp(0), _buffer(buffer), _length(length), _size(size) {} @@ -50,8 +50,8 @@ class EncodedImage public: EncodedImage() : _encodedWidth(0), _encodedHeight(0), _timeStamp(0), - _frameType(kDeltaFrame), _buffer(NULL), _length(0), _size(0), - _completeFrame(false) {} + _frameType(kDeltaFrame), _buffer(NULL), _length(0), + _size(0), _completeFrame(false) {} EncodedImage(WebRtc_UWord8* buffer, WebRtc_UWord32 length, @@ -63,7 +63,7 @@ public: WebRtc_UWord32 _encodedWidth; WebRtc_UWord32 _encodedHeight; WebRtc_UWord32 _timeStamp; - VideoFrameType _frameType; + VideoFrameType _frameType; WebRtc_UWord8* _buffer; WebRtc_UWord32 _length; WebRtc_UWord32 _size; @@ -72,4 +72,4 @@ public: } // namespace webrtc -#endif // VIDEO_IMAGE_H +#endif // COMMON_VIDEO_INTERFACE_VIDEO_IMAGE_H diff --git a/common_video/jpeg/main/interface/jpeg.h b/common_video/jpeg/main/interface/jpeg.h index 6f092b8e7f..61f832cd38 100644 --- a/common_video/jpeg/main/interface/jpeg.h +++ b/common_video/jpeg/main/interface/jpeg.h @@ -16,6 +16,7 @@ #define WEBRTC_COMMON_VIDEO_JPEG #include "typedefs.h" +#include "video_image.h" // jpeg forward declaration struct jpeg_compress_struct; @@ -47,19 +48,12 @@ public: // Output: // - 0 : OK // - (-1) : Error - WebRtc_Word32 Encode(const WebRtc_UWord8* imageBuffer, - const WebRtc_UWord32 imageBufferSize, - const WebRtc_UWord32 width, - const WebRtc_UWord32 height); + WebRtc_Word32 Encode(const RawImage& inputImage); private: - WebRtc_Word32 Encode(const WebRtc_UWord8* imageBuffer, - const WebRtc_UWord32 imageBufferSize); jpeg_compress_struct* _cinfo; WebRtc_Word8 _fileName[256]; - WebRtc_UWord32 _width; - WebRtc_UWord32 _height; }; class JpegDecoder @@ -68,25 +62,19 @@ class JpegDecoder JpegDecoder(); ~JpegDecoder(); -//Decodes a JPEG-stream -//Supports 1 image component. 3 interleaved image components, YCbCr sub-sampling 4:4:4, 4:2:2, 4:2:0. +// Decodes a JPEG-stream +// Supports 1 image component. 3 interleaved image components, +// YCbCr sub-sampling 4:4:4, 4:2:2, 4:2:0. // -//Input: -// - encodedBuffer : Pointer to the encoded stream to be decoded. -// - encodedBufferSize : Size of the data to be decoded -// - decodedBuffer : Reference to the destination of the decoded I420-image. -// - width : Reference returning width of decoded image. -// - height : Reference returning height of decoded image. +// Input: +// - inputImage : encoded image to be decoded. +// - outputImage : RawImage to store decoded output // // Output: // - 0 : OK // - (-1) : Error -//Note: decodedBuffer should be freed by user - WebRtc_Word32 Decode(const WebRtc_UWord8* encodedBuffer, - const WebRtc_UWord32 encodedBufferSize, - WebRtc_UWord8*& decodedBuffer, - WebRtc_UWord32& width, - WebRtc_UWord32& height); + WebRtc_Word32 Decode(const EncodedImage& inputImage, + RawImage& outputImage); private: jpeg_decompress_struct* _cinfo; }; diff --git a/common_video/jpeg/main/source/jpeg.cc b/common_video/jpeg/main/source/jpeg.cc index 9fffeddc07..004ecb7e93 100644 --- a/common_video/jpeg/main/source/jpeg.cc +++ b/common_video/jpeg/main/source/jpeg.cc @@ -52,18 +52,19 @@ MyErrorExit (j_common_ptr cinfo) longjmp(myerr->setjmp_buffer, 1); } -JpegEncoder::JpegEncoder(): -_width(0), -_height(0) +JpegEncoder::JpegEncoder() { - _cinfo = new jpeg_compress_struct; + _cinfo = new jpeg_compress_struct; strcpy(_fileName, "Snapshot.jpg"); } JpegEncoder::~JpegEncoder() { - delete _cinfo; - _cinfo = NULL; + if (_cinfo != NULL) + { + delete _cinfo; + _cinfo = NULL; + } } @@ -84,24 +85,21 @@ JpegEncoder::SetFileName(const WebRtc_Word8* fileName) WebRtc_Word32 -JpegEncoder::Encode(const WebRtc_UWord8* imageBuffer, - const WebRtc_UWord32 imageBufferSize, - const WebRtc_UWord32 width, - const WebRtc_UWord32 height) +JpegEncoder::Encode(const RawImage& inputImage) { - if ((imageBuffer == NULL) || (imageBufferSize == 0)) + if (inputImage._buffer == NULL || inputImage._size == 0) { return -1; } - if (width < 1 || height < 1) + if (inputImage._width < 1 || inputImage._height < 1) { return -1; } FILE* outFile = NULL; - _width = width; - _height = height; + const WebRtc_Word32 width = inputImage._width; + const WebRtc_Word32 height = inputImage._height; // Set error handler myErrorMgr jerr; @@ -121,7 +119,6 @@ JpegEncoder::Encode(const WebRtc_UWord8* imageBuffer, if ((outFile = fopen(_fileName, "wb")) == NULL) { - fprintf(stderr, "can't open %s\n", _fileName); return -2; } // Create a compression object @@ -130,51 +127,12 @@ JpegEncoder::Encode(const WebRtc_UWord8* imageBuffer, // Setting destination file jpeg_stdio_dest(_cinfo, outFile); - WebRtc_Word32 ret = 0; - - // Height of image buffer should be a multiple of 16 - if (_height % 16 == 0) - { - ret = Encode(imageBuffer, imageBufferSize); - } - else - { - WebRtc_UWord32 height16 = ((_height + 15) - 16) & - 16; - height16 = (height16 < _height) ? height16 + 16 : height16; - - // Copy image to an adequate size buffer - WebRtc_UWord32 requiredSize = height16 * _width * 3 >> 1; - WebRtc_UWord8* origImagePtr = new WebRtc_UWord8[requiredSize]; - if (origImagePtr == NULL) - { - return -1; - } - memset(origImagePtr, 0, requiredSize); - memcpy(origImagePtr, imageBuffer, imageBufferSize); - - ret = Encode(origImagePtr, requiredSize); - - // delete allocated buffer - delete [] origImagePtr; - origImagePtr = NULL; - } - - - fclose(outFile); - - return ret; -} - -WebRtc_Word32 -JpegEncoder::Encode(const WebRtc_UWord8* imageBuffer, - const WebRtc_UWord32 imageBufferSize) -{ // Set parameters for compression _cinfo->in_color_space = JCS_YCbCr; jpeg_set_defaults(_cinfo); - _cinfo->image_width = _width; - _cinfo->image_height = _height; + _cinfo->image_width = width; + _cinfo->image_height = height; _cinfo->input_components = 3; _cinfo->comp_info[0].h_samp_factor = 2; // Y @@ -196,30 +154,31 @@ JpegEncoder::Encode(const WebRtc_UWord8* imageBuffer, WebRtc_UWord32 i, j; - for (j = 0; j < _height; j += 16) + for (j = 0; j < height; j += 16) { for (i = 0; i < 16; i++) { - y[i] = (JSAMPLE*) imageBuffer + _width * (i + j); + y[i] = (JSAMPLE*) inputImage._buffer + width * (i + j); if (i % 2 == 0) { - u[i / 2] = (JSAMPLE*) imageBuffer + _width * _height + - _width / 2 * ((i + j) / 2); - v[i / 2] = (JSAMPLE*) imageBuffer + _width * _height + - _width * _height / 4 + _width / 2 * ((i + j) / 2); + u[i / 2] = (JSAMPLE*) inputImage._buffer + width * height + + width / 2 * ((i + j) / 2); + v[i / 2] = (JSAMPLE*) inputImage._buffer + width * height + + width * height / 4 + width / 2 * ((i + j) / 2); } } - jpeg_write_raw_data(_cinfo, data, 16); + jpeg_write_raw_data(_cinfo, data, 16); } jpeg_finish_compress(_cinfo); jpeg_destroy_compress(_cinfo); + fclose(outFile); + return 0; } - JpegDecoder::JpegDecoder() { _cinfo = new jpeg_decompress_struct; @@ -227,18 +186,20 @@ JpegDecoder::JpegDecoder() JpegDecoder::~JpegDecoder() { - delete _cinfo; - _cinfo = NULL; + if (_cinfo != NULL) + { + delete _cinfo; + _cinfo = NULL; + } } WebRtc_Word32 -JpegDecoder::Decode(const WebRtc_UWord8* encodedBuffer, - const WebRtc_UWord32 encodedBufferSize, - WebRtc_UWord8*& decodedBuffer, - WebRtc_UWord32& width, - WebRtc_UWord32& height) +JpegDecoder::Decode(const EncodedImage& inputImage, + RawImage& outputImage) { - // Set error handler + + WebRtc_UWord8* tmpBuffer = NULL; + // Set error handler myErrorMgr jerr; _cinfo->err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = MyErrorExit; @@ -250,6 +211,10 @@ JpegDecoder::Decode(const WebRtc_UWord8* encodedBuffer, { jpeg_destroy_decompress(_cinfo); } + if (tmpBuffer != NULL) + { + delete [] tmpBuffer; + } return -1; } @@ -259,7 +224,7 @@ JpegDecoder::Decode(const WebRtc_UWord8* encodedBuffer, jpeg_create_decompress(_cinfo); // Specify data source - jpegSetSrcBuffer(_cinfo, (JOCTET*) encodedBuffer, encodedBufferSize); + jpegSetSrcBuffer(_cinfo, (JOCTET*) inputImage._buffer, inputImage._size); // Read header data jpeg_read_header(_cinfo, TRUE); @@ -277,28 +242,47 @@ JpegDecoder::Decode(const WebRtc_UWord8* encodedBuffer, return -2; // not supported } - height = _cinfo->image_height; - width = _cinfo->image_width; + + WebRtc_UWord32 height = _cinfo->image_height; + WebRtc_UWord32 width = _cinfo->image_width; // Making sure width and height are even if (height % 2) + { height++; - if (width % 2) - width++; - - WebRtc_UWord32 height16 = ((height + 15) - 16) & - 16; - height16 = (height16 < height) ? height16 + 16 : height16; - - // allocate buffer to output - if (decodedBuffer != NULL) - { - delete [] decodedBuffer; - decodedBuffer = NULL; } - decodedBuffer = new WebRtc_UWord8[width * height16 * 3 >> 1]; - if (decodedBuffer == NULL) + if (width % 2) { - return -1; + width++; + } + + WebRtc_UWord32 height16 = (height + 15) & ~15; + WebRtc_UWord32 stride = (width + 15) & ~15; + WebRtc_UWord32 uvStride = (((stride + 1 >> 1) + 15) & ~15); + + WebRtc_UWord32 tmpRequiredSize = stride * height16 + + 2 * (uvStride * ((height16 + 1) >> 1)); + WebRtc_UWord32 requiredSize = width * height * 3 >> 1; + + // verify sufficient buffer size + if (outputImage._buffer && outputImage._size < requiredSize) + { + delete [] outputImage._buffer; + outputImage._buffer = NULL; + } + + if (outputImage._buffer == NULL) + { + outputImage._buffer = new WebRtc_UWord8[requiredSize]; + outputImage._size = requiredSize; + } + + WebRtc_UWord8* outPtr = outputImage._buffer; + + if (tmpRequiredSize > requiredSize) + { + tmpBuffer = new WebRtc_UWord8[(int) (tmpRequiredSize)]; + outPtr = tmpBuffer; } JSAMPROW y[16],u[8],v[8]; @@ -310,19 +294,21 @@ JpegDecoder::Decode(const WebRtc_UWord8* encodedBuffer, WebRtc_UWord32 hInd, i; WebRtc_UWord32 numScanLines = 16; WebRtc_UWord32 numLinesProcessed = 0; - while(_cinfo->output_scanline < _cinfo->output_height) + + while (_cinfo->output_scanline < _cinfo->output_height) { hInd = _cinfo->output_scanline; for (i = 0; i < numScanLines; i++) { - y[i] = decodedBuffer + width * (i + hInd); + y[i] = outPtr + stride * (i + hInd); if (i % 2 == 0) { - u[i / 2] = decodedBuffer + width * height + - width / 2 * ((i + hInd) / 2); - v[i / 2] = decodedBuffer + width * height + - width * height / 4 + width / 2 * ((i + hInd) / 2); + u[i / 2] = outPtr + stride * height16 + + stride / 2 * ((i + hInd) / 2); + v[i / 2] = outPtr + stride * height16 + + stride * height16 / 4 + + stride / 2 * ((i + hInd) / 2); } } // Processes exactly one iMCU row per call @@ -330,12 +316,43 @@ JpegDecoder::Decode(const WebRtc_UWord8* encodedBuffer, // Error in read if (numLinesProcessed == 0) { - delete [] decodedBuffer; jpeg_abort((j_common_ptr)_cinfo); return -1; } } + if (tmpRequiredSize > requiredSize) + { + WebRtc_UWord8* dstFramePtr = outputImage._buffer; + WebRtc_UWord8* tmpPtr = outPtr; + + for (WebRtc_UWord32 p = 0; p < 3; p++) + { + const WebRtc_UWord32 h = (p == 0) ? height : height >> 1; + const WebRtc_UWord32 h16 = (p == 0) ? height16 : height16 >> 1; + const WebRtc_UWord32 w = (p == 0) ? width : width >> 1; + const WebRtc_UWord32 s = (p == 0) ? stride : stride >> 1; + + for (WebRtc_UWord32 i = 0; i < h; i++) + { + memcpy(dstFramePtr, tmpPtr, w); + dstFramePtr += w; + tmpPtr += s; + } + tmpPtr += (h16 - h) * s; + } + } + + if (tmpBuffer != NULL) + { + delete [] tmpBuffer; + } + // Setting output Image parameter + outputImage._width = width; + outputImage._height = height; + outputImage._length = requiredSize; + outputImage._timeStamp = inputImage._timeStamp; + jpeg_finish_decompress(_cinfo); jpeg_destroy_decompress(_cinfo); return 0; diff --git a/common_video/jpeg/main/source/jpeg.gyp b/common_video/jpeg/main/source/jpeg.gyp index ad5419ed69..710b5b6e0b 100644 --- a/common_video/jpeg/main/source/jpeg.gyp +++ b/common_video/jpeg/main/source/jpeg.gyp @@ -18,12 +18,14 @@ '../../../vplib/main/source/vplib.gyp:webrtc_vplib', ], 'include_dirs': [ + '../../../interface', '../interface', '../../../../../../', ], 'direct_dependent_settings': { 'include_dirs': [ '../interface', + '../../../interface', ], }, 'conditions': [ @@ -78,12 +80,9 @@ ], 'sources': [ - # headers - '../test/test_buffer.h', - + # headers # sources - '../test/test_buffer.cc', '../test/test_jpeg.cc', ], # source diff --git a/common_video/jpeg/main/test/test_jpeg.cc b/common_video/jpeg/main/test/test_jpeg.cc index a947dbdaee..03ad00a322 100644 --- a/common_video/jpeg/main/test/test_jpeg.cc +++ b/common_video/jpeg/main/test/test_jpeg.cc @@ -19,13 +19,11 @@ #include -#include "test_buffer.h" +#include "video_image.h" #include "jpeg.h" using namespace webrtc; -#define PRINT_LINE std::cout << "-------------------------------" << std::endl; - int main(int argc, char **argv) { @@ -37,13 +35,12 @@ main(int argc, char **argv) const char* fileNameDec = "TestJpegDec.yuv"; const char* fileNameEnc = "TestJpegEnc.jpg"; - std::string str; + std::string str; std::cout << "---------------------" << std::endl; std::cout << "----- Test JPEG -----" << std::endl; std::cout << "---------------------" << std::endl; std::cout << " " << std::endl; - JpegDecoder* JpgDecPtr = new JpegDecoder( ); // Open input file @@ -55,38 +52,31 @@ main(int argc, char **argv) int length = ftell(openFile); fseek(openFile, 0, SEEK_SET); + // Read input file to buffer - TestBuffer encodedBuffer; - encodedBuffer.VerifyAndAllocate(length); - encodedBuffer.UpdateLength(length); - fread(encodedBuffer.GetBuffer(), 1, length, openFile); + EncodedImage encodedBuffer; + encodedBuffer._buffer = new WebRtc_UWord8[length]; + encodedBuffer._size = length; + encodedBuffer._length = length; + fread(encodedBuffer._buffer, 1, length, openFile); fclose(openFile); // ------------------ // Decode // ------------------ - TestBuffer imageBuffer; - WebRtc_UWord32 width = 0; - WebRtc_UWord32 height = 0; - WebRtc_UWord8* tmp = NULL; - int error = JpgDecPtr->Decode(encodedBuffer.GetBuffer(), - encodedBuffer.GetSize(), tmp, width, height); + RawImage imageBuffer; + int error = JpgDecPtr->Decode(encodedBuffer, imageBuffer); - std::cout << error << " = Decode(" << fileName.c_str() << ", (" << width << - "x" << height << "))" << std::endl; - PRINT_LINE; + std::cout << error << " = Decode(" << fileName.c_str() << ", " + "(" << imageBuffer._width << + "x" << imageBuffer._height << "))" << std::endl; if (error == 0) { - int imageBufferSize = width*height*3/2; - //update buffer info - imageBuffer.VerifyAndAllocate( imageBufferSize); - imageBuffer.CopyBuffer(imageBufferSize, tmp); - delete [] tmp; // Save decoded image to file FILE* saveFile = fopen(fileNameDec, "wb"); - fwrite(imageBuffer.GetBuffer(), 1, imageBuffer.GetLength(), saveFile); + fwrite(imageBuffer._buffer, 1, imageBuffer._length, saveFile); fclose(saveFile); // ------------------ @@ -96,39 +86,40 @@ main(int argc, char **argv) JpegEncoder* JpegEncoderPtr = new JpegEncoder(); // Test invalid inputs - - // Test buffer - TestBuffer empty; - + RawImage empty; + empty._width = 164; + empty._height = 164; int error = JpegEncoderPtr->SetFileName(0); assert(error == -1); - error = JpegEncoderPtr->Encode(empty.GetBuffer(), empty.GetSize(), - 164, 164); + error = JpegEncoderPtr->Encode(empty); assert(error == -1); - error = JpegEncoderPtr->Encode(empty.GetBuffer(), empty.GetSize(), - 0, height); + empty._buffer = new WebRtc_UWord8[10]; + empty._size = 0; + error = JpegEncoderPtr->Encode(empty); assert(error == -1); - error = JpegEncoderPtr->Encode(empty.GetBuffer(), empty.GetSize(), - width, 0); + empty._size = 10; + empty._height = 0; + error = JpegEncoderPtr->Encode(empty); + assert(error == -1); + empty._height = 164; + empty._width = 0; + error = JpegEncoderPtr->Encode(empty); assert(error == -1); error = JpegEncoderPtr->SetFileName(fileNameEnc); assert(error == 0); + delete [] empty._buffer; + // Actual Encode - error = JpegEncoderPtr->Encode(imageBuffer.GetBuffer(), - imageBuffer.GetSize(), width, height); + error = JpegEncoderPtr->Encode(imageBuffer); assert(error == 0); - std::cout << error << " = Encode(" << fileNameDec << ")" << std::endl; - - PRINT_LINE; - delete JpegEncoderPtr; } - imageBuffer.Free(); - encodedBuffer.Free(); + delete [] imageBuffer._buffer; + delete [] encodedBuffer._buffer; delete JpgDecPtr; std::cout << "Verify that the encoded and decoded images look correct." diff --git a/modules/video_coding/codecs/i420/main/source/i420.gyp b/modules/video_coding/codecs/i420/main/source/i420.gyp index 1650076d68..f3afcb6698 100644 --- a/modules/video_coding/codecs/i420/main/source/i420.gyp +++ b/modules/video_coding/codecs/i420/main/source/i420.gyp @@ -16,10 +16,12 @@ 'include_dirs': [ '../interface', '../../../interface', + '../../../../../../common_video/interface', ], 'direct_dependent_settings': { 'include_dirs': [ '../interface', + '../../../../../../common_video/interface', ], }, 'sources': [ diff --git a/modules/video_coding/codecs/test_framework/test_framework.gyp b/modules/video_coding/codecs/test_framework/test_framework.gyp index f53646c85c..861e1a4150 100644 --- a/modules/video_coding/codecs/test_framework/test_framework.gyp +++ b/modules/video_coding/codecs/test_framework/test_framework.gyp @@ -18,6 +18,7 @@ 'include_dirs': [ '../interface', + '../../../../common_video/interface', ], 'direct_dependent_settings': { diff --git a/modules/video_coding/codecs/vp8/main/source/vp8.gyp b/modules/video_coding/codecs/vp8/main/source/vp8.gyp index 73df292103..ba351fd814 100644 --- a/modules/video_coding/codecs/vp8/main/source/vp8.gyp +++ b/modules/video_coding/codecs/vp8/main/source/vp8.gyp @@ -15,6 +15,7 @@ ], 'include_dirs': [ '../interface', + '../../../../../../common_video/interface', '../../../interface', '../../../../../interface', ], @@ -49,6 +50,7 @@ 'direct_dependent_settings': { 'include_dirs': [ '../interface', + '../../../../../../common_video/interface', '../../../interface', ], }, diff --git a/modules/video_coding/main/source/video_coding.gyp b/modules/video_coding/main/source/video_coding.gyp index e04b7d83e2..f2431f4e07 100644 --- a/modules/video_coding/main/source/video_coding.gyp +++ b/modules/video_coding/main/source/video_coding.gyp @@ -20,6 +20,7 @@ '../interface', '../../../interface', '../../codecs/interface', + '../../../../common_video/interface', ], 'direct_dependent_settings': { 'include_dirs': [ diff --git a/modules/video_coding/main/source/video_coding_test.gyp b/modules/video_coding/main/source/video_coding_test.gyp index 9b0c411406..89e62eff6a 100644 --- a/modules/video_coding/main/source/video_coding_test.gyp +++ b/modules/video_coding/main/source/video_coding_test.gyp @@ -21,6 +21,7 @@ '../../../interface', '../../codecs/vp8/main/interface', '../../../../system_wrappers/interface', + '../../../../common_video/interface', '../source', ], 'sources': [ diff --git a/video_engine/main/source/vie_file_image.cc b/video_engine/main/source/vie_file_image.cc index 1ddb70aa65..7799f120a5 100644 --- a/video_engine/main/source/vie_file_image.cc +++ b/video_engine/main/source/vie_file_image.cc @@ -14,6 +14,7 @@ #include #include "vie_file_image.h" +#include "video_image.h" #include "jpeg.h" #include "trace.h" @@ -24,8 +25,8 @@ int ViEFileImage::ConvertJPEGToVideoFrame(int engineId, VideoFrame& videoFrame) { // read jpeg file into temporary buffer - WebRtc_UWord8* imageBuffer; - WebRtc_UWord32 imageBufferSize; + EncodedImage imageBuffer; + FILE* imageFile = fopen(fileNameUTF8, "rb"); if (NULL == imageFile) { @@ -35,15 +36,15 @@ int ViEFileImage::ConvertJPEGToVideoFrame(int engineId, return -1; } fseek(imageFile, 0, SEEK_END); - imageBufferSize = ftell(imageFile); + imageBuffer._size = ftell(imageFile); fseek(imageFile, 0, SEEK_SET); - imageBuffer = new WebRtc_UWord8[imageBufferSize + 1]; - if (imageBufferSize != fread(imageBuffer, sizeof(WebRtc_UWord8), - imageBufferSize, imageFile)) + imageBuffer._buffer = new WebRtc_UWord8[ imageBuffer._size + 1]; + if ( imageBuffer._size != fread(imageBuffer._buffer, sizeof(WebRtc_UWord8), + imageBuffer._size, imageFile)) { WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, engineId, "%s could not read file %s", __FUNCTION__, fileNameUTF8); - delete imageBuffer; + delete [] imageBuffer._buffer; return -1; } fclose(imageFile); @@ -52,13 +53,13 @@ int ViEFileImage::ConvertJPEGToVideoFrame(int engineId, JpegDecoder decoder; int ret = 0; - WebRtc_UWord8* imageDecodedBuffer = NULL; - WebRtc_UWord32 imageWidth, imageHeight = 0; - ret = decoder.Decode(imageBuffer, imageBufferSize, imageDecodedBuffer, - imageWidth, imageHeight); + + RawImage decodedImage; + ret = decoder.Decode(imageBuffer, decodedImage); // done with this. - delete imageBuffer; + delete [] imageBuffer._buffer; + imageBuffer._buffer = NULL; if (-1 == ret) { @@ -74,20 +75,25 @@ int ViEFileImage::ConvertJPEGToVideoFrame(int engineId, __FUNCTION__, fileNameUTF8); } - WebRtc_UWord32 imageLength = (WebRtc_UWord32)(imageWidth * imageHeight - * 1.5); - if (-1 == videoFrame.Swap(imageDecodedBuffer, imageLength, imageLength)) + WebRtc_UWord32 imageLength = (WebRtc_UWord32)(decodedImage._width * + decodedImage._height * 1.5); + if (-1 == videoFrame.Swap(decodedImage._buffer, imageLength, imageLength)) { - WEBRTC_TRACE( - webrtc::kTraceDebug, - webrtc::kTraceVideo, + WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceVideo, engineId, - "%s could not copy frame imageDecodedBuffer to frame videoFrame ", + "%s could not copy frame imageDecodedBuffer to videoFrame ", __FUNCTION__, fileNameUTF8); return -1; } - videoFrame.SetWidth(imageWidth); - videoFrame.SetHeight(imageHeight); + + if (decodedImage._buffer) + { + delete [] decodedImage._buffer; + decodedImage._buffer = NULL; + } + + videoFrame.SetWidth(decodedImage._width); + videoFrame.SetHeight(decodedImage._height); return 0; } @@ -96,7 +102,7 @@ int ViEFileImage::ConvertPictureToVideoFrame(int engineId, VideoFrame& videoFrame) { WebRtc_UWord32 pictureLength = (WebRtc_UWord32)(picture.width - * picture.height * 1.5); + * picture.height * 1.5); videoFrame.CopyFrame(pictureLength, picture.data); videoFrame.SetWidth(picture.width); videoFrame.SetHeight(picture.height); diff --git a/video_engine/main/source/vie_file_impl.cc b/video_engine/main/source/vie_file_impl.cc index 7488d06931..fec8d914ca 100644 --- a/video_engine/main/source/vie_file_impl.cc +++ b/video_engine/main/source/vie_file_impl.cc @@ -696,28 +696,40 @@ int ViEFileImpl::GetRenderSnapshot(const int videoChannel, // *** Thusly, we are not going to be writing to the disk here JpegEncoder jpegEncoder; + RawImage inputImage; if (-1 == jpegEncoder.SetFileName(fileNameUTF8)) { // could not set filename for whatever reason - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, _instanceId, + WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, + _instanceId, "\tCould not open output file '%s' for writing!", fileNameUTF8); return -1; } - if (-1 == jpegEncoder.Encode(videoFrame.Buffer(), - videoFrame.Length(), - videoFrame.Width(), - videoFrame.Height())) + inputImage._width = videoFrame.Width(); + inputImage._height = videoFrame.Height(); + videoFrame.Swap(inputImage._buffer, inputImage._length, + inputImage._size); + + if (-1 == jpegEncoder.Encode(inputImage)) { // could not encode i420->jpeg - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, _instanceId, + WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, + _instanceId, "\tCould not encode i420 -> jpeg file '%s' for " "writing!", fileNameUTF8); + if (inputImage._buffer) + { + delete [] inputImage._buffer; + } return -1; } + delete [] inputImage._buffer; + inputImage._buffer = NULL; + break; } default: @@ -805,28 +817,45 @@ int ViEFileImpl::GetCaptureDeviceSnapshot(const int captureId, // *** Thusly, we are not going to be writing to the disk here JpegEncoder jpegEncoder; + RawImage inputImage; + + inputImage._width = videoFrame.Width(); + inputImage._height = videoFrame.Height(); + videoFrame.Swap(inputImage._buffer, inputImage._length, + inputImage._size); if (-1 == jpegEncoder.SetFileName(fileNameUTF8)) { // could not set filename for whatever reason - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, _instanceId, + WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, + _instanceId, "\tCould not open output file '%s' for writing!", fileNameUTF8); + + if (inputImage._buffer) + { + delete [] inputImage._buffer; + } return -1; } - if (-1 == jpegEncoder.Encode(videoFrame.Buffer(), - videoFrame.Length(), - videoFrame.Width(), - videoFrame.Height())) + if (-1 == jpegEncoder.Encode(inputImage)) { // could not encode i420->jpeg - WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, _instanceId, + WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, + _instanceId, "\tCould not encode i420 -> jpeg file '%s' for " "writing!", fileNameUTF8); + + if (inputImage._buffer) + { + delete [] inputImage._buffer; + } return -1; } + delete [] inputImage._buffer; + inputImage._buffer = NULL; break; } default: diff --git a/video_engine/main/test/AutoTest/vie_auto_test.gypi b/video_engine/main/test/AutoTest/vie_auto_test.gypi index 4f21dd16d2..2d81516b9c 100644 --- a/video_engine/main/test/AutoTest/vie_auto_test.gypi +++ b/video_engine/main/test/AutoTest/vie_auto_test.gypi @@ -22,6 +22,7 @@ '../../interface', '../../source', '../../../../modules/video_coding/codecs/interface/', + '../../../../common_video/interface/', ], 'sources': [ # interfaces