live555 server mediacodec应用
来源:互联网 发布:我的世界mac版mod 编辑:程序博客网 时间:2024/05/29 19:51
live555 server + mediacodec
demo: https://github.com/wangzuxing/MyLive555ServerMediaCodec
java端创建缓存文件, 开启camera preview并调用mediacodec编码摄像头预览数据,把视频编码数据写入缓存文件,调用jni端live555的H264VideoFileServerMediaSubsession建立H.264视频文件流服务子会话(简单验证实时的视频流服务功能,文件写入、读出方式实现视频流服务的方式,效率比较低)
Java端:
StreamerActivity2:
static { ... System.loadLibrary("live555"); System.loadLibrary("streamer"); } ... public static native void end(); public static native void RtspTempFile(String filename); //1、创建缓存文件 public static native void WriteRtspFrame(byte[] data, int size); //jni端写编码数据入缓存文件,测试用 public static native int RtspServer(String filename); //2、调用live555的H264VideoFileServerMediaSubsession,实现.264视频文件媒体会话子服务 //yv12 转 yuv420p yvu -> yuv private void swapYV12toI420(byte[] yv12bytes, byte[] i420bytes, int width, int height) { System.arraycopy(yv12bytes, 0, i420bytes, 0,width*height); System.arraycopy(yv12bytes, width*height+width*height/4, i420bytes, width*height,width*height/4); System.arraycopy(yv12bytes, width*height, i420bytes, width*height+width*height/4,width*height/4); } // MediaCodec(类型为"video/avc") 同步编码 public void onFrame(byte[] buf, int length) { swapYV12toI420(buf, h264, width, height); ByteBuffer[] inputBuffers = mediaCodec.getInputBuffers(); ByteBuffer[] outputBuffers = mediaCodec.getOutputBuffers(); int inputBufferIndex = mediaCodec.dequeueInputBuffer(-1); if (inputBufferIndex >= 0) { ByteBuffer inputBuffer = inputBuffers[inputBufferIndex]; inputBuffer.clear(); inputBuffer.put(h264, 0, length); mediaCodec.queueInputBuffer(inputBufferIndex, 0, length, 0, 0); } MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo(); int outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo,0); while (outputBufferIndex >= 0) { ByteBuffer outputBuffer = outputBuffers[outputBufferIndex]; byte[] outData = new byte[bufferInfo.size]; outputBuffer.get(outData); if(runOneFlag){ if(outData.length == 21){ System.arraycopy(outData, 0, outData0, 0, 21); //暂存sps pps,编码器会一次性输出sps和pps包(sps pps长度因视频高、宽等参数会有差异, //编码器输出的nalu单元自动带start code) runOneFlag = false; } } runPushFlag = true; if(runPushFlag) { if(runTestFlag) { frame_count2++; if(frame_count2 >= 50){ //缓存50帧 runTestFlag = false; new Thread() { @Override public void run() { RtspServer(h264Path); //开启RTSPServer的 H264VideoFileServerMediaSubsession } }.start(); } } try { outputStream.write(outData, 0, outData.length); //nalu数据,jav端a写入.264文件, outputStream = new BufferedOutputStream(new FileOutputStream(**)); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //WriteRtspFrame(outData, outData.length); //nalu数据,jni端写入.264文件 mediaCodec.releaseOutputBuffer(outputBufferIndex, false); outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0); } }
JNI端:
streamer.cpp:
JNIEXPORT jint JNICALL Java_com_example_mylive55servermediacodec_StreamerActivity2_RtspServer(JNIEnv *env1, jobject obj, jstring filename){ TaskScheduler* scheduler = BasicTaskScheduler::createNew(); UsageEnvironment* env = BasicUsageEnvironment::createNew(*scheduler); UserAuthenticationDatabase* authDB = NULL; RTSPServer* rtspServer = RTSPServer::createNew(*env, 8554, authDB); if (rtspServer == NULL) { LOGI("Failed to create RTSP server:%s", env->getResultMsg()); return -1; } char const* descriptionString = "Session streamed by \"testOnDemandRTSPServer\""; quit = 0; ServerMediaSession* sms = NULL; // A H.264 video elementary stream: { char const* streamName = "mstreamer"; char const* inputFileName = env1->GetStringUTFChars(filename, NULL); LOGI(" inputFileName = %s", inputFileName); sms = ServerMediaSession::createNew(*env, streamName, streamName, descriptionString); sms->addSubsession(H264VideoFileServerMediaSubsession::createNew(*env, inputFileName, reuseFirstSource0)); rtspServer->addServerMediaSession(sms); announceStream0(rtspServer, sms, streamName, inputFileName); } /* { char const* streamName = "ts"; char const* inputFileName = "/sdcard/H264_720p.ts"; char const* indexFileName = "test.tsx"; ServerMediaSession* sms = ServerMediaSession::createNew(*env, streamName, streamName, descriptionString); sms->addSubsession( MPEG2TransportFileServerMediaSubsession::createNew(*env, inputFileName, indexFileName, reuseFirstSource0)); rtspServer->addServerMediaSession(sms); announceStream0(rtspServer, sms, streamName, inputFileName); } */ if (rtspServer->setUpTunnelingOverHTTP(80) || rtspServer->setUpTunnelingOverHTTP(8000) || rtspServer->setUpTunnelingOverHTTP(8080)) { LOGI("we use port-->%d", rtspServer->httpServerPortNum()); } else { LOGI("RTSP-over-HTTP tunneling is not available."); } env->taskScheduler().doEventLoop(&quit); rtspServer->removeServerMediaSession(sms); Medium::close(rtspServer); env->reclaim(); env = NULL; delete scheduler; scheduler = NULL; LOGI("......End......\n"); return 0;}JNIEXPORT void JNICALL Java_com_example_mylive55servermediacodec_StreamerActivity2_end(JNIEnv *env, jobject obj) { LOGI("Ending streaming...\n"); quit = 1; // Medium::close(rtspServer);}JNIEXPORT void JNICALL Java_com_example_mylive55servermediacodec_StreamerActivity2_RtspTempFile(JNIEnv *env, jobject obj, jstring filename){ char const*inputFilename0 = env->GetStringUTFChars(filename, NULL); inputFilename = inputFilename0; file = fopen(inputFilename0, "wb+"); if (!file) { LOGE("couldn't open %s", inputFilename0); exit(1); } LOGE(" RtspTempFile open %s ", inputFilename0);}//添加视频帧的方法JNIEXPORT void JNICALL Java_com_example_mylive55servermediacodec_StreamerActivity2_WriteRtspFrame( JNIEnv *env, jclass clz, jbyteArray data, jint size){ unsigned char *buf = (unsigned char *)env->GetByteArrayElements(data, JNI_FALSE); //length pthread_mutex_lock(&mutex); int ret = fwrite(buf, 1, size, file); if(ret != 0){ LOGI(" IDR = %d, %d", ret, size); } pthread_mutex_unlock(&mutex); env->ReleaseByteArrayElements(data, (jbyte *)buf, 0);}
0 0
- live555 server mediacodec应用
- live555 mediacodec应用
- mediacodec mp4v2应用
- live555+MediaCodec实现获取并解码RTSP视频(H264)
- LIVE555 Media Server
- live555 server 搭建
- live555 server分析
- Mediacodec
- MediaCodec
- live555 rtsp server android 移植
- 搭建玩live555 RTSP server
- live555直播实现-DM365 DVSDK+live555=RTSP server live
- Android之live555构建RTSP Server
- live555中流媒体server 部分调用关系
- live555 RTSP Server RTP over TCP BUG
- 3531上用live555实现RTSP Server
- MediaCodec storeMetaDataInBuffers应用自己分配buffer设给编码器
- live555
- 图片文件与Bitmap对象的互相转化
- CentOS7的firewall相关操作
- 影响数据安全的要素
- 铝合金门窗选购的选购经验
- 关于网页分享
- live555 server mediacodec应用
- mysql导出建表语句
- Java Web +Servlet 文件下载功能
- 苹果开发者计划许可协议2017年5月2日(发布时间)
- 智能指针
- c#常用操作小技巧
- Mac下配置android环境变量
- What is verify.dll doing on my computer?
- IIC设备驱动程序(五)————IIC设备实例化的四种方法