2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * @author Karol Majewski (k.majewski@samsung.com)
26 #include <dpl/assert.h>
27 #include <dpl/shared_ptr.h>
28 #include "mm_camcorder.h"
29 #include <commons/Exception.h>
30 #include "AttributeInfo.h"
33 const unsigned int DEFAULT_CAPTURE_WIDTH = 640;
34 const unsigned int DEFAULT_CAPTURE_HEIGHT = 480;
37 namespace WrtPlugins {
40 //.............................................................................
42 m_camcorderHandle(NULL)
44 m_camcorderPreset.videodev_type = MM_VIDEO_DEVICE_NONE,
45 m_camcorderPreset.reserved[0] = 0;
46 m_camcorderPreset.reserved[1] = 0;
47 m_camcorderPreset.reserved[2] = 0;
48 m_camcorderPreset.reserved[3] = 0;
50 pthread_mutex_init(&m_stateMutex, NULL);
52 DPL::Event::ControllerEventHandler<JobDoneEvent >::Touch();
54 //.............................................................................
55 void Camera::init(MMCamPreset preset)
57 LogDebug("Creating camcorder");
58 memcpy(&m_camcorderPreset, &preset, sizeof(m_camcorderPreset));
59 int err = mm_camcorder_create(&m_camcorderHandle, &m_camcorderPreset);
62 if (err != MM_ERROR_NONE) {
63 LogError("Creating camcorder's failed !!! " << err);
64 Throw(Commons::UnknownException);
67 //.............................................................................
70 LogDebug(__FUNCTION__);
72 DPL::Event::ControllerEventHandler<JobDoneEvent >::SwitchToThread(NULL);
75 pthread_mutex_lock(&m_stateMutex);
79 mm_camcorder_set_message_callback(m_camcorderHandle, NULL, NULL);
80 mm_camcorder_capture_stop(m_camcorderHandle);
81 mm_camcorder_stop(m_camcorderHandle);
83 pthread_mutex_unlock(&m_stateMutex);
86 mm_camcorder_destroy(m_camcorderHandle);
87 pthread_mutex_destroy(&m_stateMutex);
89 //.............................................................................
90 void Camera::tryIsInvalidParameterError(int errorCode)
93 case MM_ERROR_COMMON_INVALID_ATTRTYPE:
94 case MM_ERROR_COMMON_INVALID_PERMISSION:
95 case MM_ERROR_COMMON_OUT_OF_ARRAY:
96 case MM_ERROR_COMMON_OUT_OF_RANGE:
97 case MM_ERROR_COMMON_ATTR_NOT_EXIST:
98 LogDebug("Invalid Parameter error");
99 Throw(Commons::InvalidArgumentException);
101 LogDebug("it's not Invalid Parameter error");
103 //.............................................................................
104 int Camera::lockCameraMutex(Camera *camera)
106 LogDebug("Trying to lock camera mutex");
107 pthread_mutex_lock(&(camera->m_stateMutex));
108 LogDebug(".. - locked");
110 if (Camera::PROCESSING == camera->m_state) {
112 "Camera object is being killed or performing some locked operations, but it's receiving the message ");
113 pthread_mutex_unlock(&(camera->m_stateMutex));
117 if (Camera::IDLE == camera->m_state) {
119 "Message has been received, but no one is listening any more");
120 pthread_mutex_unlock(&(camera->m_stateMutex));
126 //.............................................................................
127 void Camera::unlockCameraMutex(Camera *camera)
129 LogDebug("Unlocking camera mutex");
130 pthread_mutex_unlock(&(camera->m_stateMutex));
132 //.............................................................................
133 /* Body of the callback function msg_callback */
134 int Camera::camcorderMessageCallback(int msg_type,
138 LogDebug(__FUNCTION__);
141 MMMessageParamType *m = static_cast<MMMessageParamType *>(msg_param);
142 Platform::Camera::Camera *igcamera =
143 static_cast<Platform::Camera::Camera *>(user_param);
146 case MM_MESSAGE_WARNING:
147 LogWarning("*MSG* Warning occured " << std::hex << m->code);
149 //lack of break is intended; treating all these messages as error.
150 case MM_MESSAGE_CAMCORDER_MAX_SIZE: /**< Maximum size, camcorder waits for user's order (cam_commit/cancel).*/
151 case MM_MESSAGE_CAMCORDER_NO_FREE_SPACE: /**< No free space, camcorder waits for user's order (cam_commit/cancel).*/
152 case MM_MESSAGE_CAMCORDER_TIME_LIMIT: /**< Time limit, camcorder waits for user's order (cam_commit/cancel)*/
153 LogError("Unexpected camcorder message: " << std::hex << msg_type);
154 LogInfo("Force camcorder to commit caputured data");
155 mm_camcorder_stop(igcamera->m_camcorderHandle);
156 mm_camcorder_unrealize(igcamera->m_camcorderHandle);
157 igcamera->DPL::Event::ControllerEventHandler<JobDoneEvent>::PostEvent(
161 case MM_MESSAGE_CAMCORDER_ERROR:
162 if (Camera::lockCameraMutex(igcamera) < 0) {
165 LogError("*MSG* Error's occured. " << std::hex << m->code);
167 switch (igcamera->getState()) {
168 case Camera::CAPTURING_IMAGE:
169 igcamera->m_eventTakePicture->setExceptionCode(
170 Commons::ExceptionCodes::UnknownException);
172 case Camera::CAPTURING_VIDEO:
173 igcamera->m_eventBeginRecording->setExceptionCode(
174 Commons::ExceptionCodes::UnknownException);
179 mm_camcorder_stop(igcamera->m_camcorderHandle);
180 mm_camcorder_unrealize(igcamera->m_camcorderHandle);
181 mm_camcorder_set_message_callback(igcamera->m_camcorderHandle,
184 igcamera->DPL::Event::ControllerEventHandler<JobDoneEvent>::PostEvent(
186 Camera::unlockCameraMutex(igcamera);
189 case MM_MESSAGE_CAMCORDER_STATE_CHANGED:
190 if (Camera::lockCameraMutex(igcamera) < 0) {
195 "*MSG* State changed " << std::hex << m->state.previous <<
196 "->" << std::hex << m->state.current);
198 if (MM_CAMCORDER_STATE_PREPARE == m->state.current &&
199 MM_CAMCORDER_STATE_READY == m->state.previous) {
200 LogDebug("MM_CAMCORDER_STATE_READY->MM_CAMCORDER_STATE_PREPARE ");
201 switch (igcamera->getState()) {
202 case Camera::CAPTURING_IMAGE:
203 error = mm_camcorder_capture_start(igcamera->m_camcorderHandle);
204 if (error != MM_ERROR_NONE) {
206 "m_camcorderHandle capture start failed " <<
208 igcamera->m_eventTakePicture->setExceptionCode(
209 Commons::ExceptionCodes::UnknownException);
210 igcamera->DPL::Event::ControllerEventHandler<JobDoneEvent>::
211 PostEvent(JobDoneEvent());
212 mm_camcorder_stop(igcamera->m_camcorderHandle);
213 mm_camcorder_unrealize(igcamera->m_camcorderHandle);
216 case Camera::CAPTURING_VIDEO:
217 LogDebug("CAPTURING_VIDEO " << igcamera->m_camcorderHandle);
218 error = mm_camcorder_record(igcamera->m_camcorderHandle);
219 if (error != MM_ERROR_NONE) {
221 "m_camcorderHandle record start failed " <<
223 igcamera->m_eventBeginRecording->setExceptionCode(
224 Commons::ExceptionCodes::UnknownException);
225 igcamera->DPL::Event::ControllerEventHandler<JobDoneEvent>::
226 PostEvent(JobDoneEvent());
227 mm_camcorder_stop(igcamera->m_camcorderHandle);
228 mm_camcorder_unrealize(igcamera->m_camcorderHandle);
237 if (MM_CAMCORDER_STATE_CAPTURING == m->state.previous &&
238 MM_CAMCORDER_STATE_PREPARE == m->state.current) {
241 "MM_CAMCORDER_STATE_CAPTURING->MM_CAMCORDER_STATE_PREPARE => stopping capture");
242 error = mm_camcorder_capture_stop(igcamera->m_camcorderHandle);
243 if (error != MM_ERROR_NONE) {
245 "m_camcorderHandle capture stopfailed " << std::hex <<
248 igcamera->logCamcorderState();
249 mm_camcorder_stop(igcamera->m_camcorderHandle);
250 mm_camcorder_unrealize(igcamera->m_camcorderHandle);
253 if (MM_CAMCORDER_STATE_RECORDING == m->state.previous &&
254 MM_CAMCORDER_STATE_PREPARE == m->state.current) {
257 "MM_CAMCORDER_STATE_CAPTURING->MM_CAMCORDER_STATE_PREPARE => stopping recording");
260 mm_camcorder_stop(igcamera->m_camcorderHandle);
261 mm_camcorder_unrealize(igcamera->m_camcorderHandle);
264 Camera::unlockCameraMutex(igcamera);
266 case MM_MESSAGE_CAMCORDER_CAPTURED:
267 if (Camera::lockCameraMutex(igcamera) < 0) {
270 LogDebug("*MSG* Captured. !!!");
271 if (Camera::CAPTURING_VIDEO == igcamera->getState() ||
272 Camera::CAPTURING_IMAGE == igcamera->getState()) {
273 mm_camcorder_capture_stop(igcamera->m_camcorderHandle);
274 mm_camcorder_stop(igcamera->m_camcorderHandle);
275 mm_camcorder_unrealize(igcamera->m_camcorderHandle);
276 igcamera->DPL::Event::ControllerEventHandler<JobDoneEvent>::PostEvent(
279 Camera::unlockCameraMutex(igcamera);
283 "*MSG* Message received. MMMessageID = " << std::hex <<
289 //.............................................................................
290 void Camera::OnEventReceived(const JobDoneEvent &event)
292 //if we received this event it means that we are (should be) in PROCESSING state and we need to send back the answer
293 //we need to check which one
295 LogDebug("JobDoneEvent received");
296 if (-1 == Camera::lockCameraMutex(this)) {
299 if (m_eventTakePicture) {
300 Platform::EventRequestReceiver< Api::Camera::EventTakePicture >::
301 ManualAnswer(m_eventTakePicture);
302 m_eventTakePicture.Reset();
303 } else if (m_eventBeginRecording) {
304 Platform::EventRequestReceiver< Api::Camera::EventBeginRecording >::
305 ManualAnswer(m_eventBeginRecording);
306 m_eventBeginRecording.Reset();
307 } else if (NULL != m_eventEndRecording.Get()) {
308 Platform::EventRequestReceiver< Api::Camera::EventEndRecording>::
309 ManualAnswer(m_eventEndRecording);
310 m_eventEndRecording.Reset();
311 } else if (m_eventRequestLiveVideo) {
312 Platform::EventRequestReceiver< Api::Camera::EventRequestLiveVideo>::
313 ManualAnswer(m_eventRequestLiveVideo);
314 m_eventRequestLiveVideo.Reset();
316 LogError("This part should not be reached");
319 setState(Camera::IDLE);
320 Camera::unlockCameraMutex(this);
321 LogDebug("camera is idle now..");
323 //.............................................................................
324 void Camera::OnRequestReceived(
325 const Api::Camera::EventTakePictureSharedPtr & event)
328 LogDebug(__FUNCTION__);
330 pthread_mutex_lock(&m_stateMutex);
331 //check is camera idle and can take a picture and camera object is not currently being destructed
332 if (Camera::IDLE != m_state) {
333 pthread_mutex_unlock(&m_stateMutex);
334 event->setExceptionCode(Commons::ExceptionCodes::AlreadyInUseException);
340 m_state = Camera::CAPTURING_IMAGE;
341 reInitializeCamcorderForPicture(event->getCaptureOptionsRef());
343 catch (const Commons::Exception &exc)
345 m_state = Camera::IDLE;
346 pthread_mutex_unlock(&m_stateMutex);
347 LogDebug("error's occured - invoking error callback");
348 event->setExceptionCode(exc.getCode());
352 //from now on we will have to call answer manually
353 event->switchToManualAnswer();
354 m_eventTakePicture = event;
355 LogDebug("setting message callback");
356 mm_camcorder_set_message_callback(m_camcorderHandle,
357 Camera::camcorderMessageCallback,
360 /* start receiving the input video stream */
361 LogDebug("mm_camcorder_start");
362 err = mm_camcorder_start(m_camcorderHandle);
363 if (err != MM_ERROR_NONE) {
364 LogError("starting camcorder failed " << std::hex << err);
365 mm_camcorder_set_message_callback(m_camcorderHandle, NULL, NULL);
366 m_state = Camera::IDLE;
367 pthread_mutex_unlock(&m_stateMutex);
368 event->setExceptionCode(Commons::ExceptionCodes::UnknownException);
369 Platform::EventRequestReceiver< Api::Camera::EventTakePicture >::
373 pthread_mutex_unlock(&m_stateMutex);
376 //.............................................................................
377 void Camera::OnRequestReceived(
378 const Api::Camera::EventBeginRecordingSharedPtr & event)
381 LogDebug(__FUNCTION__);
383 pthread_mutex_lock(&m_stateMutex);
384 //check is camera idle and can record
385 if (Camera::IDLE != m_state) {
386 pthread_mutex_unlock(&m_stateMutex);
387 event->setExceptionCode(Commons::ExceptionCodes::AlreadyInUseException);
393 m_state = Camera::CAPTURING_VIDEO;
394 reInitializeCamcorderForVideo(event->getCaptureOptionsRef());
396 catch (const Commons::Exception &exc)
398 m_state = Camera::IDLE;
399 pthread_mutex_unlock(&m_stateMutex);
400 LogDebug("error's occured - invoking error callback");
401 event->setExceptionCode(exc.getCode());
405 //from now on we will have to call answer manually
406 event->switchToManualAnswer();
407 m_eventBeginRecording = event;
408 LogDebug("setting message callback");
409 mm_camcorder_set_message_callback(m_camcorderHandle,
410 Camera::camcorderMessageCallback,
413 /* start receiving the input video stream */
414 LogDebug("mm_camcorder_start");
415 err = mm_camcorder_start(m_camcorderHandle);
416 if (err != MM_ERROR_NONE) {
417 LogError("starting camcorder failed " << std::hex << err);
418 mm_camcorder_set_message_callback(m_camcorderHandle, NULL, NULL);
419 m_state = Camera::IDLE;
420 pthread_mutex_unlock(&m_stateMutex);
421 event->setExceptionCode(Commons::ExceptionCodes::UnknownException);
422 Platform::EventRequestReceiver<Api::Camera::EventBeginRecording>::
426 pthread_mutex_unlock(&m_stateMutex);
428 //.............................................................................
429 void Camera::OnRequestReceived(
430 const Api::Camera::EventEndRecordingSharedPtr & event)
432 LogDebug("end request");
433 pthread_mutex_lock(&m_stateMutex);
434 if (m_state == Camera::CAPTURING_VIDEO) {
436 int error = mm_camcorder_commit(m_camcorderHandle);
440 case MM_ERROR_CAMCORDER_INVALID_STATE:
441 LogError("MM_ERROR_CAMCORDER_INVALID_STATE's occured");
444 //capturing video is in progress but we have an error
446 "mm_camcorder_commit error occured " << std::hex <<
447 error << " stopping it");
448 mm_camcorder_cancel(m_camcorderHandle);
449 mm_camcorder_stop(m_camcorderHandle);
450 mm_camcorder_unrealize(m_camcorderHandle);
451 event->setExceptionCode(Commons::ExceptionCodes::UnknownException);
452 m_state = Camera::IDLE;
456 LogDebug("stopVideo has been called but no recording is in progress");
457 event->setExceptionCode(Commons::ExceptionCodes::UnknownException);
459 pthread_mutex_unlock(&m_stateMutex);
461 //.............................................................................
462 void Camera::OnRequestReceived(
463 const DPL::SharedPtr<Api::Camera::EventRequestLiveVideo> & event)
465 ///TODO Not supported
466 event->setExceptionCode(Commons::ExceptionCodes::UnsupportedException);
468 //.............................................................................
469 void Camera::logCamcorderState()
471 MMCamcorderStateType state;
472 int retValue = mm_camcorder_get_state(m_camcorderHandle, &state);
473 if (MM_ERROR_NONE == retValue) {
474 LogDebug("camcorder's state: " << std::hex << state);
476 LogDebug("getting camcorder's state's failed: " << std::hex << retValue);
479 //.............................................................................
480 std::string Camera::getDescription() const
483 char *err_attr_name = NULL;
484 char *description = NULL;
487 if (mm_camcorder_get_attributes(m_camcorderHandle, &err_attr_name,
488 "camera-device-name", &description, &size,
490 LogError("GetDescription problem ");
492 LogError("mm_camcorder_get_attributes " << err_attr_name);
494 std::ostringstream oss;
495 oss << m_camcorderPreset.videodev_type;
496 desc.assign(oss.str());
498 desc.assign(description);
501 LogDebug("free err_attr_name");
504 LogDebug("desc" << desc);
507 //.............................................................................
508 int Camera::camcorderVideoCaptureCallback(MMCamcorderCaptureDataType *src,
509 MMCamcorderCaptureDataType *thumb,
512 LogDebug(__FUNCTION__);
513 Platform::Camera::Camera *camera =
514 static_cast<Platform::Camera::Camera *>(data);
516 if (Camera::CAPTURING_IMAGE != camera->getState()) {
520 assert(src->format == MM_PIXEL_FORMAT_ENCODED);
523 "MM_PIXEL_FORMAT_ENCODED src->data=%p src->length=%d, src->width=%d, src->heigtht=%d \n\n",
528 std::string fileName =
529 camera->m_eventTakePicture->getCaptureOptionsRef()->getFileName();
531 FILE* fp = fopen(fileName.c_str(), "w+");
533 LogError("file opening error!!");
536 LogDebug("open success");
537 if (fwrite(src->data, src->length, 1, fp) != 1) {
538 LogError("file writing error!!");
547 //.............................................................................
548 void Camera::setCaptureOptions(
549 const Api::Camera::ICaptureOptionsPtr &captureOptions)
553 if (NULL == captureOptions) {
556 bool ret = realizeCamcoder();
558 LogError("Realize camcoreder failed");
562 char *err_attr_name = NULL;
565 if (captureOptions->isAttributeValid(Api::Camera::ICaptureOptions::
567 LogDebug("setting width");
568 short width = captureOptions->getWidth();
569 retValue = mm_camcorder_set_attributes(m_camcorderHandle,
576 LogDebug("couldn't set width attribute " << std::hex << retValue);
577 Throw(Commons::InvalidArgumentException);
581 if (captureOptions->isAttributeValid(Api::Camera::ICaptureOptions::
583 LogDebug("setting height");
584 short height = captureOptions->getHeight();
585 retValue = mm_camcorder_set_attributes(m_camcorderHandle,
587 MMCAM_CAPTURE_HEIGHT,
592 LogDebug("couldn't set height attribute " << std::hex << retValue);
593 Throw(Commons::InvalidArgumentException);
597 if (captureOptions->isAttributeValid(Api::Camera::ICaptureOptions::
598 SETTED_FRAME_RATE)) {
599 LogDebug("setting frame rate");
600 short frameRate = captureOptions->getFrameRate();
601 retValue = mm_camcorder_set_attributes(m_camcorderHandle,
609 "couldn't set frameRate attribute " << std::hex <<
611 Throw(Commons::InvalidArgumentException);
615 if (captureOptions->isAttributeValid(Api::Camera::ICaptureOptions::
616 SETTED_MAX_BITRATE)) {
617 unsigned long bitrate = captureOptions->getMaximumBitrate();
618 LogDebug("setting max bitrate: " << bitrate);
619 retValue = mm_camcorder_set_attributes(m_camcorderHandle,
621 MMCAM_AUDIO_ENCODER_BITRATE,
623 MMCAM_VIDEO_ENCODER_BITRATE,
628 LogDebug("couldn't set bitrate attribute " << std::hex << retValue);
629 Throw(Commons::InvalidArgumentException);
633 if (captureOptions->isAttributeValid(Api::Camera::ICaptureOptions::
634 SETTED_IMAGE_RESOLUTION)) {
635 LogDebug("setting image resolution");
636 Api::Camera::ICaptureOptions::ImageResolution imageResolution =
637 captureOptions->getImageResolution();
639 //getting possible range of this argument
641 retValue = mm_camcorder_get_attribute_info(m_camcorderHandle,
642 MMCAM_IMAGE_ENCODER_QUALITY,
647 "couldn't get MMCAM_IMAGE_ENCODER_QUALITY resolution attribute info"
648 << std::hex << retValue);
649 Throw(Commons::InvalidArgumentException);
652 assert(MM_CAM_ATTRS_VALID_TYPE_INT_RANGE == info.validity_type);
654 switch (imageResolution) {
655 case Api::Camera::ICaptureOptions::IMAGE_RESOLUTION_LOW:
656 quality = info.int_range.min;
658 case Api::Camera::ICaptureOptions::IMAGE_RESOLUTION_HIGH:
659 quality = info.int_range.max;
661 case Api::Camera::ICaptureOptions::IMAGE_RESOLUTION_DEFAULT:
662 quality = info.int_range.def;
667 retValue = mm_camcorder_set_attributes(m_camcorderHandle,
669 MMCAM_IMAGE_ENCODER_QUALITY,
675 "couldn't set image quality attribute " << std::hex <<
677 Throw(Commons::InvalidArgumentException);
680 if (!captureOptions->isAttributeValid(Api::Camera::ICaptureOptions::
682 !captureOptions->isAttributeValid(Api::Camera::ICaptureOptions::
684 (Api::Camera::ICaptureOptions::IMAGE_RESOLUTION_DEFAULT !=
685 captureOptions->getImageResolution())) {
686 Resolution res = getCaptureResolution(
687 Api::Camera::ICaptureOptions::IMAGE_RESOLUTION_LOW ==
688 captureOptions->getImageResolution()
690 LogDebug("Resolution: " << res.getWidth() << "x" << res.getHeight());
691 retValue = mm_camcorder_set_attributes(m_camcorderHandle,
695 MMCAM_CAPTURE_HEIGHT,
701 "couldn't set image resolution attribute " <<
702 std::hex << retValue);
703 Throw(Commons::InvalidArgumentException);
708 ///"you can't set a file name with "MMCAM_TARGET_FILENAME" when capturing still image"
709 if (captureOptions->isAttributeValid(Api::Camera::ICaptureOptions::
711 LogDebug("setting target filename");
712 std::string fileName = captureOptions->getFileName();
714 * Not using Api::Filesystem::IManager::access() intentionally - to not
715 * introduce dependencies between Camera and Filesystem modules for such
716 * a minor feature. What's more it allows for a small optimization - only
717 * one access() call is needed when in case of Filesystem::IManager::access()
718 * two would be required (no way to get to `errno` variable).
721 if (access(fileName.c_str(), W_OK) != 0) {
722 if (ENOENT != errno) {
723 ThrowMsg(Commons::PlatformException,
724 "Can't write to specified file.");
726 } else if (!captureOptions->getOverwrite()) {
728 Commons::PlatformException,
729 "Output file already exists but overwrite has not been set.");
732 if (Camera::CAPTURING_VIDEO == m_state) {
733 retValue = mm_camcorder_set_attributes(m_camcorderHandle,
735 MMCAM_TARGET_FILENAME,
743 "couldn't set file name attribute " << std::hex <<
745 Throw(Commons::InvalidArgumentException);
750 //.............................................................................
751 int Camera::reInitializeCamcorderForPicture(
752 const Api::Camera::ICaptureOptionsPtr &captureOptions)
755 /*"However, you have to set every attribute to fit to video mode, but it's tiresome.
756 So, I recommend to you to call destroy also.
757 Like this, MMCamcorderStop() -> MMCamcorderUnrealize() ->
758 MMCamcorderDestroy() -> MMCamcorderCreate()..
759 get a new handle -> MMCamcorderRealize() ->
760 set MM_CAMCORDER_MODE_VIDEO -> MMCamcorderStart()"*/
761 LogDebug("Reinitializing camcorder for picture capturing");
762 mm_camcorder_stop(m_camcorderHandle);
763 mm_camcorder_unrealize(m_camcorderHandle);
764 mm_camcorder_destroy(m_camcorderHandle);
766 err = mm_camcorder_create(&m_camcorderHandle, &m_camcorderPreset);
768 LogError("creating camcorder has failed " << std::hex << err);
769 Throw(Commons::UnknownException);
772 char *err_attr_name = NULL;
773 err = mm_camcorder_set_attributes(
774 m_camcorderHandle, &err_attr_name,
775 MMCAM_MODE, MM_CAMCORDER_MODE_IMAGE,
776 MMCAM_IMAGE_ENCODER, MM_IMAGE_CODEC_JPEG,
777 MMCAM_CAMERA_FORMAT, MM_PIXEL_FORMAT_YUYV,
778 MMCAM_CAMERA_FPS, 30,
779 MMCAM_DISPLAY_ROTATION, MM_DISPLAY_ROTATION_NONE,
780 MMCAM_CAPTURE_FORMAT, MM_PIXEL_FORMAT_ENCODED,
781 MMCAM_CAPTURE_WIDTH, DEFAULT_CAPTURE_WIDTH,
782 MMCAM_CAPTURE_HEIGHT, DEFAULT_CAPTURE_HEIGHT,
783 MMCAM_CAPTURE_COUNT, 1,
784 MMCAM_DISPLAY_VISIBLE, false,
788 LogError("error: " << err_attr_name);
790 Throw(Commons::InvalidArgumentException);
792 mm_camcorder_set_video_capture_callback(
794 (mm_camcorder_video_capture_callback) Camera::
795 camcorderVideoCaptureCallback,
796 static_cast<void*>(this));
797 setCaptureOptions(captureOptions);
800 //.............................................................................
801 int Camera::reInitializeCamcorderForVideo(
802 const Api::Camera::ICaptureOptionsPtr &captureOptions)
804 /*"However, you have to set every attribute to fit to video mode, but it's tiresome.
805 So, I recommend to you to call destroy also.
806 Like this, MMCamcorderStop() -> MMCamcorderUnrealize() ->
807 MMCamcorderDestroy() -> MMCamcorderCreate()..
808 get a new handle -> MMCamcorderRealize() ->
809 set MM_CAMCORDER_MODE_VIDEO -> MMCamcorderStart()"*/
811 LogDebug("Reinitializing camcorder for video capturing");
813 mm_camcorder_stop(m_camcorderHandle);
814 mm_camcorder_unrealize(m_camcorderHandle);
815 mm_camcorder_destroy(m_camcorderHandle);
816 mm_camcorder_create(&m_camcorderHandle, &m_camcorderPreset);
819 char *err_attr_name = NULL;
821 err = mm_camcorder_set_attributes((MMHandleType)m_camcorderHandle,
824 MM_CAMCORDER_MODE_VIDEO,
830 MM_VIDEO_CODEC_MPEG4,
838 MM_PIXEL_FORMAT_NV12,
841 MMCAM_DISPLAY_ROTATION,
842 MM_DISPLAY_ROTATION_NONE,
843 MMCAM_AUDIO_SAMPLERATE,
847 MMCAM_AUDIO_INPUT_ROUTE,
848 MM_AUDIOROUTE_CAPTURE_NORMAL,
852 LogError("error: " << err_attr_name);
854 Throw(Commons::InvalidArgumentException);
857 setCaptureOptions(captureOptions);
861 //.............................................................................
862 bool Camera::realizeCamcoder()
864 LogDebug(__FUNCTION__);
865 MMCamcorderStateType state;
866 int ret = mm_camcorder_get_state(m_camcorderHandle, &state);
867 if (MM_CAMCORDER_STATE_NULL == state) {
868 LogDebug("camcorder is not realized - realizing..");
869 ret = mm_camcorder_realize(m_camcorderHandle);
870 if (MM_ERROR_NONE != ret) {
872 "realizing the camcorder handle failed " << std::hex <<
874 Throw(Commons::UnknownException);
878 LogDebug("camcorder's been already realized");
882 //.............................................................................
883 int Camera::unRealizeCamcoder()
885 if (!m_camcorderHandle) {
888 MMCamcorderStateType state;
889 int ret = mm_camcorder_get_state(m_camcorderHandle, &state);
890 if (MM_CAMCORDER_STATE_READY == state) {
891 ret = mm_camcorder_unrealize(m_camcorderHandle);
892 if (MM_ERROR_NONE != ret) {
894 "unrealizing the camcorder handle's failed " <<
896 Throw(Commons::UnknownException);
899 return MM_ERROR_NONE;
901 //.............................................................................
902 Camera::Resolution Camera::getCaptureResolution(bool low) const
904 Assert(m_camcorderHandle && "Camcorder handle is not valid.");
905 Resolution result(DEFAULT_CAPTURE_WIDTH, DEFAULT_CAPTURE_HEIGHT);
907 AttributeInfo::ArrayOfInt captureWidth =
908 AttributeInfo::toArrayOfInt(m_camcorderHandle, MMCAM_CAPTURE_WIDTH);
910 AttributeInfo::ArrayOfInt captureHeight =
911 AttributeInfo::toArrayOfInt(m_camcorderHandle, MMCAM_CAPTURE_HEIGHT);
913 if (!captureWidth.empty() && !captureHeight.empty()) {
915 result.setSize(captureWidth.front(), captureHeight.front());
917 result.setSize(captureWidth.back(), captureHeight.back());
921 catch (const Commons::Exception& ex) {
922 LogError("Exception: " << ex.GetMessage());
923 LogDebug("Falling back to default resolution.");