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_;