31 #include "../include/CacheDisk.h"
37 CacheDisk::CacheDisk(std::string cache_path, std::string format,
float quality,
float scale) :
CacheBase(0) {
41 needs_range_processing =
false;
43 image_format = format;
44 image_quality = quality;
57 needs_range_processing =
false;
59 image_format = format;
60 image_quality = quality;
68 void CacheDisk::InitPath(std::string cache_path) {
71 if (!cache_path.empty()) {
73 qpath = QString(cache_path.c_str());
77 qpath = QDir::tempPath() + QString(
"/preview-cache/");
90 void CacheDisk::CalculateRanges() {
92 if (needs_range_processing) {
98 std::sort(ordered_frame_numbers.begin(), ordered_frame_numbers.end());
101 Json::Value ranges = Json::Value(Json::arrayValue);
106 int64_t starting_frame = *ordered_frame_numbers.begin();
107 int64_t ending_frame = starting_frame;
110 for (
const auto frame_number : ordered_frame_numbers) {
111 if (frame_number - ending_frame > 1) {
117 range[
"start"] = std::to_string(starting_frame);
118 range[
"end"] = std::to_string(ending_frame);
119 ranges.append(range);
122 starting_frame = frame_number;
126 ending_frame = frame_number;
134 range[
"start"] = std::to_string(starting_frame);
135 range[
"end"] = std::to_string(ending_frame);
136 ranges.append(range);
139 json_ranges = ranges.toStyledString();
142 needs_range_processing =
false;
150 frame_numbers.clear();
151 ordered_frame_numbers.clear();
163 int64_t frame_number = frame->
number;
166 if (frames.count(frame_number))
173 frames[frame_number] = frame_number;
174 frame_numbers.push_front(frame_number);
175 ordered_frame_numbers.push_back(frame_number);
176 needs_range_processing =
true;
179 QString frame_path(path.path() +
"/" + QString(
"%1.").arg(frame_number) + QString(image_format.c_str()).toLower());
180 frame->
Save(frame_path.toStdString(), image_scale, image_format, image_quality);
181 if (frame_size_bytes == 0) {
183 QFile image_file(frame_path);
184 frame_size_bytes = image_file.size();
189 QString audio_path(path.path() +
"/" + QString(
"%1").arg(frame_number) +
".audio");
190 QFile audio_file(audio_path);
192 if (audio_file.open(QIODevice::WriteOnly)) {
193 QTextStream audio_stream(&audio_file);
205 audio_stream << samples[sample] << endl;
224 if (frames.count(frame_number)) {
226 QString frame_path(path.path() +
"/" + QString(
"%1.").arg(frame_number) + QString(image_format.c_str()).toLower());
227 if (path.exists(frame_path)) {
230 std::shared_ptr<QImage> image = std::shared_ptr<QImage>(
new QImage());
231 bool success = image->load(QString::fromStdString(frame_path.toStdString()));
234 image = std::shared_ptr<QImage>(
new QImage(image->convertToFormat(QImage::Format_RGBA8888)));
237 std::shared_ptr<Frame> frame(
new Frame());
238 frame->
number = frame_number;
242 QString audio_path(path.path() +
"/" + QString(
"%1").arg(frame_number) +
".audio");
243 QFile audio_file(audio_path);
244 if (audio_file.exists()) {
246 QTextStream in(&audio_file);
247 if (audio_file.open(QIODevice::ReadOnly)) {
248 int sample_rate = in.readLine().toInt();
249 int channels = in.readLine().toInt();
250 int sample_count = in.readLine().toInt();
251 int channel_layout = in.readLine().toInt();
257 int current_channel = 0;
258 int current_sample = 0;
259 float *channel_samples =
new float[sample_count];
260 while (!in.atEnd()) {
262 channel_samples[current_sample] = in.readLine().toFloat();
265 if (current_sample == sample_count) {
267 frame->
AddAudio(
true, current_channel, 0, channel_samples, sample_count, 1.0);
284 return std::shared_ptr<Frame>();
292 std::shared_ptr<openshot::Frame> f;
295 std::deque<int64_t>::iterator itr;
296 int64_t smallest_frame = -1;
297 for(itr = frame_numbers.begin(); itr != frame_numbers.end(); ++itr)
299 if (*itr < smallest_frame || smallest_frame == -1)
300 smallest_frame = *itr;
315 int64_t total_bytes = 0;
318 std::deque<int64_t>::reverse_iterator itr;
319 for(itr = frame_numbers.rbegin(); itr != frame_numbers.rend(); ++itr)
320 total_bytes += frame_size_bytes;
328 Remove(frame_number, frame_number);
338 std::deque<int64_t>::iterator itr;
339 for(itr = frame_numbers.begin(); itr != frame_numbers.end();)
342 if (*itr >= start_frame_number && *itr <= end_frame_number)
345 itr = frame_numbers.erase(itr);
351 std::vector<int64_t>::iterator itr_ordered;
352 for(itr_ordered = ordered_frame_numbers.begin(); itr_ordered != ordered_frame_numbers.end();)
354 if (*itr_ordered >= start_frame_number && *itr_ordered <= end_frame_number)
357 frames.erase(*itr_ordered);
360 QString frame_path(path.path() +
"/" + QString(
"%1.").arg(*itr_ordered) + QString(image_format.c_str()).toLower());
361 QFile image_file(frame_path);
362 if (image_file.exists())
366 QString audio_path(path.path() +
"/" + QString(
"%1").arg(*itr_ordered) +
".audio");
367 QFile audio_file(audio_path);
368 if (audio_file.exists())
371 itr_ordered = ordered_frame_numbers.erase(itr_ordered);
377 needs_range_processing =
true;
384 if (frames.count(frame_number))
390 std::deque<int64_t>::iterator itr;
391 for(itr = frame_numbers.begin(); itr != frame_numbers.end(); ++itr)
393 if (*itr == frame_number)
396 frame_numbers.erase(itr);
399 frame_numbers.push_front(frame_number);
414 frame_numbers.clear();
415 ordered_frame_numbers.clear();
416 needs_range_processing =
true;
417 frame_size_bytes = 0;
420 QString current_path = path.path();
421 path.removeRecursively();
424 InitPath(current_path.toStdString());
434 return frames.size();
438 void CacheDisk::CleanUp()
449 int64_t frame_to_remove = frame_numbers.back();
473 root[
"path"] = path.path().toStdString();
476 std::stringstream range_version_str;
477 range_version_str << range_version;
478 root[
"version"] = range_version_str.str();
484 root[
"ranges"] = ranges;
501 catch (
const std::exception& e)
504 throw InvalidJSON(
"JSON is invalid (missing keys or invalid data types)");
517 if (!root[
"type"].isNull())
519 if (!root[
"path"].isNull())
521 InitPath(root[
"path"].asString());