root/ppapi/proxy/media_stream_audio_track_resource.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. get_buffer_output_
  2. AsPPB_MediaStreamAudioTrack_API
  3. GetId
  4. HasEnded
  5. Configure
  6. GetAttrib
  7. GetBuffer
  8. RecycleBuffer
  9. Close
  10. OnNewBufferEnqueued
  11. GetAudioBuffer
  12. ReleaseBuffers

// Copyright 2014 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 "ppapi/proxy/media_stream_audio_track_resource.h"

#include "ppapi/proxy/audio_buffer_resource.h"
#include "ppapi/shared_impl/media_stream_buffer.h"
#include "ppapi/shared_impl/var.h"

namespace ppapi {
namespace proxy {

MediaStreamAudioTrackResource::MediaStreamAudioTrackResource(
    Connection connection,
    PP_Instance instance,
    int pending_renderer_id,
    const std::string& id)
    : MediaStreamTrackResourceBase(
        connection, instance, pending_renderer_id, id),
      get_buffer_output_(NULL) {
}

MediaStreamAudioTrackResource::~MediaStreamAudioTrackResource() {
  Close();
}

thunk::PPB_MediaStreamAudioTrack_API*
MediaStreamAudioTrackResource::AsPPB_MediaStreamAudioTrack_API() {
  return this;
}

PP_Var MediaStreamAudioTrackResource::GetId() {
  return StringVar::StringToPPVar(id());
}

PP_Bool MediaStreamAudioTrackResource::HasEnded() {
  return PP_FromBool(has_ended());
}

int32_t MediaStreamAudioTrackResource::Configure(
    const int32_t attrib_list[],
    scoped_refptr<TrackedCallback> callback) {
  // TODO(penghuang): Implement this function.
  return PP_ERROR_NOTSUPPORTED;
}

int32_t MediaStreamAudioTrackResource::GetAttrib(
    PP_MediaStreamAudioTrack_Attrib attrib,
    int32_t* value) {
  // TODO(penghuang): Implement this function.
  return PP_ERROR_NOTSUPPORTED;
}

int32_t MediaStreamAudioTrackResource::GetBuffer(
    PP_Resource* buffer,
    scoped_refptr<TrackedCallback> callback) {
  if (has_ended())
    return PP_ERROR_FAILED;

  if (TrackedCallback::IsPending(get_buffer_callback_))
    return PP_ERROR_INPROGRESS;

  *buffer = GetAudioBuffer();
  if (*buffer)
    return PP_OK;

  // TODO(penghuang): Use the callback as hints to determine which thread will
  // use the resource, so we could deliver buffers to the target thread directly
  // for better performance.
  get_buffer_output_ = buffer;
  get_buffer_callback_ = callback;
  return PP_OK_COMPLETIONPENDING;
}

int32_t MediaStreamAudioTrackResource::RecycleBuffer(PP_Resource buffer) {
  BufferMap::iterator it = buffers_.find(buffer);
  if (it == buffers_.end())
    return PP_ERROR_BADRESOURCE;

  scoped_refptr<AudioBufferResource> buffer_resource = it->second;
  buffers_.erase(it);

  if (has_ended())
    return PP_OK;

  DCHECK_GE(buffer_resource->GetBufferIndex(), 0);

  SendEnqueueBufferMessageToHost(buffer_resource->GetBufferIndex());
  buffer_resource->Invalidate();
  return PP_OK;
}

void MediaStreamAudioTrackResource::Close() {
  if (has_ended())
    return;

  if (TrackedCallback::IsPending(get_buffer_callback_)) {
    *get_buffer_output_ = 0;
    get_buffer_callback_->PostAbort();
    get_buffer_callback_ = NULL;
    get_buffer_output_ = 0;
  }

  ReleaseBuffers();
  MediaStreamTrackResourceBase::CloseInternal();
}

void MediaStreamAudioTrackResource::OnNewBufferEnqueued() {
  if (!TrackedCallback::IsPending(get_buffer_callback_))
    return;

  *get_buffer_output_ = GetAudioBuffer();
  int32_t result = *get_buffer_output_ ? PP_OK : PP_ERROR_FAILED;
  get_buffer_output_ = NULL;
  scoped_refptr<TrackedCallback> callback;
  callback.swap(get_buffer_callback_);
  callback->Run(result);
}

PP_Resource MediaStreamAudioTrackResource::GetAudioBuffer() {
  int32_t index = buffer_manager()->DequeueBuffer();
  if (index < 0)
      return 0;

  MediaStreamBuffer* buffer = buffer_manager()->GetBufferPointer(index);
  DCHECK(buffer);
  scoped_refptr<AudioBufferResource> resource =
      new AudioBufferResource(pp_instance(), index, buffer);
  // Add |pp_resource()| and |resource| into |buffers_|.
  // |buffers_| uses scoped_ptr<> to hold a ref of |resource|. It keeps the
  // resource alive.
  buffers_.insert(BufferMap::value_type(resource->pp_resource(), resource));
  return resource->GetReference();
}

void MediaStreamAudioTrackResource::ReleaseBuffers() {
  BufferMap::iterator it = buffers_.begin();
  while (it != buffers_.end()) {
    // Just invalidate and release VideoBufferResorce, but keep PP_Resource.
    // So plugin can still use |RecycleBuffer()|.
    it->second->Invalidate();
    it->second = NULL;
  }
}

}  // namespace proxy
}  // namespace ppapi

/* [<][>][^][v][top][bottom][index][help] */