summaryrefslogtreecommitdiff
authorXiaoliang 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)
commitb58c2ae8d751d514f9f2b78f0e173127cf706e4c (patch)
treed7e050f42313596840771391497b8b77382f8b0a
parent5ec68edad5177f88b64a39d1ce613e1e673cde62 (diff)
downloadSubTitle-b58c2ae8d751d514f9f2b78f0e173127cf706e4c.zip
SubTitle-b58c2ae8d751d514f9f2b78f0e173127cf706e4c.tar.gz
SubTitle-b58c2ae8d751d514f9f2b78f0e173127cf706e4c.tar.bz2
PD #140984: add socket to get raw data from amgeneric source
Change-Id: Iaf0fade3aa916553a480be94ff10cf2f7aced5a4
Diffstat
-rw-r--r--jni/subtitle/Android.mk2
-rw-r--r--jni/subtitle/sub_control.c2
-rw-r--r--jni/subtitle/sub_control.h12
-rw-r--r--jni/subtitle/sub_dvb_sub.c15
-rw-r--r--jni/subtitle/sub_io.cpp86
-rw-r--r--jni/subtitle/sub_io.h38
-rw-r--r--jni/subtitle/sub_jni.c22
-rw-r--r--jni/subtitle/sub_pgs_sub.c27
-rw-r--r--jni/subtitle/sub_set_sys.c34
-rw-r--r--jni/subtitle/sub_socket.cpp303
-rw-r--r--jni/subtitle/sub_socket.h50
-rw-r--r--jni/subtitle/sub_subtitle.c66
-rw-r--r--jni/subtitle/sub_vob_sub.c3
-rw-r--r--src/com/droidlogic/SubTitleService/ISubTitleService.aidl1
-rw-r--r--src/com/droidlogic/SubTitleService/SubTitleService.java28
-rw-r--r--src/com/subtitleparser/Subtitle.java17
-rw-r--r--src/com/subtitleview/SubManager.java18
-rw-r--r--src/com/subtitleview/SubtitleView.java12
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);
}