fixed urgent bug that irreparably deleted sequences

This commit is contained in:
itsmattkc
2018-11-05 17:59:29 +11:00
parent 74df34cd76
commit e342294917
12 changed files with 104 additions and 56 deletions
+16 -15
View File
@@ -203,26 +203,26 @@ void PreviewGenerator::generate_waveform() {
}
}
}
AVPacket packet;
AVPacket* packet = av_packet_alloc();
bool done = true;
bool end_of_file = false;
// get the ball rolling
av_read_frame(fmt_ctx, &packet);
avcodec_send_packet(codec_ctx[packet.stream_index], &packet);
av_read_frame(fmt_ctx, packet);
avcodec_send_packet(codec_ctx[packet->stream_index], packet);
while (!end_of_file) {
while (codec_ctx[packet.stream_index] == NULL || avcodec_receive_frame(codec_ctx[packet.stream_index], temp_frame) == AVERROR(EAGAIN)) {
av_packet_unref(&packet);
int read_ret = av_read_frame(fmt_ctx, &packet);
while (codec_ctx[packet->stream_index] == NULL || avcodec_receive_frame(codec_ctx[packet->stream_index], temp_frame) == AVERROR(EAGAIN)) {
av_packet_unref(packet);
int read_ret = av_read_frame(fmt_ctx, packet);
if (read_ret < 0) {
end_of_file = true;
if (read_ret != AVERROR_EOF) dout << "[ERROR] Failed to read packet for preview generation" << read_ret;
break;
}
if (codec_ctx[packet.stream_index] != NULL) {
int send_ret = avcodec_send_packet(codec_ctx[packet.stream_index], &packet);
if (codec_ctx[packet->stream_index] != NULL) {
int send_ret = avcodec_send_packet(codec_ctx[packet->stream_index], packet);
if (send_ret < 0 && send_ret != AVERROR(EAGAIN)) {
dout << "[ERROR] Failed to send packet for preview generation - aborting" << send_ret;
end_of_file = true;
@@ -231,9 +231,9 @@ void PreviewGenerator::generate_waveform() {
}
}
if (!end_of_file) {
MediaStream* s = media->get_stream_from_file_index(fmt_ctx->streams[packet.stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO, packet.stream_index);
MediaStream* s = media->get_stream_from_file_index(fmt_ctx->streams[packet->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO, packet->stream_index);
if (s != NULL) {
if (fmt_ctx->streams[packet.stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
if (fmt_ctx->streams[packet->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
if (!s->preview_done) {
int dstH = 120;
int dstW = dstH * ((float)temp_frame->width/(float)temp_frame->height);
@@ -267,12 +267,12 @@ void PreviewGenerator::generate_waveform() {
sws_freeContext(sws_ctx);
if (!retrieve_duration) {
avcodec_close(codec_ctx[packet.stream_index]);
codec_ctx[packet.stream_index] = NULL;
avcodec_close(codec_ctx[packet->stream_index]);
codec_ctx[packet->stream_index] = NULL;
}
}
media_lengths[packet.stream_index]++;
} else if (fmt_ctx->streams[packet.stream_index]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
media_lengths[packet->stream_index]++;
} else if (fmt_ctx->streams[packet->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
int interval = qFloor((temp_frame->sample_rate/WAVEFORM_RESOLUTION)/4)*4;
AVFrame* swr_frame = av_frame_alloc();
@@ -349,13 +349,14 @@ void PreviewGenerator::generate_waveform() {
break;
}
}
av_packet_unref(&packet);
av_packet_unref(packet);
}
}
for (int i=0;i<media->audio_tracks.size();i++) {
media->audio_tracks.at(i)->preview_done = true;
}
av_frame_free(&temp_frame);
av_packet_free(&packet);
for (unsigned int i=0;i<fmt_ctx->nb_streams;i++) {
if (codec_ctx[i] != NULL) {
avcodec_close(codec_ctx[i]);
+11 -4
View File
@@ -729,13 +729,12 @@ void MainWindow::on_actionLink_Unlink_triggered()
if (panel_timeline->focused()) panel_timeline->toggle_links();
}
void MainWindow::on_actionRipple_To_In_Point_triggered()
{
if (panel_timeline->focused()) panel_timeline->ripple_to_in_point(true);
void MainWindow::on_actionRipple_To_In_Point_triggered() {
if (panel_timeline->focused()) panel_timeline->ripple_to_in_point(true, true);
}
void MainWindow::on_actionRipple_to_Out_Point_triggered() {
if (panel_timeline->focused()) panel_timeline->ripple_to_in_point(false);
if (panel_timeline->focused()) panel_timeline->ripple_to_in_point(false, true);
}
void MainWindow::on_actionSet_In_Point_triggered() {
@@ -880,3 +879,11 @@ void MainWindow::on_actionAudio_Scrubbing_triggered() {
void MainWindow::on_actionTransition_Tool_triggered() {
if (panel_timeline->focused()) panel_timeline->ui->toolTransitionButton->click();
}
void MainWindow::on_actionEdit_to_In_Point_triggered() {
if (panel_timeline->focused()) panel_timeline->ripple_to_in_point(true, false);
}
void MainWindow::on_actionEdit_to_Out_Point_triggered() {
if (panel_timeline->focused()) panel_timeline->ripple_to_in_point(false, false);
}
+4
View File
@@ -193,6 +193,10 @@ private slots:
void on_actionTransition_Tool_triggered();
void on_actionEdit_to_In_Point_triggered();
void on_actionEdit_to_Out_Point_triggered();
private:
Ui::MainWindow *ui;
void setup_layout();
+18
View File
@@ -87,6 +87,8 @@
<addaction name="actionLink_Unlink"/>
<addaction name="actionRipple_To_In_Point"/>
<addaction name="actionRipple_to_Out_Point"/>
<addaction name="actionEdit_to_In_Point"/>
<addaction name="actionEdit_to_Out_Point"/>
<addaction name="actionSplit_at_Playhead"/>
<addaction name="separator"/>
<addaction name="actionSet_In_Point"/>
@@ -824,6 +826,22 @@
<string>T</string>
</property>
</action>
<action name="actionEdit_to_In_Point">
<property name="text">
<string>Edit to In Point</string>
</property>
<property name="shortcut">
<string>Ctrl+Alt+Q</string>
</property>
</action>
<action name="actionEdit_to_Out_Point">
<property name="text">
<string>Edit to Out Point</string>
</property>
<property name="shortcut">
<string>Ctrl+Alt+W</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
+3 -1
View File
@@ -416,14 +416,16 @@ void Project::process_file_list(bool recursive, QStringList& files, QTreeWidgetI
}
imported = true;
} else {
} else if (!files.at(i).isEmpty()) {
QString file(files.at(i));
bool skip = false;
/* Heuristic to determine whether file is part of an image sequence */
// check file extension (assume it's not a
int lastcharindex = file.lastIndexOf(".");
dout << "INFO:" << file << lastcharindex;
bool found = true;
if (lastcharindex != -1 && lastcharindex > file.lastIndexOf('/')) {
// image_sequence_formats
+33 -14
View File
@@ -702,7 +702,7 @@ void Timeline::paste() {
}
}
void Timeline::ripple_to_in_point(bool in) {
void Timeline::ripple_to_in_point(bool in, bool ripple) {
if (sequence != NULL) {
// get track count
int track_min = 0;
@@ -736,29 +736,48 @@ void Timeline::ripple_to_in_point(bool in) {
}
}
if (one_frame_mode) {
QVector<Selection> areas;
ComboAction* ca = new ComboAction();
if (one_frame_mode) {
// set up deletion areas based on track count
if (in) {
in_point = sequence->playhead;
} else {
in_point = sequence->playhead - 1;
}
for (int i=track_min;i<=track_max;i++) {
Selection s;
s.in = in_point;
s.out = in_point + 1;
s.track = i;
areas.append(s);
}
// trim and move clips around the in point
delete_areas_and_relink(ca, areas);
if (ripple) ca->append(new RippleCommand(sequence, in_point, -1));
} else {
// set up deletion areas based on track count
QVector<Selection> areas;
// set up deletion areas based on track count
for (int i=track_min;i<=track_max;i++) {
Selection s;
s.in = qMin(in_point, sequence->playhead);
s.out = qMax(in_point, sequence->playhead);
s.track = i;
areas.append(s);
}
}
// trim and move clips around the in point
ComboAction* ca = new ComboAction();
delete_areas_and_relink(ca, areas);
ca->append(new RippleCommand(sequence, in_point, (in) ? (in_point - sequence->playhead) : (sequence->playhead - in_point)));
undo_stack.push(ca);
update_ui(true);
if (in) panel_sequence_viewer->seek(in_point);
// trim and move clips around the in point
delete_areas_and_relink(ca, areas);
if (ripple) ca->append(new RippleCommand(sequence, in_point, (in) ? (in_point - sequence->playhead) : (sequence->playhead - in_point)));
}
undo_stack.push(ca);
update_ui(true);
if (in_point < sequence->playhead && ripple) panel_sequence_viewer->seek(in_point);
}
}
+1 -1
View File
@@ -92,7 +92,7 @@ public:
QVector<int> get_tracks_of_linked_clips(int i);
bool has_clip_been_split(int c);
void toggle_links();
void ripple_to_in_point(bool in);
void ripple_to_in_point(bool in, bool ripple);
void delete_in_out(bool ripple);
void previous_cut();
void next_cut();
+6 -1
View File
@@ -311,11 +311,14 @@ void Viewer::pause() {
// add it to the sequence
Clip* c = new Clip(seq);
Media* m = panel_project->last_imported_media.at(0);
m->ready_lock.lock();
c->media = m; // latest media
c->media_type = MEDIA_TYPE_FOOTAGE;
c->media_stream = 0;
c->timeline_in = recording_start;
c->timeline_out = seq->playhead;
c->timeline_out = m->get_length_in_frames(seq->frame_rate);
c->clip_in = 0;
c->track = recording_track;
c->color_r = 128;
@@ -323,6 +326,8 @@ void Viewer::pause() {
c->color_b = 128;
c->name = m->name;
m->ready_lock.unlock();
QVector<Clip*> add_clips;
add_clips.append(c);
undo_stack.push(new AddClipCommand(seq, add_clips)); // add clip
+6 -10
View File
@@ -70,6 +70,8 @@ void apply_audio_effects(Clip* c, double timecode_start, AVFrame* frame, int nb_
}
}
#define AUDIO_BUFFER_PADDING 2048
void cache_audio_worker(Clip* c, bool scrubbing, Clip* nest) {
long timeline_in = c->timeline_in;
long timeline_out = c->timeline_out;
@@ -270,7 +272,7 @@ void cache_audio_worker(Clip* c, bool scrubbing, Clip* nest) {
#endif
if (c->audio_buffer_write == 0) c->audio_buffer_write = get_buffer_offset_from_frame(c->sequence, qMax(timeline_in, c->audio_target_frame));
int offset = (audio_ibuffer_read + 512) - c->audio_buffer_write;
int offset = (audio_ibuffer_read + AUDIO_BUFFER_PADDING) - c->audio_buffer_write;
if (offset > 0) {
c->audio_buffer_write += offset;
c->frame_sample_index += offset;
@@ -325,16 +327,8 @@ void cache_audio_worker(Clip* c, bool scrubbing, Clip* nest) {
long buffer_timeline_out = get_buffer_offset_from_frame(c->sequence, timeline_out);
audio_write_lock.lock();
while (c->frame_sample_index < nb_bytes
&& c->audio_buffer_write < audio_ibuffer_read+audio_ibuffer_size-512
&& c->audio_buffer_write < audio_ibuffer_read+audio_ibuffer_size-AUDIO_BUFFER_PADDING
&& c->audio_buffer_write < buffer_timeline_out) {
/*dout << "F (" <<
c->frame_sample_index << "/" << nb_bytes
<< ") (" <<
c->audio_buffer_write << "/" << (audio_ibuffer_read+audio_ibuffer_size-512)
<< ") (" <<
c->audio_buffer_write << "/" << buffer_timeline_out << ")";*/
int upper_byte_index = (c->audio_buffer_write+1)%audio_ibuffer_size;
int lower_byte_index = (c->audio_buffer_write)%audio_ibuffer_size;
qint16 old_sample = static_cast<qint16>((audio_ibuffer[upper_byte_index] & 0xFF) << 8 | (audio_ibuffer[lower_byte_index] & 0xFF));
@@ -590,6 +584,7 @@ void open_clip_worker(Clip* clip) {
char err[1024];
av_strerror(errCode, err, 1024);
dout << "[ERROR] Could not open" << filename << "-" << err;
return;
}
errCode = avformat_find_stream_info(clip->formatCtx, NULL);
@@ -597,6 +592,7 @@ void open_clip_worker(Clip* clip) {
char err[1024];
av_strerror(errCode, err, 1024);
dout << "[ERROR] Could not open" << filename << "-" << err;
return;
}
av_dump_format(clip->formatCtx, 0, filename, 0);
+3 -4
View File
@@ -26,8 +26,7 @@ Clip::Clip(Sequence* s) :
speed(1.0),
media(NULL),
opening_transition(NULL),
closing_transition(NULL),
pkt(new AVPacket()),
closing_transition(NULL),
replaced(false),
filter_graph(NULL),
texture(NULL),
@@ -38,6 +37,7 @@ Clip::Clip(Sequence* s) :
use_existing_frame(false),
ignore_reverse(false)
{
pkt = av_packet_alloc();
reset();
}
@@ -160,8 +160,7 @@ Clip::~Clip() {
for (int i=0;i<effects.size();i++) {
delete effects.at(i);
}
av_packet_unref(pkt);
delete pkt;
av_packet_free(&pkt);
}
long Clip::get_timeline_in_with_transition() {
+1 -1
View File
@@ -355,7 +355,7 @@ AddMediaCommand::~AddMediaCommand() {
}
void AddMediaCommand::undo() {
if (parent == NULL) {
if (parent == NULL) {
panel_project->source_table->takeTopLevelItem(panel_project->source_table->indexOfTopLevelItem(item));
} else {
parent->removeChild(item);
+2 -5
View File
@@ -493,10 +493,7 @@ void TimelineWidget::wheelEvent(QWheelEvent *event) {
void TimelineWidget::dragLeaveEvent(QDragLeaveEvent*) {
if (sequence != NULL && panel_timeline->importing) {
if (panel_timeline->importing_files) {
for (int i=0;i<panel_project->last_imported_media.size();i++) {
// hack? but seems to work
undo_stack.undo();
}
undo_stack.undo();
}
panel_timeline->ghosts.clear();
panel_timeline->importing = false;
@@ -2391,7 +2388,7 @@ void TimelineWidget::paintEvent(QPaintEvent*) {
if (clip_rect.bottom() >= 0 && clip_rect.bottom() < height()) p.drawLine(QPoint(qMax(0, clip_rect.left()), clip_rect.bottom()), QPoint(qMin(width(), clip_rect.right()), clip_rect.bottom()));
// draw transition tool
if (panel_timeline->tool == TIMELINE_TOOL_TRANSITION && panel_timeline->transition_tool_clip > -1) {
if (panel_timeline->tool == TIMELINE_TOOL_TRANSITION && panel_timeline->transition_tool_clip == i) {
QRect transition_tool_rect = clip_rect;
if (panel_timeline->transition_tool_type == TA_CLOSING_TRANSITION) {
transition_tool_rect.setLeft(transition_tool_rect.left() + (3*(transition_tool_rect.width()>>2)));