java版本的RtpStream

简介: java版本的RtpStream

今天在家里的机器上,打开Eclipse,类删除也不编译出错,不知道哪里的问题。以后有机会,把这些代码编译后放出来。当初也是从网上搜索到了,略微整理而已。

package com.newayte.rtp.clinet;
import android.os.HandlerThread;
import android.os.Handler;
import com.newayte.toolkit.Log;
import java.util.concurrent.LinkedBlockingDeque;
/**
 *This class is used to analysis the data from rtp socket , recombine it to video or audio stream
 * 1. get the data from rtp socket
 * 2. put the data into buffer
 * 3. use the thread to get the data from buffer, and unpack it
 */
public abstract class RtpStream {
    private final static String TAG = RtpStream.class.getCanonicalName();
    protected final static int TRACK_VIDEO = 0x01;
    protected final static int TRACK_AUDIO = 0x02;
    public    final static int DATA_AUDIO = 0x08;
    public    final static int DATA_VIDEO = 0x60;
    private Handler mHandler;
    private HandlerThread thread;
    private boolean isStoped;
    private int oldSeqNum;
    protected class StreamPacks {
        public boolean mark;
        public int pt;
        public long timestamp;
        public int sequenceNumber;
        public long Ssrc;
        public byte[] data;
    }
    private static class bufferUnit {
        public byte[] data;
        public int len;
    }
    private static LinkedBlockingDeque<bufferUnit> bufferQueue = new LinkedBlockingDeque<bufferUnit>();
    public RtpStream() {
        thread = new HandlerThread("RTPStreamThread");
        thread.start();
        mHandler = new Handler(thread.getLooper());
        unpackThread();
        isStoped = false;
        oldSeqNum = -1;
    }
    public static void receiveData(byte[] data, int len) {
        bufferUnit tmpBuffer = new bufferUnit();
        tmpBuffer.data = new byte[len];
        System.arraycopy(data,0,tmpBuffer.data,0,len);
        tmpBuffer.len = len;
        try {
            bufferQueue.put(tmpBuffer);
        } catch (InterruptedException e) {
        }
    }
    private void unpackThread() {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                bufferUnit tmpBuffer;
                while (!isStoped) {
                    try {
                        tmpBuffer = bufferQueue.take();
                        byte[] buffer = new byte[tmpBuffer.len];
                        System.arraycopy(tmpBuffer.data,0,buffer,0,tmpBuffer.len);
                        unpackData(buffer);
                    } catch (InterruptedException e) {
                        //Log.e(TAG,"wait the new data into the queue..");
                        break;
                    }
                }
                bufferQueue.clear();
            }
        });
    }
    public void stop(){
        isStoped = true;
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        bufferQueue.clear();
        thread.quit();
    }
    protected abstract void recombinePacket(StreamPacks sp);
    private void unpackData(final byte[] buffer) {
        if (buffer == null || buffer.length == 0)
        {
          return;
        }
        if (((buffer[0]&0xFF)>>6) != 2)
        {
        Log.d(TAG, "ERROR!!!");
            return;
        }
        int size = buffer.length;
        if ((buffer[0] & 0x20) > 0)
        {
          int paddingLength = (buffer[size-1] & 0xFF);
          if (paddingLength + 12 > size)
          {
            Log.d(TAG, "ERROR!!!");
            return;
          }
        }
        int numCSRCs = (buffer[0] & 0x0F);
        int payloadOffset = 12 + 4 * numCSRCs;
        if (size < payloadOffset)
        {
          Log.d(TAG, "ERROR!!!");
        return;
        }
        if ((buffer[0] & 0x10) > 0) {
            // Header eXtension present.
            if (size < payloadOffset + 4) {
                // Not enough data to fit the basic header, all CSRC entries
                // and the first 4 bytes of the extension header.
              Log.d(TAG, "ERROR!!!");
            return;
            }
            int extensionLength = 4 * (buffer[payloadOffset+2] << 8 | buffer[payloadOffset+3]);
            if (size < payloadOffset + 4 + extensionLength)
            {
              Log.d(TAG, "ERROR!!!");
            return;
            }
            payloadOffset += 4 + extensionLength;
        }
        StreamPacks tmpStreampack = new StreamPacks();
        tmpStreampack.mark           =  (buffer[1] & 0x80) >> 7 == 1;
        tmpStreampack.pt             =   buffer[1] & 0x7F;
        tmpStreampack.sequenceNumber = ((buffer[2] & 0xFF) <<  8) |  (buffer[3] & 0xFF);
        tmpStreampack.timestamp    = ((buffer[4] & 0xFF) << 24) | ((buffer[5] & 0xFF) << 16) | ((buffer[ 6] & 0xFF) << 8) | (buffer[ 7] & 0xFF);
        tmpStreampack.Ssrc       = ((buffer[8] & 0xFF) << 24) | ((buffer[9] & 0xFF) << 16) | ((buffer[10] & 0xFF) << 8) | (buffer[11] & 0xFF);
        int dataSize = size-payloadOffset;
        //Log.d(TAG, "size="+size+", payloadOffset="+payloadOffset+", "+dataSize);
        if (dataSize > 0)
        {
          tmpStreampack.data = new byte[dataSize];
          System.arraycopy(buffer, payloadOffset, tmpStreampack.data, 0, dataSize);
          if (oldSeqNum==-1)
          {
            oldSeqNum = tmpStreampack.sequenceNumber;
          }
          if (tmpStreampack.sequenceNumber - oldSeqNum>1)
          {
              //Log.e(TAG, "RTP lost packet:"+oldSeqNum+"..."+tmpStreampack.sequenceNumber);
          }
          oldSeqNum = tmpStreampack.sequenceNumber;
          recombinePacket(tmpStreampack);
        }
    }
}
目录
相关文章
|
2月前
|
安全 Java API
Java 17 及以上版本核心特性在现代开发实践中的深度应用与高效实践方法 Java 开发实践
本项目以“学生成绩管理系统”为例,深入实践Java 17+核心特性与现代开发技术。采用Spring Boot 3.1、WebFlux、R2DBC等构建响应式应用,结合Record类、模式匹配、Stream优化等新特性提升代码质量。涵盖容器化部署(Docker)、自动化测试、性能优化及安全加固,全面展示Java最新技术在实际项目中的应用,助力开发者掌握现代化Java开发方法。
106 1
|
7月前
|
JavaScript NoSQL Java
接替此文【下篇-服务端+后台管理】优雅草蜻蜓z系统JAVA版暗影版为例-【蜻蜓z系列通用】-2025年全新项目整合搭建方式-这是独立吃透代码以后首次改变-独立PC版本vue版搭建教程-优雅草卓伊凡
接替此文【下篇-服务端+后台管理】优雅草蜻蜓z系统JAVA版暗影版为例-【蜻蜓z系列通用】-2025年全新项目整合搭建方式-这是独立吃透代码以后首次改变-独立PC版本vue版搭建教程-优雅草卓伊凡
360 96
接替此文【下篇-服务端+后台管理】优雅草蜻蜓z系统JAVA版暗影版为例-【蜻蜓z系列通用】-2025年全新项目整合搭建方式-这是独立吃透代码以后首次改变-独立PC版本vue版搭建教程-优雅草卓伊凡
|
4月前
|
JavaScript Java 关系型数据库
家政系统源码,java版本
这是一款基于SpringBoot后端框架、MySQL数据库及Uniapp移动端开发的家政预约上门服务系统。
143 6
家政系统源码,java版本
|
Java 中间件 测试技术
java依赖冲突解决问题之jar包版本冲突无法通过升降级解决时如何解决
java依赖冲突解决问题之jar包版本冲突无法通过升降级解决时如何解决
|
Java 应用服务中间件 Windows
【应用服务 App Service】App Service 中部署Java项目,查看Tomcat配置及上传自定义版本
【应用服务 App Service】App Service 中部署Java项目,查看Tomcat配置及上传自定义版本
127 0
|
11月前
|
缓存 Java Maven
java: 警告: 源发行版 11 需要目标发行版 11 无效的目标发行版: 11 jdk版本不符,项目jdk版本为其他版本
如何解决Java项目中因JDK版本不匹配导致的编译错误,包括修改`pom.xml`文件、调整项目结构、设置Maven和JDK版本,以及清理缓存和重启IDEA。
476 2
java: 警告: 源发行版 11 需要目标发行版 11 无效的目标发行版: 11 jdk版本不符,项目jdk版本为其他版本
|
10月前
|
Java Linux Windows
如何查看已安装的 Java 版本
要查看已安装的 Java 版本,打开命令提示符或终端,输入 `java -version`,回车后即可显示当前系统中 Java 的版本信息。
3451 1
|
10月前
|
Ubuntu Java Linux
如何检查 Java 版本是否兼容
要检查Java版本是否兼容,可在命令行输入“java -version”查看当前安装的Java版本,然后对比目标应用所需的Java版本,确保其满足要求。
723 1
|
11月前
|
Java Docker 容器
java版本学习网站又添加了一个libgdx模块
java版本学习网站之前添加了docker,想了想还是再把libgdx添加进去吧。
113 3
|
12月前
|
Java
java版本详解
java版本详解