~ubuntu-branches/ubuntu/vivid/bino/vivid-proposed

« back to all changes in this revision

Viewing changes to src/media_object.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Schaal
  • Date: 2011-09-09 14:23:54 UTC
  • Revision ID: james.westby@ubuntu.com-20110909142354-m1a9a4523i7ddb02
Tags: upstream-1.2.0
ImportĀ upstreamĀ versionĀ 1.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This file is part of bino, a 3D video player.
 
3
 *
 
4
 * Copyright (C) 2010-2011
 
5
 * Martin Lambers <marlam@marlam.de>
 
6
 * FrĆ©dĆ©ric Devernay <frederic.devernay@inrialpes.fr>
 
7
 * Joe <cuchac@email.cz>
 
8
 *
 
9
 * This program is free software; you can redistribute it and/or modify
 
10
 * it under the terms of the GNU General Public License as published by
 
11
 * the Free Software Foundation; either version 3 of the License, or
 
12
 * (at your option) any later version.
 
13
 *
 
14
 * This program is distributed in the hope that it will be useful,
 
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
 * GNU General Public License for more details.
 
18
 *
 
19
 * You should have received a copy of the GNU General Public License
 
20
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
21
 */
 
22
 
 
23
#include "config.h"
 
24
 
 
25
extern "C"
 
26
{
 
27
#define __STDC_CONSTANT_MACROS
 
28
#include <libavformat/avformat.h>
 
29
#include <libavdevice/avdevice.h>
 
30
#include <libavcodec/avcodec.h>
 
31
#include <libswscale/swscale.h>
 
32
}
 
33
 
 
34
#include <deque>
 
35
#include <limits>
 
36
#include <cerrno>
 
37
#include <cstring>
 
38
#include <cctype>
 
39
 
 
40
#if HAVE_SYSCONF
 
41
#  include <unistd.h>
 
42
#else
 
43
#  include <windows.h>
 
44
#endif
 
45
 
 
46
#include "gettext.h"
 
47
#define _(string) gettext(string)
 
48
 
 
49
#include "dbg.h"
 
50
#include "blob.h"
 
51
#include "exc.h"
 
52
#include "msg.h"
 
53
#include "str.h"
 
54
#include "thread.h"
 
55
 
 
56
#include "media_object.h"
 
57
 
 
58
 
 
59
// The read thread.
 
60
// This thread reads packets from the AVFormatContext and stores them in the
 
61
// appropriate packet queues.
 
62
class read_thread : public thread
 
63
{
 
64
private:
 
65
    const std::string _url;
 
66
    const bool _is_device;
 
67
    struct ffmpeg_stuff *_ffmpeg;
 
68
    bool _eof;
 
69
 
 
70
public:
 
71
    read_thread(const std::string &url, bool is_device, struct ffmpeg_stuff *ffmpeg);
 
72
    void run();
 
73
    void reset();
 
74
    bool eof() const
 
75
    {
 
76
        return _eof;
 
77
    }
 
78
};
 
79
 
 
80
// The video decode thread.
 
81
// This thread reads packets from its packet queue and decodes them to video frames.
 
82
class video_decode_thread : public thread
 
83
{
 
84
private:
 
85
    std::string _url;
 
86
    struct ffmpeg_stuff *_ffmpeg;
 
87
    int _video_stream;
 
88
    video_frame _frame;
 
89
 
 
90
    int64_t handle_timestamp(int64_t timestamp);
 
91
 
 
92
public:
 
93
    video_decode_thread(const std::string &url, struct ffmpeg_stuff *ffmpeg, int video_stream);
 
94
    void run();
 
95
    const video_frame &frame()
 
96
    {
 
97
        return _frame;
 
98
    }
 
99
};
 
100
 
 
101
// The audio decode thread.
 
102
// This thread reads packets from its packet queue and decodes them to audio blobs.
 
103
class audio_decode_thread : public thread
 
104
{
 
105
private:
 
106
    std::string _url;
 
107
    struct ffmpeg_stuff *_ffmpeg;
 
108
    int _audio_stream;
 
109
    audio_blob _blob;
 
110
 
 
111
    int64_t handle_timestamp(int64_t timestamp);
 
112
 
 
113
public:
 
114
    audio_decode_thread(const std::string &url, struct ffmpeg_stuff *ffmpeg, int audio_stream);
 
115
    void run();
 
116
    const audio_blob &blob()
 
117
    {
 
118
        return _blob;
 
119
    }
 
120
};
 
121
 
 
122
// The subtitle decode thread.
 
123
// This thread reads packets from its packet queue and decodes them to subtitle boxes.
 
124
class subtitle_decode_thread : public thread
 
125
{
 
126
private:
 
127
    std::string _url;
 
128
    struct ffmpeg_stuff *_ffmpeg;
 
129
    int _subtitle_stream;
 
130
    subtitle_box _box;
 
131
 
 
132
    int64_t handle_timestamp(int64_t timestamp);
 
133
 
 
134
public:
 
135
    subtitle_decode_thread(const std::string &url, struct ffmpeg_stuff *ffmpeg, int subtitle_stream);
 
136
    void run();
 
137
    const subtitle_box &box()
 
138
    {
 
139
        return _box;
 
140
    }
 
141
};
 
142
 
 
143
 
 
144
// Hide the FFmpeg stuff so that their messy header files cannot cause problems
 
145
// in other source files.
 
146
 
 
147
static const size_t audio_tmpbuf_size = (AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2;
 
148
 
 
149
struct ffmpeg_stuff
 
150
{
 
151
    AVFormatContext *format_ctx;
 
152
 
 
153
    bool have_active_audio_stream;
 
154
    int64_t pos;
 
155
 
 
156
    read_thread *reader;
 
157
 
 
158
    std::vector<int> video_streams;
 
159
    std::vector<AVCodecContext *> video_codec_ctxs;
 
160
    std::vector<video_frame> video_frame_templates;
 
161
    std::vector<struct SwsContext *> video_img_conv_ctxs;
 
162
    std::vector<AVCodec *> video_codecs;
 
163
    std::vector<std::deque<AVPacket> > video_packet_queues;
 
164
    std::vector<mutex> video_packet_queue_mutexes;
 
165
    std::vector<AVPacket> video_packets;
 
166
    std::vector<video_decode_thread> video_decode_threads;
 
167
    std::vector<AVFrame *> video_frames;
 
168
    std::vector<AVFrame *> video_out_frames;
 
169
    std::vector<uint8_t *> video_buffers;
 
170
    std::vector<int64_t> video_last_timestamps;
 
171
 
 
172
    std::vector<int> audio_streams;
 
173
    std::vector<AVCodecContext *> audio_codec_ctxs;
 
174
    std::vector<audio_blob> audio_blob_templates;
 
175
    std::vector<AVCodec *> audio_codecs;
 
176
    std::vector<std::deque<AVPacket> > audio_packet_queues;
 
177
    std::vector<mutex> audio_packet_queue_mutexes;
 
178
    std::vector<audio_decode_thread> audio_decode_threads;
 
179
    std::vector<unsigned char *> audio_tmpbufs;
 
180
    std::vector<blob> audio_blobs;
 
181
    std::vector<std::vector<unsigned char> > audio_buffers;
 
182
    std::vector<int64_t> audio_last_timestamps;
 
183
 
 
184
    std::vector<int> subtitle_streams;
 
185
    std::vector<AVCodecContext *> subtitle_codec_ctxs;
 
186
    std::vector<subtitle_box> subtitle_box_templates;
 
187
    std::vector<AVCodec *> subtitle_codecs;
 
188
    std::vector<std::deque<AVPacket> > subtitle_packet_queues;
 
189
    std::vector<mutex> subtitle_packet_queue_mutexes;
 
190
    std::vector<subtitle_decode_thread> subtitle_decode_threads;
 
191
    std::vector<std::deque<subtitle_box> > subtitle_box_buffers;
 
192
    std::vector<int64_t> subtitle_last_timestamps;
 
193
};
 
194
 
 
195
// Use one decoding thread per processor for video decoding.
 
196
static int video_decoding_threads()
 
197
{
 
198
    static long n = -1;
 
199
    if (n < 0)
 
200
    {
 
201
#ifdef HAVE_SYSCONF
 
202
        n = sysconf(_SC_NPROCESSORS_ONLN);
 
203
#else
 
204
        SYSTEM_INFO si;
 
205
        GetSystemInfo(&si);
 
206
        n = si.dwNumberOfProcessors;
 
207
#endif
 
208
        if (n < 1)
 
209
        {
 
210
            n = 1;
 
211
        }
 
212
        else if (n > 16)
 
213
        {
 
214
            n = 16;
 
215
        }
 
216
    }
 
217
    return n;
 
218
}
 
219
 
 
220
// Return FFmpeg error as std::string.
 
221
static std::string my_av_strerror(int err)
 
222
{
 
223
    blob b(1024);
 
224
    av_strerror(err, b.ptr<char>(), b.size());
 
225
    return std::string(b.ptr<const char>());
 
226
}
 
227
 
 
228
// Convert FFmpeg log messages to our log messages.
 
229
static void my_av_log(void *ptr, int level, const char *fmt, va_list vl)
 
230
{
 
231
    static mutex line_mutex;
 
232
    static std::string line;
 
233
    if (level > av_log_get_level())
 
234
    {
 
235
        return;
 
236
    }
 
237
 
 
238
    line_mutex.lock();
 
239
    std::string p;
 
240
    AVClass* avc = ptr ? *reinterpret_cast<AVClass**>(ptr) : NULL;
 
241
    if (avc)
 
242
    {
 
243
        p = str::asprintf("[%s @ %p] ", avc->item_name(ptr), ptr);
 
244
    }
 
245
    std::string s = str::vasprintf(fmt, vl);
 
246
    bool line_ends = false;
 
247
    if (s.length() > 0)
 
248
    {
 
249
        if (s[s.length() - 1] == '\n')
 
250
        {
 
251
            line_ends = true;
 
252
            s.erase(s.length() - 1);
 
253
        }
 
254
    }
 
255
    line += s;
 
256
    if (line_ends)
 
257
    {
 
258
        msg::level_t l;
 
259
        switch (level)
 
260
        {
 
261
        case AV_LOG_PANIC:
 
262
        case AV_LOG_FATAL:
 
263
        case AV_LOG_ERROR:
 
264
            l = msg::ERR;
 
265
            break;
 
266
        case AV_LOG_WARNING:
 
267
            l = msg::WRN;
 
268
            break;
 
269
        case AV_LOG_INFO:
 
270
        case AV_LOG_VERBOSE:
 
271
        case AV_LOG_DEBUG:
 
272
        default:
 
273
            l = msg::DBG;
 
274
            break;
 
275
        }
 
276
        size_t n;
 
277
        while ((n = line.find('\n')) != std::string::npos)
 
278
        {
 
279
            msg::msg(l, std::string("FFmpeg: ") + p + line.substr(0, n));
 
280
            line = line.substr(n + 1);
 
281
        }
 
282
        msg::msg(l, std::string("FFmpeg: ") + p + line);
 
283
        line.clear();
 
284
    }
 
285
    line_mutex.unlock();
 
286
}
 
287
 
 
288
// Handle timestamps
 
289
static int64_t timestamp_helper(int64_t &last_timestamp, int64_t timestamp)
 
290
{
 
291
    if (timestamp == std::numeric_limits<int64_t>::min())
 
292
    {
 
293
        timestamp = last_timestamp;
 
294
    }
 
295
    last_timestamp = timestamp;
 
296
    return timestamp;
 
297
}
 
298
 
 
299
// Get a stream duration
 
300
static int64_t stream_duration(AVStream *stream, AVFormatContext *format)
 
301
{
 
302
    // Try to get duration from the stream first. If that fails, fall back to
 
303
    // the value provided by the container.
 
304
    int64_t duration = stream->duration;
 
305
    if (duration > 0)
 
306
    {
 
307
        AVRational time_base = stream->time_base;
 
308
        return duration * 1000000 * time_base.num / time_base.den;
 
309
    }
 
310
    else
 
311
    {
 
312
        duration = format->duration;
 
313
        return duration * 1000000 / AV_TIME_BASE;
 
314
    }
 
315
}
 
316
 
 
317
 
 
318
media_object::media_object(bool always_convert_to_bgra32) :
 
319
    _always_convert_to_bgra32(always_convert_to_bgra32), _ffmpeg(NULL)
 
320
{
 
321
    avdevice_register_all();
 
322
    av_register_all();
 
323
    switch (msg::level())
 
324
    {
 
325
    case msg::DBG:
 
326
        av_log_set_level(AV_LOG_DEBUG);
 
327
        break;
 
328
    case msg::INF:
 
329
        av_log_set_level(AV_LOG_INFO);
 
330
        break;
 
331
    case msg::WRN:
 
332
        av_log_set_level(AV_LOG_WARNING);
 
333
        break;
 
334
    case msg::ERR:
 
335
        av_log_set_level(AV_LOG_ERROR);
 
336
        break;
 
337
    case msg::REQ:
 
338
    default:
 
339
        av_log_set_level(AV_LOG_FATAL);
 
340
        break;
 
341
    }
 
342
    av_log_set_callback(my_av_log);
 
343
}
 
344
 
 
345
media_object::~media_object()
 
346
{
 
347
    if (_ffmpeg)
 
348
    {
 
349
        close();
 
350
    }
 
351
}
 
352
 
 
353
void media_object::set_video_frame_template(int index)
 
354
{
 
355
    AVStream *video_stream = _ffmpeg->format_ctx->streams[_ffmpeg->video_streams[index]];
 
356
    AVCodecContext *video_codec_ctx = _ffmpeg->video_codec_ctxs[index];
 
357
    video_frame &video_frame_template = _ffmpeg->video_frame_templates[index];
 
358
 
 
359
    // Dimensions and aspect ratio
 
360
    video_frame_template.raw_width = video_codec_ctx->width;
 
361
    video_frame_template.raw_height = video_codec_ctx->height;
 
362
    int ar_num = 1;
 
363
    int ar_den = 1;
 
364
    int ar_snum = video_stream->sample_aspect_ratio.num;
 
365
    int ar_sden = video_stream->sample_aspect_ratio.den;
 
366
    int ar_cnum = video_codec_ctx->sample_aspect_ratio.num;
 
367
    int ar_cden = video_codec_ctx->sample_aspect_ratio.den;
 
368
    if (ar_cnum > 0 && ar_cden > 0)
 
369
    {
 
370
        ar_num = ar_cnum;
 
371
        ar_den = ar_cden;
 
372
    }
 
373
    else if (ar_snum > 0 && ar_sden > 0)
 
374
    {
 
375
        ar_num = ar_snum;
 
376
        ar_den = ar_sden;
 
377
    }
 
378
    video_frame_template.raw_aspect_ratio =
 
379
        static_cast<float>(ar_num * video_frame_template.raw_width)
 
380
        / static_cast<float>(ar_den * video_frame_template.raw_height);
 
381
    // Data layout and color space
 
382
    video_frame_template.layout = video_frame::bgra32;
 
383
    video_frame_template.color_space = video_frame::srgb;
 
384
    video_frame_template.value_range = video_frame::u8_full;
 
385
    video_frame_template.chroma_location = video_frame::center;
 
386
    if (!_always_convert_to_bgra32
 
387
            && (video_codec_ctx->pix_fmt == PIX_FMT_YUV444P
 
388
                || video_codec_ctx->pix_fmt == PIX_FMT_YUV422P
 
389
                || video_codec_ctx->pix_fmt == PIX_FMT_YUV420P))
 
390
    {
 
391
        if (video_codec_ctx->pix_fmt == PIX_FMT_YUV444P)
 
392
        {
 
393
            video_frame_template.layout = video_frame::yuv444p;
 
394
        }
 
395
        else if (video_codec_ctx->pix_fmt == PIX_FMT_YUV422P)
 
396
        {
 
397
            video_frame_template.layout = video_frame::yuv422p;
 
398
        }
 
399
        else
 
400
        {
 
401
            video_frame_template.layout = video_frame::yuv420p;
 
402
        }
 
403
        video_frame_template.color_space = video_frame::yuv601;
 
404
        if (video_codec_ctx->colorspace == AVCOL_SPC_BT709)
 
405
        {
 
406
            video_frame_template.color_space = video_frame::yuv709;
 
407
        }
 
408
        video_frame_template.value_range = video_frame::u8_mpeg;
 
409
        if (video_codec_ctx->color_range == AVCOL_RANGE_JPEG)
 
410
        {
 
411
            video_frame_template.value_range = video_frame::u8_full;
 
412
        }
 
413
        video_frame_template.chroma_location = video_frame::center;
 
414
        if (video_codec_ctx->chroma_sample_location == AVCHROMA_LOC_LEFT)
 
415
        {
 
416
            video_frame_template.chroma_location = video_frame::left;
 
417
        }
 
418
        else if (video_codec_ctx->chroma_sample_location == AVCHROMA_LOC_TOPLEFT)
 
419
        {
 
420
            video_frame_template.chroma_location = video_frame::topleft;
 
421
        }
 
422
    }
 
423
    else if (!_always_convert_to_bgra32
 
424
            && (video_codec_ctx->pix_fmt == PIX_FMT_YUVJ444P
 
425
                || video_codec_ctx->pix_fmt == PIX_FMT_YUVJ422P
 
426
                || video_codec_ctx->pix_fmt == PIX_FMT_YUVJ420P))
 
427
    {
 
428
        if (video_codec_ctx->pix_fmt == PIX_FMT_YUVJ444P)
 
429
        {
 
430
            video_frame_template.layout = video_frame::yuv444p;
 
431
        }
 
432
        else if (video_codec_ctx->pix_fmt == PIX_FMT_YUVJ422P)
 
433
        {
 
434
            video_frame_template.layout = video_frame::yuv422p;
 
435
        }
 
436
        else
 
437
        {
 
438
            video_frame_template.layout = video_frame::yuv420p;
 
439
        }
 
440
        video_frame_template.color_space = video_frame::yuv601;
 
441
        video_frame_template.value_range = video_frame::u8_full;
 
442
        video_frame_template.chroma_location = video_frame::center;
 
443
    }
 
444
    // Stereo layout
 
445
    video_frame_template.stereo_layout = video_frame::mono;
 
446
    video_frame_template.stereo_layout_swap = false;
 
447
    std::string val;
 
448
    /* Determine the stereo layout from the resolution.*/
 
449
    if (video_frame_template.raw_width / 2 > video_frame_template.raw_height)
 
450
    {
 
451
        video_frame_template.stereo_layout = video_frame::left_right;
 
452
    }
 
453
    else if (video_frame_template.raw_height > video_frame_template.raw_width)
 
454
    {
 
455
        video_frame_template.stereo_layout = video_frame::top_bottom;
 
456
    }
 
457
    /* Determine the input mode by looking at the file name.
 
458
     * This should be compatible to these conventions:
 
459
     * http://www.tru3d.com/technology/3D_Media_Formats_Software.php?file=TriDef%20Supported%203D%20Formats */
 
460
    std::string marker = _url.substr(0, _url.find_last_of('.'));
 
461
    size_t last_dash = marker.find_last_of('-');
 
462
    if (last_dash != std::string::npos)
 
463
    {
 
464
        marker = marker.substr(last_dash + 1);
 
465
    }
 
466
    else
 
467
    {
 
468
        marker = "";
 
469
    }
 
470
    for (size_t i = 0; i < marker.length(); i++)
 
471
    {
 
472
        marker[i] = std::tolower(marker[i]);
 
473
    }
 
474
    if (marker == "lr")
 
475
    {
 
476
        video_frame_template.stereo_layout = video_frame::left_right;
 
477
        video_frame_template.stereo_layout_swap = false;
 
478
    }
 
479
    else if (marker == "rl")
 
480
    {
 
481
        video_frame_template.stereo_layout = video_frame::left_right;
 
482
        video_frame_template.stereo_layout_swap = true;
 
483
    }
 
484
    else if (marker == "lrh" || marker == "lrq")
 
485
    {
 
486
        video_frame_template.stereo_layout = video_frame::left_right_half;
 
487
        video_frame_template.stereo_layout_swap = false;
 
488
    }
 
489
    else if (marker == "rlh" || marker == "rlq")
 
490
    {
 
491
        video_frame_template.stereo_layout = video_frame::left_right_half;
 
492
        video_frame_template.stereo_layout_swap = true;
 
493
    }
 
494
    else if (marker == "tb" || marker == "ab")
 
495
    {
 
496
        video_frame_template.stereo_layout = video_frame::top_bottom;
 
497
        video_frame_template.stereo_layout_swap = false;
 
498
    }
 
499
    else if (marker == "bt" || marker == "ba")
 
500
    {
 
501
        video_frame_template.stereo_layout = video_frame::top_bottom;
 
502
        video_frame_template.stereo_layout_swap = true;
 
503
    }
 
504
    else if (marker == "tbh" || marker == "abq")
 
505
    {
 
506
        video_frame_template.stereo_layout = video_frame::top_bottom_half;
 
507
        video_frame_template.stereo_layout_swap = false;
 
508
    }
 
509
    else if (marker == "bth" || marker == "baq")
 
510
    {
 
511
        video_frame_template.stereo_layout = video_frame::top_bottom_half;
 
512
        video_frame_template.stereo_layout_swap = true;
 
513
    }
 
514
    else if (marker == "eo")
 
515
    {
 
516
        video_frame_template.stereo_layout = video_frame::even_odd_rows;
 
517
        video_frame_template.stereo_layout_swap = false;
 
518
        // all image lines are given in this case, and there should be no interpolation [TODO]
 
519
    }
 
520
    else if (marker == "oe")
 
521
    {
 
522
        video_frame_template.stereo_layout = video_frame::even_odd_rows;
 
523
        video_frame_template.stereo_layout_swap = true;
 
524
        // all image lines are given in this case, and there should be no interpolation [TODO]
 
525
    }
 
526
    else if (marker == "eoq" || marker == "3dir")
 
527
    {
 
528
        video_frame_template.stereo_layout = video_frame::even_odd_rows;
 
529
        video_frame_template.stereo_layout_swap = false;
 
530
    }
 
531
    else if (marker == "oeq" || marker == "3di")
 
532
    {
 
533
        video_frame_template.stereo_layout = video_frame::even_odd_rows;
 
534
        video_frame_template.stereo_layout_swap = true;
 
535
    }
 
536
    else if (marker == "2d")
 
537
    {
 
538
        video_frame_template.stereo_layout = video_frame::mono;
 
539
        video_frame_template.stereo_layout_swap = false;
 
540
    }
 
541
    /* Check some tags defined at this link: http://www.3dtv.at/Knowhow/StereoWmvSpec_en.aspx
 
542
     * This is necessary to make the example movies provided by 3dtv.at work out of the box. */
 
543
    val = tag_value("StereoscopicLayout");
 
544
    if (val == "SideBySideRF" || val == "SideBySideLF")
 
545
    {
 
546
        video_frame_template.stereo_layout_swap = (val == "SideBySideRF");
 
547
        val = tag_value("StereoscopicHalfWidth");
 
548
        video_frame_template.stereo_layout = (val == "1" ? video_frame::left_right_half : video_frame::left_right);
 
549
 
 
550
    }
 
551
    else if (val == "OverUnderRT" || val == "OverUnderLT")
 
552
    {
 
553
        video_frame_template.stereo_layout_swap = (val == "OverUnderRT");
 
554
        val = tag_value("StereoscopicHalfHeight");
 
555
        video_frame_template.stereo_layout = (val == "1" ? video_frame::top_bottom_half : video_frame::top_bottom);
 
556
    }
 
557
    /* Check the Matroska StereoMode metadata, which is translated by FFmpeg to a "stereo_mode" tag.
 
558
     * This tag is per-track, not per-file!
 
559
     * This tag is the most reliable source of information about the stereo layout and should be used
 
560
     * by everyone. Unfortunately, we still have to look at the resolution to guess whether we have
 
561
     * a reduced resolution (*_half) stereo layout. */
 
562
    val = "";
 
563
    AVDictionaryEntry *tag = NULL;
 
564
    while ((tag = av_dict_get(video_stream->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
 
565
    {
 
566
        if (std::string(tag->key) == "stereo_mode")
 
567
        {
 
568
            val = tag->value;
 
569
            break;
 
570
        }
 
571
    }
 
572
    if (val == "mono")
 
573
    {
 
574
        video_frame_template.stereo_layout = video_frame::mono;
 
575
        video_frame_template.stereo_layout_swap = false;
 
576
    }
 
577
    else if (val == "left_right" || val == "right_left")
 
578
    {
 
579
        if (video_frame_template.raw_width / 2 > video_frame_template.raw_height)
 
580
        {
 
581
            video_frame_template.stereo_layout = video_frame::left_right;
 
582
        }
 
583
        else
 
584
        {
 
585
            video_frame_template.stereo_layout = video_frame::left_right_half;
 
586
        }
 
587
        video_frame_template.stereo_layout_swap = (val == "right_left");
 
588
    }
 
589
    else if (val == "top_bottom" || val == "bottom_top")
 
590
    {
 
591
        if (video_frame_template.raw_height > video_frame_template.raw_width)
 
592
        {
 
593
            video_frame_template.stereo_layout = video_frame::top_bottom;
 
594
        }
 
595
        else
 
596
        {
 
597
            video_frame_template.stereo_layout = video_frame::top_bottom_half;
 
598
        }
 
599
        video_frame_template.stereo_layout_swap = (val == "bottom_top");
 
600
    }
 
601
    else if (val == "row_interleaved_lr" || val == "row_interleaved_rl")
 
602
    {
 
603
        video_frame_template.stereo_layout = video_frame::even_odd_rows;
 
604
        video_frame_template.stereo_layout_swap = (val == "row_interleaved_rl");
 
605
    }
 
606
    else if (!val.empty())
 
607
    {
 
608
        msg::wrn(_("%s video stream %d: Unsupported stereo layout %s."),
 
609
                _url.c_str(), index + 1, str::sanitize(val).c_str());
 
610
        video_frame_template.stereo_layout = video_frame::mono;
 
611
        video_frame_template.stereo_layout_swap = false;
 
612
    }
 
613
    /* Sanity checks. If these fail, use safe fallback */
 
614
    if (((video_frame_template.stereo_layout == video_frame::left_right
 
615
                    || video_frame_template.stereo_layout == video_frame::left_right_half)
 
616
                && video_frame_template.raw_width % 2 != 0)
 
617
            || ((video_frame_template.stereo_layout == video_frame::top_bottom
 
618
                    || video_frame_template.stereo_layout == video_frame::top_bottom_half)
 
619
                && video_frame_template.raw_height % 2 != 0)
 
620
            || (video_frame_template.stereo_layout == video_frame::even_odd_rows
 
621
                && video_frame_template.raw_height % 2 != 0))
 
622
    {
 
623
        video_frame_template.stereo_layout = video_frame::mono;
 
624
        video_frame_template.stereo_layout_swap = false;
 
625
    }
 
626
    /* Set width and height of a single view */
 
627
    video_frame_template.set_view_dimensions();
 
628
}
 
629
 
 
630
void media_object::set_audio_blob_template(int index)
 
631
{
 
632
    AVStream *audio_stream = _ffmpeg->format_ctx->streams[_ffmpeg->audio_streams[index]];
 
633
    AVCodecContext *audio_codec_ctx = _ffmpeg->audio_codec_ctxs[index];
 
634
    audio_blob &audio_blob_template = _ffmpeg->audio_blob_templates[index];
 
635
 
 
636
    AVDictionaryEntry *tag = av_dict_get(audio_stream->metadata, "language", NULL, AV_DICT_IGNORE_SUFFIX);
 
637
    if (tag)
 
638
    {
 
639
        audio_blob_template.language = tag->value;
 
640
    }
 
641
    if (audio_codec_ctx->channels < 1
 
642
            || audio_codec_ctx->channels > 8
 
643
            || audio_codec_ctx->channels == 3
 
644
            || audio_codec_ctx->channels == 5)
 
645
    {
 
646
        throw exc(str::asprintf(_("%s audio stream %d: Cannot handle audio with %d channels."),
 
647
                    _url.c_str(), index + 1, audio_codec_ctx->channels));
 
648
    }
 
649
    audio_blob_template.channels = audio_codec_ctx->channels;
 
650
    audio_blob_template.rate = audio_codec_ctx->sample_rate;
 
651
    if (audio_codec_ctx->sample_fmt == AV_SAMPLE_FMT_U8)
 
652
    {
 
653
        audio_blob_template.sample_format = audio_blob::u8;
 
654
    }
 
655
    else if (audio_codec_ctx->sample_fmt == AV_SAMPLE_FMT_S16)
 
656
    {
 
657
        audio_blob_template.sample_format = audio_blob::s16;
 
658
    }
 
659
    else if (audio_codec_ctx->sample_fmt == AV_SAMPLE_FMT_FLT)
 
660
    {
 
661
        audio_blob_template.sample_format = audio_blob::f32;
 
662
    }
 
663
    else if (audio_codec_ctx->sample_fmt == AV_SAMPLE_FMT_DBL)
 
664
    {
 
665
        audio_blob_template.sample_format = audio_blob::d64;
 
666
    }
 
667
    else if (audio_codec_ctx->sample_fmt == AV_SAMPLE_FMT_S32
 
668
            && sizeof(int32_t) == sizeof(float))
 
669
    {
 
670
        // we need to convert this to AV_SAMPLE_FMT_FLT after decoding
 
671
        audio_blob_template.sample_format = audio_blob::f32;
 
672
    }
 
673
    else
 
674
    {
 
675
        throw exc(str::asprintf(_("%s audio stream %d: Cannot handle audio with sample format %s."),
 
676
                    _url.c_str(), index + 1, av_get_sample_fmt_name(audio_codec_ctx->sample_fmt)));
 
677
    }
 
678
}
 
679
 
 
680
void media_object::set_subtitle_box_template(int index)
 
681
{
 
682
    AVStream *subtitle_stream = _ffmpeg->format_ctx->streams[_ffmpeg->subtitle_streams[index]];
 
683
    //AVCodecContext *subtitle_codec_ctx = _ffmpeg->subtitle_codec_ctxs[index];
 
684
    subtitle_box &subtitle_box_template = _ffmpeg->subtitle_box_templates[index];
 
685
 
 
686
    AVDictionaryEntry *tag = av_dict_get(subtitle_stream->metadata, "language", NULL, AV_DICT_IGNORE_SUFFIX);
 
687
    if (tag)
 
688
    {
 
689
        subtitle_box_template.language = tag->value;
 
690
    }
 
691
}
 
692
 
 
693
void media_object::open(const std::string &url, const device_request &dev_request)
 
694
{
 
695
    assert(!_ffmpeg);
 
696
 
 
697
    _url = url;
 
698
    _is_device = dev_request.is_device();
 
699
    _ffmpeg = new struct ffmpeg_stuff;
 
700
    _ffmpeg->reader = new read_thread(_url, _is_device, _ffmpeg);
 
701
    int e;
 
702
 
 
703
    /* Set format and parameters for device input */
 
704
    AVInputFormat *iformat = NULL;
 
705
    AVDictionary *iparams = NULL;
 
706
    switch (dev_request.device)
 
707
    {
 
708
    case device_request::firewire:
 
709
        iformat = av_find_input_format("libdc1394");
 
710
        break;
 
711
    case device_request::x11:
 
712
        iformat = av_find_input_format("x11grab");
 
713
        break;
 
714
    case device_request::sys_default:
 
715
#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__
 
716
        iformat = av_find_input_format("vfwcap");
 
717
#elif defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ || defined __APPLE__
 
718
        iformat = av_find_input_format("bktr");
 
719
#else
 
720
        iformat = av_find_input_format("video4linux2");
 
721
#endif
 
722
        break;
 
723
    case device_request::no_device:
 
724
        break;
 
725
    }
 
726
    if (_is_device && !iformat)
 
727
    {
 
728
        throw exc(str::asprintf(_("No support available for %s device."),
 
729
                dev_request.device == device_request::firewire ? _("Firewire")
 
730
                : dev_request.device == device_request::x11 ? _("X11")
 
731
                : _("default")));
 
732
    }
 
733
    if (_is_device && dev_request.width != 0 && dev_request.height != 0)
 
734
    {
 
735
        av_dict_set(&iparams, "video_size", str::asprintf("%dx%d",
 
736
                    dev_request.width, dev_request.height).c_str(), 0);
 
737
    }
 
738
    if (_is_device && dev_request.frame_rate_num != 0 && dev_request.frame_rate_den != 0)
 
739
    {
 
740
        av_dict_set(&iparams, "framerate", str::asprintf("%d/%d",
 
741
                    dev_request.frame_rate_num, dev_request.frame_rate_den).c_str(), 0);
 
742
    }
 
743
 
 
744
    /* Open the input */
 
745
    _ffmpeg->format_ctx = NULL;
 
746
    if ((e = avformat_open_input(&_ffmpeg->format_ctx, _url.c_str(), iformat, &iparams)) != 0)
 
747
    {
 
748
        av_dict_free(&iparams);
 
749
        throw exc(str::asprintf(_("%s: %s"),
 
750
                    _url.c_str(), my_av_strerror(e).c_str()));
 
751
    }
 
752
    av_dict_free(&iparams);
 
753
    if (_is_device)
 
754
    {
 
755
        // For a camera device, do not read ahead multiple packets, to avoid a startup delay.
 
756
        _ffmpeg->format_ctx->max_analyze_duration = 0;
 
757
    }
 
758
    if ((e = av_find_stream_info(_ffmpeg->format_ctx)) < 0)
 
759
    {
 
760
        throw exc(str::asprintf(_("%s: Cannot read stream info: %s"),
 
761
                    _url.c_str(), my_av_strerror(e).c_str()));
 
762
    }
 
763
    av_dump_format(_ffmpeg->format_ctx, 0, _url.c_str(), 0);
 
764
 
 
765
    /* Metadata */
 
766
    AVDictionaryEntry *tag = NULL;
 
767
    while ((tag = av_dict_get(_ffmpeg->format_ctx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
 
768
    {
 
769
        _tag_names.push_back(tag->key);
 
770
        _tag_values.push_back(tag->value);
 
771
    }
 
772
 
 
773
    _ffmpeg->have_active_audio_stream = false;
 
774
    _ffmpeg->pos = std::numeric_limits<int64_t>::min();
 
775
 
 
776
    for (unsigned int i = 0; i < _ffmpeg->format_ctx->nb_streams
 
777
            && i < static_cast<unsigned int>(std::numeric_limits<int>::max()); i++)
 
778
    {
 
779
        _ffmpeg->format_ctx->streams[i]->discard = AVDISCARD_ALL;        // ignore by default; user must activate streams
 
780
        AVCodecContext *codec_ctx = _ffmpeg->format_ctx->streams[i]->codec;
 
781
        AVCodec *codec = NULL;
 
782
        if (_ffmpeg->format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
 
783
        {
 
784
            // Activate multithreaded decoding. This must be done before opening the codec; see
 
785
            // http://lists.gnu.org/archive/html/bino-list/2011-08/msg00019.html
 
786
            codec_ctx->thread_count = video_decoding_threads();
 
787
        }
 
788
        // Find and open the codec. CODEC_ID_TEXT is a special case: it has no decoder since it is unencoded raw data.
 
789
        if (_ffmpeg->format_ctx->streams[i]->codec->codec_id != CODEC_ID_TEXT
 
790
                && (!(codec = avcodec_find_decoder(_ffmpeg->format_ctx->streams[i]->codec->codec_id))
 
791
                    || (e = avcodec_open(codec_ctx, codec)) < 0))
 
792
        {
 
793
            msg::wrn(_("%s stream %d: Cannot open %s: %s"), _url.c_str(), i,
 
794
                    _ffmpeg->format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO ? _("video codec")
 
795
                    : _ffmpeg->format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO ? _("audio codec")
 
796
                    : _ffmpeg->format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_SUBTITLE ? _("subtitle codec")
 
797
                    : _("data"),
 
798
                    codec ? my_av_strerror(e).c_str() : _("codec not supported"));
 
799
        }
 
800
        else if (_ffmpeg->format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
 
801
        {
 
802
            _ffmpeg->video_streams.push_back(i);
 
803
            int j = _ffmpeg->video_streams.size() - 1;
 
804
            msg::dbg(_url + " stream " + str::from(i) + " is video stream " + str::from(j) + ".");
 
805
            _ffmpeg->video_codec_ctxs.push_back(codec_ctx);
 
806
            if (_ffmpeg->video_codec_ctxs[j]->width < 1 || _ffmpeg->video_codec_ctxs[j]->height < 1)
 
807
            {
 
808
                throw exc(str::asprintf(_("%s video stream %d: Invalid frame size."),
 
809
                            _url.c_str(), j + 1));
 
810
            }
 
811
            _ffmpeg->video_codecs.push_back(codec);
 
812
            // Determine frame template.
 
813
            _ffmpeg->video_frame_templates.push_back(video_frame());
 
814
            set_video_frame_template(j);
 
815
            // Allocate things required for decoding
 
816
            _ffmpeg->video_packets.push_back(AVPacket());
 
817
            av_init_packet(&(_ffmpeg->video_packets[j]));
 
818
            _ffmpeg->video_decode_threads.push_back(video_decode_thread(_url, _ffmpeg, j));
 
819
            _ffmpeg->video_frames.push_back(avcodec_alloc_frame());
 
820
            if (!_ffmpeg->video_frames[j])
 
821
            {
 
822
                throw exc(HERE + ": " + strerror(ENOMEM));
 
823
            }
 
824
            if (_ffmpeg->video_frame_templates[j].layout == video_frame::bgra32)
 
825
            {
 
826
                // Initialize things needed for software pixel format conversion
 
827
                int bufsize = avpicture_get_size(PIX_FMT_BGRA,
 
828
                        _ffmpeg->video_codec_ctxs[j]->width, _ffmpeg->video_codec_ctxs[j]->height);
 
829
                _ffmpeg->video_out_frames.push_back(avcodec_alloc_frame());
 
830
                _ffmpeg->video_buffers.push_back(static_cast<uint8_t *>(av_malloc(bufsize)));
 
831
                if (!_ffmpeg->video_out_frames[j] || !_ffmpeg->video_buffers[j])
 
832
                {
 
833
                    throw exc(HERE + ": " + strerror(ENOMEM));
 
834
                }
 
835
                avpicture_fill(reinterpret_cast<AVPicture *>(_ffmpeg->video_out_frames[j]), _ffmpeg->video_buffers[j],
 
836
                        PIX_FMT_BGRA, _ffmpeg->video_codec_ctxs[j]->width, _ffmpeg->video_codec_ctxs[j]->height);
 
837
                // Call sws_getCachedContext(NULL, ...) instead of sws_getContext(...) just to avoid a deprecation warning.
 
838
                _ffmpeg->video_img_conv_ctxs.push_back(sws_getCachedContext(NULL,
 
839
                            _ffmpeg->video_codec_ctxs[j]->width, _ffmpeg->video_codec_ctxs[j]->height, _ffmpeg->video_codec_ctxs[j]->pix_fmt,
 
840
                            _ffmpeg->video_codec_ctxs[j]->width, _ffmpeg->video_codec_ctxs[j]->height, PIX_FMT_BGRA,
 
841
                            SWS_POINT, NULL, NULL, NULL));
 
842
                if (!_ffmpeg->video_img_conv_ctxs[j])
 
843
                {
 
844
                    throw exc(str::asprintf(_("%s video stream %d: Cannot initialize conversion context."),
 
845
                                _url.c_str(), j + 1));
 
846
                }
 
847
            }
 
848
            else
 
849
            {
 
850
                _ffmpeg->video_out_frames.push_back(NULL);
 
851
                _ffmpeg->video_buffers.push_back(NULL);
 
852
                _ffmpeg->video_img_conv_ctxs.push_back(NULL);
 
853
            }
 
854
            _ffmpeg->video_last_timestamps.push_back(std::numeric_limits<int64_t>::min());
 
855
        }
 
856
        else if (_ffmpeg->format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
 
857
        {
 
858
            _ffmpeg->audio_streams.push_back(i);
 
859
            int j = _ffmpeg->audio_streams.size() - 1;
 
860
            msg::dbg(_url + " stream " + str::from(i) + " is audio stream " + str::from(j) + ".");
 
861
            _ffmpeg->audio_codec_ctxs.push_back(codec_ctx);
 
862
            _ffmpeg->audio_codecs.push_back(codec);
 
863
            _ffmpeg->audio_blob_templates.push_back(audio_blob());
 
864
            set_audio_blob_template(j);
 
865
            _ffmpeg->audio_decode_threads.push_back(audio_decode_thread(_url, _ffmpeg, j));
 
866
            // Manage audio_tmpbufs with av_malloc/av_free, to guarantee correct alignment.
 
867
            // Not doing this results in hard to debug crashes on some systems.
 
868
            _ffmpeg->audio_tmpbufs.push_back(static_cast<unsigned char*>(av_malloc(audio_tmpbuf_size)));
 
869
            if (!_ffmpeg->audio_tmpbufs[j])
 
870
            {
 
871
                throw exc(HERE + ": " + strerror(ENOMEM));
 
872
            }
 
873
            _ffmpeg->audio_blobs.push_back(blob());
 
874
            _ffmpeg->audio_buffers.push_back(std::vector<unsigned char>());
 
875
            _ffmpeg->audio_last_timestamps.push_back(std::numeric_limits<int64_t>::min());
 
876
        }
 
877
        else if (_ffmpeg->format_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_SUBTITLE)
 
878
        {
 
879
            _ffmpeg->subtitle_streams.push_back(i);
 
880
            int j = _ffmpeg->subtitle_streams.size() - 1;
 
881
            msg::dbg(_url + " stream " + str::from(i) + " is subtitle stream " + str::from(j) + ".");
 
882
            _ffmpeg->subtitle_codec_ctxs.push_back(codec_ctx);
 
883
            // CODEC_ID_TEXT does not have any decoder; it is just UTF-8 text in the packet data.
 
884
            _ffmpeg->subtitle_codecs.push_back(
 
885
                    _ffmpeg->subtitle_codec_ctxs[j]->codec_id == CODEC_ID_TEXT ? NULL : codec);
 
886
            _ffmpeg->subtitle_box_templates.push_back(subtitle_box());
 
887
            set_subtitle_box_template(j);
 
888
            _ffmpeg->subtitle_decode_threads.push_back(subtitle_decode_thread(_url, _ffmpeg, j));
 
889
            _ffmpeg->subtitle_box_buffers.push_back(std::deque<subtitle_box>());
 
890
            _ffmpeg->subtitle_last_timestamps.push_back(std::numeric_limits<int64_t>::min());
 
891
        }
 
892
        else
 
893
        {
 
894
            msg::dbg(_url + " stream " + str::from(i) + " contains neither video nor audio nor subtitles.");
 
895
        }
 
896
    }
 
897
    _ffmpeg->video_packet_queues.resize(video_streams());
 
898
    _ffmpeg->audio_packet_queues.resize(audio_streams());
 
899
    _ffmpeg->subtitle_packet_queues.resize(subtitle_streams());
 
900
    _ffmpeg->video_packet_queue_mutexes.resize(video_streams());
 
901
    _ffmpeg->audio_packet_queue_mutexes.resize(audio_streams());
 
902
    _ffmpeg->subtitle_packet_queue_mutexes.resize(subtitle_streams());
 
903
 
 
904
    msg::inf(_url + ":");
 
905
    for (int i = 0; i < video_streams(); i++)
 
906
    {
 
907
        msg::inf(4, _("Video stream %d: %s / %s, %g seconds"), i,
 
908
                video_frame_template(i).format_info().c_str(),
 
909
                video_frame_template(i).format_name().c_str(),
 
910
                video_duration(i) / 1e6f);
 
911
        msg::inf(8, _("Using up to %d threads for decoding."),
 
912
                _ffmpeg->video_codec_ctxs.at(i)->thread_count);
 
913
    }
 
914
    for (int i = 0; i < audio_streams(); i++)
 
915
    {
 
916
        msg::inf(4, _("Audio stream %d: %s / %s, %g seconds"), i,
 
917
                audio_blob_template(i).format_info().c_str(),
 
918
                audio_blob_template(i).format_name().c_str(),
 
919
                audio_duration(i) / 1e6f);
 
920
    }
 
921
    for (int i = 0; i < subtitle_streams(); i++)
 
922
    {
 
923
        msg::inf(4, _("Subtitle stream %d: %s / %s, %g seconds"), i,
 
924
                subtitle_box_template(i).format_info().c_str(),
 
925
                subtitle_box_template(i).format_name().c_str(),
 
926
                subtitle_duration(i) / 1e6f);
 
927
    }
 
928
    if (video_streams() == 0 && audio_streams() == 0 && subtitle_streams() == 0)
 
929
    {
 
930
        msg::inf(4, _("No usable streams."));
 
931
    }
 
932
}
 
933
 
 
934
const std::string &media_object::url() const
 
935
{
 
936
    return _url;
 
937
}
 
938
 
 
939
size_t media_object::tags() const
 
940
{
 
941
    return _tag_names.size();
 
942
}
 
943
 
 
944
const std::string &media_object::tag_name(size_t i) const
 
945
{
 
946
    assert(i < tags());
 
947
    return _tag_names[i];
 
948
}
 
949
 
 
950
const std::string &media_object::tag_value(size_t i) const
 
951
{
 
952
    assert(i < tags());
 
953
    return _tag_values[i];
 
954
}
 
955
 
 
956
const std::string &media_object::tag_value(const std::string &tag_name) const
 
957
{
 
958
    static std::string empty;
 
959
    for (size_t i = 0; i < _tag_names.size(); i++)
 
960
    {
 
961
        if (std::string(tag_name) == _tag_names[i])
 
962
        {
 
963
            return _tag_values[i];
 
964
        }
 
965
    }
 
966
    return empty;
 
967
}
 
968
 
 
969
int media_object::video_streams() const
 
970
{
 
971
    return _ffmpeg->video_streams.size();
 
972
}
 
973
 
 
974
int media_object::audio_streams() const
 
975
{
 
976
    return _ffmpeg->audio_streams.size();
 
977
}
 
978
 
 
979
int media_object::subtitle_streams() const
 
980
{
 
981
    return _ffmpeg->subtitle_streams.size();
 
982
}
 
983
 
 
984
void media_object::video_stream_set_active(int index, bool active)
 
985
{
 
986
    assert(index >= 0);
 
987
    assert(index < video_streams());
 
988
    // Stop decoder threads
 
989
    for (size_t i = 0; i < _ffmpeg->video_streams.size(); i++)
 
990
    {
 
991
        _ffmpeg->video_decode_threads[i].finish();
 
992
    }
 
993
    for (size_t i = 0; i < _ffmpeg->audio_streams.size(); i++)
 
994
    {
 
995
        _ffmpeg->audio_decode_threads[i].finish();
 
996
    }
 
997
    for (size_t i = 0; i < _ffmpeg->subtitle_streams.size(); i++)
 
998
    {
 
999
        _ffmpeg->subtitle_decode_threads[i].finish();
 
1000
    }
 
1001
    // Stop reading packets
 
1002
    _ffmpeg->reader->finish();
 
1003
    // Set status
 
1004
    _ffmpeg->format_ctx->streams[_ffmpeg->video_streams.at(index)]->discard =
 
1005
        (active ? AVDISCARD_DEFAULT : AVDISCARD_ALL);
 
1006
    // Restart reader
 
1007
    _ffmpeg->reader->start();
 
1008
}
 
1009
 
 
1010
void media_object::audio_stream_set_active(int index, bool active)
 
1011
{
 
1012
    assert(index >= 0);
 
1013
    assert(index < audio_streams());
 
1014
    // Stop decoder threads
 
1015
    for (size_t i = 0; i < _ffmpeg->video_streams.size(); i++)
 
1016
    {
 
1017
        _ffmpeg->video_decode_threads[i].finish();
 
1018
    }
 
1019
    for (size_t i = 0; i < _ffmpeg->audio_streams.size(); i++)
 
1020
    {
 
1021
        _ffmpeg->audio_decode_threads[i].finish();
 
1022
    }
 
1023
    for (size_t i = 0; i < _ffmpeg->subtitle_streams.size(); i++)
 
1024
    {
 
1025
        _ffmpeg->subtitle_decode_threads[i].finish();
 
1026
    }
 
1027
    // Stop reading packets
 
1028
    _ffmpeg->reader->finish();
 
1029
    // Set status
 
1030
    _ffmpeg->format_ctx->streams[_ffmpeg->audio_streams.at(index)]->discard =
 
1031
        (active ? AVDISCARD_DEFAULT : AVDISCARD_ALL);
 
1032
    _ffmpeg->have_active_audio_stream = false;
 
1033
    for (int i = 0; i < audio_streams(); i++)
 
1034
    {
 
1035
        if (_ffmpeg->format_ctx->streams[_ffmpeg->audio_streams.at(index)]->discard == AVDISCARD_DEFAULT)
 
1036
        {
 
1037
            _ffmpeg->have_active_audio_stream = true;
 
1038
            break;
 
1039
        }
 
1040
    }
 
1041
    // Restart reader
 
1042
    _ffmpeg->reader->start();
 
1043
}
 
1044
 
 
1045
void media_object::subtitle_stream_set_active(int index, bool active)
 
1046
{
 
1047
    assert(index >= 0);
 
1048
    assert(index < subtitle_streams());
 
1049
    // Stop decoder threads
 
1050
    for (size_t i = 0; i < _ffmpeg->video_streams.size(); i++)
 
1051
    {
 
1052
        _ffmpeg->video_decode_threads[i].finish();
 
1053
    }
 
1054
    for (size_t i = 0; i < _ffmpeg->audio_streams.size(); i++)
 
1055
    {
 
1056
        _ffmpeg->audio_decode_threads[i].finish();
 
1057
    }
 
1058
    for (size_t i = 0; i < _ffmpeg->subtitle_streams.size(); i++)
 
1059
    {
 
1060
        _ffmpeg->subtitle_decode_threads[i].finish();
 
1061
    }
 
1062
    // Stop reading packets
 
1063
    _ffmpeg->reader->finish();
 
1064
    // Set status
 
1065
    _ffmpeg->format_ctx->streams[_ffmpeg->subtitle_streams.at(index)]->discard =
 
1066
        (active ? AVDISCARD_DEFAULT : AVDISCARD_ALL);
 
1067
    // Restart reader
 
1068
    _ffmpeg->reader->start();
 
1069
}
 
1070
 
 
1071
const video_frame &media_object::video_frame_template(int video_stream) const
 
1072
{
 
1073
    assert(video_stream >= 0);
 
1074
    assert(video_stream < video_streams());
 
1075
    return _ffmpeg->video_frame_templates.at(video_stream);
 
1076
}
 
1077
 
 
1078
int media_object::video_frame_rate_numerator(int index) const
 
1079
{
 
1080
    assert(index >= 0);
 
1081
    assert(index < video_streams());
 
1082
    return _ffmpeg->format_ctx->streams[_ffmpeg->video_streams.at(index)]->r_frame_rate.num;
 
1083
}
 
1084
 
 
1085
int media_object::video_frame_rate_denominator(int index) const
 
1086
{
 
1087
    assert(index >= 0);
 
1088
    assert(index < video_streams());
 
1089
    return _ffmpeg->format_ctx->streams[_ffmpeg->video_streams.at(index)]->r_frame_rate.den;
 
1090
}
 
1091
 
 
1092
int64_t media_object::video_duration(int index) const
 
1093
{
 
1094
    assert(index >= 0);
 
1095
    assert(index < video_streams());
 
1096
    return stream_duration(
 
1097
            _ffmpeg->format_ctx->streams[_ffmpeg->video_streams.at(index)],
 
1098
            _ffmpeg->format_ctx);
 
1099
}
 
1100
 
 
1101
const audio_blob &media_object::audio_blob_template(int audio_stream) const
 
1102
{
 
1103
    assert(audio_stream >= 0);
 
1104
    assert(audio_stream < audio_streams());
 
1105
    return _ffmpeg->audio_blob_templates.at(audio_stream);
 
1106
}
 
1107
 
 
1108
int64_t media_object::audio_duration(int index) const
 
1109
{
 
1110
    assert(index >= 0);
 
1111
    assert(index < audio_streams());
 
1112
    return stream_duration(
 
1113
            _ffmpeg->format_ctx->streams[_ffmpeg->audio_streams.at(index)],
 
1114
            _ffmpeg->format_ctx);
 
1115
}
 
1116
 
 
1117
const subtitle_box &media_object::subtitle_box_template(int subtitle_stream) const
 
1118
{
 
1119
    assert(subtitle_stream >= 0);
 
1120
    assert(subtitle_stream < subtitle_streams());
 
1121
    return _ffmpeg->subtitle_box_templates.at(subtitle_stream);
 
1122
}
 
1123
 
 
1124
int64_t media_object::subtitle_duration(int index) const
 
1125
{
 
1126
    assert(index >= 0);
 
1127
    assert(index < subtitle_streams());
 
1128
    return stream_duration(
 
1129
            _ffmpeg->format_ctx->streams[_ffmpeg->subtitle_streams.at(index)],
 
1130
            _ffmpeg->format_ctx);
 
1131
}
 
1132
 
 
1133
read_thread::read_thread(const std::string &url, bool is_device, struct ffmpeg_stuff *ffmpeg) :
 
1134
    _url(url), _is_device(is_device), _ffmpeg(ffmpeg), _eof(false)
 
1135
{
 
1136
}
 
1137
 
 
1138
void read_thread::run()
 
1139
{
 
1140
    while (!_eof)
 
1141
    {
 
1142
        // We need another packet if the number of queued packets for an active stream is below a threshold.
 
1143
        // For files, we often want to read ahead to avoid i/o waits. For devices, we do not want to read
 
1144
        // ahead to avoid latency.
 
1145
        const size_t video_stream_low_threshold = (_is_device ? 1 : 2);         // Often, 1 packet results in one video frame
 
1146
        const size_t audio_stream_low_threshold = (_is_device ? 1 : 5);         // Often, 3-4 packets are needed for one buffer fill
 
1147
        const size_t subtitle_stream_low_threshold = (_is_device ? 1 : 1);      // Just a guess
 
1148
        bool need_another_packet = false;
 
1149
        for (size_t i = 0; !need_another_packet && i < _ffmpeg->video_streams.size(); i++)
 
1150
        {
 
1151
            if (_ffmpeg->format_ctx->streams[_ffmpeg->video_streams[i]]->discard == AVDISCARD_DEFAULT)
 
1152
            {
 
1153
                _ffmpeg->video_packet_queue_mutexes[i].lock();
 
1154
                need_another_packet = _ffmpeg->video_packet_queues[i].size() < video_stream_low_threshold;
 
1155
                _ffmpeg->video_packet_queue_mutexes[i].unlock();
 
1156
            }
 
1157
        }
 
1158
        for (size_t i = 0; !need_another_packet && i < _ffmpeg->audio_streams.size(); i++)
 
1159
        {
 
1160
            if (_ffmpeg->format_ctx->streams[_ffmpeg->audio_streams[i]]->discard == AVDISCARD_DEFAULT)
 
1161
            {
 
1162
                _ffmpeg->audio_packet_queue_mutexes[i].lock();
 
1163
                    need_another_packet = _ffmpeg->audio_packet_queues[i].size() < audio_stream_low_threshold;
 
1164
                    _ffmpeg->audio_packet_queue_mutexes[i].unlock();
 
1165
            }
 
1166
        }
 
1167
        for (size_t i = 0; !need_another_packet && i < _ffmpeg->subtitle_streams.size(); i++)
 
1168
        {
 
1169
            if (_ffmpeg->format_ctx->streams[_ffmpeg->subtitle_streams[i]]->discard == AVDISCARD_DEFAULT)
 
1170
            {
 
1171
                _ffmpeg->subtitle_packet_queue_mutexes[i].lock();
 
1172
                need_another_packet = _ffmpeg->subtitle_packet_queues[i].size() < subtitle_stream_low_threshold;
 
1173
                _ffmpeg->subtitle_packet_queue_mutexes[i].unlock();
 
1174
            }
 
1175
        }
 
1176
        if (!need_another_packet)
 
1177
        {
 
1178
            msg::dbg(_url + ": No need to read more packets.");
 
1179
            break;
 
1180
        }
 
1181
        // Read a packet.
 
1182
        msg::dbg(_url + ": Reading a packet.");
 
1183
        AVPacket packet;
 
1184
        int e = av_read_frame(_ffmpeg->format_ctx, &packet);
 
1185
        if (e < 0)
 
1186
        {
 
1187
            if (e == AVERROR_EOF)
 
1188
            {
 
1189
                msg::dbg(_url + ": EOF.");
 
1190
                _eof = true;
 
1191
                return;
 
1192
            }
 
1193
            else
 
1194
            {
 
1195
                throw exc(str::asprintf(_("%s: %s"), _url.c_str(), my_av_strerror(e).c_str()));
 
1196
            }
 
1197
        }
 
1198
        // Put the packet in the right queue.
 
1199
        bool packet_queued = false;
 
1200
        for (size_t i = 0; i < _ffmpeg->video_streams.size() && !packet_queued; i++)
 
1201
        {
 
1202
            if (packet.stream_index == _ffmpeg->video_streams[i])
 
1203
            {
 
1204
                // We do not check for missing timestamps here, as we do with audio
 
1205
                // packets, for the following reasons:
 
1206
                // 1. The video decoder might fill in a timestamp for us
 
1207
                // 2. We cannot drop video packets anyway, because of their
 
1208
                //    interdependencies. We would mess up decoding.
 
1209
                if (av_dup_packet(&packet) < 0)
 
1210
                {
 
1211
                    throw exc(str::asprintf(_("%s: Cannot duplicate packet."), _url.c_str()));
 
1212
                }
 
1213
                _ffmpeg->video_packet_queue_mutexes[i].lock();
 
1214
                _ffmpeg->video_packet_queues[i].push_back(packet);
 
1215
                _ffmpeg->video_packet_queue_mutexes[i].unlock();
 
1216
                packet_queued = true;
 
1217
                msg::dbg(_url + ": "
 
1218
                        + str::from(_ffmpeg->video_packet_queues[i].size())
 
1219
                        + " packets queued in video stream " + str::from(i) + ".");
 
1220
            }
 
1221
        }
 
1222
        for (size_t i = 0; i < _ffmpeg->audio_streams.size() && !packet_queued; i++)
 
1223
        {
 
1224
            if (packet.stream_index == _ffmpeg->audio_streams[i])
 
1225
            {
 
1226
                _ffmpeg->audio_packet_queue_mutexes[i].lock();
 
1227
                if (_ffmpeg->audio_packet_queues[i].empty()
 
1228
                        && _ffmpeg->audio_last_timestamps[i] == std::numeric_limits<int64_t>::min()
 
1229
                        && packet.dts == static_cast<int64_t>(AV_NOPTS_VALUE))
 
1230
                {
 
1231
                    // We have no packet in the queue and no last timestamp, probably
 
1232
                    // because we just seeked. We *need* a packet with a timestamp.
 
1233
                    msg::dbg(_url + ": audio stream " + str::from(i)
 
1234
                            + ": dropping packet because it has no timestamp");
 
1235
                }
 
1236
                else
 
1237
                {
 
1238
                    if (av_dup_packet(&packet) < 0)
 
1239
                    {
 
1240
                        _ffmpeg->audio_packet_queue_mutexes[i].unlock();
 
1241
                        throw exc(str::asprintf(_("%s: Cannot duplicate packet."), _url.c_str()));
 
1242
                    }
 
1243
                    _ffmpeg->audio_packet_queues[i].push_back(packet);
 
1244
                    packet_queued = true;
 
1245
                    msg::dbg(_url + ": "
 
1246
                            + str::from(_ffmpeg->audio_packet_queues[i].size())
 
1247
                            + " packets queued in audio stream " + str::from(i) + ".");
 
1248
                }
 
1249
                _ffmpeg->audio_packet_queue_mutexes[i].unlock();
 
1250
            }
 
1251
        }
 
1252
        for (size_t i = 0; i < _ffmpeg->subtitle_streams.size() && !packet_queued; i++)
 
1253
        {
 
1254
            if (packet.stream_index == _ffmpeg->subtitle_streams[i])
 
1255
            {
 
1256
                _ffmpeg->subtitle_packet_queue_mutexes[i].lock();
 
1257
                if (_ffmpeg->subtitle_packet_queues[i].empty()
 
1258
                        && _ffmpeg->subtitle_last_timestamps[i] == std::numeric_limits<int64_t>::min()
 
1259
                        && packet.dts == static_cast<int64_t>(AV_NOPTS_VALUE))
 
1260
                {
 
1261
                    // We have no packet in the queue and no last timestamp, probably
 
1262
                    // because we just seeked. We want a packet with a timestamp.
 
1263
                    msg::dbg(_url + ": subtitle stream " + str::from(i)
 
1264
                            + ": dropping packet because it has no timestamp");
 
1265
                }
 
1266
                else
 
1267
                {
 
1268
                    if (av_dup_packet(&packet) < 0)
 
1269
                    {
 
1270
                        _ffmpeg->subtitle_packet_queue_mutexes[i].unlock();
 
1271
                        throw exc(str::asprintf(_("%s: Cannot duplicate packet."), _url.c_str()));
 
1272
                    }
 
1273
                    _ffmpeg->subtitle_packet_queues[i].push_back(packet);
 
1274
                    packet_queued = true;
 
1275
                    msg::dbg(_url + ": "
 
1276
                            + str::from(_ffmpeg->subtitle_packet_queues[i].size())
 
1277
                            + " packets queued in subtitle stream " + str::from(i) + ".");
 
1278
                }
 
1279
                _ffmpeg->subtitle_packet_queue_mutexes[i].unlock();
 
1280
            }
 
1281
        }
 
1282
        if (!packet_queued)
 
1283
        {
 
1284
            av_free_packet(&packet);
 
1285
        }
 
1286
    }
 
1287
}
 
1288
 
 
1289
void read_thread::reset()
 
1290
{
 
1291
    exception() = exc();
 
1292
    _eof = false;
 
1293
}
 
1294
 
 
1295
video_decode_thread::video_decode_thread(const std::string &url, struct ffmpeg_stuff *ffmpeg, int video_stream) :
 
1296
    _url(url), _ffmpeg(ffmpeg), _video_stream(video_stream), _frame()
 
1297
{
 
1298
}
 
1299
 
 
1300
int64_t video_decode_thread::handle_timestamp(int64_t timestamp)
 
1301
{
 
1302
    int64_t ts = timestamp_helper(_ffmpeg->video_last_timestamps[_video_stream], timestamp);
 
1303
    if (!_ffmpeg->have_active_audio_stream || _ffmpeg->pos == std::numeric_limits<int64_t>::min())
 
1304
    {
 
1305
        _ffmpeg->pos = ts;
 
1306
    }
 
1307
    return ts;
 
1308
}
 
1309
 
 
1310
void video_decode_thread::run()
 
1311
{
 
1312
    int frame_finished = 0;
 
1313
    do
 
1314
    {
 
1315
        bool empty;
 
1316
        do
 
1317
        {
 
1318
            _ffmpeg->video_packet_queue_mutexes[_video_stream].lock();
 
1319
            empty = _ffmpeg->video_packet_queues[_video_stream].empty();
 
1320
            _ffmpeg->video_packet_queue_mutexes[_video_stream].unlock();
 
1321
            if (empty)
 
1322
            {
 
1323
                if (_ffmpeg->reader->eof())
 
1324
                {
 
1325
                    _frame = video_frame();
 
1326
                    return;
 
1327
                }
 
1328
                msg::dbg(_url + ": video stream " + str::from(_video_stream) + ": need to wait for packets...");
 
1329
                _ffmpeg->reader->start();
 
1330
                _ffmpeg->reader->finish();
 
1331
            }
 
1332
        }
 
1333
        while (empty);
 
1334
        av_free_packet(&(_ffmpeg->video_packets[_video_stream]));
 
1335
        _ffmpeg->video_packet_queue_mutexes[_video_stream].lock();
 
1336
        _ffmpeg->video_packets[_video_stream] = _ffmpeg->video_packet_queues[_video_stream].front();
 
1337
        _ffmpeg->video_packet_queues[_video_stream].pop_front();
 
1338
        _ffmpeg->video_packet_queue_mutexes[_video_stream].unlock();
 
1339
        _ffmpeg->reader->start();       // Refill the packet queue
 
1340
        avcodec_decode_video2(_ffmpeg->video_codec_ctxs[_video_stream],
 
1341
                _ffmpeg->video_frames[_video_stream], &frame_finished,
 
1342
                &(_ffmpeg->video_packets[_video_stream]));
 
1343
    }
 
1344
    while (!frame_finished);
 
1345
 
 
1346
    _frame = _ffmpeg->video_frame_templates[_video_stream];
 
1347
    if (_frame.layout == video_frame::bgra32)
 
1348
    {
 
1349
        sws_scale(_ffmpeg->video_img_conv_ctxs[_video_stream],
 
1350
                _ffmpeg->video_frames[_video_stream]->data,
 
1351
                _ffmpeg->video_frames[_video_stream]->linesize,
 
1352
                0, _frame.raw_height,
 
1353
                _ffmpeg->video_out_frames[_video_stream]->data,
 
1354
                _ffmpeg->video_out_frames[_video_stream]->linesize);
 
1355
        // TODO: Handle sws_scale errors. How?
 
1356
        _frame.data[0][0] = _ffmpeg->video_out_frames[_video_stream]->data[0];
 
1357
        _frame.line_size[0][0] = _ffmpeg->video_out_frames[_video_stream]->linesize[0];
 
1358
    }
 
1359
    else
 
1360
    {
 
1361
        _frame.data[0][0] = _ffmpeg->video_frames[_video_stream]->data[0];
 
1362
        _frame.data[0][1] = _ffmpeg->video_frames[_video_stream]->data[1];
 
1363
        _frame.data[0][2] = _ffmpeg->video_frames[_video_stream]->data[2];
 
1364
        _frame.line_size[0][0] = _ffmpeg->video_frames[_video_stream]->linesize[0];
 
1365
        _frame.line_size[0][1] = _ffmpeg->video_frames[_video_stream]->linesize[1];
 
1366
        _frame.line_size[0][2] = _ffmpeg->video_frames[_video_stream]->linesize[2];
 
1367
    }
 
1368
 
 
1369
    if (_ffmpeg->video_packets[_video_stream].dts != static_cast<int64_t>(AV_NOPTS_VALUE))
 
1370
    {
 
1371
        _frame.presentation_time = handle_timestamp(_ffmpeg->video_packets[_video_stream].dts * 1000000
 
1372
                * _ffmpeg->format_ctx->streams[_ffmpeg->video_streams[_video_stream]]->time_base.num
 
1373
                / _ffmpeg->format_ctx->streams[_ffmpeg->video_streams[_video_stream]]->time_base.den);
 
1374
    }
 
1375
    else if (_ffmpeg->video_last_timestamps[_video_stream] != std::numeric_limits<int64_t>::min())
 
1376
    {
 
1377
        msg::dbg(_url + ": video stream " + str::from(_video_stream)
 
1378
                + ": no timestamp available, using a questionable guess");
 
1379
        _frame.presentation_time = _ffmpeg->video_last_timestamps[_video_stream];
 
1380
    }
 
1381
    else
 
1382
    {
 
1383
        msg::dbg(_url + ": video stream " + str::from(_video_stream)
 
1384
                + ": no timestamp available, using a bad guess");
 
1385
        _frame.presentation_time = _ffmpeg->pos;
 
1386
    }
 
1387
}
 
1388
 
 
1389
void media_object::start_video_frame_read(int video_stream)
 
1390
{
 
1391
    assert(video_stream >= 0);
 
1392
    assert(video_stream < video_streams());
 
1393
    _ffmpeg->video_decode_threads[video_stream].start();
 
1394
}
 
1395
 
 
1396
video_frame media_object::finish_video_frame_read(int video_stream)
 
1397
{
 
1398
    assert(video_stream >= 0);
 
1399
    assert(video_stream < video_streams());
 
1400
    _ffmpeg->video_decode_threads[video_stream].finish();
 
1401
    return _ffmpeg->video_decode_threads[video_stream].frame();
 
1402
}
 
1403
 
 
1404
audio_decode_thread::audio_decode_thread(const std::string &url, struct ffmpeg_stuff *ffmpeg, int audio_stream) :
 
1405
    _url(url), _ffmpeg(ffmpeg), _audio_stream(audio_stream), _blob()
 
1406
{
 
1407
}
 
1408
 
 
1409
int64_t audio_decode_thread::handle_timestamp(int64_t timestamp)
 
1410
{
 
1411
    int64_t ts = timestamp_helper(_ffmpeg->audio_last_timestamps[_audio_stream], timestamp);
 
1412
    _ffmpeg->pos = ts;
 
1413
    return ts;
 
1414
}
 
1415
 
 
1416
void audio_decode_thread::run()
 
1417
{
 
1418
    size_t size = _ffmpeg->audio_blobs[_audio_stream].size();
 
1419
    void *buffer = _ffmpeg->audio_blobs[_audio_stream].ptr();
 
1420
    int64_t timestamp = std::numeric_limits<int64_t>::min();
 
1421
    size_t i = 0;
 
1422
    while (i < size)
 
1423
    {
 
1424
        if (_ffmpeg->audio_buffers[_audio_stream].size() > 0)
 
1425
        {
 
1426
            // Use available decoded audio data
 
1427
            size_t remaining = std::min(size - i, _ffmpeg->audio_buffers[_audio_stream].size());
 
1428
            memcpy(buffer, &(_ffmpeg->audio_buffers[_audio_stream][0]), remaining);
 
1429
            _ffmpeg->audio_buffers[_audio_stream].erase(
 
1430
                    _ffmpeg->audio_buffers[_audio_stream].begin(),
 
1431
                    _ffmpeg->audio_buffers[_audio_stream].begin() + remaining);
 
1432
            buffer = reinterpret_cast<unsigned char *>(buffer) + remaining;
 
1433
            i += remaining;
 
1434
        }
 
1435
        if (_ffmpeg->audio_buffers[_audio_stream].size() == 0)
 
1436
        {
 
1437
            // Read more audio data
 
1438
            AVPacket packet, tmppacket;
 
1439
            bool empty;
 
1440
            do
 
1441
            {
 
1442
                _ffmpeg->audio_packet_queue_mutexes[_audio_stream].lock();
 
1443
                empty = _ffmpeg->audio_packet_queues[_audio_stream].empty();
 
1444
                _ffmpeg->audio_packet_queue_mutexes[_audio_stream].unlock();
 
1445
                if (empty)
 
1446
                {
 
1447
                    if (_ffmpeg->reader->eof())
 
1448
                    {
 
1449
                        _blob = audio_blob();
 
1450
                        return;
 
1451
                    }
 
1452
                    msg::dbg(_url + ": audio stream " + str::from(_audio_stream) + ": need to wait for packets...");
 
1453
                    _ffmpeg->reader->start();
 
1454
                    _ffmpeg->reader->finish();
 
1455
                }
 
1456
            }
 
1457
            while (empty);
 
1458
            _ffmpeg->audio_packet_queue_mutexes[_audio_stream].lock();
 
1459
            packet = _ffmpeg->audio_packet_queues[_audio_stream].front();
 
1460
            _ffmpeg->audio_packet_queues[_audio_stream].pop_front();
 
1461
            _ffmpeg->audio_packet_queue_mutexes[_audio_stream].unlock();
 
1462
            _ffmpeg->reader->start();   // Refill the packet queue
 
1463
            if (timestamp == std::numeric_limits<int64_t>::min() && packet.dts != static_cast<int64_t>(AV_NOPTS_VALUE))
 
1464
            {
 
1465
                timestamp = packet.dts * 1000000
 
1466
                    * _ffmpeg->format_ctx->streams[_ffmpeg->audio_streams[_audio_stream]]->time_base.num
 
1467
                    / _ffmpeg->format_ctx->streams[_ffmpeg->audio_streams[_audio_stream]]->time_base.den;
 
1468
            }
 
1469
 
 
1470
            // Decode audio data
 
1471
            tmppacket = packet;
 
1472
            while (tmppacket.size > 0)
 
1473
            {
 
1474
                int tmpbuf_size = audio_tmpbuf_size;
 
1475
                int len = avcodec_decode_audio3(_ffmpeg->audio_codec_ctxs[_audio_stream],
 
1476
                        reinterpret_cast<int16_t *>(&(_ffmpeg->audio_tmpbufs[_audio_stream][0])), &tmpbuf_size, &tmppacket);
 
1477
                if (len < 0)
 
1478
                {
 
1479
                    tmppacket.size = 0;
 
1480
                    break;
 
1481
                }
 
1482
                tmppacket.data += len;
 
1483
                tmppacket.size -= len;
 
1484
                if (tmpbuf_size <= 0)
 
1485
                {
 
1486
                    continue;
 
1487
                }
 
1488
                // Put it in the decoded audio data buffer
 
1489
                if (_ffmpeg->audio_codec_ctxs[_audio_stream]->sample_fmt == AV_SAMPLE_FMT_S32)
 
1490
                {
 
1491
                    // we need to convert this to AV_SAMPLE_FMT_FLT
 
1492
                    assert(sizeof(int32_t) == sizeof(float));
 
1493
                    assert(tmpbuf_size % sizeof(int32_t) == 0);
 
1494
                    void *tmpbuf_v = static_cast<void *>(&(_ffmpeg->audio_tmpbufs[_audio_stream][0]));
 
1495
                    int32_t *tmpbuf_i32 = static_cast<int32_t *>(tmpbuf_v);
 
1496
                    float *tmpbuf_flt = static_cast<float *>(tmpbuf_v);
 
1497
                    const float posdiv = +static_cast<float>(std::numeric_limits<int32_t>::max());
 
1498
                    const float negdiv = -static_cast<float>(std::numeric_limits<int32_t>::min());
 
1499
                    for (size_t j = 0; j < tmpbuf_size / sizeof(int32_t); j++)
 
1500
                    {
 
1501
                        int32_t sample_i32 = tmpbuf_i32[j];
 
1502
                        float sample_flt = sample_i32 / (sample_i32 >= 0 ? posdiv : negdiv);
 
1503
                        tmpbuf_flt[j] = sample_flt;
 
1504
                    }
 
1505
                }
 
1506
                size_t old_size = _ffmpeg->audio_buffers[_audio_stream].size();
 
1507
                _ffmpeg->audio_buffers[_audio_stream].resize(old_size + tmpbuf_size);
 
1508
                memcpy(&(_ffmpeg->audio_buffers[_audio_stream][old_size]), _ffmpeg->audio_tmpbufs[_audio_stream], tmpbuf_size);
 
1509
            }
 
1510
 
 
1511
            av_free_packet(&packet);
 
1512
        }
 
1513
    }
 
1514
    if (timestamp == std::numeric_limits<int64_t>::min())
 
1515
    {
 
1516
        timestamp = _ffmpeg->audio_last_timestamps[_audio_stream];
 
1517
    }
 
1518
    if (timestamp == std::numeric_limits<int64_t>::min())
 
1519
    {
 
1520
        msg::dbg(_url + ": audio stream " + str::from(_audio_stream)
 
1521
                + ": no timestamp available, using a bad guess");
 
1522
        timestamp = _ffmpeg->pos;
 
1523
    }
 
1524
 
 
1525
    _blob = _ffmpeg->audio_blob_templates[_audio_stream];
 
1526
    _blob.data = _ffmpeg->audio_blobs[_audio_stream].ptr();
 
1527
    _blob.size = _ffmpeg->audio_blobs[_audio_stream].size();
 
1528
    _blob.presentation_time = handle_timestamp(timestamp);
 
1529
}
 
1530
 
 
1531
void media_object::start_audio_blob_read(int audio_stream, size_t size)
 
1532
{
 
1533
    assert(audio_stream >= 0);
 
1534
    assert(audio_stream < audio_streams());
 
1535
    _ffmpeg->audio_blobs[audio_stream].resize(size);
 
1536
    _ffmpeg->audio_decode_threads[audio_stream].start();
 
1537
}
 
1538
 
 
1539
audio_blob media_object::finish_audio_blob_read(int audio_stream)
 
1540
{
 
1541
    assert(audio_stream >= 0);
 
1542
    assert(audio_stream < audio_streams());
 
1543
    _ffmpeg->audio_decode_threads[audio_stream].finish();
 
1544
    return _ffmpeg->audio_decode_threads[audio_stream].blob();
 
1545
}
 
1546
 
 
1547
subtitle_decode_thread::subtitle_decode_thread(const std::string &url, struct ffmpeg_stuff *ffmpeg, int subtitle_stream) :
 
1548
    _url(url), _ffmpeg(ffmpeg), _subtitle_stream(subtitle_stream), _box()
 
1549
{
 
1550
}
 
1551
 
 
1552
int64_t subtitle_decode_thread::handle_timestamp(int64_t timestamp)
 
1553
{
 
1554
    int64_t ts = timestamp_helper(_ffmpeg->subtitle_last_timestamps[_subtitle_stream], timestamp);
 
1555
    _ffmpeg->pos = ts;
 
1556
    return ts;
 
1557
}
 
1558
 
 
1559
void subtitle_decode_thread::run()
 
1560
{
 
1561
    if (_ffmpeg->subtitle_box_buffers[_subtitle_stream].empty())
 
1562
    {
 
1563
        // Read more subtitle data
 
1564
        AVPacket packet, tmppacket;
 
1565
        bool empty;
 
1566
        do
 
1567
        {
 
1568
            _ffmpeg->subtitle_packet_queue_mutexes[_subtitle_stream].lock();
 
1569
            empty = _ffmpeg->subtitle_packet_queues[_subtitle_stream].empty();
 
1570
            _ffmpeg->subtitle_packet_queue_mutexes[_subtitle_stream].unlock();
 
1571
            if (empty)
 
1572
            {
 
1573
                if (_ffmpeg->reader->eof())
 
1574
                {
 
1575
                    _box = subtitle_box();
 
1576
                    return;
 
1577
                }
 
1578
                msg::dbg(_url + ": subtitle stream " + str::from(_subtitle_stream) + ": need to wait for packets...");
 
1579
                _ffmpeg->reader->start();
 
1580
                _ffmpeg->reader->finish();
 
1581
            }
 
1582
        }
 
1583
        while (empty);
 
1584
        _ffmpeg->subtitle_packet_queue_mutexes[_subtitle_stream].lock();
 
1585
        packet = _ffmpeg->subtitle_packet_queues[_subtitle_stream].front();
 
1586
        _ffmpeg->subtitle_packet_queues[_subtitle_stream].pop_front();
 
1587
        _ffmpeg->subtitle_packet_queue_mutexes[_subtitle_stream].unlock();
 
1588
        _ffmpeg->reader->start();   // Refill the packet queue
 
1589
 
 
1590
        // Decode subtitle data
 
1591
        int64_t timestamp = packet.pts * 1000000
 
1592
            * _ffmpeg->format_ctx->streams[_ffmpeg->subtitle_streams[_subtitle_stream]]->time_base.num
 
1593
            / _ffmpeg->format_ctx->streams[_ffmpeg->subtitle_streams[_subtitle_stream]]->time_base.den;
 
1594
        AVSubtitle subtitle;
 
1595
        int got_subtitle;
 
1596
        tmppacket = packet;
 
1597
 
 
1598
        // CODEC_ID_TEXT does not have any decoder; it is just UTF-8 text in the packet data.
 
1599
        if (_ffmpeg->subtitle_codec_ctxs[_subtitle_stream]->codec_id == CODEC_ID_TEXT)
 
1600
        {
 
1601
            int64_t duration = packet.convergence_duration * 1000000
 
1602
                * _ffmpeg->format_ctx->streams[_ffmpeg->subtitle_streams[_subtitle_stream]]->time_base.num
 
1603
                / _ffmpeg->format_ctx->streams[_ffmpeg->subtitle_streams[_subtitle_stream]]->time_base.den;
 
1604
 
 
1605
            // Put it in the subtitle buffer
 
1606
            subtitle_box box = _ffmpeg->subtitle_box_templates[_subtitle_stream];
 
1607
            box.presentation_start_time = timestamp;
 
1608
            box.presentation_stop_time = timestamp + duration;
 
1609
 
 
1610
            box.format = subtitle_box::text;
 
1611
            box.str = reinterpret_cast<const char *>(packet.data);
 
1612
 
 
1613
            _ffmpeg->subtitle_box_buffers[_subtitle_stream].push_back(box);
 
1614
 
 
1615
            tmppacket.size = 0;
 
1616
        }
 
1617
 
 
1618
        while (tmppacket.size > 0)
 
1619
        {
 
1620
            int len = avcodec_decode_subtitle2(_ffmpeg->subtitle_codec_ctxs[_subtitle_stream],
 
1621
                    &subtitle, &got_subtitle, &tmppacket);
 
1622
            if (len < 0)
 
1623
            {
 
1624
                tmppacket.size = 0;
 
1625
                break;
 
1626
            }
 
1627
            tmppacket.data += len;
 
1628
            tmppacket.size -= len;
 
1629
            if (!got_subtitle)
 
1630
            {
 
1631
                continue;
 
1632
            }
 
1633
            // Put it in the subtitle buffer
 
1634
            subtitle_box box = _ffmpeg->subtitle_box_templates[_subtitle_stream];
 
1635
            box.presentation_start_time = timestamp + subtitle.start_display_time * 1000;
 
1636
            box.presentation_stop_time = box.presentation_start_time + subtitle.end_display_time * 1000;
 
1637
            for (unsigned int i = 0; i < subtitle.num_rects; i++)
 
1638
            {
 
1639
                AVSubtitleRect *rect = subtitle.rects[i];
 
1640
                switch (rect->type)
 
1641
                {
 
1642
                case SUBTITLE_BITMAP:
 
1643
                    box.format = subtitle_box::image;
 
1644
                    box.images.push_back(subtitle_box::image_t());
 
1645
                    box.images.back().w = rect->w;
 
1646
                    box.images.back().h = rect->h;
 
1647
                    box.images.back().x = rect->x;
 
1648
                    box.images.back().y = rect->y;
 
1649
                    box.images.back().palette.resize(4 * rect->nb_colors);
 
1650
                    std::memcpy(&(box.images.back().palette[0]), rect->pict.data[1],
 
1651
                            box.images.back().palette.size());
 
1652
                    box.images.back().linesize = rect->pict.linesize[0];
 
1653
                    box.images.back().data.resize(box.images.back().h * box.images.back().linesize);
 
1654
                    std::memcpy(&(box.images.back().data[0]), rect->pict.data[0],
 
1655
                            box.images.back().data.size() * sizeof(uint8_t));
 
1656
                    break;
 
1657
                case SUBTITLE_TEXT:
 
1658
                    box.format = subtitle_box::text;
 
1659
                    if (!box.str.empty())
 
1660
                    {
 
1661
                        box.str += '\n';
 
1662
                    }
 
1663
                    box.str += rect->text;
 
1664
                    break;
 
1665
                case SUBTITLE_ASS:
 
1666
                    box.format = subtitle_box::ass;
 
1667
                    box.style = std::string(reinterpret_cast<const char *>(
 
1668
                                _ffmpeg->subtitle_codec_ctxs[_subtitle_stream]->subtitle_header),
 
1669
                            _ffmpeg->subtitle_codec_ctxs[_subtitle_stream]->subtitle_header_size);
 
1670
                    if (!box.str.empty())
 
1671
                    {
 
1672
                        box.str += '\n';
 
1673
                    }
 
1674
                    box.str += rect->ass;
 
1675
                    break;
 
1676
                case SUBTITLE_NONE:
 
1677
                    // Should never happen, but make sure we have a valid subtitle box anyway.
 
1678
                    box.format = subtitle_box::text;
 
1679
                    box.str = ' ';
 
1680
                    break;
 
1681
                }
 
1682
            }
 
1683
            _ffmpeg->subtitle_box_buffers[_subtitle_stream].push_back(box);
 
1684
            avsubtitle_free(&subtitle);
 
1685
        }
 
1686
 
 
1687
        av_free_packet(&packet);
 
1688
    }
 
1689
    if (_ffmpeg->subtitle_box_buffers[_subtitle_stream].empty())
 
1690
    {
 
1691
        _box = subtitle_box();
 
1692
        return;
 
1693
    }
 
1694
    _box = _ffmpeg->subtitle_box_buffers[_subtitle_stream].front();
 
1695
    _ffmpeg->subtitle_box_buffers[_subtitle_stream].pop_front();
 
1696
}
 
1697
 
 
1698
void media_object::start_subtitle_box_read(int subtitle_stream)
 
1699
{
 
1700
    assert(subtitle_stream >= 0);
 
1701
    assert(subtitle_stream < subtitle_streams());
 
1702
    _ffmpeg->subtitle_decode_threads[subtitle_stream].start();
 
1703
}
 
1704
 
 
1705
subtitle_box media_object::finish_subtitle_box_read(int subtitle_stream)
 
1706
{
 
1707
    assert(subtitle_stream >= 0);
 
1708
    assert(subtitle_stream < subtitle_streams());
 
1709
    _ffmpeg->subtitle_decode_threads[subtitle_stream].finish();
 
1710
    return _ffmpeg->subtitle_decode_threads[subtitle_stream].box();
 
1711
}
 
1712
 
 
1713
int64_t media_object::tell()
 
1714
{
 
1715
    return _ffmpeg->pos;
 
1716
}
 
1717
 
 
1718
void media_object::seek(int64_t dest_pos)
 
1719
{
 
1720
    msg::dbg(_url + ": Seeking from " + str::from(_ffmpeg->pos / 1e6f) + " to " + str::from(dest_pos / 1e6f) + ".");
 
1721
 
 
1722
    // Stop decoder threads
 
1723
    for (size_t i = 0; i < _ffmpeg->video_streams.size(); i++)
 
1724
    {
 
1725
        _ffmpeg->video_decode_threads[i].finish();
 
1726
    }
 
1727
    for (size_t i = 0; i < _ffmpeg->audio_streams.size(); i++)
 
1728
    {
 
1729
        _ffmpeg->audio_decode_threads[i].finish();
 
1730
    }
 
1731
    for (size_t i = 0; i < _ffmpeg->subtitle_streams.size(); i++)
 
1732
    {
 
1733
        _ffmpeg->subtitle_decode_threads[i].finish();
 
1734
    }
 
1735
    // Stop reading packets
 
1736
    _ffmpeg->reader->finish();
 
1737
    // Seek
 
1738
    int e = av_seek_frame(_ffmpeg->format_ctx, -1,
 
1739
            dest_pos * AV_TIME_BASE / 1000000,
 
1740
            dest_pos < _ffmpeg->pos ?  AVSEEK_FLAG_BACKWARD : 0);
 
1741
    if (e < 0)
 
1742
    {
 
1743
        msg::err(_("%s: Seeking failed."), _url.c_str());
 
1744
    }
 
1745
    // Throw away all queued packets
 
1746
    for (size_t i = 0; i < _ffmpeg->video_streams.size(); i++)
 
1747
    {
 
1748
        avcodec_flush_buffers(_ffmpeg->format_ctx->streams[_ffmpeg->video_streams[i]]->codec);
 
1749
        for (size_t j = 0; j < _ffmpeg->video_packet_queues[i].size(); j++)
 
1750
        {
 
1751
            av_free_packet(&_ffmpeg->video_packet_queues[i][j]);
 
1752
        }
 
1753
        _ffmpeg->video_packet_queues[i].clear();
 
1754
    }
 
1755
    for (size_t i = 0; i < _ffmpeg->audio_streams.size(); i++)
 
1756
    {
 
1757
        avcodec_flush_buffers(_ffmpeg->format_ctx->streams[_ffmpeg->audio_streams[i]]->codec);
 
1758
        _ffmpeg->audio_buffers[i].clear();
 
1759
        for (size_t j = 0; j < _ffmpeg->audio_packet_queues[i].size(); j++)
 
1760
        {
 
1761
            av_free_packet(&_ffmpeg->audio_packet_queues[i][j]);
 
1762
        }
 
1763
        _ffmpeg->audio_packet_queues[i].clear();
 
1764
    }
 
1765
    for (size_t i = 0; i < _ffmpeg->subtitle_streams.size(); i++)
 
1766
    {
 
1767
        if (_ffmpeg->format_ctx->streams[_ffmpeg->subtitle_streams[i]]->codec->codec_id != CODEC_ID_TEXT)
 
1768
        {
 
1769
            // CODEC_ID_TEXT has no decoder, so we cannot flush its buffers
 
1770
            avcodec_flush_buffers(_ffmpeg->format_ctx->streams[_ffmpeg->subtitle_streams[i]]->codec);
 
1771
        }
 
1772
        _ffmpeg->subtitle_box_buffers[i].clear();
 
1773
        for (size_t j = 0; j < _ffmpeg->subtitle_packet_queues[i].size(); j++)
 
1774
        {
 
1775
            av_free_packet(&_ffmpeg->subtitle_packet_queues[i][j]);
 
1776
        }
 
1777
        _ffmpeg->subtitle_packet_queues[i].clear();
 
1778
    }
 
1779
    // The next read request must update the position
 
1780
    for (size_t i = 0; i < _ffmpeg->video_streams.size(); i++)
 
1781
    {
 
1782
        _ffmpeg->video_last_timestamps[i] = std::numeric_limits<int64_t>::min();
 
1783
    }
 
1784
    for (size_t i = 0; i < _ffmpeg->audio_streams.size(); i++)
 
1785
    {
 
1786
        _ffmpeg->audio_last_timestamps[i] = std::numeric_limits<int64_t>::min();
 
1787
    }
 
1788
    for (size_t i = 0; i < _ffmpeg->subtitle_streams.size(); i++)
 
1789
    {
 
1790
        _ffmpeg->subtitle_last_timestamps[i] = std::numeric_limits<int64_t>::min();
 
1791
    }
 
1792
    _ffmpeg->pos = std::numeric_limits<int64_t>::min();
 
1793
    // Restart packet reading
 
1794
    _ffmpeg->reader->reset();
 
1795
    _ffmpeg->reader->start();
 
1796
}
 
1797
 
 
1798
void media_object::close()
 
1799
{
 
1800
    if (_ffmpeg)
 
1801
    {
 
1802
        try
 
1803
        {
 
1804
            // Stop decoder threads
 
1805
            for (size_t i = 0; i < _ffmpeg->video_decode_threads.size(); i++)
 
1806
            {
 
1807
                _ffmpeg->video_decode_threads[i].finish();
 
1808
            }
 
1809
            for (size_t i = 0; i < _ffmpeg->audio_decode_threads.size(); i++)
 
1810
            {
 
1811
                _ffmpeg->audio_decode_threads[i].finish();
 
1812
            }
 
1813
            for (size_t i = 0; i < _ffmpeg->subtitle_decode_threads.size(); i++)
 
1814
            {
 
1815
                _ffmpeg->subtitle_decode_threads[i].finish();
 
1816
            }
 
1817
            // Stop reading packets
 
1818
            _ffmpeg->reader->finish();
 
1819
        }
 
1820
        catch (...)
 
1821
        {
 
1822
        }
 
1823
        if (_ffmpeg->format_ctx)
 
1824
        {
 
1825
            for (size_t i = 0; i < _ffmpeg->video_frames.size(); i++)
 
1826
            {
 
1827
                av_free(_ffmpeg->video_frames[i]);
 
1828
            }
 
1829
            for (size_t i = 0; i < _ffmpeg->video_out_frames.size(); i++)
 
1830
            {
 
1831
                av_free(_ffmpeg->video_out_frames[i]);
 
1832
            }
 
1833
            for (size_t i = 0; i < _ffmpeg->video_buffers.size(); i++)
 
1834
            {
 
1835
                av_free(_ffmpeg->video_buffers[i]);
 
1836
            }
 
1837
            for (size_t i = 0; i < _ffmpeg->video_codec_ctxs.size(); i++)
 
1838
            {
 
1839
                if (i < _ffmpeg->video_codecs.size() && _ffmpeg->video_codecs[i])
 
1840
                {
 
1841
                    avcodec_close(_ffmpeg->video_codec_ctxs[i]);
 
1842
                }
 
1843
            }
 
1844
            for (size_t i = 0; i < _ffmpeg->video_img_conv_ctxs.size(); i++)
 
1845
            {
 
1846
                sws_freeContext(_ffmpeg->video_img_conv_ctxs[i]);
 
1847
            }
 
1848
            for (size_t i = 0; i < _ffmpeg->video_packet_queues.size(); i++)
 
1849
            {
 
1850
                if (_ffmpeg->video_packet_queues[i].size() > 0)
 
1851
                {
 
1852
                    msg::dbg(_url + ": " + str::from(_ffmpeg->video_packet_queues[i].size())
 
1853
                            + " unprocessed packets in video stream " + str::from(i));
 
1854
                }
 
1855
                for (size_t j = 0; j < _ffmpeg->video_packet_queues[i].size(); j++)
 
1856
                {
 
1857
                    av_free_packet(&_ffmpeg->video_packet_queues[i][j]);
 
1858
                }
 
1859
            }
 
1860
            for (size_t i = 0; i < _ffmpeg->video_packets.size(); i++)
 
1861
            {
 
1862
                av_free_packet(&(_ffmpeg->video_packets[i]));
 
1863
            }
 
1864
            for (size_t i = 0; i < _ffmpeg->audio_codec_ctxs.size(); i++)
 
1865
            {
 
1866
                if (i < _ffmpeg->audio_codecs.size() && _ffmpeg->audio_codecs[i])
 
1867
                {
 
1868
                    avcodec_close(_ffmpeg->audio_codec_ctxs[i]);
 
1869
                }
 
1870
            }
 
1871
            for (size_t i = 0; i < _ffmpeg->audio_packet_queues.size(); i++)
 
1872
            {
 
1873
                if (_ffmpeg->audio_packet_queues[i].size() > 0)
 
1874
                {
 
1875
                    msg::dbg(_url + ": " + str::from(_ffmpeg->audio_packet_queues[i].size())
 
1876
                            + " unprocessed packets in audio stream " + str::from(i));
 
1877
                }
 
1878
                for (size_t j = 0; j < _ffmpeg->audio_packet_queues[i].size(); j++)
 
1879
                {
 
1880
                    av_free_packet(&_ffmpeg->audio_packet_queues[i][j]);
 
1881
                }
 
1882
            }
 
1883
            for (size_t i = 0; i < _ffmpeg->audio_tmpbufs.size(); i++)
 
1884
            {
 
1885
                av_free(_ffmpeg->audio_tmpbufs[i]);
 
1886
            }
 
1887
            for (size_t i = 0; i < _ffmpeg->subtitle_codec_ctxs.size(); i++)
 
1888
            {
 
1889
                if (i < _ffmpeg->subtitle_codecs.size() && _ffmpeg->subtitle_codecs[i])
 
1890
                {
 
1891
                    avcodec_close(_ffmpeg->subtitle_codec_ctxs[i]);
 
1892
                }
 
1893
            }
 
1894
            for (size_t i = 0; i < _ffmpeg->subtitle_packet_queues.size(); i++)
 
1895
            {
 
1896
                if (_ffmpeg->subtitle_packet_queues[i].size() > 0)
 
1897
                {
 
1898
                    msg::dbg(_url + ": " + str::from(_ffmpeg->subtitle_packet_queues[i].size())
 
1899
                            + " unprocessed packets in subtitle stream " + str::from(i));
 
1900
                }
 
1901
                for (size_t j = 0; j < _ffmpeg->subtitle_packet_queues[i].size(); j++)
 
1902
                {
 
1903
                    av_free_packet(&_ffmpeg->subtitle_packet_queues[i][j]);
 
1904
                }
 
1905
            }
 
1906
            av_close_input_file(_ffmpeg->format_ctx);
 
1907
        }
 
1908
        delete _ffmpeg->reader;
 
1909
        delete _ffmpeg;
 
1910
        _ffmpeg = NULL;
 
1911
    }
 
1912
    _url = "";
 
1913
    _is_device = false;
 
1914
    _tag_names.clear();
 
1915
    _tag_values.clear();
 
1916
}