author | Xiaoliang Wang <xiaoliang.wang@amlogic.com> | 2017-03-26 05:17:45 (GMT) |
---|---|---|
committer | Xiaoliang Wang <xiaoliang.wang@amlogic.com> | 2017-03-31 08:14:03 (GMT) |
commit | b58c2ae8d751d514f9f2b78f0e173127cf706e4c (patch) | |
tree | d7e050f42313596840771391497b8b77382f8b0a | |
parent | 5ec68edad5177f88b64a39d1ce613e1e673cde62 (diff) | |
download | SubTitle-b58c2ae8d751d514f9f2b78f0e173127cf706e4c.zip SubTitle-b58c2ae8d751d514f9f2b78f0e173127cf706e4c.tar.gz SubTitle-b58c2ae8d751d514f9f2b78f0e173127cf706e4c.tar.bz2 |
PD #140984: add socket to get raw data from amgeneric source
Change-Id: Iaf0fade3aa916553a480be94ff10cf2f7aced5a4
-rw-r--r-- | jni/subtitle/Android.mk | 2 | ||||
-rw-r--r-- | jni/subtitle/sub_control.c | 2 | ||||
-rw-r--r-- | jni/subtitle/sub_control.h | 12 | ||||
-rw-r--r-- | jni/subtitle/sub_dvb_sub.c | 15 | ||||
-rw-r--r-- | jni/subtitle/sub_io.cpp | 86 | ||||
-rw-r--r-- | jni/subtitle/sub_io.h | 38 | ||||
-rw-r--r-- | jni/subtitle/sub_jni.c | 22 | ||||
-rw-r--r-- | jni/subtitle/sub_pgs_sub.c | 27 | ||||
-rw-r--r-- | jni/subtitle/sub_set_sys.c | 34 | ||||
-rw-r--r-- | jni/subtitle/sub_socket.cpp | 303 | ||||
-rw-r--r-- | jni/subtitle/sub_socket.h | 50 | ||||
-rw-r--r-- | jni/subtitle/sub_subtitle.c | 66 | ||||
-rw-r--r-- | jni/subtitle/sub_vob_sub.c | 3 | ||||
-rw-r--r-- | src/com/droidlogic/SubTitleService/ISubTitleService.aidl | 1 | ||||
-rw-r--r-- | src/com/droidlogic/SubTitleService/SubTitleService.java | 28 | ||||
-rw-r--r-- | src/com/subtitleparser/Subtitle.java | 17 | ||||
-rw-r--r-- | src/com/subtitleview/SubManager.java | 18 | ||||
-rw-r--r-- | src/com/subtitleview/SubtitleView.java | 12 |
18 files changed, 667 insertions, 69 deletions
diff --git a/jni/subtitle/Android.mk b/jni/subtitle/Android.mk index 078d795..7a09e42 100644 --- a/jni/subtitle/Android.mk +++ b/jni/subtitle/Android.mk @@ -4,7 +4,7 @@ include $(CLEAR_VARS) LOCAL_MODULE := libsubjni LOCAL_MODULE_TAGS := optional -LOCAL_SRC_FILES := sub_jni.c sub_api.c log_print.c sub_subtitle.c sub_vob_sub.c sub_set_sys.c vob_sub.c sub_pgs_sub.c sub_control.c avi_sub.c sub_dvb_sub.c amsysfsutils.c Amsyswrite.cpp MemoryLeakTrackUtilTmp.cpp +LOCAL_SRC_FILES := sub_jni.c sub_api.c log_print.c sub_subtitle.c sub_vob_sub.c sub_set_sys.c vob_sub.c sub_pgs_sub.c sub_control.c avi_sub.c sub_dvb_sub.c amsysfsutils.c Amsyswrite.cpp MemoryLeakTrackUtilTmp.cpp sub_socket.cpp sub_io.cpp LOCAL_ARM_MODE := arm LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) \ $(TOP)/frameworks/native/services \ diff --git a/jni/subtitle/sub_control.c b/jni/subtitle/sub_control.c index 1b24c37..d08415b 100644 --- a/jni/subtitle/sub_control.c +++ b/jni/subtitle/sub_control.c @@ -37,7 +37,7 @@ int subtitle_get_sub_size_fd(int sub_fd) return sub_size; } -int subtitle_read_sub_data_fd(int sub_fd, char *buf, unsigned int length) +int subtitle_read_sub_data_fd(int sub_fd, char *buf, int length) { int data_size = length, r, read_done = 0; while (data_size) diff --git a/jni/subtitle/sub_control.h b/jni/subtitle/sub_control.h index 719780a..71b75d0 100644 --- a/jni/subtitle/sub_control.h +++ b/jni/subtitle/sub_control.h @@ -1,7 +1,17 @@ #ifndef _SUB_CONTROL_H_ #define _SUB_CONTROL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + int subtitle_poll_sub_fd(int sub_fd, int timeout); int subtitle_get_sub_size_fd(int sub_fd); -int subtitle_read_sub_data_fd(int sub_fd, char *buf, unsigned int length); +int subtitle_read_sub_data_fd(int sub_fd, char *buf, int length); int update_read_pointer(int sub_handle, int flag); + +#ifdef __cplusplus +} +#endif + #endif diff --git a/jni/subtitle/sub_dvb_sub.c b/jni/subtitle/sub_dvb_sub.c index 583f228..9d58b07 100644 --- a/jni/subtitle/sub_dvb_sub.c +++ b/jni/subtitle/sub_dvb_sub.c @@ -9,6 +9,7 @@ #include "sub_dvb_sub.h" #include "sub_subtitle.h" +#include "sub_io.h" static unsigned SPU_RD_HOLD_SIZE = 0x20; #define OSD_HALF_SIZE (1920*1280/8) @@ -1851,14 +1852,14 @@ static int read_spu_buf(int read_handle, char *buf, int len) LOGI("read_spu_buf len = %d\n", len); if (len > 3 * 1024 * 1024) abort(); - subtitle_read_sub_data_fd(read_handle, buf, len); + getData(read_handle, buf, len); return len; } /* check subtitle hw buffer has enough data to read */ static int check_sub_buffer_length(int read_handle, int size) { - int ret = subtitle_get_sub_size_fd(read_handle); + int ret = getSize(read_handle); LOGI("[check_sub_buffer_length]read_handle:%d, size:%d, sub buffer level = %d \n", read_handle, size, ret); if (ret >= size) return 1; @@ -1883,10 +1884,9 @@ int get_dvb_spu(AML_SPUVAR *spu, int read_handle) dvb_packet_length = dvb_pes_header_length = 0; packet_header = 0; skip_packet_flag = 0; - if ((subtitle_get_sub_size_fd(read_handle)) < SPU_RD_HOLD_SIZE) + if (getSize(read_handle) < SPU_RD_HOLD_SIZE) { - LOGI("current dvb sub buffer size %d\n", - (subtitle_get_sub_size_fd(read_handle))); + LOGI("current dvb sub buffer size %d\n", getSize(read_handle)); break; } while (read_spu_buf(read_handle, tmpbuf, 1) == 1) @@ -1898,8 +1898,7 @@ int get_dvb_spu(AML_SPUVAR *spu, int read_handle) LOGI("## 222 get_dvb_spu hardware demux dvb %x,%llx,-----------\n", tmpbuf[0], packet_header & 0xffffffffff); break; } - else if ((packet_header & 0xffffffffff) == - 0x414d4c55aa) + else if ((packet_header & 0xffffffffff) == 0x414d4c5577 || (packet_header & 0xffffffffff) == 0x414d4c55aa) { LOGI("## 222 get_dvb_spu soft demux dvb %x,%llx,-----------\n", tmpbuf[0], packet_header & 0xffffffffff); goto aml_soft_demux; @@ -2154,7 +2153,7 @@ int get_dvb_spu(AML_SPUVAR *spu, int read_handle) } } aml_soft_demux: - if ((packet_header & 0xffffffffff) == 0x414d4c55aa) + if ((packet_header & 0xffffffffff) == 0x414d4c5577 || (packet_header & 0xffffffffff) == 0x414d4c55aa) { int data_len = 0; char *data = NULL; diff --git a/jni/subtitle/sub_io.cpp b/jni/subtitle/sub_io.cpp new file mode 100644 index 0000000..bc6bac1 --- a/dev/null +++ b/jni/subtitle/sub_io.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2010 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_TAG "sub_io" + +#include "sub_io.h" +#include "sub_socket.h" +#include "sub_control.h" + +//for dev +int pollFd(int sub_fd, int timeout) { + int ret = -1; + + if (mIOType == IO_TYPE_DEV) { + ret = subtitle_poll_sub_fd(sub_fd, timeout); + } + + return ret; +} + +//for socket +void startSocketServer() { + //if (mIOType == IO_TYPE_SOCKET) { + startServer(); + //} +} + +void stopSocketServer() { + //if (mIOType == IO_TYPE_SOCKET) { + stopServer(); + //} +} + +int getInfo(int type) { + int ret = -1; + + if (mIOType == IO_TYPE_SOCKET) { + ret = getInfoBySkt(type); + } + + return ret; +} + +//for common +int getSize(int sub_fd) { + int ret = -1; + + if (mIOType == IO_TYPE_DEV) { + ret = subtitle_get_sub_size_fd(sub_fd); + } + else if (mIOType == IO_TYPE_SOCKET) { + ret = getSizeBySkt(); + } + + return ret; +} + +void getData(int sub_fd, char *buf, int size) { + if (mIOType == IO_TYPE_DEV) { + subtitle_read_sub_data_fd(sub_fd, buf, size); + } + else if (mIOType == IO_TYPE_SOCKET) { + getDataBySkt(buf, size); + } +} + +void setIOType(IOType type) { + mIOType = type; +} + +IOType getIOType() { + return mIOType; +} diff --git a/jni/subtitle/sub_io.h b/jni/subtitle/sub_io.h new file mode 100644 index 0000000..24ae813 --- a/dev/null +++ b/jni/subtitle/sub_io.h @@ -0,0 +1,38 @@ +#ifndef SUB_IO_H +#define SUB_IO_H + +#define TYPE_TOTAL 1 +#define TYPE_STARTPTS 2 +#define TYPE_SUBTYPE 3 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + IO_TYPE_DEV = 0, + IO_TYPE_SOCKET = 1, + IO_TYPE_END = 0xFF, +} IOType; + +IOType mIOType; + +//for dev +int pollFd(int sub_fd, int timeout); + +//for socket +void startSocketServer(); +void stopSocketServer(); +int getInfo(int type); + +// for common +int getSize(int sub_fd); +void getData(int sub_fd, char *buf, int size); +void setIOType(IOType type); +IOType getIOType(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/jni/subtitle/sub_jni.c b/jni/subtitle/sub_jni.c index 106a7df..03b313f 100644 --- a/jni/subtitle/sub_jni.c +++ b/jni/subtitle/sub_jni.c @@ -14,6 +14,7 @@ #include "sub_subtitle.h" #include "sub_set_sys.h" #include "vob_sub.h" +#include "sub_io.h" #define LOG_TAG "sub_jni" #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) @@ -644,6 +645,24 @@ JNIEXPORT void JNICALL startSubThread(JNIEnv *env, jclass cl) } } +JNIEXPORT void JNICALL startSubServer(JNIEnv *env, jclass cl) +{ + LOGI("start tcpserver"); + startSocketServer(); +} + +JNIEXPORT void JNICALL stopSubServer(JNIEnv *env, jclass cl) +{ + LOGI("stop tcpserver"); + stopSocketServer(); +} + +JNIEXPORT void JNICALL setSubIOType(JNIEnv *env, jclass cl, jint type) +{ + LOGI("setIOType"); + setIOType(type); +} + JNIEXPORT void JNICALL stopSubThread(JNIEnv *env, jclass cl) { if (subThreadRunning == 1) @@ -669,6 +688,9 @@ static JNINativeMethod gMethods[] = {"startSubThreadByJni", "()V", (void *)startSubThread}, {"stopSubThreadByJni", "()V", (void *)stopSubThread}, { "resetForSeekByjni", "()V",(void*) resetForSeek}, + { "startSubServerByJni", "()V",(void*) startSubServer}, + { "stopSubServerByJni", "()V",(void*) stopSubServer}, + { "setIOTypeByJni", "(I)V",(void*) setSubIOType}, }; static JNINativeMethod insubMethods[] = diff --git a/jni/subtitle/sub_pgs_sub.c b/jni/subtitle/sub_pgs_sub.c index 42a0535..35cd51b 100644 --- a/jni/subtitle/sub_pgs_sub.c +++ b/jni/subtitle/sub_pgs_sub.c @@ -13,7 +13,9 @@ #include "sub_subtitle.h" #include "sub_pgs_sub.h" #include "vob_sub.h" -#include "sub_control.h" +//#include "sub_control.h" + +#include "sub_io.h" #define LOG_TAG "sub_pgs" #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) @@ -60,16 +62,14 @@ static int read_spu_byte(int read_handle, char *byte) } else { - if ((subtitle_get_sub_size_fd(read_handle)) < SPU_RD_HOLD_SIZE) + if (getSize(read_handle) < SPU_RD_HOLD_SIZE) { - LOGI("current pgs sub buffer size %d\n", - (subtitle_get_sub_size_fd(read_handle))); + LOGI("current pgs sub buffer size %d\n", getSize(read_handle)); ret = 0; } else { - subtitle_read_sub_data_fd(read_handle, - &(uVobSPU.spu_cache[0]), 8); + getData(read_handle, &(uVobSPU.spu_cache[0]), 8); int i = 0; for (i = 0; i < 4; i++) { @@ -96,7 +96,7 @@ static int read_spu_buf(int read_handle, char *buf, int len) break; } #endif - subtitle_read_sub_data_fd(read_handle, buf, len); + getData(read_handle, buf, len); read_pgs_byte += len; return len; } @@ -557,10 +557,9 @@ DECODE_START: pgs_packet_length = pgs_pes_header_length = 0; packet_header = 0; skip_packet_flag = 0; - if ((subtitle_get_sub_size_fd(read_handle)) < SPU_RD_HOLD_SIZE) + if (getSize(read_handle) < SPU_RD_HOLD_SIZE) { - LOGI("current pgs sub buffer size %d\n", - (subtitle_get_sub_size_fd(read_handle))); + LOGI("current pgs sub buffer size %d\n", getSize(read_handle)); break; } uVobSPU.spu_cache_pos = 0; @@ -577,8 +576,7 @@ DECODE_START: LOGI("## 222 get_pgs_spu hardware demux pgs %x,%llx,-----------\n", tmpbuf[0], packet_header & 0xffffffffff); break; } - else if ((packet_header & 0xffffffffff) == - 0x414d4c55aa) + else if ((packet_header & 0xffffffffff) == 0x414d4c5577 || (packet_header & 0xffffffffff) == 0x414d4c55aa) { LOGI("## 222 get_pgs_spu soft demux pgs %x,%llx,-----------\n", tmpbuf[0], packet_header & 0xffffffffff); goto aml_soft_demux; @@ -799,8 +797,7 @@ DECODE_START: LOGI("pgs_packet_length is %d\n", pgs_packet_length); subtitle_pgs.showdata.pts = pgs_dts; - if (subtitle_get_sub_size_fd - (read_handle) < pgs_packet_length || + if (getSize(read_handle) < pgs_packet_length || subtitle_status == SUB_STOP) { pgs_ret = 0; @@ -852,7 +849,7 @@ DECODE_START: } } aml_soft_demux: - if ((packet_header & 0xffffffffff) == 0x414d4c55aa) + if ((packet_header & 0xffffffffff) == 0x414d4c5577 || (packet_header & 0xffffffffff) == 0x414d4c55aa) { int read_data_len = 0, data_len = 0; int pgs_packet_type = 0; diff --git a/jni/subtitle/sub_set_sys.c b/jni/subtitle/sub_set_sys.c index 75d4831..1889d3e 100644 --- a/jni/subtitle/sub_set_sys.c +++ b/jni/subtitle/sub_set_sys.c @@ -11,6 +11,7 @@ #include "linux/ioctl.h" #include "amstream.h" #include <Amsysfsutils.h> +#include "sub_io.h" #define CODEC_AMSUBTITLE_DEVICE "/dev/amsubtitle" @@ -46,7 +47,16 @@ int get_subtitle_enable() int get_subtitle_num() { - return get_sysfs_int("/sys/class/subtitle/total"); + int ret = 0; + + if (getIOType() == IO_TYPE_DEV) { + ret = get_sysfs_int("/sys/class/subtitle/total"); + } + else if (getIOType() == IO_TYPE_SOCKET) { + ret = getInfo(TYPE_TOTAL); + } + + return ret; } int get_subtitle_language(char *valstr, int size) @@ -92,7 +102,16 @@ int get_subtitle_data() int get_subtitle_startpts() { - return get_sysfs_int("/sys/class/subtitle/startpts"); + int ret = 0; + + if (getIOType() == IO_TYPE_DEV) { + ret = get_sysfs_int("/sys/class/subtitle/startpts"); + } + else if (getIOType() == IO_TYPE_SOCKET) { + ret = getInfo(TYPE_STARTPTS); + } + + return ret; } int get_subtitle_fps() @@ -102,5 +121,14 @@ int get_subtitle_fps() int get_subtitle_subtype() { - return get_sysfs_int("/sys/class/subtitle/subtype"); + int ret = 0; + + if (getIOType() == IO_TYPE_DEV) { + ret = get_sysfs_int("/sys/class/subtitle/subtype"); + } + else if (getIOType() == IO_TYPE_SOCKET) { + ret = getInfo(TYPE_SUBTYPE); + } + + return ret; } diff --git a/jni/subtitle/sub_socket.cpp b/jni/subtitle/sub_socket.cpp new file mode 100644 index 0000000..6a4d0ad --- a/dev/null +++ b/jni/subtitle/sub_socket.cpp @@ -0,0 +1,303 @@ +/* + * Copyright (C) 2010 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 "sub_socket" + +#include <fcntl.h> +#include <utils/Log.h> +#include <binder/IPCThreadState.h> +#include <binder/IServiceManager.h> +#include <binder/PermissionCache.h> +#include <stdint.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <stdio.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <unistd.h> +#include <string.h> +#include <stdlib.h> +#include <sys/poll.h> +#include <sys/un.h> +#include <errno.h> +#include <sys/stat.h> +#include<pthread.h> + +#include "sub_socket.h" + +//using namespace android; + +/** + * Safe copy for loop buffer, check edge before copy + * @param + * sPtr : loop buffer start pointer + * mWPtr : current write pointer + * mRPtr : current read pointer + * src : source data for copy + * size : source data size + */ +void safeCopy(char* sPtr, char* src, int size) { + char* ptrStart = sPtr; + char* ptrEnd = sPtr + LOOP_BUFFER_SIZE; + int leftReg = 0;//from nearest wptr to ptrEnd + + //skip case for data recover, which means write ptr is 256*1024 bigger than read ptr + leftReg = ptrEnd - mWPtr; + ALOGI("[safeCopy]sPtr:0x%x, mWPtr:0x%x, mRPtr:0x%x, size:%d, leftReg:%d\n", sPtr, mWPtr, mRPtr, size, leftReg); + if (leftReg >= size) { + memcpy(mWPtr, src, size); + mWPtr += size; + } + else { + memcpy(mWPtr, src, leftReg); + mWPtr = sPtr; + memcpy(mWPtr, (src + leftReg), (size - leftReg)); + mWPtr += (size - leftReg); + } +} + +void safeRead(char* sPtr, char* des, int size) { + char* ptrStart = sPtr; + char* ptrEnd = sPtr + LOOP_BUFFER_SIZE; + int leftReg = 0;//from nearest rptr to ptrEnd + + leftReg = ptrEnd - mRPtr; + ALOGI("[safeRead]sPtr:0x%x,mWPtr:0x%x, mRPtr:0x%x, size:%d, leftReg:%d\n", sPtr, mWPtr, mRPtr, size, leftReg); + if (leftReg >= size) { + memcpy(des, mRPtr, size); + mRPtr += size; + } + else { + memcpy(des, mRPtr, leftReg); + mRPtr = sPtr; + memcpy((des + leftReg), mRPtr, (size - leftReg)); + mRPtr += (size - leftReg); + } +} + +int getDataSize(char* sPtr) { + char* ptrStart = sPtr; + char* ptrEnd = sPtr + LOOP_BUFFER_SIZE; + int size = 0; + + if (mWPtr >= mRPtr) { + size = mWPtr - mRPtr; + } + else { + size = (ptrEnd - mRPtr) + (mWPtr - ptrStart); + } + ALOGI("[getDataSize]mWPtr:0x%x, mRPtr:0x%x, size:%d\n", mWPtr, mRPtr, size); + + return size; +} + +void* startServerThread(void* arg) { + struct sockaddr_in addr; + memset((void *)&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(LISTEN_PORT); + addr.sin_addr.s_addr = htonl(INADDR_ANY); + mSockFd = socket(AF_INET, SOCK_STREAM, 0); + + mStop = 0; + mLoopBuf = NULL; + /*mSockFd = socket(AF_UNIX, SOCK_STREAM, 0); + struct sockaddr_un addr; + addr.sun_family = AF_UNIX; + snprintf(addr.sun_path, sizeof(addr.sun_path), "/dev/socket/sub_socket"); + int ret = unlink(addr.sun_path); + if (ret != 0 && errno != ENOENT) { + ALOGE("Failed to unlink old socket '%s': %s\n", addr.sun_path, strerror(errno)); + return NULL; + }*/ + if (bind(mSockFd,(struct sockaddr *)&addr,sizeof(addr)) == -1) { + ALOGE("bind fail. error=%d, err:%s\n", errno, strerror(errno)); + return NULL; + } + /*if (fchmodat(AT_FDCWD, addr.sun_path, (mode_t)0666, AT_SYMLINK_NOFOLLOW)) { + ALOGE("fchmodat %s fail.error=%d, err:%s\n", addr.sun_path, errno, strerror(errno)); + return NULL;; + }*/ + if (listen(mSockFd, QUEUE_SIZE) == -1) { + ALOGE("listen fail.error=%d, err:%s\n", errno, strerror(errno)); + return NULL;; + } + ALOGI("[startServerThread]listen success.\n"); + while (mStop != 1) { + struct sockaddr_in client_addr; + socklen_t length = sizeof(client_addr); + int connFd = accept(mSockFd, (struct sockaddr*)&client_addr, &length); + if (client_num++ > 9) { + client_num= 9; + close(mSockFd); + ALOGI("client number is limited"); + continue; + } + if (connFd < 0) { + ALOGE("client connect fail.error=%d, err:%s\n", errno, strerror(errno)); + exit(1); + } + ALOGI("new client accepted.\n"); + child_connect(connFd); + /*pid_t childid; + if (childid = fork() == 0) { + ALOGI("child process: %d created.\n", getpid()); + close(mSockFd); + child_connect(connFd); + exit(0); + }*/ + } + ALOGI("closed.\n"); + close(mSockFd); + return NULL; +} + +void child_connect(int sockfd) { + char recvBuf[BUFFER_SIZE] = {0}; + char sendBuf[32] = {0}; + int retLen = 0; + char retLenStr[32] = {0}; + + if (mLoopBuf == NULL) { + mLoopBuf = (char *)malloc(LOOP_BUFFER_SIZE); + memset(mLoopBuf, 0, LOOP_BUFFER_SIZE); + mRPtr = mLoopBuf; + mWPtr = mLoopBuf; + } + + pid_t pid = getpid(); + client_list[client_num] = sockfd; + while (mStop != 1) { + retLen = recv(sockfd, recvBuf, sizeof(recvBuf), 0); + if (retLen < 0) { + ALOGE("child recv fail, retLen: %d\n", retLen); + break; + } + if (!strncmp(recvBuf,"exit\n", 5)) { + ALOGI("child process: %d exited.\n", pid); + break; + } + if (!strncmp(recvBuf,"reset\n", 6)) { + ALOGI("child process: %d reset.\n", pid); + resetSocketBuffer(); + continue; + } + + if (recvBuf[0] == 0x53 + && recvBuf[1] == 0x54 + && recvBuf[2] == 0x4F + && recvBuf[3] == 0x54 + && mTotal < 0) {//STOT + mTotal = (recvBuf[4] << 24) + | (recvBuf[5] << 16) + | (recvBuf[6] << 8) + | recvBuf[7]; + ALOGI("child recv, mTotal:%d\n", mTotal); + } + else if (recvBuf[0] == 0x53 + && recvBuf[1] == 0x50 + && recvBuf[2] == 0x54 + && recvBuf[3] == 0x53 + && mStartPts < 0) {//SPTS + mStartPts = (recvBuf[4] << 24) + | (recvBuf[5] << 16) + | (recvBuf[6] << 8) + | recvBuf[7]; + ALOGI("child recv, mStartPts:%d\n", mStartPts); + } + else if (recvBuf[0] == 0x53 + && recvBuf[1] == 0x54 + && recvBuf[2] == 0x59 + && recvBuf[3] == 0x50 + && mType < 0) {//STYP + mType = (recvBuf[4] << 24) + | (recvBuf[5] << 16) + | (recvBuf[6] << 8) + | recvBuf[7]; + ALOGI("child recv, mType:%d\n", mType); + } + else/* if (recvBuf[0] == 'A' && recvBuf[1] == 'M' && recvBuf[2] == 'L') */{ + safeCopy(mLoopBuf, recvBuf, retLen); + } + + // reveived buffer length send to client + /*memset(sendBuf, 0, 32); + memset(retLenStr, 0, 32); + strcat(sendBuf, "server:received buf len:"); + sprintf(retLenStr, "%d", retLen); + strcat(sendBuf, retLenStr); + send(sockfd, sendBuf, 32, 0);*/ + } + close(sockfd); + client_num--; +} + +void startServer() { + mTotal = -1; + mStartPts = -1; + mType = -1; + + pthread_t sst; + pthread_create(&sst, NULL, startServerThread, NULL); + pthread_join(sst, NULL); +} + +void stopServer() { + mTotal = -1; + mStartPts = -1; + mType = -1; + mRPtr = mLoopBuf; + mWPtr = mLoopBuf; + if (mLoopBuf != NULL) { + free(mLoopBuf); + mLoopBuf = NULL; + } +} + +void resetSocketBuffer() { + mRPtr = mLoopBuf; + mWPtr = mLoopBuf; + if (mLoopBuf != NULL) { + memset(mLoopBuf, 0, LOOP_BUFFER_SIZE); + } +} + +int getSizeBySkt() { + return getDataSize(mLoopBuf); +} + +void getDataBySkt(char *buf, int size) { + safeRead(mLoopBuf, buf, size); +} + +int getInfoBySkt(int type) { + int ret = -1; + //ALOGI("[getInfo]mTotal:%d, mStartPts:%d,mType:%d\n", mTotal, mStartPts, mType); + switch (type) { + case 1: + ret = mTotal; + break; + case 2: + ret = mStartPts; + break; + case 3: + ret = mType; + break; + } + //ALOGI("[getInfo]type:%d, ret:%d\n", type, ret); + return ret; +} diff --git a/jni/subtitle/sub_socket.h b/jni/subtitle/sub_socket.h new file mode 100644 index 0000000..0f1ac74 --- a/dev/null +++ b/jni/subtitle/sub_socket.h @@ -0,0 +1,50 @@ +#ifndef SUB_SOCKET_H +#define SUB_SOCKET_H + +#include <stdint.h> + +#define TYPE_TOTAL 1 +#define TYPE_STARTPTS 2 +#define TYPE_SUBTYPE 3 + +#ifdef __cplusplus +extern "C" { +#endif + +#define QUEUE_SIZE 10 +#define BUFFER_SIZE 1024 +#define LOOP_BUFFER_SIZE 256*1024 +#define LISTEN_PORT 10100 + +static int mSockFd; +static int mStop; +static char *mLoopBuf; +static char *mRPtr; +static char *mWPtr; +static int mTotal; +static int mType; +static int64_t mStartPts; +static int64_t mSize; + +//client parameters +static int client_list[QUEUE_SIZE]; +static int client_num; + +static void* startServerThread(void* arg); +static void child_connect(int sockfd); +static void safeCopy(char* sPtr, char* src, int size); +void safeRead(char* sPtr, char* des, int size); +int getDataSize(char* sPtr); + +void startServer(); +void stopServer(); +int getSizeBySkt(); +void getDataBySkt(char *buf, int size); +int getInfoBySkt(int type); +void resetSocketBuffer(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/jni/subtitle/sub_subtitle.c b/jni/subtitle/sub_subtitle.c index 6642ff4..c0384c3 100644 --- a/jni/subtitle/sub_subtitle.c +++ b/jni/subtitle/sub_subtitle.c @@ -20,13 +20,15 @@ #include <android/log.h> #include "amstream.h" -#include "sub_control.h" +//#include "sub_control.h" #include "sub_subtitle.h" #include "sub_vob_sub.h" #include "sub_dvb_sub.h" #include "sub_pgs_sub.h" #include "sub_set_sys.h" +#include "sub_io.h" + typedef struct _DivXSubPictColor { char red; @@ -342,23 +344,25 @@ int get_spu(AML_SPUVAR *spu, int read_sub_fd) } if (read_sub_fd < 0) return 0; - ret = subtitle_poll_sub_fd(read_sub_fd, 10); - if (ret == 0) - { - //LOGI("codec_poll_sub_fd fail \n\n"); - ret = -1; - goto error; + + if (getIOType() == IO_TYPE_DEV) { + ret = pollFd(read_sub_fd, 10); + if (ret == 0) { + //LOGI("codec_poll_sub_fd fail \n\n"); + ret = -1; + goto error; + } } + if (get_subtitle_enable() == 0) { - size = subtitle_get_sub_size_fd(read_sub_fd); + size = getSize(read_sub_fd); if (size > 0) { char *buff = malloc(size); if (buff) { - subtitle_read_sub_data_fd(read_sub_fd, buff, - size); + getData(read_sub_fd, buff, size); free(buff); } } @@ -369,17 +373,17 @@ int get_spu(AML_SPUVAR *spu, int read_sub_fd) { //pgs subtitle sublen = 50; - size = subtitle_get_sub_size_fd(read_sub_fd); + size = getSize(read_sub_fd); LOGI("start pgs sub buffer size %d\n", size); int ret_spu = get_pgs_spu(spu, read_sub_fd); - size = subtitle_get_sub_size_fd(read_sub_fd); + size = getSize(read_sub_fd); LOGI("end pgs sub buffer size %d\n", size); return 0; } else if (get_subtitle_subtype() == 5) { sublen = 50; - size = subtitle_get_sub_size_fd(read_sub_fd); + size = getSize(read_sub_fd); LOGI("start dvb sub buffer size %d\n", size); int ret_spu = get_dvb_spu(spu, read_sub_fd); if (ret_spu == -1) @@ -389,11 +393,11 @@ int get_spu(AML_SPUVAR *spu, int read_sub_fd) subtitle_status = SUB_INIT; restlen = 0; } - size = subtitle_get_sub_size_fd(read_sub_fd); + size = getSize(read_sub_fd); LOGI("end dvb buffer size %d\n", size); return 0; } - size = subtitle_get_sub_size_fd(read_sub_fd); + size = getSize(read_sub_fd); if (size <= 0) { ret = -1; @@ -430,10 +434,7 @@ int get_spu(AML_SPUVAR *spu, int read_sub_fd) } else { - ret = - subtitle_read_sub_data_fd(read_sub_fd, - spu_buf_piece + restlen, - 16); + getData(read_sub_fd, spu_buf_piece + restlen, 16); sizeflag -= 16; spu_buf_tmp += 16; } @@ -442,17 +443,16 @@ int get_spu(AML_SPUVAR *spu, int read_sub_fd) || (spu_buf_piece[rd_oft++] != 0x4d) || (spu_buf_piece[rd_oft++] != 0x4c) || (spu_buf_piece[rd_oft++] != 0x55) - || ((spu_buf_piece[rd_oft++] & 0xfe) != 0xaa)) + /*|| ((spu_buf_piece[rd_oft++] & 0xfe) != 0xaa)*/) { LOGI("\n wrong subtitle header :%x %x %x %x %x %x %x %x %x %x %x %x \n", spu_buf_piece[0], spu_buf_piece[1], spu_buf_piece[2], spu_buf_piece[3], spu_buf_piece[4], spu_buf_piece[5], spu_buf_piece[6], spu_buf_piece[7], spu_buf_piece[8], spu_buf_piece[9], spu_buf_piece[10], spu_buf_piece[11]); - ret = - subtitle_read_sub_data_fd(read_sub_fd, - spu_buf_piece, sizeflag); + getData(read_sub_fd, spu_buf_piece, sizeflag); sizeflag = 0; LOGI("\n\n ******* find wrong subtitle header!! ******\n\n"); ret = -1; goto error; // wrong head } + rd_oft++;//0xaa or 0x77 LOGI("\n\n ******* find correct subtitle header ******\n\n"); current_type = spu_buf_piece[rd_oft++] << 16; current_type |= spu_buf_piece[rd_oft++] << 8; @@ -469,20 +469,14 @@ int get_spu(AML_SPUVAR *spu, int read_sub_fd) if (current_length > sizeflag) { LOGI("current_length > size"); - ret = - subtitle_read_sub_data_fd(read_sub_fd, - spu_buf_piece, sizeflag); + getData(read_sub_fd, spu_buf_piece, sizeflag); sizeflag = 0; ret = -1; goto error; } if (current_type == 0x17000 || current_type == 0x1700a) { - // ret = subtitle_read_sub_data_fd(read_sub_fd, spu_buf_piece+16, current_length); - ret = - subtitle_read_sub_data_fd(read_sub_fd, - spu_buf_piece + restlen + - 16, sizeflag - restlen); + getData(read_sub_fd, spu_buf_piece + restlen + 16, sizeflag - restlen); restlen = sizeflag; sizeflag = 0; spu_buf_tmp += current_length; @@ -490,10 +484,7 @@ int get_spu(AML_SPUVAR *spu, int read_sub_fd) } else { - ret = - subtitle_read_sub_data_fd(read_sub_fd, - spu_buf_piece + 16, - current_length + 4); + getData(read_sub_fd, spu_buf_piece + 16, current_length + 4); sizeflag -= (current_length + 4); spu_buf_tmp += (current_length + 4); restlen = 0; @@ -678,7 +669,7 @@ int get_spu(AML_SPUVAR *spu, int read_sub_fd) && (restbuf[1] == 0x4d) && (restbuf[2] == 0x4c) && (restbuf[3] == 0x55) - && (restbuf[4] == 0xaa)) + && ((restbuf[4] == 0xaa) || (restbuf[4] == 0x77))) { LOGI("## sub header found ! restbuf=%x,%x, ---\n", restbuf, restbuf[0]); sizeflag = restlen; @@ -1001,7 +992,7 @@ int get_inter_sub_type() int get_subtitle_buffer_size() { - return subtitle_get_sub_size_fd(aml_sub_handle); + return getSize(aml_sub_handle); } int get_inter_spu_size() @@ -1448,6 +1439,7 @@ int close_subtitle() } LOGI("start to close subtitle \n"); lp_lock(&sublock); + //resetSocketBuffer(); dvbsub_close_decoder(); close_pgs_subtitle(); if (restbuf) diff --git a/jni/subtitle/sub_vob_sub.c b/jni/subtitle/sub_vob_sub.c index 62819ca..c4b0e11 100644 --- a/jni/subtitle/sub_vob_sub.c +++ b/jni/subtitle/sub_vob_sub.c @@ -288,11 +288,12 @@ int get_vob_spu(char *spu_buf, int *bufsize, unsigned length, AML_SPUVAR *spu) || (spu_buf[rd_oft++] != 0x4d) || (spu_buf[rd_oft++] != 0x4c) || (spu_buf[rd_oft++] != 0x55) - || (spu_buf[rd_oft++] != 0xaa)) + /*|| (spu_buf[rd_oft++] != 0xaa)*/) { LOGI("## goto error ---------\n"); goto error; // wrong head } + rd_oft++;//0xaa or 0x77 rd_oft += 3; // 3 bytes for type current_length = spu_buf[rd_oft++] << 24; current_length |= spu_buf[rd_oft++] << 16; diff --git a/src/com/droidlogic/SubTitleService/ISubTitleService.aidl b/src/com/droidlogic/SubTitleService/ISubTitleService.aidl index faa626e..bfbede9 100644 --- a/src/com/droidlogic/SubTitleService/ISubTitleService.aidl +++ b/src/com/droidlogic/SubTitleService/ISubTitleService.aidl @@ -32,4 +32,5 @@ interface ISubTitleService String getSubLanguage(int idx); boolean load(String path); void setSurfaceViewParam(int x, int y, int w, int h); + void setIOType(int type); }
\ No newline at end of file diff --git a/src/com/droidlogic/SubTitleService/SubTitleService.java b/src/com/droidlogic/SubTitleService/SubTitleService.java index f48c25d..6558e0a 100644 --- a/src/com/droidlogic/SubTitleService/SubTitleService.java +++ b/src/com/droidlogic/SubTitleService/SubTitleService.java @@ -64,6 +64,7 @@ public class SubTitleService extends ISubTitleService.Stub { private static final int CLEAR = 0xFB; private static final int RESET_FOR_SEEK = 0xFC; private static final int LOAD = 0xFD; + private static final int SET_IO_TYPE = 0xFE; private static final int SUB_OFF = 0; private static final int SUB_ON = 1; private int subShowState = SUB_OFF; @@ -119,6 +120,12 @@ public class SubTitleService extends ISubTitleService.Stub { subTitleView.setTextStyle(Typeface.NORMAL); subTitleView.setViewStatus(true); + new Thread(new Runnable() { + public void run() { + subTitleView.startSocketServer(); + } + }).start(); + //prepare window mWindowManager = (WindowManager)mContext.getSystemService (Context.WINDOW_SERVICE); mDisplay = mWindowManager.getDefaultDisplay(); @@ -189,6 +196,13 @@ public class SubTitleService extends ISubTitleService.Stub { mSubtitleUtils.setSubtitleNumber(0); mSubtitleUtils = null; } + + new Thread(new Runnable() { + public void run() { + subTitleView.stopSocketServer(); + } + }).start(); + mSubTotal = -1; mSetSubId = -1; sendCloseMsg(); @@ -295,6 +309,10 @@ public class SubTitleService extends ISubTitleService.Stub { sendResetForSeekMsg(); } + public void setIOType(int type) { + sendSetIOTypeMsg(type); + } + public void option() { sendOptionMsg(); } @@ -452,6 +470,12 @@ public class SubTitleService extends ISubTitleService.Stub { mHandler.sendMessage(msg); } + private void sendSetIOTypeMsg(int type) { + Message msg = mHandler.obtainMessage(SET_IO_TYPE); + msg.arg1 = type; + mHandler.sendMessage(msg); + } + private void removeMsg() { mHandler.removeMessages(SHOW_CONTENT); mHandler.removeMessages(OPT_SHOW); @@ -799,6 +823,10 @@ public class SubTitleService extends ISubTitleService.Stub { } break; + case SET_IO_TYPE: + subTitleView.setIOType(msg.arg1); + break; + default: Log.e(TAG, "[handleMessage]error msg."); break; diff --git a/src/com/subtitleparser/Subtitle.java b/src/com/subtitleparser/Subtitle.java index f734328..4ffec79 100644 --- a/src/com/subtitleparser/Subtitle.java +++ b/src/com/subtitleparser/Subtitle.java @@ -146,6 +146,18 @@ public class Subtitle { stopSubThreadByJni(); } + public void startSocketServer() { + startSubServerByJni(); + } + + public void stopSocketServer() { + stopSubServerByJni(); + } + + public void setIOType(int type) { + setIOTypeByJni(type); + } + public void resetForSeek() { resetForSeekByjni(); } @@ -154,8 +166,9 @@ public class Subtitle { native void startSubThreadByJni(); native void stopSubThreadByJni(); native void resetForSeekByjni(); - - + native void startSubServerByJni(); + native void stopSubServerByJni(); + native void setIOTypeByJni(int type); /** * Parse a known type subtitle file into a SubtitleFile object. diff --git a/src/com/subtitleview/SubManager.java b/src/com/subtitleview/SubManager.java index 348d50d..ea0b6fa 100644 --- a/src/com/subtitleview/SubManager.java +++ b/src/com/subtitleview/SubManager.java @@ -47,6 +47,24 @@ public class SubManager { } } + public void startSocketServer() { + if (subtitle != null) { + subtitle.startSocketServer(); + } + } + + public void stopSocketServer() { + if (subtitle != null) { + subtitle.stopSocketServer(); + } + } + + public void setIOType(int type) { + if (subtitle != null) { + subtitle.setIOType(type); + } + } + public void loadSubtitleFile (String path, String enc) throws Exception { if (subapi != null) { if (subapi.type() == Subtitle.SUBTYPE.INSUB) { diff --git a/src/com/subtitleview/SubtitleView.java b/src/com/subtitleview/SubtitleView.java index a1d5440..beafa11 100644 --- a/src/com/subtitleview/SubtitleView.java +++ b/src/com/subtitleview/SubtitleView.java @@ -565,6 +565,18 @@ public class SubtitleView extends FrameLayout { SubManager.getinstance().stopSubThread(); } + public void startSocketServer() { + SubManager.getinstance().startSocketServer(); + } + + public void stopSocketServer() { + SubManager.getinstance().stopSocketServer(); + } + + public void setIOType(int type) { + SubManager.getinstance().setIOType(type); + } + public void loadSubtitleFile (String path, String enc) throws Exception { SubManager.getinstance().loadSubtitleFile (path, enc); } |