/*******************************************************************************
* Copyright (C) 2018 Cadence Design Systems, Inc.
* 
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to use this Software with Cadence processor cores only and 
* not with any other processors and platforms, subject to
* the following conditions:
* 
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

******************************************************************************/

/*******************************************************************************
 * xa-class-audio-codec.c
 *
 * Generic audio codec task implementation
 *
 ******************************************************************************/

#define MODULE_TAG                      CODEC

/*******************************************************************************
 * Includes
 ******************************************************************************/

#include "xf.h"
#include "xa-class-base.h"
#include "audio/xa-audio-decoder-api.h"

/*******************************************************************************
 * Tracing configuration
 ******************************************************************************/

TRACE_TAG(INIT, 1);
TRACE_TAG(WARNING, 1);
TRACE_TAG(INFO, 1);
TRACE_TAG(INPUT, 1);
TRACE_TAG(OUTPUT, 1);
TRACE_TAG(DECODE, 1);

/*******************************************************************************
 * Internal functions definitions
 ******************************************************************************/

typedef struct XAAudioCodec
{
    /***************************************************************************
     * Control data
     **************************************************************************/

    /* ...generic audio codec data */
    XACodecBase             base;

    /* ...input port data */
    xf_input_port_t         input;

    /* ...output port data */
    xf_output_port_t        output;

    /* ...input port index */
    WORD32                  in_idx;

    /* ...output port index */
    WORD32                  out_idx;

    /***************************************************************************
     * Run-time configuration parameters
     **************************************************************************/

    /* ...sample size in bytes */
    u32                     sample_size;

    /* ...audio sample duration */
    u32                     factor;

    /* ...total number of produced audio frames since last reset */
    u32                     produced;

}   XAAudioCodec;

/*******************************************************************************
 * Auxiliary codec execution flags
 ******************************************************************************/

/* ...input port setup condition */
#define XA_CODEC_FLAG_INPUT_SETUP       __XA_BASE_FLAG(1 << 0)

/* ...output port setup condition */
#define XA_CODEC_FLAG_OUTPUT_SETUP      __XA_BASE_FLAG(1 << 1)

/*******************************************************************************
 * Data processing scheduling
 ******************************************************************************/

/* ...prepare codec for steady operation (tbd - don't absolutely like it) */
static inline XA_ERRORCODE xa_codec_prepare_runtime(XAAudioCodec *codec)
{
    XACodecBase    *base = (XACodecBase *)codec;
    xf_message_t   *m = xf_msg_queue_head(&codec->output.queue);
    xf_start_msg_t *msg = m->buffer;
    u32             frame_size;
    u32             factor;

    /* ...fill-in buffer parameters */
    XA_API(base, XA_API_CMD_GET_CONFIG_PARAM, XA_CODEC_CONFIG_PARAM_SAMPLE_RATE, &msg->sample_rate);
    XA_API(base, XA_API_CMD_GET_CONFIG_PARAM, XA_CODEC_CONFIG_PARAM_CHANNELS, &msg->channels);
    XA_API(base, XA_API_CMD_GET_CONFIG_PARAM, XA_CODEC_CONFIG_PARAM_PCM_WIDTH, &msg->pcm_width);
    XA_API(base, XA_API_CMD_GET_MEM_INFO_SIZE, codec->in_idx, &msg->input_length);
    XA_API(base, XA_API_CMD_GET_MEM_INFO_SIZE, codec->out_idx, &msg->output_length);

    TRACE(INIT, _b("codec[%p]::runtime init: f=%u, c=%u, w=%u, i=%u, o=%u"), codec, msg->sample_rate, msg->channels, msg->pcm_width, msg->input_length, msg->output_length);

    /* ...reallocate input port buffer as needed - tbd */
    BUG(msg->input_length > codec->input.length, _x("Input buffer reallocation required: %u to %u"), codec->input.length, msg->input_length);

    /* ...save sample size in bytes */
    codec->sample_size = msg->channels * (msg->pcm_width == 16 ? 2 : 4);

    /* ...calculate frame duration; get number of samples in the frame (don't like division here - tbd) */
    frame_size = msg->output_length / codec->sample_size;

    /* ...it must be a multiple */
    XF_CHK_ERR(frame_size * codec->sample_size == msg->output_length, XA_API_FATAL_INVALID_CMD_TYPE);

    /* ...retrieve upsampling factor for given sample rate */
    XF_CHK_ERR(factor = xf_timebase_factor(msg->sample_rate), XA_API_FATAL_INVALID_CMD_TYPE);

    /* ...set frame duration factor (converts number of bytes into timebase units) */
    codec->factor = factor / codec->sample_size;

    TRACE(INIT, _b("ts-factor: %u (%u)"), codec->factor, factor);

    BUG(codec->factor * codec->sample_size != factor, _x("Freq mismatch: %u vs %u"), codec->factor * codec->sample_size, factor);

    /* ...pass response to caller (push out of output port) */
    xf_output_port_produce(&codec->output, sizeof(*msg));

    /* ...codec runtime initialization is completed */
    TRACE(INIT, _b("codec[%p] runtime initialized: i=%u, o=%u"), codec, msg->input_length, msg->output_length);

    return XA_NO_ERROR;
}

/*******************************************************************************
 * Commands processing
 ******************************************************************************/

/* ...EMPTY-THIS-BUFFER command processing */
static XA_ERRORCODE xa_codec_empty_this_buffer(XACodecBase *base, xf_message_t *m)
{
    XAAudioCodec   *codec = (XAAudioCodec *) base;

    /* ...make sure the port is valid */
    XF_CHK_ERR(XF_MSG_DST_PORT(m->id) == 0, XA_API_FATAL_INVALID_CMD);

    /* ...command is allowed only in post-init state */
    XF_CHK_ERR(base->state & XA_BASE_FLAG_POSTINIT, XA_API_FATAL_INVALID_CMD);

    /* ...put message into input queue */
    if (xf_input_port_put(&codec->input, m))
    {
        /* ...restart stream if it is in completed state */
        if (base->state & XA_BASE_FLAG_COMPLETED)
        {
            /* ...reset execution stage */
            base->state = XA_BASE_FLAG_POSTINIT | XA_BASE_FLAG_EXECUTION;

            /* ...reset execution runtime */
            XA_API(base, XA_API_CMD_EXECUTE, XA_CMD_TYPE_DO_RUNTIME_INIT, NULL);

            /* ...reset produced samples counter */
            codec->produced = 0;
        }

        /* ...codec must be in one of these states */
        XF_CHK_ERR(base->state & (XA_BASE_FLAG_RUNTIME_INIT | XA_BASE_FLAG_EXECUTION), XA_API_FATAL_INVALID_CMD);
        
        /* ...schedule data processing if output is ready */
        if (xf_output_port_ready(&codec->output))
        {
            xa_base_schedule(base, 0);
        }
    }

    TRACE(INPUT, _b("Received buffer [%p]:%u"), m->buffer, m->length);

    return XA_NO_ERROR;
}

/* ...FILL-THIS-BUFFER command processing */
static XA_ERRORCODE xa_codec_fill_this_buffer(XACodecBase *base, xf_message_t *m)
{
    XAAudioCodec   *codec = (XAAudioCodec *) base;

    /* ...make sure the port is valid */
    XF_CHK_ERR(XF_MSG_DST_PORT(m->id) == 1, XA_API_FATAL_INVALID_CMD);

    /* ...command is allowed only in postinit state */
    XF_CHK_ERR(base->state & XA_BASE_FLAG_POSTINIT, XA_API_FATAL_INVALID_CMD);

    /* ...special handling of zero-length buffer */
    if (base->state & XA_BASE_FLAG_RUNTIME_INIT)
    {
        /* ...message must be zero-length */
        BUG(m->length != 0, _x("Invalid message length: %u"), m->length);
    }
    else if (m == xf_output_port_control_msg(&codec->output))
    {
        /* ...end-of-stream processing indication received; check the state */
        BUG((base->state & XA_BASE_FLAG_COMPLETED) == 0, _x("invalid state: %x"), base->state);

        /* ... mark flushing sequence is done */
        xf_output_port_flush_done(&codec->output);

        /* ...complete pending zero-length input buffer */
        xf_input_port_purge(&codec->input);

        TRACE(INFO, _b("codec[%p] playback completed"), codec);

        /* ...playback is over */
        return XA_NO_ERROR;
    }
    else if ((base->state & XA_BASE_FLAG_COMPLETED) && !xf_output_port_routed(&codec->output))
    {
        /* ...return message arrived from application immediately */
        xf_response_ok(m);

        return XA_NO_ERROR;
    }
    else
    {
        TRACE(OUTPUT, _b("Received output buffer [%p]:%u"), m->buffer, m->length);

        /* ...adjust message length (may be shorter than original) */
        m->length = codec->output.length;
    }

    /* ...place message into output port */
    if (xf_output_port_put(&codec->output, m) && xf_input_port_ready(&codec->input))
    {
        /* ...schedule data processing instantly */
        if (base->state & (XA_BASE_FLAG_RUNTIME_INIT | XA_BASE_FLAG_EXECUTION))
        {
            xa_base_schedule(base, 0);
        }
    }

    return XA_NO_ERROR;
}

/* ...output port routing */
static XA_ERRORCODE xa_codec_port_route(XACodecBase *base, xf_message_t *m)
{
    XAAudioCodec           *codec = (XAAudioCodec *) base;
    xf_route_port_msg_t    *cmd = m->buffer;
    xf_output_port_t       *port = &codec->output;
    u32                     src = XF_MSG_DST(m->id);
    u32                     dst = cmd->dst;
    
    /* ...command is allowed only in "postinit" state */
    XF_CHK_ERR(base->state & XA_BASE_FLAG_POSTINIT, XA_API_FATAL_INVALID_CMD);

    /* ...make sure output port is addressed */
    XF_CHK_ERR(XF_MSG_DST_PORT(m->id) == 1, XA_API_FATAL_INVALID_CMD_TYPE);

    /* ...make sure port is not routed yet */
    XF_CHK_ERR(!xf_output_port_routed(port), XA_API_FATAL_INVALID_CMD_TYPE);

    /* ...route output port - allocate queue */
    XF_CHK_ERR(xf_output_port_route(port, __XF_MSG_ID(dst, src), cmd->alloc_number, cmd->alloc_size, cmd->alloc_align) == 0, XA_API_FATAL_MEM_ALLOC);

    /* ...schedule processing instantly */
    xa_base_schedule(base, 0);
    
    /* ...pass success result to caller */
    xf_response_ok(m);
    
    return XA_NO_ERROR;
}

/* ...port unroute command */
static XA_ERRORCODE xa_codec_port_unroute(XACodecBase *base, xf_message_t *m)
{
    XAAudioCodec           *codec = (XAAudioCodec *) base;
    
    /* ...command is allowed only in "postinit" state */
    XF_CHK_ERR(base->state & XA_BASE_FLAG_POSTINIT, XA_API_FATAL_INVALID_CMD);

    /* ...make sure output port is addressed */
    XF_CHK_ERR(XF_MSG_DST_PORT(m->id) == 1, XA_API_FATAL_INVALID_CMD_TYPE);

    /* ...cancel any pending processing */
    xa_base_cancel(base);

    /* ...clear output-port-setup condition */
    base->state &= ~XA_CODEC_FLAG_OUTPUT_SETUP;

    /* ...pass flush command down the graph */
    if (xf_output_port_flush(&codec->output, XF_FLUSH))
    {
        TRACE(INFO, _b("port is idle; instantly unroute"));

        /* ...flushing sequence is not needed; command may be satisfied instantly */
        xf_output_port_unroute(&codec->output);

        /* ...pass response to the proxy */
        xf_response_ok(m);
    }
    else
    {
        TRACE(INFO, _b("port is busy; propagate unroute command"));

        /* ...flushing sequence is started; save flow-control message */
        xf_output_port_unroute_start(&codec->output, m);
    }

    return XA_NO_ERROR;
}

/* ...FLUSH command processing */
static XA_ERRORCODE xa_codec_flush(XACodecBase *base, xf_message_t *m)
{
    XAAudioCodec   *codec = (XAAudioCodec *) base;

    /* ...command is allowed only in "postinit" state */
    XF_CHK_ERR(base->state & XA_BASE_FLAG_POSTINIT, XA_API_FATAL_INVALID_CMD);

    /* ...ensure input parameter length is zero */
    XF_CHK_ERR(m->length == 0, XA_API_FATAL_INVALID_CMD_TYPE);

    TRACE(1, _b("flush command received"));
    
    /* ...flush command must be addressed to input port */
    if (XF_MSG_DST_PORT(m->id) == 0)
    {
        /* ...cancel data processing message if needed */
        xa_base_cancel(base);

        /* ...input port flushing; purge content of input buffer */
        xf_input_port_purge(&codec->input);

        /* ...clear input-ready condition */
        base->state &= ~XA_CODEC_FLAG_INPUT_SETUP;

        /* ...reset execution runtime */
        XA_API(base, XA_API_CMD_EXECUTE, XA_CMD_TYPE_DO_RUNTIME_INIT, NULL);

        /* ...reset produced samples counter */
        codec->produced = 0;

        /* ...propagate flushing command to output port */
        if (xf_output_port_flush(&codec->output, XF_FLUSH))
        {
            /* ...flushing sequence is not needed; satisfy command instantly */
            xf_response(m);
        }
        else
        {
            /* ...flushing sequence is started; save flow-control message at input port */
            xf_input_port_control_save(&codec->input, m);
        }
    }
    else if (xf_output_port_unrouting(&codec->output))
    {
        /* ...flushing during port unrouting; complete unroute sequence */
        xf_output_port_unroute_done(&codec->output);

        TRACE(INFO, _b("port is unrouted"));
    }
    else
    {
        /* ...output port flush command/response; check if the port is routed */
        if (!xf_output_port_routed(&codec->output))
        {
            /* ...complete all queued messages */
            xf_output_port_flush(&codec->output, XF_FLUSH);

            /* ...and pass response to flushing command */
            xf_response(m);
        }
        else
        {            
            /* ...response to flushing command received */
            BUG(m != xf_output_port_control_msg(&codec->output), _x("invalid message: %p"), m);

            /* ...mark flushing sequence is completed */
            xf_output_port_flush_done(&codec->output);

            /* ...complete original flow-control command */
            xf_input_port_purge_done(&codec->input);
        }

        /* ...clear output-setup condition */
        base->state &= ~XA_CODEC_FLAG_OUTPUT_SETUP;
    }

    return XA_NO_ERROR;
}

/*******************************************************************************
 * Generic codec API
 ******************************************************************************/

/* ...memory buffer handling */
static XA_ERRORCODE xa_codec_memtab(XACodecBase *base, WORD32 idx, WORD32 type, WORD32 size, WORD32 align, u32 core)
{
    XAAudioCodec   *codec = (XAAudioCodec *) base;

    if (type == XA_MEMTYPE_INPUT)
    {
        /* ...input port specification; allocate internal buffer */
        XF_CHK_ERR(xf_input_port_init(&codec->input, size, align, core) == 0, XA_API_FATAL_MEM_ALLOC);

        /* ...save input port index */
        codec->in_idx = idx;

        /* ...set input buffer pointer as needed */
        (size ? XA_API(base, XA_API_CMD_SET_MEM_PTR, idx, codec->input.buffer) : 0);

        (size ? TRACE(1, _x("set input ptr: %p"), codec->input.buffer) : 0);
    }
    else
    {
        /* ...output buffer specification */
        XF_CHK_ERR(type == XA_MEMTYPE_OUTPUT, XA_API_FATAL_INVALID_CMD_TYPE);

        /* ...initialize output port queue (no allocation here yet) */
        XF_CHK_ERR(xf_output_port_init(&codec->output, size) == 0, XA_API_FATAL_MEM_ALLOC);

        /* ...save output port index */
        codec->out_idx = idx;
    }

    return XA_NO_ERROR;
}

/* ...prepare input/output buffers */
static XA_ERRORCODE xa_codec_preprocess(XACodecBase *base)
{
    XAAudioCodec   *codec = (XAAudioCodec *) base;

    /* ...prepare output buffer if needed */
    if (!(base->state & XA_CODEC_FLAG_OUTPUT_SETUP))
    {
        void   *output;

        /* ...get output buffer from port, if possible */
        if (base->state & XA_BASE_FLAG_RUNTIME_INIT)
        {
            /* ...run-time is not initialized yet; use scratch buffer */
            output = base->scratch;
        }
        else if ((output = xf_output_port_data(&codec->output)) == NULL)
        {
            /* ...no output buffer available */
            return XA_CODEC_EXEC_NO_DATA;
        }

        /* ...set the output buffer pointer */
        XA_API(base, XA_API_CMD_SET_MEM_PTR, codec->out_idx, output);

        TRACE(1, _x("set output ptr: %p"), output);
        
        /* ...mark output port is setup */
        base->state ^= XA_CODEC_FLAG_OUTPUT_SETUP;
    }

    /* ...prepare input data if needed */
    if (!(base->state & XA_CODEC_FLAG_INPUT_SETUP))
    {
        void   *input;
        u32     filled;

        /* ...fill input buffer */
        if (xf_input_port_bypass(&codec->input))
        {
            /* ...use input buffer directly; check if there is data available */
            if ((input = xf_input_port_data(&codec->input)) != NULL)
            {
                /* ...set input data buffer pointer */
                XA_API(base, XA_API_CMD_SET_MEM_PTR, codec->in_idx, input);

                /* ...retrieve number of input bytes */
                filled = xf_input_port_length(&codec->input);
            }
            else if (!xf_input_port_done(&codec->input))
            {
                /* ...return non-fatal indication to prevent further processing */
                return XA_CODEC_EXEC_NO_DATA;
            }
            else
            {
                /* ...mark we have no data in current buffer */
                filled = 0;
            }
        }
        else
        {
            /* ...port is in non-bypass mode; try to fill internal buffer */
            if (xf_input_port_done(&codec->input) || xf_input_port_fill(&codec->input))
            {
                /* ...retrieve number of bytes in input buffer (not really - tbd) */
                filled = xf_input_port_level(&codec->input);
            }
            else
            {
                /* ...return non-fatal indication to prevent further processing */
                return XA_CODEC_EXEC_NO_DATA;
            }
        }

        /* ...check if input stream is over */
        if (xf_input_port_done(&codec->input))
        {
            /* ...pass input-over command to the codec to indicate the final buffer */
            XA_API(base, XA_API_CMD_INPUT_OVER, codec->in_idx, NULL);

            TRACE(INFO, _b("codec[%p]: signal input-over (filled: %u)"), codec, filled);
        }

        TRACE(INPUT, _b("input-buffer fill-level: %u bytes"), filled);

        /* ...specify number of bytes available in the input buffer */
        XA_API(base, XA_API_CMD_SET_INPUT_BYTES, codec->in_idx, &filled);

        /* ...mark input port is setup */
        base->state ^= XA_CODEC_FLAG_INPUT_SETUP;
    }

    return XA_NO_ERROR;
}

/* ...post-processing operation; input/output ports maintenance */
static XA_ERRORCODE xa_codec_postprocess(XACodecBase *base, int done)
{
    XAAudioCodec   *codec = (XAAudioCodec *) base;
    WORD32          consumed = 0;
    WORD32          produced = 0;

    /* ...get number of consumed / produced bytes */
    XA_API(base, XA_API_CMD_GET_CURIDX_INPUT_BUF, codec->in_idx, &consumed);

    /* ...get number of produced bytes only if runtime is initialized (sample size is known) */
    (codec->sample_size ? XA_API(base, XA_API_CMD_GET_OUTPUT_BYTES, codec->out_idx, &produced) : 0);

    TRACE(DECODE, _b("codec[%p]::postprocess(c=%u, p=%u, d=%u)"), codec, consumed, produced, done);

    /* ...input buffer maintenance; check if we consumed anything */
    if (consumed)
    {
        /* ...consume specified number of bytes from input port */
        xf_input_port_consume(&codec->input, consumed);

        /* ...clear input-setup flag */
        base->state ^= XA_CODEC_FLAG_INPUT_SETUP;
    }

    /* ...output buffer maintenance; check if we have produced anything */
    if (produced)
    {
        /* ...increment total number of produced samples (really don't like division here - tbd) */
        codec->produced += produced / codec->sample_size;

        /* ...immediately complete output buffer (don't wait until it gets filled) */
        xf_output_port_produce(&codec->output, produced);

        /* ...clear output port setup flag */
        base->state ^= XA_CODEC_FLAG_OUTPUT_SETUP;
    }

    /* ...process execution stage transition */
    if (done)
    {
        if (base->state & XA_BASE_FLAG_RUNTIME_INIT)
        {
            /* ...stream is completed while codec is in runtime initialization stage */
            BUG(1, _x("breakpoint"));
        }
        else if (base->state & XA_BASE_FLAG_EXECUTION)
        {
            /* ...runtime initialization done */
            XA_CHK(xa_codec_prepare_runtime(codec));

            /* ...clear output port setup flag as we were using scratch buffer;
             * technically, no need to repeat setup of input buffer, but some codecs require
             * it as well
             */
            base->state &= ~(XA_CODEC_FLAG_INPUT_SETUP | XA_CODEC_FLAG_OUTPUT_SETUP);
        }
        else
        {
            /* ...output stream is over; propagate condition to sink port */
            if (xf_output_port_flush(&codec->output, XF_FILL_THIS_BUFFER))
            {
                /* ...flushing sequence is not needed; complete pending zero-length input */
                xf_input_port_purge(&codec->input);
                
                /* ...no propagation to output port */
                TRACE(INFO, _b("codec[%p] playback completed"), codec);
            }
            else
            {
                /* ...flushing sequence is started; wait until flow-control message returns */
                TRACE(INFO, _b("propagate end-of-stream condition"));
            }
        }

        /* ...return early to prevent task rescheduling */
        return XA_NO_ERROR;
    }

    /* ...reschedule processing if needed */
    if (xf_input_port_ready(&codec->input) && xf_output_port_ready(&codec->output))
    {
        /* ...schedule data processing with respect to its urgency */
        xa_base_schedule(base, produced * codec->factor);
    }

    return XA_NO_ERROR;
}

/* ...configuration parameter retrieval */
static XA_ERRORCODE xa_codec_getparam(XACodecBase *base, WORD32 id, pVOID value)
{
    XAAudioCodec   *codec = (XAAudioCodec *) base;

    if (id == XA_CODEC_CONFIG_PARAM_PRODUCED)
    {
        /* ...retrieve number of produced samples since last reset */
        *(u32 *)value = codec->produced;

        return XA_NO_ERROR;
    }
    else
    {
        /* ...pass command to underlying codec plugin */
        return XA_API(base, XA_API_CMD_GET_CONFIG_PARAM, id, value);
    }
}

/*******************************************************************************
 * Component entry point
 ******************************************************************************/

/* ...command hooks */
static XA_ERRORCODE (* const xa_codec_cmd[])(XACodecBase *, xf_message_t *) =
{
    [XF_OPCODE_TYPE(XF_SET_PARAM)] = xa_base_set_param,
    [XF_OPCODE_TYPE(XF_GET_PARAM)] = xa_base_get_param,
    [XF_OPCODE_TYPE(XF_ROUTE)] = xa_codec_port_route,
    [XF_OPCODE_TYPE(XF_UNROUTE)] = xa_codec_port_unroute,
    [XF_OPCODE_TYPE(XF_EMPTY_THIS_BUFFER)] = xa_codec_empty_this_buffer,
    [XF_OPCODE_TYPE(XF_FILL_THIS_BUFFER)] = xa_codec_fill_this_buffer,
    [XF_OPCODE_TYPE(XF_FLUSH)] = xa_codec_flush,
    [XF_OPCODE_TYPE(XF_SET_PARAM_EXT)] = xa_base_set_param_ext,
    [XF_OPCODE_TYPE(XF_GET_PARAM_EXT)] = xa_base_get_param_ext,
};

/* ...total number of commands supported */
#define XA_CODEC_CMD_NUM        (sizeof(xa_codec_cmd) / sizeof(xa_codec_cmd[0]))

/* ...command processor for termination state (only for routed port case) */
static int xa_audio_codec_terminate(xf_component_t *component, xf_message_t *m)
{
    XAAudioCodec   *codec = (XAAudioCodec *) component;
    u32             opcode = m->opcode;

    /* ...check if we received output port control message */
    if (m == xf_output_port_control_msg(&codec->output))
    {
        /* ...output port flushing complete; mark port is idle and terminate */
        xf_output_port_flush_done(&codec->output);
        return -1;
    }
    else if (opcode == XF_FILL_THIS_BUFFER)
    {
        /* ...output buffer returned by the sink component; ignore and keep waiting */
        TRACE(OUTPUT, _b("collect output buffer"));
        return 0;
    }
    else if (opcode == XF_UNREGISTER)
    {
        /* ...ignore subsequent unregister command/response - tbd */
        return 0;
    }
    else
    {
        /* ...everything else is responded with generic failure */
        xf_response_err(m);
        return 0;
    }
}

/* ...audio codec destructor */
static int xa_audio_codec_destroy(xf_component_t *component, xf_message_t *m)
{
    XAAudioCodec   *codec = (XAAudioCodec *) component;
    u32             core = xf_component_core(component);

    /* ...destroy input port */
    xf_input_port_destroy(&codec->input, core);

    /* ...destroy output port */
    xf_output_port_destroy(&codec->output, core);

    /* ...deallocate all resources */
    xa_base_destroy(&codec->base, XF_MM(sizeof(*codec)), core);

    TRACE(INIT, _b("audio-codec[%p@%u] destroyed"), codec, core);

    /* ...indicate the client has been destroyed */
    return 0;
}

/* ...audio codec destructor - first stage (ports unrouting) */
static int xa_audio_codec_cleanup(xf_component_t *component, xf_message_t *m)
{
    XAAudioCodec *codec = (XAAudioCodec *) component;

    /* ...complete message with error response */
    xf_response_err(m);

    /* ...cancel internal scheduling message if needed */
    xa_base_cancel(&codec->base);

    /* ...purge input port (returns OK? pretty strange at this point - tbd) */
    xf_input_port_purge(&codec->input);

    /* ...propagate unregister command to connected component */
    if (xf_output_port_flush(&codec->output, XF_FLUSH))
    {
        /* ...flushing sequence is not needed; destroy audio codec */
        return xa_audio_codec_destroy(component, NULL);
    }
    else
    {
        /* ...wait until output port is cleaned; adjust component hooks */
        component->entry = xa_audio_codec_terminate;
        component->exit = xa_audio_codec_destroy;

        TRACE(INIT, _b("codec[%p] cleanup sequence started"), codec);

        /* ...indicate that second stage is required */
        return 1;
    }
}

/*******************************************************************************
 * Audio codec component factory
 ******************************************************************************/

xf_component_t * xa_audio_codec_factory(u32 core, xa_codec_func_t process)
{
    XAAudioCodec   *codec;

    /* ...allocate local memory for codec structure */
    XF_CHK_ERR(codec = (XAAudioCodec *) xa_base_factory(core, XF_MM(sizeof(*codec)), process), NULL);

    /* ...set base codec API methods */
    codec->base.memtab = xa_codec_memtab;
    codec->base.preprocess = xa_codec_preprocess;
    codec->base.postprocess = xa_codec_postprocess;
    codec->base.getparam = xa_codec_getparam;

    /* ...set message commands processing table */
    codec->base.command = xa_codec_cmd;
    codec->base.command_num = XA_CODEC_CMD_NUM;

    /* ...set component destructor hook */
    codec->base.component.exit = xa_audio_codec_cleanup;

    TRACE(INIT, _b("Codec[%p] initialized"), codec);

    return (xf_component_t *) codec;
}
