参照openRTSP写的一个RTSP client 加了一些注解

#include "liveMedia.hh"  
#include "BasicUsageEnvironment.hh"  
#include "GroupsockHelper.hh"  
UsageEnvironment* env;  
portNumBits tunnelOverHTTPPortNum = 0;  
const char * url="rtsp://127.0.0.1:1935/vod/Extremists.m4v";  
#if defined(__WIN32__) || defined(_WIN32)  
#define snprintf _snprintf  
#endif  
int main(int argc,const char ** argv)  
{  
    //创建BasicTaskScheduler对象  
    TaskScheduler* scheduler = BasicTaskScheduler::createNew();  
    //创建BisicUsageEnvironment对象  
    env = BasicUsageEnvironment::createNew(*scheduler);  
    //创建RTSPClient对象  
    RTSPClient * rtspClient= RTSPClient::createNew(*env);  
    //由RTSPClient对象向服务器发送OPTION消息并接受回应  
    char* optionsResponse=rtspClient->sendOptionsCmd(url);  
    delete [] optionsResponse;  
    //产生SDPDescription字符串(由RTSPClient对象向服务器发送DESCRIBE消息并接受回应,根据回应的信息产生SDPDescription字符串,其中包括视音频数据的协议和解码器类型)  
    char* sdpDescription =rtspClient->describeURL(url);  
    //创建MediaSession对象(根据SDPDescription在MediaSession中创建和初始化MediaSubSession子会话对象)  
    MediaSession* session = MediaSession::createNew(*env, sdpDescription);  
    delete[] sdpDescription;  
 
    MediaSubsessionIterator iter(*session);  
    MediaSubsession *subsession;  
    while ((subsession = iter.next()) != NULL) {  
        // Creates a "RTPSource" for this subsession. (Has no effect if it's  
        // already been created.)  Returns True iff this succeeds.  
        if (!subsession->initiate()) {  
            *env << "Unable to create receiver for "" << subsession->mediumName()  
                << "/" << subsession->codecName()  
                << "" subsession: " << env->getResultMsg() << "\n";  
        } else {  
            *env << "Created receiver for "" << subsession->mediumName()  
                << "/" << subsession->codecName()  
                << "" subsession (client ports " << subsession->clientPortNum()  
                << "-" << subsession->clientPortNum()+1 << ")\n";  
            if (subsession->rtpSource() != NULL) {  
                // Because we're saving the incoming data, rather than playing  
                // it in real time, allow an especially large time threshold  
                // (1 second) for reordering misordered incoming packets:  
                unsigned const thresh = 1000000; // 1 second  
                subsession->rtpSource()->setPacketReorderingThresholdTime(thresh);  
                // Set the RTP source's OS socket buffer size as appropriate - either if we were explicitly asked (using -B),  
                // or if the desired FileSink buffer size happens to be larger than the current OS socket buffer size.  
                // (The latter case is a heuristic, on the assumption that if the user asked for a large FileSink buffer size,  
                // then the input data rate may be large enough to justify increasing the OS socket buffer size also.)  
                int socketNum = subsession->rtpSource()->RTPgs()->socketNum();  
                unsigned curBufferSize = getReceiveBufferSize(*env, socketNum);  
                unsigned newBufferSize = setReceiveBufferTo(*env, socketNum, 100000);  
 
            }  
        }  
    }  
    //由RTSPClient对象向服务器发送SETUP消息并接受回应  
    iter.reset();  
    while ((subsession = iter.next()) != NULL) {  
        if (subsession->clientPortNum() == 0) continue; // port # was not set  
        if (!rtspClient->setupMediaSubsession(*subsession)) {  
            *env << "Failed to setup "" << subsession->mediumName()  
                << "/" << subsession->codecName()  
                << "" subsession: " << env->getResultMsg() << "\n";  
        } else {  
            *env << "Setup "" << subsession->mediumName()  
                << "/" << subsession->codecName()  
                << "" subsession (client ports " << subsession->clientPortNum()  
                << "-" << subsession->clientPortNum()+1 << ")\n";  
        }  
        if (subsession->rtpSource() != NULL) {  
            // Because we're saving the incoming data, rather than playing  
            // it in real time, allow an especially large time threshold  
            // (1 second) for reordering misordered incoming packets:  
            unsigned const thresh = 1000000; // 1 second  
            subsession->rtpSource()->setPacketReorderingThresholdTime(thresh);  
        }  
    }  
    iter.reset();  
    while ((subsession = iter.next()) != NULL) {  
        if (subsession->readSource() == NULL) continue; // was not initiated  
        char outFileName[1000];  
        static unsigned streamCounter = 0;  
        snprintf(outFileName, sizeof outFileName, "%s-%s-%d",  
            subsession->mediumName(),  
            subsession->codecName(), ++streamCounter);  
        FileSink* fileSink;  
        if (strcmp(subsession->mediumName(), "audio") == 0 &&  
            (strcmp(subsession->codecName(), "AMR") == 0 ||  
            strcmp(subsession->codecName(), "AMR-WB") == 0)) {  
                // For AMR audio streams, we use a special sink that inserts AMR frame hdrs:  
                fileSink = AMRAudioFileSink::createNew(*env, outFileName);  
        } else if (strcmp(subsession->mediumName(), "video") == 0 &&  
            (strcmp(subsession->codecName(), "H264") == 0)) {  
                // For H.264 video stream, we use a special sink that insert start_codes:  
                unsigned int num=0;  
                SPropRecord * sps=parseSPropParameterSets(subsession->fmtp_spropparametersets(),num);  
                fileSink = H264VideoFileSink::createNew(*env, outFileName,100000);  
                struct timeval tv={0,0};  
                unsigned char start_code[4] = {0x00, 0x00, 0x00, 0x01};  
                fileSink->addData(start_code, 4, tv);  
                fileSink->addData(sps[0].sPropBytes,sps[0].sPropLength,tv);  
                fileSink->addData(start_code, 4, tv);  
                fileSink->addData(sps[1].sPropBytes,sps[1].sPropLength,tv);  
                delete[] sps;  
        } else {  
            // Normal case:  
            fileSink = FileSink::createNew(*env, outFileName);  
        }  
        subsession->sink = fileSink;  
        subsession->sink->startPlaying(*(subsession->readSource()),NULL,NULL);  
    }  
    rtspClient->playMediaSession(*session, 0.0f, 0.0f, (float)1.0);  
    env->taskScheduler().doEventLoop(); // does not return  
    return 0; // only to prevent compiler warning  

时间: 2024-09-13 19:37:42

参照openRTSP写的一个RTSP client 加了一些注解的相关文章

按钮-自己参照书本写了一个Java Swing中的容器类入门程序设计,但是运行结果不对,求大神帮帮忙!

问题描述 自己参照书本写了一个Java Swing中的容器类入门程序设计,但是运行结果不对,求大神帮帮忙! /*题目是这样的:创建一个窗体在其中摆放两个内容面板对两个面板进行边框个性化设置.初始状态为第二个面板不可见,当单击第一个面板中的"打开"按钮时,第二个面板即可见:当单击第一个面板中的"关闭"按钮时,第二个面板消失. 以下是我结合书本写的代码,不知道为什么运行不了???*/import javax.swing.*;import java.awt.*;impor

用c# 写的一个tcp client 发一个指令再读硬件发回来的数据,无法读取

问题描述 用c# 写的一个tcp client 发一个指令再读硬件发回来的数据,无法读取 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Window

java-在Android中写一个浏览器,加载一个登录页面如何获取用户名和密码框

问题描述 在Android中写一个浏览器,加载一个登录页面如何获取用户名和密码框 在Android中写一个浏览器,记住密码功能怎么写?大神,请指教. 解决方案 webview加载你的登录页面,登录完了后取cookie或其他认证信息(这个和你登录的网站是如何设计的有关) 解决方案二: 用webview 啊 解决方案三: 用sharedpreference来保存密码或者是账号 解决方案四: 这两个输入框是浏览器的还是网页的?

spring mvc-我用springMVC写了一个web项目,加载到tomcat8上后启动出现此异常,请懂得的来帮忙看下

问题描述 我用springMVC写了一个web项目,加载到tomcat8上后启动出现此异常,请懂得的来帮忙看下 异常信息如下: 严重: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/spring_mvc]] at or

javascript写的一个模拟阅读小说的程序

 这篇文章主要介绍了用javascript写了一个模拟阅读小说的程序,需要的朋友可以参考下  代码如下: <html>  <meta http-equiv="content-type" content="text/html; charset=UTF-8" />  <head>  <title></title>  <script type="text/javascript"> 

c#-c++写的一个简单学生信息管理系统,求助。

问题描述 c++写的一个简单学生信息管理系统,求助. 编译不报错,就是运行不出来 #include<iostream.h> #include<stdio.h> #include<string.h> class student//定义学生信息类 {public: char name[20]; char num[10]; char banji[20]; int math,english,chinese,computer; int sum; double ave; void

app-#安卓 自己写了一个可以连发数据的蓝牙APP可是运行时候崩溃了

问题描述 #安卓 自己写了一个可以连发数据的蓝牙APP可是运行时候崩溃了 本人菜鸟 先用Ontouch方法 + while循环 + thread休眠写了一个每隔100ms 按钮连续发送数据的蓝牙APP 但是在使用过程中 配对 以及连接蓝牙之后 可以发送大概5分钟 APP就崩溃了 崩溃是指:蓝牙还和我的手机连着 但是整个APP 按按钮没反应 也发送不了数据 但是其他菜单栏可以点开 关掉APP重开,APP就打不开了 只能关掉蓝牙设备 然后再打开APP 之后学习了handler用法 试着写了一段 整个

java代码-我用Java 写的一个简单截图小工具 但是出现一些在重截时出现bug 跪求大神

问题描述 我用Java 写的一个简单截图小工具 但是出现一些在重截时出现bug 跪求大神 /**在这里贴上我注释满满的代码 求一语道破 求建议 求批评 没有贴main 方法 随便写个main方法便可运行 */ ` package com.subimaga; import java.awt.AWTException; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Cursor; import java.

[原创](2010.02.07更新)忙里偷闲中写的一个系统物理/虚拟内存查看器。

[原创]忙里偷闲中写的一个系统物理/虚拟地址内容查看器     都是老技术,没啥新意.为了方便我在调试中要了解虚拟或物理内存的情况编写的,懒得装WinDbg 的情况下比较方便.程序在gccNTDrvFrame(我以前写的gcc下的NT驱动通用开发包)的基础上扩展, 并且由于直接使用微软"特有"的__try,__except功能方便些,故和VC 2008生成的obj一起连接,此外使用了MASM32V10.0写了关分页传送数据部分的代码.GUI全部用SDK编写,没有用任何图形库.所以程序体