From 708b44d7d12b3d8840ee31e540a3a4bcc9d7deba Mon Sep 17 00:00:00 2001
From: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
Date: Tue, 5 Jun 2012 18:08:05 -0400
Subject: [PATCH] * #12012: video: fix some regressions

---
 daemon/src/sip/sdp.cpp                    | 45 ++++++++++-------------
 daemon/src/sip/sdp.h                      | 10 ++---
 daemon/src/video/libav_utils.cpp          |  1 +
 daemon/src/video/shared_memory.cpp        |  8 ++--
 daemon/src/video/video_receive_thread.cpp | 36 ++++++++++++++----
 daemon/src/video/video_receive_thread.h   |  3 +-
 daemon/src/video/video_rtp_session.cpp    |  6 +--
 daemon/src/video/video_send_thread.cpp    | 14 +++----
 8 files changed, 68 insertions(+), 55 deletions(-)

diff --git a/daemon/src/sip/sdp.cpp b/daemon/src/sip/sdp.cpp
index 94c33a66e2..6639abdadc 100644
--- a/daemon/src/sip/sdp.cpp
+++ b/daemon/src/sip/sdp.cpp
@@ -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;
     }
 
diff --git a/daemon/src/sip/sdp.h b/daemon/src/sip/sdp.h
index 4af11cb16e..fa18d26cbd 100644
--- a/daemon/src/sip/sdp.h
+++ b/daemon/src/sip/sdp.h
@@ -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.
diff --git a/daemon/src/video/libav_utils.cpp b/daemon/src/video/libav_utils.cpp
index 79a13b8d9e..f07da18590 100644
--- a/daemon/src/video/libav_utils.cpp
+++ b/daemon/src/video/libav_utils.cpp
@@ -113,6 +113,7 @@ void sfl_avcodec_init()
 
     av_register_all();
     avdevice_register_all();
+    avformat_network_init();
 
     av_lockmgr_register(avcodecManageMutex);
 
diff --git a/daemon/src/video/shared_memory.cpp b/daemon/src/video/shared_memory.cpp
index bfd7e9b685..86c913f674 100644
--- a/daemon/src/video/shared_memory.cpp
+++ b/daemon/src/video/shared_memory.cpp
@@ -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");
     }
 
diff --git a/daemon/src/video/video_receive_thread.cpp b/daemon/src/video/video_receive_thread.cpp
index ec0862b576..24e0a09d14 100644
--- a/daemon/src/video/video_receive_thread.cpp
+++ b/daemon/src/video/video_receive_thread.cpp
@@ -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()
diff --git a/daemon/src/video/video_receive_thread.h b/daemon/src/video/video_receive_thread.h
index 362b6adae0..4e1d27de12 100644
--- a/daemon/src/video/video_receive_thread.h
+++ b/daemon/src/video/video_receive_thread.h
@@ -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();
diff --git a/daemon/src/video/video_rtp_session.cpp b/daemon/src/video/video_rtp_session.cpp
index b7eaa66bed..f5753e3c4a 100644
--- a/daemon/src/video/video_rtp_session.cpp
+++ b/daemon/src/video/video_rtp_session.cpp
@@ -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();
 }
diff --git a/daemon/src/video/video_send_thread.cpp b/daemon/src/video/video_send_thread.cpp
index edd64ca0ff..be700ef56c 100644
--- a/daemon/src/video/video_send_thread.cpp
+++ b/daemon/src/video/video_send_thread.cpp
@@ -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());
 
-- 
GitLab