/*
 * Copyright 2012 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef MEDIA_BASE_SHELL_BUFFER_FACTORY_H_
#define MEDIA_BASE_SHELL_BUFFER_FACTORY_H_

#include <list>
#include <map>

#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "media/base/decoder_buffer.h"
#include "media/base/media_export.h"

namespace media {

static const size_t kShellMaxArraySize = 1024 * 1024;

class DecoderBuffer;
class DecryptConfig;
class ShellBufferFactory;

// A simple scoped array class designed to re-use the memory allocated by
// ShellBufferFactory. If needed would be trivial to make generic.
class MEDIA_EXPORT ShellScopedArray
    : public base::RefCountedThreadSafe<ShellScopedArray> {
 public:
  uint8* Get() { return array_; }
  size_t Size() { return size_; }

 private:
  friend class base::RefCountedThreadSafe<ShellScopedArray>;
  friend class ShellBufferFactory;
  // Should only be called by ShellBufferFactory, consumers should use
  // ShellBufferFactory::AllocateArray to allocate a ShellScopedArray
  ShellScopedArray(uint8* resuable_buffer, size_t size);
  virtual ~ShellScopedArray();
  uint8* array_;
  size_t size_;
  scoped_refptr<ShellBufferFactory> buffer_factory_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(ShellScopedArray);
};

// Singleton instance class for the management and recycling of media-related
// buffers. It is assumed that the usage pattern of these buffers is that they
// are used for only a short amount of time, and their allocation is roughly
// cyclical. All buffers are allocated using the alignment constants defined
// above, and all buffers are allocated from the shared pool of memory of
// size defined above.
class MEDIA_EXPORT ShellBufferFactory
    : public base::RefCountedThreadSafe<ShellBufferFactory> {
 public:
  static void Initialize();
  static inline scoped_refptr<ShellBufferFactory> Instance() {
    return instance_;
  }

  typedef base::Callback<void(scoped_refptr<DecoderBuffer>)> AllocCB;
  // Returns false if the allocator will never be able to allocate a buffer
  // of the requested size. Note that if memory is currently available this
  // function will call the callback provided _before_ returning true.
  bool AllocateBuffer(size_t size, bool is_keyframe, AllocCB cb);
  // This function tries to allocate a DecoderBuffer immediately. It returns
  // NULL on failure.
  scoped_refptr<DecoderBuffer> AllocateBufferNow(size_t size, bool is_keyframe);
  // Returns a newly allocated byte field if there's room for it, or NULL if
  // there isn't. Note that this raw allocation method provides no guarantee
  // that ShellBufferFactory will still exist when the memory is to be freed.
  // If that is important please retain a reference to the buffer factory
  // (using Instance()) until the memory is to be reclaimed.
  uint8* AllocateNow(size_t size);
  // BLOCKS THE CALLING THREAD until an array of size is available and can be
  // allocated. We only allow one thread to block on an array allocation at a
  // time, all subsequents calls on other threads to AllocateArray will assert
  // and return NULL.
  scoped_refptr<ShellScopedArray> AllocateArray(size_t size);

  // Only called by DecoderBuffer and ShellScopedArray, informs the factory
  // that these objects have gone out of scoped and we can reclaim the memory
  void Reclaim(uint8* p);

  static void Terminate();

 private:
  friend class base::RefCountedThreadSafe<ShellBufferFactory>;
  ShellBufferFactory();
  ~ShellBufferFactory();
  uint8* Allocate_Locked(size_t aligned_size);

  static scoped_refptr<ShellBufferFactory> instance_;

  // protects all following members.
  base::Lock lock_;

  // queue of pending buffer allocation requests and their sizes
  typedef std::list<std::pair<AllocCB, scoped_refptr<DecoderBuffer> > >
      AllocList;
  AllocList pending_allocs_;

  // event used for blocking calls for array allocation
  base::WaitableEvent array_allocation_event_;
  // set to 0 when no thread is blocking on an array allocation
  size_t array_requested_size_;
  // set to an allocation address when allocation has succeeded
  uint8* array_allocation_;
};

}  // namespace media

#endif  // MEDIA_BASE_SHELL_BUFFER_FACTORY_H_
