From: Carl Hetherington Date: Tue, 10 May 2016 10:57:05 +0000 (+0100) Subject: Use optional<> for _video_stream. X-Git-Tag: v2.8.4~31 X-Git-Url: https://main.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=a3073b3059e8df6304d2936ab2c605e6908a7373 Use optional<> for _video_stream. --- diff --git a/src/lib/ffmpeg.cc b/src/lib/ffmpeg.cc index 656142cd4..7b1eae2b1 100644 --- a/src/lib/ffmpeg.cc +++ b/src/lib/ffmpeg.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2015 Carl Hetherington + Copyright (C) 2013-2016 Carl Hetherington This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -56,7 +56,6 @@ FFmpeg::FFmpeg (boost::shared_ptr c) , _avio_context (0) , _format_context (0) , _frame (0) - , _video_stream (-1) { setup_general (); setup_decoders (); @@ -140,7 +139,7 @@ FFmpeg::setup_general () /* Find video stream */ - int video_stream_undefined_frame_rate = -1; + optional video_stream_undefined_frame_rate; for (uint32_t i = 0; i < _format_context->nb_streams; ++i) { AVStream* s = _format_context->streams[i]; @@ -158,11 +157,11 @@ FFmpeg::setup_general () /* Files from iTunes sometimes have two video streams, one with the avg_frame_rate.num and .den set to zero. Only use such a stream if there is no alternative. */ - if (_video_stream == -1 && video_stream_undefined_frame_rate != -1) { - _video_stream = video_stream_undefined_frame_rate; + if (!_video_stream && video_stream_undefined_frame_rate) { + _video_stream = video_stream_undefined_frame_rate.get(); } - if (_video_stream < 0) { + if (!_video_stream) { throw DecodeError (N_("could not find video stream")); } @@ -224,7 +223,8 @@ FFmpeg::setup_decoders () AVCodecContext * FFmpeg::video_codec_context () const { - return _format_context->streams[_video_stream]->codec; + DCPOMATIC_ASSERT (_video_stream); + return _format_context->streams[_video_stream.get()]->codec; } AVCodecContext * diff --git a/src/lib/ffmpeg.h b/src/lib/ffmpeg.h index 43efcf74f..d38fd6362 100644 --- a/src/lib/ffmpeg.h +++ b/src/lib/ffmpeg.h @@ -72,7 +72,7 @@ protected: AVFrame* _frame; /** Index of video stream within AVFormatContext */ - int _video_stream; + boost::optional _video_stream; /* It would appear (though not completely verified) that one must have a mutex around calls to avcodec_open* and avcodec_close... and here diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index 68dcd5186..72df69126 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -121,7 +121,7 @@ FFmpegDecoder::pass (PassReason reason, bool accurate) int const si = _packet.stream_index; shared_ptr fc = _ffmpeg_content; - if (si == _video_stream && !_ignore_video && (accurate || reason != PASS_REASON_SUBTITLE)) { + if (_video_stream && si == _video_stream.get() && !_ignore_video && (accurate || reason != PASS_REASON_SUBTITLE)) { decode_video_packet (); } else if (fc->subtitle_stream() && fc->subtitle_stream()->uses_index (_format_context, si)) { decode_subtitle_packet (); @@ -295,11 +295,18 @@ FFmpegDecoder::seek (ContentTime time, bool accurate) http://www.mjbshaw.com/2012/04/seeking-in-ffmpeg-know-your-timestamp.html */ + DCPOMATIC_ASSERT (_video_stream); + ContentTime u = time - _pts_offset; if (u < ContentTime ()) { u = ContentTime (); } - av_seek_frame (_format_context, _video_stream, u.seconds() / av_q2d (_format_context->streams[_video_stream]->time_base), AVSEEK_FLAG_BACKWARD); + av_seek_frame ( + _format_context, + _video_stream.get(), + u.seconds() / av_q2d (_format_context->streams[_video_stream.get()]->time_base), + AVSEEK_FLAG_BACKWARD + ); avcodec_flush_buffers (video_codec_context()); @@ -380,6 +387,8 @@ FFmpegDecoder::decode_audio_packet () bool FFmpegDecoder::decode_video_packet () { + DCPOMATIC_ASSERT (_video_stream); + int frame_finished; if (avcodec_decode_video2 (video_codec_context(), _frame, &frame_finished, &_packet) < 0 || !frame_finished) { return false; @@ -410,7 +419,7 @@ FFmpegDecoder::decode_video_packet () shared_ptr image = i->first; if (i->second != AV_NOPTS_VALUE) { - double const pts = i->second * av_q2d (_format_context->streams[_video_stream]->time_base) + _pts_offset.seconds (); + double const pts = i->second * av_q2d (_format_context->streams[_video_stream.get()]->time_base) + _pts_offset.seconds (); video ( shared_ptr (new RawImageProxy (image)), llrint (pts * _ffmpeg_content->active_video_frame_rate ()) diff --git a/src/lib/ffmpeg_examiner.cc b/src/lib/ffmpeg_examiner.cc index 2b8b2b743..eeb0cfc38 100644 --- a/src/lib/ffmpeg_examiner.cc +++ b/src/lib/ffmpeg_examiner.cc @@ -113,7 +113,7 @@ FFmpegExaminer::FFmpegExaminer (shared_ptr c, shared_ptrstreams[_packet.stream_index]->codec; - if (_packet.stream_index == _video_stream) { + if (_video_stream && _packet.stream_index == _video_stream.get()) { video_packet (context); } @@ -179,6 +179,8 @@ FFmpegExaminer::FFmpegExaminer (shared_ptr c, shared_ptr= 0 && frame_finished) { if (!_first_video) { - _first_video = frame_time (_format_context->streams[_video_stream]); + _first_video = frame_time (_format_context->streams[_video_stream.get()]); } if (_need_video_length) { _video_length = frame_time ( - _format_context->streams[_video_stream] + _format_context->streams[_video_stream.get()] ).get_value_or (ContentTime ()).frames_round (video_frame_rate().get ()); } } @@ -297,11 +299,12 @@ FFmpegExaminer::frame_time (AVStream* s) const optional FFmpegExaminer::video_frame_rate () const { + DCPOMATIC_ASSERT (_video_stream); /* This use of r_frame_rate is debateable; there's a few different * frame rates in the format context, but this one seems to be the most * reliable. */ - return av_q2d (av_stream_get_r_frame_rate (_format_context->streams[_video_stream])); + return av_q2d (av_stream_get_r_frame_rate (_format_context->streams[_video_stream.get()])); } dcp::Size @@ -320,7 +323,8 @@ FFmpegExaminer::video_length () const optional FFmpegExaminer::sample_aspect_ratio () const { - AVRational sar = av_guess_sample_aspect_ratio (_format_context, _format_context->streams[_video_stream], 0); + DCPOMATIC_ASSERT (_video_stream); + AVRational sar = av_guess_sample_aspect_ratio (_format_context, _format_context->streams[_video_stream.get()], 0); if (sar.num == 0) { /* I assume this means that we don't know */ return optional ();