Commit 708b44d7 authored by Tristan Matthews's avatar Tristan Matthews

* #12012: video: fix some regressions

parent 3c986623
......@@ -39,6 +39,7 @@
#include "manager.h"
#ifdef SFL_VIDEO
#include <algorithm>
#include "video/video_endpoint.h"
#endif
......@@ -206,7 +207,7 @@ pjmedia_sdp_media *Sdp::setMediaDescriptorLine(bool audio)
std::ostringstream s;
s << payload;
pj_strdup2 (memPool_, &med->desc.fmt[i], s.str().c_str());
pj_strdup2(memPool_, &med->desc.fmt[i], s.str().c_str());
// Add a rtpmap field for each codec
// We could add one only for dynamic payloads because the codecs with static RTP payloads
......@@ -307,26 +308,20 @@ void Sdp::setTelephoneEventRtpmap(pjmedia_sdp_media *med)
}
#ifdef SFL_VIDEO
void Sdp::setLocalMediaVideoCapabilities(const std::vector<std::string> &videoCodecs)
void Sdp::setLocalMediaVideoCapabilities(const std::vector<std::string> &selectedCodecs)
{
if (videoCodecs.empty())
throw SdpException ("No selected video codec while building local SDP offer");
if (selectedCodecs.empty())
throw SdpException("No selected video codec while building local SDP offer");
video_codec_list_.clear();
const std::vector<std::string> &codecs_list = sfl_video::getCodecList();
for (unsigned i = 0; i < videoCodecs.size(); ++i) {
const std::string &codec = videoCodecs[i];
for (unsigned j = 0; j < codecs_list.size(); ++j) {
if (codecs_list[j] == codec) {
video_codec_list_.push_back(codec);
break;
}
}
}
for (std::vector<std::string>::const_iterator i = selectedCodecs.begin(); i != selectedCodecs.end(); ++i)
if (std::find(codecs_list.begin(), codecs_list.end(), *i) != codecs_list.end())
video_codec_list_.push_back(*i);
}
#endif
void Sdp::setLocalMediaCapabilities(const std::vector<int> &selectedCodecs)
void Sdp::setLocalMediaAudioCapabilities(const std::vector<int> &selectedCodecs)
{
if (selectedCodecs.empty())
WARN("No selected codec while building local SDP offer");
......@@ -338,7 +333,7 @@ void Sdp::setLocalMediaCapabilities(const std::vector<int> &selectedCodecs)
if (codec)
audio_codec_list_.push_back(codec);
else
WARN("SDP: Couldn't find audio codec");
WARN("Couldn't find audio codec");
}
}
......@@ -353,10 +348,10 @@ namespace {
}
#ifdef SFL_VIDEO
int Sdp::createLocalSession(const std::vector<int> &selectedCodecs, const std::vector<std::string> &videoCodecs)
int Sdp::createLocalSession(const std::vector<int> &selectedAudioCodecs, const std::vector<std::string> &selectedVideoCodecs)
{
setLocalMediaCapabilities(selectedCodecs);
setLocalMediaVideoCapabilities(videoCodecs);
setLocalMediaAudioCapabilities(selectedAudioCodecs);
setLocalMediaVideoCapabilities(selectedVideoCodecs);
localSession_ = PJ_POOL_ZALLOC_T(memPool_, pjmedia_sdp_session);
localSession_->conn = PJ_POOL_ZALLOC_T(memPool_, pjmedia_sdp_conn);
......@@ -402,7 +397,7 @@ int Sdp::createLocalSession(const std::vector<int> &selectedCodecs, const std::v
#else
int Sdp::createLocalSession(const std::vector<int> &selectedCodecs)
{
setLocalMediaCapabilities(selectedCodecs);
setLocalMediaAudioCapabilities(selectedCodecs);
localSession_ = PJ_POOL_ZALLOC_T(memPool_, pjmedia_sdp_session);
if (!localSession_) {
......@@ -455,9 +450,9 @@ int Sdp::createLocalSession(const std::vector<int> &selectedCodecs)
void Sdp::createOffer(const std::vector<int> &selectedCodecs, const std::vector<std::string> &videoCodecs)
{
if (createLocalSession(selectedCodecs, videoCodecs) != PJ_SUCCESS)
ERROR("SDP: Error: Failed to create initial offer");
else if (pjmedia_sdp_neg_create_w_local_offer (memPool_, localSession_, &negotiator_) != PJ_SUCCESS)
ERROR("SDP: Error: Failed to create an initial SDP negotiator");
ERROR("Failed to create initial offer");
else if (pjmedia_sdp_neg_create_w_local_offer(memPool_, localSession_, &negotiator_) != PJ_SUCCESS)
ERROR("Failed to create an initial SDP negotiator");
}
#else
void Sdp::createOffer(const std::vector<int> &selectedCodecs)
......@@ -475,15 +470,15 @@ void Sdp::receiveOffer(const pjmedia_sdp_session* remote,
const std::vector<std::string> &videoCodecs)
{
if (!remote) {
ERROR("SDP: Remote session is NULL");
ERROR("Remote session is NULL");
return;
}
DEBUG("SDP: Remote SDP Session:");
DEBUG("Remote SDP Session:");
printSession(remote);
if (!localSession_ and createLocalSession(selectedCodecs, videoCodecs) != PJ_SUCCESS) {
ERROR("SDP: Failed to create initial offer");
ERROR("Failed to create initial offer");
return;
}
......
......@@ -308,7 +308,7 @@ class Sdp {
*/
std::vector<sfl::Codec *> audio_codec_list_;
#ifdef SFL_VIDEO
std::vector<std::string> video_codec_list_;
std::vector<std::string> video_codec_list_;
#endif
/**
......@@ -352,18 +352,18 @@ class Sdp {
* Build the local media capabilities for this session
* @param List of codec in preference order
*/
void setLocalMediaCapabilities(const std::vector<int> &selectedCodecs);
void setLocalMediaAudioCapabilities(const std::vector<int> &selected);
#ifdef SFL_VIDEO
void setLocalMediaVideoCapabilities(const std::vector<std::string> &videoCodecs);
void setLocalMediaVideoCapabilities(const std::vector<std::string> &selected);
#endif
/*
* Build the local SDP offer
*/
#ifdef SFL_VIDEO
int createLocalSession(const std::vector<int> &selectedCodecs, const std::vector<std::string> &videoCodecs);
int createLocalSession(const std::vector<int> &selectedAudio, const std::vector<std::string> &selectedVideo);
#else
int createLocalSession(const std::vector<int> &selectedCodecs);
int createLocalSession(const std::vector<int> &selectedAudio);
#endif
/*
* Adds a sdes attribute to the given media section.
......
......@@ -113,6 +113,7 @@ void sfl_avcodec_init()
av_register_all();
avdevice_register_all();
avformat_network_init();
av_lockmgr_register(avcodecManageMutex);
......
......@@ -95,7 +95,7 @@ int createShmID(int key, int numBytes)
int shm_id = shmget(key, numBytes, 0644 | IPC_CREAT);
if (shm_id == -1)
ERROR("%s:shmget:%m", __PRETTY_FUNCTION__);
ERROR("shmget:%m");
return shm_id;
}
......@@ -106,7 +106,7 @@ uint8_t *attachShm(int shm_id)
/* attach to the segment and get a pointer to it */
uint8_t *data = reinterpret_cast<uint8_t*>(shmat(shm_id, (void *) 0, 0));
if (data == reinterpret_cast<uint8_t *>(-1)) {
ERROR("%s:shmat:%m", __PRETTY_FUNCTION__);
ERROR("shmat:%m");
data = NULL;
}
return data;
......@@ -116,7 +116,7 @@ void detachShm(uint8_t *data)
{
/* detach from the segment: */
if (data and shmdt(data) == -1)
ERROR("%s:shmdt:%m", __PRETTY_FUNCTION__);
ERROR("shmdt:%m");
}
void destroyShm(int shm_id)
......@@ -146,7 +146,7 @@ int createSemaphoreSetID(int semaphoreKey)
whose counter is initialized to '0'. */
int semaphoreSetID = semget(semaphoreKey, 1, 0600 | IPC_CREAT);
if (semaphoreSetID == -1) {
ERROR("%s:semget:%m", __PRETTY_FUNCTION__);
ERROR("semget:%m");
throw std::runtime_error("Could not create semaphore set");
}
......
......@@ -68,6 +68,22 @@ int getBufferSize(int width, int height, int format)
return sizeof(uint8_t) * avpicture_get_size(fmt, width, height);
}
string openTemp(string path, std::ofstream& f)
{
path += "/XXXXXX";
std::vector<char> dst_path(path.begin(), path.end());
dst_path.push_back('\0');
int fd = -1;
while (fd == -1) {
fd = mkstemp(&dst_path[0]);
if (fd != -1) {
path.assign(dst_path.begin(), dst_path.end() - 1);
f.open(path.c_str(), std::ios_base::trunc | std::ios_base::out);
close(fd);
}
}
return path;
}
} // end anonymous namespace
void VideoReceiveThread::loadSDP()
......@@ -75,9 +91,9 @@ void VideoReceiveThread::loadSDP()
assert(not args_["receiving_sdp"].empty());
std::ofstream os;
sdpFilename_ = openTemp("/tmp", os);
os << args_["receiving_sdp"];
DEBUG("%s:loaded SDP %s", __PRETTY_FUNCTION__,
args_["receiving_sdp"].c_str());
DEBUG("loaded SDP %s", args_["receiving_sdp"].c_str());
os.close();
}
......@@ -92,14 +108,17 @@ void VideoReceiveThread::setup()
AVInputFormat *file_iformat = 0;
std::string format_str;
std::string input;
if (args_["input"].empty()) {
loadSDP();
format_str = "sdp";
input = sdpFilename_;
} else if (args_["input"].substr(0, strlen("/dev/video")) == "/dev/video") {
// it's a v4l device if starting with /dev/video
// FIXME: This is not a robust way of checking if we mean to use a
// v4l2 device
format_str = "video4linux2";
input = args_["input"];
}
DEBUG("Using %s format", format_str.c_str());
......@@ -115,16 +134,16 @@ void VideoReceiveThread::setup()
av_dict_set(&options, "channel", args_["channel"].c_str(), 0);
// Open video file
int ret = avformat_open_input(&inputCtx_, args_["input"].c_str(), file_iformat,
&options);
CHECK(ret == 0, "Could not open input \"%s\"", args_["input"].c_str());
int ret = avformat_open_input(&inputCtx_, input.c_str(), file_iformat, &options);
CHECK(ret == 0, "Could not open input \"%s\"", input.c_str());
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 8, 0)
ret = av_find_stream_info(inputCtx_);
#else
ret = avformat_find_stream_info(inputCtx_, NULL);
#endif
CHECK(ret >= 0, "Could not find stream info!");
if (ret < 0)
DEBUG("Could not find stream info!");
// find the first video stream from the input
streamIndex_ = -1;
......@@ -146,7 +165,7 @@ void VideoReceiveThread::setup()
#else
ret = avcodec_open2(decoderCtx_, inputDecoder, NULL);
#endif
CHECK(ret >= 0, "Could not open codec");
CHECK(ret == 0, "Could not open codec");
scaledPicture_ = avcodec_alloc_frame();
CHECK(scaledPicture_, "Could not allocate output frame");
......@@ -183,7 +202,8 @@ VideoReceiveThread::VideoReceiveThread(const std::map<string, string> &args,
sfl_video::SharedMemory &handle) :
args_(args), frameNumber_(0), decoderCtx_(0), rawFrame_(0),
scaledPicture_(0), streamIndex_(-1), inputCtx_(0), imgConvertCtx_(0),
dstWidth_(-1), dstHeight_(-1), sharedMemory_(handle), receiving_(false)
dstWidth_(0), dstHeight_(0), sharedMemory_(handle), receiving_(false),
sdpFilename_()
{}
void VideoReceiveThread::run()
......
......@@ -67,12 +67,13 @@ class VideoReceiveThread : public ost::Thread {
int dstHeight_;
SharedMemory &sharedMemory_;
bool receiving_;
std::string sdpFilename_;
void setup();
void createScalingContext();
void loadSDP();
public:
bool receiving_;
VideoReceiveThread(const std::map<std::string, std::string> &args,
SharedMemory &handle);
virtual ~VideoReceiveThread();
......
......@@ -67,7 +67,7 @@ void VideoRtpSession::updateSDP(const Sdp &sdp)
// if port has changed
if (desc != rxArgs_["receiving_sdp"]) {
rxArgs_["receiving_sdp"] = desc;
DEBUG("%s:Updated incoming SDP to:\n %s", __PRETTY_FUNCTION__,
DEBUG("Updated incoming SDP to:\n %s",
rxArgs_["receiving_sdp"].c_str());
}
......@@ -117,8 +117,7 @@ void VideoRtpSession::updateDestination(const string &destination,
if (tmp.str() != txArgs_["destination"]) {
assert(sendThread_.get() == 0);
txArgs_["destination"] = tmp.str();
DEBUG("%s updated dest to %s", __PRETTY_FUNCTION__,
txArgs_["destination"].c_str());
DEBUG("updated dest to %s", txArgs_["destination"].c_str());
}
if (port == 0) {
......@@ -180,7 +179,6 @@ void VideoRtpSession::start()
void VideoRtpSession::stop()
{
DEBUG("%s", __PRETTY_FUNCTION__);
receiveThread_.reset();
sendThread_.reset();
}
......
......@@ -53,9 +53,9 @@ using std::string;
void VideoSendThread::print_and_save_sdp()
{
size_t sdp_size = outputCtx_->streams[0]->codec->extradata_size + 2048;
char *sdp = new char[sdp_size]; /* theora sdp can be huge */
av_sdp_create(&outputCtx_, 1, sdp, sdp_size);
const size_t sdp_size = outputCtx_->streams[0]->codec->extradata_size + 2048;
std::string sdp(sdp_size, 0); /* theora sdp can be huge */
av_sdp_create(&outputCtx_, 1, &(*sdp.begin()), sdp_size);
std::istringstream iss(sdp);
string line;
sdp_ = "";
......@@ -65,7 +65,6 @@ void VideoSendThread::print_and_save_sdp()
sdp_ += line + "\n";
}
DEBUG("%s", sdp_.c_str());
delete [] sdp;
sdpReady_.signal();
}
......@@ -119,11 +118,10 @@ void VideoSendThread::setup()
{
AVInputFormat *file_iformat = 0;
const char *enc_name = args_["codec"].c_str();
int ret;
// it's a v4l device if starting with /dev/video
static const char * const V4L_PATH = "/dev/video";
if (args_["input"].substr(0, sizeof(V4L_PATH) - 1) == V4L_PATH) {
DEBUG("%s:Using v4l2 format", __PRETTY_FUNCTION__);
if (args_["input"].find(V4L_PATH) != std::string::npos) {
DEBUG("Using v4l2 format");
file_iformat = av_find_input_format("video4linux2");
CHECK(file_iformat, "Could not find format video4linux2");
}
......@@ -137,7 +135,7 @@ void VideoSendThread::setup()
av_dict_set(&options, "channel", args_["channel"].c_str(), 0);
// Open video file
ret = avformat_open_input(&inputCtx_, args_["input"].c_str(),
int ret = avformat_open_input(&inputCtx_, args_["input"].c_str(),
file_iformat, &options);
CHECK(ret == 0, "Could not open input file %s", args_["input"].c_str());
......
Markdown is supported
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