Commit adf8a737 authored by Tristan Matthews's avatar Tristan Matthews

* #17558: video: move buffer size code into VideoProvider

parent 334ddd8a
......@@ -10,7 +10,7 @@ libvideo_la_SOURCES = libav_utils.cpp libav_utils.h video_rtp_session.cpp \
video_v4l2_list.cpp video_v4l2.h video_v4l2_list.h \
video_preferences.h video_preferences.cpp \
packet_handle.h packet_handle.cpp check.h shm_header.h \
shm_sink.cpp shm_sink.h video_provider.h
shm_sink.cpp shm_sink.h video_provider.cpp video_provider.h
libvideo_la_LIBADD = @LIBAVCODEC_LIBS@ @LIBAVFORMAT_LIBS@ @LIBAVDEVICE_LIBS@ @LIBSWSCALE_LIBS@ @LIBAVUTIL_LIBS@ @CCRTP_LIBS@ @UDEV_LIBS@
......
/*
* Copyright (C) 2012 Savoir-Faire Linux Inc.
* Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Additional permission under GNU GPL version 3 section 7:
*
* If you modify this program, or any covered work, by linking or
* combining it with the OpenSSL project's OpenSSL library (or a
* modified version of that library), containing parts covered by the
* terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
* grants you additional permission to convey the resulting work.
* Corresponding Source for a non-source form of such a combination
* shall include the source code for the parts of OpenSSL used as well
* as that of the covered work.
*/
#include "video_provider.h"
namespace sfl_video {
extern "C" {
#include <libavcodec/avcodec.h>
}
int VideoProvider::getBufferSize(int width, int height)
{
// determine required buffer size and allocate buffer
return avpicture_get_size(PIX_FMT_BGRA, width, height);
}
} // end namespace sfl_video
......@@ -37,6 +37,9 @@ class VideoProvider {
public:
virtual void fillBuffer(void *data) = 0;
virtual ~VideoProvider() {}
protected:
static int
getBufferSize(int width, int height);
};
}
......
......@@ -38,8 +38,6 @@
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/opt.h>
#include <libavutil/pixdesc.h>
#include <libavdevice/avdevice.h>
#include <libswscale/swscale.h>
}
......@@ -47,21 +45,12 @@ extern "C" {
#include "manager.h"
static const enum PixelFormat VIDEO_RGB_FORMAT = PIX_FMT_BGRA;
namespace sfl_video {
using std::string;
namespace { // anonymous namespace
int getBufferSize(int width, int height, int format)
{
enum PixelFormat fmt = (enum PixelFormat) format;
// determine required buffer size and allocate buffer
return avpicture_get_size(fmt, width, height);
}
int readFunction(void *opaque, uint8_t *buf, int buf_size)
{
std::istream &is = *static_cast<std::istream*>(opaque);
......@@ -184,7 +173,7 @@ void VideoReceiveThread::setup()
}
// determine required buffer size and allocate buffer
bufferSize_ = getBufferSize(dstWidth_, dstHeight_, VIDEO_RGB_FORMAT);
bufferSize_ = getBufferSize(dstWidth_, dstHeight_);
EXIT_IF_FAIL(sink_.start(), "Cannot start shared memory sink");
Manager::instance().getVideoControls()->startedDecoding(id_, sink_.openedName(), dstWidth_, dstHeight_);
......@@ -197,7 +186,7 @@ void VideoReceiveThread::createScalingContext()
imgConvertCtx_ = sws_getCachedContext(imgConvertCtx_, decoderCtx_->width,
decoderCtx_->height,
decoderCtx_->pix_fmt, dstWidth_,
dstHeight_, VIDEO_RGB_FORMAT,
dstHeight_, PIX_FMT_BGRA,
SWS_BICUBIC, NULL, NULL, NULL);
if (!imgConvertCtx_) {
ERROR("Cannot init the conversion context!");
......@@ -259,7 +248,7 @@ void VideoReceiveThread::fillBuffer(void *data)
{
avpicture_fill(reinterpret_cast<AVPicture *>(scaledPicture_),
static_cast<uint8_t *>(data),
VIDEO_RGB_FORMAT,
PIX_FMT_BGRA,
dstWidth_,
dstHeight_);
......
......@@ -122,7 +122,7 @@ void VideoRtpSession::start()
if (sending_) {
if (sendThread_.get())
WARN("Restarting video sender");
sendThread_.reset(new VideoSendThread(txArgs_));
sendThread_.reset(new VideoSendThread("local", txArgs_));
sendThread_->start();
} else {
DEBUG("Video sending disabled");
......
......@@ -29,6 +29,7 @@
*/
#include "video_send_thread.h"
#include "dbus/video_controls.h"
#include "packet_handle.h"
#include "check.h"
......@@ -225,6 +226,13 @@ void VideoSendThread::setup()
#endif
EXIT_IF_FAIL(ret >= 0, "Could not open codec");
// determine required buffer size and allocate buffer
bufferSize_ = getBufferSize(inputDecoderCtx_->width, inputDecoderCtx_->height);
EXIT_IF_FAIL(sink_.start(), "Cannot start shared memory sink");
Manager::instance().getVideoControls()->startedDecoding(id_, sink_.openedName(), inputDecoderCtx_->width, inputDecoderCtx_->height);
DEBUG("shm sink started with size %d, width %d and height %d", bufferSize_, inputDecoderCtx_->width, inputDecoderCtx_->height);
outputCtx_ = avformat_alloc_context();
outputCtx_->interrupt_callback = interruptCb_;
......@@ -332,7 +340,7 @@ int VideoSendThread::interruptCb(void *ctx)
return not context->threadRunning_;
}
VideoSendThread::VideoSendThread(const std::map<string, string> &args) :
VideoSendThread::VideoSendThread(const std::string &id, const std::map<string, string> &args) :
args_(args),
scaledPictureBuf_(0),
outbuf_(0),
......@@ -347,6 +355,9 @@ VideoSendThread::VideoSendThread(const std::map<string, string> &args) :
outputCtx_(0),
imgConvertCtx_(0),
sdp_(),
sink_(),
bufferSize_(0),
id_(id),
interruptCb_(),
threadRunning_(false),
forceKeyFrame_(0),
......@@ -434,8 +445,29 @@ void VideoSendThread::run()
createScalingContext();
while (threadRunning_)
if (captureFrame())
if (captureFrame()) {
renderFrame();
encodeAndSendVideo();
}
}
/// Copies and scales our rendered frame to the buffer pointed to by data
void VideoSendThread::fillBuffer(void *data)
{
avpicture_layout(reinterpret_cast<AVPicture *>(rawFrame_),
inputDecoderCtx_->pix_fmt,
inputDecoderCtx_->width,
inputDecoderCtx_->height,
static_cast<unsigned char *>(data),
bufferSize_);
}
void VideoSendThread::renderFrame()
{
// we want our rendering code to be called by the shm_sink,
// because it manages the shared memory synchronization
sink_.render_callback(*this, bufferSize_);
}
......
......@@ -34,6 +34,8 @@
#include <map>
#include <string>
#include "noncopyable.h"
#include "shm_sink.h"
#include "video_provider.h"
extern "C" {
#include <libavformat/avformat.h>
......@@ -48,7 +50,7 @@ class AVCodec;
namespace sfl_video {
class VideoSendThread {
class VideoSendThread : public VideoProvider {
private:
NON_COPYABLE(VideoSendThread);
void forcePresetX264();
......@@ -56,6 +58,7 @@ class VideoSendThread {
void setup();
void prepareEncoderContext(AVCodec *encoder);
void createScalingContext();
void fillBuffer(void *data);
static int interruptCb(void *ctx);
std::map<std::string, std::string> args_;
......@@ -76,6 +79,11 @@ class VideoSendThread {
SwsContext *imgConvertCtx_;
std::string sdp_;
AVIOInterruptCB interruptCb_;
SHMSink sink_;
size_t bufferSize_;
const std::string id_;
bool threadRunning_;
int forceKeyFrame_;
static void *runCallback(void *);
......@@ -83,10 +91,12 @@ class VideoSendThread {
int frameNumber_;
void run();
bool captureFrame();
void renderFrame();
void encodeAndSendVideo();
friend struct VideoTxContextHandle;
public:
explicit VideoSendThread(const std::map<std::string, std::string> &args);
VideoSendThread(const std::string &id, const std::map<std::string, std::string> &args);
~VideoSendThread();
void start();
std::string getSDP() const { return sdp_; }
......
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