<div dir="ltr"><div><div style="font-family:arial,sans-serif;font-size:10px">Hi</div><div style="font-family:arial,sans-serif;font-size:10px"><br></div><div style="font-family:arial,sans-serif;font-size:10px">I'm trying to use libavformat as RTSP client for pushing stream to server. </div><div style="font-family:arial,sans-serif;font-size:10px">I'm using Darwin Streaming Server. I'm using h264/opus encoding.</div><div style="font-family:arial,sans-serif;font-size:10px"><br></div><div style="font-family:arial,sans-serif;font-size:10px">I find a problem that the sdp file always set audio sampling rate to 48000hz, </div><div style="font-family:arial,sans-serif;font-size:10px">no matter how I set the AVFormatContext before avformat_write_header() call.</div><div style="font-family:arial,sans-serif;font-size:10px"><br></div><div style="font-family:arial,sans-serif;font-size:10px">the sdp file looks like below:</div><div style="font-family:arial,sans-serif;font-size:10px"><br></div><div style="font-family:arial,sans-serif;font-size:10px"><div>v=0</div><div>o=- 0 0 IN IP4 127.0.0.1</div><div>s=No Name</div><div>c=IN IP4 121.***.***.***</div><div>t=0 0</div><div>a=tool:libavformat 55.48.100</div><div>m=video 0 RTP/AVP 96</div><div>b=AS:128</div><div>a=rtpmap:96 H264/90000</div><div>a=fmtp:96 packetization-mode=1</div><div>a=control:streamid=0</div><div>m=audio 0 RTP/AVP 97</div><div>b=AS:16</div><div>a=rtpmap:97 opus/48000</div><div>a=control:streamid=1</div></div><div style="font-family:arial,sans-serif;font-size:10px"><br></div><div style="font-family:arial,sans-serif;font-size:10px">I find that in libavformat/sdp.c file, the 48000 is hard coded. <br></div><div style="font-family:arial,sans-serif;font-size:10px">Is this what meant to be?</div><div style="font-family:arial,sans-serif;font-size:10px">(I've masked out the real ip address)</div><div style="font-family:arial,sans-serif;font-size:10px"><br></div><div style="font-family:arial,sans-serif;font-size:10px"><div>case AV_CODEC_ID_OPUS:</div><div> av_strlcatf(buff, size, "a=rtpmap:%d opus/48000\r\n",</div><div> payload_type);</div><div> break;</div></div><div style="font-family:arial,sans-serif;font-size:10px"><br></div><div style="font-family:arial,sans-serif;font-size:10px">comparing to speex case branch:</div><div style="font-family:arial,sans-serif;font-size:10px"><div><br></div><div>case AV_CODEC_ID_SPEEX:</div><div> av_strlcatf(buff, size, "a=rtpmap:%d speex/%d\r\n",</div><div> payload_type, c->sample_rate);</div></div><div style="font-family:arial,sans-serif;font-size:10px"><br></div><div style="font-family:arial,sans-serif;font-size:10px">it is using the real sample rate, what confused me.</div><div style="font-family:arial,sans-serif;font-size:10px"><br></div><div style="font-family:arial,sans-serif;font-size:10px">below is my code, if there's any mistake please tell me, </div><div style="font-family:arial,sans-serif;font-size:10px">I just learn to use avlibs recently.</div><div style="font-family:arial,sans-serif;font-size:10px">I referenced mostly from this link </div><div style="font-family:arial,sans-serif;font-size:10px"><a href="https://www.ffmpeg.org/doxygen/0.6/output-example_8c-source.html" target="_blank">https://www.ffmpeg.org/doxygen/0.6/output-example_8c-source.html</a></div><div style="font-family:arial,sans-serif;font-size:10px"><br></div><div style="font-family:arial,sans-serif;font-size:10px"><div>int live_rtsp_start(int fps){</div><div> AVOutputFormat *fmt;</div><div> int ret;</div><div> </div><div> const int buffsize = 1024;</div><div> char logbuff[buffsize];</div><div> char server[buffsize];</div><div><br></div><div> av_register_all();</div><div> avformat_network_init();</div><div><br></div><div> //oc = avformat_alloc_context();</div><div> snprintf(server, buffsize, "rtsp://%s/%s", "121.***.***.***", "live12.sdp");</div><div> avformat_alloc_output_context2(&oc, 0, "rtsp", server);</div><div> if (!oc) {</div><div> androidlog("memory error");</div><div> return -1;</div><div> }</div><div> androidlog(oc->filename);</div><div> </div><div> //create video stream</div><div> AVStream * v_stream = avformat_new_stream(oc, NULL);</div><div> if(!v_stream){</div><div> return -4;</div><div> }</div><div> v_stream->id = 0;</div><div><br></div><div> AVCodecContext* codec = v_stream->codec;</div><div> codec->codec_id = CODEC_ID_H264;</div><div> codec->codec_type = AVMEDIA_TYPE_VIDEO;</div><div> codec->width = out_width;</div><div> codec->height = out_height;</div><div> codec->time_base.den = 1;</div><div> codec->time_base.num = fps;</div><div><br></div><div> if(oc->oformat->flags & AVFMT_GLOBALHEADER){</div><div> codec->flags != CODEC_FLAG_GLOBAL_HEADER;</div><div> }</div><div><br></div><div> //create audio stream</div><div> AVStream * a_stream = avformat_new_stream(oc, NULL);</div><div> if(!a_stream){</div><div> return -5;</div><div> }</div><div> a_stream->id = 1;</div><div><br></div><div> AVCodecContext* a_codec = a_stream->codec;</div><div> a_codec->codec_type = AVMEDIA_TYPE_AUDIO;</div><div> a_codec->codec_id = CODEC_ID_OPUS;</div><div> a_codec->channels = 1;</div><div> a_codec->sample_rate = 8000;</div><div> a_codec->time_base = (AVRational){1, a_codec->sample_rate};</div><div> a_codec->frame_size = 320;</div><div> a_codec->bit_rate = 16000;</div><div> //a_codec->codec_tag = av_codec_get_tag(oc, CODEC_ID_OPUS);</div><div> </div><div> if(oc->oformat->flags & AVFMT_GLOBALHEADER){</div><div> a_codec->flags != CODEC_FLAG_GLOBAL_HEADER;</div><div> }</div><div> </div><div> av_dump_format(oc, 0, server ,1);</div><div><br></div><div> androidlog("write header\n");</div><div> ret = avformat_write_header(oc, NULL);</div><div><br></div><div> if(ret < 0){</div><div> av_strerror(ret, logbuff, buffsize);</div><div> androidlog("avformat_write_header err\n");</div><div> androidlog(logbuff);</div><div> return ret;</div><div> }</div><div>}</div></div></div><br clear="all"><div><div dir="ltr">Thanks,<div>Peter</div></div></div>
</div>