提交 9c2280b8 authored 作者: autulin's avatar autulin

udp能推了,但是延迟大,待优化:

1. 视频、音频队列缓存数据过多,mux处理是否过慢 2. rtp预览的时候不够流畅,是否需要拆包
上级 00e3442f
......@@ -2,6 +2,7 @@
// Created by autulin on 2018/9/13.
//
#include <netdb.h>
#include "GB28181_sender.h"
GB28181_sender::GB28181_sender(UserArguments *arg) : args(arg) {}
......@@ -9,10 +10,11 @@ GB28181_sender::GB28181_sender(UserArguments *arg) : args(arg) {}
int GB28181_sender::initSender() {
switch (args->outType) {
case 0: // udp
LOGE("ip:%s, port:%d", args->ip_addr, args->port);
LOGE("ip:%s, port:%d, out_type:%d", args->ip_addr, args->port, args->outType);
initSocket(args->ip_addr, args->port);
break;
case 1: // tcp
LOGE("ip:%s, port:%d", args->ip_addr, args->port);
LOGE("ip:%s, port:%d, out_type:%d", args->ip_addr, args->port, args->outType);
break;
case 2: // file
//打开ps文件
......@@ -40,10 +42,14 @@ void *GB28181_sender::processSend(void *obj) {
while (gb28181Sender->isRuning) {
uint8_t *pkt_buf = *gb28181Sender->pkt_queue.wait_and_pop().get();
uint16_t len = bytes2short(pkt_buf);
LOGE("get pkt len: %d", len);
// char strBuf[16];
// sprintf(strBuf, "get pkt len: %d", len);
int n;
switch (gb28181Sender->args->outType) {
case 0: // udp
n = gb28181Sender->sendData(pkt_buf + 2, len);
LOGE("get pkt len: %d. sent %d. (queue left size: %d)", len, n, gb28181Sender->pkt_queue.size());
break;
case 1: // tcp
break;
......@@ -72,10 +78,13 @@ int GB28181_sender::closeSender() {
} else {
stoped = 1;
}
int n = 0;
switch (args->outType) {
case 0: // udp
n = closeSocket();
break;
case 1: // tcp
n = closeSocket();
break;
case 2: // file
fout.close();
......@@ -83,6 +92,46 @@ int GB28181_sender::closeSender() {
default:
break;
}
if (n < 0) {
LOGE("close socket error");
}
return n;
}
int GB28181_sender::initSocket(char *hostname, int port) {
//todo
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0){
LOGE("ERROR opening socket");
return sockfd;
}
// struct hostent *server;
// server = gethostbyname(hostname);
// if (server == NULL) {
// LOGE("ERROR, no such host as %s\n", hostname);
// return -1;
// }
/* build the server's Internet address */
bzero((char *) &serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
// bcopy((char *)server->h_addr,
// (char *)&serveraddr.sin_addr.s_addr, server->h_length);
inet_aton(hostname, &serveraddr.sin_addr);
serveraddr.sin_port = htons(port);
serverlen = sizeof(serveraddr);
return 0;
}
int GB28181_sender::sendData(uint8_t *buf, int len) {
int n = sendto(sockfd, buf, len, 0, (const sockaddr *) &serveraddr, serverlen);
return n;
}
int GB28181_sender::closeSocket() {
close(sockfd);
return 0;
}
......@@ -6,6 +6,15 @@
#define GB28181ANDROID_GB28181_SENDER_H
#include <fstream>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/endian.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "base_include.h"
#include "user_arguments.h"
......@@ -33,6 +42,14 @@ private:
int isRuning;
volatile int stoped;
int sockfd;
struct sockaddr_in serveraddr;
int serverlen;
int initSocket(char* hostname, int port);
int sendData(uint8_t * buf, int len);
int closeSocket();
};
......
......@@ -11,6 +11,9 @@
#define PES_HDR_LEN 19
#define RTP_HDR_LEN 12
#define RTP_PKT_END 1
#define RTP_PKT_APPENDING 0
/***
*@remark: ps头的封装,里面的具体数据的填写已经占位,可以参考标准
*@param : pData [in] 填充ps头数据的地址
......@@ -191,12 +194,15 @@ int gb28181_make_pes_header(char *pData, int stream_id, int payload_len, int64_t
}
/***
*@remark: rtp头的封装,里面的具体数据的填写已经占位,可以参考标准
*@param : pData [in] 填充ps头数据的地址
*@return: 0 success, others failed
*/
int gb28181_make_rtp_header(char *pData, int seqNum, int64_t timestamp, int ssrc )
/**
* RTP头封装
* @param pData buffer地址
* @param seqNum 序号
* @param timestamp 时间戳
* @param ssrc 标识
* @return
*/
int gb28181_make_rtp_header(char *pData, int seqNum, int64_t timestamp, int ssrc, int isEnd)
{
bits_buffer_t bitsBuffer;
......@@ -209,7 +215,7 @@ int gb28181_make_rtp_header(char *pData, int seqNum, int64_t timestamp, int ssrc
bits_write(&bitsBuffer, 1, 0); /*P*/
bits_write(&bitsBuffer, 1, 0); /*X*/
bits_write(&bitsBuffer, 4, 0); /*CSRC个数*/
bits_write(&bitsBuffer, 1, 1); /*一帧是否结束*/
bits_write(&bitsBuffer, 1, isEnd); /*一帧是否结束*/
bits_write(&bitsBuffer, 7, 96); /*载荷的数据类型*/
bits_write(&bitsBuffer, 16, seqNum); /*序列号,第几个*/
bits_write(&bitsBuffer, 32, timestamp); /*时间戳,第一个 */
......
......@@ -368,7 +368,7 @@ int GB28181Muxer::mux(GB28181Muxer *gb28181Muxer) {
gb28181Muxer->arguments->v_custom_format);
delete (picture_buf);
gb28181Muxer->pFrame->pts = (v_time - gb28181Muxer->startTime) * 90;
LOGE("v_time: %lld, get a pts:%lld (aduio queue left num: %d, video queue left num: %d)",
LOGE("v_time: %lld, get a pts:%lld (audio queue left num: %d, video queue left num: %d)",
v_time, gb28181Muxer->pFrame->pts, audio_queue.size(), video_queue.size());
int got_picture;
......@@ -384,14 +384,14 @@ int GB28181Muxer::mux(GB28181Muxer *gb28181Muxer) {
int64_t frameDiv = newPts - lastPts;
append = (frameDiv + append) % 3600;
int audioCnt = (frameDiv + append) / 3600;
LOGE("now pts:%lld.|%lld| next pts:%lld,audio count:%d",
gb28181Muxer->nowPkt->pts,
gb28181Muxer->nextPkt->pts - gb28181Muxer->nowPkt->pts,
gb28181Muxer->nextPkt->pts, audioCnt);
// LOGE("now pts:%lld.|%lld| next pts:%lld,audio count:%d",
// gb28181Muxer->nowPkt->pts,
// gb28181Muxer->nextPkt->pts - gb28181Muxer->nowPkt->pts,
// gb28181Muxer->nextPkt->pts, audioCnt);
// 0 rtp header
// gb28181_make_rtp_header(szTempPacketHead + nSizePos, cnt++, lastPts, 1);
// nSizePos += RTP_HDR_LEN;
gb28181_make_rtp_header(szTempPacketHead + nSizePos, cnt++, lastPts, 1, RTP_PKT_END);
nSizePos += RTP_HDR_LEN;
// 1 package for ps header
gb28181_make_ps_header(szTempPacketHead + nSizePos, lastPts);
nSizePos += PS_HDR_LEN;
......@@ -413,7 +413,7 @@ int GB28181Muxer::mux(GB28181Muxer *gb28181Muxer) {
uint16_t pktPos = 0;
uint16_t pkt_len = (uint16_t) (nSizePos + nSize + audioCnt * (PES_HDR_LEN + aFrameLen));
LOGE("pkt_len in muxer: %d", pkt_len);
// LOGE("pkt_len in muxer: %d", pkt_len);
uint8_t *pkt_full = (uint8_t *) malloc(pkt_len + 2);
memcpy(pkt_full, short2Bytes(pkt_len), 2);
pktPos += 2;
......
......@@ -13,6 +13,12 @@ import android.widget.RelativeLayout;
import com.autulin.gb28181library.utils.DeviceUtils;
import java.io.File;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
public class DemoActivity extends AppCompatActivity implements
MediaRecorderBase.OnErrorListener, MediaRecorderBase.OnPreparedListener {
......@@ -43,10 +49,31 @@ public class DemoActivity extends AppCompatActivity implements
mMediaRecorder.endMux();
}
}
// new Thread(runnable).start();
}
});
}
private Runnable runnable = new Runnable() {
@Override
public void run() {
try {
DatagramSocket socket = new DatagramSocket(8888);
InetAddress serverAddress = InetAddress.getByName("10.112.181.160");
String str = "hello";
DatagramPacket pkt = new DatagramPacket (str.getBytes() , str.getBytes().length , serverAddress , 8888);
socket.send(pkt);
socket.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
};
@Override
public void onResume() {
super.onResume();
......@@ -92,8 +119,8 @@ public class DemoActivity extends AppCompatActivity implements
// 设置输出
// String fileName = String.valueOf(System.currentTimeMillis());
String fileName = "tttttt";
mediaOutput = mMediaRecorder.setFileOutPut(fileName); //输出到文件,这里demo是/sdcard/DCIM/pstest/tttttt.ps
// mediaOutput = mMediaRecorder.setUdpOutPut("10.112.181.160", 8888);
// mediaOutput = mMediaRecorder.setFileOutPut(fileName); //输出到文件,这里demo是/sdcard/DCIM/pstest/tttttt.ps
mediaOutput = mMediaRecorder.setUdpOutPut("10.112.181.160", 8888);
mMediaRecorder.setSurfaceHolder(mSurfaceView.getHolder());
mMediaRecorder.prepare();
......
......@@ -20,10 +20,9 @@ public class JNIBridge {
*/
public final static int ROTATE_270_CROP_LT_MIRROR_LR=3;
public final static int TCP = 0;
public final static int UDP = 1;
public final static int UDP = 0;
public final static int TCP = 1;
public static final int FILE = 2;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论