2 * Copyright 2013 Sveriges Television AB http://casparcg.com/
4 * This file is part of CasparCG (www.casparcg.com).
6 * CasparCG is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * CasparCG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
19 * Author: Robert Nagy, ronag89@gmail.com
22 #include "../../stdafx.h"
24 #include "video_decoder.h"
26 #include "../util/util.h"
28 #include "../../ffmpeg_error.h"
30 #include <core/frame/frame_transform.h>
31 #include <core/frame/frame_factory.h>
33 #include <boost/range/algorithm_ext/push_back.hpp>
34 #include <boost/filesystem.hpp>
39 #pragma warning (push)
40 #pragma warning (disable : 4244)
44 #include <libavcodec/avcodec.h>
45 #include <libavformat/avformat.h>
51 namespace caspar { namespace ffmpeg {
53 struct video_decoder::implementation : boost::noncopyable
56 const spl::shared_ptr<AVCodecContext> codec_context_;
58 std::queue<spl::shared_ptr<AVPacket>> packets_;
60 const uint32_t nb_frames_;
62 const int width_ = codec_context_->width;
63 const int height_ = codec_context_->height;
66 tbb::atomic<uint32_t> file_frame_number_;
69 explicit implementation(const spl::shared_ptr<AVFormatContext>& context)
70 : codec_context_(open_codec(*context, AVMEDIA_TYPE_VIDEO, index_, false))
71 , nb_frames_(static_cast<uint32_t>(context->streams[index_]->nb_frames))
73 file_frame_number_ = 0;
75 codec_context_->refcounted_frames = 1;
78 void push(const std::shared_ptr<AVPacket>& packet)
83 if(packet->stream_index == index_ || packet->data == nullptr)
84 packets_.push(spl::make_shared_ptr(packet));
87 std::shared_ptr<AVFrame> poll()
92 auto packet = packets_.front();
94 if(packet->data == nullptr)
96 if(codec_context_->codec->capabilities & CODEC_CAP_DELAY)
98 auto video = decode(packet);
104 file_frame_number_ = static_cast<uint32_t>(packet->pos);
105 avcodec_flush_buffers(codec_context_.get());
106 return flush_video();
110 return decode(packet);
113 std::shared_ptr<AVFrame> decode(spl::shared_ptr<AVPacket> pkt)
115 auto decoded_frame = std::shared_ptr<AVFrame>(av_frame_alloc(), [](AVFrame* frame)
117 av_frame_free(&frame);
120 int frame_finished = 0;
121 THROW_ON_ERROR2(avcodec_decode_video2(codec_context_.get(), decoded_frame.get(), &frame_finished, pkt.get()), "[video_decoder]");
123 // If a decoder consumes less then the whole packet then something is wrong
124 // that might be just harmless padding at the end, or a problem with the
125 // AVParser or demuxer which puted more then one frame in a AVPacket.
127 if(frame_finished == 0)
130 is_progressive_ = !decoded_frame->interlaced_frame;
132 if(decoded_frame->repeat_pict > 0)
133 CASPAR_LOG(warning) << "[video_decoder] Field repeat_pict not implemented.";
135 ++file_frame_number_;
137 // This ties the life of the decoded_frame to the packet that it came from. For the
138 // current version of ffmpeg (0.8 or c17808c) the RAW_VIDEO codec returns frame data
139 // owned by the packet.
140 return std::shared_ptr<AVFrame>(decoded_frame.get(), [decoded_frame, pkt](AVFrame*){});
145 return packets_.size() >= 8;
148 uint32_t nb_frames() const
150 return std::max(nb_frames_, static_cast<uint32_t>(file_frame_number_));
153 std::wstring print() const
155 return L"[video-decoder] " + u16(codec_context_->codec->long_name);
159 video_decoder::video_decoder(const spl::shared_ptr<AVFormatContext>& context) : impl_(new implementation(context)){}
160 void video_decoder::push(const std::shared_ptr<AVPacket>& packet){impl_->push(packet);}
161 std::shared_ptr<AVFrame> video_decoder::poll(){return impl_->poll();}
162 bool video_decoder::ready() const{return impl_->ready();}
163 int video_decoder::width() const{return impl_->width_;}
164 int video_decoder::height() const{return impl_->height_;}
165 uint32_t video_decoder::nb_frames() const{return impl_->nb_frames();}
166 uint32_t video_decoder::file_frame_number() const{return static_cast<uint32_t>(impl_->file_frame_number_);}
167 bool video_decoder::is_progressive() const{return impl_->is_progressive_;}
168 std::wstring video_decoder::print() const{return impl_->print();}