Changing JPEG API to to accept rawImage and encodedImage; moved video_image.h from modules/video_coding/codecs to common_video/interface, and some general re-write to JPEG, especially with regard to memory handling. Required VCM/ViE changes are also included.

Review URL: http://webrtc-codereview.appspot.com/55002

git-svn-id: http://webrtc.googlecode.com/svn/trunk@139 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
mikhal@google.com 2011-07-01 01:17:49 +00:00
parent 67d7282900
commit b5427cbd35
13 changed files with 243 additions and 205 deletions

View File

@ -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 <stdlib.h>
@ -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

View File

@ -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;
};

View File

@ -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;

View File

@ -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

View File

@ -19,13 +19,11 @@
#include <stdio.h>
#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."

View File

@ -16,10 +16,12 @@
'include_dirs': [
'../interface',
'../../../interface',
'../../../../../../common_video/interface',
],
'direct_dependent_settings': {
'include_dirs': [
'../interface',
'../../../../../../common_video/interface',
],
},
'sources': [

View File

@ -18,6 +18,7 @@
'include_dirs': [
'../interface',
'../../../../common_video/interface',
],
'direct_dependent_settings': {

View File

@ -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',
],
},

View File

@ -20,6 +20,7 @@
'../interface',
'../../../interface',
'../../codecs/interface',
'../../../../common_video/interface',
],
'direct_dependent_settings': {
'include_dirs': [

View File

@ -21,6 +21,7 @@
'../../../interface',
'../../codecs/vp8/main/interface',
'../../../../system_wrappers/interface',
'../../../../common_video/interface',
'../source',
],
'sources': [

View File

@ -14,6 +14,7 @@
#include <stdio.h>
#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);

View File

@ -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:

View File

@ -22,6 +22,7 @@
'../../interface',
'../../source',
'../../../../modules/video_coding/codecs/interface/',
'../../../../common_video/interface/',
],
'sources': [
# interfaces