Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/modules/videoio/src/cap_ffmpeg_impl.hpp
16339 views
1
/*M///////////////////////////////////////////////////////////////////////////////////////
2
//
3
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4
//
5
// By downloading, copying, installing or using the software you agree to this license.
6
// If you do not agree to this license, do not download, install,
7
// copy or use the software.
8
//
9
//
10
// License Agreement
11
// For Open Source Computer Vision Library
12
//
13
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15
// Third party copyrights are property of their respective owners.
16
//
17
// Redistribution and use in source and binary forms, with or without modification,
18
// are permitted provided that the following conditions are met:
19
//
20
// * Redistribution's of source code must retain the above copyright notice,
21
// this list of conditions and the following disclaimer.
22
//
23
// * Redistribution's in binary form must reproduce the above copyright notice,
24
// this list of conditions and the following disclaimer in the documentation
25
// and/or other materials provided with the distribution.
26
//
27
// * The name of the copyright holders may not be used to endorse or promote products
28
// derived from this software without specific prior written permission.
29
//
30
// This software is provided by the copyright holders and contributors "as is" and
31
// any express or implied warranties, including, but not limited to, the implied
32
// warranties of merchantability and fitness for a particular purpose are disclaimed.
33
// In no event shall the Intel Corporation or contributors be liable for any direct,
34
// indirect, incidental, special, exemplary, or consequential damages
35
// (including, but not limited to, procurement of substitute goods or services;
36
// loss of use, data, or profits; or business interruption) however caused
37
// and on any theory of liability, whether in contract, strict liability,
38
// or tort (including negligence or otherwise) arising in any way out of
39
// the use of this software, even if advised of the possibility of such damage.
40
//
41
//M*/
42
43
#include "cap_ffmpeg_api.hpp"
44
#if !(defined(_WIN32) || defined(WINCE))
45
# include <pthread.h>
46
#endif
47
#include <assert.h>
48
#include <algorithm>
49
#include <limits>
50
51
#define OPENCV_FOURCC(c1, c2, c3, c4) (((c1) & 255) + (((c2) & 255) << 8) + (((c3) & 255) << 16) + (((c4) & 255) << 24))
52
#define CALC_FFMPEG_VERSION(a,b,c) ( a<<16 | b<<8 | c )
53
54
#if defined _MSC_VER && _MSC_VER >= 1200
55
#pragma warning( disable: 4244 4510 4610 )
56
#endif
57
58
#ifdef __GNUC__
59
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
60
#endif
61
62
#ifndef CV_UNUSED // Required for standalone compilation mode (OpenCV defines this in base.hpp)
63
#define CV_UNUSED(name) (void)name
64
#endif
65
66
#ifdef __cplusplus
67
extern "C" {
68
#endif
69
70
#include "ffmpeg_codecs.hpp"
71
72
#include <libavutil/mathematics.h>
73
74
#if LIBAVUTIL_BUILD > CALC_FFMPEG_VERSION(51,11,0)
75
#include <libavutil/opt.h>
76
#endif
77
78
#if LIBAVUTIL_BUILD >= (LIBAVUTIL_VERSION_MICRO >= 100 \
79
? CALC_FFMPEG_VERSION(51, 63, 100) : CALC_FFMPEG_VERSION(54, 6, 0))
80
#include <libavutil/imgutils.h>
81
#endif
82
83
#include <libavcodec/avcodec.h>
84
#include <libswscale/swscale.h>
85
86
#ifdef __cplusplus
87
}
88
#endif
89
90
#if defined _MSC_VER && _MSC_VER >= 1200
91
#pragma warning( default: 4244 4510 4610 )
92
#endif
93
94
#ifdef NDEBUG
95
#define CV_WARN(message)
96
#else
97
#define CV_WARN(message) fprintf(stderr, "warning: %s (%s:%d)\n", message, __FILE__, __LINE__)
98
#endif
99
100
#if defined _WIN32
101
#include <windows.h>
102
#if defined _MSC_VER && _MSC_VER < 1900
103
struct timespec
104
{
105
time_t tv_sec;
106
long tv_nsec;
107
};
108
#endif
109
#elif defined __linux__ || defined __APPLE__ || defined __HAIKU__
110
#include <unistd.h>
111
#include <stdio.h>
112
#include <sys/types.h>
113
#include <sys/time.h>
114
#if defined __APPLE__
115
#include <sys/sysctl.h>
116
#include <mach/clock.h>
117
#include <mach/mach.h>
118
#endif
119
#endif
120
121
#ifndef MIN
122
#define MIN(a, b) ((a) < (b) ? (a) : (b))
123
#endif
124
125
#if defined(__APPLE__)
126
#define AV_NOPTS_VALUE_ ((int64_t)0x8000000000000000LL)
127
#else
128
#define AV_NOPTS_VALUE_ ((int64_t)AV_NOPTS_VALUE)
129
#endif
130
131
#ifndef AVERROR_EOF
132
#define AVERROR_EOF (-MKTAG( 'E','O','F',' '))
133
#endif
134
135
#if LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(54,25,0)
136
# define CV_CODEC_ID AVCodecID
137
# define CV_CODEC(name) AV_##name
138
#else
139
# define CV_CODEC_ID CodecID
140
# define CV_CODEC(name) name
141
#endif
142
143
#if LIBAVUTIL_BUILD < (LIBAVUTIL_VERSION_MICRO >= 100 \
144
? CALC_FFMPEG_VERSION(51, 74, 100) : CALC_FFMPEG_VERSION(51, 42, 0))
145
#define AVPixelFormat PixelFormat
146
#define AV_PIX_FMT_BGR24 PIX_FMT_BGR24
147
#define AV_PIX_FMT_RGB24 PIX_FMT_RGB24
148
#define AV_PIX_FMT_GRAY8 PIX_FMT_GRAY8
149
#define AV_PIX_FMT_YUV422P PIX_FMT_YUV422P
150
#define AV_PIX_FMT_YUV420P PIX_FMT_YUV420P
151
#define AV_PIX_FMT_YUV444P PIX_FMT_YUV444P
152
#define AV_PIX_FMT_YUVJ420P PIX_FMT_YUVJ420P
153
#define AV_PIX_FMT_GRAY16LE PIX_FMT_GRAY16LE
154
#define AV_PIX_FMT_GRAY16BE PIX_FMT_GRAY16BE
155
#endif
156
157
#ifndef PKT_FLAG_KEY
158
#define PKT_FLAG_KEY AV_PKT_FLAG_KEY
159
#endif
160
161
#if LIBAVUTIL_BUILD >= (LIBAVUTIL_VERSION_MICRO >= 100 \
162
? CALC_FFMPEG_VERSION(52, 38, 100) : CALC_FFMPEG_VERSION(52, 13, 0))
163
#define USE_AV_FRAME_GET_BUFFER 1
164
#else
165
#define USE_AV_FRAME_GET_BUFFER 0
166
#ifndef AV_NUM_DATA_POINTERS // required for 0.7.x/0.8.x ffmpeg releases
167
#define AV_NUM_DATA_POINTERS 4
168
#endif
169
#endif
170
171
172
#ifndef USE_AV_INTERRUPT_CALLBACK
173
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 21, 0)
174
#define USE_AV_INTERRUPT_CALLBACK 1
175
#else
176
#define USE_AV_INTERRUPT_CALLBACK 0
177
#endif
178
#endif
179
180
#if USE_AV_INTERRUPT_CALLBACK
181
#define LIBAVFORMAT_INTERRUPT_OPEN_TIMEOUT_MS 30000
182
#define LIBAVFORMAT_INTERRUPT_READ_TIMEOUT_MS 30000
183
184
#ifdef _WIN32
185
// http://stackoverflow.com/questions/5404277/porting-clock-gettime-to-windows
186
187
static
188
inline LARGE_INTEGER get_filetime_offset()
189
{
190
SYSTEMTIME s;
191
FILETIME f;
192
LARGE_INTEGER t;
193
194
s.wYear = 1970;
195
s.wMonth = 1;
196
s.wDay = 1;
197
s.wHour = 0;
198
s.wMinute = 0;
199
s.wSecond = 0;
200
s.wMilliseconds = 0;
201
SystemTimeToFileTime(&s, &f);
202
t.QuadPart = f.dwHighDateTime;
203
t.QuadPart <<= 32;
204
t.QuadPart |= f.dwLowDateTime;
205
return t;
206
}
207
208
static
209
inline void get_monotonic_time(timespec *tv)
210
{
211
LARGE_INTEGER t;
212
FILETIME f;
213
double microseconds;
214
static LARGE_INTEGER offset;
215
static double frequencyToMicroseconds;
216
static int initialized = 0;
217
static BOOL usePerformanceCounter = 0;
218
219
if (!initialized)
220
{
221
LARGE_INTEGER performanceFrequency;
222
initialized = 1;
223
usePerformanceCounter = QueryPerformanceFrequency(&performanceFrequency);
224
if (usePerformanceCounter)
225
{
226
QueryPerformanceCounter(&offset);
227
frequencyToMicroseconds = (double)performanceFrequency.QuadPart / 1000000.;
228
}
229
else
230
{
231
offset = get_filetime_offset();
232
frequencyToMicroseconds = 10.;
233
}
234
}
235
236
if (usePerformanceCounter)
237
{
238
QueryPerformanceCounter(&t);
239
} else {
240
GetSystemTimeAsFileTime(&f);
241
t.QuadPart = f.dwHighDateTime;
242
t.QuadPart <<= 32;
243
t.QuadPart |= f.dwLowDateTime;
244
}
245
246
t.QuadPart -= offset.QuadPart;
247
microseconds = (double)t.QuadPart / frequencyToMicroseconds;
248
t.QuadPart = microseconds;
249
tv->tv_sec = t.QuadPart / 1000000;
250
tv->tv_nsec = (t.QuadPart % 1000000) * 1000;
251
}
252
#else
253
static
254
inline void get_monotonic_time(timespec *time)
255
{
256
#if defined(__APPLE__) && defined(__MACH__)
257
clock_serv_t cclock;
258
mach_timespec_t mts;
259
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
260
clock_get_time(cclock, &mts);
261
mach_port_deallocate(mach_task_self(), cclock);
262
time->tv_sec = mts.tv_sec;
263
time->tv_nsec = mts.tv_nsec;
264
#else
265
clock_gettime(CLOCK_MONOTONIC, time);
266
#endif
267
}
268
#endif
269
270
static
271
inline timespec get_monotonic_time_diff(timespec start, timespec end)
272
{
273
timespec temp;
274
if (end.tv_nsec - start.tv_nsec < 0)
275
{
276
temp.tv_sec = end.tv_sec - start.tv_sec - 1;
277
temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
278
}
279
else
280
{
281
temp.tv_sec = end.tv_sec - start.tv_sec;
282
temp.tv_nsec = end.tv_nsec - start.tv_nsec;
283
}
284
return temp;
285
}
286
287
static
288
inline double get_monotonic_time_diff_ms(timespec time1, timespec time2)
289
{
290
timespec delta = get_monotonic_time_diff(time1, time2);
291
double milliseconds = delta.tv_sec * 1000 + (double)delta.tv_nsec / 1000000.0;
292
293
return milliseconds;
294
}
295
#endif // USE_AV_INTERRUPT_CALLBACK
296
297
static int get_number_of_cpus(void)
298
{
299
#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(52, 111, 0)
300
return 1;
301
#elif defined _WIN32
302
SYSTEM_INFO sysinfo;
303
GetSystemInfo( &sysinfo );
304
305
return (int)sysinfo.dwNumberOfProcessors;
306
#elif defined __linux__ || defined __HAIKU__
307
return (int)sysconf( _SC_NPROCESSORS_ONLN );
308
#elif defined __APPLE__
309
int numCPU=0;
310
int mib[4];
311
size_t len = sizeof(numCPU);
312
313
// set the mib for hw.ncpu
314
mib[0] = CTL_HW;
315
mib[1] = HW_AVAILCPU; // alternatively, try HW_NCPU;
316
317
// get the number of CPUs from the system
318
sysctl(mib, 2, &numCPU, &len, NULL, 0);
319
320
if( numCPU < 1 )
321
{
322
mib[1] = HW_NCPU;
323
sysctl( mib, 2, &numCPU, &len, NULL, 0 );
324
325
if( numCPU < 1 )
326
numCPU = 1;
327
}
328
329
return (int)numCPU;
330
#else
331
return 1;
332
#endif
333
}
334
335
336
struct Image_FFMPEG
337
{
338
unsigned char* data;
339
int step;
340
int width;
341
int height;
342
int cn;
343
};
344
345
346
#if USE_AV_INTERRUPT_CALLBACK
347
struct AVInterruptCallbackMetadata
348
{
349
timespec value;
350
unsigned int timeout_after_ms;
351
int timeout;
352
};
353
354
// https://github.com/opencv/opencv/pull/12693#issuecomment-426236731
355
static
356
inline const char* _opencv_avcodec_get_name(AVCodecID id)
357
{
358
#if LIBAVCODEC_VERSION_MICRO >= 100 \
359
&& LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(53, 47, 100)
360
return avcodec_get_name(id);
361
#else
362
const AVCodecDescriptor *cd;
363
AVCodec *codec;
364
365
if (id == AV_CODEC_ID_NONE)
366
{
367
return "none";
368
}
369
cd = avcodec_descriptor_get(id);
370
if (cd)
371
{
372
return cd->name;
373
}
374
codec = avcodec_find_decoder(id);
375
if (codec)
376
{
377
return codec->name;
378
}
379
codec = avcodec_find_encoder(id);
380
if (codec)
381
{
382
return codec->name;
383
}
384
385
return "unknown_codec";
386
#endif
387
}
388
389
static
390
inline void _opencv_ffmpeg_free(void** ptr)
391
{
392
if(*ptr) free(*ptr);
393
*ptr = 0;
394
}
395
396
static
397
inline int _opencv_ffmpeg_interrupt_callback(void *ptr)
398
{
399
AVInterruptCallbackMetadata* metadata = (AVInterruptCallbackMetadata*)ptr;
400
assert(metadata);
401
402
if (metadata->timeout_after_ms == 0)
403
{
404
return 0; // timeout is disabled
405
}
406
407
timespec now;
408
get_monotonic_time(&now);
409
410
metadata->timeout = get_monotonic_time_diff_ms(metadata->value, now) > metadata->timeout_after_ms;
411
412
return metadata->timeout ? -1 : 0;
413
}
414
#endif
415
416
static
417
inline void _opencv_ffmpeg_av_packet_unref(AVPacket *pkt)
418
{
419
#if LIBAVCODEC_BUILD >= (LIBAVCODEC_VERSION_MICRO >= 100 \
420
? CALC_FFMPEG_VERSION(55, 25, 100) : CALC_FFMPEG_VERSION(55, 16, 0))
421
av_packet_unref(pkt);
422
#else
423
av_free_packet(pkt);
424
#endif
425
};
426
427
static
428
inline void _opencv_ffmpeg_av_image_fill_arrays(void *frame, uint8_t *ptr, enum AVPixelFormat pix_fmt, int width, int height)
429
{
430
#if LIBAVUTIL_BUILD >= (LIBAVUTIL_VERSION_MICRO >= 100 \
431
? CALC_FFMPEG_VERSION(51, 63, 100) : CALC_FFMPEG_VERSION(54, 6, 0))
432
av_image_fill_arrays(((AVFrame*)frame)->data, ((AVFrame*)frame)->linesize, ptr, pix_fmt, width, height, 1);
433
#else
434
avpicture_fill((AVPicture*)frame, ptr, pix_fmt, width, height);
435
#endif
436
};
437
438
static
439
inline int _opencv_ffmpeg_av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height)
440
{
441
#if LIBAVUTIL_BUILD >= (LIBAVUTIL_VERSION_MICRO >= 100 \
442
? CALC_FFMPEG_VERSION(51, 63, 100) : CALC_FFMPEG_VERSION(54, 6, 0))
443
return av_image_get_buffer_size(pix_fmt, width, height, 1);
444
#else
445
return avpicture_get_size(pix_fmt, width, height);
446
#endif
447
};
448
449
static AVRational _opencv_ffmpeg_get_sample_aspect_ratio(AVStream *stream)
450
{
451
#if LIBAVUTIL_VERSION_MICRO >= 100 && LIBAVUTIL_BUILD >= CALC_FFMPEG_VERSION(54, 5, 100)
452
return av_guess_sample_aspect_ratio(NULL, stream, NULL);
453
#else
454
AVRational undef = {0, 1};
455
456
// stream
457
AVRational ratio = stream ? stream->sample_aspect_ratio : undef;
458
av_reduce(&ratio.num, &ratio.den, ratio.num, ratio.den, INT_MAX);
459
if (ratio.num > 0 && ratio.den > 0)
460
return ratio;
461
462
// codec
463
ratio = stream && stream->codec ? stream->codec->sample_aspect_ratio : undef;
464
av_reduce(&ratio.num, &ratio.den, ratio.num, ratio.den, INT_MAX);
465
if (ratio.num > 0 && ratio.den > 0)
466
return ratio;
467
468
return undef;
469
#endif
470
}
471
472
473
struct CvCapture_FFMPEG
474
{
475
bool open( const char* filename );
476
void close();
477
478
double getProperty(int) const;
479
bool setProperty(int, double);
480
bool grabFrame();
481
bool retrieveFrame(int, unsigned char** data, int* step, int* width, int* height, int* cn);
482
483
void init();
484
485
void seek(int64_t frame_number);
486
void seek(double sec);
487
bool slowSeek( int framenumber );
488
489
int64_t get_total_frames() const;
490
double get_duration_sec() const;
491
double get_fps() const;
492
int get_bitrate() const;
493
494
double r2d(AVRational r) const;
495
int64_t dts_to_frame_number(int64_t dts);
496
double dts_to_sec(int64_t dts);
497
498
AVFormatContext * ic;
499
AVCodec * avcodec;
500
int video_stream;
501
AVStream * video_st;
502
AVFrame * picture;
503
AVFrame rgb_picture;
504
int64_t picture_pts;
505
506
AVPacket packet;
507
Image_FFMPEG frame;
508
struct SwsContext *img_convert_ctx;
509
510
int64_t frame_number, first_frame_number;
511
512
double eps_zero;
513
/*
514
'filename' contains the filename of the videosource,
515
'filename==NULL' indicates that ffmpeg's seek support works
516
for the particular file.
517
'filename!=NULL' indicates that the slow fallback function is used for seeking,
518
and so the filename is needed to reopen the file on backward seeking.
519
*/
520
char * filename;
521
522
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
523
AVDictionary *dict;
524
#endif
525
#if USE_AV_INTERRUPT_CALLBACK
526
AVInterruptCallbackMetadata interrupt_metadata;
527
#endif
528
};
529
530
void CvCapture_FFMPEG::init()
531
{
532
ic = 0;
533
video_stream = -1;
534
video_st = 0;
535
picture = 0;
536
picture_pts = AV_NOPTS_VALUE_;
537
first_frame_number = -1;
538
memset( &rgb_picture, 0, sizeof(rgb_picture) );
539
memset( &frame, 0, sizeof(frame) );
540
filename = 0;
541
memset(&packet, 0, sizeof(packet));
542
av_init_packet(&packet);
543
img_convert_ctx = 0;
544
545
avcodec = 0;
546
frame_number = 0;
547
eps_zero = 0.000025;
548
549
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
550
dict = NULL;
551
#endif
552
}
553
554
555
void CvCapture_FFMPEG::close()
556
{
557
if( img_convert_ctx )
558
{
559
sws_freeContext(img_convert_ctx);
560
img_convert_ctx = 0;
561
}
562
563
if( picture )
564
{
565
#if LIBAVCODEC_BUILD >= (LIBAVCODEC_VERSION_MICRO >= 100 \
566
? CALC_FFMPEG_VERSION(55, 45, 101) : CALC_FFMPEG_VERSION(55, 28, 1))
567
av_frame_free(&picture);
568
#elif LIBAVCODEC_BUILD >= (LIBAVCODEC_VERSION_MICRO >= 100 \
569
? CALC_FFMPEG_VERSION(54, 59, 100) : CALC_FFMPEG_VERSION(54, 28, 0))
570
avcodec_free_frame(&picture);
571
#else
572
av_free(picture);
573
#endif
574
}
575
576
if( video_st )
577
{
578
#if LIBAVFORMAT_BUILD > 4628
579
avcodec_close( video_st->codec );
580
581
#else
582
avcodec_close( &(video_st->codec) );
583
584
#endif
585
video_st = NULL;
586
}
587
588
if( ic )
589
{
590
#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 24, 2)
591
av_close_input_file(ic);
592
#else
593
avformat_close_input(&ic);
594
#endif
595
596
ic = NULL;
597
}
598
599
#if USE_AV_FRAME_GET_BUFFER
600
av_frame_unref(&rgb_picture);
601
#else
602
if( rgb_picture.data[0] )
603
{
604
free( rgb_picture.data[0] );
605
rgb_picture.data[0] = 0;
606
}
607
#endif
608
609
// free last packet if exist
610
if (packet.data) {
611
_opencv_ffmpeg_av_packet_unref (&packet);
612
packet.data = NULL;
613
}
614
615
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
616
if (dict != NULL)
617
av_dict_free(&dict);
618
#endif
619
620
init();
621
}
622
623
624
#ifndef AVSEEK_FLAG_FRAME
625
#define AVSEEK_FLAG_FRAME 0
626
#endif
627
#ifndef AVSEEK_FLAG_ANY
628
#define AVSEEK_FLAG_ANY 1
629
#endif
630
631
class ImplMutex
632
{
633
public:
634
ImplMutex() { init(); }
635
~ImplMutex() { destroy(); }
636
637
void init();
638
void destroy();
639
640
void lock();
641
bool trylock();
642
void unlock();
643
644
struct Impl;
645
protected:
646
Impl* impl;
647
648
private:
649
ImplMutex(const ImplMutex&);
650
ImplMutex& operator = (const ImplMutex& m);
651
};
652
653
#if defined _WIN32 || defined WINCE
654
655
struct ImplMutex::Impl
656
{
657
void init()
658
{
659
#if (_WIN32_WINNT >= 0x0600)
660
::InitializeCriticalSectionEx(&cs, 1000, 0);
661
#else
662
::InitializeCriticalSection(&cs);
663
#endif
664
refcount = 1;
665
}
666
void destroy() { DeleteCriticalSection(&cs); }
667
668
void lock() { EnterCriticalSection(&cs); }
669
bool trylock() { return TryEnterCriticalSection(&cs) != 0; }
670
void unlock() { LeaveCriticalSection(&cs); }
671
672
CRITICAL_SECTION cs;
673
int refcount;
674
};
675
676
#ifndef __GNUC__
677
static int _interlockedExchangeAdd(int* addr, int delta)
678
{
679
#if defined _MSC_VER && _MSC_VER >= 1500
680
return (int)_InterlockedExchangeAdd((long volatile*)addr, delta);
681
#else
682
return (int)InterlockedExchangeAdd((long volatile*)addr, delta);
683
#endif
684
}
685
#endif // __GNUC__
686
687
#elif defined __APPLE__
688
689
#include <libkern/OSAtomic.h>
690
691
struct ImplMutex::Impl
692
{
693
void init() { sl = OS_SPINLOCK_INIT; refcount = 1; }
694
void destroy() { }
695
696
void lock() { OSSpinLockLock(&sl); }
697
bool trylock() { return OSSpinLockTry(&sl); }
698
void unlock() { OSSpinLockUnlock(&sl); }
699
700
OSSpinLock sl;
701
int refcount;
702
};
703
704
#elif defined __linux__ && !defined __ANDROID__
705
706
struct ImplMutex::Impl
707
{
708
void init() { pthread_spin_init(&sl, 0); refcount = 1; }
709
void destroy() { pthread_spin_destroy(&sl); }
710
711
void lock() { pthread_spin_lock(&sl); }
712
bool trylock() { return pthread_spin_trylock(&sl) == 0; }
713
void unlock() { pthread_spin_unlock(&sl); }
714
715
pthread_spinlock_t sl;
716
int refcount;
717
};
718
719
#else
720
721
struct ImplMutex::Impl
722
{
723
void init() { pthread_mutex_init(&sl, 0); refcount = 1; }
724
void destroy() { pthread_mutex_destroy(&sl); }
725
726
void lock() { pthread_mutex_lock(&sl); }
727
bool trylock() { return pthread_mutex_trylock(&sl) == 0; }
728
void unlock() { pthread_mutex_unlock(&sl); }
729
730
pthread_mutex_t sl;
731
int refcount;
732
};
733
734
#endif
735
736
void ImplMutex::init()
737
{
738
impl = new Impl();
739
impl->init();
740
}
741
void ImplMutex::destroy()
742
{
743
impl->destroy();
744
delete(impl);
745
impl = NULL;
746
}
747
void ImplMutex::lock() { impl->lock(); }
748
void ImplMutex::unlock() { impl->unlock(); }
749
bool ImplMutex::trylock() { return impl->trylock(); }
750
751
static int LockCallBack(void **mutex, AVLockOp op)
752
{
753
ImplMutex* localMutex = reinterpret_cast<ImplMutex*>(*mutex);
754
switch (op)
755
{
756
case AV_LOCK_CREATE:
757
localMutex = reinterpret_cast<ImplMutex*>(malloc(sizeof(ImplMutex)));
758
if (!localMutex)
759
return 1;
760
localMutex->init();
761
*mutex = localMutex;
762
if (!*mutex)
763
return 1;
764
break;
765
766
case AV_LOCK_OBTAIN:
767
localMutex->lock();
768
break;
769
770
case AV_LOCK_RELEASE:
771
localMutex->unlock();
772
break;
773
774
case AV_LOCK_DESTROY:
775
localMutex->destroy();
776
free(localMutex);
777
localMutex = NULL;
778
*mutex = NULL;
779
break;
780
}
781
return 0;
782
}
783
784
static ImplMutex _mutex;
785
static bool _initialized = false;
786
787
class AutoLock
788
{
789
public:
790
AutoLock(ImplMutex& m) : mutex(&m) { mutex->lock(); }
791
~AutoLock() { mutex->unlock(); }
792
protected:
793
ImplMutex* mutex;
794
private:
795
AutoLock(const AutoLock&); // disabled
796
AutoLock& operator = (const AutoLock&); // disabled
797
};
798
799
static void ffmpeg_log_callback(void *ptr, int level, const char *fmt, va_list vargs)
800
{
801
static bool skip_header = false;
802
static int prev_level = -1;
803
CV_UNUSED(ptr);
804
if (!skip_header || level != prev_level) printf("[OPENCV:FFMPEG:%02d] ", level);
805
vprintf(fmt, vargs);
806
size_t fmt_len = strlen(fmt);
807
skip_header = fmt_len > 0 && fmt[fmt_len - 1] != '\n';
808
prev_level = level;
809
}
810
811
class InternalFFMpegRegister
812
{
813
public:
814
InternalFFMpegRegister()
815
{
816
AutoLock lock(_mutex);
817
if (!_initialized)
818
{
819
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0)
820
avformat_network_init();
821
#endif
822
823
/* register all codecs, demux and protocols */
824
av_register_all();
825
826
/* register a callback function for synchronization */
827
av_lockmgr_register(&LockCallBack);
828
829
#ifndef NO_GETENV
830
char* debug_option = getenv("OPENCV_FFMPEG_DEBUG");
831
if (debug_option != NULL)
832
{
833
av_log_set_level(AV_LOG_VERBOSE);
834
av_log_set_callback(ffmpeg_log_callback);
835
}
836
else
837
#endif
838
{
839
av_log_set_level(AV_LOG_ERROR);
840
}
841
842
_initialized = true;
843
}
844
}
845
846
~InternalFFMpegRegister()
847
{
848
_initialized = false;
849
av_lockmgr_register(NULL);
850
}
851
};
852
853
static InternalFFMpegRegister _init;
854
855
bool CvCapture_FFMPEG::open( const char* _filename )
856
{
857
AutoLock lock(_mutex);
858
unsigned i;
859
bool valid = false;
860
861
close();
862
863
#if USE_AV_INTERRUPT_CALLBACK
864
/* interrupt callback */
865
interrupt_metadata.timeout_after_ms = LIBAVFORMAT_INTERRUPT_OPEN_TIMEOUT_MS;
866
get_monotonic_time(&interrupt_metadata.value);
867
868
ic = avformat_alloc_context();
869
ic->interrupt_callback.callback = _opencv_ffmpeg_interrupt_callback;
870
ic->interrupt_callback.opaque = &interrupt_metadata;
871
#endif
872
873
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
874
#ifndef NO_GETENV
875
char* options = getenv("OPENCV_FFMPEG_CAPTURE_OPTIONS");
876
if(options == NULL)
877
{
878
av_dict_set(&dict, "rtsp_transport", "tcp", 0);
879
}
880
else
881
{
882
#if LIBAVUTIL_BUILD >= (LIBAVUTIL_VERSION_MICRO >= 100 ? CALC_FFMPEG_VERSION(52, 17, 100) : CALC_FFMPEG_VERSION(52, 7, 0))
883
av_dict_parse_string(&dict, options, ";", "|", 0);
884
#else
885
av_dict_set(&dict, "rtsp_transport", "tcp", 0);
886
#endif
887
}
888
#else
889
av_dict_set(&dict, "rtsp_transport", "tcp", 0);
890
#endif
891
int err = avformat_open_input(&ic, _filename, NULL, &dict);
892
#else
893
int err = av_open_input_file(&ic, _filename, NULL, 0, NULL);
894
#endif
895
896
if (err < 0)
897
{
898
CV_WARN("Error opening file");
899
CV_WARN(_filename);
900
goto exit_func;
901
}
902
err =
903
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 6, 0)
904
avformat_find_stream_info(ic, NULL);
905
#else
906
av_find_stream_info(ic);
907
#endif
908
if (err < 0)
909
{
910
CV_WARN("Could not find codec parameters");
911
goto exit_func;
912
}
913
for(i = 0; i < ic->nb_streams; i++)
914
{
915
#if LIBAVFORMAT_BUILD > 4628
916
AVCodecContext *enc = ic->streams[i]->codec;
917
#else
918
AVCodecContext *enc = &ic->streams[i]->codec;
919
#endif
920
921
//#ifdef FF_API_THREAD_INIT
922
// avcodec_thread_init(enc, get_number_of_cpus());
923
//#else
924
enc->thread_count = get_number_of_cpus();
925
//#endif
926
927
#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
928
#define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO
929
#endif
930
931
if( AVMEDIA_TYPE_VIDEO == enc->codec_type && video_stream < 0)
932
{
933
// backup encoder' width/height
934
int enc_width = enc->width;
935
int enc_height = enc->height;
936
937
AVCodec *codec;
938
if(av_dict_get(dict, "video_codec", NULL, 0) == NULL) {
939
codec = avcodec_find_decoder(enc->codec_id);
940
} else {
941
codec = avcodec_find_decoder_by_name(av_dict_get(dict, "video_codec", NULL, 0)->value);
942
}
943
if (!codec ||
944
#if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0)
945
avcodec_open2(enc, codec, NULL)
946
#else
947
avcodec_open(enc, codec)
948
#endif
949
< 0)
950
goto exit_func;
951
952
// checking width/height (since decoder can sometimes alter it, eg. vp6f)
953
if (enc_width && (enc->width != enc_width)) { enc->width = enc_width; }
954
if (enc_height && (enc->height != enc_height)) { enc->height = enc_height; }
955
956
video_stream = i;
957
video_st = ic->streams[i];
958
#if LIBAVCODEC_BUILD >= (LIBAVCODEC_VERSION_MICRO >= 100 \
959
? CALC_FFMPEG_VERSION(55, 45, 101) : CALC_FFMPEG_VERSION(55, 28, 1))
960
picture = av_frame_alloc();
961
#else
962
picture = avcodec_alloc_frame();
963
#endif
964
965
frame.width = enc->width;
966
frame.height = enc->height;
967
frame.cn = 3;
968
frame.step = 0;
969
frame.data = NULL;
970
break;
971
}
972
}
973
974
if(video_stream >= 0) valid = true;
975
976
exit_func:
977
978
#if USE_AV_INTERRUPT_CALLBACK
979
// deactivate interrupt callback
980
interrupt_metadata.timeout_after_ms = 0;
981
#endif
982
983
if( !valid )
984
close();
985
986
return valid;
987
}
988
989
990
bool CvCapture_FFMPEG::grabFrame()
991
{
992
bool valid = false;
993
int got_picture;
994
995
int count_errs = 0;
996
const int max_number_of_attempts = 1 << 9;
997
998
if( !ic || !video_st ) return false;
999
1000
if( ic->streams[video_stream]->nb_frames > 0 &&
1001
frame_number > ic->streams[video_stream]->nb_frames )
1002
return false;
1003
1004
picture_pts = AV_NOPTS_VALUE_;
1005
1006
#if USE_AV_INTERRUPT_CALLBACK
1007
// activate interrupt callback
1008
get_monotonic_time(&interrupt_metadata.value);
1009
interrupt_metadata.timeout_after_ms = LIBAVFORMAT_INTERRUPT_READ_TIMEOUT_MS;
1010
#endif
1011
1012
// get the next frame
1013
while (!valid)
1014
{
1015
1016
_opencv_ffmpeg_av_packet_unref (&packet);
1017
1018
#if USE_AV_INTERRUPT_CALLBACK
1019
if (interrupt_metadata.timeout)
1020
{
1021
valid = false;
1022
break;
1023
}
1024
#endif
1025
1026
int ret = av_read_frame(ic, &packet);
1027
if (ret == AVERROR(EAGAIN)) continue;
1028
1029
/* else if (ret < 0) break; */
1030
1031
if( packet.stream_index != video_stream )
1032
{
1033
_opencv_ffmpeg_av_packet_unref (&packet);
1034
count_errs++;
1035
if (count_errs > max_number_of_attempts)
1036
break;
1037
continue;
1038
}
1039
1040
// Decode video frame
1041
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
1042
avcodec_decode_video2(video_st->codec, picture, &got_picture, &packet);
1043
#elif LIBAVFORMAT_BUILD > 4628
1044
avcodec_decode_video(video_st->codec,
1045
picture, &got_picture,
1046
packet.data, packet.size);
1047
#else
1048
avcodec_decode_video(&video_st->codec,
1049
picture, &got_picture,
1050
packet.data, packet.size);
1051
#endif
1052
1053
// Did we get a video frame?
1054
if(got_picture)
1055
{
1056
//picture_pts = picture->best_effort_timestamp;
1057
if( picture_pts == AV_NOPTS_VALUE_ )
1058
picture_pts = picture->pkt_pts != AV_NOPTS_VALUE_ && picture->pkt_pts != 0 ? picture->pkt_pts : picture->pkt_dts;
1059
1060
frame_number++;
1061
valid = true;
1062
}
1063
else
1064
{
1065
count_errs++;
1066
if (count_errs > max_number_of_attempts)
1067
break;
1068
}
1069
}
1070
1071
if( valid && first_frame_number < 0 )
1072
first_frame_number = dts_to_frame_number(picture_pts);
1073
1074
#if USE_AV_INTERRUPT_CALLBACK
1075
// deactivate interrupt callback
1076
interrupt_metadata.timeout_after_ms = 0;
1077
#endif
1078
1079
// return if we have a new picture or not
1080
return valid;
1081
}
1082
1083
1084
bool CvCapture_FFMPEG::retrieveFrame(int, unsigned char** data, int* step, int* width, int* height, int* cn)
1085
{
1086
if( !video_st || !picture->data[0] )
1087
return false;
1088
1089
if( img_convert_ctx == NULL ||
1090
frame.width != video_st->codec->width ||
1091
frame.height != video_st->codec->height ||
1092
frame.data == NULL )
1093
{
1094
// Some sws_scale optimizations have some assumptions about alignment of data/step/width/height
1095
// Also we use coded_width/height to workaround problem with legacy ffmpeg versions (like n0.8)
1096
int buffer_width = video_st->codec->coded_width, buffer_height = video_st->codec->coded_height;
1097
1098
img_convert_ctx = sws_getCachedContext(
1099
img_convert_ctx,
1100
buffer_width, buffer_height,
1101
video_st->codec->pix_fmt,
1102
buffer_width, buffer_height,
1103
AV_PIX_FMT_BGR24,
1104
SWS_BICUBIC,
1105
NULL, NULL, NULL
1106
);
1107
1108
if (img_convert_ctx == NULL)
1109
return false;//CV_Error(0, "Cannot initialize the conversion context!");
1110
1111
#if USE_AV_FRAME_GET_BUFFER
1112
av_frame_unref(&rgb_picture);
1113
rgb_picture.format = AV_PIX_FMT_BGR24;
1114
rgb_picture.width = buffer_width;
1115
rgb_picture.height = buffer_height;
1116
if (0 != av_frame_get_buffer(&rgb_picture, 32))
1117
{
1118
CV_WARN("OutOfMemory");
1119
return false;
1120
}
1121
#else
1122
int aligns[AV_NUM_DATA_POINTERS];
1123
avcodec_align_dimensions2(video_st->codec, &buffer_width, &buffer_height, aligns);
1124
rgb_picture.data[0] = (uint8_t*)realloc(rgb_picture.data[0],
1125
_opencv_ffmpeg_av_image_get_buffer_size( AV_PIX_FMT_BGR24,
1126
buffer_width, buffer_height ));
1127
_opencv_ffmpeg_av_image_fill_arrays(&rgb_picture, rgb_picture.data[0],
1128
AV_PIX_FMT_BGR24, buffer_width, buffer_height );
1129
#endif
1130
frame.width = video_st->codec->width;
1131
frame.height = video_st->codec->height;
1132
frame.cn = 3;
1133
frame.data = rgb_picture.data[0];
1134
frame.step = rgb_picture.linesize[0];
1135
}
1136
1137
sws_scale(
1138
img_convert_ctx,
1139
picture->data,
1140
picture->linesize,
1141
0, video_st->codec->coded_height,
1142
rgb_picture.data,
1143
rgb_picture.linesize
1144
);
1145
1146
*data = frame.data;
1147
*step = frame.step;
1148
*width = frame.width;
1149
*height = frame.height;
1150
*cn = frame.cn;
1151
1152
return true;
1153
}
1154
1155
1156
double CvCapture_FFMPEG::getProperty( int property_id ) const
1157
{
1158
if( !video_st ) return 0;
1159
1160
double codec_tag = 0;
1161
AVCodecID codec_id = AV_CODEC_ID_NONE;
1162
const char* codec_fourcc = NULL;
1163
1164
switch( property_id )
1165
{
1166
case CV_FFMPEG_CAP_PROP_POS_MSEC:
1167
return 1000.0*(double)frame_number/get_fps();
1168
case CV_FFMPEG_CAP_PROP_POS_FRAMES:
1169
return (double)frame_number;
1170
case CV_FFMPEG_CAP_PROP_POS_AVI_RATIO:
1171
return r2d(ic->streams[video_stream]->time_base);
1172
case CV_FFMPEG_CAP_PROP_FRAME_COUNT:
1173
return (double)get_total_frames();
1174
case CV_FFMPEG_CAP_PROP_FRAME_WIDTH:
1175
return (double)frame.width;
1176
case CV_FFMPEG_CAP_PROP_FRAME_HEIGHT:
1177
return (double)frame.height;
1178
case CV_FFMPEG_CAP_PROP_FPS:
1179
return get_fps();
1180
case CV_FFMPEG_CAP_PROP_FOURCC:
1181
#if LIBAVFORMAT_BUILD > 4628
1182
codec_id = video_st->codec->codec_id;
1183
codec_tag = (double) video_st->codec->codec_tag;
1184
#else
1185
codec_id = video_st->codec.codec_id;
1186
codec_tag = (double)video_st->codec.codec_tag;
1187
#endif
1188
1189
if(codec_tag || codec_id == AV_CODEC_ID_NONE)
1190
{
1191
return codec_tag;
1192
}
1193
1194
codec_fourcc = _opencv_avcodec_get_name(codec_id);
1195
if(!codec_fourcc || strlen(codec_fourcc) < 4 || strcmp(codec_fourcc, "unknown_codec") == 0)
1196
{
1197
return codec_tag;
1198
}
1199
1200
return (double) OPENCV_FOURCC(codec_fourcc[0], codec_fourcc[1], codec_fourcc[2], codec_fourcc[3]);
1201
case CV_FFMPEG_CAP_PROP_SAR_NUM:
1202
return _opencv_ffmpeg_get_sample_aspect_ratio(ic->streams[video_stream]).num;
1203
case CV_FFMPEG_CAP_PROP_SAR_DEN:
1204
return _opencv_ffmpeg_get_sample_aspect_ratio(ic->streams[video_stream]).den;
1205
default:
1206
break;
1207
}
1208
1209
return 0;
1210
}
1211
1212
double CvCapture_FFMPEG::r2d(AVRational r) const
1213
{
1214
return r.num == 0 || r.den == 0 ? 0. : (double)r.num / (double)r.den;
1215
}
1216
1217
double CvCapture_FFMPEG::get_duration_sec() const
1218
{
1219
double sec = (double)ic->duration / (double)AV_TIME_BASE;
1220
1221
if (sec < eps_zero)
1222
{
1223
sec = (double)ic->streams[video_stream]->duration * r2d(ic->streams[video_stream]->time_base);
1224
}
1225
1226
return sec;
1227
}
1228
1229
int CvCapture_FFMPEG::get_bitrate() const
1230
{
1231
return ic->bit_rate;
1232
}
1233
1234
double CvCapture_FFMPEG::get_fps() const
1235
{
1236
#if 0 && LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(55, 1, 100) && LIBAVFORMAT_VERSION_MICRO >= 100
1237
double fps = r2d(av_guess_frame_rate(ic, ic->streams[video_stream], NULL));
1238
#else
1239
#if LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(54, 1, 0)
1240
double fps = r2d(ic->streams[video_stream]->avg_frame_rate);
1241
#else
1242
double fps = r2d(ic->streams[video_stream]->r_frame_rate);
1243
#endif
1244
1245
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
1246
if (fps < eps_zero)
1247
{
1248
fps = r2d(ic->streams[video_stream]->avg_frame_rate);
1249
}
1250
#endif
1251
1252
if (fps < eps_zero)
1253
{
1254
fps = 1.0 / r2d(ic->streams[video_stream]->codec->time_base);
1255
}
1256
#endif
1257
return fps;
1258
}
1259
1260
int64_t CvCapture_FFMPEG::get_total_frames() const
1261
{
1262
int64_t nbf = ic->streams[video_stream]->nb_frames;
1263
1264
if (nbf == 0)
1265
{
1266
nbf = (int64_t)floor(get_duration_sec() * get_fps() + 0.5);
1267
}
1268
return nbf;
1269
}
1270
1271
int64_t CvCapture_FFMPEG::dts_to_frame_number(int64_t dts)
1272
{
1273
double sec = dts_to_sec(dts);
1274
return (int64_t)(get_fps() * sec + 0.5);
1275
}
1276
1277
double CvCapture_FFMPEG::dts_to_sec(int64_t dts)
1278
{
1279
return (double)(dts - ic->streams[video_stream]->start_time) *
1280
r2d(ic->streams[video_stream]->time_base);
1281
}
1282
1283
void CvCapture_FFMPEG::seek(int64_t _frame_number)
1284
{
1285
_frame_number = std::min(_frame_number, get_total_frames());
1286
int delta = 16;
1287
1288
// if we have not grabbed a single frame before first seek, let's read the first frame
1289
// and get some valuable information during the process
1290
if( first_frame_number < 0 && get_total_frames() > 1 )
1291
grabFrame();
1292
1293
for(;;)
1294
{
1295
int64_t _frame_number_temp = std::max(_frame_number-delta, (int64_t)0);
1296
double sec = (double)_frame_number_temp / get_fps();
1297
int64_t time_stamp = ic->streams[video_stream]->start_time;
1298
double time_base = r2d(ic->streams[video_stream]->time_base);
1299
time_stamp += (int64_t)(sec / time_base + 0.5);
1300
if (get_total_frames() > 1) av_seek_frame(ic, video_stream, time_stamp, AVSEEK_FLAG_BACKWARD);
1301
avcodec_flush_buffers(ic->streams[video_stream]->codec);
1302
if( _frame_number > 0 )
1303
{
1304
grabFrame();
1305
1306
if( _frame_number > 1 )
1307
{
1308
frame_number = dts_to_frame_number(picture_pts) - first_frame_number;
1309
//printf("_frame_number = %d, frame_number = %d, delta = %d\n",
1310
// (int)_frame_number, (int)frame_number, delta);
1311
1312
if( frame_number < 0 || frame_number > _frame_number-1 )
1313
{
1314
if( _frame_number_temp == 0 || delta >= INT_MAX/4 )
1315
break;
1316
delta = delta < 16 ? delta*2 : delta*3/2;
1317
continue;
1318
}
1319
while( frame_number < _frame_number-1 )
1320
{
1321
if(!grabFrame())
1322
break;
1323
}
1324
frame_number++;
1325
break;
1326
}
1327
else
1328
{
1329
frame_number = 1;
1330
break;
1331
}
1332
}
1333
else
1334
{
1335
frame_number = 0;
1336
break;
1337
}
1338
}
1339
}
1340
1341
void CvCapture_FFMPEG::seek(double sec)
1342
{
1343
seek((int64_t)(sec * get_fps() + 0.5));
1344
}
1345
1346
bool CvCapture_FFMPEG::setProperty( int property_id, double value )
1347
{
1348
if( !video_st ) return false;
1349
1350
switch( property_id )
1351
{
1352
case CV_FFMPEG_CAP_PROP_POS_MSEC:
1353
case CV_FFMPEG_CAP_PROP_POS_FRAMES:
1354
case CV_FFMPEG_CAP_PROP_POS_AVI_RATIO:
1355
{
1356
switch( property_id )
1357
{
1358
case CV_FFMPEG_CAP_PROP_POS_FRAMES:
1359
seek((int64_t)value);
1360
break;
1361
1362
case CV_FFMPEG_CAP_PROP_POS_MSEC:
1363
seek(value/1000.0);
1364
break;
1365
1366
case CV_FFMPEG_CAP_PROP_POS_AVI_RATIO:
1367
seek((int64_t)(value*ic->duration));
1368
break;
1369
}
1370
1371
picture_pts=(int64_t)value;
1372
}
1373
break;
1374
default:
1375
return false;
1376
}
1377
1378
return true;
1379
}
1380
1381
1382
///////////////// FFMPEG CvVideoWriter implementation //////////////////////////
1383
struct CvVideoWriter_FFMPEG
1384
{
1385
bool open( const char* filename, int fourcc,
1386
double fps, int width, int height, bool isColor );
1387
void close();
1388
bool writeFrame( const unsigned char* data, int step, int width, int height, int cn, int origin );
1389
1390
void init();
1391
1392
AVOutputFormat * fmt;
1393
AVFormatContext * oc;
1394
uint8_t * outbuf;
1395
uint32_t outbuf_size;
1396
FILE * outfile;
1397
AVFrame * picture;
1398
AVFrame * input_picture;
1399
uint8_t * picbuf;
1400
AVStream * video_st;
1401
int input_pix_fmt;
1402
unsigned char * aligned_input;
1403
size_t aligned_input_size;
1404
int frame_width, frame_height;
1405
int frame_idx;
1406
bool ok;
1407
struct SwsContext *img_convert_ctx;
1408
};
1409
1410
static const char * icvFFMPEGErrStr(int err)
1411
{
1412
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
1413
switch(err) {
1414
case AVERROR_BSF_NOT_FOUND:
1415
return "Bitstream filter not found";
1416
case AVERROR_DECODER_NOT_FOUND:
1417
return "Decoder not found";
1418
case AVERROR_DEMUXER_NOT_FOUND:
1419
return "Demuxer not found";
1420
case AVERROR_ENCODER_NOT_FOUND:
1421
return "Encoder not found";
1422
case AVERROR_EOF:
1423
return "End of file";
1424
case AVERROR_EXIT:
1425
return "Immediate exit was requested; the called function should not be restarted";
1426
case AVERROR_FILTER_NOT_FOUND:
1427
return "Filter not found";
1428
case AVERROR_INVALIDDATA:
1429
return "Invalid data found when processing input";
1430
case AVERROR_MUXER_NOT_FOUND:
1431
return "Muxer not found";
1432
case AVERROR_OPTION_NOT_FOUND:
1433
return "Option not found";
1434
case AVERROR_PATCHWELCOME:
1435
return "Not yet implemented in FFmpeg, patches welcome";
1436
case AVERROR_PROTOCOL_NOT_FOUND:
1437
return "Protocol not found";
1438
case AVERROR_STREAM_NOT_FOUND:
1439
return "Stream not found";
1440
default:
1441
break;
1442
}
1443
#else
1444
switch(err) {
1445
case AVERROR_NUMEXPECTED:
1446
return "Incorrect filename syntax";
1447
case AVERROR_INVALIDDATA:
1448
return "Invalid data in header";
1449
case AVERROR_NOFMT:
1450
return "Unknown format";
1451
case AVERROR_IO:
1452
return "I/O error occurred";
1453
case AVERROR_NOMEM:
1454
return "Memory allocation error";
1455
default:
1456
break;
1457
}
1458
#endif
1459
1460
return "Unspecified error";
1461
}
1462
1463
/* function internal to FFMPEG (libavformat/riff.c) to lookup codec id by fourcc tag*/
1464
extern "C" {
1465
enum CV_CODEC_ID codec_get_bmp_id(unsigned int tag);
1466
}
1467
1468
void CvVideoWriter_FFMPEG::init()
1469
{
1470
fmt = 0;
1471
oc = 0;
1472
outbuf = 0;
1473
outbuf_size = 0;
1474
outfile = 0;
1475
picture = 0;
1476
input_picture = 0;
1477
picbuf = 0;
1478
video_st = 0;
1479
input_pix_fmt = 0;
1480
aligned_input = NULL;
1481
aligned_input_size = 0;
1482
img_convert_ctx = 0;
1483
frame_width = frame_height = 0;
1484
frame_idx = 0;
1485
ok = false;
1486
}
1487
1488
/**
1489
* the following function is a modified version of code
1490
* found in ffmpeg-0.4.9-pre1/output_example.c
1491
*/
1492
static AVFrame * icv_alloc_picture_FFMPEG(int pix_fmt, int width, int height, bool alloc)
1493
{
1494
AVFrame * picture;
1495
uint8_t * picture_buf = 0;
1496
int size;
1497
1498
#if LIBAVCODEC_BUILD >= (LIBAVCODEC_VERSION_MICRO >= 100 \
1499
? CALC_FFMPEG_VERSION(55, 45, 101) : CALC_FFMPEG_VERSION(55, 28, 1))
1500
picture = av_frame_alloc();
1501
#else
1502
picture = avcodec_alloc_frame();
1503
#endif
1504
if (!picture)
1505
return NULL;
1506
1507
picture->format = pix_fmt;
1508
picture->width = width;
1509
picture->height = height;
1510
1511
size = _opencv_ffmpeg_av_image_get_buffer_size( (AVPixelFormat) pix_fmt, width, height);
1512
if(alloc){
1513
picture_buf = (uint8_t *) malloc(size);
1514
if (!picture_buf)
1515
{
1516
av_free(picture);
1517
return NULL;
1518
}
1519
_opencv_ffmpeg_av_image_fill_arrays(picture, picture_buf,
1520
(AVPixelFormat) pix_fmt, width, height);
1521
}
1522
1523
return picture;
1524
}
1525
1526
/* add a video output stream to the container */
1527
static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc,
1528
CV_CODEC_ID codec_id,
1529
int w, int h, int bitrate,
1530
double fps, int pixel_format)
1531
{
1532
AVCodecContext *c;
1533
AVStream *st;
1534
int frame_rate, frame_rate_base;
1535
AVCodec *codec;
1536
1537
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 10, 0)
1538
st = avformat_new_stream(oc, 0);
1539
#else
1540
st = av_new_stream(oc, 0);
1541
#endif
1542
1543
if (!st) {
1544
CV_WARN("Could not allocate stream");
1545
return NULL;
1546
}
1547
1548
#if LIBAVFORMAT_BUILD > 4628
1549
c = st->codec;
1550
#else
1551
c = &(st->codec);
1552
#endif
1553
1554
#if LIBAVFORMAT_BUILD > 4621
1555
c->codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO);
1556
#else
1557
c->codec_id = oc->oformat->video_codec;
1558
#endif
1559
1560
if(codec_id != CV_CODEC(CODEC_ID_NONE)){
1561
c->codec_id = codec_id;
1562
}
1563
1564
//if(codec_tag) c->codec_tag=codec_tag;
1565
codec = avcodec_find_encoder(c->codec_id);
1566
1567
c->codec_type = AVMEDIA_TYPE_VIDEO;
1568
1569
#if LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(54,25,0)
1570
// Set per-codec defaults
1571
AVCodecID c_id = c->codec_id;
1572
avcodec_get_context_defaults3(c, codec);
1573
// avcodec_get_context_defaults3 erases codec_id for some reason
1574
c->codec_id = c_id;
1575
#endif
1576
1577
/* put sample parameters */
1578
int64_t lbit_rate = (int64_t)bitrate;
1579
lbit_rate += (bitrate / 2);
1580
lbit_rate = std::min(lbit_rate, (int64_t)INT_MAX);
1581
c->bit_rate = lbit_rate;
1582
1583
// took advice from
1584
// http://ffmpeg-users.933282.n4.nabble.com/warning-clipping-1-dct-coefficients-to-127-127-td934297.html
1585
c->qmin = 3;
1586
1587
/* resolution must be a multiple of two */
1588
c->width = w;
1589
c->height = h;
1590
1591
/* time base: this is the fundamental unit of time (in seconds) in terms
1592
of which frame timestamps are represented. for fixed-fps content,
1593
timebase should be 1/framerate and timestamp increments should be
1594
identically 1. */
1595
frame_rate=(int)(fps+0.5);
1596
frame_rate_base=1;
1597
while (fabs(((double)frame_rate/frame_rate_base) - fps) > 0.001){
1598
frame_rate_base*=10;
1599
frame_rate=(int)(fps*frame_rate_base + 0.5);
1600
}
1601
#if LIBAVFORMAT_BUILD > 4752
1602
c->time_base.den = frame_rate;
1603
c->time_base.num = frame_rate_base;
1604
/* adjust time base for supported framerates */
1605
if(codec && codec->supported_framerates){
1606
const AVRational *p= codec->supported_framerates;
1607
AVRational req = {frame_rate, frame_rate_base};
1608
const AVRational *best=NULL;
1609
AVRational best_error= {INT_MAX, 1};
1610
for(; p->den!=0; p++){
1611
AVRational error= av_sub_q(req, *p);
1612
if(error.num <0) error.num *= -1;
1613
if(av_cmp_q(error, best_error) < 0){
1614
best_error= error;
1615
best= p;
1616
}
1617
}
1618
if (best == NULL)
1619
return NULL;
1620
c->time_base.den= best->num;
1621
c->time_base.num= best->den;
1622
}
1623
#else
1624
c->frame_rate = frame_rate;
1625
c->frame_rate_base = frame_rate_base;
1626
#endif
1627
1628
c->gop_size = 12; /* emit one intra frame every twelve frames at most */
1629
c->pix_fmt = (AVPixelFormat) pixel_format;
1630
1631
if (c->codec_id == CV_CODEC(CODEC_ID_MPEG2VIDEO)) {
1632
c->max_b_frames = 2;
1633
}
1634
if (c->codec_id == CV_CODEC(CODEC_ID_MPEG1VIDEO) || c->codec_id == CV_CODEC(CODEC_ID_MSMPEG4V3)){
1635
/* needed to avoid using macroblocks in which some coeffs overflow
1636
this doesn't happen with normal video, it just happens here as the
1637
motion of the chroma plane doesn't match the luma plane */
1638
/* avoid FFMPEG warning 'clipping 1 dct coefficients...' */
1639
c->mb_decision=2;
1640
}
1641
1642
#if LIBAVUTIL_BUILD > CALC_FFMPEG_VERSION(51,11,0)
1643
/* Some settings for libx264 encoding, restore dummy values for gop_size
1644
and qmin since they will be set to reasonable defaults by the libx264
1645
preset system. Also, use a crf encode with the default quality rating,
1646
this seems easier than finding an appropriate default bitrate. */
1647
if (c->codec_id == AV_CODEC_ID_H264) {
1648
c->gop_size = -1;
1649
c->qmin = -1;
1650
c->bit_rate = 0;
1651
if (c->priv_data)
1652
av_opt_set(c->priv_data,"crf","23", 0);
1653
}
1654
#endif
1655
1656
#if LIBAVCODEC_VERSION_INT>0x000409
1657
// some formats want stream headers to be separate
1658
if(oc->oformat->flags & AVFMT_GLOBALHEADER)
1659
{
1660
#if LIBAVCODEC_BUILD > CALC_FFMPEG_VERSION(56, 35, 0)
1661
c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
1662
#else
1663
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
1664
#endif
1665
}
1666
#endif
1667
1668
#if LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(52, 42, 0)
1669
st->avg_frame_rate = (AVRational){frame_rate, frame_rate_base};
1670
#endif
1671
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(55, 20, 0)
1672
st->time_base = c->time_base;
1673
#endif
1674
1675
return st;
1676
}
1677
1678
static const int OPENCV_NO_FRAMES_WRITTEN_CODE = 1000;
1679
1680
static int icv_av_write_frame_FFMPEG( AVFormatContext * oc, AVStream * video_st,
1681
#if LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(54, 1, 0)
1682
uint8_t *, uint32_t,
1683
#else
1684
uint8_t * outbuf, uint32_t outbuf_size,
1685
#endif
1686
AVFrame * picture )
1687
{
1688
#if LIBAVFORMAT_BUILD > 4628
1689
AVCodecContext * c = video_st->codec;
1690
#else
1691
AVCodecContext * c = &(video_st->codec);
1692
#endif
1693
int ret = OPENCV_NO_FRAMES_WRITTEN_CODE;
1694
1695
#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(57, 0, 0)
1696
if (oc->oformat->flags & AVFMT_RAWPICTURE)
1697
{
1698
/* raw video case. The API will change slightly in the near
1699
futur for that */
1700
AVPacket pkt;
1701
av_init_packet(&pkt);
1702
1703
pkt.flags |= PKT_FLAG_KEY;
1704
pkt.stream_index= video_st->index;
1705
pkt.data= (uint8_t *)picture;
1706
pkt.size= sizeof(AVPicture);
1707
1708
ret = av_write_frame(oc, &pkt);
1709
}
1710
else
1711
#endif
1712
{
1713
/* encode the image */
1714
AVPacket pkt;
1715
av_init_packet(&pkt);
1716
#if LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(54, 1, 0)
1717
int got_output = 0;
1718
pkt.data = NULL;
1719
pkt.size = 0;
1720
ret = avcodec_encode_video2(c, &pkt, picture, &got_output);
1721
if (ret < 0)
1722
;
1723
else if (got_output) {
1724
if (pkt.pts != (int64_t)AV_NOPTS_VALUE)
1725
pkt.pts = av_rescale_q(pkt.pts, c->time_base, video_st->time_base);
1726
if (pkt.dts != (int64_t)AV_NOPTS_VALUE)
1727
pkt.dts = av_rescale_q(pkt.dts, c->time_base, video_st->time_base);
1728
if (pkt.duration)
1729
pkt.duration = av_rescale_q(pkt.duration, c->time_base, video_st->time_base);
1730
pkt.stream_index= video_st->index;
1731
ret = av_write_frame(oc, &pkt);
1732
_opencv_ffmpeg_av_packet_unref(&pkt);
1733
}
1734
else
1735
ret = OPENCV_NO_FRAMES_WRITTEN_CODE;
1736
#else
1737
int out_size = avcodec_encode_video(c, outbuf, outbuf_size, picture);
1738
/* if zero size, it means the image was buffered */
1739
if (out_size > 0) {
1740
#if LIBAVFORMAT_BUILD > 4752
1741
if(c->coded_frame->pts != (int64_t)AV_NOPTS_VALUE)
1742
pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base, video_st->time_base);
1743
#else
1744
pkt.pts = c->coded_frame->pts;
1745
#endif
1746
if(c->coded_frame->key_frame)
1747
pkt.flags |= PKT_FLAG_KEY;
1748
pkt.stream_index= video_st->index;
1749
pkt.data= outbuf;
1750
pkt.size= out_size;
1751
1752
/* write the compressed frame in the media file */
1753
ret = av_write_frame(oc, &pkt);
1754
}
1755
#endif
1756
}
1757
return ret;
1758
}
1759
1760
/// write a frame with FFMPEG
1761
bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int width, int height, int cn, int origin )
1762
{
1763
// check parameters
1764
if (input_pix_fmt == AV_PIX_FMT_BGR24) {
1765
if (cn != 3) {
1766
return false;
1767
}
1768
}
1769
else if (input_pix_fmt == AV_PIX_FMT_GRAY8) {
1770
if (cn != 1) {
1771
return false;
1772
}
1773
}
1774
else {
1775
assert(false);
1776
}
1777
1778
if( (width & -2) != frame_width || (height & -2) != frame_height || !data )
1779
return false;
1780
width = frame_width;
1781
height = frame_height;
1782
1783
// typecast from opaque data type to implemented struct
1784
#if LIBAVFORMAT_BUILD > 4628
1785
AVCodecContext *c = video_st->codec;
1786
#else
1787
AVCodecContext *c = &(video_st->codec);
1788
#endif
1789
1790
// FFmpeg contains SIMD optimizations which can sometimes read data past
1791
// the supplied input buffer.
1792
// Related info: https://trac.ffmpeg.org/ticket/6763
1793
// 1. To ensure that doesn't happen, we pad the step to a multiple of 32
1794
// (that's the minimal alignment for which Valgrind doesn't raise any warnings).
1795
// 2. (dataend - SIMD_SIZE) and (dataend + SIMD_SIZE) is from the same 4k page
1796
const int CV_STEP_ALIGNMENT = 32;
1797
const size_t CV_SIMD_SIZE = 32;
1798
const size_t CV_PAGE_MASK = ~(4096 - 1);
1799
const unsigned char* dataend = data + ((size_t)height * step);
1800
if (step % CV_STEP_ALIGNMENT != 0 ||
1801
(((size_t)dataend - CV_SIMD_SIZE) & CV_PAGE_MASK) != (((size_t)dataend + CV_SIMD_SIZE) & CV_PAGE_MASK))
1802
{
1803
int aligned_step = (step + CV_STEP_ALIGNMENT - 1) & ~(CV_STEP_ALIGNMENT - 1);
1804
1805
size_t new_size = (aligned_step * height + CV_SIMD_SIZE);
1806
1807
if (!aligned_input || aligned_input_size < new_size)
1808
{
1809
if (aligned_input)
1810
av_freep(&aligned_input);
1811
aligned_input_size = new_size;
1812
aligned_input = (unsigned char*)av_mallocz(aligned_input_size);
1813
}
1814
1815
if (origin == 1)
1816
for( int y = 0; y < height; y++ )
1817
memcpy(aligned_input + y*aligned_step, data + (height-1-y)*step, step);
1818
else
1819
for( int y = 0; y < height; y++ )
1820
memcpy(aligned_input + y*aligned_step, data + y*step, step);
1821
1822
data = aligned_input;
1823
step = aligned_step;
1824
}
1825
1826
if ( c->pix_fmt != input_pix_fmt ) {
1827
assert( input_picture );
1828
// let input_picture point to the raw data buffer of 'image'
1829
_opencv_ffmpeg_av_image_fill_arrays(input_picture, (uint8_t *) data,
1830
(AVPixelFormat)input_pix_fmt, width, height);
1831
input_picture->linesize[0] = step;
1832
1833
if( !img_convert_ctx )
1834
{
1835
img_convert_ctx = sws_getContext(width,
1836
height,
1837
(AVPixelFormat)input_pix_fmt,
1838
c->width,
1839
c->height,
1840
c->pix_fmt,
1841
SWS_BICUBIC,
1842
NULL, NULL, NULL);
1843
if( !img_convert_ctx )
1844
return false;
1845
}
1846
1847
if ( sws_scale(img_convert_ctx, input_picture->data,
1848
input_picture->linesize, 0,
1849
height,
1850
picture->data, picture->linesize) < 0 )
1851
return false;
1852
}
1853
else{
1854
_opencv_ffmpeg_av_image_fill_arrays(picture, (uint8_t *) data,
1855
(AVPixelFormat)input_pix_fmt, width, height);
1856
picture->linesize[0] = step;
1857
}
1858
1859
picture->pts = frame_idx;
1860
bool ret = icv_av_write_frame_FFMPEG( oc, video_st, outbuf, outbuf_size, picture) >= 0;
1861
frame_idx++;
1862
1863
return ret;
1864
}
1865
1866
/// close video output stream and free associated memory
1867
void CvVideoWriter_FFMPEG::close()
1868
{
1869
// nothing to do if already released
1870
if ( !picture )
1871
return;
1872
1873
/* no more frame to compress. The codec has a latency of a few
1874
frames if using B frames, so we get the last frames by
1875
passing the same picture again */
1876
// TODO -- do we need to account for latency here?
1877
1878
/* write the trailer, if any */
1879
if(ok && oc)
1880
{
1881
#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(57, 0, 0)
1882
if (!(oc->oformat->flags & AVFMT_RAWPICTURE))
1883
#endif
1884
{
1885
for(;;)
1886
{
1887
int ret = icv_av_write_frame_FFMPEG( oc, video_st, outbuf, outbuf_size, NULL);
1888
if( ret == OPENCV_NO_FRAMES_WRITTEN_CODE || ret < 0 )
1889
break;
1890
}
1891
}
1892
av_write_trailer(oc);
1893
}
1894
1895
if( img_convert_ctx )
1896
{
1897
sws_freeContext(img_convert_ctx);
1898
img_convert_ctx = 0;
1899
}
1900
1901
// free pictures
1902
#if LIBAVFORMAT_BUILD > 4628
1903
if( video_st->codec->pix_fmt != input_pix_fmt)
1904
#else
1905
if( video_st->codec.pix_fmt != input_pix_fmt)
1906
#endif
1907
{
1908
if(picture->data[0])
1909
free(picture->data[0]);
1910
picture->data[0] = 0;
1911
}
1912
av_free(picture);
1913
1914
if (input_picture)
1915
av_free(input_picture);
1916
1917
/* close codec */
1918
#if LIBAVFORMAT_BUILD > 4628
1919
avcodec_close(video_st->codec);
1920
#else
1921
avcodec_close(&(video_st->codec));
1922
#endif
1923
1924
av_free(outbuf);
1925
1926
if (oc)
1927
{
1928
if (!(fmt->flags & AVFMT_NOFILE))
1929
{
1930
/* close the output file */
1931
1932
#if LIBAVCODEC_VERSION_INT < ((52<<16)+(123<<8)+0)
1933
#if LIBAVCODEC_VERSION_INT >= ((51<<16)+(49<<8)+0)
1934
url_fclose(oc->pb);
1935
#else
1936
url_fclose(&oc->pb);
1937
#endif
1938
#else
1939
avio_close(oc->pb);
1940
#endif
1941
1942
}
1943
1944
/* free the stream */
1945
avformat_free_context(oc);
1946
}
1947
1948
av_freep(&aligned_input);
1949
1950
init();
1951
}
1952
1953
#define CV_PRINTABLE_CHAR(ch) ((ch) < 32 ? '?' : (ch))
1954
#define CV_TAG_TO_PRINTABLE_CHAR4(tag) CV_PRINTABLE_CHAR((tag) & 255), CV_PRINTABLE_CHAR(((tag) >> 8) & 255), CV_PRINTABLE_CHAR(((tag) >> 16) & 255), CV_PRINTABLE_CHAR(((tag) >> 24) & 255)
1955
1956
static inline bool cv_ff_codec_tag_match(const AVCodecTag *tags, CV_CODEC_ID id, unsigned int tag)
1957
{
1958
while (tags->id != AV_CODEC_ID_NONE)
1959
{
1960
if (tags->id == id && tags->tag == tag)
1961
return true;
1962
tags++;
1963
}
1964
return false;
1965
}
1966
static inline bool cv_ff_codec_tag_list_match(const AVCodecTag *const *tags, CV_CODEC_ID id, unsigned int tag)
1967
{
1968
int i;
1969
for (i = 0; tags && tags[i]; i++) {
1970
bool res = cv_ff_codec_tag_match(tags[i], id, tag);
1971
if (res)
1972
return res;
1973
}
1974
return false;
1975
}
1976
1977
/// Create a video writer object that uses FFMPEG
1978
bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc,
1979
double fps, int width, int height, bool is_color )
1980
{
1981
CV_CODEC_ID codec_id = CV_CODEC(CODEC_ID_NONE);
1982
int err, codec_pix_fmt;
1983
double bitrate_scale = 1;
1984
1985
close();
1986
1987
// check arguments
1988
if( !filename )
1989
return false;
1990
if(fps <= 0)
1991
return false;
1992
1993
// we allow frames of odd width or height, but in this case we truncate
1994
// the rightmost column/the bottom row. Probably, this should be handled more elegantly,
1995
// but some internal functions inside FFMPEG swscale require even width/height.
1996
width &= -2;
1997
height &= -2;
1998
if( width <= 0 || height <= 0 )
1999
return false;
2000
2001
/* auto detect the output format from the name and fourcc code. */
2002
2003
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
2004
fmt = av_guess_format(NULL, filename, NULL);
2005
#else
2006
fmt = guess_format(NULL, filename, NULL);
2007
#endif
2008
2009
if (!fmt)
2010
return false;
2011
2012
/* determine optimal pixel format */
2013
if (is_color) {
2014
input_pix_fmt = AV_PIX_FMT_BGR24;
2015
}
2016
else {
2017
input_pix_fmt = AV_PIX_FMT_GRAY8;
2018
}
2019
2020
/* Lookup codec_id for given fourcc */
2021
#if LIBAVCODEC_VERSION_INT<((51<<16)+(49<<8)+0)
2022
if( (codec_id = codec_get_bmp_id( fourcc )) == CV_CODEC(CODEC_ID_NONE) )
2023
return false;
2024
#else
2025
if( (codec_id = av_codec_get_id(fmt->codec_tag, fourcc)) == CV_CODEC(CODEC_ID_NONE) )
2026
{
2027
const struct AVCodecTag * fallback_tags[] = {
2028
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(54, 1, 0)
2029
// APIchanges:
2030
// 2012-01-31 - dd6d3b0 - lavf 54.01.0
2031
// Add avformat_get_riff_video_tags() and avformat_get_riff_audio_tags().
2032
avformat_get_riff_video_tags(),
2033
#endif
2034
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(55, 25, 100) && defined LIBAVFORMAT_VERSION_MICRO && LIBAVFORMAT_VERSION_MICRO >= 100
2035
// APIchanges: ffmpeg only
2036
// 2014-01-19 - 1a193c4 - lavf 55.25.100 - avformat.h
2037
// Add avformat_get_mov_video_tags() and avformat_get_mov_audio_tags().
2038
avformat_get_mov_video_tags(),
2039
#endif
2040
codec_bmp_tags, // fallback for avformat < 54.1
2041
NULL };
2042
if( (codec_id = av_codec_get_id(fallback_tags, fourcc)) == CV_CODEC(CODEC_ID_NONE) )
2043
{
2044
fflush(stdout);
2045
fprintf(stderr, "OpenCV: FFMPEG: tag 0x%08x/'%c%c%c%c' is not found (format '%s / %s')'\n",
2046
fourcc, CV_TAG_TO_PRINTABLE_CHAR4(fourcc),
2047
fmt->name, fmt->long_name);
2048
return false;
2049
}
2050
}
2051
// validate tag
2052
if (cv_ff_codec_tag_list_match(fmt->codec_tag, codec_id, fourcc) == false)
2053
{
2054
fflush(stdout);
2055
fprintf(stderr, "OpenCV: FFMPEG: tag 0x%08x/'%c%c%c%c' is not supported with codec id %d and format '%s / %s'\n",
2056
fourcc, CV_TAG_TO_PRINTABLE_CHAR4(fourcc),
2057
codec_id, fmt->name, fmt->long_name);
2058
int supported_tag;
2059
if( (supported_tag = av_codec_get_tag(fmt->codec_tag, codec_id)) != 0 )
2060
{
2061
fprintf(stderr, "OpenCV: FFMPEG: fallback to use tag 0x%08x/'%c%c%c%c'\n",
2062
supported_tag, CV_TAG_TO_PRINTABLE_CHAR4(supported_tag));
2063
fourcc = supported_tag;
2064
}
2065
}
2066
#endif
2067
2068
// alloc memory for context
2069
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
2070
oc = avformat_alloc_context();
2071
#else
2072
oc = av_alloc_format_context();
2073
#endif
2074
assert (oc);
2075
2076
/* set file name */
2077
oc->oformat = fmt;
2078
snprintf(oc->filename, sizeof(oc->filename), "%s", filename);
2079
2080
/* set some options */
2081
oc->max_delay = (int)(0.7*AV_TIME_BASE); /* This reduces buffer underrun warnings with MPEG */
2082
2083
// set a few optimal pixel formats for lossless codecs of interest..
2084
switch (codec_id) {
2085
#if LIBAVCODEC_VERSION_INT>((50<<16)+(1<<8)+0)
2086
case CV_CODEC(CODEC_ID_JPEGLS):
2087
// BGR24 or GRAY8 depending on is_color...
2088
codec_pix_fmt = input_pix_fmt;
2089
break;
2090
#endif
2091
case CV_CODEC(CODEC_ID_HUFFYUV):
2092
codec_pix_fmt = AV_PIX_FMT_YUV422P;
2093
break;
2094
case CV_CODEC(CODEC_ID_MJPEG):
2095
case CV_CODEC(CODEC_ID_LJPEG):
2096
codec_pix_fmt = AV_PIX_FMT_YUVJ420P;
2097
bitrate_scale = 3;
2098
break;
2099
case CV_CODEC(CODEC_ID_RAWVIDEO):
2100
codec_pix_fmt = input_pix_fmt == AV_PIX_FMT_GRAY8 ||
2101
input_pix_fmt == AV_PIX_FMT_GRAY16LE ||
2102
input_pix_fmt == AV_PIX_FMT_GRAY16BE ? input_pix_fmt : AV_PIX_FMT_YUV420P;
2103
break;
2104
default:
2105
// good for lossy formats, MPEG, etc.
2106
codec_pix_fmt = AV_PIX_FMT_YUV420P;
2107
break;
2108
}
2109
2110
double bitrate = MIN(bitrate_scale*fps*width*height, (double)INT_MAX/2);
2111
2112
// TODO -- safe to ignore output audio stream?
2113
video_st = icv_add_video_stream_FFMPEG(oc, codec_id,
2114
width, height, (int)(bitrate + 0.5),
2115
fps, codec_pix_fmt);
2116
2117
/* set the output parameters (must be done even if no
2118
parameters). */
2119
#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
2120
if (av_set_parameters(oc, NULL) < 0) {
2121
return false;
2122
}
2123
#endif
2124
2125
#if 0
2126
#if FF_API_DUMP_FORMAT
2127
dump_format(oc, 0, filename, 1);
2128
#else
2129
av_dump_format(oc, 0, filename, 1);
2130
#endif
2131
#endif
2132
2133
/* now that all the parameters are set, we can open the audio and
2134
video codecs and allocate the necessary encode buffers */
2135
if (!video_st){
2136
return false;
2137
}
2138
2139
AVCodec *codec;
2140
AVCodecContext *c;
2141
2142
#if LIBAVFORMAT_BUILD > 4628
2143
c = (video_st->codec);
2144
#else
2145
c = &(video_st->codec);
2146
#endif
2147
2148
c->codec_tag = fourcc;
2149
/* find the video encoder */
2150
codec = avcodec_find_encoder(c->codec_id);
2151
if (!codec) {
2152
fprintf(stderr, "Could not find encoder for codec id %d: %s\n", c->codec_id, icvFFMPEGErrStr(
2153
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
2154
AVERROR_ENCODER_NOT_FOUND
2155
#else
2156
-1
2157
#endif
2158
));
2159
return false;
2160
}
2161
2162
int64_t lbit_rate = (int64_t)c->bit_rate;
2163
lbit_rate += (bitrate / 2);
2164
lbit_rate = std::min(lbit_rate, (int64_t)INT_MAX);
2165
c->bit_rate_tolerance = (int)lbit_rate;
2166
c->bit_rate = (int)lbit_rate;
2167
2168
/* open the codec */
2169
if ((err=
2170
#if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0)
2171
avcodec_open2(c, codec, NULL)
2172
#else
2173
avcodec_open(c, codec)
2174
#endif
2175
) < 0) {
2176
fprintf(stderr, "Could not open codec '%s': %s\n", codec->name, icvFFMPEGErrStr(err));
2177
return false;
2178
}
2179
2180
outbuf = NULL;
2181
2182
2183
#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(57, 0, 0)
2184
if (!(oc->oformat->flags & AVFMT_RAWPICTURE))
2185
#endif
2186
{
2187
/* allocate output buffer */
2188
/* assume we will never get codec output with more than 4 bytes per pixel... */
2189
outbuf_size = width*height*4;
2190
outbuf = (uint8_t *) av_malloc(outbuf_size);
2191
}
2192
2193
bool need_color_convert;
2194
need_color_convert = (c->pix_fmt != input_pix_fmt);
2195
2196
/* allocate the encoded raw picture */
2197
picture = icv_alloc_picture_FFMPEG(c->pix_fmt, c->width, c->height, need_color_convert);
2198
if (!picture) {
2199
return false;
2200
}
2201
2202
/* if the output format is not our input format, then a temporary
2203
picture of the input format is needed too. It is then converted
2204
to the required output format */
2205
input_picture = NULL;
2206
if ( need_color_convert ) {
2207
input_picture = icv_alloc_picture_FFMPEG(input_pix_fmt, c->width, c->height, false);
2208
if (!input_picture) {
2209
return false;
2210
}
2211
}
2212
2213
/* open the output file, if needed */
2214
if (!(fmt->flags & AVFMT_NOFILE)) {
2215
#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
2216
if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0)
2217
#else
2218
if (avio_open(&oc->pb, filename, AVIO_FLAG_WRITE) < 0)
2219
#endif
2220
{
2221
return false;
2222
}
2223
}
2224
2225
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(52, 111, 0)
2226
/* write the stream header, if any */
2227
err=avformat_write_header(oc, NULL);
2228
#else
2229
err=av_write_header( oc );
2230
#endif
2231
2232
if(err < 0)
2233
{
2234
close();
2235
remove(filename);
2236
return false;
2237
}
2238
frame_width = width;
2239
frame_height = height;
2240
frame_idx = 0;
2241
ok = true;
2242
2243
return true;
2244
}
2245
2246
2247
2248
CvCapture_FFMPEG* cvCreateFileCapture_FFMPEG( const char* filename )
2249
{
2250
CvCapture_FFMPEG* capture = (CvCapture_FFMPEG*)malloc(sizeof(*capture));
2251
if (!capture)
2252
return 0;
2253
capture->init();
2254
if( capture->open( filename ))
2255
return capture;
2256
2257
capture->close();
2258
free(capture);
2259
return 0;
2260
}
2261
2262
2263
void cvReleaseCapture_FFMPEG(CvCapture_FFMPEG** capture)
2264
{
2265
if( capture && *capture )
2266
{
2267
(*capture)->close();
2268
free(*capture);
2269
*capture = 0;
2270
}
2271
}
2272
2273
int cvSetCaptureProperty_FFMPEG(CvCapture_FFMPEG* capture, int prop_id, double value)
2274
{
2275
return capture->setProperty(prop_id, value);
2276
}
2277
2278
double cvGetCaptureProperty_FFMPEG(CvCapture_FFMPEG* capture, int prop_id)
2279
{
2280
return capture->getProperty(prop_id);
2281
}
2282
2283
int cvGrabFrame_FFMPEG(CvCapture_FFMPEG* capture)
2284
{
2285
return capture->grabFrame();
2286
}
2287
2288
int cvRetrieveFrame_FFMPEG(CvCapture_FFMPEG* capture, unsigned char** data, int* step, int* width, int* height, int* cn)
2289
{
2290
return capture->retrieveFrame(0, data, step, width, height, cn);
2291
}
2292
2293
CvVideoWriter_FFMPEG* cvCreateVideoWriter_FFMPEG( const char* filename, int fourcc, double fps,
2294
int width, int height, int isColor )
2295
{
2296
CvVideoWriter_FFMPEG* writer = (CvVideoWriter_FFMPEG*)malloc(sizeof(*writer));
2297
if (!writer)
2298
return 0;
2299
writer->init();
2300
if( writer->open( filename, fourcc, fps, width, height, isColor != 0 ))
2301
return writer;
2302
writer->close();
2303
free(writer);
2304
return 0;
2305
}
2306
2307
void cvReleaseVideoWriter_FFMPEG( CvVideoWriter_FFMPEG** writer )
2308
{
2309
if( writer && *writer )
2310
{
2311
(*writer)->close();
2312
free(*writer);
2313
*writer = 0;
2314
}
2315
}
2316
2317
2318
int cvWriteFrame_FFMPEG( CvVideoWriter_FFMPEG* writer,
2319
const unsigned char* data, int step,
2320
int width, int height, int cn, int origin)
2321
{
2322
return writer->writeFrame(data, step, width, height, cn, origin);
2323
}
2324
2325
2326
2327
/*
2328
* For CUDA encoder
2329
*/
2330
2331
struct OutputMediaStream_FFMPEG
2332
{
2333
bool open(const char* fileName, int width, int height, double fps);
2334
void close();
2335
2336
void write(unsigned char* data, int size, int keyFrame);
2337
2338
// add a video output stream to the container
2339
static AVStream* addVideoStream(AVFormatContext *oc, CV_CODEC_ID codec_id, int w, int h, int bitrate, double fps, AVPixelFormat pixel_format);
2340
2341
AVOutputFormat* fmt_;
2342
AVFormatContext* oc_;
2343
AVStream* video_st_;
2344
};
2345
2346
void OutputMediaStream_FFMPEG::close()
2347
{
2348
// no more frame to compress. The codec has a latency of a few
2349
// frames if using B frames, so we get the last frames by
2350
// passing the same picture again
2351
2352
// TODO -- do we need to account for latency here?
2353
2354
if (oc_)
2355
{
2356
// write the trailer, if any
2357
av_write_trailer(oc_);
2358
2359
// free the streams
2360
for (unsigned int i = 0; i < oc_->nb_streams; ++i)
2361
{
2362
av_freep(&oc_->streams[i]->codec);
2363
av_freep(&oc_->streams[i]);
2364
}
2365
2366
if (!(fmt_->flags & AVFMT_NOFILE) && oc_->pb)
2367
{
2368
// close the output file
2369
2370
#if LIBAVCODEC_VERSION_INT < ((52<<16)+(123<<8)+0)
2371
#if LIBAVCODEC_VERSION_INT >= ((51<<16)+(49<<8)+0)
2372
url_fclose(oc_->pb);
2373
#else
2374
url_fclose(&oc_->pb);
2375
#endif
2376
#else
2377
avio_close(oc_->pb);
2378
#endif
2379
}
2380
2381
// free the stream
2382
av_free(oc_);
2383
}
2384
}
2385
2386
AVStream* OutputMediaStream_FFMPEG::addVideoStream(AVFormatContext *oc, CV_CODEC_ID codec_id, int w, int h, int bitrate, double fps, AVPixelFormat pixel_format)
2387
{
2388
AVCodec* codec = avcodec_find_encoder(codec_id);
2389
if (!codec)
2390
{
2391
fprintf(stderr, "Could not find encoder for codec id %d\n", codec_id);
2392
return NULL;
2393
}
2394
2395
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 10, 0)
2396
AVStream* st = avformat_new_stream(oc, 0);
2397
#else
2398
AVStream* st = av_new_stream(oc, 0);
2399
#endif
2400
if (!st)
2401
return 0;
2402
2403
#if LIBAVFORMAT_BUILD > 4628
2404
AVCodecContext* c = st->codec;
2405
#else
2406
AVCodecContext* c = &(st->codec);
2407
#endif
2408
2409
c->codec_id = codec_id;
2410
c->codec_type = AVMEDIA_TYPE_VIDEO;
2411
2412
// put sample parameters
2413
c->bit_rate = bitrate;
2414
2415
// took advice from
2416
// http://ffmpeg-users.933282.n4.nabble.com/warning-clipping-1-dct-coefficients-to-127-127-td934297.html
2417
c->qmin = 3;
2418
2419
// resolution must be a multiple of two
2420
c->width = w;
2421
c->height = h;
2422
2423
// time base: this is the fundamental unit of time (in seconds) in terms
2424
// of which frame timestamps are represented. for fixed-fps content,
2425
// timebase should be 1/framerate and timestamp increments should be
2426
// identically 1
2427
2428
int frame_rate = static_cast<int>(fps+0.5);
2429
int frame_rate_base = 1;
2430
while (fabs((static_cast<double>(frame_rate)/frame_rate_base) - fps) > 0.001)
2431
{
2432
frame_rate_base *= 10;
2433
frame_rate = static_cast<int>(fps*frame_rate_base + 0.5);
2434
}
2435
c->time_base.den = frame_rate;
2436
c->time_base.num = frame_rate_base;
2437
2438
#if LIBAVFORMAT_BUILD > 4752
2439
// adjust time base for supported framerates
2440
if (codec && codec->supported_framerates)
2441
{
2442
AVRational req = {frame_rate, frame_rate_base};
2443
const AVRational* best = NULL;
2444
AVRational best_error = {INT_MAX, 1};
2445
2446
for (const AVRational* p = codec->supported_framerates; p->den!=0; ++p)
2447
{
2448
AVRational error = av_sub_q(req, *p);
2449
2450
if (error.num < 0)
2451
error.num *= -1;
2452
2453
if (av_cmp_q(error, best_error) < 0)
2454
{
2455
best_error= error;
2456
best= p;
2457
}
2458
}
2459
2460
if (best == NULL)
2461
return NULL;
2462
c->time_base.den= best->num;
2463
c->time_base.num= best->den;
2464
}
2465
#endif
2466
2467
c->gop_size = 12; // emit one intra frame every twelve frames at most
2468
c->pix_fmt = pixel_format;
2469
2470
if (c->codec_id == CV_CODEC(CODEC_ID_MPEG2VIDEO))
2471
c->max_b_frames = 2;
2472
2473
if (c->codec_id == CV_CODEC(CODEC_ID_MPEG1VIDEO) || c->codec_id == CV_CODEC(CODEC_ID_MSMPEG4V3))
2474
{
2475
// needed to avoid using macroblocks in which some coeffs overflow
2476
// this doesn't happen with normal video, it just happens here as the
2477
// motion of the chroma plane doesn't match the luma plane
2478
2479
// avoid FFMPEG warning 'clipping 1 dct coefficients...'
2480
2481
c->mb_decision = 2;
2482
}
2483
2484
#if LIBAVCODEC_VERSION_INT > 0x000409
2485
// some formats want stream headers to be separate
2486
if (oc->oformat->flags & AVFMT_GLOBALHEADER)
2487
{
2488
#if LIBAVCODEC_BUILD > CALC_FFMPEG_VERSION(56, 35, 0)
2489
c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
2490
#else
2491
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
2492
#endif
2493
}
2494
#endif
2495
2496
return st;
2497
}
2498
2499
bool OutputMediaStream_FFMPEG::open(const char* fileName, int width, int height, double fps)
2500
{
2501
fmt_ = 0;
2502
oc_ = 0;
2503
video_st_ = 0;
2504
2505
// auto detect the output format from the name and fourcc code
2506
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
2507
fmt_ = av_guess_format(NULL, fileName, NULL);
2508
#else
2509
fmt_ = guess_format(NULL, fileName, NULL);
2510
#endif
2511
if (!fmt_)
2512
return false;
2513
2514
CV_CODEC_ID codec_id = CV_CODEC(CODEC_ID_H264);
2515
2516
// alloc memory for context
2517
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0)
2518
oc_ = avformat_alloc_context();
2519
#else
2520
oc_ = av_alloc_format_context();
2521
#endif
2522
if (!oc_)
2523
return false;
2524
2525
// set some options
2526
oc_->oformat = fmt_;
2527
snprintf(oc_->filename, sizeof(oc_->filename), "%s", fileName);
2528
2529
oc_->max_delay = (int)(0.7 * AV_TIME_BASE); // This reduces buffer underrun warnings with MPEG
2530
2531
// set a few optimal pixel formats for lossless codecs of interest..
2532
AVPixelFormat codec_pix_fmt = AV_PIX_FMT_YUV420P;
2533
int bitrate_scale = 64;
2534
2535
// TODO -- safe to ignore output audio stream?
2536
video_st_ = addVideoStream(oc_, codec_id, width, height, width * height * bitrate_scale, fps, codec_pix_fmt);
2537
if (!video_st_)
2538
return false;
2539
2540
// set the output parameters (must be done even if no parameters)
2541
#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
2542
if (av_set_parameters(oc_, NULL) < 0)
2543
return false;
2544
#endif
2545
2546
// now that all the parameters are set, we can open the audio and
2547
// video codecs and allocate the necessary encode buffers
2548
2549
#if LIBAVFORMAT_BUILD > 4628
2550
AVCodecContext* c = (video_st_->codec);
2551
#else
2552
AVCodecContext* c = &(video_st_->codec);
2553
#endif
2554
2555
c->codec_tag = MKTAG('H', '2', '6', '4');
2556
c->bit_rate_tolerance = c->bit_rate;
2557
2558
// open the output file, if needed
2559
if (!(fmt_->flags & AVFMT_NOFILE))
2560
{
2561
#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
2562
int err = url_fopen(&oc_->pb, fileName, URL_WRONLY);
2563
#else
2564
int err = avio_open(&oc_->pb, fileName, AVIO_FLAG_WRITE);
2565
#endif
2566
2567
if (err != 0)
2568
return false;
2569
}
2570
2571
// write the stream header, if any
2572
int header_err =
2573
#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0)
2574
av_write_header(oc_);
2575
#else
2576
avformat_write_header(oc_, NULL);
2577
#endif
2578
if (header_err != 0)
2579
return false;
2580
2581
return true;
2582
}
2583
2584
void OutputMediaStream_FFMPEG::write(unsigned char* data, int size, int keyFrame)
2585
{
2586
// if zero size, it means the image was buffered
2587
if (size > 0)
2588
{
2589
AVPacket pkt;
2590
av_init_packet(&pkt);
2591
2592
if (keyFrame)
2593
pkt.flags |= PKT_FLAG_KEY;
2594
2595
pkt.stream_index = video_st_->index;
2596
pkt.data = data;
2597
pkt.size = size;
2598
2599
// write the compressed frame in the media file
2600
av_write_frame(oc_, &pkt);
2601
}
2602
}
2603
2604
struct OutputMediaStream_FFMPEG* create_OutputMediaStream_FFMPEG(const char* fileName, int width, int height, double fps)
2605
{
2606
OutputMediaStream_FFMPEG* stream = (OutputMediaStream_FFMPEG*) malloc(sizeof(OutputMediaStream_FFMPEG));
2607
if (!stream)
2608
return 0;
2609
2610
if (stream->open(fileName, width, height, fps))
2611
return stream;
2612
2613
stream->close();
2614
free(stream);
2615
2616
return 0;
2617
}
2618
2619
void release_OutputMediaStream_FFMPEG(struct OutputMediaStream_FFMPEG* stream)
2620
{
2621
stream->close();
2622
free(stream);
2623
}
2624
2625
void write_OutputMediaStream_FFMPEG(struct OutputMediaStream_FFMPEG* stream, unsigned char* data, int size, int keyFrame)
2626
{
2627
stream->write(data, size, keyFrame);
2628
}
2629
2630
/*
2631
* For CUDA decoder
2632
*/
2633
2634
enum
2635
{
2636
VideoCodec_MPEG1 = 0,
2637
VideoCodec_MPEG2,
2638
VideoCodec_MPEG4,
2639
VideoCodec_VC1,
2640
VideoCodec_H264,
2641
VideoCodec_JPEG,
2642
VideoCodec_H264_SVC,
2643
VideoCodec_H264_MVC,
2644
2645
// Uncompressed YUV
2646
VideoCodec_YUV420 = (('I'<<24)|('Y'<<16)|('U'<<8)|('V')), // Y,U,V (4:2:0)
2647
VideoCodec_YV12 = (('Y'<<24)|('V'<<16)|('1'<<8)|('2')), // Y,V,U (4:2:0)
2648
VideoCodec_NV12 = (('N'<<24)|('V'<<16)|('1'<<8)|('2')), // Y,UV (4:2:0)
2649
VideoCodec_YUYV = (('Y'<<24)|('U'<<16)|('Y'<<8)|('V')), // YUYV/YUY2 (4:2:2)
2650
VideoCodec_UYVY = (('U'<<24)|('Y'<<16)|('V'<<8)|('Y')) // UYVY (4:2:2)
2651
};
2652
2653
enum
2654
{
2655
VideoChromaFormat_Monochrome = 0,
2656
VideoChromaFormat_YUV420,
2657
VideoChromaFormat_YUV422,
2658
VideoChromaFormat_YUV444
2659
};
2660
2661
struct InputMediaStream_FFMPEG
2662
{
2663
public:
2664
bool open(const char* fileName, int* codec, int* chroma_format, int* width, int* height);
2665
void close();
2666
2667
bool read(unsigned char** data, int* size, int* endOfFile);
2668
2669
private:
2670
InputMediaStream_FFMPEG(const InputMediaStream_FFMPEG&);
2671
InputMediaStream_FFMPEG& operator =(const InputMediaStream_FFMPEG&);
2672
2673
AVFormatContext* ctx_;
2674
int video_stream_id_;
2675
AVPacket pkt_;
2676
2677
#if USE_AV_INTERRUPT_CALLBACK
2678
AVInterruptCallbackMetadata interrupt_metadata;
2679
#endif
2680
};
2681
2682
bool InputMediaStream_FFMPEG::open(const char* fileName, int* codec, int* chroma_format, int* width, int* height)
2683
{
2684
int err;
2685
2686
ctx_ = 0;
2687
video_stream_id_ = -1;
2688
memset(&pkt_, 0, sizeof(AVPacket));
2689
2690
#if USE_AV_INTERRUPT_CALLBACK
2691
/* interrupt callback */
2692
interrupt_metadata.timeout_after_ms = LIBAVFORMAT_INTERRUPT_OPEN_TIMEOUT_MS;
2693
get_monotonic_time(&interrupt_metadata.value);
2694
2695
ctx_ = avformat_alloc_context();
2696
ctx_->interrupt_callback.callback = _opencv_ffmpeg_interrupt_callback;
2697
ctx_->interrupt_callback.opaque = &interrupt_metadata;
2698
#endif
2699
2700
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0)
2701
avformat_network_init();
2702
#endif
2703
2704
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 6, 0)
2705
err = avformat_open_input(&ctx_, fileName, 0, 0);
2706
#else
2707
err = av_open_input_file(&ctx_, fileName, 0, 0, 0);
2708
#endif
2709
if (err < 0)
2710
return false;
2711
2712
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 6, 0)
2713
err = avformat_find_stream_info(ctx_, 0);
2714
#else
2715
err = av_find_stream_info(ctx_);
2716
#endif
2717
if (err < 0)
2718
return false;
2719
2720
for (unsigned int i = 0; i < ctx_->nb_streams; ++i)
2721
{
2722
#if LIBAVFORMAT_BUILD > 4628
2723
AVCodecContext *enc = ctx_->streams[i]->codec;
2724
#else
2725
AVCodecContext *enc = &ctx_->streams[i]->codec;
2726
#endif
2727
2728
if (enc->codec_type == AVMEDIA_TYPE_VIDEO)
2729
{
2730
video_stream_id_ = static_cast<int>(i);
2731
2732
switch (enc->codec_id)
2733
{
2734
case CV_CODEC(CODEC_ID_MPEG1VIDEO):
2735
*codec = ::VideoCodec_MPEG1;
2736
break;
2737
2738
case CV_CODEC(CODEC_ID_MPEG2VIDEO):
2739
*codec = ::VideoCodec_MPEG2;
2740
break;
2741
2742
case CV_CODEC(CODEC_ID_MPEG4):
2743
*codec = ::VideoCodec_MPEG4;
2744
break;
2745
2746
case CV_CODEC(CODEC_ID_VC1):
2747
*codec = ::VideoCodec_VC1;
2748
break;
2749
2750
case CV_CODEC(CODEC_ID_H264):
2751
*codec = ::VideoCodec_H264;
2752
break;
2753
2754
default:
2755
return false;
2756
};
2757
2758
switch (enc->pix_fmt)
2759
{
2760
case AV_PIX_FMT_YUV420P:
2761
*chroma_format = ::VideoChromaFormat_YUV420;
2762
break;
2763
2764
case AV_PIX_FMT_YUV422P:
2765
*chroma_format = ::VideoChromaFormat_YUV422;
2766
break;
2767
2768
case AV_PIX_FMT_YUV444P:
2769
*chroma_format = ::VideoChromaFormat_YUV444;
2770
break;
2771
2772
default:
2773
return false;
2774
}
2775
2776
*width = enc->coded_width;
2777
*height = enc->coded_height;
2778
2779
break;
2780
}
2781
}
2782
2783
if (video_stream_id_ < 0)
2784
return false;
2785
2786
av_init_packet(&pkt_);
2787
2788
#if USE_AV_INTERRUPT_CALLBACK
2789
// deactivate interrupt callback
2790
interrupt_metadata.timeout_after_ms = 0;
2791
#endif
2792
2793
return true;
2794
}
2795
2796
void InputMediaStream_FFMPEG::close()
2797
{
2798
if (ctx_)
2799
{
2800
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 24, 2)
2801
avformat_close_input(&ctx_);
2802
#else
2803
av_close_input_file(ctx_);
2804
#endif
2805
}
2806
2807
// free last packet if exist
2808
if (pkt_.data)
2809
_opencv_ffmpeg_av_packet_unref(&pkt_);
2810
}
2811
2812
bool InputMediaStream_FFMPEG::read(unsigned char** data, int* size, int* endOfFile)
2813
{
2814
bool result = false;
2815
2816
#if USE_AV_INTERRUPT_CALLBACK
2817
// activate interrupt callback
2818
get_monotonic_time(&interrupt_metadata.value);
2819
interrupt_metadata.timeout_after_ms = LIBAVFORMAT_INTERRUPT_READ_TIMEOUT_MS;
2820
#endif
2821
2822
// free last packet if exist
2823
if (pkt_.data)
2824
_opencv_ffmpeg_av_packet_unref(&pkt_);
2825
2826
// get the next frame
2827
for (;;)
2828
{
2829
#if USE_AV_INTERRUPT_CALLBACK
2830
if(interrupt_metadata.timeout)
2831
{
2832
break;
2833
}
2834
#endif
2835
2836
int ret = av_read_frame(ctx_, &pkt_);
2837
2838
if (ret == AVERROR(EAGAIN))
2839
continue;
2840
2841
if (ret < 0)
2842
{
2843
if (ret == (int)AVERROR_EOF)
2844
*endOfFile = true;
2845
break;
2846
}
2847
2848
if (pkt_.stream_index != video_stream_id_)
2849
{
2850
_opencv_ffmpeg_av_packet_unref(&pkt_);
2851
continue;
2852
}
2853
2854
result = true;
2855
break;
2856
}
2857
2858
#if USE_AV_INTERRUPT_CALLBACK
2859
// deactivate interrupt callback
2860
interrupt_metadata.timeout_after_ms = 0;
2861
#endif
2862
2863
if (result)
2864
{
2865
*data = pkt_.data;
2866
*size = pkt_.size;
2867
*endOfFile = false;
2868
}
2869
2870
return result;
2871
}
2872
2873
InputMediaStream_FFMPEG* create_InputMediaStream_FFMPEG(const char* fileName, int* codec, int* chroma_format, int* width, int* height)
2874
{
2875
InputMediaStream_FFMPEG* stream = (InputMediaStream_FFMPEG*) malloc(sizeof(InputMediaStream_FFMPEG));
2876
if (!stream)
2877
return 0;
2878
2879
if (stream && stream->open(fileName, codec, chroma_format, width, height))
2880
return stream;
2881
2882
stream->close();
2883
free(stream);
2884
2885
return 0;
2886
}
2887
2888
void release_InputMediaStream_FFMPEG(InputMediaStream_FFMPEG* stream)
2889
{
2890
stream->close();
2891
free(stream);
2892
}
2893
2894
int read_InputMediaStream_FFMPEG(InputMediaStream_FFMPEG* stream, unsigned char** data, int* size, int* endOfFile)
2895
{
2896
return stream->read(data, size, endOfFile);
2897
}
2898
2899