1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found in the LICENSE file.
4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#ifndef MEDIA_BASE_AUDIO_BUFFER_QUEUE_H_
6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#define MEDIA_BASE_AUDIO_BUFFER_QUEUE_H_
7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <deque>
9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/basictypes.h"
11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/memory/scoped_ptr.h"
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "media/base/audio_buffer.h"
13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "media/base/media_export.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace media {
16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass AudioBus;
18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// A queue of AudioBuffers to support reading of arbitrary chunks of a media
20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// data source. Audio data can be copied into an AudioBus for output. The
21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// current position can be forwarded to anywhere in the buffered data.
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch//
23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// This class is not inherently thread-safe. Concurrent access must be
24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// externally serialized.
25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass MEDIA_EXPORT AudioBufferQueue {
26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public:
27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  AudioBufferQueue();
28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  ~AudioBufferQueue();
29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Clears the buffer queue.
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void Clear();
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Appends |buffer_in| to this queue.
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void Append(const scoped_refptr<AudioBuffer>& buffer_in);
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Reads a maximum of |frames| frames into |dest| from the current position.
37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Returns the number of frames read. The current position will advance by the
387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // amount of frames read. |dest_frame_offset| specifies a starting offset into
397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // |dest|. On each call, the frames are converted from their source format
407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // into the destination AudioBus.
417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  int ReadFrames(int frames, int dest_frame_offset, AudioBus* dest);
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Copies up to |frames| frames from current position to |dest|. Returns
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // number of frames copied. Doesn't advance current position. Starts at
457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // |source_frame_offset| from current position. |dest_frame_offset| specifies
467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // a starting offset into |dest|. On each call, the frames are converted from
477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // their source format into the destination AudioBus.
487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  int PeekFrames(int frames,
497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 int source_frame_offset,
507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 int dest_frame_offset,
517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 AudioBus* dest);
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Moves the current position forward by |frames| frames. If |frames| exceeds
54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // frames available, the seek operation will fail.
55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  void SeekFrames(int frames);
56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Returns the number of frames buffered beyond the current position.
58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int frames() const { return frames_; }
59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch private:
61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Definition of the buffer queue.
62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  typedef std::deque<scoped_refptr<AudioBuffer> > BufferQueue;
63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // An internal method shared by ReadFrames() and SeekFrames() that actually
65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // does reading. It reads a maximum of |frames| frames into |dest|. Returns
66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // the number of frames read. The current position will be moved forward by
67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // the number of frames read if |advance_position| is set. If |dest| is NULL,
68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // only the current position will advance but no data will be copied.
697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // |source_frame_offset| can be used to skip frames before reading.
707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // |dest_frame_offset| specifies a starting offset into |dest|.
71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int InternalRead(int frames,
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                   bool advance_position,
737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                   int source_frame_offset,
747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                   int dest_frame_offset,
75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                   AudioBus* dest);
76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  BufferQueue::iterator current_buffer_;
78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  BufferQueue buffers_;
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int current_buffer_offset_;
80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Number of frames available to be read in the buffer.
82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int frames_;
83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DISALLOW_COPY_AND_ASSIGN(AudioBufferQueue);
85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch};
86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace media
88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif  // MEDIA_BASE_AUDIO_BUFFER_QUEUE_H_
90