| Index: services/media/audio/platform/generic/standard_output_base.h
 | 
| diff --git a/services/media/audio/platform/generic/standard_output_base.h b/services/media/audio/platform/generic/standard_output_base.h
 | 
| new file mode 100644
 | 
| index 0000000000000000000000000000000000000000..fe3205a9a77901777c208781a7da46769c153f3f
 | 
| --- /dev/null
 | 
| +++ b/services/media/audio/platform/generic/standard_output_base.h
 | 
| @@ -0,0 +1,117 @@
 | 
| +// 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 SERVICES_MEDIA_AUDIO_PLATFORM_GENERIC_STANDARD_OUTPUT_BASE_H_
 | 
| +#define SERVICES_MEDIA_AUDIO_PLATFORM_GENERIC_STANDARD_OUTPUT_BASE_H_
 | 
| +
 | 
| +#include "base/callback.h"
 | 
| +#include "mojo/services/media/common/cpp/linear_transform.h"
 | 
| +#include "mojo/services/media/common/cpp/local_time.h"
 | 
| +#include "mojo/services/media/common/interfaces/media_common.mojom.h"
 | 
| +#include "mojo/services/media/common/interfaces/media_types.mojom.h"
 | 
| +#include "services/media/audio/audio_output.h"
 | 
| +#include "services/media/audio/audio_track_to_output_link.h"
 | 
| +#include "services/media/audio/platform/generic/mixer.h"
 | 
| +
 | 
| +namespace mojo {
 | 
| +namespace media {
 | 
| +namespace audio {
 | 
| +
 | 
| +class StandardOutputBase : public AudioOutput {
 | 
| + public:
 | 
| +  ~StandardOutputBase() override;
 | 
| +
 | 
| + protected:
 | 
| +  struct MixJob {
 | 
| +    static constexpr uint32_t INVALID_GENERATION = 0;
 | 
| +
 | 
| +    // State for the job set up once by the output implementation and then used
 | 
| +    // by all tracks.
 | 
| +    void*    buf;
 | 
| +    uint32_t buf_frames;
 | 
| +    int64_t  start_pts_of;  // start PTS, expressed in output frames.
 | 
| +    uint32_t local_to_output_gen;
 | 
| +    bool     accumulate;
 | 
| +    const LinearTransform* local_to_output;
 | 
| +
 | 
| +    // State for the job which is set up for each track during SetupMix
 | 
| +    uint32_t frames_produced;
 | 
| +  };
 | 
| +
 | 
| +  struct TrackBookkeeping : public AudioTrackToOutputLink::Bookkeeping {
 | 
| +    TrackBookkeeping();
 | 
| +    ~TrackBookkeeping() override;
 | 
| +
 | 
| +    LinearTransform lt_to_track_frames;
 | 
| +    LinearTransform out_frames_to_track_frames;
 | 
| +    uint32_t lt_to_track_frames_gen = 0;
 | 
| +    uint32_t out_frames_to_track_frames_gen = MixJob::INVALID_GENERATION;
 | 
| +    uint32_t step_size;
 | 
| +    MixerPtr mixer;
 | 
| +
 | 
| +    void UpdateTrackTrans(const AudioTrackImplPtr& track);
 | 
| +    void UpdateOutputTrans(const MixJob& job);
 | 
| +  };
 | 
| +
 | 
| +  explicit StandardOutputBase(AudioOutputManager* manager);
 | 
| +
 | 
| +  void Process() final;
 | 
| +  MediaResult InitializeLink(const AudioTrackToOutputLinkPtr& link) final;
 | 
| +
 | 
| +  void SetNextSchedTime(const LocalTime& next_sched_time) {
 | 
| +    next_sched_time_ = next_sched_time;
 | 
| +    next_sched_time_known_ = true;
 | 
| +  }
 | 
| +
 | 
| +  void SetNextSchedDelay(const LocalDuration& next_sched_delay) {
 | 
| +    SetNextSchedTime(LocalClock::now() + next_sched_delay);
 | 
| +  }
 | 
| +
 | 
| +  virtual bool StartMixJob(MixJob* job, const LocalTime& process_start) = 0;
 | 
| +  virtual bool FinishMixJob(const MixJob& job) = 0;
 | 
| +  virtual TrackBookkeeping* AllocBookkeeping();
 | 
| +
 | 
| +  LpcmMediaTypeDetailsPtr output_format_;
 | 
| +  uint32_t output_bytes_per_frame_;
 | 
| +
 | 
| + private:
 | 
| +  using TrackSetupTask = std::function<bool(const AudioTrackImplPtr& track,
 | 
| +                                            TrackBookkeeping* info)>;
 | 
| +  using TrackProcessTask =
 | 
| +    std::function<bool(const AudioTrackImplPtr& track,
 | 
| +                       TrackBookkeeping* info,
 | 
| +                       const AudioPipe::AudioPacketRefPtr& pkt_ref)>;
 | 
| +
 | 
| +  void ForeachTrack(const TrackSetupTask& setup,
 | 
| +                    const TrackProcessTask& process);
 | 
| +
 | 
| +  bool SetupMix(const AudioTrackImplPtr& track, TrackBookkeeping* info);
 | 
| +  bool ProcessMix(const AudioTrackImplPtr& track,
 | 
| +                  TrackBookkeeping* info,
 | 
| +                  const AudioPipe::AudioPacketRefPtr& pkt_ref);
 | 
| +
 | 
| +  bool SetupTrim(const AudioTrackImplPtr& track, TrackBookkeeping* info);
 | 
| +  bool ProcessTrim(const AudioTrackImplPtr& track,
 | 
| +                   TrackBookkeeping* info,
 | 
| +                   const AudioPipe::AudioPacketRefPtr& pkt_ref);
 | 
| +
 | 
| +  LocalTime next_sched_time_;
 | 
| +  bool next_sched_time_known_;
 | 
| +
 | 
| +  // State used by the mix task.
 | 
| +  TrackSetupTask setup_mix_;
 | 
| +  TrackProcessTask process_mix_;
 | 
| +  MixJob cur_mix_job_;
 | 
| +
 | 
| +  // State used by the trim task.
 | 
| +  TrackSetupTask setup_trim_;
 | 
| +  TrackProcessTask process_trim_;
 | 
| +  int64_t trim_threshold_;
 | 
| +};
 | 
| +
 | 
| +}  // namespace audio
 | 
| +}  // namespace media
 | 
| +}  // namespace mojo
 | 
| +
 | 
| +#endif  // SERVICES_MEDIA_AUDIO_PLATFORM_GENERIC_STANDARD_OUTPUT_BASE_H_
 | 
| 
 |