예제 #1
0
파일: data.cpp 프로젝트: aglenday/OpenApoc
IFile Data::load_file(const UString &path, Data::FileMode mode)
{
	IFile f;
	if (mode != Data::FileMode::Read)
	{
		LogError("Invalid FileMode set for \"%s\"", path.c_str());
		return f;
	}
	UString foundPath = GetCorrectCaseFilename(path);
	if (foundPath == "")
	{
		LogInfo("Failed to find \"%s\"", path.c_str());
		assert(!f);
		return f;
	}
	f.f.reset(new PhysfsIFileImpl(foundPath, path));
	f.rdbuf(dynamic_cast<PhysfsIFileImpl *>(f.f.get()));
	LogInfo("Loading \"%s\" from \"%s\"", path.c_str(), f.systemPath().c_str());
	return f;
}
예제 #2
0
IFile FileSystem::open(const UString &path)
{
	TRACE_FN_ARGS1("PATH", path);
	IFile f;

	auto lowerPath = path.toLower();
	if (path != lowerPath)
	{
		LogError("Path \"%s\" contains CAPITAL - cut it out!", path);
	}

	if (!PHYSFS_exists(path.cStr()))
	{
		LogInfo("Failed to find \"%s\"", path);
		LogAssert(!f);
		return f;
	}
	f.f.reset(new PhysfsIFileImpl(path));
	f.rdbuf(dynamic_cast<PhysfsIFileImpl *>(f.f.get()));
	LogInfo("Loading \"%s\" from \"%s\"", path, f.systemPath());
	return f;
}
예제 #3
0
	bool load(IFile &file)
	{
		TRACE_FN;
		double usf; // uSeconds per frame
		this->video_data = file.readAll();
		this->video_data_size = file.size();

		auto video_path = file.systemPath();
		this->file_path = video_path;

		LogInfo("Read %llu bytes from video",
		        static_cast<unsigned long long>(this->video_data_size));

		this->smk_ctx = smk_open_memory(reinterpret_cast<unsigned char *>(this->video_data.get()),
		                                static_cast<unsigned long>(this->video_data_size));
		if (!this->smk_ctx)
		{
			LogWarning("Failed to read SMK file \"%s\"", video_path.cStr());
			this->video_data.reset();
			return false;
		}
		LogInfo("Successfully created SMK context");

		if (smk_info_all(this->smk_ctx, nullptr, &this->frame_count, &usf))
		{
			LogWarning("Failed to read SMK file info from \"%s\"", video_path.cStr());
			this->video_data.reset();
			smk_close(this->smk_ctx);
			this->smk_ctx = nullptr;
			return false;
		}

		this->frame_time = std::chrono::nanoseconds((unsigned int)(usf * 1000));

		LogInfo("Video frame count %lu, ns per frame = %u (USF: %f)", this->frame_count,
		        this->frame_time.count(), usf);

		unsigned long height, width;
		if (smk_info_video(this->smk_ctx, &width, &height, nullptr))
		{
			LogWarning("Failed to read SMK video info from \"%s\"", video_path.cStr());
			this->video_data.reset();
			smk_close(this->smk_ctx);
			this->smk_ctx = nullptr;
			return false;
		}

		this->frame_size = {width, height};
		LogInfo("Video frame size {%u,%u}", this->frame_size.x, this->frame_size.y);

		auto ret = smk_enable_video(this->smk_ctx, 1);
		if (ret == SMK_ERROR)
		{
			LogWarning("Error enabling video for \"%s\"", video_path.cStr());
			return false;
		}

		unsigned char audio_track_mask;
		unsigned char channels[7];
		unsigned char bitdepth[7];
		unsigned long audio_rate[7];

		ret = smk_info_audio(this->smk_ctx, &audio_track_mask, channels, bitdepth, audio_rate);
		if (ret == SMK_ERROR)
		{
			LogWarning("Error reading audio info for \"%s\"", video_path.cStr());
			return false;
		}

		if (audio_track_mask & SMK_AUDIO_TRACK_0)
		{
			// WE only support a single track
			LogInfo("Audio track: channels %u depth %u rate %lu", (unsigned)channels[0],
			        (unsigned)bitdepth[0], audio_rate[0]);
		}
		else
		{
			LogWarning("Unsupported audio track mask 0x%02x for \"%s\"", (unsigned)audio_track_mask,
			           video_path.cStr());
			return false;
		}
		switch (channels[0])
		{
			case 1:
				// Mono
				this->audio_format.channels = 1;
				break;

			case 2:
				// Stereo
				this->audio_format.channels = 2;
				break;
			default:
				LogWarning("Unsupported audio channel count %u for \"%s\"", (unsigned)channels[0],
				           video_path.cStr());
				return false;
		}
		switch (bitdepth[0])
		{
			case 8:
				this->audio_format.format = AudioFormat::SampleFormat::PCM_UINT8;
				this->audio_bytes_per_sample = 1;
				break;
			case 16:
				this->audio_format.format = AudioFormat::SampleFormat::PCM_SINT16;
				this->audio_bytes_per_sample = 2;
				break;
			default:
				LogWarning("Unsupported audio bit depth %u for \"%s\"", (unsigned)bitdepth[0],
				           video_path.cStr());
				return false;
		}
		this->audio_format.frequency = audio_rate[0];

		ret = smk_enable_audio(this->smk_ctx, 0, 1);

		if (ret == SMK_ERROR)
		{
			LogWarning("Error enabling audio track 0 for \"%s\"", video_path.cStr());
		}

		// Everything looks  good
		return true;
	}