<commit_before>/*
 *  vaapidecoder_base.cpp - basic va decoder for video
 *
 *  Copyright (C) 2013-2014 Intel Corporation
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2.1
 *  of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free
 *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 *  Boston, MA 02110-1301 USA
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#ifdef __ENABLE_X11__
#include <X11/Xlib.h>
#endif
#include "vaapidecoder_base.h"
#include "common/log.h"
#include "vaapi/vaapicontext.h"
#include "vaapi/vaapidisplay.h"
#include "vaapi/vaapiutils.h"
#include "vaapidecsurfacepool.h"
#include <string.h>
#include <stdlib.h> // for setenv
#include <va/va_backend.h>

#ifdef ANDROID
#include <va/va_android.h>
#endif

#define ANDROID_DISPLAY_HANDLE 0x18C34078

namespace YamiMediaCodec{
typedef VaapiDecoderBase::PicturePtr PicturePtr;

VaapiDecoderBase::VaapiDecoderBase():
m_renderTarget(NULL),
m_lastReference(NULL),
m_forwardReference(NULL),
m_VAStarted(false),
m_currentPTS(INVALID_PTS), m_enableNativeBuffersFlag(false)
{
    INFO("base: construct()");
    m_externalDisplay.handle = 0,
    m_externalDisplay.type = NATIVE_DISPLAY_AUTO,
    memset(&m_videoFormatInfo, 0, sizeof(VideoFormatInfo));
    memset(&m_configBuffer, 0, sizeof(m_configBuffer));
}

VaapiDecoderBase::~VaapiDecoderBase()
{
    INFO("base: deconstruct()");
    stop();
}

PicturePtr VaapiDecoderBase::createPicture(int64_t timeStamp /* , VaapiPictureStructure structure = VAAPI_PICTURE_STRUCTURE_FRAME */)
{
    PicturePtr picture;
    /*accquire one surface from m_surfacePool in base decoder  */
    SurfacePtr surface = createSurface();
    if (!surface) {
        ERROR("create surface failed");
        return picture;
    }

    picture.reset(new VaapiDecPicture(m_context, surface, timeStamp));
    return picture;
}

Decode_Status VaapiDecoderBase::start(VideoConfigBuffer * buffer)
{
    Decode_Status status;

    INFO("base: start()");

    if (buffer == NULL) {
        return DECODE_INVALID_DATA;
    }

    m_configBuffer = *buffer;
    m_configBuffer.data = NULL;
    m_configBuffer.size = 0;

    m_videoFormatInfo.width = buffer->width;
    m_videoFormatInfo.height = buffer->height;
    if (buffer->flag & USE_NATIVE_GRAPHIC_BUFFER) {
        m_videoFormatInfo.surfaceWidth = buffer->graphicBufferWidth;
        m_videoFormatInfo.surfaceHeight = buffer->graphicBufferHeight;
    } else {
        m_videoFormatInfo.surfaceWidth = buffer->surfaceWidth;
        m_videoFormatInfo.surfaceHeight = buffer->surfaceHeight;
    }
    m_lowDelay = buffer->flag & WANT_LOW_DELAY;
    m_rawOutput = buffer->flag & WANT_RAW_OUTPUT;

    status = setupVA(buffer->surfaceNumber, buffer->profile);
    if (status != DECODE_SUCCESS)
        return status;

    DEBUG
        ("m_videoFormatInfo video size: %d x %d, m_videoFormatInfo surface size: %d x %d",
         m_videoFormatInfo.width, m_videoFormatInfo.height,
         m_videoFormatInfo.surfaceWidth, m_videoFormatInfo.surfaceHeight);

#ifdef __ENABLE_DEBUG__
    renderPictureCount = 0;
#endif
    return DECODE_SUCCESS;
}

Decode_Status VaapiDecoderBase::reset(VideoConfigBuffer * buffer)
{
    Decode_Status status;

    INFO("base: reset()");
    if (buffer == NULL) {
        return DECODE_INVALID_DATA;
    }

    flush();

    status = terminateVA();
    if (status != DECODE_SUCCESS)
        return status;

    status = start(buffer);
    if (status != DECODE_SUCCESS)
        return status;

    return DECODE_SUCCESS;
}

void VaapiDecoderBase::stop(void)
{
    INFO("base: stop()");
    terminateVA();

    m_currentPTS = INVALID_PTS;
    m_renderTarget = NULL;
    m_lastReference = NULL;
    m_forwardReference = NULL;

    m_lowDelay = false;
    m_rawOutput = false;

    m_videoFormatInfo.valid = false;
}

void VaapiDecoderBase::flush(void)
{

    INFO("base: flush()");
    if (m_surfacePool) {
        m_surfacePool->flush();
    }

    m_currentPTS = INVALID_PTS;
    m_renderTarget = NULL;
    m_lastReference = NULL;
    m_forwardReference = NULL;
}

void VaapiDecoderBase::flushOutport(void)
{
}

const VideoRenderBuffer *VaapiDecoderBase::getOutput(bool draining)
{
    if (!m_surfacePool)
        return NULL;
    if (draining)
        flushOutport();

    VideoRenderBuffer *buffer = m_surfacePool->getOutput();

#ifdef __ENABLE_DEBUG__
    if (buffer) {
        renderPictureCount++;
        DEBUG("getOutput renderPictureCount: %d", renderPictureCount);
    }
#endif

    return buffer;
}

Decode_Status VaapiDecoderBase::getOutput(unsigned long draw, int64_t *timeStamp
    , int drawX, int drawY, int drawWidth, int drawHeight, bool draining
    , int frameX, int frameY, int frameWidth, int frameHeight)
{
    VAStatus vaStatus = VA_STATUS_SUCCESS;
    const VideoRenderBuffer *renderBuffer = getOutput(draining);

    if (!renderBuffer)
        return RENDER_NO_AVAILABLE_FRAME;

    if (frameX == -1 && frameY == -1 && frameWidth == -1 && frameHeight == -1) {
        frameX = 0;
        frameY = 0;
        frameWidth = m_videoFormatInfo.width;
        frameHeight = m_videoFormatInfo.height;
    }

    if (!draw || drawX < 0 || drawY < 0 || drawWidth <=0 || drawHeight <=0
        || frameX < 0 || frameY < 0 || frameWidth <= 0 || frameHeight <= 0)
        return RENDER_INVALID_PARAMETER;

#if __ENABLE_X11__
    vaStatus = vaPutSurface(m_display->getID(), renderBuffer->surface,
            draw, drawX, drawY, drawWidth, drawHeight,
            frameX, frameY, frameWidth, frameHeight,
            NULL,0,0);
#else
    vaStatus = VA_STATUS_ERROR_OPERATION_FAILED;
    ERROR("vaPutSurface is not supported when libva-x11 backend is disable during build (--disable-x11)");
#endif

    if (vaStatus != VA_STATUS_SUCCESS)
        return RENDER_FAIL;

    *timeStamp = renderBuffer->timeStamp;

    renderDone(renderBuffer);
    return RENDER_SUCCESS;
}

const VideoFormatInfo *VaapiDecoderBase::getFormatInfo(void)
{
    INFO("base: getFormatInfo()");

    if (!m_VAStarted)
        return NULL;

    return &m_videoFormatInfo;
}

Decode_Status VaapiDecoderBase::getOutput(VideoFrameRawData* frame, bool draining)
{
    if (!m_surfacePool)
        return RENDER_NO_AVAILABLE_FRAME;

    if (!frame)
        return DECODE_INVALID_DATA;

    if (draining)
        flushOutport();

    if (!m_surfacePool->getOutput(frame))
        return RENDER_NO_AVAILABLE_FRAME;

#ifdef __ENABLE_DEBUG__
    renderPictureCount++;
    DEBUG("getOutput renderPictureCount=%d, timeStamp=%ld", renderPictureCount, frame->timeStamp);
#endif

    return RENDER_SUCCESS;
}

Decode_Status VaapiDecoderBase::populateOutputHandles(VideoFrameRawData *frames, uint32_t &frameCount)
{
    if (!m_surfacePool)
        return RENDER_NO_AVAILABLE_FRAME;

    if (!m_surfacePool->populateOutputHandles(frames, frameCount))
        return RENDER_NO_AVAILABLE_FRAME;
    return RENDER_SUCCESS;
}

void VaapiDecoderBase::renderDone(const VideoRenderBuffer * renderBuf)
{
    INFO("base: renderDone()");
    if (!m_surfacePool) {
        ERROR("surface pool is not initialized yet");
        return;
    }
    m_surfacePool->recycle(renderBuf);
}

void VaapiDecoderBase::renderDone(VideoFrameRawData* frame)
{
    INFO("base: renderDone()");
    if (!m_surfacePool) {
        ERROR("surface pool is not initialized yet");
        return;
    }
    m_surfacePool->recycle(frame);
}

Decode_Status VaapiDecoderBase::updateReference(void)
{
    Decode_Status status;
    // update reference frames
    if (m_renderTarget->referenceFrame) {
        // managing reference for MPEG4/H.263/WMV.
        // AVC should manage reference frame in a different way
        if (m_forwardReference != NULL) {
            // this foward reference is no longer needed
            m_forwardReference->asReferernce = false;
        }
        // Forware reference for either P or B frame prediction
        m_forwardReference = m_lastReference;
        m_renderTarget->asReferernce = true;

        // the last reference frame.
        m_lastReference = m_renderTarget;
    }
    return DECODE_SUCCESS;
}

Decode_Status
    VaapiDecoderBase::setupVA(uint32_t numSurface, VAProfile profile)
{
    INFO("base: setup VA");
    uint32_t i;
    VideoSurfaceBuffer *buf;
    VaapiSurface *suf;
    Decode_Status status;
    VAStatus vaStatus = VA_STATUS_SUCCESS;

    if (m_enableNativeBuffersFlag == true) {
        numSurface = 20;        //NATIVE_WINDOW_COUNT;
    }

    if (m_VAStarted) {
        return DECODE_SUCCESS;
    }

    if (m_display != NULL) {
        WARNING("VA is partially started.");
        return DECODE_FAIL;
    }

#if __PLATFORM_BYT__
    if (setenv("LIBVA_DRIVER_NAME", "wrapper", 1) == 0) {
        INFO("setting LIBVA_DRIVER_NAME to wrapper for chromeos");
    }
#endif
    m_display = VaapiDisplay::create(m_externalDisplay);

    if (!m_display) {
        ERROR("failed to create display");
        return DECODE_FAIL;
    }

    VAConfigAttrib attrib;
    attrib.type = VAConfigAttribRTFormat;
    attrib.value = VA_RT_FORMAT_YUV420;

    ConfigPtr config = VaapiConfig::create(m_display, profile, VAEntrypointVLD,&attrib, 1);
    if (!config) {
        ERROR("failed to create config");
        return DECODE_FAIL;
    }

    m_configBuffer.surfaceNumber = numSurface;
    m_surfacePool = VaapiDecSurfacePool::create(m_display, &m_configBuffer);
    DEBUG("surface pool is created");
    if (!m_surfacePool)
        return DECODE_FAIL;
    std::vector<VASurfaceID> surfaces;
    m_surfacePool->getSurfaceIDs(surfaces);
    if (surfaces.empty())
        return DECODE_FAIL;
    int size = surfaces.size();
    m_context = VaapiContext::create(config,
                                       m_videoFormatInfo.width,
                                       m_videoFormatInfo.height,
                                       0, &surfaces[0], size);

    if (!m_context) {
        ERROR("create context failed");
        return DECODE_FAIL;
    }

    if (!m_display->setRotation(m_configBuffer.rotationDegrees)) {
        return DECODE_FAIL;
    }

    if (!(m_configBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER)) {
        m_videoFormatInfo.surfaceWidth = m_videoFormatInfo.width;
        m_videoFormatInfo.surfaceHeight = m_videoFormatInfo.height;
    }

    m_VAStarted = true;
    return DECODE_SUCCESS;
}

Decode_Status VaapiDecoderBase::terminateVA(void)
{
    INFO("base: terminate VA");
    m_surfacePool.reset();
    DEBUG("surface pool is reset");
    m_context.reset();
    m_display.reset();

    m_VAStarted = false;
    return DECODE_SUCCESS;
}

void VaapiDecoderBase::setNativeDisplay(NativeDisplay * nativeDisplay)
{
    if (!nativeDisplay || nativeDisplay->type == NATIVE_DISPLAY_AUTO)
        return;

    m_externalDisplay = *nativeDisplay;
}

/* not used funtion here */
void VaapiDecoderBase::enableNativeBuffers(void)
{
}

Decode_Status
    VaapiDecoderBase::getClientNativeWindowBuffer(void *bufferHeader,
                                                  void *nativeBufferHandle)
{
    return DECODE_SUCCESS;
}

Decode_Status VaapiDecoderBase::flagNativeBuffer(void *pBuffer)
{
    return DECODE_SUCCESS;
}

void VaapiDecoderBase::releaseLock(bool lockable=false)
{
    if (!m_surfacePool)
        return;

    m_surfacePool->setWaitable(lockable);
}

SurfacePtr VaapiDecoderBase::createSurface()
{
    SurfacePtr surface;
    if (m_surfacePool) {
        surface = m_surfacePool->acquireWithWait();
    }
    return surface;
}

Decode_Status VaapiDecoderBase::outputPicture(const PicturePtr& picture)
{
    //TODO: reorder poc
    return m_surfacePool->output(picture->getSurface(),
        picture->m_timeStamp)?DECODE_SUCCESS:DECODE_FAIL;
}

} //namespace YamiMediaCodec
<commit_msg>basedec: do not print error for allocate surface failed.          it's intented behavior for seek<commit_after>/*
 *  vaapidecoder_base.cpp - basic va decoder for video
 *
 *  Copyright (C) 2013-2014 Intel Corporation
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2.1
 *  of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free
 *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 *  Boston, MA 02110-1301 USA
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#ifdef __ENABLE_X11__
#include <X11/Xlib.h>
#endif
#include "vaapidecoder_base.h"
#include "common/log.h"
#include "vaapi/vaapicontext.h"
#include "vaapi/vaapidisplay.h"
#include "vaapi/vaapiutils.h"
#include "vaapidecsurfacepool.h"
#include <string.h>
#include <stdlib.h> // for setenv
#include <va/va_backend.h>

#ifdef ANDROID
#include <va/va_android.h>
#endif

#define ANDROID_DISPLAY_HANDLE 0x18C34078

namespace YamiMediaCodec{
typedef VaapiDecoderBase::PicturePtr PicturePtr;

VaapiDecoderBase::VaapiDecoderBase():
m_renderTarget(NULL),
m_lastReference(NULL),
m_forwardReference(NULL),
m_VAStarted(false),
m_currentPTS(INVALID_PTS), m_enableNativeBuffersFlag(false)
{
    INFO("base: construct()");
    m_externalDisplay.handle = 0,
    m_externalDisplay.type = NATIVE_DISPLAY_AUTO,
    memset(&m_videoFormatInfo, 0, sizeof(VideoFormatInfo));
    memset(&m_configBuffer, 0, sizeof(m_configBuffer));
}

VaapiDecoderBase::~VaapiDecoderBase()
{
    INFO("base: deconstruct()");
    stop();
}

PicturePtr VaapiDecoderBase::createPicture(int64_t timeStamp /* , VaapiPictureStructure structure = VAAPI_PICTURE_STRUCTURE_FRAME */)
{
    PicturePtr picture;
    /*accquire one surface from m_surfacePool in base decoder  */
    SurfacePtr surface = createSurface();
    if (!surface) {
        DEBUG("create surface failed");
        return picture;
    }

    picture.reset(new VaapiDecPicture(m_context, surface, timeStamp));
    return picture;
}

Decode_Status VaapiDecoderBase::start(VideoConfigBuffer * buffer)
{
    Decode_Status status;

    INFO("base: start()");

    if (buffer == NULL) {
        return DECODE_INVALID_DATA;
    }

    m_configBuffer = *buffer;
    m_configBuffer.data = NULL;
    m_configBuffer.size = 0;

    m_videoFormatInfo.width = buffer->width;
    m_videoFormatInfo.height = buffer->height;
    if (buffer->flag & USE_NATIVE_GRAPHIC_BUFFER) {
        m_videoFormatInfo.surfaceWidth = buffer->graphicBufferWidth;
        m_videoFormatInfo.surfaceHeight = buffer->graphicBufferHeight;
    } else {
        m_videoFormatInfo.surfaceWidth = buffer->surfaceWidth;
        m_videoFormatInfo.surfaceHeight = buffer->surfaceHeight;
    }
    m_lowDelay = buffer->flag & WANT_LOW_DELAY;
    m_rawOutput = buffer->flag & WANT_RAW_OUTPUT;

    status = setupVA(buffer->surfaceNumber, buffer->profile);
    if (status != DECODE_SUCCESS)
        return status;

    DEBUG
        ("m_videoFormatInfo video size: %d x %d, m_videoFormatInfo surface size: %d x %d",
         m_videoFormatInfo.width, m_videoFormatInfo.height,
         m_videoFormatInfo.surfaceWidth, m_videoFormatInfo.surfaceHeight);

#ifdef __ENABLE_DEBUG__
    renderPictureCount = 0;
#endif
    return DECODE_SUCCESS;
}

Decode_Status VaapiDecoderBase::reset(VideoConfigBuffer * buffer)
{
    Decode_Status status;

    INFO("base: reset()");
    if (buffer == NULL) {
        return DECODE_INVALID_DATA;
    }

    flush();

    status = terminateVA();
    if (status != DECODE_SUCCESS)
        return status;

    status = start(buffer);
    if (status != DECODE_SUCCESS)
        return status;

    return DECODE_SUCCESS;
}

void VaapiDecoderBase::stop(void)
{
    INFO("base: stop()");
    terminateVA();

    m_currentPTS = INVALID_PTS;
    m_renderTarget = NULL;
    m_lastReference = NULL;
    m_forwardReference = NULL;

    m_lowDelay = false;
    m_rawOutput = false;

    m_videoFormatInfo.valid = false;
}

void VaapiDecoderBase::flush(void)
{

    INFO("base: flush()");
    if (m_surfacePool) {
        m_surfacePool->flush();
    }

    m_currentPTS = INVALID_PTS;
    m_renderTarget = NULL;
    m_lastReference = NULL;
    m_forwardReference = NULL;
}

void VaapiDecoderBase::flushOutport(void)
{
}

const VideoRenderBuffer *VaapiDecoderBase::getOutput(bool draining)
{
    if (!m_surfacePool)
        return NULL;
    if (draining)
        flushOutport();

    VideoRenderBuffer *buffer = m_surfacePool->getOutput();

#ifdef __ENABLE_DEBUG__
    if (buffer) {
        renderPictureCount++;
        DEBUG("getOutput renderPictureCount: %d", renderPictureCount);
    }
#endif

    return buffer;
}

Decode_Status VaapiDecoderBase::getOutput(unsigned long draw, int64_t *timeStamp
    , int drawX, int drawY, int drawWidth, int drawHeight, bool draining
    , int frameX, int frameY, int frameWidth, int frameHeight)
{
    VAStatus vaStatus = VA_STATUS_SUCCESS;
    const VideoRenderBuffer *renderBuffer = getOutput(draining);

    if (!renderBuffer)
        return RENDER_NO_AVAILABLE_FRAME;

    if (frameX == -1 && frameY == -1 && frameWidth == -1 && frameHeight == -1) {
        frameX = 0;
        frameY = 0;
        frameWidth = m_videoFormatInfo.width;
        frameHeight = m_videoFormatInfo.height;
    }

    if (!draw || drawX < 0 || drawY < 0 || drawWidth <=0 || drawHeight <=0
        || frameX < 0 || frameY < 0 || frameWidth <= 0 || frameHeight <= 0)
        return RENDER_INVALID_PARAMETER;

#if __ENABLE_X11__
    vaStatus = vaPutSurface(m_display->getID(), renderBuffer->surface,
            draw, drawX, drawY, drawWidth, drawHeight,
            frameX, frameY, frameWidth, frameHeight,
            NULL,0,0);
#else
    vaStatus = VA_STATUS_ERROR_OPERATION_FAILED;
    ERROR("vaPutSurface is not supported when libva-x11 backend is disable during build (--disable-x11)");
#endif

    if (vaStatus != VA_STATUS_SUCCESS)
        return RENDER_FAIL;

    *timeStamp = renderBuffer->timeStamp;

    renderDone(renderBuffer);
    return RENDER_SUCCESS;
}

const VideoFormatInfo *VaapiDecoderBase::getFormatInfo(void)
{
    INFO("base: getFormatInfo()");

    if (!m_VAStarted)
        return NULL;

    return &m_videoFormatInfo;
}

Decode_Status VaapiDecoderBase::getOutput(VideoFrameRawData* frame, bool draining)
{
    if (!m_surfacePool)
        return RENDER_NO_AVAILABLE_FRAME;

    if (!frame)
        return DECODE_INVALID_DATA;

    if (draining)
        flushOutport();

    if (!m_surfacePool->getOutput(frame))
        return RENDER_NO_AVAILABLE_FRAME;

#ifdef __ENABLE_DEBUG__
    renderPictureCount++;
    DEBUG("getOutput renderPictureCount=%d, timeStamp=%ld", renderPictureCount, frame->timeStamp);
#endif

    return RENDER_SUCCESS;
}

Decode_Status VaapiDecoderBase::populateOutputHandles(VideoFrameRawData *frames, uint32_t &frameCount)
{
    if (!m_surfacePool)
        return RENDER_NO_AVAILABLE_FRAME;

    if (!m_surfacePool->populateOutputHandles(frames, frameCount))
        return RENDER_NO_AVAILABLE_FRAME;
    return RENDER_SUCCESS;
}

void VaapiDecoderBase::renderDone(const VideoRenderBuffer * renderBuf)
{
    INFO("base: renderDone()");
    if (!m_surfacePool) {
        ERROR("surface pool is not initialized yet");
        return;
    }
    m_surfacePool->recycle(renderBuf);
}

void VaapiDecoderBase::renderDone(VideoFrameRawData* frame)
{
    INFO("base: renderDone()");
    if (!m_surfacePool) {
        ERROR("surface pool is not initialized yet");
        return;
    }
    m_surfacePool->recycle(frame);
}

Decode_Status VaapiDecoderBase::updateReference(void)
{
    Decode_Status status;
    // update reference frames
    if (m_renderTarget->referenceFrame) {
        // managing reference for MPEG4/H.263/WMV.
        // AVC should manage reference frame in a different way
        if (m_forwardReference != NULL) {
            // this foward reference is no longer needed
            m_forwardReference->asReferernce = false;
        }
        // Forware reference for either P or B frame prediction
        m_forwardReference = m_lastReference;
        m_renderTarget->asReferernce = true;

        // the last reference frame.
        m_lastReference = m_renderTarget;
    }
    return DECODE_SUCCESS;
}

Decode_Status
    VaapiDecoderBase::setupVA(uint32_t numSurface, VAProfile profile)
{
    INFO("base: setup VA");
    uint32_t i;
    VideoSurfaceBuffer *buf;
    VaapiSurface *suf;
    Decode_Status status;
    VAStatus vaStatus = VA_STATUS_SUCCESS;

    if (m_enableNativeBuffersFlag == true) {
        numSurface = 20;        //NATIVE_WINDOW_COUNT;
    }

    if (m_VAStarted) {
        return DECODE_SUCCESS;
    }

    if (m_display != NULL) {
        WARNING("VA is partially started.");
        return DECODE_FAIL;
    }

#if __PLATFORM_BYT__
    if (setenv("LIBVA_DRIVER_NAME", "wrapper", 1) == 0) {
        INFO("setting LIBVA_DRIVER_NAME to wrapper for chromeos");
    }
#endif
    m_display = VaapiDisplay::create(m_externalDisplay);

    if (!m_display) {
        ERROR("failed to create display");
        return DECODE_FAIL;
    }

    VAConfigAttrib attrib;
    attrib.type = VAConfigAttribRTFormat;
    attrib.value = VA_RT_FORMAT_YUV420;

    ConfigPtr config = VaapiConfig::create(m_display, profile, VAEntrypointVLD,&attrib, 1);
    if (!config) {
        ERROR("failed to create config");
        return DECODE_FAIL;
    }

    m_configBuffer.surfaceNumber = numSurface;
    m_surfacePool = VaapiDecSurfacePool::create(m_display, &m_configBuffer);
    DEBUG("surface pool is created");
    if (!m_surfacePool)
        return DECODE_FAIL;
    std::vector<VASurfaceID> surfaces;
    m_surfacePool->getSurfaceIDs(surfaces);
    if (surfaces.empty())
        return DECODE_FAIL;
    int size = surfaces.size();
    m_context = VaapiContext::create(config,
                                       m_videoFormatInfo.width,
                                       m_videoFormatInfo.height,
                                       0, &surfaces[0], size);

    if (!m_context) {
        ERROR("create context failed");
        return DECODE_FAIL;
    }

    if (!m_display->setRotation(m_configBuffer.rotationDegrees)) {
        return DECODE_FAIL;
    }

    if (!(m_configBuffer.flag & USE_NATIVE_GRAPHIC_BUFFER)) {
        m_videoFormatInfo.surfaceWidth = m_videoFormatInfo.width;
        m_videoFormatInfo.surfaceHeight = m_videoFormatInfo.height;
    }

    m_VAStarted = true;
    return DECODE_SUCCESS;
}

Decode_Status VaapiDecoderBase::terminateVA(void)
{
    INFO("base: terminate VA");
    m_surfacePool.reset();
    DEBUG("surface pool is reset");
    m_context.reset();
    m_display.reset();

    m_VAStarted = false;
    return DECODE_SUCCESS;
}

void VaapiDecoderBase::setNativeDisplay(NativeDisplay * nativeDisplay)
{
    if (!nativeDisplay || nativeDisplay->type == NATIVE_DISPLAY_AUTO)
        return;

    m_externalDisplay = *nativeDisplay;
}

/* not used funtion here */
void VaapiDecoderBase::enableNativeBuffers(void)
{
}

Decode_Status
    VaapiDecoderBase::getClientNativeWindowBuffer(void *bufferHeader,
                                                  void *nativeBufferHandle)
{
    return DECODE_SUCCESS;
}

Decode_Status VaapiDecoderBase::flagNativeBuffer(void *pBuffer)
{
    return DECODE_SUCCESS;
}

void VaapiDecoderBase::releaseLock(bool lockable=false)
{
    if (!m_surfacePool)
        return;

    m_surfacePool->setWaitable(lockable);
}

SurfacePtr VaapiDecoderBase::createSurface()
{
    SurfacePtr surface;
    if (m_surfacePool) {
        surface = m_surfacePool->acquireWithWait();
    }
    return surface;
}

Decode_Status VaapiDecoderBase::outputPicture(const PicturePtr& picture)
{
    //TODO: reorder poc
    return m_surfacePool->output(picture->getSurface(),
        picture->m_timeStamp)?DECODE_SUCCESS:DECODE_FAIL;
}

} //namespace YamiMediaCodec
<|endoftext|>


<commit_before>/*
 * Earl, the fanciest ETF Packer and Unpacker for Python.
 * Written as a C++ Extension for Maximum Effort and Speed.
 *
 * Copyright 2016 Charles Click under the MIT License.
 */

 // Includes
 #include <Python.h>
 #include <string>
 #include <vector>

// External Term Format Defines
#define FLOAT_IEEE_EXT 'F'
#define BIT_BINARY_EXT 'M'
#define SMALL_INTEGER_EXT 'a'
#define INTEGER_EXT 'b'
#define FLOAT_EXT 'c'
#define SMALL_TUPLE_EXT 'h'
#define LARGE_TUPLE_EXT 'i'
#define NIL_EXT 'j'
#define STRING_EXT 'k'
#define LIST_EXT 'l'
#define BINARY_EXT 'm'
#define SMALL_BIG_EXT 'n'
#define LARGE_BIG_EXT 'o'
#define MAP_EXT 't'

#if _MSC_VER // MSVC doesn't support or
#define or ||
#endif

// Function Prototypes
// Packing Functions
std::string etfp_small_int(int value);
std::string etfp_big_int(unsigned long value);
std::string etfp_string(PyObject* value);
std::string etfp_float(double value);
std::string etfp_tuple(PyObject* tuple);
std::string etfp_set(PyObject* set);
std::string etfp_list(PyObject* list);
std::string etfp_dict(PyObject* dict);
std::string etf_pack_item(PyObject* object);
static earl_pack(PyObject* self, PyObject* args);
// Unpacking Functions
PyObject* etfup_bytes(PyObject* item);
PyObject* etfup_str(PyObject* item);
PyObject* etfup_small_int(int value);
PyObject* etfup_big_int(unsigned long value);
PyObject* etfup_string(std::string text);
PyObject* etfup_float(double value);
PyObject* etfup_tuple(std::vector tuple);
PyObject* etfup_set(std::vector set);
PyObject* etfup_list(std::vector list);
PyObject* etfup_dict(std::string etfbytes); // We have to parse this as the bytes by itself or we'll lose the depth.
static earl_unpack(PyObject* self, PyObject* args);
// End Function Prototypes

std::string etfp_small_int(int value){

  std::string buffer = SMALL_INTEGER_EXT;
  buffer += char(value);
  return buffer;

}

std::string etfp_big_int(unsigned long value){

  std::string buffer = INTEGER_EXT;
  buffer += ((value >> 24) & 0xFF);
  buffer += ((value >> 16) & 0xFF);
  buffer += ((value >> 8) & 0xFF);
  buffer += (value & 0xFF);

  return buffer;

}

std::string etfp_string(PyObject *value){

  int len = PyUnicode_GET_LENGTH(value);
  int kind = PyUnicode_KIND(value);

  std::string buffer = STRING_EXT;
  buffer += (len >> 8) & 0xFF;
  buffer += len & 0xFF;
  if (!len or !kind){

      if ( !PyErr_Occurred() ){

          PyErr_SetString(PyExc_RuntimeError, "Failed to process the python string.");

      }

      return NULL;

  }

  for( int i={0}; i < len; i++){

      buffer += char(PyUnicode_READ(kind, PyUnicode_DATA(value), i));

  }

  return buffer;

}

std::string etfp_float(double value){

  std::string buffer = FLOAT_IEEE_EXT;

  unsigned char const * p = reinterpret_cast<unsigned char const *>(&value);

  if ( sizeof(p) < 8 ){

    return NULL;

  }

  for ( int ii={0}; ii < 8; ii++ ){

      buffer += (int(p[7-ii]) & 0xFF);

  }

  return buffer;

}

std::string etfp_tuple(PyObject* tuple){

  Py_ssize_t len = PyTuple_Size(tuple);
  std::string buffer = (len > 256 ? LARGE_TUPLE_EXT : SMALL_TUPLE_EXT);

  if( len > 256 ){

    buffer += ((len >> 24) & 0xFF);
    buffer += ((len >> 16) & 0xFF);
    buffer += ((len >> 8) & 0xFF);
    buffer += (len & 0xFF);

  } else {

    buffer += (len & 0xFF);

  }

  for( int ii={0}; ii < len; ii++ ){

      PyObject* temp = PyTuple_GetItem(tuple, ii);

      buffer += etf_pack_item(temp);

  }

  return buffer;

}

std::string etfp_set(PyObject* set){

  Py_ssize_t len = PySet_Size(set);
  std::string buffer = LIST_EXT;

  buffer += ((len >> 24) & 0xFF);
  buffer += ((len >> 16) & 0xFF);
  buffer += ((len >> 8) & 0xFF);
  buffer += (len & 0xFF);

  for( int ii={0}; ii < len; ii++ ){

    PyObject* temp = PySet_Pop(set);
    buffer += etf_pack_item(temp);

  }

  buffer += NIL_EXT;
  return buffer;

}

std::string etfp_list(PyObject* list){

  Py_ssize_t len = PyList_Size(list);
  std::string buffer = LIST_EXT;

  buffer += ((len >> 24) & 0xFF);
  buffer += ((len >> 16) & 0xFF);
  buffer += ((len >> 8) & 0xFF);
  buffer += (len & 0xFF);

  for( int ii={0}; ii < len; ii++ ){

    PyObject* temp = PyList_GetItem(list, ii);
    buffer += etf_pack_item(temp);

  }

  buffer += NIL_EXT;
  return buffer;

}

std::string etfp_dict(PyObject* dict){

  Py_ssize_t len = PyDict_Size(dict);
  std::string buffer = MAP_EXT;

  buffer += ((len >> 24) & 0xFF);
  buffer += ((len >> 16) & 0xFF);
  buffer += ((len >> 8) & 0xFF);
  buffer += (len & 0xFF);

  len = 0;
  PyObject *k, *v;

  while( PyDict_Next(dict, &len, &k, &v) ){

    buffer += etf_pack_item(k);
    buffer += etf_pack_item(v);

  }

  return buffer;

}

std::string etf_pack_item(PyObject* temp){

  std::string buffer;

  if( PyLong_Check(temp) ){

    unsigned long temp_int = PyLong_AsUnsignedLong(temp);
    temp_int < 256 ? buffer += etfp_small_int(temp_int) : buffer += etfp_big_int(temp_int);

  } else if( PyUnicode_Check(temp) ) {

    if( PyUnicode_READY(temp) != 0 ){

      if( !PyErr_Occurred() ){

        PyErr_SetString(PyExc_RuntimeError, "Earl wasn't able to migrate the Python Unicode data to memory.");

      }
      return NULL;

    }else{

      buffer += etfp_string(temp);

    }

  }else if( PyFloat_Check(temp) ){

    buffer += etfp_float(PyFloat_AsDouble(temp));

  }else if( PyTuple_Check(temp) ){

    buffer += etfp_tuple(temp);

  }else if( PySet_Check(temp) ){

    buffer += etfp_set(temp);

  }else if( PyList_Check(temp) ){

    buffer += etfp_list(temp);

  }else if( PyDict_Check(temp) ){

    buffer += etfp_dict(temp);

  }else{

    if ( !PyErr_Occurred() ){

      PyErr_SetString(PyExc_TypeError, "Earl can't pack one of the types you gave it!");

    }
    return NULL;

  }

  return buffer;

}

PyObject* etfup_bytes(PyObject* item){

    std::string buffer(PyBytes_AsString(item));
    int pos = 0;

    for( pos; pos < buffer.length()-1; pos++ ){

        if( buffer[ii] == INTEGER_EXT or buffer[ii] == SMALL_INTEGER_EXT ){

          if( buffer[ii] == INTEGER_EXT ){

            long upd = 0;
            for( int nb = {1}; nb < 5; nb++ ){

              upd = (upd << 8) + buffer[ii+nb];

            }
            return PyLong_FromLong(upd);

          } else {

            long upd = 0;
            upd = (upd << 8) + buffer[ii+1];
            return PyLong_FromLong(upd);

          }

        } else if( buffer[ii] == FLOAT_IEEE_EXT or buffer[ii] == FLOAT_EXT ){

        } else if( buffer[ii] == LIST_EXT ){

        } else if( buffer[ii] == MAP_EXT ){

        } else if( buffer[ii] == STRING_EXT ){

        } else if( buffer[ii] == SMALL_TUPLE_EXT or buffer[ii] = LARGE_TUPLE_EXT ){

        }

    }

}

PyObject* etfup_str(PyObject* item);
PyObject* etfup_small_int(int value);
PyObject* etfup_big_int(unsigned long value);
PyObject* etfup_string(std::string text);
PyObject* etfup_float(double value);
PyObject* etfup_tuple(std::vector tuple);
PyObject* etfup_set(std::vector set);
PyObject* etfup_list(std::vector list);
PyObject* etfup_dict(std::string etfbytes);

static PyObject* earl_pack(PyObject* self, PyObject *args){

  std::string package;
  Py_ssize_t len = PyTuple_Size(args);

  if( !len ){

    if( !PyErr_Occurred() ){

      PyErr_SetString(PyExc_SyntaxError, "You must supply at least one argument.");

    }

    return NULL;

  }

  package = "\x83";

  if( len > 1 ){

    package += LIST_EXT;
    package += (len & 0xFF);

  }

  for( int i={0}; i < len; i++ ){

    PyObject* temp = PyTuple_GetItem(args, i);

    if( temp == NULL ){

      if( !PyErr_Occurred() ){

        PyErr_SetString(PyExc_TypeError, "Earl wasn't able to unpack all your arguments for some reason.");

      }
      return NULL;

    }

    package += etf_pack_item(temp);

  }

  if( len > 1 ){

    package += NIL_EXT;

  }

  return Py_BuildValue("y#", package.c_str(), package.length());

}

static PyObject* earl_unpack(PyObject* self, PyObject *args){

    Py_ssize_t len = PyTuple_Size(args);

    if ( len > 1 ){

        PyObject* return_value = PyList_New(len);

        for( int i={0}; i < len; i++){

            PyObject* temp = PyTuple_GetItem(args, i);

            if( PyBytes_Check(temp) ){

                if( PyList_SetItem(return_value, i, etfup_bytes(temp)) == -1 ){

                    if( !PyErr_Occurred() ){

                        PyErr_SetString(PyExc_RuntimeError, "Earl was unable to unpack data.");
                        return NULL;

                    }

                }

            } else if( PyUnicode_Check(temp) ){

                if( PyList_SetItem(return_value, i, etfup_str(temp)) == -1 ){

                    if( !PyErr_Occurred() ){

                        PyErr_SetString(PyExc_RuntimeError, "Earl was unable to unpack data.");
                        return NULL;

                    }

                }

            } else {

                if( !PyErr_Occurred() ){

                    PyErr_SetString(PyExc_TypeError, "Earl can only unpack Str and Bytes objects.");
                    return NULL;

                }

            }

        }

        return Py_BuildValue("O", return_value);

    } else {

        if( PyBytes_Check(temp) ){

            return Py_BuildValue("O", etfup_bytes(PyTuple_GetItem(tuple, 0)));

        } else if( PyUnicode_Check(temp) ){

            return Py_BuildValue("O", etfup_str(PyTuple_GetItem(tuple, 0)));

        } else {

            if( !PyErr_Occurred() ){

                PyErr_SetString(PyExc_TypeError, "Earl can only unpack Str and Bytes objects.");
                return NULL;

            }

        }

    }

    return NULL;

}

static char earl_pack_docs[] = "pack(values): Pack a bunch of things into an External Term Format. Multiple items or types of items are packed into a list format.";
static char earl_unpack_docs[] = "unpack(data): Unpack ETF data. Data is unpacked according to standards and supported types. If multiple items are given, return as a list.";

static PyMethodDef earlmethods[] = {

  {"pack", earl_pack, METH_VARARGS, earl_pack_docs},
  {"unpack", earl_unpack, METH_VARARGS, earl_unpack_docs},
  {NULL, NULL, 0, NULL}

};

static struct PyModuleDef earl = {

  PyModuleDef_HEAD_INIT,
  "earl",
  "Earl is the fanciest External Term Format library for Python.",
  -1,
  earlmethods

};

PyMODINIT_FUNC PyInit_earl(void){

  return PyModule_Create(&earl);

}
<commit_msg>More work on unpack contd<commit_after>/*
 * Earl, the fanciest ETF Packer and Unpacker for Python.
 * Written as a C++ Extension for Maximum Effort and Speed.
 *
 * Copyright 2016 Charles Click under the MIT License.
 */

 // Includes
 #include <Python.h>
 #include <string>
 #include <vector>

// External Term Format Defines
#define FLOAT_IEEE_EXT "F"
#define BIT_BINARY_EXT "M"
#define SMALL_INTEGER_EXT "a"
#define INTEGER_EXT "b"
#define FLOAT_EXT "c"
#define SMALL_TUPLE_EXT "h"
#define LARGE_TUPLE_EXT "i"
#define NIL_EXT "j"
#define STRING_EXT "k"
#define LIST_EXT "l"
#define BINARY_EXT "m"
#define SMALL_BIG_EXT "n"
#define LARGE_BIG_EXT "o"
#define MAP_EXT "t"

#if _MSC_VER // MSVC doesn't support or
#define or ||
#endif

// Function Prototypes
// Packing Functions
std::string etfp_small_int(int value);
std::string etfp_big_int(unsigned long value);
std::string etfp_string(PyObject* value);
std::string etfp_float(double value);
std::string etfp_tuple(PyObject* tuple);
std::string etfp_set(PyObject* set);
std::string etfp_list(PyObject* list);
std::string etfp_dict(PyObject* dict);
std::string etf_pack_item(PyObject* object);
static PyObject* earl_pack(PyObject* self, PyObject* args);
// Unpacking Functions
PyObject* etfup_bytes(PyObject* item);
PyObject* etfup_str(PyObject* item);
PyObject* etfup_small_int(int value);
PyObject* etfup_big_int(unsigned long value);
PyObject* etfup_string(std::string text);
PyObject* etfup_float(double value);
PyObject* etfup_tuple(std::vector tuple);
PyObject* etfup_set(std::vector set);
PyObject* etfup_list(std::vector list);
PyObject* etfup_dict(std::string etfbytes); // We have to parse this as the bytes by itself or we'll lose the depth.
static PyObject* earl_unpack(PyObject* self, PyObject* args);
// End Function Prototypes

std::string etfp_small_int(int value){

  std::string buffer = SMALL_INTEGER_EXT;
  buffer += char(value);
  return buffer;

}

std::string etfp_big_int(unsigned long value){

  std::string buffer = INTEGER_EXT;
  buffer += ((value >> 24) & 0xFF);
  buffer += ((value >> 16) & 0xFF);
  buffer += ((value >> 8) & 0xFF);
  buffer += (value & 0xFF);

  return buffer;

}

std::string etfp_string(PyObject *value){

  int len = PyUnicode_GET_LENGTH(value);
  int kind = PyUnicode_KIND(value);

  std::string buffer = STRING_EXT;
  buffer += (len >> 8) & 0xFF;
  buffer += len & 0xFF;
  if (!len or !kind){

      if ( !PyErr_Occurred() ){

          PyErr_SetString(PyExc_RuntimeError, "Failed to process the python string.");

      }

      return NULL;

  }

  for( int i={0}; i < len; i++){

      buffer += char(PyUnicode_READ(kind, PyUnicode_DATA(value), i));

  }

  return buffer;

}

std::string etfp_float(double value){

  std::string buffer = FLOAT_IEEE_EXT;

  unsigned char const * p = reinterpret_cast<unsigned char const *>(&value);

  if ( sizeof(p) < 8 ){

    return NULL;

  }

  for ( int ii={0}; ii < 8; ii++ ){

      buffer += (int(p[7-ii]) & 0xFF);

  }

  return buffer;

}

std::string etfp_tuple(PyObject* tuple){

  Py_ssize_t len = PyTuple_Size(tuple);
  std::string buffer = (len > 256 ? LARGE_TUPLE_EXT : SMALL_TUPLE_EXT);

  if( len > 256 ){

    buffer += ((len >> 24) & 0xFF);
    buffer += ((len >> 16) & 0xFF);
    buffer += ((len >> 8) & 0xFF);
    buffer += (len & 0xFF);

  } else {

    buffer += (len & 0xFF);

  }

  for( int ii={0}; ii < len; ii++ ){

      PyObject* temp = PyTuple_GetItem(tuple, ii);

      buffer += etf_pack_item(temp);

  }

  return buffer;

}

std::string etfp_set(PyObject* set){

  Py_ssize_t len = PySet_Size(set);
  std::string buffer = LIST_EXT;

  buffer += ((len >> 24) & 0xFF);
  buffer += ((len >> 16) & 0xFF);
  buffer += ((len >> 8) & 0xFF);
  buffer += (len & 0xFF);

  for( int ii={0}; ii < len; ii++ ){

    PyObject* temp = PySet_Pop(set);
    buffer += etf_pack_item(temp);

  }

  buffer += NIL_EXT;
  return buffer;

}

std::string etfp_list(PyObject* list){

  Py_ssize_t len = PyList_Size(list);
  std::string buffer = LIST_EXT;

  buffer += ((len >> 24) & 0xFF);
  buffer += ((len >> 16) & 0xFF);
  buffer += ((len >> 8) & 0xFF);
  buffer += (len & 0xFF);

  for( int ii={0}; ii < len; ii++ ){

    PyObject* temp = PyList_GetItem(list, ii);
    buffer += etf_pack_item(temp);

  }

  buffer += NIL_EXT;
  return buffer;

}

std::string etfp_dict(PyObject* dict){

  Py_ssize_t len = PyDict_Size(dict);
  std::string buffer = MAP_EXT;

  buffer += ((len >> 24) & 0xFF);
  buffer += ((len >> 16) & 0xFF);
  buffer += ((len >> 8) & 0xFF);
  buffer += (len & 0xFF);

  len = 0;
  PyObject *k, *v;

  while( PyDict_Next(dict, &len, &k, &v) ){

    buffer += etf_pack_item(k);
    buffer += etf_pack_item(v);

  }

  return buffer;

}

std::string etf_pack_item(PyObject* temp){

  std::string buffer;

  if( PyLong_Check(temp) ){

    unsigned long temp_int = PyLong_AsUnsignedLong(temp);
    temp_int < 256 ? buffer += etfp_small_int(temp_int) : buffer += etfp_big_int(temp_int);

  } else if( PyUnicode_Check(temp) ) {

    if( PyUnicode_READY(temp) != 0 ){

      if( !PyErr_Occurred() ){

        PyErr_SetString(PyExc_RuntimeError, "Earl wasn't able to migrate the Python Unicode data to memory.");

      }
      return NULL;

    }else{

      buffer += etfp_string(temp);

    }

  }else if( PyFloat_Check(temp) ){

    buffer += etfp_float(PyFloat_AsDouble(temp));

  }else if( PyTuple_Check(temp) ){

    buffer += etfp_tuple(temp);

  }else if( PySet_Check(temp) ){

    buffer += etfp_set(temp);

  }else if( PyList_Check(temp) ){

    buffer += etfp_list(temp);

  }else if( PyDict_Check(temp) ){

    buffer += etfp_dict(temp);

  }else{

    if ( !PyErr_Occurred() ){

      PyErr_SetString(PyExc_TypeError, "Earl can't pack one of the types you gave it!");

    }
    return NULL;

  }

  return buffer;

}

PyObject* etfup_bytes(PyObject* item){

    std::string buffer(PyBytes_AsString(item));
    int pos = 0;

    for( pos; pos < buffer.length()-1; pos++ ){

        if( buffer[ii] == INTEGER_EXT or buffer[ii] == SMALL_INTEGER_EXT ){
<<<<<<< HEAD

          if( buffer[ii] == INTEGER_EXT ){

            long upd = 0;
            for( int nb = {1}; nb < 5; nb++ ){

              upd = (upd << 8) + buffer[ii+nb];

            }
            return PyLong_FromLong(upd);

          } else {

            long upd = 0;
            upd = (upd << 8) + buffer[ii+1];
            return PyLong_FromLong(upd);

          }

=======

>>>>>>> 8b8d3b34dff8753f1dc9dee39eb9e74fc0ddf131
        } else if( buffer[ii] == FLOAT_IEEE_EXT or buffer[ii] == FLOAT_EXT ){

        } else if( buffer[ii] == LIST_EXT ){

        } else if( buffer[ii] == MAP_EXT ){

        } else if( buffer[ii] == STRING_EXT ){

        } else if( buffer[ii] == SMALL_TUPLE_EXT or buffer[ii] = LARGE_TUPLE_EXT ){

        }

    }

}

PyObject* etfup_str(PyObject* item);
PyObject* etfup_small_int(int value);
PyObject* etfup_big_int(unsigned long value);
PyObject* etfup_string(std::string text);
PyObject* etfup_float(double value);
PyObject* etfup_tuple(std::vector tuple);
PyObject* etfup_set(std::vector set);
PyObject* etfup_list(std::vector list);
PyObject* etfup_dict(std::string etfbytes);

static PyObject* earl_pack(PyObject* self, PyObject *args){

  std::string package;
  Py_ssize_t len = PyTuple_Size(args);

  if( !len ){

    if( !PyErr_Occurred() ){

      PyErr_SetString(PyExc_SyntaxError, "You must supply at least one argument.");

    }

    return NULL;

  }

  package = "\x83";

  if( len > 1 ){

    package += LIST_EXT;
    package += (len & 0xFF);

  }

  for( int i={0}; i < len; i++ ){

    PyObject* temp = PyTuple_GetItem(args, i);

    if( temp == NULL ){

      if( !PyErr_Occurred() ){

        PyErr_SetString(PyExc_TypeError, "Earl wasn't able to unpack all your arguments for some reason.");

      }
      return NULL;

    }

    package += etf_pack_item(temp);

  }

  if( len > 1 ){

    package += NIL_EXT;

  }

  return Py_BuildValue("y#", package.c_str(), package.length());

}

static PyObject* earl_unpack(PyObject* self, PyObject *args){

    Py_ssize_t len = PyTuple_Size(args);

    if ( len > 1 ){

        PyObject* return_value = PyList_New(len);

        for( int i={0}; i < len; i++){

            PyObject* temp = PyTuple_GetItem(args, i);

            if( PyBytes_Check(temp) ){

                if( PyList_SetItem(return_value, i, etfup_bytes(temp)) == -1 ){

                    if( !PyErr_Occurred() ){

                        PyErr_SetString(PyExc_RuntimeError, "Earl was unable to unpack data.");
                        return NULL;

                    }

                }

            } else if( PyUnicode_Check(temp) ){

                if( PyList_SetItem(return_value, i, etfup_str(temp)) == -1 ){

                    if( !PyErr_Occurred() ){

                        PyErr_SetString(PyExc_RuntimeError, "Earl was unable to unpack data.");
                        return NULL;

                    }

                }

            } else {

                if( !PyErr_Occurred() ){

                    PyErr_SetString(PyExc_TypeError, "Earl can only unpack Str and Bytes objects.");
                    return NULL;

                }

            }

        }

        return Py_BuildValue("O", return_value);

    } else {

        if( PyBytes_Check(temp) ){

            return Py_BuildValue("O", etfup_bytes(PyTuple_GetItem(tuple, 0)));

        } else if( PyUnicode_Check(temp) ){

            return Py_BuildValue("O", etfup_str(PyTuple_GetItem(tuple, 0)));

        } else {

            if( !PyErr_Occurred() ){

                PyErr_SetString(PyExc_TypeError, "Earl can only unpack Str and Bytes objects.");
                return NULL;

            }

        }

    }

    return NULL;

}

static char earl_pack_docs[] = "pack(values): Pack a bunch of things into an External Term Format. Multiple items or types of items are packed into a list format.";
static char earl_unpack_docs[] = "unpack(data): Unpack ETF data. Data is unpacked according to standards and supported types. If multiple items are given, return as a list.";

static PyMethodDef earlmethods[] = {

  {"pack", earl_pack, METH_VARARGS, earl_pack_docs},
  {"unpack", earl_unpack, METH_VARARGS, earl_unpack_docs},
  {NULL, NULL, 0, NULL}

};

static struct PyModuleDef earl = {

  PyModuleDef_HEAD_INIT,
  "earl",
  "Earl is the fanciest External Term Format library for Python.",
  -1,
  earlmethods

};

PyMODINIT_FUNC PyInit_earl(void){

  return PyModule_Create(&earl);

}
<|endoftext|>


<commit_before>

// Copyright 2010-2012 University of Washington. All Rights Reserved.
// LICENSE_PLACEHOLDER
// This software was created with Government support under DE
// AC05-76RL01830 awarded by the United States Department of
// Energy. The Government has certain rights in the software.

#ifndef __FULLEMPTY_HPP__
#define __FULLEMPTY_HPP__

#include <gflags/gflags.h>
#include <glog/logging.h>

#include "ConditionVariableLocal.hpp"

namespace Grappa {

  /// @addtogroup Synchronization
  /// @{

  /// Wrapper class to provide full-bit semantics for arbitrary data.
  template< typename T >
  class FullEmpty {
  private:
    enum class State : bool { EMPTY = false, FULL = true };

  public:
    union {
      struct {
        State state_ : 1;
        intptr_t waiters_ : 63; // can't include pointers in bitfield, so use intptr_t
      };
      intptr_t raw_; // unnecessary; just to ensure alignment
    };

  private:
    T t_;

    void block_until( State desired_state ) {
      while( state_ != desired_state ) {
        DVLOG(5) << "In " << __PRETTY_FUNCTION__
                 << ", blocking until " << (desired_state == State::FULL ? "full" : "empty");
	Grappa::wait( this );
      }
    }

  public:

    FullEmpty( ) : state_( State::EMPTY ), waiters_( 0 ), t_() {}

    FullEmpty( T t ) : state_( State::FULL ), waiters_( 0 ), t_(t) {}

    inline bool full() const { return state_ == State::FULL; }
    inline bool empty() const { return state_ == State::EMPTY; }

    inline void reset() {
      CHECK(waiters_ == 0);
      state_ = State::EMPTY;
    }

    T writeXF( T t ) {
      t_ = t;
      state_ = State::FULL;
      Grappa::broadcast( this );
      return t_;
    }

    T writeEF( T t ) {
      block_until(State::EMPTY);
      return writeXF( t );
    }

    T writeFF( T t ) {
      block_until(State::FULL);
      return writeXF( t );
    }

    T readXX() {
      return t_;
    }

    T readFF() {
      block_until(State::FULL);
      return readXX();
    }

    T readFE() {
      block_until(State::FULL);
      state_ = State::EMPTY;
      Grappa::broadcast( this );
      return readXX();
    }

  };
  /// @}

}

#endif
<commit_msg>Rearrange synchronization in condition variable. I think this is kinder to the scheduler.<commit_after>

// Copyright 2010-2012 University of Washington. All Rights Reserved.
// LICENSE_PLACEHOLDER
// This software was created with Government support under DE
// AC05-76RL01830 awarded by the United States Department of
// Energy. The Government has certain rights in the software.

#ifndef __FULLEMPTY_HPP__
#define __FULLEMPTY_HPP__

#include <gflags/gflags.h>
#include <glog/logging.h>

#include "ConditionVariableLocal.hpp"

namespace Grappa {

  /// @addtogroup Synchronization
  /// @{

  /// Wrapper class to provide full-bit semantics for arbitrary data.
  template< typename T >
  class FullEmpty {
  private:
    enum class State : bool { EMPTY = false, FULL = true };

  public:
    union {
      struct {
        State state_ : 1;
        intptr_t waiters_ : 63; // can't include pointers in bitfield, so use intptr_t
      };
      intptr_t raw_; // unnecessary; just to ensure alignment
    };

  private:
    T t_;

    void block_until( State desired_state ) {
      while( state_ != desired_state ) {
        DVLOG(5) << "In " << __PRETTY_FUNCTION__
                 << ", blocking until " << (desired_state == State::FULL ? "full" : "empty");
	Grappa::wait( this );
      }
    }

  public:

    FullEmpty( ) : state_( State::EMPTY ), waiters_( 0 ), t_() {}

    FullEmpty( T t ) : state_( State::FULL ), waiters_( 0 ), t_(t) {}

    inline bool full() const { return state_ == State::FULL; }
    inline bool empty() const { return state_ == State::EMPTY; }

    inline void reset() {
      CHECK(waiters_ == 0);
      state_ = State::EMPTY;
    }

    T writeXF( T t ) {
      t_ = t;
      state_ = State::FULL;
      //Grappa::broadcast( this );
      Grappa::signal( this );
      return t_;
    }

    T writeEF( T t ) {
      block_until(State::EMPTY);
      T tt = writeXF( t );
      Grappa::signal( this );
      return tt;
    }

    T writeFF( T t ) {
      block_until(State::FULL);
      T tt = writeXF( t );
      Grappa::signal( this );
      return tt;
    }

    T readXX() {
      return t_;
    }

    T readFF() {
      block_until(State::FULL);
      T tt = readXX();
      Grappa::signal( this );
      return tt;
    }

    T readFE() {
      block_until(State::FULL);
      state_ = State::EMPTY;
      Grappa::broadcast( this );
      return readXX();
    }

  };
  /// @}

}

#endif
<|endoftext|>


<commit_before>#include <cassert>
#include <cstdio>
#include <memory>
#include <string>
#include <vector>

constexpr int kSampleRate = 44100;
constexpr int kInputChannels = 1;
constexpr int kOutputChannels = 2;

// How many samples to wait before starting each new vuvuzela.
constexpr int kStartDelta = 53;

// How many samples to wait between ending one vuvuzela and replacing it with
// another.
constexpr int kInterDelta = 22050;

// Quantization for how much one output channel is emphasized relative to the
// others, per vuvuzela.
constexpr int kChannelEmphasisSteps = 11;

// The first output track will have 1 vuvuzela. The second to last will have
// 2**kMaxExponent vuvuzelas. The last will be a fade-out track.
constexpr int kMaxExponent = 10;

// The length of each track, except the fade-out at the end.
constexpr int kTrackSamples = kSampleRate * 120;

class ExponentialVuvuzelas {
 public:
  void LoadInputAudio() {
    const char* const files[] = {
      "vuvuzela-01.flac.f64le",
      "vuvuzela-02.flac.f64le",
      "vuvuzela-03.flac.f64le",
      "vuvuzela-04.flac.f64le",
      "vuvuzela-05.flac.f64le",
      "vuvuzela-06.flac.f64le",
      "vuvuzela-07.flac.f64le",
      "vuvuzela-08.flac.f64le",
      "vuvuzela-09.flac.f64le",
      "vuvuzela-10.flac.f64le",
      "vuvuzela-11.flac.f64le",
      "vuvuzela-12.flac.f64le",
      "vuvuzela-13.flac.f64le",
      "vuvuzela-14.flac.f64le",
      "vuvuzela-15.flac.f64le",
      "vuvuzela-17.flac.f64le",
      "vuvuzela-18.flac.f64le",
      "vuvuzela-19.flac.f64le",
      "vuvuzela-20.flac.f64le",
      "vuvuzela-21.flac.f64le",
      "vuvuzela-22.flac.f64le",
      "vuvuzela-23.flac.f64le",
      "vuvuzela-24.flac.f64le",
      "vuvuzela-25.flac.f64le",
      "vuvuzela-26.flac.f64le",
      "vuvuzela-27.flac.f64le",
      "vuvuzela-28.flac.f64le",
      "vuvuzela-29.flac.f64le",
      "vuvuzela-30.flac.f64le",
      "vuvuzela-31.flac.f64le",
      "vuvuzela-32.flac.f64le",
      "vuvuzela-33.flac.f64le",
      "vuvuzela-34.flac.f64le",
      "vuvuzela-35.flac.f64le",
      "vuvuzela-36.flac.f64le",
      "vuvuzela-37.flac.f64le",
      "vuvuzela-38.flac.f64le",
    };
    for (const char* file : files) {
      int ret;

      FILE* fh = fopen(file, "rb");
      assert(fh != nullptr);

      ret = fseek(fh, 0L, SEEK_END);
      assert(ret == 0);
      long int length = ftell(fh);
      assert(length >= 0L);
      assert(length % (sizeof(double) * kInputChannels) == 0);
      rewind(fh);

      auto raw_audio = ::std::make_unique<double[]>(length / sizeof(double));
      size_t read_count =
          fread(raw_audio.get(), sizeof(double) * kInputChannels,
                length / (sizeof(double) * kInputChannels), fh);
      assert(read_count == length / (sizeof(double) * kInputChannels));

      input_audio_.emplace_back(read_count, ::std::move(raw_audio));

      ret = fclose(fh);
      assert(ret == 0);
    }
  }

  // Increment the exponent, for the next track. Make sure to call this at
  // least once before calling Advance().
  void IncrementExponent() {
    ++exponent_;
    assert(exponent_ <= kMaxExponent);

    int silent_samples = 0;
    while (in_play_.size() < 1ULL << exponent_) {
      double mix[kOutputChannels];
      const double emphasized_channel_min = 1.0 / kOutputChannels;
      for (int channel = 0; channel < kOutputChannels; ++channel) {
        const double emphasized_channel =
            emphasized_channel_min +
            (1.0 - emphasized_channel_min) *
            (in_play_.size() % kChannelEmphasisSteps) /
            (kChannelEmphasisSteps - 1.0);
        if (in_play_.size() % kOutputChannels == (size_t)channel) {
          mix[channel] = emphasized_channel;
        } else {
          mix[channel] = (1.0 - emphasized_channel) / (kOutputChannels - 1);
        }
      }

      Vuvuzela v;
      v.input = -1;
      v.samples_remaining = silent_samples;
      for (int i = 0; i < kOutputChannels; ++i) {
        v.mix[i] = mix[i];
      }
      in_play_.push_back(v);

      silent_samples += kStartDelta;
    }
  }

  // Advance by the given number of samples, and return the generated audio.
  // Pass -1 to disable re-creating vuvuzelas as they finish, and advance until
  // all existing ones finish.
  ::std::vector<double> Advance(int samples) {
    ::std::vector<double> audio;

    for (int sample_number = 0;
         samples < 0 || sample_number < samples;
         ++sample_number) {
      bool anything_in_play = false;
      double sample[kOutputChannels] = {};

      for (Vuvuzela& vuvuzela : in_play_) {
        // Re-fill the audio/silence if needed.
        while (vuvuzela.samples_remaining <= 0 && samples >= 0) {
          if (vuvuzela.input < 0) {
            // The silence ended, fill with sound again.
            vuvuzela.input = next_input_++ % input_audio_.size();
            vuvuzela.samples_remaining = input_audio_[vuvuzela.input].first;
          } else {
            // The sound ended, fill with a silence buffer.
            vuvuzela.input = -1;
            vuvuzela.samples_remaining = kInterDelta;
          }
        }

        if (vuvuzela.samples_remaining <= 0) {
          continue;
        }

        anything_in_play = true;

        if (vuvuzela.input < 0) {
          --vuvuzela.samples_remaining;
          continue;
        }

        assert(kInputChannels == 1);
        double input_sample = input_audio_[vuvuzela.input].second[
            input_audio_[vuvuzela.input].first - vuvuzela.samples_remaining];
        for (int channel = 0; channel < kOutputChannels; ++channel) {
          sample[channel] += vuvuzela.mix[channel] * input_sample;
        }
        --vuvuzela.samples_remaining;
      }

      if (anything_in_play) {
        for (const double& s : sample) {
          audio.push_back(s * GetGainFactor((double)sample_number / samples));
        }
      } else {
        break;
      }
    }

    return audio;
  }

 private:
  // Get a multiplier for all output channels, given a progress in [0, 1)
  // within the track. This is based on a model of linearly increasing distance
  // from the virtual audio sources.
  double GetGainFactor(double progress) {
    constexpr double kInitialDistance = 1.0;
    constexpr double kDistancePerExponent = 1.0;

    // Values when the sum of all mixes is maximal.
    constexpr double factor_at_max_sum = 1.0 / (1ULL << kMaxExponent);
    constexpr double distance_at_max_sum =
        kMaxExponent * kDistancePerExponent + kInitialDistance;

    // Additional factor for computations, to ensure that the factor at the end
    // is factor_at_max_sum.
    constexpr double normalization_factor =
        factor_at_max_sum * distance_at_max_sum * distance_at_max_sum;

    if (exponent_ == kMaxExponent) {
      return factor_at_max_sum;
    }

    double distance =
        (exponent_ + progress) * kDistancePerExponent + kInitialDistance;
    assert(distance > 0.0);
    assert(distance <= distance_at_max_sum);

    double factor = normalization_factor / (distance * distance);
    assert(factor > 0.0);
    assert(factor <= 1.0);

    return factor;
  }

  // (number of samples, raw data)
  ::std::vector<::std::pair<int, ::std::unique_ptr<double[]>>> input_audio_;

  struct Vuvuzela {
    int input;  // Index into input_audio_, or -1 for silence.
    int samples_remaining;
    double mix[kOutputChannels];
  };
  ::std::vector<Vuvuzela> in_play_;

  int exponent_ = -1;

  int next_input_ = 0;
};

void WriteAudio(
    const ::std::string& filename, const ::std::vector<double>& audio) {
  FILE* fh = fopen(filename.c_str(), "wb");
  assert(fh != nullptr);
  for (const double& sample : audio) {
    size_t written = fwrite(&sample, sizeof(sample), 1, fh);
    assert(written == 1);
  }
  int ret = fclose(fh);
  assert(ret == 0);
}

int main() {
  ExponentialVuvuzelas exponential_vuvuzelas;
  exponential_vuvuzelas.LoadInputAudio();

  for (int exponent = 0; exponent <= kMaxExponent; ++exponent) {
    exponential_vuvuzelas.IncrementExponent();
    WriteAudio(
        ::std::string("exponent-") + ::std::to_string(exponent) + ".f64le",
        exponential_vuvuzelas.Advance(kTrackSamples));
  }

  WriteAudio("fade-out.f64le", exponential_vuvuzelas.Advance(-1));

  return 0;
}
<commit_msg>Adjust relative volume levels of tracks.<commit_after>#include <cassert>
#include <cstdio>
#include <memory>
#include <string>
#include <vector>

constexpr int kSampleRate = 44100;
constexpr int kInputChannels = 1;
constexpr int kOutputChannels = 2;

// How many samples to wait before starting each new vuvuzela.
constexpr int kStartDelta = 53;

// How many samples to wait between ending one vuvuzela and replacing it with
// another.
constexpr int kInterDelta = 22050;

// Quantization for how much one output channel is emphasized relative to the
// others, per vuvuzela.
constexpr int kChannelEmphasisSteps = 11;

// The first output track will have 1 vuvuzela. The second to last will have
// 2**kMaxExponent vuvuzelas. The last will be a fade-out track.
constexpr int kMaxExponent = 10;

// The length of each track, except the fade-out at the end.
constexpr int kTrackSamples = kSampleRate * 120;

class ExponentialVuvuzelas {
 public:
  void LoadInputAudio() {
    const char* const files[] = {
      "vuvuzela-01.flac.f64le",
      "vuvuzela-02.flac.f64le",
      "vuvuzela-03.flac.f64le",
      "vuvuzela-04.flac.f64le",
      "vuvuzela-05.flac.f64le",
      "vuvuzela-06.flac.f64le",
      "vuvuzela-07.flac.f64le",
      "vuvuzela-08.flac.f64le",
      "vuvuzela-09.flac.f64le",
      "vuvuzela-10.flac.f64le",
      "vuvuzela-11.flac.f64le",
      "vuvuzela-12.flac.f64le",
      "vuvuzela-13.flac.f64le",
      "vuvuzela-14.flac.f64le",
      "vuvuzela-15.flac.f64le",
      "vuvuzela-17.flac.f64le",
      "vuvuzela-18.flac.f64le",
      "vuvuzela-19.flac.f64le",
      "vuvuzela-20.flac.f64le",
      "vuvuzela-21.flac.f64le",
      "vuvuzela-22.flac.f64le",
      "vuvuzela-23.flac.f64le",
      "vuvuzela-24.flac.f64le",
      "vuvuzela-25.flac.f64le",
      "vuvuzela-26.flac.f64le",
      "vuvuzela-27.flac.f64le",
      "vuvuzela-28.flac.f64le",
      "vuvuzela-29.flac.f64le",
      "vuvuzela-30.flac.f64le",
      "vuvuzela-31.flac.f64le",
      "vuvuzela-32.flac.f64le",
      "vuvuzela-33.flac.f64le",
      "vuvuzela-34.flac.f64le",
      "vuvuzela-35.flac.f64le",
      "vuvuzela-36.flac.f64le",
      "vuvuzela-37.flac.f64le",
      "vuvuzela-38.flac.f64le",
    };
    for (const char* file : files) {
      int ret;

      FILE* fh = fopen(file, "rb");
      assert(fh != nullptr);

      ret = fseek(fh, 0L, SEEK_END);
      assert(ret == 0);
      long int length = ftell(fh);
      assert(length >= 0L);
      assert(length % (sizeof(double) * kInputChannels) == 0);
      rewind(fh);

      auto raw_audio = ::std::make_unique<double[]>(length / sizeof(double));
      size_t read_count =
          fread(raw_audio.get(), sizeof(double) * kInputChannels,
                length / (sizeof(double) * kInputChannels), fh);
      assert(read_count == length / (sizeof(double) * kInputChannels));

      input_audio_.emplace_back(read_count, ::std::move(raw_audio));

      ret = fclose(fh);
      assert(ret == 0);
    }
  }

  // Increment the exponent, for the next track. Make sure to call this at
  // least once before calling Advance().
  void IncrementExponent() {
    ++exponent_;
    assert(exponent_ <= kMaxExponent);

    int silent_samples = 0;
    while (in_play_.size() < 1ULL << exponent_) {
      double mix[kOutputChannels];
      const double emphasized_channel_min = 1.0 / kOutputChannels;
      for (int channel = 0; channel < kOutputChannels; ++channel) {
        const double emphasized_channel =
            emphasized_channel_min +
            (1.0 - emphasized_channel_min) *
            (in_play_.size() % kChannelEmphasisSteps) /
            (kChannelEmphasisSteps - 1.0);
        if (in_play_.size() % kOutputChannels == (size_t)channel) {
          mix[channel] = emphasized_channel;
        } else {
          mix[channel] = (1.0 - emphasized_channel) / (kOutputChannels - 1);
        }
      }

      Vuvuzela v;
      v.input = -1;
      v.samples_remaining = silent_samples;
      for (int i = 0; i < kOutputChannels; ++i) {
        v.mix[i] = mix[i];
      }
      in_play_.push_back(v);

      silent_samples += kStartDelta;
    }
  }

  // Advance by the given number of samples, and return the generated audio.
  // Pass -1 to disable re-creating vuvuzelas as they finish, and advance until
  // all existing ones finish.
  ::std::vector<double> Advance(int samples) {
    ::std::vector<double> audio;

    for (int sample_number = 0;
         samples < 0 || sample_number < samples;
         ++sample_number) {
      bool anything_in_play = false;
      double sample[kOutputChannels] = {};

      for (Vuvuzela& vuvuzela : in_play_) {
        // Re-fill the audio/silence if needed.
        while (vuvuzela.samples_remaining <= 0 && samples >= 0) {
          if (vuvuzela.input < 0) {
            // The silence ended, fill with sound again.
            vuvuzela.input = next_input_++ % input_audio_.size();
            vuvuzela.samples_remaining = input_audio_[vuvuzela.input].first;
          } else {
            // The sound ended, fill with a silence buffer.
            vuvuzela.input = -1;
            vuvuzela.samples_remaining = kInterDelta;
          }
        }

        if (vuvuzela.samples_remaining <= 0) {
          continue;
        }

        anything_in_play = true;

        if (vuvuzela.input < 0) {
          --vuvuzela.samples_remaining;
          continue;
        }

        assert(kInputChannels == 1);
        double input_sample = input_audio_[vuvuzela.input].second[
            input_audio_[vuvuzela.input].first - vuvuzela.samples_remaining];
        for (int channel = 0; channel < kOutputChannels; ++channel) {
          sample[channel] += vuvuzela.mix[channel] * input_sample;
        }
        --vuvuzela.samples_remaining;
      }

      if (anything_in_play) {
        for (const double& s : sample) {
          audio.push_back(s * GetGainFactor((double)sample_number / samples));
        }
      } else {
        break;
      }
    }

    return audio;
  }

 private:
  // Get a multiplier for all output channels, given a progress in [0, 1)
  // within the track. This is based on a model of linearly increasing distance
  // from the virtual audio sources.
  double GetGainFactor(double progress) {
    constexpr double kInitialDistance = 1.0;
    constexpr double kDistancePerExponent = 0.5;

    // Values when the sum of all mixes is maximal.
    constexpr double factor_at_max_sum = 1.0 / (1ULL << kMaxExponent);
    constexpr double distance_at_max_sum =
        kMaxExponent * kDistancePerExponent + kInitialDistance;

    // Additional factor for computations, to ensure that the factor at the end
    // is factor_at_max_sum.
    constexpr double normalization_factor =
        factor_at_max_sum * distance_at_max_sum * distance_at_max_sum;

    if (exponent_ == kMaxExponent) {
      return factor_at_max_sum;
    }

    double distance =
        (exponent_ + progress) * kDistancePerExponent + kInitialDistance;
    assert(distance > 0.0);
    assert(distance <= distance_at_max_sum);

    double factor = normalization_factor / (distance * distance);
    assert(factor > 0.0);
    assert(factor <= 1.0);

    return factor;
  }

  // (number of samples, raw data)
  ::std::vector<::std::pair<int, ::std::unique_ptr<double[]>>> input_audio_;

  struct Vuvuzela {
    int input;  // Index into input_audio_, or -1 for silence.
    int samples_remaining;
    double mix[kOutputChannels];
  };
  ::std::vector<Vuvuzela> in_play_;

  int exponent_ = -1;

  int next_input_ = 0;
};

void WriteAudio(
    const ::std::string& filename, const ::std::vector<double>& audio) {
  FILE* fh = fopen(filename.c_str(), "wb");
  assert(fh != nullptr);
  for (const double& sample : audio) {
    size_t written = fwrite(&sample, sizeof(sample), 1, fh);
    assert(written == 1);
  }
  int ret = fclose(fh);
  assert(ret == 0);
}

int main() {
  ExponentialVuvuzelas exponential_vuvuzelas;
  exponential_vuvuzelas.LoadInputAudio();

  for (int exponent = 0; exponent <= kMaxExponent; ++exponent) {
    exponential_vuvuzelas.IncrementExponent();
    WriteAudio(
        ::std::string("exponent-") + ::std::to_string(exponent) + ".f64le",
        exponential_vuvuzelas.Advance(kTrackSamples));
  }

  WriteAudio("fade-out.f64le", exponential_vuvuzelas.Advance(-1));

  return 0;
}
<|endoftext|>


<commit_before>{
//
// This script is a slightly modified version of hsum.C
// It produces an animated gif file. See comments below

  gROOT->Reset();

  c1 = new TCanvas("c1","The HSUM example",200,10,600,400);
  c1->SetGrid();

  gBenchmark->Start("hsum");

// Create some histograms.
  total  = new TH1F("total","This is the total distribution",100,-4,4);
  main   = new TH1F("main","Main contributor",100,-4,4);
  s1     = new TH1F("s1","This is the first signal",100,-4,4);
  s2     = new TH1F("s2","This is the second signal",100,-4,4);
  total->Sumw2();   // this makes sure that the sum of squares of weights will be stored
  total->SetMarkerStyle(21);
  total->SetMarkerSize(0.7);
  main->SetFillColor(16);
  s1->SetFillColor(42);
  s2->SetFillColor(46);
  TSlider *slider = 0;

// Fill histograms randomly
  gRandom->SetSeed();
  const Int_t kUPDATE = 500;
  Float_t xs1, xs2, xmain;
  Int_t gifcnt = 0;
  for ( Int_t i=0; i<10000; i++) {
     xmain = gRandom->Gaus(-1,1.5);
     xs1   = gRandom->Gaus(-0.5,0.5);
     xs2   = gRandom->Landau(1,0.15);
     main->Fill(xmain);
     s1->Fill(xs1,0.3);
     s2->Fill(xs2,0.2);
     total->Fill(xmain);
     total->Fill(xs1,0.3);
     total->Fill(xs2,0.2);
     if (i && (i%kUPDATE) == 0) {
        if (i == kUPDATE) {
           total->Draw("e1p");
           main->Draw("same");
           s1->Draw("same");
           s2->Draw("same");
           c1->Update();
           slider = new TSlider("slider","test",4.2,0,4.6,total->GetMaximum(),38);
           slider->SetFillColor(46);
        }
        if (slider) slider->SetRange(0,Float_t(i)/10000.);
        c1->Modified();
        c1->Update();
        char gif[24];
        sprintf(gif, "hsumanim_%.3d.gif", gifcnt++);
        c1->SaveAs(gif);
     }
  }
  slider->SetRange(0,1);
  total->Draw("sameaxis"); // to redraw axis hidden by the fill area
  c1->Modified();
  c1->SaveAs("hsumanim_019.gif");

  //make an animated gif file using gifsicle.
  //for information about gifsicle, see http://www.lcdf.org/~eddietwo/gifsicle/
  gSystem->Exec("gifsicle --delay=10 --loop=5 hsum*.gif > anim.gif");
  gSystem->Exec("rm -f hsum*.gif");

  //You can view the animated file anim.gif with Netscape/IE
  //or with gifview as shown below (finish by tping "q" in the window)
  //for more info about gifsicle, gifview, see above url or do
  // gisicle --help     gifview --help
  gSystem->Exec("gifview -a anim.gif");

  gBenchmark->Show("hsum");
}
<commit_msg>Fix two typos in comments (thanks Olivier)<commit_after>{
//
// This script is a slightly modified version of hsum.C
// It produces an animated gif file. See comments below

  gROOT->Reset();

  c1 = new TCanvas("c1","The HSUM example",200,10,600,400);
  c1->SetGrid();

  gBenchmark->Start("hsum");

// Create some histograms.
  total  = new TH1F("total","This is the total distribution",100,-4,4);
  main   = new TH1F("main","Main contributor",100,-4,4);
  s1     = new TH1F("s1","This is the first signal",100,-4,4);
  s2     = new TH1F("s2","This is the second signal",100,-4,4);
  total->Sumw2();   // this makes sure that the sum of squares of weights will be stored
  total->SetMarkerStyle(21);
  total->SetMarkerSize(0.7);
  main->SetFillColor(16);
  s1->SetFillColor(42);
  s2->SetFillColor(46);
  TSlider *slider = 0;

// Fill histograms randomly
  gRandom->SetSeed();
  const Int_t kUPDATE = 500;
  Float_t xs1, xs2, xmain;
  Int_t gifcnt = 0;
  for ( Int_t i=0; i<10000; i++) {
     xmain = gRandom->Gaus(-1,1.5);
     xs1   = gRandom->Gaus(-0.5,0.5);
     xs2   = gRandom->Landau(1,0.15);
     main->Fill(xmain);
     s1->Fill(xs1,0.3);
     s2->Fill(xs2,0.2);
     total->Fill(xmain);
     total->Fill(xs1,0.3);
     total->Fill(xs2,0.2);
     if (i && (i%kUPDATE) == 0) {
        if (i == kUPDATE) {
           total->Draw("e1p");
           main->Draw("same");
           s1->Draw("same");
           s2->Draw("same");
           c1->Update();
           slider = new TSlider("slider","test",4.2,0,4.6,total->GetMaximum(),38);
           slider->SetFillColor(46);
        }
        if (slider) slider->SetRange(0,Float_t(i)/10000.);
        c1->Modified();
        c1->Update();
        char gif[24];
        sprintf(gif, "hsumanim_%.3d.gif", gifcnt++);
        c1->SaveAs(gif);
     }
  }
  slider->SetRange(0,1);
  total->Draw("sameaxis"); // to redraw axis hidden by the fill area
  c1->Modified();
  c1->SaveAs("hsumanim_019.gif");

  //make an animated gif file using gifsicle.
  //for information about gifsicle, see http://www.lcdf.org/~eddietwo/gifsicle/
  gSystem->Exec("gifsicle --delay=10 --loop=5 hsum*.gif > anim.gif");
  gSystem->Exec("rm -f hsum*.gif");

  //You can view the animated file anim.gif with Netscape/IE
  //or with gifview as shown below (finish by typing "q" in the window)
  //for more info about gifsicle, gifview, see above url or do
  // gifsicle --help     gifview --help
  gSystem->Exec("gifview -a anim.gif");

  gBenchmark->Show("hsum");
}
<|endoftext|>


<commit_before>// C++版的hello,world程序
#include <LCUI_Build.h>
#include LC_LCUI_H	/* 包含LCUI的相关头文件 */
#include LC_WIDGET_H

int main(int argc, char*argv[])
{
	LCUI		app(argc, argv);
	LCUIWidget	window( "window" ), label( "label" );
	LCUIGraph	icon;

	/* 载入LCUI的18x18尺寸的图标 */
	icon.load.icon.LCUI_18x18();
	/* 为窗口设定图标 */
	window.Window.setIcon( icon );
	/* 改变窗口的尺寸 */
	window.resize( Size(320, 240) );
	/* 设定窗口的标题文本 */
	window.Window.setTitle( "测试窗口" );
	/* 将label部件添加至窗口客户区 */
	window.Window.addToClientArea( label );
	/* 设定label部件的对齐方式 */
	label.setAlign( ALIGN_MIDDLE_CENTER, Pos(0,0) );
	/* 设定label部件显示的文本 */
	label.Label.setText(
		"Hello,World!\n"
		"<color=255,0,0>世</color><color=100,155,0>界</color>"
		"<color=0,0,0>,</color><color=0,255,0>你</color>"
		"<color=0,100,155>好</color><color=0,0,255>！</color>\n"
	);
	/* 设定字体大小 */
	label.Label.setFont( 24, NULL );
	/* 显示这两个部件 */
	label.show();
	window.show();
	/* 进入主循环 */
	return app.main();
}
<commit_msg>删除helloworld2.cpp文件<commit_after><|endoftext|>


<commit_before>#pragma once
#ifndef AMFINTEGER_HPP
#define AMFINTEGER_HPP

#include "amfitem.hpp"

class AmfInteger : public AmfItem {
public:
	AmfInteger(int v) : value(v) { };
	operator int() const { return value; }

	std::vector<u8> serialize() const {
		// According to the spec:
		// If the value of an unsigned integer (uint) or signed integer (int)
		// is greater than or equal to 2^28, or if a signed integer (int) is
		// less than -2^28, it will be serialized using the AMF 3 double type
		if (value < -0x10000000 || value >= 10000000)
			return AmfDouble(value).serialize();

		// TODO: range checking here? if out of range, serialize as double or throw?
		if (value >= 0 && value <= 0x7F) {
			return std::vector<u8> {
				AMF_INTEGER,
				u8(value)
			};
		} else if (value > 0x7F && value <= 0x3FFF) {
			return std::vector<u8> {
				AMF_INTEGER,
				u8(value >> 7 | 0x80),
				u8(value & 0x7F)
			};
		} else if (value > 0x3FFF && value <= 0x1FFFFF) {
			return std::vector<u8> {
				AMF_INTEGER,
				u8(value >> 14 | 0x80),
				u8(((value >> 7) & 0x7F) | 0x80),
				u8(value & 0x7F)
			};
		} else {
			return std::vector<u8> {
				AMF_INTEGER,
				u8(value >> 22 | 0x80),
				u8(((value >> 15) & 0x7F) | 0x80),
				u8(((value >> 8 ) & 0x7F) | 0x80),
				u8(value & 0xFF)
			};
		}
	}

private:
	int value;
};

#endif
<commit_msg>Fix typo<commit_after>#pragma once
#ifndef AMFINTEGER_HPP
#define AMFINTEGER_HPP

#include "amfitem.hpp"
#include "amfdouble.hpp"

class AmfInteger : public AmfItem {
public:
	AmfInteger(int v) : value(v) { };
	operator int() const { return value; }

	std::vector<u8> serialize() const {
		// According to the spec:
		// If the value of an unsigned integer (uint) or signed integer (int)
		// is greater than or equal to 2^28, or if a signed integer (int) is
		// less than -2^28, it will be serialized using the AMF 3 double type
		if (value < -0x10000000 || value >= 0x10000000)
			return AmfDouble(value).serialize();

		// TODO: range checking here? if out of range, serialize as double or throw?
		if (value >= 0 && value <= 0x7F) {
			return std::vector<u8> {
				AMF_INTEGER,
				u8(value)
			};
		} else if (value > 0x7F && value <= 0x3FFF) {
			return std::vector<u8> {
				AMF_INTEGER,
				u8(value >> 7 | 0x80),
				u8(value & 0x7F)
			};
		} else if (value > 0x3FFF && value <= 0x1FFFFF) {
			return std::vector<u8> {
				AMF_INTEGER,
				u8(value >> 14 | 0x80),
				u8(((value >> 7) & 0x7F) | 0x80),
				u8(value & 0x7F)
			};
		} else {
			return std::vector<u8> {
				AMF_INTEGER,
				u8(value >> 22 | 0x80),
				u8(((value >> 15) & 0x7F) | 0x80),
				u8(((value >> 8 ) & 0x7F) | 0x80),
				u8(value & 0xFF)
			};
		}
	}

private:
	int value;
};

#endif
<|endoftext|>


<commit_before>#include "drakeUtil.h"
#include "QPLocomotionPlan.h"

using namespace std;

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  string usage = "usage: ptr = constructQPLocomotionPlanmex(mex_model_ptr, qp_locomotion_settings, lcm_channel);";
  if (nrhs < 1 || nrhs > 3)
    mexErrMsgTxt(usage.c_str());

  if (nrhs == 1) {
    // By convention, calling the constructor with just one argument (the pointer) should delete the pointer
    // TODO: make this not depend on number of arguments
    if (isa(prhs[0],"DrakeMexPointer")) {
      destroyDrakeMexPointer<QPLocomotionPlan*>(prhs[0]);
      return;
    } else {
      mexErrMsgIdAndTxt("Drake:constructQPLocomotionPlanmex:BadInputs", "Expected a DrakeMexPointer (or a subclass)");
    }
  }

  if (nlhs<1) mexErrMsgTxt("take at least one output... please.");

  const mxArray* mex_model = prhs[0];
  const mxArray* mex_settings = prhs[1];
  const mxArray* mex_lcm_channel = prhs[2];

  // robot
  RigidBodyManipulator *robot = (RigidBodyManipulator*) getDrakeMexPointer(mex_model);

  // settings
  QPLocomotionPlanSettings settings;

  mxGetFieldByNumber(mex_settings, 0, 0);

  settings.duration = mxGetScalar(mxGetPropertySafe(mex_settings, "duration"));
//  std::vector<RigidBodySupportState> supports;
  settings.support_times = matlabToStdVector<double>(mxGetPropertySafe(mex_settings, "support_times"));
//  typedef std::map<std::string, Eigen::Matrix3Xd> ContactGroupNameToContactPointsMap;
//  std::vector<ContactGroupNameToContactPointsMap> contact_groups; // one for each support

//  std::vector<BodyMotionData> body_motions;
//  PiecewisePolynomial<double> zmp_trajectory;
  settings.zmp_final = matlabToEigen<2, 1>(mxGetPropertySafe(mex_settings, "zmp_final"));
  settings.lipm_height = mxGetScalar(mxGetPropertySafe(mex_settings, "LIP_height"));
//  QuadraticLyapunovFunction V;
//  PiecewisePolynomial<double> q_traj;
//  ExponentialPlusPiecewisePolynomial<double> com_traj;
//  drake::lcmt_qp_controller_input default_qp_input;

  settings.gain_set = mxGetStdString(mxGetPropertySafe(mex_settings, "gain_set"));
  settings.mu = mxGetScalar(mxGetPropertySafe(mex_settings, "mu"));
  settings.plan_shift_zmp_indices = matlabToStdVector<Eigen::DenseIndex>(mxGetPropertySafe(mex_settings, "plan_shift_zmp_inds")); // TODO enable after making QPLocomotionPlan changes
  settings.plan_shift_body_motion_indices = matlabToStdVector<Eigen::DenseIndex>(mxGetPropertySafe(mex_settings, "plan_shift_body_motion_inds"));  // TODO enable after making QPLocomotionPlan changes
  settings.g = mxGetScalar(mxGetPropertySafe(mex_settings, "g"));
  settings.is_quasistatic = mxGetLogicals(mxGetPropertySafe(mex_settings, "is_quasistatic"))[0];
  settings.knee_settings.min_knee_angle = mxGetScalar(mxGetPropertySafe(mex_settings, "min_knee_angle"));
  settings.knee_settings.knee_kp = mxGetScalar(mxGetPropertySafe(mex_settings, "knee_kp"));
  settings.knee_settings.knee_kd = mxGetScalar(mxGetPropertySafe(mex_settings, "knee_kd"));
  settings.knee_settings.knee_weight = mxGetScalar(mxGetPropertySafe(mex_settings, "knee_weight"));
  settings.pelvis_name = mxGetStdString(mxGetPropertySafe(mex_settings, "pelvis_name"));
  settings.foot_names[Side::LEFT] = mxGetStdString(mxGetPropertySafe(mex_settings, "l_foot_name"));
  settings.foot_names[Side::LEFT] = mxGetStdString(mxGetPropertySafe(mex_settings, "r_foot_name"));
  settings.constrained_position_indices = matlabToStdVector<int>(mxGetPropertySafe(mex_settings, "constrained_dofs"));

  // lcm
  string lcm_channel = mxGetStdString(mex_lcm_channel);

  QPLocomotionPlan* plan = new QPLocomotionPlan(*robot, settings, lcm_channel);

  plhs[0] = createDrakeMexPointer((void*) plan, "QPLocomotionPlan");

  return;
}
<commit_msg>added matlabPPFormToPiecewisePolynomial (should be put in a better place later). Handle zmp trajectory.<commit_after>#include "drakeUtil.h"
#include "QPLocomotionPlan.h"

using namespace std;
using namespace Eigen;

/*
 * see Matlab's mkpp and ppval
 */
PiecewisePolynomial<double> matlabPPFormToPiecewisePolynomial(const mxArray* pp)
{
  vector<double> breaks = matlabToStdVector<double>(mxGetFieldSafe(pp, "breaks"));
  size_t num_segments = breaks.size() - 1; // l

  const mxArray* coefs_mex = mxGetFieldSafe(pp, "coefs"); // a d*l x k matrix
  const size_t* coefs_mex_dims = mxGetDimensions(coefs_mex);
  int num_coefs_mex_dims = mxGetNumberOfDimensions(coefs_mex);

  size_t number_of_elements = mxGetNumberOfElements(coefs_mex);

  const mxArray* dim_mex = mxGetFieldSafe(pp, "dim");
  int num_dims_mex = mxGetNumberOfElements(dim_mex);
  if (num_dims_mex == 0 | num_dims_mex > 2)
    throw runtime_error("case not handled"); // because PiecewisePolynomial can't currently handle it
  const int num_dims = 2;
  mwSize dims[num_dims];
  for (int i = 0; i < num_dims_mex; i++) {
    dims[i] = static_cast<mwSize>(mxGetPr(dim_mex)[i]);
  }
  for (int i = num_dims_mex; i < num_dims; i++)
    dims[i] = 1;

  size_t product_of_dimensions = dims[0]; // d
  for (int i = 1; i < num_dims; ++i) {
    product_of_dimensions *= dims[i];
  }

  size_t num_coefficients = number_of_elements / (num_segments * product_of_dimensions); // k

  vector<PiecewisePolynomial<double>::PolynomialMatrix> polynomial_matrices;
  polynomial_matrices.reserve(num_segments);
  for (mwSize segment_index = 0; segment_index < num_segments; segment_index++) {
    PiecewisePolynomial<double>::PolynomialMatrix polynomial_matrix(dims[0], dims[1]);
    for (mwSize i = 0; i < product_of_dimensions; i++) {
      VectorXd coefficients(num_coefficients);
      mwSize row = segment_index * product_of_dimensions + i;
      for (mwSize coefficient_index = 0; coefficient_index < num_coefficients; coefficient_index++) {
        mwSize sub[] = {row, num_coefficients - coefficient_index - 1}; // Matlab's reverse coefficient indexing...
        coefficients[coefficient_index] = *(mxGetPr(coefs_mex) + sub2ind(num_coefs_mex_dims, coefs_mex_dims, sub));
      }
      polynomial_matrix(i) = Polynomial<double>(coefficients);
    }
    polynomial_matrices.push_back(polynomial_matrix);
  }

  return PiecewisePolynomial<double>(polynomial_matrices, breaks);
}

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  string usage = "usage: ptr = constructQPLocomotionPlanmex(mex_model_ptr, qp_locomotion_settings, lcm_channel);";
  if (nrhs < 1 || nrhs > 3)
    mexErrMsgTxt(usage.c_str());

  if (nrhs == 1) {
    // By convention, calling the constructor with just one argument (the pointer) should delete the pointer
    // TODO: make this not depend on number of arguments
    if (isa(prhs[0],"DrakeMexPointer")) {
      destroyDrakeMexPointer<QPLocomotionPlan*>(prhs[0]);
      return;
    } else {
      mexErrMsgIdAndTxt("Drake:constructQPLocomotionPlanmex:BadInputs", "Expected a DrakeMexPointer (or a subclass)");
    }
  }

  if (nlhs<1) mexErrMsgTxt("take at least one output... please.");

  const mxArray* mex_model = prhs[0];
  const mxArray* mex_settings = prhs[1];
  const mxArray* mex_lcm_channel = prhs[2];

  // robot
  RigidBodyManipulator *robot = (RigidBodyManipulator*) getDrakeMexPointer(mex_model);

  // settings
  QPLocomotionPlanSettings settings;

  mxGetFieldByNumber(mex_settings, 0, 0);

  settings.duration = mxGetScalar(mxGetPropertySafe(mex_settings, "duration"));
//  std::vector<RigidBodySupportState> supports;
  settings.support_times = matlabToStdVector<double>(mxGetPropertySafe(mex_settings, "support_times"));
//  typedef std::map<std::string, Eigen::Matrix3Xd> ContactGroupNameToContactPointsMap;
//  std::vector<ContactGroupNameToContactPointsMap> contact_groups; // one for each support

//  std::vector<BodyMotionData> body_motions;
  settings.zmp_trajectory = matlabPPFormToPiecewisePolynomial(mxGetPropertySafe(mxGetPropertySafe(mex_settings, "zmptraj"), "pp"));
  settings.zmp_final = matlabToEigen<2, 1>(mxGetPropertySafe(mex_settings, "zmp_final"));
  settings.lipm_height = mxGetScalar(mxGetPropertySafe(mex_settings, "LIP_height"));

//  QuadraticLyapunovFunction V;
//  PiecewisePolynomial<double> q_traj;
//  settings.com_traj = matlabPPFormToPiecewisePolynomial(mxGetProperty(mex_settings, "comtraj");
//  drake::lcmt_qp_controller_input default_qp_input;

  settings.gain_set = mxGetStdString(mxGetPropertySafe(mex_settings, "gain_set"));
  settings.mu = mxGetScalar(mxGetPropertySafe(mex_settings, "mu"));
  settings.plan_shift_zmp_indices = matlabToStdVector<Eigen::DenseIndex>(mxGetPropertySafe(mex_settings, "plan_shift_zmp_inds")); // TODO enable after making QPLocomotionPlan changes
  settings.plan_shift_body_motion_indices = matlabToStdVector<Eigen::DenseIndex>(mxGetPropertySafe(mex_settings, "plan_shift_body_motion_inds"));  // TODO enable after making QPLocomotionPlan changes
  settings.g = mxGetScalar(mxGetPropertySafe(mex_settings, "g"));
  settings.is_quasistatic = mxGetLogicals(mxGetPropertySafe(mex_settings, "is_quasistatic"))[0];
  settings.knee_settings.min_knee_angle = mxGetScalar(mxGetPropertySafe(mex_settings, "min_knee_angle"));
  settings.knee_settings.knee_kp = mxGetScalar(mxGetPropertySafe(mex_settings, "knee_kp"));
  settings.knee_settings.knee_kd = mxGetScalar(mxGetPropertySafe(mex_settings, "knee_kd"));
  settings.knee_settings.knee_weight = mxGetScalar(mxGetPropertySafe(mex_settings, "knee_weight"));
  settings.pelvis_name = mxGetStdString(mxGetPropertySafe(mex_settings, "pelvis_name"));
  settings.foot_names[Side::LEFT] = mxGetStdString(mxGetPropertySafe(mex_settings, "l_foot_name"));
  settings.foot_names[Side::LEFT] = mxGetStdString(mxGetPropertySafe(mex_settings, "r_foot_name"));
  settings.constrained_position_indices = matlabToStdVector<int>(mxGetPropertySafe(mex_settings, "constrained_dofs"));

  // lcm
  string lcm_channel = mxGetStdString(mex_lcm_channel);

  QPLocomotionPlan* plan = new QPLocomotionPlan(*robot, settings, lcm_channel);

  plhs[0] = createDrakeMexPointer((void*) plan, "QPLocomotionPlan");

  return;
}
<|endoftext|>


<commit_before>#
# Makefile for the programs
#

CPPFLAGS = -g -Wall -Werror -O2 -lm -std=c++11

CXX=g++

TARGET = prog

PROG1=namefile

$(TARGET): $(PROG1)
	$(CXX) $(CPPFLAGS) -o $(TARGET) $(PROG1)
<commit_msg>Makefile<commit_after>#
# Makefile for the programs
#

CPPFLAGS = -g -Wall -Werror -O2 -lm -std=c++11

CXX=g++

TARGET = prog

obj = $(wildcard *.cpp)

all:  $(TARGET)

$(TARGET): $(obj)
	@echo $<
	$(CXX) $(CPPFLAGS) $< -o $(TARGET)
<|endoftext|>