Motown: Add examples/media_test, a command line media player app.
R=johngro@google.com
Review URL: https://codereview.chromium.org/1809703003 .
diff --git a/examples/BUILD.gn b/examples/BUILD.gn
index 8a5b07e..e93c3c3 100644
--- a/examples/BUILD.gn
+++ b/examples/BUILD.gn
@@ -22,6 +22,7 @@
"//examples/hello_mojo",
"//examples/http_handler",
"//examples/indirect_service",
+ "//examples/media_test",
"//examples/native_run_app",
"//examples/notification_generator",
"//examples/recursive_content_handler",
diff --git a/examples/media_test/BUILD.gn b/examples/media_test/BUILD.gn
new file mode 100644
index 0000000..55a3078
--- /dev/null
+++ b/examples/media_test/BUILD.gn
@@ -0,0 +1,28 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//mojo/public/mojo_application.gni")
+
+mojo_native_application("media_test") {
+ sources = [
+ "keystroke.cc",
+ "keystroke.h",
+ "media_test.cc",
+ "media_test.h",
+ "media_test_app.cc",
+ ]
+
+ deps = [
+ "//base",
+ "//mojo/application",
+ "//mojo/environment:chromium",
+ "//mojo/gpu",
+ "//mojo/public/cpp/bindings",
+ "//mojo/public/cpp/utility",
+ "//mojo/public/interfaces/application",
+ "//mojo/services/media/common/cpp",
+ "//mojo/services/media/common/interfaces",
+ "//mojo/services/media/control/interfaces",
+ ]
+}
diff --git a/examples/media_test/keystroke.cc b/examples/media_test/keystroke.cc
new file mode 100644
index 0000000..9e12063
--- /dev/null
+++ b/examples/media_test/keystroke.cc
@@ -0,0 +1,52 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <iostream>
+
+#include "examples/media_test/keystroke.h"
+
+namespace mojo {
+namespace media {
+namespace examples {
+
+namespace {
+
+bool eat_newline = false;
+bool upped_already = false;
+
+} // namespace
+
+char Keystroke(void) {
+ const char *kUp = "\033[A";
+
+ fcntl(STDIN_FILENO, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK);
+ char buf[1];
+ if (read(STDIN_FILENO, buf, 1) > 0) {
+ if (!upped_already) {
+ std::cout << kUp << std::flush;
+ upped_already = true;
+ }
+
+ if (buf[0] == '\n') {
+ upped_already = false;
+ if (eat_newline) {
+ eat_newline = false;
+ } else {
+ return buf[0];
+ }
+ } else {
+ eat_newline = true;
+ return buf[0];
+ }
+ }
+ return 0;
+}
+
+} // namespace examples
+} // namespace media
+} // namespace mojo
diff --git a/examples/media_test/keystroke.h b/examples/media_test/keystroke.h
new file mode 100644
index 0000000..7da4b63
--- /dev/null
+++ b/examples/media_test/keystroke.h
@@ -0,0 +1,22 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EXAMPLES_MEDIA_TEST_KEYSTROKE_H_
+#define EXAMPLES_MEDIA_TEST_KEYSTROKE_H_
+
+namespace mojo {
+namespace media {
+namespace examples {
+
+// Returns keystroke or 0 if no key has been pressed. This is non-blocking,
+// but requires the user to hit enter and doesn't suppress echo. Enter alone
+// produces a newline ('\n'). If non-newline characters are entered, the
+// terminating newline is suppressed.
+char Keystroke();
+
+} // namespace examples
+} // namespace media
+} // namespace mojo
+
+#endif // EXAMPLES_MEDIA_TEST_KEYSTROKE_H_
diff --git a/examples/media_test/media_test.cc b/examples/media_test/media_test.cc
new file mode 100644
index 0000000..206e959
--- /dev/null
+++ b/examples/media_test/media_test.cc
@@ -0,0 +1,111 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "examples/media_test/media_test.h"
+#include "mojo/services/media/common/cpp/linear_transform.h"
+#include "mojo/services/media/common/cpp/local_time.h"
+#include "mojo/services/media/control/interfaces/media_factory.mojom.h"
+
+namespace mojo {
+namespace media {
+namespace examples {
+
+// static
+std::unique_ptr<MediaTest> MediaTest::Create(
+ mojo::ApplicationImpl* app,
+ const std::string& input_file_name) {
+ return std::unique_ptr<MediaTest>(new MediaTest(app, input_file_name));
+}
+
+MediaTest::MediaTest(
+ mojo::ApplicationImpl* app,
+ const std::string& input_file_name) :
+ state_(MediaState::UNPREPARED) {
+ MediaFactoryPtr factory;
+ app->ConnectToService("mojo:media_factory", &factory);
+
+ factory->CreatePlayer(input_file_name, GetProxy(&media_player_));
+
+ HandleStatusUpdates();
+}
+
+MediaTest::~MediaTest() {}
+
+void MediaTest::RegisterUpdateCallback(const UpdateCallback& callback) {
+ update_callback_ = callback;
+}
+
+void MediaTest::Play() {
+ media_player_->Play();
+}
+
+void MediaTest::Pause() {
+ media_player_->Pause();
+}
+
+void MediaTest::Seek(int64_t position_ns) {
+ media_player_->Seek(position_ns);
+}
+
+MediaState MediaTest::state() const {
+ return state_;
+}
+
+int64_t MediaTest::position_ns() const {
+ // Apply the transform to the current time.
+ int64_t position;
+ transform_.DoForwardTransform(
+ LocalClock::now().time_since_epoch().count(),
+ &position);
+
+ MOJO_DCHECK(position >= 0);
+
+ if (metadata_ &&
+ static_cast<uint64_t>(position) > metadata_->duration) {
+ position = metadata_->duration;
+ }
+
+ return position;
+}
+
+const MediaMetadataPtr& MediaTest::metadata() const {
+ return metadata_;
+}
+
+void MediaTest::HandleStatusUpdates(
+ uint64_t version,
+ MediaPlayerStatusPtr status) {
+ if (status) {
+ // Process status received from the player.
+ state_ = status->state;
+
+ // Create a linear transform that translates local time to presentation
+ // time. Note that 'reference' here refers to the presentation time, and
+ // 'target' refers to the local time.
+ if (status->timeline_transform) {
+ transform_ = LinearTransform(
+ status->timeline_transform->quad->target_offset,
+ status->timeline_transform->quad->reference_delta,
+ status->timeline_transform->quad->target_delta,
+ status->timeline_transform->quad->reference_offset);
+ }
+
+ metadata_ = status->metadata.Pass();
+
+ if (update_callback_ != nullptr) {
+ update_callback_();
+ }
+ }
+
+ // Request a status update.
+ media_player_->GetStatus(
+ version,
+ [this](uint64_t version, MediaPlayerStatusPtr status) {
+ HandleStatusUpdates(version, status.Pass());
+ });
+}
+
+} // namespace examples
+} // namespace media
+} // namespace mojo
diff --git a/examples/media_test/media_test.h b/examples/media_test/media_test.h
new file mode 100644
index 0000000..2c03118
--- /dev/null
+++ b/examples/media_test/media_test.h
@@ -0,0 +1,73 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EXAMPLES_MEDIA_TEST_MEDIA_TEST_H_
+#define EXAMPLES_MEDIA_TEST_MEDIA_TEST_H_
+
+#include "base/macros.h"
+#include "mojo/public/cpp/application/application_impl.h"
+#include "mojo/services/media/common/cpp/linear_transform.h"
+#include "mojo/services/media/common/interfaces/rate_control.mojom.h"
+#include "mojo/services/media/control/interfaces/media_factory.mojom.h"
+#include "mojo/services/media/control/interfaces/media_player.mojom.h"
+
+namespace mojo {
+namespace media {
+namespace examples {
+
+// Model for media test application.
+class MediaTest {
+ public:
+ using UpdateCallback = std::function<void()>;
+
+ static std::unique_ptr<MediaTest> Create(
+ mojo::ApplicationImpl* app,
+ const std::string& input_file_name);
+
+ ~MediaTest();
+
+ // Registers a callback signalling that the app should update its view.
+ void RegisterUpdateCallback(const UpdateCallback& callback);
+
+ // Starts playback.
+ void Play();
+
+ // Pauses playback.
+ void Pause();
+
+ // Seeks to the position indicated in nanoseconds from the start of the media.
+ void Seek(int64_t position_ns);
+
+ // Returns the current state of the player.
+ MediaState state() const;
+
+ // Returns the current presentation time in nanoseconds.
+ int64_t position_ns() const;
+
+ // Returns the current media metadata, if there is any.
+ const MediaMetadataPtr& metadata() const;
+
+ private:
+ MediaTest(mojo::ApplicationImpl* app, const std::string& input_file_name);
+
+ // Handles a status update from the player. When called with the default
+ // argument values, initiates status updates.
+ void HandleStatusUpdates(
+ uint64_t version = MediaPlayer::kInitialStatus,
+ MediaPlayerStatusPtr status = nullptr);
+
+ MediaPlayerPtr media_player_;
+ MediaState state_;
+ LinearTransform transform_ = LinearTransform(0, 0, 1, 0);
+ MediaMetadataPtr metadata_;
+ UpdateCallback update_callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(MediaTest);
+};
+
+} // namespace examples
+} // namespace media
+} // namespace mojo
+
+#endif // EXAMPLES_MEDIA_TEST_MEDIA_TEST_H_
diff --git a/examples/media_test/media_test_app.cc b/examples/media_test/media_test_app.cc
new file mode 100644
index 0000000..b916f61
--- /dev/null
+++ b/examples/media_test/media_test_app.cc
@@ -0,0 +1,332 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <deque>
+#include <iomanip>
+#include <iostream>
+
+#include "base/bind.h"
+#include "examples/media_test/keystroke.h"
+#include "examples/media_test/media_test.h"
+#include "mojo/application/application_runner_chromium.h"
+#include "mojo/public/c/system/main.h"
+#include "mojo/public/cpp/application/application_connection.h"
+#include "mojo/public/cpp/application/application_delegate.h"
+#include "mojo/public/cpp/application/application_impl.h"
+
+namespace mojo {
+namespace media {
+namespace examples {
+
+class MediaTestApp : public mojo::ApplicationDelegate {
+ public:
+ MediaTestApp() {}
+
+ ~MediaTestApp() override {}
+
+ // ApplicationDelegate implementation.
+ void Initialize(mojo::ApplicationImpl* app) override {
+ app_ = app;
+ ProcessArgs(app->args());
+
+ std::cout << std::endl << "MEDIA TEST" << std::endl << std::endl;
+
+ if (input_file_names_.empty()) {
+ std::cout << "Please provide the names of the files you want to play;"
+ << " for example:" << std::endl;
+ std::cout << "mojo/devtools/common/mojo_run \\" << std::endl;
+ std::cout << " \"https://core.mojoapps.io/media_test.mojo \\"
+ << std::endl;
+ std::cout << " file:///usr/local/google/home/you/superstition.ogg \\"
+ << std::endl;
+ std::cout << " file:///usr/local/google/home/you/higherground.ogg\""
+ << std::endl << std::endl;
+ base::MessageLoop::current()->Quit();
+ return;
+ }
+
+ std::cout << " <enter> play/pause" << std::endl;
+ std::cout << " n<enter> next file" << std::endl;
+ std::cout << " p<enter> previous file" << std::endl;
+ std::cout << " <digit><enter> seek (0% - 90%)" << std::endl;
+ std::cout << " q<enter> quit" << std::endl << std::endl;
+
+ if (paint_) {
+ std::cout << " duration <none>" << std::endl;
+ std::cout << " title <none>" << std::endl;
+ std::cout << " artist <none>" << std::endl;
+ std::cout << " album <none>" << std::endl;
+ std::cout << " publisher <none>" << std::endl;
+ std::cout << " genre <none>" << std::endl;
+ std::cout << " composer <none>" << std::endl << std::endl;
+ std::cout << std::endl << std::endl << kUp << std::flush;
+ } else {
+ std::cout << std::endl;
+ }
+
+ CreateNewMediaTest();
+ Poll();
+ }
+
+ bool ConfigureIncomingConnection(
+ mojo::ApplicationConnection* connection) override {
+ return true;
+ }
+
+ private:
+ static const char *kHome;
+ static const char *kClearLine;
+ static const char *kUp;
+ static constexpr double ns_per_second = 1000000000.0;
+
+ // Processes arguments.
+ void ProcessArgs(const std::vector<std::string>& args) {
+ for (size_t i = 1; i < args.size(); ++i) {
+ const std::string& arg = args[i];
+ if (arg == "--paint") {
+ paint_ = true;
+ } else if (arg == "--no-paint") {
+ paint_ = false;
+ } else {
+ input_file_names_.push_back(arg);
+ }
+ }
+
+ input_file_names_iter_ = input_file_names_.begin();
+ }
+
+ // Creates a new MediaTest object to play the file referenced by
+ // input_file_names_iter_.
+ void CreateNewMediaTest() {
+ MOJO_DCHECK(input_file_names_iter_ != input_file_names_.end());
+ media_test_ = MediaTest::Create(app_, *input_file_names_iter_);
+
+ metadata_shown_ = false;
+ media_test_->RegisterUpdateCallback([this]() {
+ HandleMediaTestUpdateCallback();
+ });
+
+ media_test_->Play();
+ }
+
+ void HandleMediaTestUpdateCallback() {
+ if (media_test_->state() == MediaState::ENDED) {
+ // MediaTest doesn't appreciate being deleted in this callback.
+ // Next time Poll runs, we move on to the next file.
+ base::MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&MediaTestApp::PlayNext, base::Unretained(this)));
+ }
+
+ const MediaMetadataPtr& metadata = media_test_->metadata();
+
+ if (metadata) {
+ duration_ns_ = metadata->duration;
+ }
+
+ if (paint_) {
+ // Move the cursor up the terminal so we paint over the old metadata
+ // (7 lines) a blank line and the state line (total of 9 lines).
+ std::cout << kHome
+ << kUp << kUp << kUp << kUp << kUp << kUp << kUp << kUp << kUp;
+ }
+
+ if (!paint_ && metadata_shown_) {
+ // Do nothing.
+ } else if (metadata) {
+ metadata_shown_ = true;
+ std::cout << " duration " << std::setprecision(1) <<
+ double(metadata->duration) / ns_per_second << " seconds"
+ << clear_line() << std::endl;
+ std::cout << " title " <<
+ (metadata->title ? metadata->title : "<none>")
+ << clear_line() << std::endl;
+ std::cout << " artist " <<
+ (metadata->artist ? metadata->artist : "<none>")
+ << clear_line() << std::endl;
+ std::cout << " album " <<
+ (metadata->album ? metadata->album : "<none>")
+ << clear_line() << std::endl;
+ std::cout << " publisher " <<
+ (metadata->publisher ? metadata->publisher : "<none>")
+ << clear_line() << std::endl;
+ std::cout << " genre " <<
+ (metadata->genre ? metadata->genre : "<none>")
+ << clear_line() << std::endl;
+ std::cout << " composer " <<
+ (metadata->composer ? metadata->composer : "<none>")
+ << clear_line() << std::endl << std::endl;
+ } else {
+ std::cout << " duration <none>" << kClearLine << std::endl;
+ std::cout << " title <none>" << kClearLine << std::endl;
+ std::cout << " artist <none>" << kClearLine << std::endl;
+ std::cout << " album <none>" << kClearLine << std::endl;
+ std::cout << " publisher <none>" << kClearLine << std::endl;
+ std::cout << " genre <none>" << kClearLine << std::endl;
+ std::cout << " composer <none>" << kClearLine << std::endl;
+ std::cout << std::endl;
+ }
+ std::cout << " " << state_string() << clear_line() << std::endl;
+ }
+
+ // Returns a string describing the MediaTest object's state.
+ const char* state_string() const {
+ switch (media_test_->state()) {
+ case MediaState::FAULT:
+ return "FAULT";
+ case MediaState::UNPREPARED:
+ return "unprepared";
+ case MediaState::PAUSED:
+ return "paused";
+ case MediaState::PLAYING:
+ return "playing";
+ case MediaState::ENDED:
+ return "ended";
+ }
+ return "UNSUPPORTED STATE VALUE";
+ }
+
+ // Handles a keystroke.
+ void HandleKeystroke(char keystroke) {
+ switch (keystroke) {
+ case '\n':
+ TogglePlayPause();
+ break;
+ case 'q':
+ base::MessageLoop::current()->Quit();
+ quit_ = true;
+ if (paint_) {
+ std::cout << kHome << kUp << " quitting" << kClearLine << std::endl
+ << kClearLine << std::endl;
+ } else {
+ std::cout << " quitting" << std::endl;
+ }
+ break;
+ case 'n':
+ if (++input_file_names_iter_ == input_file_names_.end()) {
+ input_file_names_iter_ = input_file_names_.begin();
+ }
+ CreateNewMediaTest();
+ break;
+ case 'p':
+ if (input_file_names_iter_ == input_file_names_.begin()) {
+ input_file_names_iter_ = input_file_names_.end();
+ }
+ input_file_names_iter_--;
+ CreateNewMediaTest();
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9': {
+ int64_t position_ns = ((keystroke - '0') / 10.0) * duration_ns_;
+ media_test_->Seek(position_ns);
+ if (!paint_) {
+ std::cout << " seeking to " << std::fixed << std::setprecision(1)
+ << double(position_ns) / ns_per_second
+ << " seconds " << std::endl;
+ }
+ break;
+ }
+ }
+ }
+
+ // Toggles between play and pause (prepared) states.
+ void TogglePlayPause() {
+ switch (media_test_->state()) {
+ case MediaState::PAUSED:
+ media_test_->Play();
+ break;
+ case MediaState::PLAYING:
+ media_test_->Pause();
+ break;
+ case MediaState::ENDED:
+ if (input_file_names_.size() == 1) {
+ // Replaying the only file. Reuse the same MediaTest instance.
+ media_test_->Seek(0);
+ media_test_->Play();
+ } else {
+ // Starting a new file. Create a new MediaTest instance.
+ CreateNewMediaTest();
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Does any needed work and schedules itself to run again soon. Quits when
+ // quit_ is true.
+ void Poll() {
+ MOJO_DCHECK(!quit_);
+
+ char keystroke = Keystroke();
+ if (keystroke != 0) {
+ HandleKeystroke(keystroke);
+ }
+
+ if (quit_) {
+ // Eat the any additional keystrokes, which would otherwise make it to the
+ // command shell.
+ while (Keystroke() != 0) {
+ // Do nothing.
+ }
+ return;
+ }
+
+ if (paint_) {
+ std::cout << kHome << " " << std::fixed << std::setprecision(1)
+ << double(media_test_->position_ns()) / ns_per_second
+ << " seconds " << kClearLine << std::flush;
+ }
+
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&MediaTestApp::Poll, base::Unretained(this)),
+ base::TimeDelta::FromMilliseconds(100));
+ }
+
+ void PlayNext() {
+ if (++input_file_names_iter_ == input_file_names_.end()) {
+ input_file_names_iter_ = input_file_names_.begin();
+ } else {
+ CreateNewMediaTest();
+ }
+ }
+
+ const char* clear_line() const {
+ return paint_ ? kClearLine : "";
+ }
+
+ mojo::ApplicationImpl* app_;
+ std::unique_ptr<MediaTest> media_test_;
+ std::deque<std::string> input_file_names_;
+ decltype(input_file_names_.begin()) input_file_names_iter_;
+ bool quit_ = false;
+ bool paint_ = true;
+ bool metadata_shown_ = false;
+ uint64_t duration_ns_;
+
+ DISALLOW_COPY_AND_ASSIGN(MediaTestApp);
+};
+
+const char* MediaTestApp::kHome = "\r";
+const char* MediaTestApp::kClearLine = "\033[K";
+const char* MediaTestApp::kUp = "\033[A";
+
+} // namespace examples
+} // namespace media
+} // namespace mojo
+
+MojoResult MojoMain(MojoHandle application_request) {
+ mojo::ApplicationRunnerChromium
+ runner(new mojo::media::examples::MediaTestApp);
+ return runner.Run(application_request);
+}
diff --git a/mojo/dart/packages/mojo_services/lib/mojo/media/media_player.mojom.dart b/mojo/dart/packages/mojo_services/lib/mojo/media/media_player.mojom.dart
index 29293e0..87f4dc8 100644
--- a/mojo/dart/packages/mojo_services/lib/mojo/media/media_player.mojom.dart
+++ b/mojo/dart/packages/mojo_services/lib/mojo/media/media_player.mojom.dart
@@ -487,6 +487,7 @@
void pause();
void seek(int position);
dynamic getStatus(int versionLastSeen,[Function responseFactory = null]);
+ static const int kInitialStatus = 0;
}
diff --git a/mojo/dart/packages/mojo_services/lib/mojo/media/media_sink.mojom.dart b/mojo/dart/packages/mojo_services/lib/mojo/media/media_sink.mojom.dart
index f4a441a..ae1aa27 100644
--- a/mojo/dart/packages/mojo_services/lib/mojo/media/media_sink.mojom.dart
+++ b/mojo/dart/packages/mojo_services/lib/mojo/media/media_sink.mojom.dart
@@ -756,6 +756,7 @@
dynamic getStatus(int versionLastSeen,[Function responseFactory = null]);
void play();
void pause();
+ static const int kInitialStatus = 0;
}
diff --git a/mojo/dart/packages/mojo_services/lib/mojo/media/media_source.mojom.dart b/mojo/dart/packages/mojo_services/lib/mojo/media/media_source.mojom.dart
index 284f295..bc7d94d 100644
--- a/mojo/dart/packages/mojo_services/lib/mojo/media/media_source.mojom.dart
+++ b/mojo/dart/packages/mojo_services/lib/mojo/media/media_source.mojom.dart
@@ -1471,6 +1471,7 @@
dynamic prime([Function responseFactory = null]);
dynamic flush([Function responseFactory = null]);
dynamic seek(int position,[Function responseFactory = null]);
+ static const int kInitialStatus = 0;
}
diff --git a/mojo/services/media/control/interfaces/media_player.mojom b/mojo/services/media/control/interfaces/media_player.mojom
index 12cad67..f9907bb 100644
--- a/mojo/services/media/control/interfaces/media_player.mojom
+++ b/mojo/services/media/control/interfaces/media_player.mojom
@@ -11,6 +11,10 @@
// Plays media.
interface MediaPlayer {
+ // Special value for GetStatus version_last_seen parameter to get the current
+ // status immediately.
+ const uint64 kInitialStatus = 0;
+
// Starts playback.
Play();
@@ -22,8 +26,9 @@
// TODO(dalesat): Consider adding parameters regarding desired precision.
Seek(int64 position);
- // Gets the status. To get the status immediately, call GetStatus(0). To
- // get updates thereafter, pass the version sent in the previous callback.
+ // Gets the status. To get the status immediately, call
+ // GetStatus(kInitialStatus). To get updates thereafter, pass the version
+ // sent in the previous callback.
GetStatus(uint64 version_last_seen) =>
(uint64 version, MediaPlayerStatus status);
};
diff --git a/mojo/services/media/control/interfaces/media_sink.mojom b/mojo/services/media/control/interfaces/media_sink.mojom
index efaa630..14c2f40 100644
--- a/mojo/services/media/control/interfaces/media_sink.mojom
+++ b/mojo/services/media/control/interfaces/media_sink.mojom
@@ -18,6 +18,10 @@
interface MediaSink {
// TODO(dalesat): Support fanout to many destinations.
+ // Special value for GetStatus version_last_seen parameter to get the current
+ // status immediately.
+ const uint64 kInitialStatus = 0;
+
// Gets the clock disposition from the source.
GetClockDisposition() => (ClockDisposition clock_disposition);
@@ -30,8 +34,9 @@
// Gets the consumer for the stream to be delivered.
GetConsumer(MediaConsumer& consumer);
- // Gets the status. To get the status immediately, call GetStatus(0). To
- // get updates thereafter, pass the version sent in the previous callback.
+ // Gets the status. To get the status immediately, call
+ // GetStatus(kInitialStatus). To get updates thereafter, pass the version
+ // sent in the previous callback.
GetStatus(uint64 version_last_seen) =>
(uint64 version, MediaSinkStatus status);
diff --git a/mojo/services/media/control/interfaces/media_source.mojom b/mojo/services/media/control/interfaces/media_source.mojom
index a4cebd3..59f40c4 100644
--- a/mojo/services/media/control/interfaces/media_source.mojom
+++ b/mojo/services/media/control/interfaces/media_source.mojom
@@ -14,6 +14,10 @@
// Produces media streams delivered from a specified origin.
interface MediaSource {
+ // Special value for GetStatus version_last_seen parameter to get the current
+ // status immediately.
+ const uint64 kInitialStatus = 0;
+
// Gets the streams produced by this source.
GetStreams() => (array<MediaSourceStreamDescriptor> streams);
@@ -32,8 +36,9 @@
// Gets the pull mode producer for the specified stream.
GetPullModeProducer(uint32 stream_index, MediaPullModeProducer& producer);
- // Gets the status. To get the status immediately, call GetStatus(0). To
- // get updates thereafter, pass the version sent in the previous callback.
+ // Gets the status. To get the status immediately, call
+ // GetStatus(kInitialStatus). To get updates thereafter, pass the version
+ // sent in the previous callback.
GetStatus(uint64 version_last_seen) =>
(uint64 version, MediaSourceStatus status);
diff --git a/services/media/factory_service/media_player_impl.h b/services/media/factory_service/media_player_impl.h
index d871eba..b3b3c9e 100644
--- a/services/media/factory_service/media_player_impl.h
+++ b/services/media/factory_service/media_player_impl.h
@@ -103,14 +103,14 @@
// Handles a status update from the source. When called with the default
// argument values, initiates source status updates.
void HandleSourceStatusUpdates(
- uint64_t version = 0,
+ uint64_t version = MediaSource::kInitialStatus,
MediaSourceStatusPtr status = nullptr);
// Handles a status update from a sink. When called with the default
// argument values, initiates sink status updates.
void HandleSinkStatusUpdates(
const std::unique_ptr<Stream>& stream,
- uint64_t version = 0,
+ uint64_t version = MediaSink::kInitialStatus,
MediaSinkStatusPtr status = nullptr);
Event event_;
diff --git a/services/media/framework_ffmpeg/ffmpeg_demux.cc b/services/media/framework_ffmpeg/ffmpeg_demux.cc
index e71ebfa..a00a2a7 100644
--- a/services/media/framework_ffmpeg/ffmpeg_demux.cc
+++ b/services/media/framework_ffmpeg/ffmpeg_demux.cc
@@ -76,7 +76,7 @@
static_cast<size_t>(av_packet->size),
av_packet->data),
av_packet_(std::move(av_packet)) {
- DCHECK(av_packet->size >= 0);
+ DCHECK(av_packet_->size >= 0);
}
ffmpeg::AvPacketPtr av_packet_;