Bug 963142 - fix negative-rotation math error in startRecording(), r=dhylands
authorMike Habicher <mikeh@mozilla.com>
Thu, 23 Jan 2014 19:10:23 -0500
changeset 181040 15ec5afea92ff2e1b4a775398571c08450e0d709
parent 181039 6c84e3865bfb7c951056361b6ca3166030d83572
child 181041 0296575a1305c8d65aaaa2859f75e24a899c8a20
push id3343
push userffxbld
push dateMon, 17 Mar 2014 21:55:32 +0000
treeherdermozilla-beta@2f7d3415f79f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdhylands
bugs963142
milestone29.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 963142 - fix negative-rotation math error in startRecording(), r=dhylands
dom/camera/GonkCameraControl.cpp
dom/camera/GonkCameraControl.h
--- a/dom/camera/GonkCameraControl.cpp
+++ b/dom/camera/GonkCameraControl.cpp
@@ -963,16 +963,40 @@ nsGonkCameraControl::SetPictureSize(uint
     RwAutoLockWrite write(mRwLock);
     mParams.setPictureSize(static_cast<int>(w), static_cast<int>(h));
   }
 
   // Finally, update the thumbnail size
   UpdateThumbnailSize();
 }
 
+int32_t
+nsGonkCameraControl::RationalizeRotation(int32_t aRotation)
+{
+  int32_t r = aRotation;
+
+  // The result of this operation is an angle from 0..270 degrees,
+  // in steps of 90 degrees. Angles are rounded to the nearest
+  // magnitude, so 45 will be rounded to 90, and -45 will be rounded
+  // to -90 (not 0).
+  if (r >= 0) {
+    r += 45;
+  } else {
+    r -= 45;
+  }
+  r /= 90;
+  r %= 4;
+  r *= 90;
+  if (r < 0) {
+    r += 360;
+  }
+
+  return r;
+}
+
 nsresult
 nsGonkCameraControl::TakePictureImpl(TakePictureTask* aTakePicture)
 {
   if (aTakePicture->mCancel) {
     if (mCameraHw.get()) {
       mCameraHw->CancelTakePicture();
     }
   }
@@ -987,29 +1011,19 @@ nsGonkCameraControl::TakePictureImpl(Tak
 
   SetPictureSize(aTakePicture->mSize.width, aTakePicture->mSize.height);
 
   // Picture format -- need to keep it for the callback.
   mFileFormat = aTakePicture->mFileFormat;
   SetParameter(CameraParameters::KEY_PICTURE_FORMAT, NS_ConvertUTF16toUTF8(mFileFormat).get());
 
   // Round 'rotation' up to a positive value from 0..270 degrees, in steps of 90.
-  uint32_t r = static_cast<uint32_t>(aTakePicture->mRotation);
+  int32_t r = static_cast<uint32_t>(aTakePicture->mRotation);
   r += mCameraHw->GetSensorOrientation(GonkCameraHardware::OFFSET_SENSOR_ORIENTATION);
-  if (r >= 0) {
-    r += 45;
-  } else {
-    r -= 45;
-  }
-  r /= 90;
-  r %= 4;
-  r *= 90;
-  if (r < 0) {
-    r += 360;
-  }
+  r = RationalizeRotation(r);
   DOM_CAMERA_LOGI("setting picture rotation to %d degrees (mapped from %d)\n", r, aTakePicture->mRotation);
   SetParameter(CameraParameters::KEY_ROTATION, nsPrintfCString("%u", r).get());
 
   // Add any specified positional information -- don't care if these fail.
   if (!isnan(aTakePicture->mPosition.latitude)) {
     DOM_CAMERA_LOGI("setting picture latitude to %lf\n", aTakePicture->mPosition.latitude);
     SetParameter(CameraParameters::KEY_GPS_LATITUDE, nsPrintfCString("%lf", aTakePicture->mPosition.latitude).get());
   }
@@ -1519,24 +1533,17 @@ nsGonkCameraControl::SetupRecording(int 
     aMaxFileSizeBytes = -1;
   }
   snprintf(buffer, SIZE, "max-filesize=%lld", aMaxFileSizeBytes);
   CHECK_SETARG(mRecorder->setParameters(String8(buffer)));
 
   // adjust rotation by camera sensor offset
   int r = aRotation;
   r += mCameraHw->GetSensorOrientation();
-  r %= 360;
-  r += 45;
-  r /= 90;
-  r *= 90;
-  if (r < 0) {
-    // the video recorder only supports positive rotations
-    r += 360;
-  }
+  r = RationalizeRotation(r);
   DOM_CAMERA_LOGI("setting video rotation to %d degrees (mapped from %d)\n", r, aRotation);
   snprintf(buffer, SIZE, "video-param-rotation-angle-degrees=%d", r);
   CHECK_SETARG(mRecorder->setParameters(String8(buffer)));
 
   CHECK_SETARG(mRecorder->setListener(new GonkRecorderListener(this)));
 
   // recording API needs file descriptor of output file
   CHECK_SETARG(mRecorder->setOutputFile(aFd, 0, 0));
--- a/dom/camera/GonkCameraControl.h
+++ b/dom/camera/GonkCameraControl.h
@@ -91,16 +91,18 @@ protected:
 
   nsresult SetupRecording(int aFd, int aRotation, int64_t aMaxFileSizeBytes, int64_t aMaxVideoLengthMs);
   nsresult SetupVideoMode(const nsAString& aProfile);
   void SetPreviewSize(uint32_t aWidth, uint32_t aHeight);
   void SetThumbnailSize(uint32_t aWidth, uint32_t aHeight);
   void UpdateThumbnailSize();
   void SetPictureSize(uint32_t aWidth, uint32_t aHeight);
 
+  int32_t RationalizeRotation(int32_t aRotation);
+
   android::sp<android::GonkCameraHardware> mCameraHw;
   double                    mExposureCompensationMin;
   double                    mExposureCompensationStep;
   bool                      mDeferConfigUpdate;
   PRRWLock*                 mRwLock;
   android::CameraParameters mParams;
   uint32_t                  mWidth;
   uint32_t                  mHeight;