1 /**
2  * @file
3  * @brief Header file for ChunkReader class
4  * @author Jonathan Thomas <jonathan@openshot.org>
5  *
6  * @ref License
7  */
8 
9 /* LICENSE
10  *
11  * Copyright (c) 2008-2019 OpenShot Studios, LLC
12  * <http://www.openshotstudios.com/>. This file is part of
13  * OpenShot Library (libopenshot), an open-source project dedicated to
14  * delivering high quality video editing and animation solutions to the
15  * world. For more information visit <http://www.openshot.org/>.
16  *
17  * OpenShot Library (libopenshot) is free software: you can redistribute it
18  * and/or modify it under the terms of the GNU Lesser General Public License
19  * as published by the Free Software Foundation, either version 3 of the
20  * License, or (at your option) any later version.
21  *
22  * OpenShot Library (libopenshot) is distributed in the hope that it will be
23  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25  * GNU Lesser General Public License for more details.
26  *
27  * You should have received a copy of the GNU Lesser General Public License
28  * along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>.
29  */
30 
31 #ifndef OPENSHOT_CHUNK_READER_H
32 #define OPENSHOT_CHUNK_READER_H
33 
34 #include "ReaderBase.h"
35 #include <string>
36 #include <memory>
37 
38 #include "Frame.h"
39 #include "Json.h"
40 #include "CacheMemory.h"
41 
42 namespace openshot
43 {
44 
45 	/**
46 	 * @brief This struct holds the location of a frame within a chunk.
47 	 *
48 	 * Chunks are small video files, which typically contain a few seconds of video each.
49 	 * Locating a frame among these small video files is accomplished by using
50 	 * this struct.
51 	 */
52 	struct ChunkLocation
53 	{
54 		int64_t number; ///< The chunk number
55 		int64_t frame; ///< The frame number
56 	};
57 
58 	/**
59 	 * @brief This enumeration allows the user to choose which version
60 	 * of the chunk they would like (low, medium, or high quality).
61 	 *
62 	 * Since chunks contain multiple video streams, this version enumeration
63 	 * allows the user to choose which version of the chunk they would like.
64 	 * For example, if you want a small version with reduced quality, you can
65 	 * choose the THUMBNAIL version. This is used on the ChunkReader
66 	 * constructor.
67 	 */
68 	enum ChunkVersion
69 	{
70 		THUMBNAIL,	///< The lowest quality stream contained in this chunk file
71 		PREVIEW,	///< The medium quality stream contained in this chunk file
72 		FINAL		///< The highest quality stream contained in this chunk file
73 	};
74 
75 	/**
76 	 * @brief This class reads a special chunk-formatted file, which can be easily
77 	 * shared in a distributed environment.
78 	 *
79 	 * It stores the video in small "chunks", which are really just short video clips,
80 	 * a few seconds each. A ChunkReader only needs the part of the chunk that contains
81 	 * the frames it is looking for. For example, if you only need the end of a video,
82 	 * only the last few chunks might be needed to successfully access those openshot::Frame objects.
83 	 *
84 	 * \code
85 	 * // This example demonstrates how to read a chunk folder and access frame objects inside it.
86 	 * ChunkReader r("/home/jonathan/apps/chunks/chunk1/", FINAL); // Load highest quality version of this chunk file
87 	 * r.DisplayInfo(); // Display all known details about this chunk file
88 	 * r.Open(); // Open the reader
89 	 *
90 	 * // Access frame 1
91 	 * r.GetFrame(1)->Display();
92 	 *
93 	 * // Close the reader
94 	 * r.Close();
95 	 * \endcode
96 	 */
97 	class ChunkReader : public ReaderBase
98 	{
99 	private:
100 		std::string path;
101 		bool is_open;
102 		int64_t chunk_size;
103 		openshot::ReaderBase *local_reader;
104 		ChunkLocation previous_location;
105 		ChunkVersion version;
106 		std::shared_ptr<openshot::Frame> last_frame;
107 
108 		/// Check if folder path existing
109 		bool does_folder_exist(std::string path);
110 
111 		/// Find the location of a frame in a chunk
112 		ChunkLocation find_chunk_frame(int64_t requested_frame);
113 
114 		/// get a formatted path of a specific chunk
115 		std::string get_chunk_path(int64_t chunk_number, std::string folder, std::string extension);
116 
117 		/// Load JSON meta data about this chunk folder
118 		void load_json();
119 
120 	public:
121 
122 		/// @brief Constructor for ChunkReader.  This automatically opens the chunk file or folder and loads
123 		/// frame 1, or it throws one of the following exceptions.
124 		/// @param path				The folder path / location of a chunk (chunks are stored as folders)
125 		/// @param chunk_version	Choose the video version / quality (THUMBNAIL, PREVIEW, or FINAL)
126 		ChunkReader(std::string path, ChunkVersion chunk_version);
127 
128 		/// Close the reader
129 		void Close() override;
130 
131 		/// @brief Get the chunk size (number of frames to write in each chunk)
132 		/// @returns	The number of frames in this chunk
GetChunkSize()133 		int64_t GetChunkSize() { return chunk_size; };
134 
135 		/// @brief Set the chunk size (number of frames to write in each chunk)
136 		/// @param new_size		The number of frames per chunk
SetChunkSize(int64_t new_size)137 		void SetChunkSize(int64_t new_size) { chunk_size = new_size; };
138 
139 		/// Get the cache object used by this reader (always return NULL for this reader)
GetCache()140 		openshot::CacheMemory* GetCache() override { return NULL; };
141 
142 		/// @brief Get an openshot::Frame object for a specific frame number of this reader.
143 		/// @returns				The requested frame (containing the image and audio)
144 		/// @param requested_frame	The frame number you want to retrieve
145 		std::shared_ptr<openshot::Frame> GetFrame(int64_t requested_frame) override;
146 
147 		/// Determine if reader is open or closed
IsOpen()148 		bool IsOpen() override { return is_open; };
149 
150 		/// Return the type name of the class
Name()151 		std::string Name() override { return "ChunkReader"; };
152 
153 		// Get and Set JSON methods
154 		std::string Json() const override; ///< Generate JSON string of this object
155 		void SetJson(const std::string value) override; ///< Load JSON string into this object
156 		Json::Value JsonValue() const override; ///< Generate Json::Value for this object
157 		void SetJsonValue(const Json::Value root) override; ///< Load Json::Value into this object
158 
159 		/// Open the reader. This is required before you can access frames or data from the reader.
160 		void Open() override;
161 	};
162 
163 }
164 
165 #endif
166