upgraded to ocio v2
This commit is contained in:
@@ -51,7 +51,7 @@ OLIVE_NAMESPACE_ENTER
|
||||
FFmpegDecoder::FFmpegDecoder() :
|
||||
scale_ctx_(nullptr),
|
||||
scale_divider_(0),
|
||||
pool_(QThread::idealThreadCount()),
|
||||
pool_(QThread::idealThreadCount()*2),
|
||||
is_working_(false),
|
||||
cache_at_zero_(false),
|
||||
cache_at_eof_(false)
|
||||
@@ -120,21 +120,20 @@ FramePtr FFmpegDecoder::RetrieveStillImage(const rational &timecode, const int &
|
||||
|
||||
if (ret >= 0) {
|
||||
// Create frame to return
|
||||
FramePtr copy = Frame::Create();
|
||||
copy->set_video_params(VideoParams(frame->width,
|
||||
frame->height,
|
||||
native_pix_fmt_,
|
||||
std::static_pointer_cast<VideoStream>(stream())->pixel_aspect_ratio(),
|
||||
std::static_pointer_cast<VideoStream>(stream())->interlacing(),
|
||||
divider));
|
||||
copy->set_timestamp(timecode);
|
||||
copy->allocate();
|
||||
output_frame = Frame::Create();
|
||||
output_frame->set_video_params(VideoParams(frame->width,
|
||||
frame->height,
|
||||
native_pix_fmt_,
|
||||
std::static_pointer_cast<VideoStream>(stream())->pixel_aspect_ratio(),
|
||||
std::static_pointer_cast<VideoStream>(stream())->interlacing(),
|
||||
divider));
|
||||
output_frame->set_timestamp(timecode);
|
||||
output_frame->allocate();
|
||||
|
||||
uint8_t* copy_data = reinterpret_cast<uint8_t*>(copy->data());
|
||||
int copy_linesize = copy->linesize_bytes();
|
||||
FFmpegFrameToNativeBuffer(frame->data, frame->linesize, ©_data, ©_linesize);
|
||||
uint8_t* copy_data = reinterpret_cast<uint8_t*>(output_frame->data());
|
||||
int copy_linesize = output_frame->linesize_bytes();
|
||||
|
||||
return copy;
|
||||
FFmpegBufferToNativeBuffer(frame->data, frame->linesize, ©_data, ©_linesize);
|
||||
} else {
|
||||
qWarning() << "Failed to retrieve still image from decoder";
|
||||
}
|
||||
@@ -151,6 +150,11 @@ FramePtr FFmpegDecoder::RetrieveVideoInternal(const rational &timecode, const in
|
||||
{
|
||||
VideoStreamPtr vs = std::static_pointer_cast<VideoStream>(stream());
|
||||
|
||||
if (scale_divider_ != divider) {
|
||||
FreeScaler();
|
||||
InitScaler(divider);
|
||||
}
|
||||
|
||||
if (vs->video_type() == VideoStream::kVideoTypeStill
|
||||
|| vs->video_type() == VideoStream::kVideoTypeImageSequence) {
|
||||
|
||||
@@ -158,8 +162,6 @@ FramePtr FFmpegDecoder::RetrieveVideoInternal(const rational &timecode, const in
|
||||
|
||||
} else {
|
||||
|
||||
FFmpegFramePool::ElementPtr return_frame = nullptr;
|
||||
|
||||
int64_t target_ts = vs->get_time_in_timebase_units(timecode);
|
||||
|
||||
int divided_width = VideoParams::GetScaledDimension(vs->width(), divider);
|
||||
@@ -171,12 +173,10 @@ FramePtr FFmpegDecoder::RetrieveVideoInternal(const rational &timecode, const in
|
||||
|
||||
// Set new frame pool parameters
|
||||
pool_.SetParameters(divided_width, divided_height, native_pix_fmt_);
|
||||
} else {
|
||||
return_frame = GetFrameFromCache(target_ts);
|
||||
}
|
||||
|
||||
// Retrieve frame
|
||||
return_frame = RetrieveFrame(target_ts, divider);
|
||||
FFmpegFramePool::ElementPtr return_frame = RetrieveFrame(target_ts, divider);
|
||||
|
||||
// We found the frame, we'll return a copy
|
||||
if (return_frame) {
|
||||
@@ -563,7 +563,7 @@ uint64_t FFmpegDecoder::ValidateChannelLayout(AVStream* stream)
|
||||
return av_get_default_channel_layout(stream->codecpar->channels);
|
||||
}
|
||||
|
||||
void FFmpegDecoder::FFmpegFrameToNativeBuffer(uint8_t **input_data, int *input_linesize, uint8_t** output_buffer, int* output_linesize)
|
||||
void FFmpegDecoder::FFmpegBufferToNativeBuffer(uint8_t **input_data, int *input_linesize, uint8_t** output_buffer, int* output_linesize)
|
||||
{
|
||||
sws_scale(scale_ctx_,
|
||||
input_data,
|
||||
@@ -640,17 +640,12 @@ void FFmpegDecoder::ClearFrameCache()
|
||||
|
||||
FFmpegFramePool::ElementPtr FFmpegDecoder::RetrieveFrame(const int64_t& target_ts, int divider)
|
||||
{
|
||||
if (scale_divider_ != divider) {
|
||||
FreeScaler();
|
||||
InitScaler(divider);
|
||||
}
|
||||
|
||||
int64_t seek_ts = target_ts;
|
||||
bool still_seeking = false;
|
||||
|
||||
// If the frame wasn't in the frame cache, see if this frame cache is too old to use
|
||||
if (cached_frames_.isEmpty()
|
||||
|| (target_ts < cached_frames_.first()->timestamp() && target_ts > cached_frames_.last()->timestamp() + 2*second_ts_)) {
|
||||
|| (target_ts < cached_frames_.first()->timestamp() || target_ts > cached_frames_.last()->timestamp() + 2*second_ts_)) {
|
||||
ClearFrameCache();
|
||||
|
||||
instance_.Seek(seek_ts);
|
||||
@@ -659,6 +654,12 @@ FFmpegFramePool::ElementPtr FFmpegDecoder::RetrieveFrame(const int64_t& target_t
|
||||
}
|
||||
|
||||
still_seeking = true;
|
||||
} else {
|
||||
// Search cache for frame
|
||||
FFmpegFramePool::ElementPtr cached_frame = GetFrameFromCache(target_ts);
|
||||
if (cached_frame) {
|
||||
return cached_frame;
|
||||
}
|
||||
}
|
||||
|
||||
int ret;
|
||||
@@ -727,9 +728,9 @@ FFmpegFramePool::ElementPtr FFmpegDecoder::RetrieveFrame(const int64_t& target_t
|
||||
}
|
||||
|
||||
// Store in queue, converting to native format
|
||||
int destination_linesize = Frame::generate_linesize_bytes(VideoParams::GetScaledDimension(instance_.avstream()->codecpar->width, divider), native_pix_fmt_);
|
||||
uint8_t* destination_data = cached->data();
|
||||
FFmpegFrameToNativeBuffer(working_frame->data, working_frame->linesize, &destination_data, &destination_linesize);
|
||||
int destination_linesize = Frame::generate_linesize_bytes(VideoParams::GetScaledDimension(instance_.avstream()->codecpar->width, divider), native_pix_fmt_);
|
||||
FFmpegBufferToNativeBuffer(working_frame->data, working_frame->linesize, &destination_data, &destination_linesize);
|
||||
|
||||
// Set timestamp so this frame can be identified later
|
||||
cached->set_timestamp(working_frame->pts);
|
||||
|
||||
@@ -130,7 +130,7 @@ private:
|
||||
|
||||
static uint64_t ValidateChannelLayout(AVStream *stream);
|
||||
|
||||
void FFmpegFrameToNativeBuffer(uint8_t** input_data, int* input_linesize, uint8_t **output_buffer, int *output_linesize);
|
||||
void FFmpegBufferToNativeBuffer(uint8_t** input_data, int* input_linesize, uint8_t **output_buffer, int *output_linesize);
|
||||
|
||||
FFmpegFramePool::ElementPtr GetFrameFromCache(const int64_t& t) const;
|
||||
|
||||
|
||||
+7
-5
@@ -45,14 +45,14 @@ void Frame::set_video_params(const VideoParams ¶ms)
|
||||
{
|
||||
params_ = params;
|
||||
|
||||
linesize_ = generate_linesize_bytes(params_.width(), params_.format());
|
||||
linesize_ = generate_linesize_bytes(width(), params_.format());
|
||||
linesize_pixels_ = linesize_ / PixelFormat::BytesPerPixel(params_.format());
|
||||
}
|
||||
|
||||
int Frame::generate_linesize_bytes(int width, PixelFormat::Format format)
|
||||
{
|
||||
// Align to 32 bytes (not sure if this is necessary?)
|
||||
return ((PixelFormat::BytesPerPixel(format) * width) + 31) & ~31;
|
||||
return PixelFormat::BytesPerPixel(format) * ((width + 31) & ~31);
|
||||
}
|
||||
|
||||
Color Frame::get_pixel(int x, int y) const
|
||||
@@ -82,15 +82,17 @@ void Frame::set_pixel(int x, int y, const Color &c)
|
||||
c.toData(data_.data() + byte_offset, video_params().format());
|
||||
}
|
||||
|
||||
void Frame::allocate()
|
||||
bool Frame::allocate()
|
||||
{
|
||||
// Assume this frame is intended to be a video frame
|
||||
if (!params_.is_valid()) {
|
||||
qWarning() << "Tried to allocate a frame with invalid parameters";
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
data_.resize(PixelFormat::GetBufferSize(params_.format(), linesize_, params_.height()));
|
||||
data_.resize(PixelFormat::GetBufferSize(params_.format(), linesize_, height()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
+1
-1
@@ -116,7 +116,7 @@ public:
|
||||
*
|
||||
* If a memory buffer has been previously allocated without destroying, this function will destroy it.
|
||||
*/
|
||||
void allocate();
|
||||
bool allocate();
|
||||
|
||||
/**
|
||||
* @brief Return whether the frame is allocated or not
|
||||
|
||||
Reference in New Issue
Block a user