From 97ec6298ff10af38fb4e10ac7ba70aa05aa928c7 Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Wed, 15 Mar 2017 02:06:53 -0500 Subject: [PATCH] Adding frame number display options to a clip, which can be super useful when debugging issues. Options include: None, Clip, Timeline, or Both. Also improving missing frame detection, to have less false positives (i.e. flickering 1st frame) --- include/Clip.h | 1 + include/Enums.h | 9 +++++++++ src/Clip.cpp | 11 +++++++++++ src/FFmpegReader.cpp | 2 +- src/Timeline.cpp | 23 +++++++++++++++++++++++ 5 files changed, 45 insertions(+), 1 deletion(-) diff --git a/include/Clip.h b/include/Clip.h index aa24d670..7e9012e5 100644 --- a/include/Clip.h +++ b/include/Clip.h @@ -151,6 +151,7 @@ namespace openshot { GravityType gravity; ///< The gravity of a clip determines where it snaps to it's parent ScaleType scale; ///< The scale determines how a clip should be resized to fit it's parent AnchorType anchor; ///< The anchor determines what parent a clip should snap to + FrameDisplayType display; ///< The format to display the frame number (if any) /// Default Constructor Clip(); diff --git a/include/Enums.h b/include/Enums.h index e8434246..8e994a1b 100644 --- a/include/Enums.h +++ b/include/Enums.h @@ -60,5 +60,14 @@ namespace openshot ANCHOR_CANVAS, ///< Anchor the clip to the canvas ANCHOR_VIEWPORT ///< Anchor the clip to the viewport (which can be moved / animated around the canvas) }; + + /// This enumeration determines the display format of the clip's frame number (if any). Useful for debugging. + enum FrameDisplayType + { + FRAME_DISPLAY_NONE, ///< Do not display the frame number + FRAME_DISPLAY_CLIP, ///< Display the clip's internal frame number + FRAME_DISPLAY_TIMELINE, ///< Display the timeline's frame number + FRAME_DISPLAY_BOTH ///< Display both the clip's and timeline's frame number + }; } #endif diff --git a/src/Clip.cpp b/src/Clip.cpp index 631e07dc..4eefa70d 100644 --- a/src/Clip.cpp +++ b/src/Clip.cpp @@ -40,6 +40,7 @@ void Clip::init_settings() gravity = GRAVITY_CENTER; scale = SCALE_FIT; anchor = ANCHOR_CANVAS; + display = FRAME_DISPLAY_NONE; waveform = false; previous_properties = ""; @@ -669,6 +670,7 @@ string Clip::PropertiesJSON(long int requested_frame) { root["gravity"] = add_property_json("Gravity", gravity, "int", "", NULL, 0, 8, false, requested_frame); root["scale"] = add_property_json("Scale", scale, "int", "", NULL, 0, 3, false, requested_frame); root["anchor"] = add_property_json("Anchor", anchor, "int", "", NULL, 0, 1, false, requested_frame); + root["display"] = add_property_json("Frame Number", display, "int", "", NULL, 0, 3, false, requested_frame); root["waveform"] = add_property_json("Waveform", waveform, "int", "", NULL, 0, 1, false, requested_frame); // Add gravity choices (dropdown style) @@ -692,6 +694,12 @@ string Clip::PropertiesJSON(long int requested_frame) { root["anchor"]["choices"].append(add_property_choice_json("Canvas", ANCHOR_CANVAS, anchor)); root["anchor"]["choices"].append(add_property_choice_json("Viewport", ANCHOR_VIEWPORT, anchor)); + // Add frame number display choices (dropdown style) + root["display"]["choices"].append(add_property_choice_json("None", FRAME_DISPLAY_NONE, display)); + root["display"]["choices"].append(add_property_choice_json("Clip", FRAME_DISPLAY_CLIP, display)); + root["display"]["choices"].append(add_property_choice_json("Timeline", FRAME_DISPLAY_TIMELINE, display)); + root["display"]["choices"].append(add_property_choice_json("Both", FRAME_DISPLAY_BOTH, display)); + // Add waveform choices (dropdown style) root["waveform"]["choices"].append(add_property_choice_json("Yes", true, waveform)); root["waveform"]["choices"].append(add_property_choice_json("No", false, waveform)); @@ -730,6 +738,7 @@ Json::Value Clip::JsonValue() { root["gravity"] = gravity; root["scale"] = scale; root["anchor"] = anchor; + root["display"] = display; root["waveform"] = waveform; root["scale_x"] = scale_x.JsonValue(); root["scale_y"] = scale_y.JsonValue(); @@ -814,6 +823,8 @@ void Clip::SetJsonValue(Json::Value root) { scale = (ScaleType) root["scale"].asInt(); if (!root["anchor"].isNull()) anchor = (AnchorType) root["anchor"].asInt(); + if (!root["display"].isNull()) + display = (FrameDisplayType) root["display"].asInt(); if (!root["waveform"].isNull()) waveform = root["waveform"].asBool(); if (!root["scale_x"].isNull()) diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index 1e816265..ce62680b 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -1659,7 +1659,7 @@ void FFmpegReader::CheckWorkingFrames(bool end_of_stream, long int requested_fra if (!info.has_audio) is_audio_ready = true; // Make final any frames that get stuck (for whatever reason) - if (checked_count > 40 && (!is_video_ready || !is_audio_ready)) { + if (checked_count > 80 && (!is_video_ready || !is_audio_ready)) { // Debug output ZmqLogger::Instance()->AppendDebugMethod("FFmpegReader::CheckWorkingFrames (exceeded checked_count)", "requested_frame", requested_frame, "frame_number", f->number, "is_video_ready", is_video_ready, "is_audio_ready", is_audio_ready, "checked_count", checked_count, "checked_frames.size()", checked_frames.size()); diff --git a/src/Timeline.cpp b/src/Timeline.cpp index 4b524ba5..3afe1ec1 100644 --- a/src/Timeline.cpp +++ b/src/Timeline.cpp @@ -518,6 +518,29 @@ void Timeline::add_layer(tr1::shared_ptr new_frame, Clip* source_clip, lo painter.setCompositionMode(QPainter::CompositionMode_SourceOver); painter.drawImage(0, 0, *source_image); + // Draw frame #'s on top of image (if needed) + if (source_clip->display != FRAME_DISPLAY_NONE) { + stringstream frame_number_str; + switch (source_clip->display) + { + case (FRAME_DISPLAY_CLIP): + frame_number_str << clip_frame_number; + break; + + case (FRAME_DISPLAY_TIMELINE): + frame_number_str << timeline_frame_number; + break; + + case (FRAME_DISPLAY_BOTH): + frame_number_str << timeline_frame_number << " (" << clip_frame_number << ")"; + break; + } + + // Draw frame number on top of image + painter.setPen(QColor("#ffffff")); + painter.drawText(20, 20, QString(frame_number_str.str().c_str())); + } + painter.end(); // Debug output