Android-android socket cpu占用过高

项目合作 项目合作 主题:1030 回复:2135

Android-android socket cpu占用过高

偏爱自由 发布于 2017-10-10 字数 12029 浏览 1032 回复 2

这是一个视频传输的应用程序不知道什么原因 运行的时候CPU占用90% 本身的编解码运行没问题只占了7%, 一下是 发送端和接收端的代码

发送端: 

package com.king.evbdemo;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

import android.media.EvbMediaCodec;


public class VideoRecord implements Runnable {

private final int PORT = 8800;

private InetAddress remoteIP;
private String ipAddr;

private DatagramSocket sendSocket = null;
private DatagramPacket sendPacket = null;

private byte[] buffer = new byte[512];

private int frameSize = 512;
private int num = 0;
private int number = 0;

private boolean recording;

public VideoRecord() {

ipAddr = "127.0.0.1";

try {
remoteIP = InetAddress.getByName(ipAddr);
} catch (UnknownHostException e1) {
e1.printStackTrace();
}

sendPacket = new DatagramPacket(buffer, buffer.length, remoteIP, PORT);

try {
sendSocket = new DatagramSocket();
} catch (SocketException e) {
e.printStackTrace();
}
}

public void transVideoRecord() {
recording = true;
new Thread(this).start();
}

public void releaseMediaRecorder() {
recording = false;
EvbMediaCodec.evbRecorderClose();
if (sendSocket != null)
sendSocket.close();
}

@Override
public void run() {

int[] len = new int[2];
byte[] header = new byte[64];
byte[] frame = new byte[40960];

boolean firstFrame = true;

EvbMediaCodec.evbRecorderInit();

int headerLen = 0, encodeFrameLen = 0, remain = 0;

boolean times = true;

while (recording) {

if (firstFrame) {
firstFrame = false;

encodeFrameLen = EvbMediaCodec.evbRecorderFrame(header, frame, len);

headerLen = len[0];
System.arraycopy(header, 0, buffer, 0, headerLen);

sendPacket.setLength(512);
System.out.println("send headerLen="+headerLen);
try {
sendSocket.send(sendPacket);
} catch (IOException e) {
e.printStackTrace();
}

number = 0;
System.out.println("encodeFrameLen&&&&&&&&"+encodeFrameLen);
while (number < encodeFrameLen) {
remain = encodeFrameLen - number;
num = (frameSize < remain) ? frameSize : remain;

System.arraycopy(frame, number, buffer, 0, num);
if (num<512) {
num=512;
}
sendPacket.setLength(num);

System.out.println("send num="+num);

try {
sendSocket.setReceiveBufferSize(1024*1024*5);
sendSocket.send(sendPacket);
} catch (IOException e) {
e.printStackTrace();
}

number += num;
}

continue;

}
encodeFrameLen = EvbMediaCodec.evbRecorderFrame(header, frame, len);
number = 0;
System.out.println("encodeFrameLen>>"+encodeFrameLen);
while (number < encodeFrameLen) {
remain = encodeFrameLen - number;
num = (frameSize < remain) ? frameSize : remain;

System.arraycopy(frame, number, buffer, 0, num);
if (num<512) {
num=512;
}
sendPacket.setLength(num);
try {
sendSocket.send(sendPacket);
} catch (IOException e) {
e.printStackTrace();
}
number += num;

}

}


}

}
接收端:
package com.king.evbdemo;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.Vector;

import android.media.EvbMediaCodec;

public class VideoPlay implements Runnable {

private final int PORT = 8800;

private Vector<DataPacket> videoDataVector = new Vector<DataPacket>();

private int mTrans = 0x0F0F0F0F;

//UDPͨ��
private DatagramSocket dSocket = null;
private DatagramPacket dPacket = null;

private VideoReceiver receiver = null;

private boolean receiving = true;

//��Ƶ�����߳��Ƿ����
private boolean videoDecoding = true;

public VideoPlay() {
receiving = true;

EvbMediaCodec.evbPlayerInit();

}

public void playH264Video() {
Thread t = new Thread(this);
t.start();
}

public void receiveData() {
receiver = new VideoReceiver();
Thread t = new Thread(receiver);
t.start();
}


@Override
public void run() {

boolean bFirst = true;
boolean bFindPPS = false;
boolean bFindSPS = false;

DataPacket videoData = null;

byte[] videoBytesData = null;
int videoDataLength = 0;

byte[] frameBuffer = new byte[40980];
byte[] tempBuffer = new byte[40960];
int frameBufferUsedLength = 0;
int tempBufferUsedLength = 0;
int tempBufferTotalLength = 0;
int iPPS = 0;
int nalLen = 0;

while (videoDecoding) {
if (videoDataVector.size() <= 5) continue;

videoData = videoDataVector.remove(0);
videoBytesData = videoData.getData();
videoDataLength = videoData.getLength();

if (bFirst) {
bFirst = false;
EvbMediaCodec.evbPlayerFrame(videoBytesData, videoDataLength, 1);
System.out.println("---------decode header len="+videoDataLength);
continue;
}


System.arraycopy(videoBytesData, 0, tempBuffer, tempBufferTotalLength, videoDataLength);
tempBufferTotalLength += videoDataLength;
if (tempBufferTotalLength < 4096 * 2)
continue;

iPPS = 0;
tempBufferUsedLength = 0;
while (tempBufferTotalLength - tempBufferUsedLength > 0) {
nalLen = mergeBuffer(frameBuffer, frameBufferUsedLength, tempBuffer, tempBufferUsedLength, tempBufferTotalLength - tempBufferUsedLength, 8);
frameBufferUsedLength += nalLen;
tempBufferUsedLength += nalLen;


if (mTrans == 1) {
mTrans = 0x0F0F0F0F;
if ((frameBufferUsedLength-4) > 0) {
int size = frameBufferUsedLength-4;
EvbMediaCodec.evbPlayerFrame(frameBuffer, size, 0);

frameBuffer[0] = 0;
frameBuffer[1] = 0;
frameBuffer[2] = 0;
frameBuffer[3] = 1;
frameBufferUsedLength = 4;
}
}
}

tempBufferTotalLength = 0;
}

EvbMediaCodec.evbPlayerClose();

}


private int mergeBuffer(byte[] NalBuf, int NalBufUsed, byte[] SockBuf, int SockBufUsed, int SockRemain, int aTemp) {
int i = 0;
int sockLocate = 0;
byte Temp;
for (i=0; i<SockRemain; i++) {
sockLocate = i + SockBufUsed;
Temp = SockBuf[sockLocate];
NalBuf[i + NalBufUsed] = Temp;

mTrans <<= 8;
mTrans |= Temp;

if (mTrans == 1) {//&& SockBuf[sockLocate - 1] == 0 && SockBuf[sockLocate - 2] == 0 && SockBuf[sockLocate - 3] == 0
i++;
break;
}
}
return i;
}


private boolean findH264Separator(byte[] data, int offset, int len) {
int i = 0;
int mtrans = 0x0F0F0F0F;
byte tmp;
for (i=offset; i<len; i++) {
tmp = data[i];
mtrans <<= 8;
mtrans |= tmp;

// �ҵ�һ���ָ���
if (mtrans == 1) {
return true;
}
}
return false;
}


public void mediaRelease() {

receiving = false;
videoDecoding = false;

EvbMediaCodec.evbPlayerClose();
if (dSocket != null) {
dSocket.close();
dSocket = null;
}
}

class VideoReceiver implements Runnable {
public void run() {

byte[] receivePacket = new byte[512];
byte[] packetData = new byte[512];

byte[] tempAllData = new byte[512];

int packetLength = 0; //���

try {
dSocket = new DatagramSocket(PORT);
dPacket = new DatagramPacket(receivePacket, receivePacket.length);
videoDataVector.clear();
} catch (SocketException ex) {
ex.printStackTrace();
return;
}

while (receiving) {
try {
dSocket.setReceiveBufferSize(1024*1024*5);
dSocket.receive(dPacket);
} catch (IOException e) {
e.printStackTrace();
}
packetData = dPacket.getData(); //����ʵ�ʽ��յ���ݶ���, ʼ����DatagramPacket������Сһ��
packetLength = dPacket.getLength();
System.arraycopy(packetData, 0, tempAllData, 0, packetLength);

if (packetLength > 0) {
DataPacket video = new DataPacket(tempAllData, packetLength);
videoDataVector.add(video);
}
}
}
}

}

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

支持 Markdown 语法,需要帮助?

评论(2

泛泛之交 2017-10-26 2 楼

的确是死循环造成的,本身的数据传递没什么异常,但是视频在解码的时候是进行死循环处理的特别占CPU在这个循环中加一个延时10毫秒就OK了。

晚风撩人 2017-10-18 1 楼

你检查下是不是因为通信线路堵塞的问题,还是程序里出现了死循环。你还可以在各个处理部分用Log.d出一些log,用logcat监视一下看看cpu占用率高的时候都在做什么。