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:
parent
8d95a700e9
commit
7cbb5a05c4
@ -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;
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -28,6 +28,7 @@
|
||||
'include',
|
||||
'<(webrtc_root)',
|
||||
'<(webrtc_root)/common_video/interface',
|
||||
'<(webrtc_root)/modules/interface/',
|
||||
],
|
||||
'direct_dependent_settings': {
|
||||
'include_dirs': [
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user