#include "clip.h" #include "effects/effect.h" #include "effects/transition.h" #include "io/media.h" #include "io/config.h" #include "playback/playback.h" #include "playback/cacher.h" #include "panels/project.h" #include "project/sequence.h" #include "panels/timeline.h" #include extern "C" { #include } Clip::Clip(Sequence* s) : sequence(s), enabled(true), clip_in(0), timeline_in(0), timeline_out(0), track(0), undeletable(0), media(NULL), opening_transition(NULL), closing_transition(NULL), pkt(new AVPacket()), replaced(false), texture(NULL), fbo(NULL), autoscale(config.autoscale_by_default) { reset(); } Clip* Clip::copy(Sequence* s) { Clip* copy = new Clip(s); copy->enabled = enabled; copy->name = QString(name); copy->clip_in = clip_in; copy->timeline_in = timeline_in; copy->timeline_out = timeline_out; copy->track = track; copy->color_r = color_r; copy->color_g = color_g; copy->color_b = color_b; copy->sequence = s; copy->media = media; copy->media_type = media_type; copy->media_stream = media_stream; copy->autoscale = autoscale; for (int i=0;ieffects.append(effects.at(i)->copy(copy)); } if (opening_transition != NULL) copy->opening_transition = opening_transition->copy(); if (closing_transition != NULL) copy->closing_transition = closing_transition->copy(); return copy; } void Clip::reset() { cache_size = false; audio_just_reset = false; cache_A.offset = false; cache_B.offset = false; open = false; finished_opening = false; pkt_written = false; cache_A.written = false; cache_B.written = false; cache_A.unread = false; cache_B.unread = false; reached_end = false; audio_reset = false; frame_sample_index = -1; audio_buffer_write = false; texture_frame = -1; formatCtx = NULL; stream = NULL; codec = NULL; codecCtx = NULL; texture = NULL; cache_A.frames = NULL; cache_B.frames = NULL; } void Clip::reset_audio() { switch (media_type) { case MEDIA_TYPE_FOOTAGE: case MEDIA_TYPE_TONE: audio_reset = true; frame_sample_index = -1; audio_buffer_write = 0; reached_end = false; break; case MEDIA_TYPE_SEQUENCE: { Sequence* nested_sequence = static_cast(media); for (int i=0;iclips.size();i++) { Clip* c = nested_sequence->clips.at(i); if (c != NULL) c->reset_audio(); } } break; } } void Clip::refresh() { // validates media if it was replaced if (replaced && media_type == MEDIA_TYPE_FOOTAGE) { Media* m = static_cast(media); media_stream = (track < 0) ? m->video_tracks.at(0)->file_index : m->audio_tracks.at(0)->file_index; } replaced = false; // reinitializes all effects... just in case for (int i=0;irefresh(); } } Clip::~Clip() { if (open) { close_clip(this); // make sure clip has closed before clip is destroyed if (multithreaded && media_type == MEDIA_TYPE_FOOTAGE) { cacher->wait(); } } if (opening_transition != NULL) delete opening_transition; if (closing_transition != NULL) delete closing_transition; for (int i=0;ilink != NULL) { return timeline_in - opening_transition->link->length; } else { return timeline_in; } } long Clip::get_timeline_out_with_transition() { if (closing_transition != NULL && closing_transition->link != NULL) { return timeline_out + closing_transition->link->length; } else { return timeline_out; } } // timeline functions long Clip::getLength() { return timeline_out - timeline_in; } long Clip::getMediaLength(double framerate) { switch (media_type) { case MEDIA_TYPE_FOOTAGE: { Media* m = static_cast(media); if (m->get_stream_from_file_index(track < 0, media_stream)->infinite_length) { return LONG_MAX; } else { return m->get_length_in_frames(framerate); } } break; case MEDIA_TYPE_SEQUENCE: { Sequence* s = static_cast(media); return refactor_frame_number(s->getEndFrame(), s->frame_rate, framerate); } case MEDIA_TYPE_SOLID: case MEDIA_TYPE_TONE: return LONG_MAX; } return 0; } int Clip::getWidth() { if (media == NULL && sequence != NULL) return sequence->width; switch (media_type) { case MEDIA_TYPE_FOOTAGE: { MediaStream* ms = static_cast(media)->get_stream_from_file_index(track < 0, media_stream); if (ms != NULL) return ms->video_width; if (sequence != NULL) return sequence->width; } case MEDIA_TYPE_SEQUENCE: { Sequence* s = static_cast(media); return s->width; } } return 0; } int Clip::getHeight() { if (media == NULL && sequence != NULL) return sequence->height; switch (media_type) { case MEDIA_TYPE_FOOTAGE: { MediaStream* ms = static_cast(media)->get_stream_from_file_index(track < 0, media_stream); if (ms != NULL) return ms->video_height; if (sequence != NULL) return sequence->height; } case MEDIA_TYPE_SEQUENCE: { Sequence* s = static_cast(media); return s->height; } } return 0; }