Commit 63ee22c7 authored by wjia@chromium.org's avatar wjia@chromium.org

chop the width/height to even number when incoming frame has odd number dimension.

Some video capture device has odd number for width/height. Need to chop them to even number.

BUG=139004
Review URL: https://chromiumcodereview.appspot.com/10837225

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@151753 0039d316-1c4b-4281-b951-d872f2087c98
parent 24d16231
......@@ -67,7 +67,9 @@ struct VideoCaptureController::SharedDIB {
VideoCaptureController::VideoCaptureController(
media_stream::VideoCaptureManager* video_capture_manager)
: frame_info_available_(false),
: chopped_width_(0),
chopped_height_(0),
frame_info_available_(false),
video_capture_manager_(video_capture_manager),
device_in_use_(false),
state_(video_capture::kStopped) {
......@@ -277,10 +279,12 @@ void VideoCaptureController::OnIncomingCapturedFrame(const uint8* data,
case media::VideoCaptureCapability::kColorUnknown: // Color format not set.
break;
case media::VideoCaptureCapability::kI420: {
DCHECK(!chopped_width_ && !chopped_height_);
memcpy(target, data, (frame_info_.width * frame_info_.height * 3) / 2);
break;
}
case media::VideoCaptureCapability::kYV12: {
DCHECK(!chopped_width_ && !chopped_height_);
const uint8* ptr = data;
memcpy(yplane, ptr, (frame_info_.width * frame_info_.height));
ptr += frame_info_.width * frame_info_.height;
......@@ -290,11 +294,13 @@ void VideoCaptureController::OnIncomingCapturedFrame(const uint8* data,
break;
}
case media::VideoCaptureCapability::kNV21: {
DCHECK(!chopped_width_ && !chopped_height_);
media::ConvertNV21ToYUV(data, yplane, uplane, vplane, frame_info_.width,
frame_info_.height);
break;
}
case media::VideoCaptureCapability::kYUY2: {
DCHECK(!chopped_width_ && !chopped_height_);
media::ConvertYUY2ToYUV(data, yplane, uplane, vplane, frame_info_.width,
frame_info_.height);
break;
......@@ -303,11 +309,11 @@ void VideoCaptureController::OnIncomingCapturedFrame(const uint8* data,
int ystride = frame_info_.width;
int uvstride = frame_info_.width / 2;
#if defined(OS_WIN) // RGB on Windows start at the bottom line.
int rgb_stride = -3 * frame_info_.width;
const uint8* rgb_src = data + 3 * frame_info_.width *
(frame_info_.height -1);
int rgb_stride = -3 * (frame_info_.width + chopped_width_);
const uint8* rgb_src = data + 3 * (frame_info_.width + chopped_width_) *
(frame_info_.height -1 + chopped_height_);
#else
int rgb_stride = 3 * frame_info_.width;
int rgb_stride = 3 * (frame_info_.width + chopped_width_);
const uint8* rgb_src = data;
#endif
media::ConvertRGB24ToYUV(rgb_src, yplane, uplane, vplane,
......@@ -317,7 +323,8 @@ void VideoCaptureController::OnIncomingCapturedFrame(const uint8* data,
}
case media::VideoCaptureCapability::kARGB: {
media::ConvertRGB32ToYUV(data, yplane, uplane, vplane, frame_info_.width,
frame_info_.height, frame_info_.width * 4,
frame_info_.height,
(frame_info_.width + chopped_width_) * 4,
frame_info_.width, frame_info_.width / 2);
break;
}
......@@ -341,10 +348,22 @@ void VideoCaptureController::OnError() {
void VideoCaptureController::OnFrameInfo(
const media::VideoCaptureCapability& info) {
frame_info_= info;
// Handle cases when |info| has odd numbers for width/height.
if (info.width & 1) {
--frame_info_.width;
chopped_width_ = 1;
} else {
chopped_width_ = 0;
}
if (info.height & 1) {
--frame_info_.height;
chopped_height_ = 1;
} else {
chopped_height_ = 0;
}
BrowserThread::PostTask(BrowserThread::IO,
FROM_HERE,
base::Bind(&VideoCaptureController::DoFrameInfoOnIOThread,
this, info));
base::Bind(&VideoCaptureController::DoFrameInfoOnIOThread, this));
}
VideoCaptureController::~VideoCaptureController() {
......@@ -389,14 +408,17 @@ void VideoCaptureController::DoIncomingCapturedFrameOnIOThread(
}
}
void VideoCaptureController::DoFrameInfoOnIOThread(
const media::VideoCaptureCapability& info) {
void VideoCaptureController::DoFrameInfoOnIOThread() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
DCHECK(owned_dibs_.empty())
<< "Device is restarted without releasing shared memory.";
// Allocate memory only when device has been started.
if (state_ != video_capture::kStarted)
return;
bool frames_created = true;
const size_t needed_size = (info.width * info.height * 3) / 2;
const size_t needed_size = (frame_info_.width * frame_info_.height * 3) / 2;
{
base::AutoLock lock(lock_);
for (size_t i = 1; i <= kNoOfDIBS; ++i) {
......
......@@ -88,7 +88,7 @@ class CONTENT_EXPORT VideoCaptureController
// Worker functions on IO thread.
void DoIncomingCapturedFrameOnIOThread(int buffer_id, base::Time timestamp);
void DoFrameInfoOnIOThread(const media::VideoCaptureCapability& info);
void DoFrameInfoOnIOThread();
void DoErrorOnIOThread();
void DoDeviceStoppedOnIOThread();
......@@ -132,6 +132,10 @@ class CONTENT_EXPORT VideoCaptureController
// It's modified on caller thread, assuming there is only one OnFrameInfo()
// call per StartCapture().
media::VideoCaptureCapability frame_info_;
// Chopped pixels in width/height in case video capture device has odd numbers
// for width/height.
int chopped_width_;
int chopped_height_;
// It's accessed only on IO thread.
bool frame_info_available_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment