Loader.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * Copyright (c) 2018-2023, the SerenityOS developers.
  3. * Copyright (c) 2024, Jelle Raaijmakers <jelle@ladybird.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include "Loader.h"
  8. #include "FFmpegLoader.h"
  9. #include <AK/TypedTransfer.h>
  10. #include <LibCore/MappedFile.h>
  11. namespace Audio {
  12. LoaderPlugin::LoaderPlugin(NonnullOwnPtr<SeekableStream> stream)
  13. : m_stream(move(stream))
  14. {
  15. }
  16. Loader::Loader(NonnullOwnPtr<LoaderPlugin> plugin)
  17. : m_plugin(move(plugin))
  18. {
  19. }
  20. struct LoaderPluginInitializer {
  21. bool (*sniff)(SeekableStream&);
  22. ErrorOr<NonnullOwnPtr<LoaderPlugin>, LoaderError> (*create)(NonnullOwnPtr<SeekableStream>);
  23. };
  24. static constexpr LoaderPluginInitializer s_initializers[] = {
  25. { FFmpegLoaderPlugin::sniff, FFmpegLoaderPlugin::create },
  26. };
  27. ErrorOr<NonnullRefPtr<Loader>, LoaderError> Loader::create(StringView path)
  28. {
  29. auto stream = TRY(Core::MappedFile::map(path, Core::MappedFile::Mode::ReadOnly));
  30. auto plugin = TRY(Loader::create_plugin(move(stream)));
  31. return adopt_ref(*new (nothrow) Loader(move(plugin)));
  32. }
  33. ErrorOr<NonnullRefPtr<Loader>, LoaderError> Loader::create(ReadonlyBytes buffer)
  34. {
  35. auto stream = TRY(try_make<FixedMemoryStream>(buffer));
  36. auto plugin = TRY(Loader::create_plugin(move(stream)));
  37. return adopt_ref(*new (nothrow) Loader(move(plugin)));
  38. }
  39. ErrorOr<NonnullOwnPtr<LoaderPlugin>, LoaderError> Loader::create_plugin(NonnullOwnPtr<SeekableStream> stream)
  40. {
  41. for (auto const& loader : s_initializers) {
  42. if (loader.sniff(*stream)) {
  43. TRY(stream->seek(0, SeekMode::SetPosition));
  44. return loader.create(move(stream));
  45. }
  46. TRY(stream->seek(0, SeekMode::SetPosition));
  47. }
  48. return LoaderError { "No loader plugin available" };
  49. }
  50. LoaderSamples Loader::get_more_samples(size_t samples_to_read_from_input)
  51. {
  52. if (m_plugin_at_end_of_stream && m_buffer.is_empty())
  53. return FixedArray<Sample> {};
  54. size_t remaining_samples = total_samples() - loaded_samples();
  55. size_t samples_to_read = min(remaining_samples, samples_to_read_from_input);
  56. auto samples = TRY(FixedArray<Sample>::create(samples_to_read));
  57. size_t sample_index = 0;
  58. if (m_buffer.size() > 0) {
  59. size_t to_transfer = min(m_buffer.size(), samples_to_read);
  60. AK::TypedTransfer<Sample>::move(samples.data(), m_buffer.data(), to_transfer);
  61. if (to_transfer < m_buffer.size())
  62. m_buffer.remove(0, to_transfer);
  63. else
  64. m_buffer.clear_with_capacity();
  65. sample_index += to_transfer;
  66. }
  67. while (sample_index < samples_to_read) {
  68. auto chunk_data = TRY(m_plugin->load_chunks(samples_to_read - sample_index));
  69. chunk_data.remove_all_matching([](auto& chunk) { return chunk.is_empty(); });
  70. if (chunk_data.is_empty()) {
  71. m_plugin_at_end_of_stream = true;
  72. break;
  73. }
  74. for (auto& chunk : chunk_data) {
  75. if (sample_index < samples_to_read) {
  76. auto count = min(samples_to_read - sample_index, chunk.size());
  77. AK::TypedTransfer<Sample>::move(samples.span().offset(sample_index), chunk.data(), count);
  78. // We didn't read all of the chunk; transfer the rest into the buffer.
  79. if (count < chunk.size()) {
  80. auto remaining_samples_count = chunk.size() - count;
  81. // We will always have an empty buffer at this point!
  82. TRY(m_buffer.try_append(chunk.span().offset(count), remaining_samples_count));
  83. }
  84. } else {
  85. // We're now past what the user requested. Transfer the entirety of the data into the buffer.
  86. TRY(m_buffer.try_append(chunk.data(), chunk.size()));
  87. }
  88. sample_index += chunk.size();
  89. }
  90. }
  91. return samples;
  92. }
  93. }