diff -Nru libhybris-0.61/compat/camera/camera_compatibility_layer.cpp libhybris-0.62/compat/camera/camera_compatibility_layer.cpp --- libhybris-0.61/compat/camera/camera_compatibility_layer.cpp 2013-03-04 23:50:38.000000000 +0000 +++ libhybris-0.62/compat/camera/camera_compatibility_layer.cpp 2013-05-29 20:24:10.000000000 +0000 @@ -15,6 +15,7 @@ * * Authored by: Thomas Voß */ +#include "camera_control.h" #include "camera_compatibility_layer.h" #include "camera_compatibility_layer_capabilities.h" #include "camera_compatibility_layer_configuration_translator.h" @@ -34,91 +35,83 @@ #define REPORT_FUNCTION() ALOGV("%s \n", __PRETTY_FUNCTION__); -struct CameraControl : public android::CameraListener, - public android::SurfaceTexture::FrameAvailableListener + +// From android::SurfaceTexture::FrameAvailableListener +void CameraControl::onFrameAvailable() { - android::Mutex guard; - CameraControlListener* listener; - android::sp camera; - android::CameraParameters camera_parameters; - android::sp preview_texture; + REPORT_FUNCTION(); + if (listener) + listener->on_preview_texture_needs_update_cb(listener->context); +} - // From android::SurfaceTexture::FrameAvailableListener - void onFrameAvailable() +// From android::CameraListener +void CameraControl::notify(int32_t msg_type, int32_t ext1, int32_t ext2) +{ + REPORT_FUNCTION(); + printf("\text1: %d, ext2: %d \n", ext1, ext2); + if (!listener) + return; + + switch(msg_type) { - REPORT_FUNCTION(); - if (listener) - listener->on_preview_texture_needs_update_cb(listener->context); + case CAMERA_MSG_ERROR: + if (listener->on_msg_error_cb) + listener->on_msg_error_cb(listener->context); + break; + case CAMERA_MSG_SHUTTER: + if (listener->on_msg_shutter_cb) + listener->on_msg_shutter_cb(listener->context); + break; + case CAMERA_MSG_ZOOM: + if (listener->on_msg_zoom_cb) + listener->on_msg_zoom_cb(listener->context, ext1); + break; + case CAMERA_MSG_FOCUS: + if (listener->on_msg_focus_cb) + listener->on_msg_focus_cb(listener->context); + break; + default: + break; } +} - // From android::CameraListener - void notify(int32_t msg_type, int32_t ext1, int32_t ext2) +void CameraControl::postData( + int32_t msg_type, + const android::sp& data, + camera_frame_metadata_t* metadata) +{ + REPORT_FUNCTION(); + if (!listener) + return; + + switch(msg_type) { - REPORT_FUNCTION(); - printf("\text1: %d, ext2: %d \n", ext1, ext2); - if (!listener) - return; - - switch(msg_type) - { - case CAMERA_MSG_ERROR: - if (listener->on_msg_error_cb) - listener->on_msg_error_cb(listener->context); - break; - case CAMERA_MSG_SHUTTER: - if (listener->on_msg_shutter_cb) - listener->on_msg_shutter_cb(listener->context); - break; - case CAMERA_MSG_ZOOM: - if (listener->on_msg_zoom_cb) - listener->on_msg_zoom_cb(listener->context, ext1); - break; - case CAMERA_MSG_FOCUS: - if (listener->on_msg_focus_cb) - listener->on_msg_focus_cb(listener->context); - break; - default: - break; - } + case CAMERA_MSG_RAW_IMAGE: + if (listener->on_data_raw_image_cb) + listener->on_data_raw_image_cb(data->pointer(), data->size(), listener->context); + break; + case CAMERA_MSG_COMPRESSED_IMAGE: + if (listener->on_data_compressed_image_cb) + listener->on_data_compressed_image_cb(data->pointer(), data->size(), listener->context); + break; + default: + break; } - void postData( - int32_t msg_type, - const android::sp& data, - camera_frame_metadata_t* metadata) - { - REPORT_FUNCTION() - if (!listener) - return; - - switch(msg_type) - { - case CAMERA_MSG_RAW_IMAGE: - if (listener->on_data_raw_image_cb) - listener->on_data_raw_image_cb(data->pointer(), data->size(), listener->context); - break; - case CAMERA_MSG_COMPRESSED_IMAGE: - if (listener->on_data_compressed_image_cb) - listener->on_data_compressed_image_cb(data->pointer(), data->size(), listener->context); - break; - default: - break; - } + camera->releaseRecordingFrame(data); +} - camera->releaseRecordingFrame(data); - } +void CameraControl::postDataTimestamp( + nsecs_t timestamp, + int32_t msg_type, + const android::sp& data) +{ + REPORT_FUNCTION(); + (void) timestamp; + (void) msg_type; + (void) data; +} - void postDataTimestamp( - nsecs_t timestamp, - int32_t msg_type, - const android::sp& data) - { - REPORT_FUNCTION() - (void) timestamp; - (void) msg_type; - (void) data; - } -}; namespace { @@ -179,6 +172,18 @@ control->camera->unlock(); } +int android_camera_lock(CameraControl* control) +{ + android::Mutex::Autolock al(control->guard); + return control->camera->lock(); +} + +int android_camera_unlock(CameraControl* control) +{ + android::Mutex::Autolock al(control->guard); + return control->camera->unlock(); +} + void android_camera_delete(CameraControl* control) { delete control; @@ -664,3 +669,40 @@ control->camera->setParameters(control->camera_parameters.flatten()); } +void android_camera_enumerate_supported_video_sizes(CameraControl* control, size_callback cb, void* ctx) +{ + REPORT_FUNCTION(); + assert(control); + assert(cb); + + android::Mutex::Autolock al(control->guard); + android::Vector sizes; + control->camera_parameters.getSupportedVideoSizes(sizes); + + for(unsigned int i = 0; i < sizes.size(); i++) + { + cb(ctx, sizes[i].width, sizes[i].height); + } +} + +void android_camera_get_video_size(CameraControl* control, int* width, int* height) +{ + REPORT_FUNCTION(); + assert(control); + + android::Mutex::Autolock al(control->guard); + + control->camera_parameters.getVideoSize(width, height); +} + +void android_camera_set_video_size(CameraControl* control, int width, int height) +{ + + REPORT_FUNCTION(); + assert(control); + + android::Mutex::Autolock al(control->guard); + + control->camera_parameters.setVideoSize(width, height); + control->camera->setParameters(control->camera_parameters.flatten()); +} diff -Nru libhybris-0.61/compat/camera/camera_compatibility_layer.h libhybris-0.62/compat/camera/camera_compatibility_layer.h --- libhybris-0.61/compat/camera/camera_compatibility_layer.h 2013-03-04 23:50:38.000000000 +0000 +++ libhybris-0.62/compat/camera/camera_compatibility_layer.h 2013-05-29 20:24:10.000000000 +0000 @@ -83,6 +83,9 @@ // Disconnects the camera and deletes the pointer void android_camera_disconnect(CameraControl* control); + int android_camera_lock(CameraControl* control); + int android_camera_unlock(CameraControl* control); + // Deletes the CameraControl void android_camera_delete(CameraControl* control); diff -Nru libhybris-0.61/compat/camera/camera_compatibility_layer_capabilities.h libhybris-0.62/compat/camera/camera_compatibility_layer_capabilities.h --- libhybris-0.61/compat/camera/camera_compatibility_layer_capabilities.h 2013-03-04 23:50:38.000000000 +0000 +++ libhybris-0.62/compat/camera/camera_compatibility_layer_capabilities.h 2013-05-29 20:24:10.000000000 +0000 @@ -133,9 +133,14 @@ void android_camera_set_focus_region(CameraControl* control, FocusRegion* region); void android_camera_reset_focus_region(CameraControl* control); -// Set photo metadata + // Set photo metadata void android_camera_set_rotation(CameraControl* control, int rotation); + // Video support + void android_camera_enumerate_supported_video_sizes(CameraControl* control, size_callback cb, void* ctx); + void android_camera_get_video_size(CameraControl* control, int* width, int* height); + void android_camera_set_video_size(CameraControl* control, int width, int height); + #ifdef __cplusplus } #endif diff -Nru libhybris-0.61/compat/camera/camera_control.h libhybris-0.62/compat/camera/camera_control.h --- libhybris-0.61/compat/camera/camera_control.h 1970-01-01 00:00:00.000000000 +0000 +++ libhybris-0.62/compat/camera/camera_control.h 2013-05-29 20:24:10.000000000 +0000 @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2013 Canonical Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CAMERA_CONTROL_H_ +#define CAMERA_CONTROL_H_ + +#include +#include +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct CameraControlListener; + +struct CameraControl : public android::CameraListener, + public android::SurfaceTexture::FrameAvailableListener +{ + android::Mutex guard; + CameraControlListener* listener; + android::sp camera; + android::CameraParameters camera_parameters; + android::sp preview_texture; + + // From android::SurfaceTexture::FrameAvailableListener + void onFrameAvailable(); + + // From android::CameraListener + void notify(int32_t msg_type, int32_t ext1, int32_t ext2); + + void postData( + int32_t msg_type, + const android::sp& data, + camera_frame_metadata_t* metadata); + + void postDataTimestamp( + nsecs_t timestamp, + int32_t msg_type, + const android::sp& data); +}; + + +#ifdef __cplusplus +} +#endif + +#endif // CAMERA_CONTROL_H_ diff -Nru libhybris-0.61/compat/media/Android.mk libhybris-0.62/compat/media/Android.mk --- libhybris-0.61/compat/media/Android.mk 2013-03-04 23:50:38.000000000 +0000 +++ libhybris-0.62/compat/media/Android.mk 2013-05-29 20:24:10.000000000 +0000 @@ -4,12 +4,14 @@ HYBRIS_PATH := $(LOCAL_PATH)/../../ LOCAL_SRC_FILES:= \ - media_compatibility_layer.cpp + media_compatibility_layer.cpp \ + recorder_compatibility_layer.cpp LOCAL_MODULE:= libmedia_compat_layer LOCAL_MODULE_TAGS := optional LOCAL_C_INCLUDES := \ + $(HYBRIS_PATH)/compat/camera \ $(HYBRIS_PATH)/compat/surface_flinger \ $(HYBRIS_PATH)/compat/input \ frameworks/base/media/libstagefright/include \ @@ -18,6 +20,7 @@ LOCAL_SHARED_LIBRARIES := \ libcutils \ + libcamera_client \ libutils \ libbinder \ libhardware \ @@ -30,7 +33,7 @@ include $(CLEAR_VARS) -LOCAL_SRC_FILES:= \ +LOCAL_SRC_FILES:= \ test_player.cpp \ LOCAL_MODULE:= test_player diff -Nru libhybris-0.61/compat/media/media_compatibility_layer.cpp libhybris-0.62/compat/media/media_compatibility_layer.cpp --- libhybris-0.61/compat/media/media_compatibility_layer.cpp 2013-03-04 23:50:38.000000000 +0000 +++ libhybris-0.62/compat/media/media_compatibility_layer.cpp 2013-05-29 20:24:10.000000000 +0000 @@ -401,6 +401,7 @@ return BAD_VALUE; } + mp->reset(); mp->setSourceFd(fd); struct stat st; diff -Nru libhybris-0.61/compat/media/media_compatibility_layer.h libhybris-0.62/compat/media/media_compatibility_layer.h --- libhybris-0.61/compat/media/media_compatibility_layer.h 2013-03-04 23:50:38.000000000 +0000 +++ libhybris-0.62/compat/media/media_compatibility_layer.h 2013-05-29 20:24:10.000000000 +0000 @@ -19,8 +19,6 @@ #ifndef MEDIA_COMPATIBILITY_LAYER_H_ #define MEDIA_COMPATIBILITY_LAYER_H_ -#include - #include #include @@ -51,7 +49,7 @@ int android_media_set_data_source(MediaPlayerWrapper *mp, const char* url); int android_media_set_preview_texture(MediaPlayerWrapper *mp, int texture_id); void android_media_update_surface_texture(MediaPlayerWrapper *mp); - void android_media_surface_texture_get_transformation_matrix(MediaPlayerWrapper *mp, GLfloat*matrix); + void android_media_surface_texture_get_transformation_matrix(MediaPlayerWrapper *mp, float*matrix); int android_media_play(MediaPlayerWrapper *mp); int android_media_pause(MediaPlayerWrapper *mp); int android_media_stop(MediaPlayerWrapper *mp); diff -Nru libhybris-0.61/compat/media/recorder_compatibility_layer.cpp libhybris-0.62/compat/media/recorder_compatibility_layer.cpp --- libhybris-0.61/compat/media/recorder_compatibility_layer.cpp 1970-01-01 00:00:00.000000000 +0000 +++ libhybris-0.62/compat/media/recorder_compatibility_layer.cpp 2013-05-29 20:24:10.000000000 +0000 @@ -0,0 +1,476 @@ +/* + * Copyright © 2013 Canonical Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "recorder_compatibility_layer.h" +#include + +#include +#include +#include + +//#define LOG_NDEBUG 0 +#undef LOG_TAG +#define LOG_TAG "MediaRecorderCompatibilityLayer" +#include +#include + +#define REPORT_FUNCTION() ALOGV("%s \n", __PRETTY_FUNCTION__); + +/*! + * \brief The MediaRecorderListenerWrapper class is used to listen to events + * from the MediaRecorder + */ +class MediaRecorderListenerWrapper : public android::MediaRecorderListener +{ +public: + MediaRecorderListenerWrapper() + : error_cb(NULL), + error_context(NULL) + { + } + + void notify(int msg, int ext1, int ext2) + { + ALOGV("\tmsg: %d, ext1: %d, ext2: %d \n", msg, ext1, ext2); + + switch(msg) + { + case android::MEDIA_RECORDER_EVENT_ERROR: { + ALOGV("\tMEDIA_RECORDER_EVENT_ERROR msg\n"); + // TODO: Extend this cb to include the error message + if (error_cb != NULL) + error_cb(error_context); + else + ALOGE("Failed to signal error to app layer, callback not set."); + break; + } + default: + ALOGV("\tUnknown notification\n"); + } + } + + void setErrorCb(on_recorder_msg_error cb, void *context) + { + REPORT_FUNCTION(); + error_cb = cb; + error_context = context; + } + +private: + on_recorder_msg_error error_cb; + void *error_context; +}; + +/*! + * \brief The MediaRecorderWrapper struct wraps the MediaRecorder class + */ +struct MediaRecorderWrapper : public android::MediaRecorder +{ +public: + MediaRecorderWrapper() + : MediaRecorder(), + media_recorder_listener(new MediaRecorderListenerWrapper()) + { + setListener(media_recorder_listener); + } + + ~MediaRecorderWrapper() + { + reset(); + } + + void setErrorCb(on_recorder_msg_error cb, void *context) + { + REPORT_FUNCTION(); + + assert(media_recorder_listener != NULL); + media_recorder_listener->setErrorCb(cb, context); + } + +private: + android::sp media_recorder_listener; +}; + + +using namespace android; + +/*! + * \brief android_recorder_set_error_cb + * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() + * \param cb The callback function to be called when a recording error occurs + * \param context + */ +void android_recorder_set_error_cb(MediaRecorderWrapper *mr, on_recorder_msg_error cb, + void *context) +{ + REPORT_FUNCTION() + + if (mr == NULL) + { + ALOGE("mr must not be NULL"); + return; + } + + mr->setErrorCb(cb, context); +} + +/*! + * \brief android_media_new_recorder creates a new MediaRecorder + * \return New MediaRecorder object, or NULL if the object could not be created. + */ +MediaRecorderWrapper *android_media_new_recorder() +{ + REPORT_FUNCTION() + + MediaRecorderWrapper *mr = new MediaRecorderWrapper; + if (mr == NULL) + { + ALOGE("Failed to create new MediaRecorderWrapper instance."); + return NULL; + } + + return mr; +} + +/*! + * \brief android_recorder_initCheck + * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() + * \return negative value if an error occured + */ +int android_recorder_initCheck(MediaRecorderWrapper *mr) +{ + REPORT_FUNCTION() + + if (mr == NULL) + { + ALOGE("mr must not be NULL"); + return BAD_VALUE; + } + + return mr->initCheck(); +} + +/*! + * \brief android_recorder_setCamera sets the camera object for recording videos + * from the camera + * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() + * \param control Wrapper for the camera (see camera in hybris) + * \return negative value if an error occured + */ +int android_recorder_setCamera(MediaRecorderWrapper *mr, CameraControl* control) +{ + REPORT_FUNCTION() + + if (mr == NULL) + { + ALOGE("mr must not be NULL"); + return BAD_VALUE; + } + if (control == NULL) + { + ALOGE("control must not be NULL"); + return BAD_VALUE; + } + + return mr->setCamera(control->camera->remote(), control->camera->getRecordingProxy()); +} + +/*! + * \brief android_recorder_setVideoSource sets the video source. + * If no video source is set, only audio is recorded. + * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() + * \param vs The video source. It's either the camera of gralloc buffer + * \return negative value if an error occured + */ +int android_recorder_setVideoSource(MediaRecorderWrapper *mr, VideoSource vs) +{ + REPORT_FUNCTION() + + if (mr == NULL) + { + ALOGE("mr must not be NULL"); + return BAD_VALUE; + } + + return mr->setVideoSource(static_cast(vs)); +} + +/*! + * \brief android_recorder_setAudioSource + * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() + * \param as The audio source. + * \return negative value if an error occured + */ +int android_recorder_setAudioSource(MediaRecorderWrapper *mr, AudioSource as) +{ + REPORT_FUNCTION() + + if (mr == NULL) + { + ALOGE("mr must not be NULL"); + return BAD_VALUE; + } + + return mr->setAudioSource(static_cast(as)); +} + +/*! + * \brief android_recorder_setOutputFormat + * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() + * \param of The output file format + * \return negative value if an error occured + */ +int android_recorder_setOutputFormat(MediaRecorderWrapper *mr, OutputFormat of) +{ + REPORT_FUNCTION() + + if (mr == NULL) + { + ALOGE("mr must not be NULL"); + return BAD_VALUE; + } + + return mr->setOutputFormat(static_cast(of)); +} + +/*! + * \brief android_recorder_setVideoEncoder + * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() + * \param ve The video encoder sets the codec for the video + * \return negative value if an error occured + */ +int android_recorder_setVideoEncoder(MediaRecorderWrapper *mr, VideoEncoder ve) +{ + REPORT_FUNCTION() + + if (mr == NULL) + { + ALOGE("mr must not be NULL"); + return BAD_VALUE; + } + + return mr->setVideoEncoder(static_cast(ve)); +} + +/*! + * \brief android_recorder_setAudioEncoder + * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() + * \param ae The audio encoder sets the codec for the audio + * \return negative value if an error occured + */ +int android_recorder_setAudioEncoder(MediaRecorderWrapper *mr, AudioEncoder ae) +{ + REPORT_FUNCTION() + + if (mr == NULL) + { + ALOGE("mr must not be NULL"); + return BAD_VALUE; + } + + return mr->setAudioEncoder(static_cast(ae)); +} + +/*! + * \brief android_recorder_setOutputFile sets the output file to the given file descriptor + * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() + * \param fd File descriptor of an open file, that the stream can be written to + * \return negative value if an error occured + */ +int android_recorder_setOutputFile(MediaRecorderWrapper *mr, int fd) +{ + REPORT_FUNCTION() + + if (mr == NULL) + { + ALOGE("mr must not be NULL"); + return BAD_VALUE; + } + + return mr->setOutputFile(fd, 0, 0); +} + +/*! + * \brief android_recorder_setVideoSize + * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() + * \param width width for the video to record + * \param height height for the video to record + * \return negative value if an error occured + */ +int android_recorder_setVideoSize(MediaRecorderWrapper *mr, int width, int height) +{ + REPORT_FUNCTION() + + if (mr == NULL) + { + ALOGE("mr must not be NULL"); + return BAD_VALUE; + } + + return mr->setVideoSize(width, height); +} + +/*! + * \brief android_recorder_setVideoFrameRate + * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() + * \param frames_per_second Frames per second has typical values for a movie clip in 720p is 30 + * \return negative value if an error occured + */ +int android_recorder_setVideoFrameRate(MediaRecorderWrapper *mr, int frames_per_second) +{ + REPORT_FUNCTION() + + if (mr == NULL) + { + ALOGE("mr must not be NULL"); + return BAD_VALUE; + } + + return mr->setVideoFrameRate(frames_per_second); +} + +/*! + * \brief android_recorder_setParameters sets a parameter. Even those without + * explicit function. + * For possible parameters look for example in StagefrightRecorder::setParameter() + * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() + * \param parameters list of parameters. format is "parameter1=value;parameter2=value" + * \return negative value if an error occured + */ +int android_recorder_setParameters(MediaRecorderWrapper *mr, const char* parameters) +{ + REPORT_FUNCTION() + + if (mr == NULL) + { + ALOGE("mr must not be NULL"); + return BAD_VALUE; + } + + String8 params(parameters); + return mr->setParameters(params); +} + +/*! + * \brief android_recorder_start starts the recording. + * The MediaRecorder has to be in state "prepared" + * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() + * \return negative value if an error occured + */ +int android_recorder_start(MediaRecorderWrapper *mr) +{ + REPORT_FUNCTION() + + if (mr == NULL) + { + ALOGE("mr must not be NULL"); + return BAD_VALUE; + } + + return mr->start(); +} + +/*! + * \brief android_recorder_stop Stops a running recording. + * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() + * \return negative value if an error occured + */ +int android_recorder_stop(MediaRecorderWrapper *mr) +{ + REPORT_FUNCTION() + + if (mr == NULL) + { + ALOGE("mr must not be NULL"); + return BAD_VALUE; + } + + return mr->stop(); +} + +/*! + * \brief android_recorder_prepare put the MediaRecorder into state "prepare" + * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() + * \return negative value if an error occured + */ +int android_recorder_prepare(MediaRecorderWrapper *mr) +{ + REPORT_FUNCTION() + + if (mr == NULL) + { + ALOGE("mr must not be NULL"); + return BAD_VALUE; + } + + return mr->prepare(); +} + +/*! + * \brief android_recorder_reset resets the MediaRecorder + * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() + * \return negative value if an error occured + */ +int android_recorder_reset(MediaRecorderWrapper *mr) +{ + REPORT_FUNCTION() + + if (mr == NULL) + { + ALOGE("mr must not be NULL"); + return BAD_VALUE; + } + + return mr->reset(); +} + +/*! + * \brief android_recorder_close closes the MediaRecorder + * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() + * \return negative value if an error occured + */ +int android_recorder_close(MediaRecorderWrapper *mr) +{ + REPORT_FUNCTION() + + if (mr == NULL) + { + ALOGE("mr must not be NULL"); + return BAD_VALUE; + } + + return mr->close(); +} + +/*! + * \brief android_recorder_release releases the MediaRecorder resources + * This deletes the object. So don't use it after calling this function. + * \param mr A MediaRecorderWrapper instance, created by calling android_media_new_recorder() + * \return negative value if an error occured + */ +int android_recorder_release(MediaRecorderWrapper *mr) +{ + REPORT_FUNCTION() + + if (mr == NULL) + { + ALOGE("mr must not be NULL"); + return BAD_VALUE; + } + + return mr->release(); +} diff -Nru libhybris-0.61/compat/media/recorder_compatibility_layer.h libhybris-0.62/compat/media/recorder_compatibility_layer.h --- libhybris-0.61/compat/media/recorder_compatibility_layer.h 1970-01-01 00:00:00.000000000 +0000 +++ libhybris-0.62/compat/media/recorder_compatibility_layer.h 2013-05-29 20:24:10.000000000 +0000 @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2013 Canonical Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RECORDER_COMPATIBILITY_LAYER_H_ +#define RECORDER_COMPATIBILITY_LAYER_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + struct MediaRecorderWrapper; + struct CameraControl; + + // values are from andoid /frameworks/av/include/media/mediarecorder.h + typedef enum + { + ANDROID_VIDEO_SOURCE_DEFAULT = 0, + ANDROID_VIDEO_SOURCE_CAMERA = 1, + ANDROID_VIDEO_SOURCE_GRALLOC_BUFFER = 2 + } VideoSource; + + // values are from andoid /system/core/include/system/audio.h + typedef enum + { + ANDROID_AUDIO_SOURCE_DEFAULT = 0, + ANDROID_AUDIO_SOURCE_MIC = 1, + ANDROID_AUDIO_SOURCE_VOICE_UPLINK = 2, + ANDROID_AUDIO_SOURCE_VOICE_DOWNLINK = 3, + ANDROID_AUDIO_SOURCE_VOICE_CALL = 4, + ANDROID_AUDIO_SOURCE_CAMCORDER = 5, + ANDROID_AUDIO_SOURCE_VOICE_RECOGNITION = 6, + ANDROID_AUDIO_SOURCE_VOICE_COMMUNICATION = 7, + ANDROID_AUDIO_SOURCE_REMOTE_SUBMIX = 8, + ANDROID_AUDIO_SOURCE_CNT, + ANDROID_AUDIO_SOURCE_MAX = ANDROID_AUDIO_SOURCE_CNT - 1 + } AudioSource; + + // values are from andoid /frameworks/av/include/media/mediarecorder.h + typedef enum + { + ANDROID_OUTPUT_FORMAT_DEFAULT = 0, + ANDROID_OUTPUT_FORMAT_THREE_GPP = 1, + ANDROID_OUTPUT_FORMAT_MPEG_4 = 2, + ANDROID_OUTPUT_FORMAT_AUDIO_ONLY_START = 3, + /* These are audio only file formats */ + ANDROID_OUTPUT_FORMAT_RAW_AMR = 3, //to be backward compatible + ANDROID_OUTPUT_FORMAT_AMR_NB = 3, + ANDROID_OUTPUT_FORMAT_AMR_WB = 4, + ANDROID_OUTPUT_FORMAT_AAC_ADIF = 5, + ANDROID_OUTPUT_FORMAT_AAC_ADTS = 6, + /* Stream over a socket, limited to a single stream */ + ANDROID_OUTPUT_FORMAT_RTP_AVP = 7, + /* H.264/AAC data encapsulated in MPEG2/TS */ + ANDROID_OUTPUT_FORMAT_MPEG2TS = 8 + } OutputFormat; + + // values are from andoid /frameworks/av/include/media/mediarecorder.h + typedef enum + { + ANDROID_VIDEO_ENCODER_DEFAULT = 0, + ANDROID_VIDEO_ENCODER_H263 = 1, + ANDROID_VIDEO_ENCODER_H264 = 2, + ANDROID_VIDEO_ENCODER_MPEG_4_SP = 3 + } VideoEncoder; + + // values are from andoid /frameworks/av/include/media/mediarecorder.h + typedef enum + { + ANDROID_AUDIO_ENCODER_DEFAULT = 0, + ANDROID_AUDIO_ENCODER_AMR_NB = 1, + ANDROID_AUDIO_ENCODER_AMR_WB = 2, + ANDROID_AUDIO_ENCODER_AAC = 3, + ANDROID_AUDIO_ENCODER_HE_AAC = 4, + ANDROID_AUDIO_ENCODER_AAC_ELD = 5 + } AudioEncoder; + + // Callback types + typedef void (*on_recorder_msg_error)(void *context); + + // Callback setters + void android_recorder_set_error_cb(MediaRecorderWrapper *mr, on_recorder_msg_error cb, + void *context); + + // Main recorder control API + MediaRecorderWrapper *android_media_new_recorder(); + int android_recorder_initCheck(MediaRecorderWrapper *mr); + int android_recorder_setCamera(MediaRecorderWrapper *mr, CameraControl* control); + int android_recorder_setVideoSource(MediaRecorderWrapper *mr, VideoSource vs); + int android_recorder_setAudioSource(MediaRecorderWrapper *mr, AudioSource as); + int android_recorder_setOutputFormat(MediaRecorderWrapper *mr, OutputFormat of); + int android_recorder_setVideoEncoder(MediaRecorderWrapper *mr, VideoEncoder ve); + int android_recorder_setAudioEncoder(MediaRecorderWrapper *mr, AudioEncoder ae); + int android_recorder_setOutputFile(MediaRecorderWrapper *mr, int fd); + int android_recorder_setVideoSize(MediaRecorderWrapper *mr, int width, int height); + int android_recorder_setVideoFrameRate(MediaRecorderWrapper *mr, int frames_per_second); + int android_recorder_setParameters(MediaRecorderWrapper *mr, const char* parameters); + int android_recorder_start(MediaRecorderWrapper *mr); + int android_recorder_stop(MediaRecorderWrapper *mr); + int android_recorder_prepare(MediaRecorderWrapper *mr); + int android_recorder_reset(MediaRecorderWrapper *mr); + int android_recorder_close(MediaRecorderWrapper *mr); + int android_recorder_release(MediaRecorderWrapper *mr); + +#ifdef __cplusplus +} +#endif + +#endif diff -Nru libhybris-0.61/compat/surface_flinger/glcommon.h libhybris-0.62/compat/surface_flinger/glcommon.h --- libhybris-0.61/compat/surface_flinger/glcommon.h 2013-03-04 23:50:38.000000000 +0000 +++ libhybris-0.62/compat/surface_flinger/glcommon.h 2013-05-29 20:24:10.000000000 +0000 @@ -15,10 +15,6 @@ * * Authored by: Thomas Voß */ -#include -#include -#include -#include #include diff -Nru libhybris-0.61/compat/surface_flinger/surface_flinger_compatibility_layer.h libhybris-0.62/compat/surface_flinger/surface_flinger_compatibility_layer.h --- libhybris-0.61/compat/surface_flinger/surface_flinger_compatibility_layer.h 2013-03-04 23:50:38.000000000 +0000 +++ libhybris-0.62/compat/surface_flinger/surface_flinger_compatibility_layer.h 2013-05-29 20:24:10.000000000 +0000 @@ -23,8 +23,6 @@ extern "C" { #endif -#include -#include #include #include diff -Nru libhybris-0.61/compat/surface_flinger/test.cpp libhybris-0.62/compat/surface_flinger/test.cpp --- libhybris-0.61/compat/surface_flinger/test.cpp 2013-03-04 23:50:38.000000000 +0000 +++ libhybris-0.62/compat/surface_flinger/test.cpp 2013-05-29 20:24:10.000000000 +0000 @@ -21,6 +21,9 @@ #include +#include +#include + bool setupGraphics(); void hw_render(EGLDisplay, EGLSurface); void hw_step(); diff -Nru libhybris-0.61/debian/changelog libhybris-0.62/debian/changelog --- libhybris-0.61/debian/changelog 2013-05-29 20:37:53.000000000 +0000 +++ libhybris-0.62/debian/changelog 2013-05-29 20:37:53.000000000 +0000 @@ -1,8 +1,30 @@ -libhybris (0.61-0phablet1raring1) raring; urgency=low +libhybris (0.62-0phablet1) raring; urgency=low - * Automatic build of revision 123 + [ Ricardo Salveti de Araujo ] + * common/hooks.c: adding getgrgid to avoid another segfault + * common/properties.c: also probe property from kernel cmdline + (used by mako) + * compat/surface_flinger/test.cpp: fixing test case due gl header + changes + * gl2.c: updating glShaderSource definition based on latest mesa + (fix ftbfs at raring) + + [ Michael Zanetti ] + * reset the media player before setting a new stream. Makes skipping + in QMediaPlaylist work. + + [ Guenter Schwann ] + * First video recording support + * Do not call releaseRecordingFrame() after capture (LP: #1169352) + + [ Jim Hodapp ] + * Add hook for vasprintf which is needed for the new MediaCodec-based + media player backend. + + [ Michael Terry ] + * Remove unnecessary GLES header includes - -- PS Jenkins bot Thu, 21 Mar 2013 12:25:47 +0000 + -- PS Jenkins bot Wed, 29 May 2013 20:24:16 +0000 libhybris (0.61-0phablet1) quantal; urgency=low diff -Nru libhybris-0.61/hybris/Makefile libhybris-0.62/hybris/Makefile --- libhybris-0.61/hybris/Makefile 2013-03-04 23:50:38.000000000 +0000 +++ libhybris-0.62/hybris/Makefile 2013-05-29 20:24:10.000000000 +0000 @@ -15,7 +15,7 @@ ICS_SOURCES=ics/linker.c ics/dlfcn.c ics/rt.c ics/linker_environ.c ics/linker_format.c ics/init.c -all: libhybris_ics.so libEGL.so.1 libGLESv2.so.2 libcamera.so libmediaplayer.so libhardware.so libis.so libsf.so test_camera test_media_player test_sf test_egl test_hw test_sensors test_glesv2 +all: libhybris_ics.so libEGL.so.1 libGLESv2.so.2 libcamera.so libmediaplayer.so libhardware.so libis.so libsf.so test_camera test_media_player test_recorder test_sf test_egl test_hw test_sensors test_glesv2 libhybris_ics.so: $(COMMON_SOURCES) $(ICS_SOURCES) $(CC) -g -shared -o $@ -ldl -pthread -fPIC -Iics -Icommon -DLINKER_DEBUG=1 -DLINKER_TEXT_BASE=0xB0000100 -DLINKER_AREA_SIZE=0x01000000 $(ARCHFLAGS) \ @@ -91,6 +91,9 @@ test_media_player: libmediaplayer.so libsf.so libis.so media/test_player.cpp libhybris_ics.so $(CXX) -g -o $@ media/test_player.cpp libmediaplayer.so libsf.so libis.so libEGL.so.1 libGLESv2.so.2 libhybris_ics.so -I../compat/media -I../compat/input -I../compat/surface_flinger +test_recorder: libmediaplayer.so libcamera.so libsf.so libis.so media/test_recorder.cpp libhybris_ics.so + $(CXX) -g -o $@ media/test_recorder.cpp libmediaplayer.so libcamera.so libsf.so libis.so libEGL.so.1 libGLESv2.so.2 libhybris_ics.so -I../compat/media -I../compat/camera -I../compat/input -I../compat/surface_flinger + test_hw: libhardware.so hardware/test.c libhybris_ics.so $(CC) -g -o $@ hardware/test.c libhardware.so libhybris_ics.so -I . diff -Nru libhybris-0.61/hybris/camera/camera.cpp libhybris-0.62/hybris/camera/camera.cpp --- libhybris-0.61/hybris/camera/camera.cpp 2013-03-04 23:50:38.000000000 +0000 +++ libhybris-0.62/hybris/camera/camera.cpp 2013-05-29 20:24:10.000000000 +0000 @@ -122,6 +122,8 @@ IMPLEMENT_FUNCTION0(int, android_camera_get_number_of_devices); IMPLEMENT_FUNCTION2(CameraControl*, android_camera_connect_to, CameraType, CameraControlListener*); IMPLEMENT_VOID_FUNCTION1(android_camera_disconnect, CameraControl*); +IMPLEMENT_FUNCTION1(int, android_camera_lock, CameraControl*); +IMPLEMENT_FUNCTION1(int, android_camera_unlock, CameraControl*); IMPLEMENT_VOID_FUNCTION1(android_camera_delete, CameraControl*); IMPLEMENT_VOID_FUNCTION1(android_camera_dump_parameters, CameraControl*); @@ -140,6 +142,7 @@ IMPLEMENT_VOID_FUNCTION1(android_camera_reset_focus_region, CameraControl*); IMPLEMENT_VOID_FUNCTION2(android_camera_set_preview_fps, CameraControl*, int); IMPLEMENT_VOID_FUNCTION2(android_camera_set_rotation, CameraControl*, int); +IMPLEMENT_VOID_FUNCTION3(android_camera_set_video_size, CameraControl*, int, int); // Getters IMPLEMENT_VOID_FUNCTION2(android_camera_get_effect_mode, CameraControl*, EffectMode*); IMPLEMENT_VOID_FUNCTION2(android_camera_get_flash_mode, CameraControl*, FlashMode*); @@ -152,10 +155,12 @@ IMPLEMENT_VOID_FUNCTION3(android_camera_get_preview_fps_range, CameraControl*, int*, int*); IMPLEMENT_VOID_FUNCTION2(android_camera_get_preview_fps, CameraControl*, int*); IMPLEMENT_VOID_FUNCTION2(android_camera_get_preview_texture_transformation, CameraControl*, float*); +IMPLEMENT_VOID_FUNCTION3(android_camera_get_video_size, CameraControl*, int*, int*); // Enumerators IMPLEMENT_VOID_FUNCTION3(android_camera_enumerate_supported_picture_sizes, CameraControl*, size_callback, void*); IMPLEMENT_VOID_FUNCTION3(android_camera_enumerate_supported_preview_sizes, CameraControl*, size_callback, void*); +IMPLEMENT_VOID_FUNCTION3(android_camera_enumerate_supported_video_sizes, CameraControl*, size_callback, void*); IMPLEMENT_VOID_FUNCTION1(android_camera_update_preview_texture, CameraControl*); diff -Nru libhybris-0.61/hybris/common/hooks.c libhybris-0.62/hybris/common/hooks.c --- libhybris-0.61/hybris/common/hooks.c 2013-03-04 23:50:38.000000000 +0000 +++ libhybris-0.62/hybris/common/hooks.c 2013-05-29 20:24:10.000000000 +0000 @@ -31,6 +31,7 @@ #include #include #include +#include #include @@ -855,6 +856,7 @@ {"putw", putw}, {"sprintf", sprintf}, {"snprintf", snprintf}, + {"vasprintf", vasprintf}, {"vfprintf", vfprintf}, {"vsprintf", vsprintf}, {"vsnprintf", vsnprintf}, @@ -866,6 +868,8 @@ {"gethostbyname", gethostbyname}, {"gethostbyname2", gethostbyname2}, {"gethostent", gethostent}, + /* grp.h */ + {"getgrgid", getgrgid}, {NULL, NULL}, }; diff -Nru libhybris-0.61/hybris/common/properties.c libhybris-0.62/hybris/common/properties.c --- libhybris-0.61/hybris/common/properties.c 2013-03-04 23:50:38.000000000 +0000 +++ libhybris-0.62/hybris/common/properties.c 2013-05-29 20:24:10.000000000 +0000 @@ -19,6 +19,11 @@ #include #include #include +#include +#include +#include + +#define PROP_NAME_MAX 32 static char *find_key(const char *key) { @@ -55,6 +60,54 @@ return NULL; } +static char *find_key_kernel_cmdline(const char *key) +{ + char cmdline[1024]; + char *ptr; + int fd; + + fd = open("/proc/cmdline", O_RDONLY); + if (fd >= 0) { + int n = read(fd, cmdline, 1023); + if (n < 0) n = 0; + + /* get rid of trailing newline, it happens */ + if (n > 0 && cmdline[n-1] == '\n') n--; + + cmdline[n] = 0; + close(fd); + } else { + cmdline[0] = 0; + } + + ptr = cmdline; + + while (ptr && *ptr) { + char *x = strchr(ptr, ' '); + if (x != 0) *x++ = 0; + + char *name = ptr; + ptr = x; + + char *value = strchr(name, '='); + int name_len = strlen(name); + + if (value == 0) continue; + *value++ = 0; + if (name_len == 0) continue; + + if (!strncmp(name, "androidboot.", 12) && name_len > 12) { + const char *boot_prop_name = name + 12; + char prop[PROP_NAME_MAX]; + snprintf(prop, sizeof(prop), "ro.%s", boot_prop_name); + if (strcmp(prop, key) == 0) + return strdup(value); + } + } + + return NULL; +} + int property_get(const char *key, char *value, const char *default_value) { char *ret = NULL; @@ -95,24 +148,24 @@ } #endif if (ret == NULL) - { - if (default_value != NULL) - { - strcpy(value, default_value); - return strlen(value); - } - else return 0; - } + { + /* Property might be available via /proc/cmdline */ + ret = find_key_kernel_cmdline(key); + } + if (ret) { strcpy(value, ret); free(ret); return strlen(value); } - else + else if (default_value != NULL) { - return 0; + strcpy(value, default_value); + return strlen(value); } + + return 0; } int property_set(const char *key, const char *value) { diff -Nru libhybris-0.61/hybris/glesv2/gl2.c libhybris-0.62/hybris/glesv2/gl2.c --- libhybris-0.61/hybris/glesv2/gl2.c 2013-03-04 23:50:38.000000000 +0000 +++ libhybris-0.62/hybris/glesv2/gl2.c 2013-05-29 20:24:10.000000000 +0000 @@ -128,7 +128,7 @@ static void (*_glSampleCoverage)(GLclampf value, GLboolean invert) FP_ATTRIB = NULL; static void (*_glScissor)(GLint x, GLint y, GLsizei width, GLsizei height) = NULL; static void (*_glShaderBinary)(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length) = NULL; -static void (*_glShaderSource)(GLuint shader, GLsizei count, const GLchar** string, const GLint* length) = NULL; +static void (*_glShaderSource)(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length) = NULL; static void (*_glStencilFunc)(GLenum func, GLint ref, GLuint mask) = NULL; static void (*_glStencilFuncSeparate)(GLenum face, GLenum func, GLint ref, GLuint mask) = NULL; static void (*_glStencilMask)(GLuint mask) = NULL; @@ -787,7 +787,7 @@ return (*_glShaderBinary)(n, shaders, binaryformat, binary, length); } -void glShaderSource (GLuint shader, GLsizei count, const GLchar** string, const GLint* length) +void glShaderSource (GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length) { GLES2_DLSYM(glShaderSource); return (*_glShaderSource)(shader, count, string, length); diff -Nru libhybris-0.61/hybris/install.sh libhybris-0.62/hybris/install.sh --- libhybris-0.61/hybris/install.sh 2013-03-04 23:50:38.000000000 +0000 +++ libhybris-0.62/hybris/install.sh 2013-05-29 20:24:10.000000000 +0000 @@ -1,16 +1,26 @@ -adb push libEGL.so.1.0 /data/ubuntu/usr/lib -adb push libEGL.so.1 /data/ubuntu/usr/lib -adb push libsf.so.1.0 /data/ubuntu/usr/lib -adb push libsf.so.1 /data/ubuntu/usr/lib -adb push libis.so.1.0 /data/ubuntu/usr/lib -adb push libis.so.1 /data/ubuntu/usr/lib -adb push libhardware.so.1.0 /data/ubuntu/usr/lib -adb push libhardware.so.1 /data/ubuntu/usr/lib -adb push libhybris_ics.so /data/ubuntu/usr/lib -adb push libGLESv2.so.2 /data/ubuntu/usr/lib -adb push libGLESv2.so.2.0 /data/ubuntu/usr/lib -adb push test_egl /data/ubuntu/root -adb push test_glesv2 /data/ubuntu/root -adb push test_hw /data/ubuntu/root -adb push test_sensors /data/ubuntu/root -adb push test_sf /data/ubuntu/root +LIB_TARGET=/data/ubuntu/usr/lib/arm-linux-gnueabihf +TEST_TARGET=/data/ubuntu/root + +adb push libEGL.so.1.0 $LIB_TARGET +adb push libEGL.so.1 $LIB_TARGET +adb push libsf.so.1.0 $LIB_TARGET +adb push libsf.so.1 $LIB_TARGET +adb push libis.so.1.0 $LIB_TARGET +adb push libis.so.1 $LIB_TARGET +adb push libhardware.so.1.0 $LIB_TARGET +adb push libhardware.so.1 $LIB_TARGET +adb push libhybris_ics.so $LIB_TARGET +adb push libGLESv2.so.2 $LIB_TARGET +adb push libGLESv2.so.2.0 $LIB_TARGET +adb push libcamera.so.1.0 $LIB_TARGET +adb push libcamera.so.1 $LIB_TARGET +adb push libcamera.so $LIB_TARGET +adb push libmediaplayer.so.1.0 $LIB_TARGET +adb push test_egl $TEST_TARGET +adb push test_glesv2 $TEST_TARGET +adb push test_hw $TEST_TARGET +adb push test_sensors $TEST_TARGET +adb push test_sf $TEST_TARGET +adb push test_camera $TEST_TARGET +adb push test_recorder $TEST_TARGET + diff -Nru libhybris-0.61/hybris/media/media.cpp libhybris-0.62/hybris/media/media.cpp --- libhybris-0.61/hybris/media/media.cpp 2013-03-04 23:50:38.000000000 +0000 +++ libhybris-0.62/hybris/media/media.cpp 2013-05-29 20:24:10.000000000 +0000 @@ -17,6 +17,7 @@ */ #include +#include #include #include @@ -117,6 +118,13 @@ MEDIA_PLAYER_DLSYM(&f, #symbol); \ f(_1, _2); } +#define IMPLEMENT_FUNCTION3(return_type, symbol, arg1, arg2, arg3) \ + return_type symbol(arg1 _1, arg2 _2, arg3 _3) \ + { \ + static return_type (*f)(arg1, arg2, arg3) = NULL; \ + MEDIA_PLAYER_DLSYM(&f, #symbol); \ + return f(_1, _2, _3); } + #define IMPLEMENT_VOID_FUNCTION3(symbol, arg1, arg2, arg3) \ void symbol(arg1 _1, arg2 _2, arg3 _3) \ { \ @@ -139,7 +147,7 @@ IMPLEMENT_FUNCTION2(int, android_media_set_volume, MediaPlayerWrapper *, int); // Getters -IMPLEMENT_VOID_FUNCTION2(android_media_surface_texture_get_transformation_matrix, MediaPlayerWrapper *, GLfloat*); +IMPLEMENT_VOID_FUNCTION2(android_media_surface_texture_get_transformation_matrix, MediaPlayerWrapper *, float*); IMPLEMENT_FUNCTION2(int, android_media_get_current_position, MediaPlayerWrapper *, int*); IMPLEMENT_FUNCTION2(int, android_media_get_duration, MediaPlayerWrapper *, int*); IMPLEMENT_FUNCTION2(int, android_media_get_volume, MediaPlayerWrapper *, int*); @@ -151,6 +159,29 @@ IMPLEMENT_VOID_FUNCTION3(android_media_set_playback_complete_cb, MediaPlayerWrapper *, on_playback_complete, void*); IMPLEMENT_VOID_FUNCTION3(android_media_set_media_prepared_cb, MediaPlayerWrapper *, on_media_prepared, void*); +// Recorder +IMPLEMENT_FUNCTION0(MediaRecorderWrapper*, android_media_new_recorder); +IMPLEMENT_FUNCTION1(int, android_recorder_initCheck, MediaRecorderWrapper*); +IMPLEMENT_FUNCTION2(int, android_recorder_setCamera, MediaRecorderWrapper*, CameraControl*); +IMPLEMENT_FUNCTION2(int, android_recorder_setVideoSource, MediaRecorderWrapper*, VideoSource); +IMPLEMENT_FUNCTION2(int, android_recorder_setAudioSource, MediaRecorderWrapper*, AudioSource); +IMPLEMENT_FUNCTION2(int, android_recorder_setOutputFormat, MediaRecorderWrapper*, OutputFormat); +IMPLEMENT_FUNCTION2(int, android_recorder_setVideoEncoder, MediaRecorderWrapper*, VideoEncoder); +IMPLEMENT_FUNCTION2(int, android_recorder_setAudioEncoder, MediaRecorderWrapper*, AudioEncoder); +IMPLEMENT_FUNCTION2(int, android_recorder_setOutputFile, MediaRecorderWrapper*, int); +IMPLEMENT_FUNCTION3(int, android_recorder_setVideoSize, MediaRecorderWrapper*, int, int); +IMPLEMENT_FUNCTION2(int, android_recorder_setVideoFrameRate, MediaRecorderWrapper*, int); +IMPLEMENT_FUNCTION2(int, android_recorder_setParameters, MediaRecorderWrapper*, const char*); +IMPLEMENT_FUNCTION1(int, android_recorder_start, MediaRecorderWrapper*); +IMPLEMENT_FUNCTION1(int, android_recorder_stop, MediaRecorderWrapper*); +IMPLEMENT_FUNCTION1(int, android_recorder_prepare, MediaRecorderWrapper*); +IMPLEMENT_FUNCTION1(int, android_recorder_reset, MediaRecorderWrapper*); +IMPLEMENT_FUNCTION1(int, android_recorder_close, MediaRecorderWrapper*); +IMPLEMENT_FUNCTION1(int, android_recorder_release, MediaRecorderWrapper*); + +// Recorder Callbacks +IMPLEMENT_VOID_FUNCTION3(android_recorder_set_error_cb, MediaRecorderWrapper *, on_recorder_msg_error, void*); + #ifdef __cplusplus } #endif diff -Nru libhybris-0.61/hybris/media/test_recorder.cpp libhybris-0.62/hybris/media/test_recorder.cpp --- libhybris-0.61/hybris/media/test_recorder.cpp 1970-01-01 00:00:00.000000000 +0000 +++ libhybris-0.62/hybris/media/test_recorder.cpp 2013-05-29 20:24:10.000000000 +0000 @@ -0,0 +1,504 @@ +/* + * Copyright (C) 2012 Canonical Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "camera_compatibility_layer.h" +#include "camera_compatibility_layer_capabilities.h" +#include "recorder_compatibility_layer.h" + +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +int shot_counter = 1; +int32_t current_zoom_level = 1; +bool new_camera_frame_available = true; +MediaRecorderWrapper *mr = 0; +GLuint preview_texture_id = 0; + +void error_msg_cb(void* context) +{ + printf("%s \n", __PRETTY_FUNCTION__); +} + +void shutter_msg_cb(void* context) +{ + printf("%s \n", __PRETTY_FUNCTION__); +} + +void zoom_msg_cb(void* context, int32_t new_zoom_level) +{ + printf("%s \n", __PRETTY_FUNCTION__); + + CameraControl* cc = static_cast(context); + static int zoom; + current_zoom_level = new_zoom_level; +} + +void autofocus_msg_cb(void* context) +{ + printf("%s \n", __PRETTY_FUNCTION__); +} + +void raw_data_cb(void* data, uint32_t data_size, void* context) +{ + printf("%s: %d \n", __PRETTY_FUNCTION__, data_size); +} + +void jpeg_data_cb(void* data, uint32_t data_size, void* context) +{ + printf("%s: %d \n", __PRETTY_FUNCTION__, data_size); + CameraControl* cc = static_cast(context); + android_camera_start_preview(cc); +} + +void size_cb(void* ctx, int width, int height) +{ + printf("Supported size: [%d,%d]\n", width, height); +} + +void preview_texture_needs_update_cb(void* ctx) +{ + new_camera_frame_available = true; +} + +void on_new_input_event(Event* event, void* context) +{ + assert(context); + + if (event->type == KEY_EVENT_TYPE && event->action == ISCL_KEY_EVENT_ACTION_UP) + { + printf("We have got a key event: %d \n", event->details.key.key_code); + + CameraControl* cc = static_cast(context); + + int ret; + switch(event->details.key.key_code) + { + case ISCL_KEYCODE_VOLUME_UP: + printf("Starting video recording\n"); + + android_camera_unlock(cc); + + ret = android_recorder_setCamera(mr, cc); + if (ret < 0) { + printf("android_recorder_setCamera() failed\n"); + return; + } + //state initial / idle + ret = android_recorder_setAudioSource(mr, ANDROID_AUDIO_SOURCE_CAMCORDER); + if (ret < 0) { + printf("android_recorder_setAudioSource() failed\n"); + return; + } + ret = android_recorder_setVideoSource(mr, ANDROID_VIDEO_SOURCE_CAMERA); + if (ret < 0) { + printf("android_recorder_setVideoSource() failed\n"); + return; + } + //state initialized + ret = android_recorder_setOutputFormat(mr, ANDROID_OUTPUT_FORMAT_MPEG_4); + if (ret < 0) { + printf("android_recorder_setOutputFormat() failed\n"); + return; + } + //state DataSourceConfigured + ret = android_recorder_setAudioEncoder(mr, ANDROID_AUDIO_ENCODER_AAC); + if (ret < 0) { + printf("android_recorder_setAudioEncoder() failed\n"); + return; + } + ret = android_recorder_setVideoEncoder(mr, ANDROID_VIDEO_ENCODER_H264); + if (ret < 0) { + printf("android_recorder_setVideoEncoder() failed\n"); + return; + } + + int fd; + fd = open("/root/test_video.avi", O_WRONLY | O_CREAT); + if (fd < 0) { + printf("Could not open file for video recording\n"); + printf("FD: %i\n", fd); + return; + } + ret = android_recorder_setOutputFile(mr, fd); + if (ret < 0) { + printf("android_recorder_setOutputFile() failed\n"); + return; + } + + ret = android_recorder_setVideoSize(mr, 1280, 720); + if (ret < 0) { + printf("android_recorder_setVideoSize() failed\n"); + return; + } + ret = android_recorder_setVideoFrameRate(mr, 30); + if (ret < 0) { + printf("android_recorder_setVideoFrameRate() failed\n"); + return; + } + + ret = android_recorder_prepare(mr); + if (ret < 0) { + printf("android_recorder_prepare() failed\n"); + return; + } + //state prepared + ret = android_recorder_start(mr); + if (ret < 0) { + printf("android_recorder_start() failed\n"); + return; + } + break; + case ISCL_KEYCODE_VOLUME_DOWN: + printf("Stoping video recording\n"); + ret = android_recorder_stop(mr); + printf("Stoping video recording returned\n"); + if (ret < 0) { + printf("android_recorder_stop() failed\n"); + return; + } + printf("Stopped video recording\n"); + ret = android_recorder_reset(mr); + if (ret < 0) { + printf("android_recorder_reset() failed\n"); + return; + } + printf("Reset video recorder\n"); + break; + } + } +} + +struct ClientWithSurface +{ + SfClient* client; + SfSurface* surface; +}; + +ClientWithSurface client_with_surface(bool setup_surface_with_egl) +{ + ClientWithSurface cs = ClientWithSurface(); + + cs.client = sf_client_create(); + + if (!cs.client) + { + printf("Problem creating client ... aborting now."); + return cs; + } + + static const size_t primary_display = 0; + + SfSurfaceCreationParameters params = + { + 0, + 0, + sf_get_display_width(primary_display), + sf_get_display_height(primary_display), + -1, //PIXEL_FORMAT_RGBA_8888, + 15000, + 0.5f, + setup_surface_with_egl, // Do not associate surface with egl, will be done by camera HAL + "CameraCompatLayerTestSurface" + }; + + cs.surface = sf_surface_create(cs.client, ¶ms); + + if (!cs.surface) + { + printf("Problem creating surface ... aborting now."); + return cs; + } + + sf_surface_make_current(cs.surface); + + return cs; +} + +#define PRINT_GLERROR() printf("GL error@%d: %x\n", __LINE__, glGetError()); + +struct RenderData +{ + static const char* vertex_shader() + { + return + "#extension GL_OES_EGL_image_external : require \n" + "attribute vec4 a_position; \n" + "attribute vec2 a_texCoord; \n" + "uniform mat4 m_texMatrix; \n" + "varying vec2 v_texCoord; \n" + "varying float topDown; \n" + "void main() \n" + "{ \n" + " gl_Position = a_position; \n" + " v_texCoord = a_texCoord; \n" + // " v_texCoord = (m_texMatrix * vec4(a_texCoord, 0.0, 1.0)).xy;\n" + //" topDown = v_texCoord.y; \n" + "} \n"; + } + + static const char* fragment_shader() + { + return + "#extension GL_OES_EGL_image_external : require \n" + "precision mediump float; \n" + "varying vec2 v_texCoord; \n" + "uniform samplerExternalOES s_texture; \n" + "void main() \n" + "{ \n" + " gl_FragColor = texture2D( s_texture, v_texCoord );\n" + "} \n"; + } + + static GLuint loadShader(GLenum shaderType, const char* pSource) { + GLuint shader = glCreateShader(shaderType); + + if (shader) { + glShaderSource(shader, 1, &pSource, NULL); + glCompileShader(shader); + GLint compiled = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); + if (!compiled) { + GLint infoLen = 0; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); + if (infoLen) { + char* buf = (char*) malloc(infoLen); + if (buf) { + glGetShaderInfoLog(shader, infoLen, NULL, buf); + fprintf(stderr, "Could not compile shader %d:\n%s\n", + shaderType, buf); + free(buf); + } + glDeleteShader(shader); + shader = 0; + } + } + } + else + { + printf("Error, during shader creation: %i\n", glGetError()); + } + return shader; + } + + static GLuint create_program(const char* pVertexSource, const char* pFragmentSource) { + GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource); + if (!vertexShader) { + printf("vertex shader not compiled\n"); + return 0; + } + + GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource); + if (!pixelShader) { + printf("frag shader not compiled\n"); + return 0; + } + + GLuint program = glCreateProgram(); + if (program) { + glAttachShader(program, vertexShader); + glAttachShader(program, pixelShader); + glLinkProgram(program); + GLint linkStatus = GL_FALSE; + glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); + if (linkStatus != GL_TRUE) { + GLint bufLength = 0; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); + if (bufLength) { + char* buf = (char*) malloc(bufLength); + if (buf) { + glGetProgramInfoLog(program, bufLength, NULL, buf); + fprintf(stderr, "Could not link program:\n%s\n", buf); + free(buf); + } + } + glDeleteProgram(program); + program = 0; + } + } + return program; + } + + RenderData() : program_object(create_program(vertex_shader(), fragment_shader())) + { + position_loc = glGetAttribLocation(program_object, "a_position"); + tex_coord_loc = glGetAttribLocation(program_object, "a_texCoord"); + sampler_loc = glGetUniformLocation(program_object, "s_texture"); + matrix_loc = glGetUniformLocation(program_object, "m_texMatrix"); + } + + // Handle to a program object + GLuint program_object; + // Attribute locations + GLint position_loc; + GLint tex_coord_loc; + // Sampler location + GLint sampler_loc; + // Matrix location + GLint matrix_loc; +}; + +int main(int argc, char** argv) +{ + printf("Test application for video recording using the camera\n"); + printf("Recording start with volume up button. And stops with volume down.\n"); + printf("The result is stored to /root/test_video.avi\n\n"); + + CameraControlListener listener; + memset(&listener, 0, sizeof(listener)); + listener.on_msg_error_cb = error_msg_cb; + listener.on_msg_shutter_cb = shutter_msg_cb; + listener.on_msg_focus_cb = autofocus_msg_cb; + listener.on_msg_zoom_cb = zoom_msg_cb; + + listener.on_data_raw_image_cb = raw_data_cb; + listener.on_data_compressed_image_cb = jpeg_data_cb; + listener.on_preview_texture_needs_update_cb = preview_texture_needs_update_cb; + CameraControl* cc = android_camera_connect_to(BACK_FACING_CAMERA_TYPE, + &listener); + if (cc == NULL) + { + printf("Problem connecting to camera"); + return 1; + } + + listener.context = cc; + + mr = android_media_new_recorder(); + + AndroidEventListener event_listener; + event_listener.on_new_event = on_new_input_event; + event_listener.context = cc; + + InputStackConfiguration input_configuration = { true, 25000 }; + + android_input_stack_initialize(&event_listener, &input_configuration); + android_input_stack_start(); + + android_camera_dump_parameters(cc); + + printf("Supported video sizes:\n"); + android_camera_enumerate_supported_video_sizes(cc, size_cb, NULL); + + int min_fps, max_fps, current_fps; + + android_camera_set_preview_size(cc, 1280, 720); + + int width, height; + android_camera_get_video_size(cc, &width, &height); + printf("Current video size: [%d,%d]\n", width, height); + + ClientWithSurface cs = client_with_surface(true /* Associate surface with egl. */); + + if (!cs.surface) + { + printf("Problem acquiring surface for preview"); + return 1; + } + + EGLDisplay disp = sf_client_get_egl_display(cs.client); + EGLSurface surface = sf_surface_get_egl_surface(cs.surface); + + sf_surface_make_current(cs.surface); + RenderData render_data; + glGenTextures(1, &preview_texture_id); + glClearColor(1.0, 0., 0.5, 1.); + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri( + GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri( + GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + android_camera_set_preview_texture(cc, preview_texture_id); + android_camera_start_preview(cc); + + GLfloat transformation_matrix[16]; + android_camera_get_preview_texture_transformation(cc, transformation_matrix); + glUniformMatrix4fv(render_data.matrix_loc, 1, GL_FALSE, transformation_matrix); + + printf("Started camera preview.\n"); + + while(true) + { + + /*if (new_camera_frame_available) + { + printf("Updating texture"); + new_camera_frame_available = false; + }*/ + static GLfloat vVertices[] = { 0.0f, 0.0f, 0.0f, // Position 0 + 0.0f, 0.0f, // TexCoord 0 + 0.0f, 1.0f, 0.0f, // Position 1 + 0.0f, 1.0f, // TexCoord 1 + 1.0f, 1.0f, 0.0f, // Position 2 + 1.0f, 1.0f, // TexCoord 2 + 1.0f, 0.0f, 0.0f, // Position 3 + 1.0f, 0.0f // TexCoord 3 + }; + + GLushort indices[] = { 0, 1, 2, 0, 2, 3 }; + + // Set the viewport + // Clear the color buffer + glClear(GL_COLOR_BUFFER_BIT); + // Use the program object + glUseProgram(render_data.program_object); + // Enable attributes + glEnableVertexAttribArray(render_data.position_loc); + glEnableVertexAttribArray(render_data.tex_coord_loc); + // Load the vertex position + glVertexAttribPointer(render_data.position_loc, + 3, + GL_FLOAT, + GL_FALSE, + 5 * sizeof(GLfloat), + vVertices); + // Load the texture coordinate + glVertexAttribPointer(render_data.tex_coord_loc, + 2, + GL_FLOAT, + GL_FALSE, + 5 * sizeof(GLfloat), + vVertices+3); + + glActiveTexture(GL_TEXTURE0); + // Set the sampler texture unit to 0 + glUniform1i(render_data.sampler_loc, 0); + glUniform1i(render_data.matrix_loc, 0); + android_camera_update_preview_texture(cc); + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices); + glDisableVertexAttribArray(render_data.position_loc); + glDisableVertexAttribArray(render_data.tex_coord_loc); + + eglSwapBuffers(disp, surface); + } +} diff -Nru libhybris-0.61/hybris/sf/test.cpp libhybris-0.62/hybris/sf/test.cpp --- libhybris-0.61/hybris/sf/test.cpp 2013-03-04 23:50:38.000000000 +0000 +++ libhybris-0.62/hybris/sf/test.cpp 2013-05-29 20:24:10.000000000 +0000 @@ -22,6 +22,9 @@ #include +#include +#include + #include "surface_flinger_compatibility_layer.h" SfSurface* sf_surface_create(SfClient* client, SfSurfaceCreationParameters* params);