зеркало из https://github.com/mozilla/gecko-dev.git
Bug 819835 - add support for setting the EXIF DateTime field, r=sotaro
This commit is contained in:
Родитель
a1d14d0e97
Коммит
3fb12b17e4
|
@ -333,7 +333,7 @@ CameraControlImpl::AutoFocus(nsICameraAutoFocusCallback* onSuccess, nsICameraErr
|
|||
}
|
||||
|
||||
nsresult
|
||||
CameraControlImpl::TakePicture(CameraSize aSize, int32_t aRotation, const nsAString& aFileFormat, CameraPosition aPosition, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError)
|
||||
CameraControlImpl::TakePicture(CameraSize aSize, int32_t aRotation, const nsAString& aFileFormat, CameraPosition aPosition, uint64_t aDateTime, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
bool cancel = false;
|
||||
|
@ -349,7 +349,7 @@ CameraControlImpl::TakePicture(CameraSize aSize, int32_t aRotation, const nsAStr
|
|||
cancel = true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> takePictureTask = new TakePictureTask(this, cancel, aSize, aRotation, aFileFormat, aPosition, onSuccess, onError);
|
||||
nsCOMPtr<nsIRunnable> takePictureTask = new TakePictureTask(this, cancel, aSize, aRotation, aFileFormat, aPosition, aDateTime, onSuccess, onError);
|
||||
return mCameraThread->Dispatch(takePictureTask, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ public:
|
|||
nsresult StartPreview(DOMCameraPreview* aDOMPreview);
|
||||
void StopPreview();
|
||||
nsresult AutoFocus(nsICameraAutoFocusCallback* onSuccess, nsICameraErrorCallback* onError);
|
||||
nsresult TakePicture(dom::CameraSize aSize, int32_t aRotation, const nsAString& aFileFormat, dom::CameraPosition aPosition, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError);
|
||||
nsresult TakePicture(dom::CameraSize aSize, int32_t aRotation, const nsAString& aFileFormat, dom::CameraPosition aPosition, uint64_t aDateTime, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError);
|
||||
nsresult StartRecording(dom::CameraStartRecordingOptions* aOptions, nsIFile* aFolder, const nsAString& aFilename, nsICameraStartRecordingCallback* onSuccess, nsICameraErrorCallback* onError);
|
||||
nsresult StopRecording();
|
||||
nsresult GetPreviewStreamVideoMode(dom::CameraRecorderOptions* aOptions, nsICameraPreviewStreamCallback* onSuccess, nsICameraErrorCallback* onError);
|
||||
|
@ -361,13 +361,14 @@ protected:
|
|||
class TakePictureTask : public nsRunnable
|
||||
{
|
||||
public:
|
||||
TakePictureTask(CameraControlImpl* aCameraControl, bool aCancel, dom::CameraSize aSize, int32_t aRotation, const nsAString& aFileFormat, dom::CameraPosition aPosition, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError)
|
||||
TakePictureTask(CameraControlImpl* aCameraControl, bool aCancel, dom::CameraSize aSize, int32_t aRotation, const nsAString& aFileFormat, dom::CameraPosition aPosition, uint64_t aDateTime, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError)
|
||||
: mCameraControl(aCameraControl)
|
||||
, mCancel(aCancel)
|
||||
, mSize(aSize)
|
||||
, mRotation(aRotation)
|
||||
, mFileFormat(aFileFormat)
|
||||
, mPosition(aPosition)
|
||||
, mDateTime(aDateTime)
|
||||
, mOnSuccessCb(new nsMainThreadPtrHolder<nsICameraTakePictureCallback>(onSuccess))
|
||||
, mOnErrorCb(new nsMainThreadPtrHolder<nsICameraErrorCallback>(onError))
|
||||
{
|
||||
|
@ -399,6 +400,7 @@ public:
|
|||
int32_t mRotation;
|
||||
nsString mFileFormat;
|
||||
dom::CameraPosition mPosition;
|
||||
uint64_t mDateTime;
|
||||
nsMainThreadPtrHandle<nsICameraTakePictureCallback> mOnSuccessCb;
|
||||
nsMainThreadPtrHandle<nsICameraErrorCallback> mOnErrorCb;
|
||||
};
|
||||
|
|
|
@ -357,7 +357,7 @@ nsDOMCameraControl::TakePicture(const JS::Value& aOptions, nsICameraTakePictureC
|
|||
rv = pos.Init(cx, &options.position);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return mCameraControl->TakePicture(size, options.rotation, options.fileFormat, pos, onSuccess, onError);
|
||||
return mCameraControl->TakePicture(size, options.rotation, options.fileFormat, pos, options.dateTime, onSuccess, onError);
|
||||
}
|
||||
|
||||
/* [implicit_jscontext] void GetPreviewStreamVideoMode (in jsval aOptions, in nsICameraPreviewStreamCallback onSuccess, [optional] in nsICameraErrorCallback onError); */
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -797,6 +798,28 @@ nsGonkCameraControl::TakePictureImpl(TakePictureTask* aTakePicture)
|
|||
SetParameter(CameraParameters::KEY_GPS_TIMESTAMP, nsPrintfCString("%lf", aTakePicture->mPosition.timestamp).get());
|
||||
}
|
||||
|
||||
// Add the non-GPS timestamp. The EXIF date/time field is formatted as
|
||||
// "YYYY:MM:DD HH:MM:SS", without room for a time-zone; as such, the time
|
||||
// is meant to be stored as a local time. Since we are given seconds from
|
||||
// Epoch GMT, we use localtime_r() to handle the conversion.
|
||||
time_t time = aTakePicture->mDateTime;
|
||||
if (time != aTakePicture->mDateTime) {
|
||||
DOM_CAMERA_LOGE("picture date/time '%llu' is too far in the future\n", aTakePicture->mDateTime);
|
||||
} else {
|
||||
struct tm t;
|
||||
if (localtime_r(&time, &t)) {
|
||||
char dateTime[20];
|
||||
if (strftime(dateTime, sizeof(dateTime), "%Y:%m:%d %T", &t)) {
|
||||
DOM_CAMERA_LOGI("setting picture date/time to %s\n", dateTime);
|
||||
SetParameter(CameraParameters::KEY_EXIF_DATETIME, dateTime);
|
||||
} else {
|
||||
DOM_CAMERA_LOGE("picture date/time couldn't be converted to string\n");
|
||||
}
|
||||
} else {
|
||||
DOM_CAMERA_LOGE("picture date/time couldn't be converted to local time: (%d) %s\n", errno, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
mDeferConfigUpdate = false;
|
||||
PushParameters();
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ public:
|
|||
virtual nsresult StartPreview(DOMCameraPreview* aDOMPreview) = 0;
|
||||
virtual void StopPreview() = 0;
|
||||
virtual nsresult AutoFocus(nsICameraAutoFocusCallback* onSuccess, nsICameraErrorCallback* onError) = 0;
|
||||
virtual nsresult TakePicture(dom::CameraSize aSize, int32_t aRotation, const nsAString& aFileFormat, dom::CameraPosition aPosition, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError) = 0;
|
||||
virtual nsresult TakePicture(dom::CameraSize aSize, int32_t aRotation, const nsAString& aFileFormat, dom::CameraPosition aPosition, uint64_t aDateTime, nsICameraTakePictureCallback* onSuccess, nsICameraErrorCallback* onError) = 0;
|
||||
virtual nsresult StartRecording(dom::CameraStartRecordingOptions* aOptions, nsIFile* aFolder, const nsAString& aFilename, nsICameraStartRecordingCallback* onSuccess, nsICameraErrorCallback* onError) = 0;
|
||||
virtual nsresult StopRecording() = 0;
|
||||
virtual nsresult GetPreviewStreamVideoMode(dom::CameraRecorderOptions* aOptions, nsICameraPreviewStreamCallback* onSuccess, nsICameraErrorCallback* onError) = 0;
|
||||
|
|
|
@ -150,6 +150,10 @@ dictionary CameraPictureOptions
|
|||
January 1, 1970.
|
||||
*/
|
||||
jsval position;
|
||||
|
||||
/* the number of seconds from January 1, 1970 UTC. This can be
|
||||
different from the positional timestamp (above). */
|
||||
long long dateTime;
|
||||
};
|
||||
|
||||
/* These properties affect the video recording preview, e.g.
|
||||
|
@ -163,7 +167,7 @@ dictionary CameraPictureOptions
|
|||
an arbitrary profile will be chosen.
|
||||
|
||||
'rotation' is the degrees clockwise to rotate the preview; if
|
||||
this options is not supported, it will be ignored; if this option
|
||||
this option is not supported, it will be ignored; if this option
|
||||
is missing, the default is 0.
|
||||
*/
|
||||
dictionary CameraRecorderOptions
|
||||
|
|
Загрузка…
Ссылка в новой задаче