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