X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fffmpeg_image_proxy.cc;h=ab9b94b149e10e0ffdeafae194742d4e7ccef930;hb=f3e52bd763513190de60e7f6b68c50b34ab80fee;hp=c978fc3834f95f8e63c691876315744ace4c5746;hpb=e64a1a9aae0200d14feed49a4c6cf537bf5708a4;p=dcpomatic.git diff --git a/src/lib/ffmpeg_image_proxy.cc b/src/lib/ffmpeg_image_proxy.cc index c978fc383..ab9b94b14 100644 --- a/src/lib/ffmpeg_image_proxy.cc +++ b/src/lib/ffmpeg_image_proxy.cc @@ -18,37 +18,41 @@ */ -#include "ffmpeg_image_proxy.h" + +#include "compose.hpp" #include "cross.h" -#include "exceptions.h" #include "dcpomatic_socket.h" +#include "exceptions.h" +#include "ffmpeg_image_proxy.h" #include "image.h" -#include "compose.hpp" #include "util.h" #include "warnings.h" #include +DCPOMATIC_DISABLE_WARNINGS extern "C" { #include #include #include } -DCPOMATIC_DISABLE_WARNINGS #include DCPOMATIC_ENABLE_WARNINGS #include #include "i18n.h" -using std::string; + using std::cout; -using std::pair; -using std::min; using std::make_pair; -using boost::shared_ptr; +using std::make_shared; +using std::min; +using std::pair; +using std::shared_ptr; +using std::string; using boost::optional; -using boost::dynamic_pointer_cast; +using std::dynamic_pointer_cast; using dcp::raw_convert; + FFmpegImageProxy::FFmpegImageProxy (boost::filesystem::path path, VideoRange video_range) : _data (path) , _video_range (video_range) @@ -119,11 +123,12 @@ FFmpegImageProxy::avio_seek (int64_t const pos, int whence) return _pos; } -DCPOMATIC_DISABLE_WARNINGS ImageProxy::Result FFmpegImageProxy::image (optional) const { + auto constexpr name_for_errors = "FFmpegImageProxy::image"; + boost::mutex::scoped_lock lm (_mutex); if (_image) { @@ -162,40 +167,51 @@ FFmpegImageProxy::image (optional) const } } - if (avformat_find_stream_info(format_context, 0) < 0) { - throw DecodeError (_("could not find stream information")); + int r = avformat_find_stream_info(format_context, 0); + if (r < 0) { + throw DecodeError (N_("avcodec_find_stream_info"), name_for_errors, r); } DCPOMATIC_ASSERT (format_context->nb_streams == 1); AVFrame* frame = av_frame_alloc (); if (!frame) { - throw DecodeError (N_("could not allocate frame")); + std::bad_alloc (); } - AVCodecContext* codec_context = format_context->streams[0]->codec; - AVCodec* codec = avcodec_find_decoder (codec_context->codec_id); + auto codec = avcodec_find_decoder (format_context->streams[0]->codecpar->codec_id); DCPOMATIC_ASSERT (codec); - if (avcodec_open2 (codec_context, codec, 0) < 0) { - throw DecodeError (N_("could not open decoder")); + auto context = avcodec_alloc_context3 (codec); + if (!context) { + throw DecodeError (N_("avcodec_alloc_context3"), name_for_errors); + } + + r = avcodec_open2 (context, codec, 0); + if (r < 0) { + throw DecodeError (N_("avcodec_open2"), name_for_errors, r); } AVPacket packet; - int r = av_read_frame (format_context, &packet); + r = av_read_frame (format_context, &packet); if (r < 0) { - throw DecodeError (N_("could not read frame")); + throw DecodeError (N_("av_read_frame"), name_for_errors, r); } - int frame_finished; - if (avcodec_decode_video2(codec_context, frame, &frame_finished, &packet) < 0 || !frame_finished) { - throw DecodeError (N_("could not decode video")); + r = avcodec_send_packet (context, &packet); + if (r < 0) { + throw DecodeError (N_("avcodec_send_packet"), name_for_errors, r); } - AVPixelFormat const pix_fmt = static_cast(frame->format); + r = avcodec_receive_frame (context, frame); + if (r < 0) { + throw DecodeError (N_("avcodec_receive_frame"), name_for_errors, r); + } + + auto const pix_fmt = static_cast(frame->format); - _image.reset (new Image(frame)); - if (_video_range == VIDEO_RANGE_VIDEO && av_pix_fmt_desc_get(pix_fmt)->flags & AV_PIX_FMT_FLAG_RGB) { + _image = make_shared(frame); + if (_video_range == VideoRange::VIDEO && av_pix_fmt_desc_get(pix_fmt)->flags & AV_PIX_FMT_FLAG_RGB) { /* Asking for the video range to be converted by libswscale (in Image) will not work for * RGB sources since that method only processes video range in YUV and greyscale. So we have * to do it ourselves here. @@ -205,7 +221,7 @@ FFmpegImageProxy::image (optional) const av_packet_unref (&packet); av_frame_free (&frame); - avcodec_close (codec_context); + avcodec_free_context (&context); avformat_close_input (&format_context); av_free (avio_context->buffer); av_free (avio_context); @@ -213,7 +229,6 @@ FFmpegImageProxy::image (optional) const return Result (_image, 0); } -DCPOMATIC_ENABLE_WARNINGS void FFmpegImageProxy::add_metadata (xmlpp::Node* node) const