Android手机视频监控JNI问题【续】

Smile__LV 2010-09-21 01:48:35
坐着板凳等牛人之前发过类似的求助帖,问题讲的不是很清楚,再次重新整理,求高手指教:
原帖地址:http://topic.csdn.net/u/20100917/10/068962e2-a9f7-40fa-aaad-770243bf8c0e.html?seed=1287149481&r=68566763#r_68566763

各位大侠,小弟现在做一个Android手机视频监控软件,就是通过手机查看摄像头的视频,就像飞天眼。我们把每个用户的信息保存在一个服务器上,使用XML格式。用户登录的时候需要用户名和密码,用户查看某个摄像头的时候我们要传数据过去(IP和端口还有摄像头用户名和密码)。我们使用JNI解码H264视频数据。现在遇到一个问题就是在Java层LoginCam(String name,String password)直接传给JNI的C程序会出错,报错空指针。。不知道各位大侠有什么好办法帮忙解决吗?QQ467887719 小弟在此先谢了!
我先在对应的包下写了VView自定义类,之后就删除了因为我在H264Android.java里面重写了它。
(以下所说的.c文件不特别说明都是特指H264Android.c文件)
代码如下:

package com.handlerun.view;

public class VView {

public native void LiveVideo(byte[] out);
public native int getSequence(byte[] out);
public native int InitDecoder();
public native int UninitDecoder();
public native int DecoderNal(byte[] in, int insize, byte[] out);
public native int Connectiondvs(String ip,int port);
public native int LoginCam(String username,String password);
public native int StopLive();

static {
System.loadLibrary("H264Android");
}

}


把.c Javac,javah之后生成的.h代码如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_handlerun_view_VView */

#ifndef _Included_com_handlerun_view_VView
#define _Included_com_handlerun_view_VView
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_handlerun_view_VView
* Method: LiveVideo
* Signature: (I[B)I
*/
JNIEXPORT jint JNICALL Java_com_handlerun_view_VView_LiveVideo
(JNIEnv *env, jobject obj, jbyteArray out);

/*
* Class: com_handlerun_view_VView
* Method: getSequence
* Signature: ([B)I
*/
JNIEXPORT jint JNICALL Java_com_handlerun_view_VView_getSequence
(JNIEnv *env, jobject obj, jbyteArray out);

/*
* Class: com_handlerun_view_VView
* Method: InitDecoder
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_handlerun_view_VView_InitDecoder
(JNIEnv *env, jobject obj);

/*
* Class: com_handlerun_view_VView
* Method: UninitDecoder
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_handlerun_view_VView_UninitDecoder
(JNIEnv *env, jobject obj);

/*
* Class: com_handlerun_view_VView
* Method: DecoderNal
* Signature: ([BI[B)I
*/
JNIEXPORT jint JNICALL Java_com_handlerun_view_VView_DecoderNal
(JNIEnv *env, jobject obj, jbyteArray in, jint nallen, jbyteArray out);

/*
* Class: com_handlerun_view_VView
* Method: Connectiondvs
* Signature: (Ljava/lang/String;I)I
*/
JNIEXPORT jint JNICALL Java_com_handlerun_view_VView_Connectiondvs
(JNIEnv *env, jobject obj, jstring ip, jint port);

/*
* Class: com_handlerun_view_VView
* Method: LoginCam
* Signature: (Ljava/lang/String;Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_com_handlerun_view_VView_LoginCam
(JNIEnv *env, jobject obj, jstring username, jstring password);

/*
* Class: com_handlerun_view_VView
* Method: StopLive
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_handlerun_view_VView_StopLive
(JNIEnv *env, jobject obj);

#ifdef __cplusplus
}
#endif
#endif

Debug调试报错如下,这CSDN逼迫我把截图上传到了QQ空间(再次鄙视下CSDN)就是报LoginCam函数的空指针(因为单步调试走到这个函数处就报错了)图片:
兄弟们实在不行去我QQ空间吧 ,在我的QQ空间相册里面http://user.qzone.qq.com/467887719?ptlang=2052 哭泣、、、、、

JNI层我在.c实现那些方法:部分代码如下:(只发LoginCam(String username,String password)这个方法,就他报错)
.c文件开始定义全局的变量:
int portNum=NULL;//端口
char ipAdress=NULL;//IP地址
char u_name=NULL;//摄像头用户名
char pwd=NULL;//密码

.c里面调用如下:
JNIEXPORT jint JNICALL Java_com_handlerun_view_VView_LoginCam
(JNIEnv *env,jobject obj,jstring username,jstring password)
{

pwd =(char*)(*env)->GetStringUTFChars(env,password, NULL);
u_name=(char*)(*env)->GetStringUTFChars(env,username, NULL);

char um="admin";
char pd="123456";
int a=strcmp(um,u_name);
int b=strcmp(pd,password);
if(a==0&&b==0)
{
return 0;
}else{
return 1;
}

}
...全文
1166 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
djmxia 2013-04-20
  • 打赏
  • 举报
回复
LZ这个能不能留个联系方式指导一下
meliuzhifeng 2012-07-12
  • 打赏
  • 举报
回复
楼主有些问题需要请教你,给你发私信了,谢谢指导
sxjzhjj 2012-02-08
  • 打赏
  • 举报
回复
楼上诸位的进展如何,请教中
jobby1990 2011-10-10
  • 打赏
  • 举报
回复
楼主啊~我最近也在做网络摄像头,登录和获取h.264 搞得我头大!!!能否赐教一下啊,最好有个demo 836904938@qq.com 拜谢~
jefferyyangkai 2011-04-01
  • 打赏
  • 举报
回复
最近也在做jni,所以搜到的,正好发现你有个bug,所以提出来
Smile__LV 2011-03-30
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 jefferyyangkai 的回复:]
回复了才发现已经结贴了,无所谓了,lz看到说句话就行了
[/Quote]
谢谢你朋友 ,帖子这么久了你都来看来呵呵 。
jefferyyangkai 2011-03-29
  • 打赏
  • 举报
回复
回复了才发现已经结贴了,无所谓了,lz看到说句话就行了
jefferyyangkai 2011-03-29
  • 打赏
  • 举报
回复
首先恭喜lz把程序改成了没有错误的,但你这里有内存泄露的bug。

pwd =(char*)(*env)->GetStringUTFChars(env,password, NULL);你对java层的password增加了一次引用,但从没释放(C层删除pwd 时,你没有通知java层),所以在java层一直认为这一变量引用计数不为0,也就永远不会删除这个变量,后果很严重,你懂的。

在你不需要再试用pwd时,写入(*env)->ReleaseStringUTFChars(env, jstring, pwd ); 通知java层,此变量减少1引用计数。
yanghuaixi 2010-12-28
  • 打赏
  • 举报
回复
好贴啊
xiaoyemeng 2010-11-15
  • 打赏
  • 举报
回复
楼主提供的资料不错,学习。。顶!
susemm 2010-09-28
  • 打赏
  • 举报
回复
我什么也不说,拿分走人。
Smile__LV 2010-09-21
  • 打赏
  • 举报
回复
原因找到了 原来是我使用char接收一个字符串 出错了 错误代码:
int portNum=NULL;//端口
char ipAdress=NULL;//IP地址
char u_name=NULL;//摄像头用户名
char pwd=NULL;//密码

以及:
JNIEXPORT jint JNICALL Java_com_handlerun_view_VView_LoginCam
(JNIEnv *env,jobject obj,jstring username,jstring password)
{

pwd =(char*)(*env)->GetStringUTFChars(env,password, NULL);
u_name=(char*)(*env)->GetStringUTFChars(env,username, NULL);

char um="admin";
char pd="123456";
int a=strcmp(um,u_name);
int b=strcmp(pd,password);
if(a==0&&b==0)
{
return 0;
}else{
return 1;
}


应该修改成:
int portNum=NULL;//端口
char *ipAdress=NULL;//IP地址
char *u_name=NULL;//摄像头用户名
char *pwd=NULL;//密码

以及:
u_name=(char*)(*env)->GetStringUTFChars(env,username, NULL);
pwd =(char*)(*env)->GetStringUTFChars(env,password, NULL);
char *pd="123456";
char *um="admin";

int a=strcmp(um,u_name);
int b=strcmp(pd,password);
if(a==0&&b==0)
{
return 0;
}else{
return 1;
}
loseleo 2010-09-21
  • 打赏
  • 举报
回复
先顶一下再说吧,群里狮子~
Smile__LV 2010-09-21
  • 打赏
  • 举报
回复
CSDN人气这么旺盛 自己不顶马上就沉底了、、、、、、、、


大侠来帮忙啊
Smile__LV 2010-09-21
  • 打赏
  • 举报
回复
这里给出Connectiondvs函数在JNI层被调用的代码:
JNIEXPORT jint JNICALL Java_com_handlerun_view_VView_Connectiondvs
(JNIEnv *env, jobject obj, jstring ip, jint port)
{
ipAdress=(char*)(*env)->GetStringUTFChars(env,ip, NULL);

portNum=++port;//HTTP端口加1是tcp端口

return 1;
}
Smile__LV 2010-09-21
  • 打赏
  • 举报
回复
现在说我在java层H264Android.java调用的函数
package com.handlerun.view;

import java.nio.ByteBuffer;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Bitmap.Config;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

public class H264Android extends Activity {

VView vv;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
vv = new VView(this);
setContentView(vv);
}

// Menu item Ids
public static final int PLAY_ID = Menu.FIRST;
public static final int EXIT_ID = Menu.FIRST + 1;

@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);

menu.add(0, PLAY_ID, 0, R.string.play);
menu.add(0, EXIT_ID, 1, R.string.exit);

return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case PLAY_ID:
{
String file = "/sdcard/free.264";
vv.PlayVideo(file);
return true;
}
case EXIT_ID:
{
finish();
return true;
}
}
return super.onOptionsItemSelected(item);
}

}

class VView extends View implements Runnable{

Bitmap mBitQQ = null;

Paint mPaint = null;

Bitmap mSCBitmap = null;

Matrix matrix = new Matrix();

byte [] mPixel = new byte[288*352*2];

ByteBuffer buffer = ByteBuffer.wrap( mPixel );
Bitmap VideoBit = Bitmap.createBitmap(352, 288, Config.RGB_565);

VView v = this;

int mTrans=0x0F0F0F0F;
public native int InitDecoder();
public native int UninitDecoder();
public native int DecoderNal(byte[] in, int insize, byte[] out);
public native void LiveVideo(byte[] out);
public native int getSequence(byte[] out);
public native int Connectiondvs(String ip,int port);
//public native int Login(String username,String password);
public native int LoginCam(String username,String password);
public native int StopLive();
static
{
System.loadLibrary("H264Android");
}
/**
* 构造函数
*/
public VView(Context context) {
super(context);
setFocusable(true);

int i = mPixel.length;

for(i=0; i<mPixel.length; i++)
{
mPixel[i]=(byte)0x00;
}
}
/**
* 播放视频
* @param file
*/
public void PlayVideo(String file)
{
String uName="admin";
String pWd="123456";
int connect=Connectiondvs("192.168.1.170",5014);
System.out.println("connect+++"+connect);
int lo=LoginCam(uName, pWd);
System.out.println("login+++"+lo);
if(lo==1&&connect==1){
new Thread(this).start();
new Thread(new Video()).start();
}
}

@Override protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
VideoBit.copyPixelsFromBuffer(buffer);//makeBuffer(data565, N));
canvas.drawBitmap(VideoBit, 0, 0, null);
}

public void updateUI()
{
postInvalidate();
}

public void run()
{
byte[] index ={0};
int getIndex = 0;
int beforeIndex = 0;

while (!Thread.currentThread().isInterrupted())
{
getIndex = getSequence(index);
//System.out.println("getIndex++++"+getIndex);
if(getIndex!=0&&getIndex!=beforeIndex)
{
System.out.println(" #################################### ");

//运行测试内容
long t1= System.currentTimeMillis();
updateUI();
long t2= System.currentTimeMillis();
// System.out.println("******** tiem " + (t2-t1));
beforeIndex = getIndex ;
}
}
}


public void sayHello()
{
System.out.println("****************#####################################################");
}


class Video implements Runnable{
public void run() {
// TODO Auto-generated method stub
LiveVideo(mPixel);
}
}
}


单步调试到
int lo=LoginCam(uName, pWd);
就会报错空指针。。。而和LoginCam这个函数很相似的函数Connectiondvs却不报错。而且可以输出connect+++1的结果。

80,361

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧