Commit 4f0b19a2 authored by Tristan Matthews's avatar Tristan Matthews
Browse files

* #13814: video: use local profile-level-id in negotiation

parent e1855c43
......@@ -226,7 +226,10 @@ Sdp::setMediaDescriptorLine(bool audio)
std::ostringstream os;
// FIXME: this should not be hardcoded, it will determine what profile and level
// our peer will send us
os << "fmtp:" << dynamic_payload << " " << libav_utils::MAX_H264_PROFILE_LEVEL_ID;
std::string profileLevelID(video_codec_list_[i]["parameters"]);
if (profileLevelID.empty())
profileLevelID = libav_utils::MAX_H264_PROFILE_LEVEL_ID;
os << "fmtp:" << dynamic_payload << " " << profileLevelID;
med->attr[med->attr_count++] = pjmedia_sdp_attr_create(memPool_, os.str().c_str(), NULL);
}
#endif
......@@ -431,12 +434,16 @@ string Sdp::getLineFromSession(const pjmedia_sdp_session *sess, const string &ke
return "";
}
// FIXME:
// Here we filter out parts of the SDP that libavformat doesn't need to
// know about...we should probably give the video decoder thread the original
// SDP and deal with the streams properly at that level
string Sdp::getIncomingVideoDescription() const
{
stringstream ss;
ss << "v=0" << std::endl;
ss << "o=- 0 0 IN IP4 " << localIpAddr_ << std::endl;
ss << "s=sflphone" << std::endl;
ss << "s=" << PACKAGE_NAME << std::endl;
ss << "c=IN IP4 " << remoteIpAddr_ << std::endl;
ss << "t=0 0" << std::endl;
......@@ -454,6 +461,11 @@ string Sdp::getIncomingVideoDescription() const
std::string vCodecLine(getLineFromSession(activeLocalSession_, s.str()));
ss << vCodecLine << std::endl;
std::string profileLevelID;
getProfileLevelID(activeLocalSession_, profileLevelID, payload_num);
if (not profileLevelID.empty())
ss << "a=fmtp:" << payload_num << " " << profileLevelID << std::endl;
unsigned videoIdx;
for (videoIdx = 0; videoIdx < activeLocalSession_->media_count and pj_stricmp2(&activeLocalSession_->media[videoIdx]->desc.media, "video") != 0; ++videoIdx)
;
......@@ -527,11 +539,12 @@ Sdp::getOutgoingVideoPayload() const
}
void
Sdp::getOutgoingProfileLevelID(std::string &profile, int payload) const
Sdp::getProfileLevelID(const pjmedia_sdp_session *session,
std::string &profile, int payload) const
{
std::ostringstream os;
os << "a=fmtp:" << payload;
string fmtpLine(getLineFromSession(activeRemoteSession_, os.str()));
string fmtpLine(getLineFromSession(session, os.str()));
const std::string needle("profile-level-id=");
const size_t DIGITS_IN_PROFILE_LEVEL_ID = 6;
const size_t needleLength = needle.size() + DIGITS_IN_PROFILE_LEVEL_ID;
......@@ -669,7 +682,7 @@ bool Sdp::getOutgoingVideoSettings(map<string, string> &args) const
os << payload;
args["payload_type"] = os.str();
// override with profile-level-id from remote, if present
getOutgoingProfileLevelID(args["parameters"], payload);
getProfileLevelID(activeRemoteSession_, args["parameters"], payload);
}
return true;
}
......
......@@ -251,7 +251,7 @@ class Sdp {
std::string getOutgoingVideoCodec() const;
std::string getOutgoingVideoField(const std::string &codec, const char *key) const;
int getOutgoingVideoPayload() const;
void getOutgoingProfileLevelID(std::string &dest, int payload) const;
void getProfileLevelID(const pjmedia_sdp_session *session, std::string &dest, int payload) const;
/**
* The pool to allocate memory, ownership to SipCall
......
......@@ -100,6 +100,18 @@ void VideoReceiveThread::loadSDP()
os.close();
}
void VideoReceiveThread::openDecoder()
{
if (decoderCtx_)
avcodec_close(decoderCtx_);
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53, 6, 0)
int ret = avcodec_open(decoderCtx_, inputDecoder_);
#else
int ret = avcodec_open2(decoderCtx_, inputDecoder_, NULL);
#endif
EXIT_IF_FAIL(ret == 0, "Could not open codec");
}
// We do this setup here instead of the constructor because we don't want the
// main thread to block while this executes, so it happens in the video thread.
void VideoReceiveThread::setup()
......@@ -162,15 +174,10 @@ void VideoReceiveThread::setup()
decoderCtx_ = inputCtx_->streams[streamIndex_]->codec;
// find the decoder for the video stream
AVCodec *inputDecoder = avcodec_find_decoder(decoderCtx_->codec_id);
EXIT_IF_FAIL(inputDecoder, "Unsupported codec");
inputDecoder_ = avcodec_find_decoder(decoderCtx_->codec_id);
EXIT_IF_FAIL(inputDecoder_, "Unsupported codec");
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53, 6, 0)
ret = avcodec_open(decoderCtx_, inputDecoder);
#else
ret = avcodec_open2(decoderCtx_, inputDecoder, NULL);
#endif
EXIT_IF_FAIL(ret == 0, "Could not open codec");
openDecoder();
scaledPicture_ = avcodec_alloc_frame();
EXIT_IF_FAIL(scaledPicture_, "Could not allocate output frame");
......@@ -207,7 +214,7 @@ int VideoReceiveThread::interruptCb(void *ctx)
}
VideoReceiveThread::VideoReceiveThread(const std::string &id, const std::map<string, string> &args) :
args_(args), frameNumber_(0), decoderCtx_(0), rawFrame_(0),
args_(args), frameNumber_(0), inputDecoder_(0), decoderCtx_(0), rawFrame_(0),
scaledPicture_(0), streamIndex_(-1), inputCtx_(0), imgConvertCtx_(0),
dstWidth_(0), dstHeight_(0), sink_(), receiving_(false), sdpFilename_(),
bufferSize_(0), id_(id), interruptCb_(), requestKeyFrameCallback_(0)
......@@ -261,8 +268,11 @@ void VideoReceiveThread::run()
int frameFinished = 0;
const int len = avcodec_decode_video2(decoderCtx_, rawFrame_, &frameFinished,
&inpacket);
if (len <= 0 and requestKeyFrameCallback_)
if (len <= 0 and requestKeyFrameCallback_) {
openDecoder();
requestKeyFrameCallback_(id_);
usleep(250000);
}
// we want our rendering code to be called by the shm_sink,
// because it manages the shared memory synchronization
......
......@@ -60,6 +60,7 @@ class VideoReceiveThread : public ost::Thread {
/* These variables should be used in thread (i.e. run()) only! */
/*-------------------------------------------------------------*/
AVCodec *inputDecoder_;
AVCodecContext *decoderCtx_;
AVFrame *rawFrame_;
AVFrame *scaledPicture_;
......@@ -76,6 +77,7 @@ class VideoReceiveThread : public ost::Thread {
size_t bufferSize_;
const std::string id_;
void setup();
void openDecoder();
void createScalingContext();
void loadSDP();
void fill_buffer(void *data);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment