1 // Copyright 2008-present Contributors to the OpenImageIO project.
2 // SPDX-License-Identifier: BSD-3-Clause
3 // https://github.com/OpenImageIO/oiio/blob/master/LICENSE.md
4 
5 extern "C" {  // ffmpeg is a C api
6 #include <cerrno>
7 #include <libavcodec/avcodec.h>
8 #include <libavformat/avformat.h>
9 #include <libswscale/swscale.h>
10 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 24, 0)
11 #    include <libavutil/imgutils.h>
12 #endif
13 }
14 
15 // It's hard to figure out FFMPEG versions from what they give us, so
16 // record some of the milestones once and for all for easy reference.
17 #define USE_FFMPEG_2_6 (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 26, 100))
18 #define USE_FFMPEG_2_7 (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 41, 100))
19 #define USE_FFMPEG_2_8 (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 60, 100))
20 #define USE_FFMPEG_3_0 (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 24, 100))
21 #define USE_FFMPEG_3_1 (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 48, 100))
22 #define USE_FFMPEG_3_2 (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 64, 100))
23 #define USE_FFMPEG_3_3 (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 89, 100))
24 #define USE_FFMPEG_3_4 (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 107, 100))
25 #define USE_FFMPEG_4_0 (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58, 18, 100))
26 #define USE_FFMPEG_4_1 (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58, 35, 100))
27 #define USE_FFMPEG_4_2 (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58, 54, 100))
28 #define USE_FFMPEG_4_3 (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58, 91, 100))
29 #define USE_FFMPEG_4_4 (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58, 134, 100))
30 
31 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55, 28, 1)
32 #    define av_frame_alloc avcodec_alloc_frame
33 //Ancient versions used av_freep
34 #    if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(54, 59, 100)
35 #        define av_frame_free av_freep
36 #    else
37 #        define av_frame_free avcodec_free_frame
38 #    endif
39 #endif
40 
41 // PIX_FMT was renamed to AV_PIX_FMT on this version
42 #if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(51, 74, 100)
43 #    define AVPixelFormat PixelFormat
44 #    define AV_PIX_FMT_RGB24 PIX_FMT_RGB24
45 #    define AV_PIX_FMT_RGB48 PIX_FMT_RGB48
46 #    define AV_PIX_FMT_YUVJ420P PIX_FMT_YUVJ420P
47 #    define AV_PIX_FMT_YUVJ422P PIX_FMT_YUVJ422P
48 #    define AV_PIX_FMT_YUVJ440P PIX_FMT_YUVJ440P
49 #    define AV_PIX_FMT_YUVJ444P PIX_FMT_YUVJ444P
50 #    define AV_PIX_FMT_YUV420P PIX_FMT_YUV420P
51 #    define AV_PIX_FMT_YUV422P PIX_FMT_YUV422P
52 #    define AV_PIX_FMT_YUV440P PIX_FMT_YUV440P
53 #    define AV_PIX_FMT_YUV444P PIX_FMT_YUV444P
54 #endif
55 
56 // r_frame_rate deprecated in ffmpeg
57 // see ffmpeg commit #aba232c for details
58 #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 42, 0)
59 #    define r_frame_rate avg_frame_rate
60 #endif
61 
62 #if USE_FFMPEG_3_0
63 #    define av_free_packet av_packet_unref
64 #    define avpicture_get_size(fmt, w, h) av_image_get_buffer_size(fmt, w, h, 1)
65 
66 inline int
avpicture_fill(AVPicture * picture,uint8_t * ptr,enum AVPixelFormat pix_fmt,int width,int height)67 avpicture_fill(AVPicture* picture, uint8_t* ptr, enum AVPixelFormat pix_fmt,
68                int width, int height)
69 {
70     AVFrame* frame = reinterpret_cast<AVFrame*>(picture);
71     return av_image_fill_arrays(frame->data, frame->linesize, ptr, pix_fmt,
72                                 width, height, 1);
73 }
74 #endif
75 
76 #if USE_FFMPEG_3_1
77 // AVStream::codec was changed to AVStream::codecpar
78 #    define stream_codec(ix) m_format_context->streams[(ix)]->codecpar
79 // avcodec_decode_video2 was deprecated.
80 // This now works by sending `avpkt` to the decoder, which buffers the
81 // decoded image in `avctx`. Then `avcodec_receive_frame` will copy the
82 // frame to `picture`.
83 inline int
receive_frame(AVCodecContext * avctx,AVFrame * picture,AVPacket * avpkt)84 receive_frame(AVCodecContext* avctx, AVFrame* picture, AVPacket* avpkt)
85 {
86     int ret;
87 
88     ret = avcodec_send_packet(avctx, avpkt);
89 
90     if (ret < 0)
91         return 0;
92 
93     ret = avcodec_receive_frame(avctx, picture);
94 
95     if (ret < 0)
96         return 0;
97 
98     return 1;
99 }
100 #else
101 #    define stream_codec(ix) m_format_context->streams[(ix)]->codec
102 inline int
receive_frame(AVCodecContext * avctx,AVFrame * picture,AVPacket * avpkt)103 receive_frame(AVCodecContext* avctx, AVFrame* picture, AVPacket* avpkt)
104 {
105     int ret;
106     avcodec_decode_video2(avctx, picture, &ret, avpkt);
107     return ret;
108 }
109 #endif
110 
111 
112 
113 #if (LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 56, 100))
114 #    define CODEC_CAP_DELAY AV_CODEC_CAP_DELAY
115 #endif
116 
117 
118 #include <OpenImageIO/imageio.h>
119 #include <iostream>
120 #include <mutex>
121 
122 OIIO_PLUGIN_NAMESPACE_BEGIN
123 
124 
125 class FFmpegInput final : public ImageInput {
126 public:
127     FFmpegInput();
128     virtual ~FFmpegInput();
format_name(void) const129     virtual const char* format_name(void) const override
130     {
131         return "FFmpeg movie";
132     }
133     virtual bool valid_file(const std::string& name) const override;
134     virtual bool open(const std::string& name, ImageSpec& spec) override;
135     virtual bool close(void) override;
current_subimage(void) const136     virtual int current_subimage(void) const override
137     {
138         lock_guard lock(m_mutex);
139         return m_subimage;
140     }
141     virtual bool seek_subimage(int subimage, int miplevel) override;
142     virtual bool read_native_scanline(int subimage, int miplevel, int y, int z,
143                                       void* data) override;
144     void read_frame(int pos);
145 #if 0
146     const char *metadata (const char * key);
147     bool has_metadata (const char * key);
148 #endif
149     bool seek(int pos);
150     double fps() const;
151     int64_t time_stamp(int pos) const;
152 
153 private:
154     std::string m_filename;
155     int m_subimage;
156     int64_t m_nsubimages;
157     AVFormatContext* m_format_context;
158     AVCodecContext* m_codec_context;
159     AVCodec* m_codec;
160     AVFrame* m_frame;
161     AVFrame* m_rgb_frame;
162     size_t m_stride;  // scanline width in bytes, a.k.a. scanline stride
163     AVPixelFormat m_dst_pix_format;
164     SwsContext* m_sws_rgb_context;
165     AVRational m_frame_rate;
166     std::vector<uint8_t> m_rgb_buffer;
167     std::vector<int> m_video_indexes;
168     int m_video_stream;
169     int64_t m_frames;
170     int m_last_search_pos;
171     int m_last_decoded_pos;
172     bool m_offset_time;
173     bool m_codec_cap_delay;
174     bool m_read_frame;
175     int64_t m_start_time;
176 
177     // init to initialize state
init(void)178     void init(void)
179     {
180         m_filename.clear();
181         m_format_context  = 0;
182         m_codec_context   = 0;
183         m_codec           = 0;
184         m_frame           = 0;
185         m_rgb_frame       = 0;
186         m_sws_rgb_context = 0;
187         m_stride          = 0;
188         m_rgb_buffer.clear();
189         m_video_indexes.clear();
190         m_video_stream     = -1;
191         m_frames           = 0;
192         m_last_search_pos  = 0;
193         m_last_decoded_pos = 0;
194         m_offset_time      = true;
195         m_read_frame       = false;
196         m_codec_cap_delay  = false;
197         m_subimage         = 0;
198         m_start_time       = 0;
199     }
200 };
201 
202 
203 
204 // Obligatory material to make this a recognizeable imageio plugin
205 OIIO_PLUGIN_EXPORTS_BEGIN
206 
207 OIIO_EXPORT int ffmpeg_imageio_version = OIIO_PLUGIN_VERSION;
208 
209 OIIO_EXPORT const char*
ffmpeg_imageio_library_version()210 ffmpeg_imageio_library_version()
211 {
212     return "FFMpeg " OIIO_FFMPEG_VERSION " (" LIBAVFORMAT_IDENT ")";
213 }
214 
215 OIIO_EXPORT ImageInput*
ffmpeg_input_imageio_create()216 ffmpeg_input_imageio_create()
217 {
218     return new FFmpegInput;
219 }
220 // FFmpeg hints:
221 // AVI (Audio Video Interleaved)
222 // QuickTime / MOV
223 // raw MPEG-4 video
224 // MPEG-1 Systems / MPEG program stream
225 OIIO_EXPORT const char* ffmpeg_input_extensions[] = {
226     "avi", "mov", "qt", "mp4", "m4a", "3gp", "3g2", "mj2", "m4v", "mpg", nullptr
227 };
228 
229 
230 OIIO_PLUGIN_EXPORTS_END
231 
232 
233 
FFmpegInput()234 FFmpegInput::FFmpegInput() { init(); }
235 
236 
237 
~FFmpegInput()238 FFmpegInput::~FFmpegInput() { close(); }
239 
240 
241 
242 bool
valid_file(const std::string & name) const243 FFmpegInput::valid_file(const std::string& name) const
244 {
245     // Quick/naive test -- just make sure the extension is valid for one of
246     // the supported file types supported by this reader.
247     for (int i = 0; ffmpeg_input_extensions[i]; ++i)
248         if (Strutil::ends_with(name, ffmpeg_input_extensions[i]))
249             return true;
250     return false;
251 }
252 
253 
254 
255 bool
open(const std::string & name,ImageSpec & spec)256 FFmpegInput::open(const std::string& name, ImageSpec& spec)
257 {
258     // Temporary workaround: refuse to open a file whose name does not
259     // indicate that it's a movie file. This avoids the problem that ffmpeg
260     // is willing to open tiff and other files better handled by other
261     // plugins. The better long-term solution is to replace av_register_all
262     // with our own function that registers only the formats that we want
263     // this reader to handle. At some point, we will institute that superior
264     // approach, but in the mean time, this is a quick solution that 90%
265     // does the job.
266     bool valid_extension = false;
267     for (int i = 0; ffmpeg_input_extensions[i]; ++i)
268         if (Strutil::ends_with(name, ffmpeg_input_extensions[i])) {
269             valid_extension = true;
270             break;
271         }
272     if (!valid_extension) {
273         errorf("\"%s\" could not open input", name);
274         return false;
275     }
276 
277     static std::once_flag init_flag;
278     std::call_once(init_flag, av_register_all);
279     const char* file_name = name.c_str();
280     av_log_set_level(AV_LOG_FATAL);
281     if (avformat_open_input(&m_format_context, file_name, NULL, NULL) != 0) {
282         // avformat_open_input allocs format_context
283         errorf("\"%s\" could not open input", file_name);
284         return false;
285     }
286     if (avformat_find_stream_info(m_format_context, NULL) < 0) {
287         errorf("\"%s\" could not find stream info", file_name);
288         return false;
289     }
290     m_video_stream = -1;
291     for (unsigned int i = 0; i < m_format_context->nb_streams; i++) {
292         if (stream_codec(i)->codec_type == AVMEDIA_TYPE_VIDEO) {
293             if (m_video_stream < 0) {
294                 m_video_stream = i;
295             }
296             m_video_indexes.push_back(i);  // needed for later use
297             break;
298         }
299     }
300     if (m_video_stream == -1) {
301         errorf("\"%s\" could not find a valid videostream", file_name);
302         return false;
303     }
304 
305     // codec context for videostream
306 #if USE_FFMPEG_3_1
307     AVCodecParameters* par = stream_codec(m_video_stream);
308 
309     m_codec = avcodec_find_decoder(par->codec_id);
310     if (!m_codec) {
311         errorf("\"%s\" can't find decoder", file_name);
312         return false;
313     }
314 
315     m_codec_context = avcodec_alloc_context3(m_codec);
316     if (!m_codec_context) {
317         errorf("\"%s\" can't allocate decoder context", file_name);
318         return false;
319     }
320 
321     int ret;
322 
323     ret = avcodec_parameters_to_context(m_codec_context, par);
324     if (ret < 0) {
325         errorf("\"%s\" unsupported codec", file_name);
326         return false;
327     }
328 #else
329     m_codec_context = stream_codec(m_video_stream);
330 
331     m_codec = avcodec_find_decoder(m_codec_context->codec_id);
332     if (!m_codec) {
333         errorf("\"%s\" unsupported codec", file_name);
334         return false;
335     }
336 #endif
337 
338     if (avcodec_open2(m_codec_context, m_codec, NULL) < 0) {
339         errorf("\"%s\" could not open codec", file_name);
340         return false;
341     }
342     if (!strcmp(m_codec_context->codec->name, "mjpeg")
343         || !strcmp(m_codec_context->codec->name, "dvvideo")) {
344         m_offset_time = false;
345     }
346     m_codec_cap_delay = (bool)(m_codec_context->codec->capabilities
347                                & CODEC_CAP_DELAY);
348 
349     AVStream* stream = m_format_context->streams[m_video_stream];
350     if (stream->r_frame_rate.num != 0 && stream->r_frame_rate.den != 0) {
351         m_frame_rate = stream->r_frame_rate;
352     }
353 
354     m_frames     = stream->nb_frames;
355     m_start_time = stream->start_time;
356     if (!m_frames) {
357         seek(0);
358         AVPacket pkt;
359         av_init_packet(&pkt);
360         av_read_frame(m_format_context, &pkt);
361         int64_t first_pts = pkt.pts;
362         int64_t max_pts   = 0;
363         av_free_packet(&pkt);  //because seek(int) uses m_format_context
364         seek(1 << 29);
365         av_init_packet(&pkt);  //Is this needed?
366         while (stream && av_read_frame(m_format_context, &pkt) >= 0) {
367             int64_t current_pts = static_cast<int64_t>(
368                 av_q2d(stream->time_base) * (pkt.pts - first_pts) * fps());
369             if (current_pts > max_pts) {
370                 max_pts = current_pts + 1;
371             }
372             av_free_packet(&pkt);  //Always free before format_context usage
373         }
374         m_frames = max_pts;
375     }
376     m_frame     = av_frame_alloc();
377     m_rgb_frame = av_frame_alloc();
378 
379     AVPixelFormat src_pix_format;
380     switch (m_codec_context->pix_fmt) {  // deprecation warning for YUV formats
381     case AV_PIX_FMT_YUVJ420P: src_pix_format = AV_PIX_FMT_YUV420P; break;
382     case AV_PIX_FMT_YUVJ422P: src_pix_format = AV_PIX_FMT_YUV422P; break;
383     case AV_PIX_FMT_YUVJ444P: src_pix_format = AV_PIX_FMT_YUV444P; break;
384     case AV_PIX_FMT_YUVJ440P: src_pix_format = AV_PIX_FMT_YUV440P; break;
385     default: src_pix_format = m_codec_context->pix_fmt; break;
386     }
387 
388     // Assume by default that we're delivering RGB UINT8
389     int nchannels     = 3;
390     TypeDesc datatype = TypeUInt8;
391     m_dst_pix_format  = AV_PIX_FMT_RGB24;
392     // Look for formats that indicate we should save some different number
393     // of channels or bit depth.
394     switch (src_pix_format) {
395     // support for 10-bit and 12-bit pix_fmts
396     case AV_PIX_FMT_RGB48BE:
397     case AV_PIX_FMT_RGB48LE:
398     case AV_PIX_FMT_BGR48BE:
399     case AV_PIX_FMT_BGR48LE:
400     case AV_PIX_FMT_YUV420P9BE:
401     case AV_PIX_FMT_YUV420P9LE:
402     case AV_PIX_FMT_YUV422P9BE:
403     case AV_PIX_FMT_YUV422P9LE:
404     case AV_PIX_FMT_YUV444P9BE:
405     case AV_PIX_FMT_YUV444P9LE:
406     case AV_PIX_FMT_YUV420P10BE:
407     case AV_PIX_FMT_YUV420P10LE:
408     case AV_PIX_FMT_YUV422P10BE:
409     case AV_PIX_FMT_YUV422P10LE:
410     case AV_PIX_FMT_YUV444P10BE:
411     case AV_PIX_FMT_YUV444P10LE:
412     case AV_PIX_FMT_YUV420P12BE:
413     case AV_PIX_FMT_YUV420P12LE:
414     case AV_PIX_FMT_YUV422P12BE:
415     case AV_PIX_FMT_YUV422P12LE:
416     case AV_PIX_FMT_YUV444P12BE:
417     case AV_PIX_FMT_YUV444P12LE:
418     case AV_PIX_FMT_YUV420P14BE:
419     case AV_PIX_FMT_YUV420P14LE:
420     case AV_PIX_FMT_YUV422P14BE:
421     case AV_PIX_FMT_YUV422P14LE:
422     case AV_PIX_FMT_YUV444P14BE:
423     case AV_PIX_FMT_YUV444P14LE:
424     case AV_PIX_FMT_GBRP9BE:
425     case AV_PIX_FMT_GBRP9LE:
426     case AV_PIX_FMT_GBRP10BE:
427     case AV_PIX_FMT_GBRP10LE:
428     case AV_PIX_FMT_GBRP16BE:
429     case AV_PIX_FMT_GBRP16LE:
430     case AV_PIX_FMT_GBRP12BE:
431     case AV_PIX_FMT_GBRP12LE:
432     case AV_PIX_FMT_GBRP14BE:
433     case AV_PIX_FMT_GBRP14LE:
434     case AV_PIX_FMT_BAYER_BGGR16LE:
435     case AV_PIX_FMT_BAYER_BGGR16BE:
436     case AV_PIX_FMT_BAYER_RGGB16LE:
437     case AV_PIX_FMT_BAYER_RGGB16BE:
438     case AV_PIX_FMT_BAYER_GBRG16LE:
439     case AV_PIX_FMT_BAYER_GBRG16BE:
440     case AV_PIX_FMT_BAYER_GRBG16LE:
441     case AV_PIX_FMT_BAYER_GRBG16BE:
442     case AV_PIX_FMT_GBRAP10BE:
443     case AV_PIX_FMT_GBRAP10LE:
444     case AV_PIX_FMT_GBRAP12BE:
445     case AV_PIX_FMT_GBRAP12LE:
446     case AV_PIX_FMT_P016LE:
447     case AV_PIX_FMT_P016BE:
448         datatype         = TypeUInt16;
449         m_dst_pix_format = AV_PIX_FMT_RGB48;
450         break;
451     // Grayscale 8 bit
452     case AV_PIX_FMT_GRAY8:
453     case AV_PIX_FMT_MONOWHITE:
454     case AV_PIX_FMT_MONOBLACK:
455         datatype         = TypeUInt8;
456         m_dst_pix_format = AV_PIX_FMT_GRAY8;
457         break;
458     // Grayscale 16 bit
459     case AV_PIX_FMT_GRAY9BE:
460     case AV_PIX_FMT_GRAY9LE:
461     case AV_PIX_FMT_GRAY10BE:
462     case AV_PIX_FMT_GRAY10LE:
463     case AV_PIX_FMT_GRAY12BE:
464     case AV_PIX_FMT_GRAY12LE:
465     case AV_PIX_FMT_GRAY16BE:
466     case AV_PIX_FMT_GRAY16LE:
467         datatype         = TypeUInt16;
468         m_dst_pix_format = AV_PIX_FMT_GRAY16;
469         break;
470     // RGBA 8 bit
471     case AV_PIX_FMT_YA8:  // YA, but promote to RGBA because who cares
472     case AV_PIX_FMT_YUVA422P:
473     case AV_PIX_FMT_YUVA444P:
474     case AV_PIX_FMT_GBRAP:
475         nchannels        = 4;
476         datatype         = TypeUInt8;
477         m_dst_pix_format = AV_PIX_FMT_RGBA;
478         break;
479     // RGBA 16 bit
480     case AV_PIX_FMT_YA16:  // YA, but promote to RGBA
481     case AV_PIX_FMT_YUVA420P9BE:
482     case AV_PIX_FMT_YUVA420P9LE:
483     case AV_PIX_FMT_YUVA422P9BE:
484     case AV_PIX_FMT_YUVA422P9LE:
485     case AV_PIX_FMT_YUVA444P9BE:
486     case AV_PIX_FMT_YUVA444P9LE:
487     case AV_PIX_FMT_YUVA420P10BE:
488     case AV_PIX_FMT_YUVA420P10LE:
489     case AV_PIX_FMT_YUVA422P10BE:
490     case AV_PIX_FMT_YUVA422P10LE:
491     case AV_PIX_FMT_YUVA444P10BE:
492     case AV_PIX_FMT_YUVA444P10LE:
493 #if USE_FFMPEG_4_2
494     case AV_PIX_FMT_YUVA422P12BE:
495     case AV_PIX_FMT_YUVA422P12LE:
496     case AV_PIX_FMT_YUVA444P12BE:
497     case AV_PIX_FMT_YUVA444P12LE:
498 #endif
499     case AV_PIX_FMT_YUVA420P16BE:
500     case AV_PIX_FMT_YUVA420P16LE:
501     case AV_PIX_FMT_YUVA422P16BE:
502     case AV_PIX_FMT_YUVA422P16LE:
503     case AV_PIX_FMT_YUVA444P16BE:
504     case AV_PIX_FMT_YUVA444P16LE:
505     case AV_PIX_FMT_GBRAP16:
506         nchannels        = 4;
507         datatype         = TypeUInt16;
508         m_dst_pix_format = AV_PIX_FMT_RGBA64;
509         break;
510     // RGB float
511     case AV_PIX_FMT_GBRPF32BE:
512     case AV_PIX_FMT_GBRPF32LE:
513         nchannels        = 3;
514         datatype         = TypeFloat;
515         m_dst_pix_format = AV_PIX_FMT_RGB48;  // ? AV_PIX_FMT_GBRPF32
516         // FIXME: They don't have a type for RGB float, only GBR float.
517         // Yuck. Punt for now and save as uint16 RGB. If people care, we
518         // can return and ask for GBR float and swap order.
519         break;
520     // RGBA float
521     case AV_PIX_FMT_GBRAPF32BE:
522     case AV_PIX_FMT_GBRAPF32LE:
523         nchannels        = 4;
524         datatype         = TypeFloat;
525         m_dst_pix_format = AV_PIX_FMT_RGBA64;  // ? AV_PIX_FMT_GBRAPF32
526         // FIXME: They don't have a type for RGBA float, only GBRA float.
527         // Yuck. Punt for now and save as uint16 RGB. If people care, we
528         // can return and ask for GBRA float and swap order.
529         break;
530 
531     // Everything else is regular 8 bit RGB
532     default: break;
533     }
534 
535     m_spec   = ImageSpec(m_codec_context->width, m_codec_context->height,
536                        nchannels, datatype);
537     m_stride = (size_t)(m_spec.scanline_bytes());
538 
539     m_rgb_buffer.resize(avpicture_get_size(m_dst_pix_format,
540                                            m_codec_context->width,
541                                            m_codec_context->height),
542                         0);
543 
544     m_sws_rgb_context
545         = sws_getContext(m_codec_context->width, m_codec_context->height,
546                          src_pix_format, m_codec_context->width,
547                          m_codec_context->height, m_dst_pix_format, SWS_AREA,
548                          NULL, NULL, NULL);
549 
550     AVDictionaryEntry* tag = NULL;
551     while ((tag = av_dict_get(m_format_context->metadata, "", tag,
552                               AV_DICT_IGNORE_SUFFIX))) {
553         m_spec.attribute(tag->key, tag->value);
554     }
555     int rat[2] = { m_frame_rate.num, m_frame_rate.den };
556     m_spec.attribute("FramesPerSecond", TypeRational, &rat);
557     m_spec.attribute("oiio:Movie", true);
558     m_spec.attribute("oiio:subimages", int(m_frames));
559     m_spec.attribute("oiio:BitsPerSample",
560                      m_codec_context->bits_per_raw_sample);
561     m_spec.attribute("ffmpeg:codec_name", m_codec_context->codec->long_name);
562     m_nsubimages = m_frames;
563     spec         = m_spec;
564     m_filename   = name;
565     return true;
566 }
567 
568 
569 
570 bool
seek_subimage(int subimage,int miplevel)571 FFmpegInput::seek_subimage(int subimage, int miplevel)
572 {
573     if (subimage < 0 || subimage >= m_nsubimages || miplevel > 0) {
574         return false;
575     }
576     if (subimage == m_subimage) {
577         return true;
578     }
579     m_subimage   = subimage;
580     m_read_frame = false;
581     return true;
582 }
583 
584 
585 
586 bool
read_native_scanline(int subimage,int miplevel,int y,int,void * data)587 FFmpegInput::read_native_scanline(int subimage, int miplevel, int y, int /*z*/,
588                                   void* data)
589 {
590     lock_guard lock(m_mutex);
591     if (!seek_subimage(subimage, miplevel))
592         return false;
593     if (!m_read_frame) {
594         read_frame(m_subimage);
595     }
596     memcpy(data, m_rgb_frame->data[0] + y * m_rgb_frame->linesize[0], m_stride);
597     return true;
598 }
599 
600 
601 
602 bool
close(void)603 FFmpegInput::close(void)
604 {
605     if (m_codec_context)
606         avcodec_close(m_codec_context);
607     if (m_format_context)
608         avformat_close_input(&m_format_context);
609     av_free(m_format_context);  // will free m_codec and m_codec_context
610     av_frame_free(&m_frame);    // free after close input
611     av_frame_free(&m_rgb_frame);
612     sws_freeContext(m_sws_rgb_context);
613     init();
614     return true;
615 }
616 
617 
618 
619 void
read_frame(int frame)620 FFmpegInput::read_frame(int frame)
621 {
622     if (m_last_decoded_pos + 1 != frame) {
623         seek(frame);
624     }
625     AVPacket pkt;
626     int finished = 0;
627     int ret      = 0;
628     while ((ret = av_read_frame(m_format_context, &pkt)) == 0
629            || m_codec_cap_delay) {
630         if (ret == AVERROR_EOF) {
631             break;
632         }
633         if (pkt.stream_index == m_video_stream) {
634             if (ret < 0 && m_codec_cap_delay) {
635                 pkt.data = NULL;
636                 pkt.size = 0;
637             }
638 
639             finished = receive_frame(m_codec_context, m_frame, &pkt);
640 
641             double pts = 0;
642             if (static_cast<int64_t>(m_frame->pkt_pts)
643                 != int64_t(AV_NOPTS_VALUE)) {
644                 pts = av_q2d(
645                           m_format_context->streams[m_video_stream]->time_base)
646                       * m_frame->pkt_pts;
647             }
648 
649             int current_frame = int((pts - m_start_time) * fps() + 0.5f);  //???
650             //current_frame =   m_frame->display_picture_number;
651             m_last_search_pos = current_frame;
652 
653             if (current_frame == frame && finished) {
654                 avpicture_fill(reinterpret_cast<AVPicture*>(m_rgb_frame),
655                                &m_rgb_buffer[0], m_dst_pix_format,
656                                m_codec_context->width, m_codec_context->height);
657                 sws_scale(m_sws_rgb_context,
658                           static_cast<uint8_t const* const*>(m_frame->data),
659                           m_frame->linesize, 0, m_codec_context->height,
660                           m_rgb_frame->data, m_rgb_frame->linesize);
661                 m_last_decoded_pos = current_frame;
662                 av_free_packet(&pkt);
663                 break;
664             }
665         }
666         av_free_packet(&pkt);
667     }
668     m_read_frame = true;
669 }
670 
671 
672 
673 #if 0
674 const char *
675 FFmpegInput::metadata (const char * key)
676 {
677     AVDictionaryEntry * entry = av_dict_get (m_format_context->metadata, key, NULL, 0);
678     return entry ? av_strdup(entry->value) : NULL;
679     // FIXME -- that looks suspiciously like a memory leak
680 }
681 
682 
683 
684 bool
685 FFmpegInput::has_metadata (const char * key)
686 {
687     return av_dict_get (m_format_context->metadata, key, NULL, 0); // is there a better to check exists?
688 }
689 #endif
690 
691 
692 
693 bool
seek(int frame)694 FFmpegInput::seek(int frame)
695 {
696     int64_t offset = time_stamp(frame);
697     int flags      = AVSEEK_FLAG_BACKWARD;
698     avcodec_flush_buffers(m_codec_context);
699     av_seek_frame(m_format_context, -1, offset, flags);
700     return true;
701 }
702 
703 
704 
705 int64_t
time_stamp(int frame) const706 FFmpegInput::time_stamp(int frame) const
707 {
708     int64_t timestamp = static_cast<int64_t>(
709         (static_cast<double>(frame)
710          / (fps()
711             * av_q2d(m_format_context->streams[m_video_stream]->time_base))));
712     if (static_cast<int64_t>(m_format_context->start_time)
713         != int64_t(AV_NOPTS_VALUE)) {
714         timestamp += static_cast<int64_t>(
715             static_cast<double>(m_format_context->start_time) * AV_TIME_BASE
716             / av_q2d(m_format_context->streams[m_video_stream]->time_base));
717     }
718     return timestamp;
719 }
720 
721 
722 
723 double
fps() const724 FFmpegInput::fps() const
725 {
726     if (m_frame_rate.den) {
727         return av_q2d(m_frame_rate);
728     }
729     return 1.0f;
730 }
731 
732 OIIO_PLUGIN_NAMESPACE_END
733