summaryrefslogtreecommitdiff
authorZhiwei Yan <zhiwei.yan@amlogic.com>2017-04-05 10:45:29 (GMT)
committer Zhiwei Yan <zhiwei.yan@amlogic.com>2017-04-05 11:04:00 (GMT)
commitff5be508c0627e644dce7ff2e0f107fc8c5d5115 (patch)
tree1a2b34425a06ee6ee39dd5de01fc20b6fe4ae631
parentb58c2ae8d751d514f9f2b78f0e173127cf706e4c (diff)
downloadSubTitle-ff5be508c0627e644dce7ff2e0f107fc8c5d5115.zip
SubTitle-ff5be508c0627e644dce7ff2e0f107fc8c5d5115.tar.gz
SubTitle-ff5be508c0627e644dce7ff2e0f107fc8c5d5115.tar.bz2
pd#138966:integrate ccsubview into subtitleservice
Change-Id: Iaa3505f52a815e97848396b431e251d1760f55b5
Diffstat
-rw-r--r--Android.mk2
-rw-r--r--jni/ccsub/Android.mk28
-rw-r--r--jni/ccsub/ccsub.cpp412
-rw-r--r--res/layout/subtitleview.xml36
-rw-r--r--src/com/droidlogic/SubTitleService/SubTitleService.java59
-rw-r--r--src/com/subtitleview/CcSubView.java208
6 files changed, 728 insertions, 17 deletions
diff --git a/Android.mk b/Android.mk
index e576883..63089ca 100644
--- a/Android.mk
+++ b/Android.mk
@@ -24,7 +24,7 @@ LOCAL_PROGUARD_ENABLED := disabled
LOCAL_PACKAGE_NAME := SubTitle
LOCAL_CERTIFICATE := platform
LOCAL_JAVA_LIBRARIES := droidlogic
-LOCAL_REQUIRED_MODULES := libsubjni
+LOCAL_REQUIRED_MODULES := libsubjni libccsubjni
include $(BUILD_PACKAGE)
include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/jni/ccsub/Android.mk b/jni/ccsub/Android.mk
new file mode 100644
index 0000000..7ceb494
--- a/dev/null
+++ b/jni/ccsub/Android.mk
@@ -0,0 +1,28 @@
+LOCAL_PATH := $(call my-dir)
+DVB_PATH := $(wildcard external/dvb)
+ifeq ($(DVB_PATH), )
+ DVB_PATH := $(wildcard vendor/amlogic/external/dvb)
+endif
+ifeq ($(DVB_PATH), )
+ DVB_PATH := $(wildcard vendor/amlogic/dvb)
+endif
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libccsubjni
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := ccsub.cpp
+LOCAL_ARM_MODE := arm
+LOCAL_C_INCLUDES := external/libzvbi/src \
+ $(DVB_PATH)/include/am_mw \
+ $(DVB_PATH)/include/am_adp \
+ bionic/libc/include \
+ vendor/amlogic/frameworks/av/LibPlayer/amcodec/include \
+ vendor/amlogic/frameworks/av/LibPlayer/amadec/include \
+ external/skia/include\
+ vendor/amlogic/dvb/android/ndk/include\
+ vendor/amlogic/dvb/android/ndk/include/linux \
+ common/include/linux/amlogic
+
+LOCAL_SHARED_LIBRARIES += libjnigraphics libzvbi libam_mw libam_adp libskia liblog libcutils
+LOCAL_PRELINK_MODULE := false
+include $(BUILD_SHARED_LIBRARY)
diff --git a/jni/ccsub/ccsub.cpp b/jni/ccsub/ccsub.cpp
new file mode 100644
index 0000000..fd3d2b6
--- a/dev/null
+++ b/jni/ccsub/ccsub.cpp
@@ -0,0 +1,412 @@
+#include <am_cc.h>
+#include <core/SkBitmap.h>
+#include <jni.h>
+#include <android/log.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <cutils/properties.h>
+
+#include <android/bitmap.h>
+extern "C" {
+
+static JavaVM *gJavaVM = NULL;
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "ccsubjni"
+#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
+#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
+#define INIT_W 720
+#define INIT_H 576
+
+#define AV_DEV_NO 0
+#define DMX_DEV_NO 0
+
+static jmethodID gUpdateID;
+static jfieldID gBitmapID;
+int ccbitmapsize_w, ccbitmapsize_h;
+
+
+typedef struct {
+ pthread_mutex_t lock;
+ AM_CC_Handle_t cc_handle;
+ int dmx_id;
+ int filter_handle;
+ jobject obj;
+ SkBitmap *bitmap;
+ jobject obj_bitmap;
+ int bmp_w;
+ int bmp_h;
+ int bmp_pitch;
+ uint8_t *buffer;
+ int sub_w;
+ int sub_h;
+} DevCCData;
+
+static DevCCData gCCData;
+
+static DevCCData* cc_get_data(JNIEnv *env, jobject obj)
+{
+ return &gCCData;
+}
+
+static uint8_t *lock_bitmap(JNIEnv *env, jobject bitmap)
+{
+ int attached = 0;
+ if (!env) {
+ int ret;
+ ret = gJavaVM->GetEnv((void **) &env, JNI_VERSION_1_4);
+ if (ret < 0) {
+ ret = gJavaVM->AttachCurrentThread(&env, NULL);
+ if (ret < 0) {
+ LOGE("Can't attach thread");
+ return NULL;
+ }
+ attached = 1;
+ }
+ }
+
+ uint8_t *buf;
+ AndroidBitmap_lockPixels(env, bitmap, (void **) &buf);
+
+ if (attached) {
+ gJavaVM->DetachCurrentThread();
+ }
+
+ return buf;
+}
+
+static void unlock_bitmap(JNIEnv *env, jobject bitmap)
+{
+ int attached = 0;
+ if (!env) {
+ int ret;
+ ret = gJavaVM->GetEnv((void **) &env, JNI_VERSION_1_4);
+ if (ret < 0) {
+ ret = gJavaVM->AttachCurrentThread(&env, NULL);
+ if (ret < 0) {
+ LOGE("Can't attach thread");
+ return;
+ }
+ attached = 1;
+ }
+ }
+
+ AndroidBitmap_unlockPixels(env, bitmap);
+
+ if (attached) {
+ gJavaVM->DetachCurrentThread();
+ }
+}
+
+static void notify_bitmap_changed(jobject bitmap)
+{
+ lock_bitmap(NULL, bitmap);
+ unlock_bitmap(NULL, bitmap);
+}
+
+static uint8_t *get_bitmap(JNIEnv *env, DevCCData *cc, int *w, int *h, int *pitch)
+{
+ uint8_t *buf;
+
+ buf = lock_bitmap(env, cc->obj_bitmap);
+ unlock_bitmap(env, cc->obj_bitmap);
+ LOGI("---bitmap buffer [%p]", buf);
+
+ if (!buf) {
+ LOGE("allocate bitmap buffer failed");
+ } else {
+ AndroidBitmapInfo bitmapInfo;
+ AndroidBitmap_getInfo(env, cc->obj_bitmap, &bitmapInfo);
+ LOGI("init bitmap info w:%d h:%d s:%d", bitmapInfo.width, bitmapInfo.height, bitmapInfo.stride);
+
+ if (w) {
+ *w = bitmapInfo.width;
+ }
+ if (h) {
+ *h = bitmapInfo.height;
+ }
+ if (pitch) {
+ *pitch = bitmapInfo.stride;
+ }
+ }
+
+ return buf;
+}
+
+static void clear_bitmap(DevCCData *cc)
+{
+ uint8_t *ptr = cc->buffer;
+ int y = cc->bmp_h;
+
+ while (y--) {
+ memset(ptr, 0, cc->bmp_pitch);
+ ptr += cc->bmp_pitch;
+ }
+}
+
+static void cc_draw_begin_cb(AM_CC_Handle_t handle, AM_CC_DrawPara_t *draw_para)
+{
+ DevCCData *cc = (DevCCData*)AM_CC_GetUserData(handle);
+
+ pthread_mutex_lock(&cc->lock);
+ if (cc && cc->buffer && cc->obj_bitmap) {
+ cc->buffer = lock_bitmap(NULL, cc->obj_bitmap);
+ }
+}
+
+static void sub_update(jobject obj)
+{
+ JNIEnv *env;
+ int ret;
+ int attached = 0;
+
+ if (!obj)
+ return;
+
+ ret = gJavaVM->GetEnv((void**) &env, JNI_VERSION_1_4);
+
+ if (ret<0) {
+ ret = gJavaVM->AttachCurrentThread(&env, NULL);
+ if (ret<0) {
+ LOGE("Can't attach thread");
+ return;
+ }
+ attached = 1;
+ }
+
+ env->CallVoidMethod(obj, gUpdateID, ccbitmapsize_w, ccbitmapsize_h);
+ if (attached) {
+ gJavaVM->DetachCurrentThread();
+ }
+}
+
+static jint cc_init(JNIEnv *env, jobject obj)
+{
+ DevCCData *data;
+ jclass bmp_clazz;
+ jfieldID fid;
+ jobject bmp;
+ jlong hbmp;
+
+ data = &gCCData;
+ memset(data, 0, sizeof(DevCCData));
+
+ pthread_mutex_init(&data->lock, NULL);
+
+ data->obj = env->NewGlobalRef(obj);
+ bmp = env->GetStaticObjectField(env->FindClass("com/subtitleview/CcSubView"), gBitmapID);
+ data->obj_bitmap = env->NewGlobalRef(bmp);
+
+ data->buffer = get_bitmap(env, data, &data->bmp_w, &data->bmp_h, &data->bmp_pitch);
+ if (!data->buffer) {
+ env->DeleteGlobalRef(data->obj);
+ env->DeleteGlobalRef(data->obj_bitmap);
+ pthread_mutex_destroy(&data->lock);
+ return -1;
+ }
+ LOGI("init w:%d h:%d p:%d", data->bmp_w, data->bmp_h, data->bmp_pitch);
+ /*just init, no effect*/
+ data->sub_w = INIT_W;
+ data->sub_h = INIT_H;
+
+ return 0;
+}
+
+static jint cc_destroy(JNIEnv *env, jobject obj)
+{
+ DevCCData *data = cc_get_data(env, obj);
+
+ if (data) {
+
+ if (data->obj) {
+ env->DeleteGlobalRef(data->obj);
+ data->obj = NULL;
+ }
+ if (data->obj_bitmap) {
+ env->DeleteGlobalRef(data->obj_bitmap);
+ data->obj_bitmap = NULL;
+ }
+ pthread_mutex_destroy(&data->lock);
+ }
+
+ return 0;
+}
+
+static jint cc_lock(JNIEnv *env, jobject obj)
+{
+ DevCCData *data = cc_get_data(env, obj);
+
+ pthread_mutex_lock(&data->lock);
+
+ return 0;
+}
+
+static jint cc_unlock(JNIEnv *env, jobject obj)
+{
+ DevCCData *data = cc_get_data(env, obj);
+
+ pthread_mutex_unlock(&data->lock);
+
+ return 0;
+}
+
+static void cc_draw_end_cb(AM_CC_Handle_t handle, AM_CC_DrawPara_t *draw_para)
+{
+ DevCCData *cc = (DevCCData*)AM_CC_GetUserData(handle);
+
+ unlock_bitmap(NULL, cc->obj_bitmap);
+
+ cc->sub_w = draw_para->caption_width;
+ cc->sub_h = draw_para->caption_height;
+ ccbitmapsize_w = draw_para->caption_width;
+ ccbitmapsize_h = draw_para->caption_height;
+
+ pthread_mutex_unlock(&cc->lock);
+ LOGE("cc_draw_end_cb");
+ sub_update(cc->obj);
+}
+
+static jint dev_start_atsc_cc(JNIEnv *env, jobject obj, jint caption, jint fg_color,
+ jint fg_opacity, jint bg_color, jint bg_opacity, jint font_style, jint font_size)
+{
+ DevCCData *data = cc_get_data(env, obj);
+ AM_CC_CreatePara_t cc_para;
+ AM_CC_StartPara_t spara;
+ int ret;
+
+ LOGI("start cc: caption %d, fgc %d, bgc %d, fgo %d, bgo %d, fsize %d, fstyle %d",
+ caption, fg_color, bg_color, fg_opacity, bg_opacity, font_size, font_style);
+
+ cc_para.bmp_buffer = data->buffer;
+ cc_para.pitch = data->bmp_pitch;
+ cc_para.draw_begin = cc_draw_begin_cb;
+ cc_para.draw_end = cc_draw_end_cb;
+ cc_para.user_data = (void*)data;
+
+ spara.caption = (AM_CC_CaptionMode_t)caption;
+ spara.user_options.bg_color = (AM_CC_Color_t)bg_color;
+ spara.user_options.fg_color = (AM_CC_Color_t)fg_color;
+ spara.user_options.bg_opacity = (AM_CC_Opacity_t)bg_opacity;
+ spara.user_options.fg_opacity = (AM_CC_Opacity_t)fg_opacity;
+ spara.user_options.font_size = (AM_CC_FontSize_t)font_size;
+ spara.user_options.font_style = (AM_CC_FontStyle_t)font_style;
+
+ ret = AM_CC_Create(&cc_para, &data->cc_handle);
+ if (ret != AM_SUCCESS)
+ goto error;
+
+ ret = AM_CC_Start(data->cc_handle, &spara);
+ if (ret != AM_SUCCESS)
+ goto error;
+
+ LOGI("start cc successfully!");
+ return 0;
+error:
+ if (data->cc_handle != NULL) {
+ AM_CC_Destroy(data->cc_handle);
+ }
+ LOGI("start cc failed!");
+ return -1;
+}
+
+static jint dev_stop_atsc_cc(JNIEnv *env, jobject obj)
+{
+ DevCCData *data = cc_get_data(env, obj);
+
+ LOGI("stop cc");
+ AM_CC_Destroy(data->cc_handle);
+
+ pthread_mutex_lock(&data->lock);
+ data->buffer = lock_bitmap(env, data->obj_bitmap);
+ clear_bitmap(data);
+ unlock_bitmap(env, data->obj_bitmap);
+ pthread_mutex_unlock(&data->lock);
+
+ sub_update(data->obj);
+
+ data->cc_handle= NULL;
+
+ return 0;
+}
+
+static jint cc_set_active(JNIEnv *env, jobject obj, jboolean active)
+{
+ DevCCData *data = cc_get_data(env, obj);
+
+ if (active) {
+ if (data->obj) {
+ env->DeleteGlobalRef(data->obj);
+ data->obj = NULL;
+ }
+
+ data->obj = env->NewGlobalRef(obj);
+ } else {
+ if (env->IsSameObject(data->obj, obj)) {
+ env->DeleteGlobalRef(data->obj);
+ data->obj = NULL;
+ }
+ }
+
+ return 0;
+}
+
+static JNINativeMethod gMethods[] = {
+ /* name, signature, funcPtr */
+ {"native_cc_init", "()I", (void*)cc_init},
+ {"native_cc_destroy", "()I", (void*)cc_destroy},
+ {"native_cc_lock", "()I", (void*)cc_lock},
+ {"native_cc_unlock", "()I", (void*)cc_unlock},
+ {"native_start_atsc_cc", "(IIIIIII)I", (void*)dev_start_atsc_cc},
+ {"native_stop_atsc_cc", "()I", (void*)dev_stop_atsc_cc},
+ {"native_cc_set_active", "(Z)I", (void*)cc_set_active}
+};
+
+
+JNIEXPORT jint
+JNI_OnLoad(JavaVM* vm, void* reserved)
+{
+ LOGE("in JNI_OnLoad\n");
+ JNIEnv* env = NULL;
+ jclass clazz;
+ int rc;
+
+ gJavaVM = vm;
+
+ if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
+ LOGE("GetEnv failed");
+ return -1;
+ }
+ LOGE("GetEnv ok");
+
+ clazz = env->FindClass("com/subtitleview/CcSubView");
+ if (clazz == NULL) {
+ LOGE("FindClass com/subtitleview/CcSubView failed");
+ return -1;
+ }
+ LOGI("find CcSubView class ok");
+ if ((rc = (env->RegisterNatives(clazz, gMethods, sizeof(gMethods)/sizeof(gMethods[0])))) < 0) {
+ LOGE("RegisterNatives failed");
+ return -1;
+ }
+ LOGI("RegisterNatives subfunc ok");
+ gUpdateID = env->GetMethodID(clazz, "update", "(II)V");
+
+ gBitmapID = env->GetStaticFieldID(clazz, "bitmap", "Landroid/graphics/Bitmap;");
+
+ LOGI("load jnitestplay ok");
+ return JNI_VERSION_1_4;
+}
+
+JNIEXPORT void
+JNI_OnUnload(JavaVM* vm, void* reserved)
+{
+ JNIEnv* env = NULL;
+
+ if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
+ return;
+ }
+}
+
+} \ No newline at end of file
diff --git a/res/layout/subtitleview.xml b/res/layout/subtitleview.xml
index 6ed086c..1eca77d 100644
--- a/res/layout/subtitleview.xml
+++ b/res/layout/subtitleview.xml
@@ -1,15 +1,21 @@
-<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/sub"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
-
- <com.subtitleview.SubtitleView
- android:id="@+id/subtitle"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_centerHorizontal="true"
- android:layout_alignParentBottom="true"
- android:layout_marginBottom="50dp">
- </com.subtitleview.SubtitleView>
-</RelativeLayout> \ No newline at end of file
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/sub"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+ <com.subtitleview.SubtitleView
+ android:id="@+id/subtitle"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_centerHorizontal="true"
+ android:layout_alignParentBottom="true"
+ android:layout_marginBottom="50dp">
+ </com.subtitleview.SubtitleView>
+ <com.subtitleview.CcSubView
+ android:id="@+id/ccsubtitle"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_centerHorizontal="true"
+ android:layout_above="@+id/subtitle">
+ </com.subtitleview.CcSubView>
+</RelativeLayout>
diff --git a/src/com/droidlogic/SubTitleService/SubTitleService.java b/src/com/droidlogic/SubTitleService/SubTitleService.java
index 6558e0a..505268f 100644
--- a/src/com/droidlogic/SubTitleService/SubTitleService.java
+++ b/src/com/droidlogic/SubTitleService/SubTitleService.java
@@ -13,6 +13,7 @@ import android.os.IBinder;
import java.lang.ref.WeakReference;
import android.view.*;
import android.view.ViewGroup;
+import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
@@ -21,6 +22,7 @@ import android.widget.AdapterView.OnItemClickListener;
import android.graphics.*;
import com.subtitleparser.*;
import com.subtitleview.SubtitleView;
+import com.subtitleview.CcSubView;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
@@ -64,7 +66,11 @@ 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 CCSTART = 0xE1;
+ private static final int CCSTOP = 0xE2;
+
private static final int SUB_OFF = 0;
private static final int SUB_ON = 1;
private int subShowState = SUB_OFF;
@@ -97,6 +103,9 @@ public class SubTitleService extends ISubTitleService.Stub {
private int mTextSize = 20;
private int mBottomMargin = 50; //should sync with SubtitleView.xml
+ //ccsubtitleview
+ private CcSubView ccSubView = null;
+
public SubTitleService(Context context) {
LOGI("[SubTitleService]");
mContext = context;
@@ -119,6 +128,7 @@ public class SubTitleService extends ISubTitleService.Stub {
subTitleView.setTextSize(20);
subTitleView.setTextStyle(Typeface.NORMAL);
subTitleView.setViewStatus(true);
+ ccSubView = (CcSubView) mSubView.findViewById(R.id.ccsubtitle);
new Thread(new Runnable() {
public void run() {
@@ -164,7 +174,7 @@ public class SubTitleService extends ISubTitleService.Stub {
if (mOptionDialog != null) {
mOptionDialog.dismiss();
}
-
+ StartCcSub();
if (path != null && !path.equals("")) {
File file = new File(path);
String name = file.getName();
@@ -205,6 +215,9 @@ public class SubTitleService extends ISubTitleService.Stub {
mSubTotal = -1;
mSetSubId = -1;
+ if (isViewAdded) {
+ StopCcSub();
+ }
sendCloseMsg();
}
@@ -383,6 +396,39 @@ public class SubTitleService extends ISubTitleService.Stub {
return language;
}
+ public void StartCcSub() {
+ sendStartCcSubMsg();
+ }
+
+ public void StopCcSub() {
+ sendStopCcSubMsg();
+ }
+
+ private void sendStartCcSubMsg() {
+ Message msg = mHandler.obtainMessage(CCSTART);
+ mHandler.sendMessage(msg);
+ }
+
+ private void sendStopCcSubMsg() {
+ Message msg = mHandler.obtainMessage(CCSTOP);
+ mHandler.sendMessage(msg);
+ }
+
+ private void ccStart() {
+ LOGI("cc subtitle start");
+ ccSubView.startCC();
+ ccSubView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+ ccSubView.show();
+ ccSubView.setActive(true);
+ }
+
+ private void ccStop() {
+ LOGI("cc subtitle stop");
+ ccSubView.hide();
+ ccSubView.setActive(false);
+ ccSubView.stopCC();
+ }
+
private void sendOpenMsg(int idx) {
if (mSubtitleUtils != null) {
Message msg = mHandler.obtainMessage(OPEN);
@@ -784,6 +830,7 @@ public class SubTitleService extends ISubTitleService.Stub {
subTitleView.setVisibility (View.GONE);
subShowState = SUB_OFF;
}
+ ccSubView.hide();
break;
case DISPLAY:
@@ -791,6 +838,7 @@ public class SubTitleService extends ISubTitleService.Stub {
subTitleView.setVisibility (View.VISIBLE);
subShowState = SUB_ON;
}
+ ccSubView.show();
break;
case CLEAR:
@@ -825,6 +873,15 @@ public class SubTitleService extends ISubTitleService.Stub {
case SET_IO_TYPE:
subTitleView.setIOType(msg.arg1);
+
+ case CCSTART:
+ addView();
+ ccStart();
+ break;
+
+ case CCSTOP:
+ ccStop();
+ removeView();
break;
default:
diff --git a/src/com/subtitleview/CcSubView.java b/src/com/subtitleview/CcSubView.java
new file mode 100644
index 0000000..25e5fed
--- a/dev/null
+++ b/src/com/subtitleview/CcSubView.java
@@ -0,0 +1,208 @@
+package com.subtitleview;
+
+import android.content.Context;
+import android.view.View;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.Paint;
+import android.graphics.Color;
+import android.util.AttributeSet;
+import java.lang.Exception;
+import android.util.Log;
+import android.os.SystemProperties;
+
+public class CcSubView extends View {
+ private static final String TAG = "CcSubView";
+ private static Bitmap bitmap = null;
+ private static final int BUFFER_W = 1920;
+ private static final int BUFFER_H = 1080;
+ private static int buffer_w;
+ private static int buffer_h;
+ private static boolean visible;
+ private static Object lock = new Object();
+ private int displeft = 0;
+ private int dispright = 0;
+ private int disptop = 0;
+ private int dispbottom = 0;
+ private static CcSubView activeView = null;
+ private boolean active = true;
+ private Context mContext;
+
+ private native int native_cc_init();
+ private native int native_cc_destroy();
+ private native int native_cc_lock();
+ private native int native_cc_unlock();
+ private native int native_cc_clear();
+ private native int native_start_atsc_cc(int caption, int fg_color, int fg_opacity, int bg_color, int bg_opacity, int font_style, int font_size);
+ private native int native_stop_atsc_cc();
+ private native int native_cc_set_active(boolean active);
+
+ static{
+ System.loadLibrary("am_adp");
+ System.loadLibrary("am_mw");
+ System.loadLibrary("zvbi");
+ System.loadLibrary("ccsubjni");
+ }
+
+ private void init(){
+ if (bitmap == null) {
+ bitmap = Bitmap.createBitmap(BUFFER_W, BUFFER_H, Bitmap.Config.ARGB_8888);
+ }
+ native_cc_init();
+ Log.d(TAG, "native init");
+ }
+
+ static public class DTVCCParams{
+ private int caption_mode = 0;
+ private int fg_color = 0;
+ private int fg_opacity = 0;
+ private int bg_color = 0;
+ private int bg_opacity = 0;
+ private int font_style = 0;
+ private int font_size = 40;
+
+ public DTVCCParams(int caption, int fg_color, int fg_opacity,
+ int bg_color, int bg_opacity, int font_style, int font_size){
+ this.caption_mode = caption;
+ this.fg_color = fg_color;
+ this.fg_opacity = fg_opacity;
+ this.bg_color = bg_color;
+ this.bg_opacity = bg_opacity;
+ this.font_style = font_style;
+ this.font_size = font_size;
+ }
+ }
+
+ DTVCCParams dtv_cc = new DTVCCParams(0, 0, 0, 0, 1, 0, 0);
+
+ private void update(int w, int h) {
+ buffer_w = w;
+ buffer_h = h;
+ postInvalidate();
+ }
+
+ private void update() {
+ postInvalidate();
+ }
+
+ public void show(){
+ if (visible)
+ return;
+
+ Log.d(TAG, "show");
+
+ visible = true;
+ update();
+ }
+
+ public void hide(){
+ if (!visible)
+ return;
+
+ Log.d(TAG, "hide");
+
+ visible = false;
+ update();
+ }
+
+ public void startCC(){
+ synchronized(lock){
+
+ native_start_atsc_cc(
+ dtv_cc.caption_mode,
+ dtv_cc.fg_color,
+ dtv_cc.fg_opacity,
+ dtv_cc.bg_color,
+ dtv_cc.bg_opacity,
+ dtv_cc.font_style,
+ dtv_cc.font_size);
+
+ }
+
+ }
+
+ public void stopCC(){
+ synchronized(lock){
+ native_stop_atsc_cc();
+ }
+ }
+
+ public void onDraw(Canvas canvas){
+ synchronized(lock){
+ Rect sr;
+ Rect dr;
+ int h_s, h_e, buffer_w_dr, buffer_h_dr;
+
+ buffer_w_dr = Integer.parseInt(SystemProperties.get("sys.subtitleService.ccsize", "0")) * buffer_w / 4 + buffer_w;
+ buffer_h_dr = Integer.parseInt(SystemProperties.get("sys.subtitleService.ccsize", "0")) * buffer_h / 4 + buffer_h;
+
+ h_s = getHeight() - buffer_h_dr -Integer.parseInt(SystemProperties.get("sys.subtitleService.cchs", "0")) * buffer_h_dr / 5 / 2;
+ h_e = h_s + buffer_h_dr;
+ dr = new Rect((getWidth()-buffer_w_dr) /2, h_s, (getWidth()-buffer_w_dr) /2+buffer_w_dr, h_e);
+
+ //Log.d(TAG, "-----h_s: " + h_s + " h_e: " + h_e + " ******buffer_w: " + buffer_w + " buffer_h: " + buffer_h + " buffer_w_dr: " + buffer_w_dr + " buffer_h_dr: " + buffer_h_dr +
+ // " ----getWidth: "+getWidth()+" getHeight: "+getHeight());
+
+ if (!visible) {
+ return;
+ }
+
+ native_cc_lock();
+
+ //Log.d(TAG, " CcSubView onDraw");
+ sr = new Rect(0, 0, buffer_w, buffer_h);
+
+ canvas.drawBitmap(bitmap, sr, dr, new Paint());
+
+ /*******************************************/
+ /*
+ Paint paint = new Paint();
+ paint.setColor(Color.RED);
+ paint.setStyle(Paint.Style.STROKE);
+ canvas.drawRect(new Rect(10, 10, 100, 30), paint);
+
+ paint.setColor(Color.GREEN);
+ canvas.drawText("1111111111111111111111", 10, 50, paint);
+ */
+ /********************************************/
+ native_cc_unlock();
+ }
+ }
+
+ public CcSubView(Context context){
+ super(context);
+ mContext = context;
+ init();
+ }
+
+ public CcSubView(Context context, AttributeSet attrs){
+ super(context, attrs);
+ mContext = context;
+ init();
+ }
+
+ public CcSubView(Context context, AttributeSet attrs, int defStyle){
+ super(context, attrs, defStyle);
+ init();
+ }
+
+ public void setActive(boolean active){
+ synchronized(lock){
+ native_cc_set_active(active);
+ this.active = active;
+ if (active) {
+ activeView = this;
+ /*}else if(activeView == this){
+ activeView = null;*/
+ }
+ postInvalidate();
+ }
+ }
+
+ protected void finalize() throws Throwable {
+ native_cc_clear();
+ native_cc_destroy();
+ super.finalize();
+ }
+}