static SLresult IAndroidBufferQueue_Clear(SLAndroidBufferQueueItf self)
{
    SL_ENTER_INTERFACE
    result = SL_RESULT_SUCCESS;

    IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;

    interface_lock_exclusive(thiz);

    // reset the queue pointers
    thiz->mFront = &thiz->mBufferArray[0];
    thiz->mRear = &thiz->mBufferArray[0];
    // reset the queue state
    thiz->mState.count = 0;
    thiz->mState.index = 0;

    // object-specific behavior for a clear
    switch (InterfaceToObjectID(thiz)) {
    case SL_OBJECTID_AUDIOPLAYER:
        android_audioPlayer_androidBufferQueue_clear_l((CAudioPlayer*) thiz->mThis);
        break;
    case XA_OBJECTID_MEDIAPLAYER:
        android_Player_androidBufferQueue_clear_l((CMediaPlayer*) thiz->mThis);
        break;
    default:
        result = SL_RESULT_PARAMETER_INVALID;
    }

    interface_unlock_exclusive(thiz);

    SL_LEAVE_INTERFACE
}
static SLresult IAndroidBufferQueue_RegisterCallback(SLAndroidBufferQueueItf self,
        slAndroidBufferQueueCallback callback, void *pContext)
{
    SL_ENTER_INTERFACE

    IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;

    interface_lock_exclusive(thiz);

    // verify pre-condition that media object is in the SL_PLAYSTATE_STOPPED state
    if (SL_PLAYSTATE_STOPPED == getAssociatedState(thiz)) {
        thiz->mCallback = callback;
        thiz->mContext = pContext;

        // FIXME investigate why these two cases are not handled symmetrically any more
        switch (InterfaceToObjectID(thiz)) {
          case SL_OBJECTID_AUDIOPLAYER:
            result = android_audioPlayer_androidBufferQueue_registerCallback_l(
                    (CAudioPlayer*) thiz->mThis);
            break;
          case XA_OBJECTID_MEDIAPLAYER:
            result = SL_RESULT_SUCCESS;
            break;
          default:
            result = SL_RESULT_PARAMETER_INVALID;
        }

    } else {
        result = SL_RESULT_PRECONDITIONS_VIOLATED;
    }

    interface_unlock_exclusive(thiz);

    SL_LEAVE_INTERFACE
}
static SLresult IAndroidBufferQueue_Clear(SLAndroidBufferQueueItf self)
{
    SL_ENTER_INTERFACE
    result = SL_RESULT_SUCCESS;

    IAndroidBufferQueue *thiz = (IAndroidBufferQueue *) self;

    interface_lock_exclusive(thiz);

    // reset the queue pointers
    thiz->mFront = &thiz->mBufferArray[0];
    thiz->mRear = &thiz->mBufferArray[0];
    // reset the queue state
    thiz->mState.count = 0;
    thiz->mState.index = 0;
    // reset the individual buffers
    for (XAuint16 i=0 ; i<(thiz->mNumBuffers + 1) ; i++) {
        thiz->mBufferArray[i].mDataBuffer = NULL;
        thiz->mBufferArray[i].mDataSize = 0;
        thiz->mBufferArray[i].mDataSizeConsumed = 0;
        thiz->mBufferArray[i].mBufferContext = NULL;
        thiz->mBufferArray[i].mBufferState = SL_ANDROIDBUFFERQUEUEEVENT_NONE;
        switch (thiz->mBufferType) {
          case kAndroidBufferTypeMpeg2Ts:
            thiz->mBufferArray[i].mItems.mTsCmdData.mTsCmdCode = ANDROID_MP2TSEVENT_NONE;
            thiz->mBufferArray[i].mItems.mTsCmdData.mPts = 0;
            break;
          case kAndroidBufferTypeAacadts:
            thiz->mBufferArray[i].mItems.mAdtsCmdData.mAdtsCmdCode = ANDROID_ADTSEVENT_NONE;
            break;
          default:
            result = SL_RESULT_CONTENT_UNSUPPORTED;
        }
    }

    if (SL_RESULT_SUCCESS == result) {
        // object-specific behavior for a clear
        switch (InterfaceToObjectID(thiz)) {
        case SL_OBJECTID_AUDIOPLAYER:
            result = SL_RESULT_SUCCESS;
            android_audioPlayer_androidBufferQueue_clear_l((CAudioPlayer*) thiz->mThis);
            break;
        case XA_OBJECTID_MEDIAPLAYER:
            result = SL_RESULT_SUCCESS;
            android_Player_androidBufferQueue_clear_l((CMediaPlayer*) thiz->mThis);
            break;
        default:
            result = SL_RESULT_PARAMETER_INVALID;
        }
    }

    interface_unlock_exclusive(thiz);

    SL_LEAVE_INTERFACE
}
static SLuint32 getAssociatedState(IAndroidBufferQueue *thiz)
{
    SLuint32 state;
    switch (InterfaceToObjectID(thiz)) {
      case XA_OBJECTID_MEDIAPLAYER:
        state = ((CMediaPlayer *) thiz->mThis)->mPlay.mState;
        break;
      case SL_OBJECTID_AUDIOPLAYER:
        state = ((CAudioPlayer *) thiz->mThis)->mPlay.mState;
        break;
      default:
        // unreachable, but just in case we will assume it is stopped
        assert(SL_BOOLEAN_FALSE);
        state = SL_PLAYSTATE_STOPPED;
        break;
    }
    return state;
}