MCPcopy Create free account
hub / github.com/OpenShot/libopenshot / GetFrame

Method GetFrame

src/FFmpegReader.cpp:1197–1261  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1195}
1196
1197std::shared_ptr<Frame> FFmpegReader::GetFrame(int64_t requested_frame) {
1198 last_seek_max_frame = -1;
1199 seek_stagnant_count = 0;
1200 // Check for open reader (or throw exception)
1201 if (!is_open)
1202 throw ReaderClosed("The FFmpegReader is closed. Call Open() before calling this method.", path);
1203
1204 // Adjust for a requested frame that is too small or too large
1205 if (requested_frame < 1)
1206 requested_frame = 1;
1207 if (requested_frame > info.video_length && is_duration_known)
1208 requested_frame = info.video_length;
1209 if (info.has_video && info.video_length == 0)
1210 // Invalid duration of video file
1211 throw InvalidFile("Could not detect the duration of the video or audio stream.", path);
1212
1213 // Debug output
1214 ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::GetFrame", "requested_frame", requested_frame, "last_frame", last_frame);
1215
1216 // Check the cache for this frame
1217 std::shared_ptr<Frame> frame = final_cache.GetFrame(requested_frame);
1218 if (frame) {
1219 // Debug output
1220 ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::GetFrame", "returned cached frame", requested_frame);
1221 // Return the cached frame
1222 return frame;
1223 } else {
1224
1225 // Prevent async calls to the remainder of this code
1226 const std::lock_guard<std::recursive_mutex> lock(getFrameMutex);
1227
1228 // Check the cache a 2nd time (due to the potential previous lock)
1229 frame = final_cache.GetFrame(requested_frame);
1230 if (frame) {
1231 // Debug output
1232 ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::GetFrame", "returned cached frame on 2nd look", requested_frame);
1233 } else {
1234 // Frame is not in cache
1235 // Reset seek count
1236 seek_count = 0;
1237
1238 // Are we within X frames of the requested frame?
1239 int64_t diff = requested_frame - last_frame;
1240 if (diff >= 1 && diff <= 20) {
1241 // Continue walking the stream
1242 frame = ReadStream(requested_frame);
1243 } else {
1244 // Greater than 30 frames away, or backwards, we need to seek to the nearest key frame
1245 if (enable_seek) {
1246 // Only seek if enabled
1247 Seek(requested_frame);
1248
1249 } else if (!enable_seek && diff < 0) {
1250 // Start over, since we can't seek, and the requested frame is smaller than our position
1251 // Since we are seeking to frame 1, this actually just closes/re-opens the reader
1252 Seek(1);
1253 }
1254

Callers 3

ReadStreamMethod · 0.45
CreateFrameMethod · 0.45
CheckWorkingFramesMethod · 0.45

Calls 3

ReaderClosedClass · 0.85
InvalidFileClass · 0.85
AppendDebugMethodMethod · 0.80

Tested by

no test coverage detected