JPEG: Replacing RawImage with VideoFrame.

Replacing RawImage with VideoFrame in JPEG related code

BUG=
TEST=

Review URL: https://webrtc-codereview.appspot.com/703004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@2530 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
mikhal@webrtc.org 2012-07-25 20:38:14 +00:00
parent 8d95a700e9
commit 7cbb5a05c4
6 changed files with 47 additions and 100 deletions

View File

@ -12,7 +12,8 @@
#define WEBRTC_COMMON_VIDEO_JPEG
#include "typedefs.h"
#include "video_image.h"
#include "modules/interface/module_common_types.h" // VideoFrame
#include "common_video/interface/video_image.h" // EncodedImage
// jpeg forward declaration
struct jpeg_compress_struct;
@ -44,7 +45,7 @@ public:
// Output:
// - 0 : OK
// - (-1) : Error
WebRtc_Word32 Encode(const RawImage& inputImage);
WebRtc_Word32 Encode(const VideoFrame& inputImage);
private:
@ -64,13 +65,13 @@ class JpegDecoder
//
// Input:
// - inputImage : encoded image to be decoded.
// - outputImage : RawImage to store decoded output
// - outputImage : VideoFrame to store decoded output.
//
// Output:
// - 0 : OK
// - (-1) : Error
WebRtc_Word32 Decode(const EncodedImage& inputImage,
RawImage& outputImage);
VideoFrame& outputImage);
private:
jpeg_decompress_struct* _cinfo;
};

View File

@ -17,6 +17,7 @@
#include "common_video/jpeg/include/jpeg.h"
#include "common_video/jpeg/data_manager.h"
#include "common_video/libyuv/include/libyuv.h"
extern "C" {
#if defined(USE_SYSTEM_LIBJPEG)
@ -81,21 +82,21 @@ JpegEncoder::SetFileName(const char* fileName)
WebRtc_Word32
JpegEncoder::Encode(const RawImage& inputImage)
JpegEncoder::Encode(const VideoFrame& inputImage)
{
if (inputImage._buffer == NULL || inputImage._size == 0)
if (inputImage.Buffer() == NULL || inputImage.Size() == 0)
{
return -1;
}
if (inputImage._width < 1 || inputImage._height < 1)
if (inputImage.Width() < 1 || inputImage.Height() < 1)
{
return -1;
}
FILE* outFile = NULL;
const WebRtc_UWord32 width = inputImage._width;
const WebRtc_UWord32 height = inputImage._height;
const WebRtc_UWord32 width = inputImage.Width();
const WebRtc_UWord32 height = inputImage.Height();
// Set error handler
myErrorMgr jerr;
@ -140,15 +141,15 @@ JpegEncoder::Encode(const RawImage& inputImage)
_cinfo->raw_data_in = TRUE;
WebRtc_UWord32 height16 = (height + 15) & ~15;
WebRtc_UWord8* imgPtr = inputImage._buffer;
WebRtc_UWord8* imgPtr = inputImage.Buffer();
WebRtc_UWord8* origImagePtr = NULL;
if (height16 != height)
{
// Copy image to an adequate size buffer
WebRtc_UWord32 requiredSize = height16 * width * 3 >> 1;
WebRtc_UWord32 requiredSize = CalcBufferSize(kI420, width, height16);
origImagePtr = new WebRtc_UWord8[requiredSize];
memset(origImagePtr, 0, requiredSize);
memcpy(origImagePtr, inputImage._buffer, inputImage._length);
memcpy(origImagePtr, inputImage.Buffer(), inputImage.Length());
imgPtr = origImagePtr;
}
@ -209,7 +210,7 @@ JpegDecoder::~JpegDecoder()
WebRtc_Word32
JpegDecoder::Decode(const EncodedImage& inputImage,
RawImage& outputImage)
VideoFrame& outputImage)
{
WebRtc_UWord8* tmpBuffer = NULL;
@ -278,20 +279,9 @@ JpegDecoder::Decode(const EncodedImage& inputImage,
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;
// Verify sufficient buffer size.
outputImage.VerifyAndAllocate(requiredSize);
WebRtc_UWord8* outPtr = outputImage.Buffer();
if (tmpRequiredSize > requiredSize)
{
@ -337,7 +327,7 @@ JpegDecoder::Decode(const EncodedImage& inputImage,
if (tmpRequiredSize > requiredSize)
{
WebRtc_UWord8* dstFramePtr = outputImage._buffer;
WebRtc_UWord8* dstFramePtr = outputImage.Buffer();
WebRtc_UWord8* tmpPtr = outPtr;
for (WebRtc_UWord32 p = 0; p < 3; p++)
@ -362,10 +352,10 @@ JpegDecoder::Decode(const EncodedImage& inputImage,
delete [] tmpBuffer;
}
// Setting output Image parameter
outputImage._width = width;
outputImage._height = height;
outputImage._length = requiredSize;
outputImage._timeStamp = inputImage._timeStamp;
outputImage.SetWidth(width);
outputImage.SetHeight(height);
outputImage.SetLength(requiredSize);
outputImage.SetTimeStamp(inputImage._timeStamp);
jpeg_finish_decompress(_cinfo);
jpeg_destroy_decompress(_cinfo);

View File

@ -28,6 +28,7 @@
'include',
'<(webrtc_root)',
'<(webrtc_root)/common_video/interface',
'<(webrtc_root)/modules/interface/',
],
'direct_dependent_settings': {
'include_dirs': [

View File

@ -15,6 +15,7 @@
#include "common_video/interface/video_image.h"
#include "gtest/gtest.h"
#include "testsupport/fileutils.h"
#include "modules/interface/module_common_types.h"
namespace webrtc {
@ -74,39 +75,38 @@ class JpegTest: public testing::Test {
TEST_F(JpegTest, Decode) {
encoded_buffer_ = ReadEncodedImage(input_filename_);
RawImage image_buffer;
VideoFrame image_buffer;
EXPECT_EQ(0, decoder_->Decode(*encoded_buffer_, image_buffer));
EXPECT_GT(image_buffer._length, 0u);
EXPECT_EQ(kImageWidth, image_buffer._width);
EXPECT_EQ(kImageHeight, image_buffer._height);
delete [] image_buffer._buffer;
EXPECT_GT(image_buffer.Length(), 0u);
EXPECT_EQ(kImageWidth, image_buffer.Width());
EXPECT_EQ(kImageHeight, image_buffer.Height());
image_buffer.Free();
}
TEST_F(JpegTest, EncodeInvalidInputs) {
RawImage empty;
empty._width = 164;
empty._height = 164;
VideoFrame empty;
empty.SetWidth(164);
empty.SetHeight(164);
EXPECT_EQ(-1, encoder_->SetFileName(0));
EXPECT_EQ(-1, encoder_->Encode(empty));
empty._buffer = new WebRtc_UWord8[10];
empty._size = 0;
empty.VerifyAndAllocate(0);
EXPECT_EQ(-1, encoder_->Encode(empty));
empty._size = 10;
empty._height = 0;
empty.VerifyAndAllocate(10);
empty.SetHeight(0);
EXPECT_EQ(-1, encoder_->Encode(empty));
empty._height = 164;
empty._width = 0;
empty.SetHeight(164);
empty.SetWidth(0);
EXPECT_EQ(-1, encoder_->Encode(empty));
delete[] empty._buffer;
empty.Free();
}
TEST_F(JpegTest, Encode) {
// Decode our input image then encode it again to a new file:
encoded_buffer_ = ReadEncodedImage(input_filename_);
RawImage image_buffer;
VideoFrame image_buffer;
EXPECT_EQ(0, decoder_->Decode(*encoded_buffer_, image_buffer));
EXPECT_EQ(0, encoder_->SetFileName(encoded_filename_.c_str()));
@ -114,13 +114,13 @@ TEST_F(JpegTest, Encode) {
// Save decoded image to file.
FILE* save_file = fopen(decoded_filename_.c_str(), "wb");
if (fwrite(image_buffer._buffer, 1,
image_buffer._length, save_file) != image_buffer._length) {
if (fwrite(image_buffer.Buffer(), 1,
image_buffer.Length(), save_file) != image_buffer.Length()) {
return;
}
fclose(save_file);
delete[] image_buffer._buffer;
image_buffer.Free();
}
} // namespace webrtc

View File

@ -70,8 +70,7 @@ int ViEFileImage::ConvertJPEGToVideoFrame(int engine_id,
fclose(image_file);
JpegDecoder decoder;
RawImage decoded_image;
int ret = decoder.Decode(image_buffer, decoded_image);
int ret = decoder.Decode(image_buffer, *video_frame);
delete [] image_buffer._buffer;
image_buffer._buffer = NULL;
@ -86,25 +85,6 @@ int ViEFileImage::ConvertJPEGToVideoFrame(int engine_id,
"%s could not convert jpeg's data to i420 format",
__FUNCTION__, file_nameUTF8);
}
// Image length in I420.
WebRtc_UWord32 image_length = (WebRtc_UWord32)(decoded_image._width *
decoded_image._height * 1.5);
if (-1 == video_frame->Swap(decoded_image._buffer, image_length,
image_length)) {
WEBRTC_TRACE(kTraceDebug, kTraceVideo, engine_id,
"%s could not copy frame image_decoded_buffer to video_frame ",
__FUNCTION__, file_nameUTF8);
return -1;
}
if (decoded_image._buffer) {
delete [] decoded_image._buffer;
decoded_image._buffer = NULL;
}
video_frame->SetWidth(decoded_image._width);
video_frame->SetHeight(decoded_image._height);
return 0;
}

View File

@ -566,7 +566,6 @@ int ViEFileImpl::GetRenderSnapshot(const int video_channel,
// not return you the buffer. Thus, we are not going to be writing to the
// disk here.
JpegEncoder jpeg_encoder;
RawImage input_image;
if (jpeg_encoder.SetFileName(file_nameUTF8) == -1) {
WEBRTC_TRACE(kTraceError, kTraceVideo, shared_data_->instance_id(),
"\tCould not open output file '%s' for writing!",
@ -574,23 +573,12 @@ int ViEFileImpl::GetRenderSnapshot(const int video_channel,
return -1;
}
input_image._width = video_frame.Width();
input_image._height = video_frame.Height();
video_frame.Swap(input_image._buffer, input_image._length,
input_image._size);
if (jpeg_encoder.Encode(input_image) == -1) {
if (jpeg_encoder.Encode(video_frame) == -1) {
WEBRTC_TRACE(kTraceError, kTraceVideo, shared_data_->instance_id(),
"\tCould not encode i420 -> jpeg file '%s' for writing!",
file_nameUTF8);
if (input_image._buffer) {
delete [] input_image._buffer;
input_image._buffer = NULL;
}
return -1;
}
delete [] input_image._buffer;
input_image._buffer = NULL;
return 0;
}
@ -642,33 +630,20 @@ int ViEFileImpl::GetCaptureDeviceSnapshot(const int capture_id,
// not return you the buffer Thusly, we are not going to be writing to the
// disk here.
JpegEncoder jpeg_encoder;
RawImage input_image;
input_image._width = video_frame.Width();
input_image._height = video_frame.Height();
video_frame.Swap(input_image._buffer, input_image._length,
input_image._size);
if (jpeg_encoder.SetFileName(file_nameUTF8) == -1) {
WEBRTC_TRACE(kTraceError, kTraceVideo, shared_data_->instance_id(),
"\tCould not open output file '%s' for writing!",
file_nameUTF8);
if (input_image._buffer) {
delete [] input_image._buffer;
}
return -1;
}
if (jpeg_encoder.Encode(input_image) == -1) {
if (jpeg_encoder.Encode(video_frame) == -1) {
WEBRTC_TRACE(kTraceError, kTraceVideo, shared_data_->instance_id(),
"\tCould not encode i420 -> jpeg file '%s' for "
"writing!", file_nameUTF8);
if (input_image._buffer) {
delete [] input_image._buffer;
}
return -1;
}
delete [] input_image._buffer;
input_image._buffer = NULL;
return 0;
}