我正在编写自定义DirectShow源推送过滤器,它应该从视频服务器接收RTP数据并将它们推送到渲染器.我写了一个CVideoPushPin类,它继承自CSourceStream和CVideoReceiverThread类,它是从视频服务器接收RTP数据包的线程的包装器.接收者线程基本上做了三件事:
组装帧,将它们复制到缓冲区并将有关它们的信息存储到256个元素队列中,其定义如下:
struct queue_elem {
char *start; // Pointer to a frame in a buffer
int length; // Lenght of data
REFERENCE_TIME recvTime; // Timestamp when the frame was received (stream time)
};
struct data {
struct queue_elem queue[QUEUE_LENGTH];
int qWrIdx;
int qRdIdx;
HANDLE mutex;
};
Run Code Online (Sandbox Code Playgroud)每个接收到的帧都用当前流时间加上时间戳
p->StreamTime(refTime);
REFERENCE_TIME rt = refTime.GetUnits();
Run Code Online (Sandbox Code Playgroud)问题是我不知道如何在FillBuffer方法中为每个MediaSample设置时间戳.我尝试了几种方法,但播放要么停止,要么太慢.目前FillBuffer方法如下所示:
REFERENCE_TIME thisFrameStartTime, thisFrameEndTime;
// Make sure if there are at least 4 frames in the buffer
if(noOfFrames >= 4)
{
currentQe = m_myData.queue[m_myData.qRdIdx++]; //Take current …Run Code Online (Sandbox Code Playgroud) 我将在Android上制作一个PTT项目.您能否告诉我Android有多深入支持语音和多媒体API(如RTP,RTSP,VoIP)?
我正在寻找一种使用和通过互联网流式传输预先录制的MP3或WAV文件的方法。现在的主要绊脚石是如何从文件及其中获取a ,以便可以像通过麦克风或摄像机发出的流一样传递它。SIPRTPstreamsynchronizeRTP
在ffmpeg streamingGuide中,它写道:
ffmpeg -re -f lavfi -i aevalsrc="sin(400*2*PI*t)" -ar 8000 -f mulaw -f rtp rtp://127.0.0.1:1234 &
ffplay rtp://127.0.0.1:1234
Run Code Online (Sandbox Code Playgroud)
我想用一个真实的视频文件来取代人工信号.然后我在终端A写下面:
ffmpeg -re -i outputFile.avi -f mulaw -f rtp rtp://127.0.0.1:1234
Run Code Online (Sandbox Code Playgroud)
它似乎工作:框架信息正在计数.以下是终端A的信息:
frame= 309 fps= 29 q=31.0 Lsize= 931kB time=00:00:10.30 bitrate= 740.8kbits/s video:922kB audio:0kB subtitle:0 global headers:0kB muxing overhead 1.030813%
Run Code Online (Sandbox Code Playgroud)
当终端A的帧仍在计数(未完成)时,我在终端B输入以下内容:
ffplay rtp://127.0.0.1:1234
Run Code Online (Sandbox Code Playgroud)
但它不起作用:错误信息是:
[udp @ 0x7fb370001500] bind failed: Address already in useB f=0/0
rtp://127.0.0.1:1234: Input/output error
Run Code Online (Sandbox Code Playgroud)
为什么?
[更新1]按照Camille Goudeseune的指示,我使用了foo.sdp
ffmpeg终端的输入是:
ffmpeg -re -i out.avi -f mulaw -f rtp rtp://127.0.0.1:1235
ffplay的终端是: …
我想要完成的事情:
我正在创建一个基于Linux的机器人,它将接收麦克风输入,发送Windows机器,它将使用Microsoft语音识别处理音频并将响应发送回机器人.机器人可能距离服务器数百英里,所以我想在互联网上这样做.
到目前为止我做了什么:
我需要帮助的是:
我坚持如何实际将流从VLC发送到SpeechRecognitionEngine.VLC根本不公开流.有没有办法可以捕获流并将该流对象传递给SpeechRecognitionEngine?或者RTP不是解决方案吗?
在此先感谢您的帮助.
我正在测试移动设备之间的音频/视频P2P连接。
在学习WebRTC时,我注意到NAT遍历(使用STUN服务器),而UDP漏洞打孔是使P2P成为可能的关键。
另一方面,我注意到iOS设备上的HLS(HttpLiveStreaming)针对A / V实时流进行了非常优化,甚至在Android4.x(3.x不稳定)下也可以广泛使用。
所以,这是我的问题,如果我将HLS用于移动P2P:
a)HLS是基于TCP(HTTP)而不是UDP的协议,因此是否存在性能缺陷?
请参阅:视频流上的TCP与UDP
b)NAT遍历如何?因为HLS是HTTP(port:80),会更容易吗?我已阅读维基百科http://en.wikipedia.org/wiki/HTTP_Live_Streaming
由于其请求仅使用标准HTTP事务,因此HTTP Live Streaming能够遍历允许通过标准HTTP流量的任何防火墙或代理服务器,这与基于RTP的基于UDP的协议不同。这也允许通过广泛可用的CDN传递内容。
c)android设备兼容性如何?调用StreamingLive分发是否有很多问题?
谢谢。
从sdp中的profile-level-id中识别h264配置文件和级别?
如何识别约束实际意味着什么?例如,我有一个profile-type-id: 42801e转换为:

我如何将其与此处表格中定义的功能相关联?
上述参考文献确定,这Constraint_set0_flag: 1意味着它是约束基线轮廓.但是如何将旗帜与三个不同的NO(来自表格)相关联,以区分基线轮廓和约束基线轮廓?
更新
无法确认上述,关于识别Constrained Baseline profile,是否正确.该声明的参考(第306页):
Decoders conforming to the Constrained Baseline profile at a
specific level shall be capable of decoding all bitstreams
in which all of the following are true:
– profile_idc is equal to 66 or constraint_set0_flag is equal to 1,
– constraint_set1_flag is equal to 1,
– level_idc and constraint_set3_flag represent a level
less than or …Run Code Online (Sandbox Code Playgroud) 我正在为Android构建VOIP应用程序,并使用内置的RTP工具android.net.rtp。除以下问题外,一切工作正常:
请记住,对于AudioStream,我正在使用PCMU编解码器,而远程方也是如此。
以下是一些关键代码:
初始化音频设施(一次):
public class SoundManager implements AudioManager.OnAudioFocusChangeListener {
Context appContext;
AudioManager audio;
AudioStream audioStream;
AudioGroup audioGroup;
InetAddress localAddress;
private static final String TAG = "SoundManager";
public SoundManager(Context appContext, String ip){
this.appContext = appContext;
audio = (AudioManager) appContext.getSystemService(Context.AUDIO_SERVICE);
try {
localAddress = InetAddress.getByName(ip);
audioGroup = new AudioGroup();
audioGroup.setMode(AudioGroup.MODE_ECHO_SUPPRESSION);
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
初始化AudioSession(在每次通话开始之前一次)
public int setupAudioStream() {
Log.i(TAG, "Setting up Audio Stream");
try {
audioStream = new AudioStream(localAddress);
audioStream.setCodec(AudioCodec.PCMU);
audioStream.setMode(RtpStream.MODE_NORMAL);
}
catch (SocketException …Run Code Online (Sandbox Code Playgroud) 使用Kurento Media Server在iOS应用程序中实现屏幕共享(重放工具包).我得到遵循RTMP协议的CMSampleBuffer.但Kurento不支持RTMP.它确实支持RTP.有没有办法从RTMP转换为RTP.我读到了关于ffmpeg的内容,但似乎需要在服务器端实现,这需要对当前流程进行大量更改,例如下面的[浏览器] - > RTMP - > [Node_Media_Server(srs)] - > RTMP - >
[FFmpeg] - > RtpEndpoint - > [Kurento] - > WebrtcEndpoint - > [浏览器]
这种流程是否足够有效?
有没有办法从客户端转换它,即iOS应用程序?
我使用Intel硬件MFT将NV12帧编码为H264流,并使用Live555通过LAN上的RTP通过流传输编码的帧,并在另一端进行ffplay设置以解码和显示它们。该设置可以与软件编码器(SYNC或ASYNC软件MFT)配合使用,但是ffplay抱怨当在Intel硬件MFT中完成编码时,SPS / PPS不可用,并且仅显示一个乱码。我发现英特尔硬件编码器在馈入初始样本并通过MF_MT_MPEG_SEQUENCE_HEADER使SPS / PPS可用之后触发MF_E_TRANSFORM_STREAM_CHANGE事件。我能够捕获该MF_E_TRANSFORM_STREAM_CHANGE事件并获取序列标头blob。
问题是,Live555需要分别设置SPS和PPS。但是,我对于从MF_MT_MPEG_SEQUENCE_HEADER blob中提取SPS和PPS感到非常困惑。
根据我的理解以及在其他线程中的进一步查找,SPS和PPS分别以00 00 00 01 67和0 00 00 01 68开头。但是,我在从英特尔编码器收到的Blob中找不到任何序列。
https://github.com/cisco/openh264/issues/756 SPS的开始:00 00 00 01 67 PPS的开始:00 00 00 01 68
从intel MFT获得的序列头:
序列头大小50
冒号头:0 0 1 27 64 0 28 ac 2b 40 3c 1 13 f2 e0 22 0 0 3 0 2 0 0 3 0 79 d0 80 f 42 0 3 d0 93 7b df 7 68 70 ca 80 0 0 0 1 28 ee 3c b0 …