Пример #1
0
std::tr1::shared_ptr<AegiVideoFrame> ThreadedFrameSource::ProcFrame(int frameNum, double time, bool raw) {
	std::tr1::shared_ptr<AegiVideoFrame> frame(new AegiVideoFrame, delete_frame);
	{
		wxMutexLocker locker(providerMutex);
		try {
			frame->CopyFrom(videoProvider->GetFrame(frameNum));
		}
		catch (VideoProviderError const& err) { throw VideoProviderErrorEvent(err); }
	}

	// This deliberately results in a call to LoadSubtitles while a render
	// is pending making the queued render use the new file
	if (!raw) {
		try {
			wxMutexLocker locker(fileMutex);
			if (subs.get() && singleFrame != frameNum) {
				// Generally edits and seeks come in groups; if the last thing done
				// was seek it is more likely that the user will seek again and
				// vice versa. As such, if this is the first frame requested after
				// an edit, only export the currently visible lines (because the
				// other lines will probably not be viewed before the file changes
				// again), and if it's a different frame, export the entire file.
				if (singleFrame == -1) {
					AssExporter exporter(subs.get());
					exporter.AddAutoFilters();
					exporter.ExportTransform();

					singleFrame = frameNum;
					// Copying a nontrivially sized AssFile is fairly slow, so
					// instead muck around with its innards to just temporarily
					// remove the non-visible lines without deleting them
					std::list<AssEntry*> visible;
					std::remove_copy_if(subs->Line.begin(), subs->Line.end(),
						std::back_inserter(visible),
						invisible_line(time));
					try {
						std::swap(subs->Line, visible);
						provider->LoadSubtitles(subs.get());
						std::swap(subs->Line, visible);
					}
					catch(...) {
						std::swap(subs->Line, visible);
						throw;
					}
				}
				else {
					provider->LoadSubtitles(subs.get());
					subs.reset();
				}
			}
		}
		catch (wxString const& err) { throw SubtitlesProviderErrorEvent(err); }

		provider->DrawSubtitles(*frame, time);
	}
	return frame;
}
Пример #2
0
std::shared_ptr<AegiVideoFrame> ThreadedFrameSource::ProcFrame(int frameNum, double time, bool raw) {
	std::shared_ptr<AegiVideoFrame> frame(new AegiVideoFrame, [](AegiVideoFrame *frame) {
		frame->Clear();
		delete frame;
	});

	{
		wxMutexLocker locker(providerMutex);
		try {
			frame->CopyFrom(videoProvider->GetFrame(frameNum));
		}
		catch (VideoProviderError const& err) { throw VideoProviderErrorEvent(err); }
	}

	// This deliberately results in a call to LoadSubtitles while a render
	// is pending making the queued render use the new file
	if (!raw && provider) {
		try {
			wxMutexLocker locker(fileMutex);
			if (subs.get() && singleFrame != frameNum) {
				// Generally edits and seeks come in groups; if the last thing done
				// was seek it is more likely that the user will seek again and
				// vice versa. As such, if this is the first frame requested after
				// an edit, only export the currently visible lines (because the
				// other lines will probably not be viewed before the file changes
				// again), and if it's a different frame, export the entire file.
				if (singleFrame == -1) {
					// This will crash if any of the export filters try to use
					// anything but the subtitles, but that wouldn't be safe to
					// do anyway
					agi::Context c;
					memset(&c, 0, sizeof c);
					c.ass = subs.get();

					AssExporter exporter(&c);
					exporter.AddAutoFilters();
					exporter.ExportTransform();

					singleFrame = frameNum;
					// Copying a nontrivially sized AssFile is fairly slow, so
					// instead muck around with its innards to just temporarily
					// remove the non-visible lines without deleting them
					std::deque<AssEntry*> full;
					for (auto& line : subs->Line)
						full.push_back(&line);
					subs->Line.remove_if(invisible_line(time));

					try {
						provider->LoadSubtitles(subs.get());

						subs->Line.clear();
						boost::push_back(subs->Line, full | boost::adaptors::indirected);
					}
					catch(...) {
						subs->Line.clear();
						boost::push_back(subs->Line, full | boost::adaptors::indirected);
						throw;
					}
				}
				else {
					provider->LoadSubtitles(subs.get());
					subs.reset();
				}
			}
		}
		catch (wxString const& err) { throw SubtitlesProviderErrorEvent(err); }

		provider->DrawSubtitles(*frame, time);
	}
	return frame;
}