~ubuntu-branches/ubuntu/trusty/sflphone/trusty

« back to all changes in this revision

Viewing changes to daemon/src/video/video_send_thread.cpp

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (4.3.4 sid)
  • Revision ID: package-import@ubuntu.com-20140128182336-jrsv0k9u6cawc068
Tags: 1.3.0-1
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  Copyright (C) 2004-2012 Savoir-Faire Linux Inc.
3
 
 *  Author: Tristan Matthews <tristan.matthews@savoirfairelinux.com>
4
 
 *
5
 
 *  This program is free software; you can redistribute it and/or modify
6
 
 *  it under the terms of the GNU General Public License as published by
7
 
 *  the Free Software Foundation; either version 3 of the License, or
8
 
 *  (at your option) any later version.
9
 
 *
10
 
 *  This program is distributed in the hope that it will be useful,
11
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 *  GNU General Public License for more details.
14
 
 *
15
 
 *  You should have received a copy of the GNU General Public License
16
 
 *  along with this program; if not, write to the Free Software
17
 
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
18
 
 *
19
 
 *  Additional permission under GNU GPL version 3 section 7:
20
 
 *
21
 
 *  If you modify this program, or any covered work, by linking or
22
 
 *  combining it with the OpenSSL project's OpenSSL library (or a
23
 
 *  modified version of that library), containing parts covered by the
24
 
 *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
25
 
 *  grants you additional permission to convey the resulting work.
26
 
 *  Corresponding Source for a non-source form of such a combination
27
 
 *  shall include the source code for the parts of OpenSSL used as well
28
 
 *  as that of the covered work.
29
 
 */
30
 
 
31
 
#include "video_send_thread.h"
32
 
#include "socket_pair.h"
33
 
#include "dbus/video_controls.h"
34
 
#include "packet_handle.h"
35
 
#include "check.h"
36
 
 
37
 
// libav includes
38
 
extern "C" {
39
 
#include <libavcodec/avcodec.h>
40
 
#include <libavformat/avformat.h>
41
 
#include <libavutil/opt.h>
42
 
#include <libavutil/pixdesc.h>
43
 
#include <libavutil/mathematics.h>
44
 
#include <libavdevice/avdevice.h>
45
 
#include <libswscale/swscale.h>
46
 
}
47
 
 
48
 
#include <map>
49
 
#include "manager.h"
50
 
 
51
 
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 28, 0)
52
 
// fallback to av_freep for older libavcodec
53
 
#define avcodec_free_frame av_freep
54
 
#endif
55
 
 
56
 
namespace sfl_video {
57
 
 
58
 
using std::string;
59
 
 
60
 
void VideoSendThread::print_sdp()
61
 
{
62
 
    /* theora sdp can be huge */
63
 
    const size_t sdp_size = outputCtx_->streams[0]->codec->extradata_size + 2048;
64
 
    std::string sdp(sdp_size, 0);
65
 
    av_sdp_create(&outputCtx_, 1, &(*sdp.begin()), sdp_size);
66
 
    std::istringstream iss(sdp);
67
 
    string line;
68
 
    sdp_ = "";
69
 
    while (std::getline(iss, line)) {
70
 
        /* strip windows line ending */
71
 
        line = line.substr(0, line.length() - 1);
72
 
        sdp_ += line + "\n";
73
 
    }
74
 
    DEBUG("sending\n%s", sdp_.c_str());
75
 
}
76
 
 
77
 
void VideoSendThread::forcePresetX264()
78
 
{
79
 
    const char *speedPreset = "ultrafast";
80
 
    if (av_opt_set(encoderCtx_->priv_data, "preset", speedPreset, 0))
81
 
        WARN("Failed to set x264 preset '%s'", speedPreset);
82
 
    const char *tune = "zerolatency";
83
 
    if (av_opt_set(encoderCtx_->priv_data, "tune", tune, 0))
84
 
        WARN("Failed to set x264 tune '%s'", tune);
85
 
}
86
 
 
87
 
void VideoSendThread::prepareEncoderContext(AVCodec *encoder)
88
 
{
89
 
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53, 12, 0)
90
 
    encoderCtx_ = avcodec_alloc_context();
91
 
    avcodec_get_context_defaults(encoderCtx_);
92
 
    (void) encoder;
93
 
#else
94
 
    encoderCtx_ = avcodec_alloc_context3(encoder);
95
 
#endif
96
 
 
97
 
    // set some encoder settings here
98
 
    encoderCtx_->bit_rate = 1000 * atoi(args_["bitrate"].c_str());
99
 
    DEBUG("Using bitrate %d", encoderCtx_->bit_rate);
100
 
 
101
 
    // resolution must be a multiple of two
102
 
    if (args_["width"].empty() and inputDecoderCtx_)
103
 
        encoderCtx_->width = inputDecoderCtx_->width;
104
 
    else
105
 
        encoderCtx_->width = atoi(args_["width"].c_str());
106
 
 
107
 
    if (args_["height"].empty() and inputDecoderCtx_)
108
 
        encoderCtx_->height = inputDecoderCtx_->height;
109
 
    else
110
 
        encoderCtx_->height = atoi(args_["height"].c_str());
111
 
 
112
 
    const int DEFAULT_FPS = 30;
113
 
    const int fps = args_["framerate"].empty() ? DEFAULT_FPS : atoi(args_["framerate"].c_str());
114
 
    encoderCtx_->time_base = (AVRational) {1, fps};
115
 
    // emit one intra frame every gop_size frames
116
 
    encoderCtx_->max_b_frames = 0;
117
 
    encoderCtx_->pix_fmt = PIX_FMT_YUV420P;
118
 
 
119
 
    // Fri Jul 22 11:37:59 EDT 2011:tmatth:XXX: DON'T set this, we want our
120
 
    // pps and sps to be sent in-band for RTP
121
 
    // This is to place global headers in extradata instead of every keyframe.
122
 
    // encoderCtx_->flags |= CODEC_FLAG_GLOBAL_HEADER;
123
 
}
124
 
 
125
 
namespace {
126
 
void
127
 
extractProfileLevelID(const std::string &parameters, AVCodecContext *ctx)
128
 
{
129
 
    // From RFC3984:
130
 
    // If no profile-level-id is present, the Baseline Profile without
131
 
    // additional constraints at Level 1 MUST be implied.
132
 
    ctx->profile = FF_PROFILE_H264_BASELINE;
133
 
    ctx->level = 0x0d;
134
 
    // ctx->level = 0x0d; // => 13 aka 1.3
135
 
    if (parameters.empty())
136
 
        return;
137
 
 
138
 
    const std::string target("profile-level-id=");
139
 
    size_t needle = parameters.find(target);
140
 
    if (needle == std::string::npos)
141
 
        return;
142
 
 
143
 
    needle += target.length();
144
 
    const size_t id_length = 6; /* digits */
145
 
    const std::string profileLevelID(parameters.substr(needle, id_length));
146
 
    if (profileLevelID.length() != id_length)
147
 
        return;
148
 
 
149
 
    int result;
150
 
    std::stringstream ss;
151
 
    ss << profileLevelID;
152
 
    ss >> std::hex >> result;
153
 
    // profile-level id consists of three bytes
154
 
    const unsigned char profile_idc = result >> 16;             // 42xxxx -> 42
155
 
    const unsigned char profile_iop = ((result >> 8) & 0xff);   // xx80xx -> 80
156
 
    ctx->level = result & 0xff;                                 // xxxx0d -> 0d
157
 
    switch (profile_idc) {
158
 
        case FF_PROFILE_H264_BASELINE:
159
 
            // check constraint_set_1_flag
160
 
            ctx->profile |= (profile_iop & 0x40) >> 6 ? FF_PROFILE_H264_CONSTRAINED : 0;
161
 
            break;
162
 
        case FF_PROFILE_H264_HIGH_10:
163
 
        case FF_PROFILE_H264_HIGH_422:
164
 
        case FF_PROFILE_H264_HIGH_444_PREDICTIVE:
165
 
            // check constraint_set_3_flag
166
 
            ctx->profile |= (profile_iop & 0x10) >> 4 ? FF_PROFILE_H264_INTRA : 0;
167
 
            break;
168
 
    }
169
 
    DEBUG("Using profile %x and level %d", ctx->profile, ctx->level);
170
 
}
171
 
}
172
 
 
173
 
void VideoSendThread::setup()
174
 
{
175
 
    AVInputFormat *file_iformat = 0;
176
 
    const char *enc_name = args_["codec"].c_str();
177
 
    // it's a v4l device if starting with /dev/video
178
 
    static const char * const V4L_PATH = "/dev/video";
179
 
    if (args_["input"].find(V4L_PATH) != std::string::npos) {
180
 
        DEBUG("Using v4l2 format");
181
 
        file_iformat = av_find_input_format("video4linux2");
182
 
        EXIT_IF_FAIL(file_iformat, "Could not find format video4linux2");
183
 
    }
184
 
 
185
 
    AVDictionary *options = NULL;
186
 
    if (!args_["framerate"].empty())
187
 
        av_dict_set(&options, "framerate", args_["framerate"].c_str(), 0);
188
 
    if (!args_["video_size"].empty())
189
 
        av_dict_set(&options, "video_size", args_["video_size"].c_str(), 0);
190
 
    if (!args_["channel"].empty())
191
 
        av_dict_set(&options, "channel", args_["channel"].c_str(), 0);
192
 
 
193
 
    // Open video file
194
 
    inputCtx_ = avformat_alloc_context();
195
 
    inputCtx_->interrupt_callback = interruptCb_;
196
 
    int ret = avformat_open_input(&inputCtx_, args_["input"].c_str(),
197
 
                                  file_iformat, options ? &options : NULL);
198
 
    if (ret < 0) {
199
 
        if (options)
200
 
            av_dict_free(&options);
201
 
        EXIT_IF_FAIL(false, "Could not open input file %s", args_["input"].c_str());
202
 
    }
203
 
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 8, 0)
204
 
    ret = av_find_stream_info(inputCtx_);
205
 
#else
206
 
    ret = avformat_find_stream_info(inputCtx_, options ? &options : NULL);
207
 
#endif
208
 
    if (options)
209
 
        av_dict_free(&options);
210
 
    EXIT_IF_FAIL(ret >= 0, "Couldn't find stream info");
211
 
 
212
 
    // find the first video stream from the input
213
 
    streamIndex_ = -1;
214
 
    for (unsigned i = 0; streamIndex_ == -1 && i < inputCtx_->nb_streams; ++i)
215
 
        if (inputCtx_->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
216
 
            streamIndex_ = i;
217
 
 
218
 
    EXIT_IF_FAIL(streamIndex_ != -1, "Could not find video stream");
219
 
 
220
 
    // Get a pointer to the codec context for the video stream
221
 
    inputDecoderCtx_ = inputCtx_->streams[streamIndex_]->codec;
222
 
    EXIT_IF_FAIL(inputDecoderCtx_, "Could not get input codec context");
223
 
 
224
 
    // find the decoder for the video stream
225
 
    AVCodec *inputDecoder = avcodec_find_decoder(inputDecoderCtx_->codec_id);
226
 
    EXIT_IF_FAIL(inputDecoder, "Could not decode video stream");
227
 
 
228
 
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53, 6, 0)
229
 
    ret = avcodec_open(inputDecoderCtx_, inputDecoder);
230
 
#else
231
 
    ret = avcodec_open2(inputDecoderCtx_, inputDecoder, NULL);
232
 
#endif
233
 
    EXIT_IF_FAIL(ret >= 0, "Could not open codec");
234
 
 
235
 
    // determine required buffer size and allocate buffer
236
 
    bufferSize_ = avpicture_get_size(PIX_FMT_BGRA, inputDecoderCtx_->width, inputDecoderCtx_->height);
237
 
 
238
 
    EXIT_IF_FAIL(sink_.start(), "Cannot start shared memory sink");
239
 
    Manager::instance().getVideoControls()->startedDecoding(id_, sink_.openedName(), inputDecoderCtx_->width, inputDecoderCtx_->height);
240
 
    DEBUG("shm sink started with size %d, width %d and height %d", bufferSize_, inputDecoderCtx_->width, inputDecoderCtx_->height);
241
 
 
242
 
    outputCtx_ = avformat_alloc_context();
243
 
    outputCtx_->interrupt_callback = interruptCb_;
244
 
 
245
 
    AVOutputFormat *file_oformat = av_guess_format("rtp", args_["destination"].c_str(), NULL);
246
 
    EXIT_IF_FAIL(file_oformat, "Unable to find a suitable output format for %s",
247
 
          args_["destination"].c_str());
248
 
 
249
 
    outputCtx_->oformat = file_oformat;
250
 
    strncpy(outputCtx_->filename, args_["destination"].c_str(),
251
 
            sizeof outputCtx_->filename);
252
 
    // guarantee that buffer is NULL terminated
253
 
    outputCtx_->filename[sizeof outputCtx_->filename - 1] = '\0';
254
 
 
255
 
    /* find the video encoder */
256
 
    AVCodec *encoder = avcodec_find_encoder_by_name(enc_name);
257
 
    EXIT_IF_FAIL(encoder != 0, "Encoder \"%s\" not found!", enc_name);
258
 
 
259
 
    prepareEncoderContext(encoder);
260
 
 
261
 
    /* let x264 preset override our encoder settings */
262
 
    if (args_["codec"] == "libx264") {
263
 
        // FIXME: this should be parsed from the fmtp:profile-level-id
264
 
        // attribute of our peer, it will determine what profile and
265
 
        // level we are sending (i.e. that they can accept).
266
 
        extractProfileLevelID(args_["parameters"], encoderCtx_);
267
 
        forcePresetX264();
268
 
    }
269
 
 
270
 
    scaledInput_ = avcodec_alloc_frame();
271
 
 
272
 
    // open encoder
273
 
 
274
 
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53, 6, 0)
275
 
    EXIT_IF_FAIL(avcodec_open(encoderCtx_, encoder) >= 0, "Could not open encoder")
276
 
#else
277
 
    EXIT_IF_FAIL(avcodec_open2(encoderCtx_, encoder, NULL) >= 0, "Could not open "
278
 
          "encoder")
279
 
#endif
280
 
 
281
 
    // add video stream to outputformat context
282
 
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 8, 0)
283
 
    stream_ = av_new_stream(outputCtx_, 0);
284
 
#else
285
 
    stream_ = avformat_new_stream(outputCtx_, 0);
286
 
#endif
287
 
    EXIT_IF_FAIL(stream_ != 0, "Could not allocate stream.");
288
 
    stream_->codec = encoderCtx_;
289
 
 
290
 
    // Set our output AVIOcontext
291
 
    outputCtx_->pb = muxContext_.get();
292
 
    outputCtx_->interrupt_callback = interruptCb_;
293
 
    outputCtx_->packet_size = outputCtx_->pb->buffer_size;
294
 
 
295
 
    AVDictionary *outOptions = NULL;
296
 
    // write the stream header, if any
297
 
    if (not args_["payload_type"].empty()) {
298
 
        DEBUG("Writing stream header for payload type %s", args_["payload_type"].c_str());
299
 
        av_dict_set(&outOptions, "payload_type", args_["payload_type"].c_str(), 0);
300
 
    }
301
 
 
302
 
    ret = avformat_write_header(outputCtx_, outOptions ? &outOptions : NULL);
303
 
    if (outOptions)
304
 
        av_dict_free(&outOptions);
305
 
    EXIT_IF_FAIL(ret >= 0, "Could not write header for output file...check codec parameters");
306
 
 
307
 
    av_dump_format(outputCtx_, 0, outputCtx_->filename, 1);
308
 
    print_sdp();
309
 
 
310
 
    // allocate buffers for both scaled (pre-encoder) and encoded frames
311
 
    encoderBufferSize_ = avpicture_get_size(encoderCtx_->pix_fmt, encoderCtx_->width,
312
 
                                            encoderCtx_->height);
313
 
    EXIT_IF_FAIL(encoderBufferSize_ > FF_MIN_BUFFER_SIZE, "Encoder buffer too small");
314
 
    encoderBuffer_ = reinterpret_cast<uint8_t*>(av_malloc(encoderBufferSize_));
315
 
    const int scaledInputSize = avpicture_get_size(encoderCtx_->pix_fmt, encoderCtx_->width, encoderCtx_->height);
316
 
    scaledInputBuffer_ = reinterpret_cast<uint8_t*>(av_malloc(scaledInputSize));
317
 
    avpicture_fill(reinterpret_cast<AVPicture *>(scaledInput_),
318
 
                   static_cast<uint8_t *>(scaledInputBuffer_),
319
 
                   encoderCtx_->pix_fmt,
320
 
                   encoderCtx_->width,
321
 
                   encoderCtx_->height);
322
 
}
323
 
 
324
 
// This callback is used by libav internally to break out of blocking calls
325
 
int VideoSendThread::interruptCb(void *ctx)
326
 
{
327
 
    VideoSendThread *context = static_cast<VideoSendThread*>(ctx);
328
 
    return not context->threadRunning_;
329
 
}
330
 
 
331
 
VideoSendThread::VideoSendThread(const std::string &id, const std::map<string, string> &args) :
332
 
    args_(args),
333
 
    scaledInputBuffer_(0),
334
 
    encoderBuffer_(0),
335
 
    inputDecoderCtx_(0),
336
 
    rawFrame_(0),
337
 
    scaledInput_(0),
338
 
    streamIndex_(-1),
339
 
    encoderBufferSize_(0),
340
 
    encoderCtx_(0),
341
 
    stream_(0),
342
 
    inputCtx_(0),
343
 
    outputCtx_(0),
344
 
    previewConvertCtx_(0),
345
 
    encoderConvertCtx_(0),
346
 
    sdp_(),
347
 
    sink_(),
348
 
    bufferSize_(0),
349
 
    id_(id),
350
 
    interruptCb_(),
351
 
    threadRunning_(false),
352
 
    forceKeyFrame_(0),
353
 
    thread_(0),
354
 
    frameNumber_(0),
355
 
    muxContext_()
356
 
{
357
 
    interruptCb_.callback = interruptCb;
358
 
    interruptCb_.opaque = this;
359
 
}
360
 
 
361
 
void
362
 
VideoSendThread::addIOContext(SocketPair &socketPair)
363
 
{
364
 
    muxContext_.reset(socketPair.createAVIOContext(), &av_free);
365
 
}
366
 
 
367
 
struct VideoTxContextHandle {
368
 
    VideoTxContextHandle(VideoSendThread &tx) : tx_(tx) {}
369
 
 
370
 
    ~VideoTxContextHandle()
371
 
    {
372
 
        if (tx_.encoderConvertCtx_)
373
 
            sws_freeContext(tx_.encoderConvertCtx_);
374
 
        if (tx_.previewConvertCtx_)
375
 
            sws_freeContext(tx_.previewConvertCtx_);
376
 
 
377
 
        // write the trailer, if any.  the trailer must be written
378
 
        // before you close the CodecContexts open when you wrote the
379
 
        // header; otherwise write_trailer may try to use memory that
380
 
        // was freed on av_codec_close()
381
 
        if (tx_.outputCtx_ and tx_.outputCtx_->priv_data) {
382
 
            av_write_trailer(tx_.outputCtx_);
383
 
        }
384
 
 
385
 
        if (tx_.muxContext_ and tx_.muxContext_->buffer)
386
 
            av_free(tx_.muxContext_->buffer);
387
 
 
388
 
        if (tx_.scaledInputBuffer_)
389
 
            av_free(tx_.scaledInputBuffer_);
390
 
 
391
 
        if (tx_.encoderBuffer_)
392
 
            av_free(tx_.encoderBuffer_);
393
 
 
394
 
        // free the scaled frame
395
 
        if (tx_.scaledInput_)
396
 
            av_free(tx_.scaledInput_);
397
 
 
398
 
        // free the YUV frame
399
 
        if (tx_.rawFrame_)
400
 
            avcodec_free_frame(&tx_.rawFrame_);
401
 
 
402
 
        // close the codecs
403
 
        if (tx_.encoderCtx_) {
404
 
            avcodec_close(tx_.encoderCtx_);
405
 
            av_freep(&tx_.encoderCtx_);
406
 
        }
407
 
 
408
 
        // doesn't need to be freed, we didn't use avcodec_alloc_context
409
 
        if (tx_.inputDecoderCtx_)
410
 
            avcodec_close(tx_.inputDecoderCtx_);
411
 
 
412
 
        // close the video file
413
 
        if (tx_.inputCtx_) {
414
 
#if LIBAVFORMAT_VERSION_MAJOR < 55
415
 
            av_close_input_file(tx_.inputCtx_);
416
 
#else
417
 
            avformat_close_input(&tx_.inputCtx_);
418
 
#endif
419
 
        }
420
 
    }
421
 
    VideoSendThread &tx_;
422
 
};
423
 
 
424
 
 
425
 
void VideoSendThread::start()
426
 
{
427
 
    threadRunning_ = true;
428
 
    pthread_create(&thread_, NULL, &runCallback, this);
429
 
}
430
 
 
431
 
 
432
 
void *VideoSendThread::runCallback(void *data)
433
 
{
434
 
    VideoSendThread *context = static_cast<VideoSendThread*>(data);
435
 
    context->run();
436
 
    return NULL;
437
 
}
438
 
 
439
 
 
440
 
void VideoSendThread::run()
441
 
{
442
 
    // We don't want setup() called in the main thread in case it exits or blocks
443
 
    VideoTxContextHandle handle(*this);
444
 
    setup();
445
 
 
446
 
    while (threadRunning_)
447
 
        if (captureFrame()) {
448
 
            renderFrame();
449
 
            encodeAndSendVideo();
450
 
        }
451
 
}
452
 
 
453
 
/// Copies and scales our rendered frame to the buffer pointed to by data
454
 
void VideoSendThread::fillBuffer(void *data)
455
 
{
456
 
    AVFrame preview;
457
 
    avpicture_fill(reinterpret_cast<AVPicture *>(&preview),
458
 
                   static_cast<uint8_t *>(data),
459
 
                   PIX_FMT_BGRA,
460
 
                   inputDecoderCtx_->width,
461
 
                   inputDecoderCtx_->height);
462
 
    // Just need to convert colour space to BGRA
463
 
    previewConvertCtx_ = sws_getCachedContext(previewConvertCtx_,
464
 
                                              inputDecoderCtx_->width,
465
 
                                              inputDecoderCtx_->height,
466
 
                                              inputDecoderCtx_->pix_fmt,
467
 
                                              inputDecoderCtx_->width,
468
 
                                              inputDecoderCtx_->height,
469
 
                                              PIX_FMT_BGRA, SWS_BICUBIC,
470
 
                                              NULL, NULL, NULL);
471
 
    EXIT_IF_FAIL(previewConvertCtx_, "Could not get preview context");
472
 
    sws_scale(previewConvertCtx_, rawFrame_->data, rawFrame_->linesize, 0,
473
 
              inputDecoderCtx_->height, preview.data,
474
 
              preview.linesize);
475
 
}
476
 
 
477
 
 
478
 
void VideoSendThread::renderFrame()
479
 
{
480
 
    // we want our rendering code to be called by the shm_sink,
481
 
    // because it manages the shared memory synchronization
482
 
    sink_.render_callback(*this, bufferSize_);
483
 
}
484
 
 
485
 
 
486
 
bool VideoSendThread::captureFrame()
487
 
{
488
 
    AVPacket inpacket;
489
 
    int ret = av_read_frame(inputCtx_, &inpacket);
490
 
 
491
 
    if (ret == AVERROR(EAGAIN))
492
 
        return false;
493
 
    else if (ret < 0)
494
 
        EXIT_IF_FAIL(false, "Could not read frame");
495
 
 
496
 
    // Guarantees that we free the packet allocated by av_read_frame
497
 
    PacketHandle inpacket_handle(inpacket);
498
 
 
499
 
    if (!rawFrame_ and not (rawFrame_ = avcodec_alloc_frame())) {
500
 
        ERROR("Could not allocate video frame");
501
 
        threadRunning_ = false;
502
 
        return false;
503
 
    } else {
504
 
        avcodec_get_frame_defaults(rawFrame_);
505
 
    }
506
 
 
507
 
    // is this a packet from the video stream?
508
 
    if (inpacket.stream_index != streamIndex_)
509
 
        return false;
510
 
 
511
 
    // decode video frame from camera
512
 
    int frameFinished = 0;
513
 
    avcodec_decode_video2(inputDecoderCtx_, rawFrame_, &frameFinished,
514
 
                          &inpacket);
515
 
    if (!frameFinished)
516
 
        return false;
517
 
 
518
 
    encoderConvertCtx_ = sws_getCachedContext(encoderConvertCtx_,
519
 
                                              inputDecoderCtx_->width,
520
 
                                              inputDecoderCtx_->height,
521
 
                                              inputDecoderCtx_->pix_fmt,
522
 
                                              encoderCtx_->width,
523
 
                                              encoderCtx_->height,
524
 
                                              encoderCtx_->pix_fmt, SWS_BICUBIC,
525
 
                                              NULL, NULL, NULL);
526
 
    EXIT_IF_FAIL(encoderConvertCtx_, "Could not get encoder convert context");
527
 
    sws_scale(encoderConvertCtx_, rawFrame_->data, rawFrame_->linesize, 0,
528
 
              inputDecoderCtx_->height, scaledInput_->data,
529
 
              scaledInput_->linesize);
530
 
 
531
 
    // Set presentation timestamp on our scaled frame before encoding it
532
 
    scaledInput_->pts = frameNumber_++;
533
 
 
534
 
    return true;
535
 
}
536
 
 
537
 
 
538
 
void VideoSendThread::encodeAndSendVideo()
539
 
{
540
 
#if LIBAVCODEC_VERSION_INT > AV_VERSION_INT(53, 20, 0)
541
 
    if (forceKeyFrame_ > 0) {
542
 
        scaledInput_->pict_type = AV_PICTURE_TYPE_I;
543
 
        atomic_decrement(&forceKeyFrame_);
544
 
    } else if (scaledInput_->pict_type == AV_PICTURE_TYPE_I) {
545
 
        /* FIXME: Should be AV_PICTURE_TYPE_NONE for newer libavutil */
546
 
        scaledInput_->pict_type = (AVPictureType) 0;
547
 
    }
548
 
#else
549
 
    if (forceKeyFrame_ > 0) {
550
 
        scaledInput_->pict_type = FF_I_TYPE;
551
 
        atomic_decrement(&forceKeyFrame_);
552
 
    } else if (scaledInput_->pict_type == FF_I_TYPE) {
553
 
        scaledInput_->pict_type = (AVPictureType) 0;
554
 
    }
555
 
#endif
556
 
 
557
 
    const int encodedSize = avcodec_encode_video(encoderCtx_, encoderBuffer_,
558
 
                                                 encoderBufferSize_, scaledInput_);
559
 
 
560
 
    if (encodedSize <= 0)
561
 
        return;
562
 
 
563
 
    AVPacket opkt;
564
 
    av_init_packet(&opkt);
565
 
    PacketHandle opkt_handle(opkt);
566
 
 
567
 
    opkt.data = encoderBuffer_;
568
 
    opkt.size = encodedSize;
569
 
 
570
 
    // rescale pts from encoded video framerate to rtp
571
 
    // clock rate
572
 
    if (encoderCtx_->coded_frame->pts != static_cast<int64_t>(AV_NOPTS_VALUE))
573
 
        opkt.pts = av_rescale_q(encoderCtx_->coded_frame->pts,
574
 
                encoderCtx_->time_base,
575
 
                stream_->time_base);
576
 
    else
577
 
        opkt.pts = 0;
578
 
 
579
 
    // is it a key frame?
580
 
    if (encoderCtx_->coded_frame->key_frame)
581
 
        opkt.flags |= AV_PKT_FLAG_KEY;
582
 
    opkt.stream_index = stream_->index;
583
 
 
584
 
    // write the compressed frame to the output
585
 
    EXIT_IF_FAIL(av_interleaved_write_frame(outputCtx_, &opkt) >= 0,
586
 
                 "interleaved_write_frame failed");
587
 
}
588
 
 
589
 
VideoSendThread::~VideoSendThread()
590
 
{
591
 
    set_false_atomic(&threadRunning_);
592
 
    Manager::instance().getVideoControls()->stoppedDecoding(id_, sink_.openedName());
593
 
    if (thread_)
594
 
        pthread_join(thread_, NULL);
595
 
}
596
 
 
597
 
void VideoSendThread::forceKeyFrame()
598
 
{
599
 
    atomic_increment(&forceKeyFrame_);
600
 
}
601
 
 
602
 
} // end namespace sfl_video