author | niko.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) |
commit | b6f235731a87516c52cc7c9e4c55ae888b3e671b (patch) | |
tree | a82186a3dcd124986432d70317439b003948a166 | |
download | screen_source-b6f235731a87516c52cc7c9e4c55ae888b3e671b.zip screen_source-b6f235731a87516c52cc7c9e4c55ae888b3e671b.tar.gz screen_source-b6f235731a87516c52cc7c9e4c55ae888b3e671b.tar.bz2 |
Init screen_source.---Zefeng.Tong.
-rwxr-xr-x | Android.mk | 18 | ||||
-rwxr-xr-x | aml_screen.cpp | 188 | ||||
-rwxr-xr-x | test/Android.mk | 16 | ||||
-rwxr-xr-x | test/screen_source_test.cpp | 91 | ||||
-rwxr-xr-x | v4l2_vdin.cpp | 211 | ||||
-rwxr-xr-x | v4l2_vdin.h | 69 |
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 |