summaryrefslogtreecommitdiff
authorniko.he <niko.he@amlogic.com>2013-01-25 03:40:58 (GMT)
committer niko.he <niko.he@amlogic.com>2013-01-25 03:40:58 (GMT)
commitb6f235731a87516c52cc7c9e4c55ae888b3e671b (patch)
treea82186a3dcd124986432d70317439b003948a166
downloadscreen_source-b6f235731a87516c52cc7c9e4c55ae888b3e671b.zip
screen_source-b6f235731a87516c52cc7c9e4c55ae888b3e671b.tar.gz
screen_source-b6f235731a87516c52cc7c9e4c55ae888b3e671b.tar.bz2
Init screen_source.---Zefeng.Tong.
Diffstat
-rwxr-xr-xAndroid.mk18
-rwxr-xr-xaml_screen.cpp188
-rwxr-xr-xtest/Android.mk16
-rwxr-xr-xtest/screen_source_test.cpp91
-rwxr-xr-xv4l2_vdin.cpp211
-rwxr-xr-xv4l2_vdin.h69
6 files changed, 593 insertions, 0 deletions
diff --git a/Android.mk b/Android.mk
new file mode 100755
index 0000000..3c84e57
--- a/dev/null
+++ b/Android.mk
@@ -0,0 +1,18 @@
+# Copyright (C) 2013 Amlogic
+#
+#
+
+LOCAL_PATH := $(call my-dir)
+
+# HAL module implemenation, not prelinked and stored in
+# /system/lib/hw/screen_source.amlogic.so
+include $(CLEAR_VARS)
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+LOCAL_SRC_FILES := aml_screen.cpp v4l2_vdin.cpp
+
+LOCAL_SHARED_LIBRARIES:= libutils
+
+LOCAL_MODULE := screen_source.amlogic
+LOCAL_CFLAGS:= -DLOG_TAG=\"screen_source\"
+LOCAL_MODULE_TAGS := optional
+include $(BUILD_SHARED_LIBRARY)
diff --git a/aml_screen.cpp b/aml_screen.cpp
new file mode 100755
index 0000000..5828cd4
--- a/dev/null
+++ b/aml_screen.cpp
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "screen_source"
+#include <hardware/hardware.h>
+#include <hardware/aml_screen.h>
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/select.h>
+#include <linux/videodev.h>
+#include <sys/time.h>
+
+
+#include <errno.h>
+#include <cutils/log.h>
+#include <cutils/atomic.h>
+
+#include "v4l2_vdin.h"
+
+#ifndef LOGD
+#define LOGD ALOGD
+#endif
+#ifndef LOGV
+#define LOGV ALOGV
+#endif
+#ifndef LOGE
+#define LOGE ALOGE
+#endif
+#ifndef LOGI
+#define LOGI ALOGI
+#endif
+/*****************************************************************************/
+
+static int aml_screen_device_open(const struct hw_module_t* module, const char* name,
+ struct hw_device_t** device);
+
+static struct hw_module_methods_t aml_screen_module_methods = {
+ open: aml_screen_device_open
+};
+
+aml_screen_module_t HAL_MODULE_INFO_SYM = {
+ common: {
+ tag: HARDWARE_MODULE_TAG,
+ version_major: 1,
+ version_minor: 0,
+ id: AML_SCREEN_HARDWARE_MODULE_ID,
+ name: "aml screen source module",
+ author: "Amlogic",
+ methods: &aml_screen_module_methods,
+ dso : NULL,
+ reserved : {0},
+ }
+};
+
+/*****************************************************************************/
+
+static int aml_screen_device_close(struct hw_device_t *dev)
+{
+ android::vdin_screen_source* source = NULL;
+ aml_screen_device_t* ctx = (aml_screen_device_t*)dev;
+ if (ctx) {
+
+ if (ctx->priv)
+ {
+ source = (android::vdin_screen_source*)ctx->priv;
+ delete source;
+ source = NULL;
+ }
+
+ free(ctx);
+ }
+ return 0;
+}
+
+int screen_source_start(struct aml_screen_device* dev)
+{
+ android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv;
+ LOGV("screen_source_start");
+ return source->start();
+}
+int screen_source_stop(struct aml_screen_device* dev)
+{
+ android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv;
+ return source->stop();
+}
+int screen_source_get_format(struct aml_screen_device* dev)
+{
+ android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv;
+ return source->get_format();
+}
+int screen_source_set_format(struct aml_screen_device* dev, int width, int height, int pix_format)
+{
+ android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv;
+
+ if ((width > 0) && (height > 0) && ((pix_format == V4L2_PIX_FMT_NV21) || (pix_format == V4L2_PIX_FMT_YUV420)))
+ {
+ return source->set_format(width, height, pix_format);
+ }
+ else
+ {
+ return source->set_format();
+ }
+}
+char* screen_source_aquire_buffer(struct aml_screen_device* dev)
+{
+ android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv;
+ char * ptr_return;
+
+ ptr_return = source->aquire_buffer();
+
+ return ptr_return;
+}
+int screen_source_release_buffer(struct aml_screen_device* dev, char* ptr)
+{
+ android::vdin_screen_source* source = (android::vdin_screen_source*)dev->priv;
+ return source->release_buffer(ptr);
+}
+/*****************************************************************************/
+
+static int aml_screen_device_open(const struct hw_module_t* module, const char* name,
+ struct hw_device_t** device)
+{
+ int status = -EINVAL;
+ android::vdin_screen_source* source = NULL;
+
+ LOGV("aml_screen_device_open");
+
+ if (!strcmp(name, AML_SCREEN_SOURCE)) {
+ aml_screen_device_t *dev = (aml_screen_device_t*)malloc(sizeof(aml_screen_device_t));
+
+ if (!dev)
+ {
+ LOGE("no memory for the screen source device");
+ return -ENOMEM;
+ }
+ /* initialize handle here */
+ memset(dev, 0, sizeof(*dev));
+
+ source = new android::vdin_screen_source;
+ if (!source)
+ {
+ LOGE("no memory for class of vdin_screen_source");
+ free (dev);
+ return -ENOMEM;
+ }
+ dev->priv = (void*)source;
+
+ /* initialize the procs */
+ dev->common.tag = HARDWARE_DEVICE_TAG;
+ dev->common.version = 0;
+ dev->common.module = const_cast<hw_module_t*>(module);
+ dev->common.close = aml_screen_device_close;
+
+ dev->ops.start = screen_source_start;
+ dev->ops.stop = screen_source_stop;
+ dev->ops.get_format = screen_source_get_format;
+ dev->ops.set_format = screen_source_set_format;
+ dev->ops.aquire_buffer = screen_source_aquire_buffer;
+ dev->ops.release_buffer = screen_source_release_buffer;
+
+ *device = &dev->common;
+
+ status = 0;
+ }
+ return status;
+}
diff --git a/test/Android.mk b/test/Android.mk
new file mode 100755
index 0000000..a17fdd5
--- a/dev/null
+++ b/test/Android.mk
@@ -0,0 +1,16 @@
+# Build the unit tests.
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := screen_source_test
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := screen_source_test.cpp
+
+LOCAL_SHARED_LIBRARIES := libutils\
+ libhardware
+
+#LOCAL_C_INCLUDES :=
+
+include $(BUILD_EXECUTABLE) \ No newline at end of file
diff --git a/test/screen_source_test.cpp b/test/screen_source_test.cpp
new file mode 100755
index 0000000..fa38337
--- a/dev/null
+++ b/test/screen_source_test.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#define LOG_NDEBUG 0
+#define LOG_TAG "screen_source_test"
+#include <hardware/hardware.h>
+#include <hardware/aml_screen.h>
+
+#include <errno.h>
+#include <cutils/log.h>
+#include <cutils/atomic.h>
+
+#include <stdio.h>
+#include <assert.h>
+#include <limits.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sched.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+
+#ifndef LOGD
+#define LOGD ALOGD
+#endif
+#ifndef LOGV
+#define LOGV ALOGV
+#endif
+#ifndef LOGE
+#define LOGE ALOGE
+#endif
+#ifndef LOGI
+#define LOGI ALOGI
+#endif
+/*****************************************************************************/
+int main(int argc, char **argv) {
+ aml_screen_module_t* mModule;
+ aml_screen_device_t* mDev;
+ int ret = 0;
+ int dumpfd;
+ char * pSrcBufffer;
+ int i = 100;
+
+ if (hw_get_module(AML_SCREEN_HARDWARE_MODULE_ID,
+ (const hw_module_t **)&mModule) < 0)
+ {
+ LOGE("can not get screen source module");
+ ret = -1;
+ }
+ else
+ {
+ LOGV("succeed to get screen source module");
+ mModule->common.methods->open((const hw_module_t *)mModule,
+ AML_SCREEN_SOURCE, (struct hw_device_t**)&mDev);
+ //do test here, we can use ops of mDev to operate vdin source
+ }
+
+ mDev->ops.start(mDev);
+
+ dumpfd = open("/tmp/yuvsource", O_CREAT | O_RDWR | O_TRUNC, 0644);
+ LOGV("dumpfd:%d\n");
+
+ while(i--)
+ {
+ pSrcBufffer = mDev->ops.aquire_buffer(mDev);
+
+ write(dumpfd, pSrcBufffer, 640*480*3/2);
+
+ //usleep(100000);
+ LOGV("release_buffer %x pSrcBufffer:%x", mDev->ops.release_buffer, pSrcBufffer);
+ mDev->ops.release_buffer(mDev);
+ }
+
+ mDev->ops.stop(mDev);
+
+ return ret;
+}
+/*****************************************************************************/
diff --git a/v4l2_vdin.cpp b/v4l2_vdin.cpp
new file mode 100755
index 0000000..48a9d54
--- a/dev/null
+++ b/v4l2_vdin.cpp
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * 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.
+ */
+
+
+//reinclude because of a bug with the log macros
+#define LOG_NDEBUG 0
+#define LOG_TAG "V4L2VINSOURCE"
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/select.h>
+#include <linux/videodev.h>
+#include <sys/time.h>
+
+#include <cutils/properties.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "v4l2_vdin.h"
+
+namespace android {
+
+vdin_screen_source::vdin_screen_source()
+ : mCameraHandle(-1),
+ mVideoInfo(NULL)
+{
+ mCameraHandle = open("/dev/video11", O_RDWR);
+ if (mCameraHandle < 0)
+ {
+ ALOGE("[%s %d] mCameraHandle:%x", __FUNCTION__, __LINE__, mCameraHandle);
+ }
+ mVideoInfo = (struct VideoInfo *) calloc (1, sizeof (struct VideoInfo));
+ if (mVideoInfo == NULL)
+ {
+ ALOGE("[%s %d] no memory for mVideoInfo", __FUNCTION__, __LINE__);
+ }
+}
+
+vdin_screen_source::~vdin_screen_source()
+{
+ if (mCameraHandle >= 0)
+ {
+ close(mCameraHandle);
+ }
+ if (mVideoInfo)
+ {
+ free (mVideoInfo);
+ }
+}
+
+int vdin_screen_source::start()
+{
+ int ret = -1;
+
+ ALOGV("[%s %d] mCameraHandle:%x", __FUNCTION__, __LINE__, mCameraHandle);
+
+ ioctl(mCameraHandle, VIDIOC_QUERYCAP, &mVideoInfo->cap);
+
+ mVideoInfo->rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ mVideoInfo->rb.memory = V4L2_MEMORY_MMAP;
+ mVideoInfo->rb.count = NB_BUFFER;
+
+ ret = ioctl(mCameraHandle, VIDIOC_REQBUFS, &mVideoInfo->rb);
+
+ if (ret < 0) {
+ ALOGE("[%s %d] VIDIOC_REQBUFS:%d mCameraHandle:%x", __FUNCTION__, __LINE__, ret, mCameraHandle);
+ return ret;
+ }
+
+ for (int i = 0; i < NB_BUFFER; i++) {
+ memset (&mVideoInfo->buf, 0, sizeof (struct v4l2_buffer));
+
+ mVideoInfo->buf.index = i;
+ mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ mVideoInfo->buf.memory = V4L2_MEMORY_MMAP;
+
+ ret = ioctl (mCameraHandle, VIDIOC_QUERYBUF, &mVideoInfo->buf);
+ if (ret < 0) {
+ ALOGE("[%s %d]VIDIOC_QUERYBUF %d failed", __FUNCTION__, __LINE__, i);
+ return ret;
+ }
+ mVideoInfo->mem[i] = mmap (0, mVideoInfo->buf.length, PROT_READ | PROT_WRITE,
+ MAP_SHARED, mCameraHandle, mVideoInfo->buf.m.offset);
+
+ if (mVideoInfo->mem[i] == MAP_FAILED) {
+ ALOGE("[%s %d] MAP_FAILED", __FUNCTION__, __LINE__);
+ return -1;
+ }
+
+ mBufs.add((int)mVideoInfo->mem[i], i);
+ }
+ ALOGV("[%s %d] VIDIOC_QUERYBUF successful", __FUNCTION__, __LINE__);
+
+ for (int i = 0; i < NB_BUFFER; i++) {
+ mVideoInfo->buf.index = i;
+ mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ mVideoInfo->buf.memory = V4L2_MEMORY_MMAP;
+ ret = ioctl(mCameraHandle, VIDIOC_QBUF, &mVideoInfo->buf);
+ if (ret < 0) {
+ ALOGE("VIDIOC_QBUF Failed");
+ return -1;
+ }
+ }
+ enum v4l2_buf_type bufType;
+ bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+ ret = ioctl (mCameraHandle, VIDIOC_STREAMON, &bufType);
+
+ ALOGV("[%s %d] VIDIOC_STREAMON:%x", __FUNCTION__, __LINE__, ret);
+
+ return ret;
+}
+
+int vdin_screen_source::stop()
+{
+ int ret;
+ enum v4l2_buf_type bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+ ret = ioctl (mCameraHandle, VIDIOC_STREAMOFF, &bufType);
+ if (ret < 0) {
+ ALOGE("StopStreaming: Unable to stop capture: %s", strerror(errno));
+ }
+ for (int i = 0; i < NB_BUFFER; i++)
+ {
+ if (munmap(mVideoInfo->mem[i], mVideoInfo->buf.length) < 0)
+ ALOGE("Unmap failed");
+ }
+ return ret;
+}
+
+int vdin_screen_source::get_format()
+{
+ return 0;
+}
+
+int vdin_screen_source::set_format(int width, int height, int color_format)
+{
+ ALOGV("[%s %d]", __FUNCTION__, __LINE__);
+ int ret;
+
+ mVideoInfo->width = width;
+ mVideoInfo->height = height;
+ mVideoInfo->framesizeIn = (width * height << 1); //note color format
+ mVideoInfo->formatIn = color_format;
+
+ mVideoInfo->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ mVideoInfo->format.fmt.pix.width = width;
+ mVideoInfo->format.fmt.pix.height = height;
+ mVideoInfo->format.fmt.pix.pixelformat = color_format;
+
+ ret = ioctl(mCameraHandle, VIDIOC_S_FMT, &mVideoInfo->format);
+ if (ret < 0) {
+ ALOGE("[%s %d]VIDIOC_S_FMT %d", __FUNCTION__, __LINE__, ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+
+char* vdin_screen_source::aquire_buffer()
+{
+ int ret = -1;
+
+ mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ mVideoInfo->buf.memory = V4L2_MEMORY_MMAP;
+
+ ret = ioctl(mCameraHandle, VIDIOC_DQBUF, &mVideoInfo->buf);
+
+ return (char *)mVideoInfo->mem[mVideoInfo->buf.index];
+}
+
+int vdin_screen_source::release_buffer(char* ptr)
+{
+ int ret = -1;
+ int CurrentIndex;
+ v4l2_buffer hbuf_query;
+ memset(&hbuf_query,0,sizeof(v4l2_buffer));
+
+ CurrentIndex = mBufs.valueFor(( unsigned int )ptr);
+ hbuf_query.index = CurrentIndex;
+ hbuf_query.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ hbuf_query.memory = V4L2_MEMORY_MMAP;
+ ret = ioctl(mCameraHandle, VIDIOC_QBUF, &hbuf_query);
+
+ return 0;
+}
+
+}
diff --git a/v4l2_vdin.h b/v4l2_vdin.h
new file mode 100755
index 0000000..4dca247
--- a/dev/null
+++ b/v4l2_vdin.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * 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 <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/select.h>
+#include <linux/videodev.h>
+#include <sys/time.h>
+
+#include <utils/KeyedVector.h>
+#include <cutils/properties.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+namespace android {
+
+#define NB_BUFFER 4
+
+struct VideoInfo {
+ struct v4l2_capability cap;
+ struct v4l2_format format;
+ struct v4l2_buffer buf;
+ struct v4l2_requestbuffers rb;
+ void *mem[NB_BUFFER];
+ bool isStreaming;
+ int width;
+ int height;
+ int formatIn;
+ int framesizeIn;
+};
+
+class vdin_screen_source {
+ public:
+ vdin_screen_source();
+ ~vdin_screen_source();
+
+ int start();
+ int stop();
+ int get_format();
+ int set_format(int width = 640, int height = 480, int color_format = V4L2_PIX_FMT_NV21);
+ char * aquire_buffer();
+ int release_buffer(char* ptr);
+ private:
+ int mCurrentIndex;
+ KeyedVector<int, int> mBufs;
+ int mCameraHandle;
+ struct VideoInfo *mVideoInfo;
+};
+
+} \ No newline at end of file