<commit_before>/*
 * Copyright (C) 2006-2009 Texas Instruments, Incorporated
 * Copyright (C) 2007-2009 Nokia Corporation.
 *
 * Author: <NAME> <<EMAIL>>
 *
 * 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
 * version 2.1 of the License.
 *
 * 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
 *
 */

#include <string.h>

#include "gstomx_util.h"
#include "gstomx_port.h"
#include "gstomx.h"

GST_DEBUG_CATEGORY_EXTERN (gstomx_util_debug);

#define CODEC_DATA_FLAG 0x00000080 /* special nFlags field to use to indicated codec-data */

static OMX_BUFFERHEADERTYPE * request_buffer (GOmxPort *port);
static void release_buffer (GOmxPort *port, OMX_BUFFERHEADERTYPE *omx_buffer);

#define DEBUG(port, fmt, args...) \
    GST_DEBUG ("<%s:%s> "fmt, GST_OBJECT_NAME ((port)->core->object), (port)->name, ##args)
#define LOG(port, fmt, args...) \
    GST_LOG ("<%s:%s> "fmt, GST_OBJECT_NAME ((port)->core->object), (port)->name, ##args)
#define WARNING(port, fmt, args...) \
    GST_WARNING ("<%s:%s> "fmt, GST_OBJECT_NAME ((port)->core->object), (port)->name, ##args)

/*
 * Port
 */

GOmxPort *
g_omx_port_new (GOmxCore *core, const gchar *name, guint index)
{
    GOmxPort *port = g_new0 (GOmxPort, 1);

    port->core = core;
    port->name = g_strdup_printf ("%s:%d", name, index);
    port->port_index = index;
    port->num_buffers = 0;
    port->buffers = NULL;

    port->enabled = TRUE;
    port->queue = async_queue_new ();
    port->mutex = g_mutex_new ();

    return port;
}

void
g_omx_port_free (GOmxPort *port)
{
    DEBUG (port, "begin");

    g_mutex_free (port->mutex);
    async_queue_free (port->queue);

    g_free (port->name);

    g_free (port->buffers);
    g_free (port);

    DEBUG (port, "end");
}

void
g_omx_port_setup (GOmxPort *port,
                  OMX_PARAM_PORTDEFINITIONTYPE *omx_port)
{
    GOmxPortType type = -1;

    switch (omx_port->eDir)
    {
        case OMX_DirInput:
            type = GOMX_PORT_INPUT;
            break;
        case OMX_DirOutput:
            type = GOMX_PORT_OUTPUT;
            break;
        default:
            break;
    }

    port->type = type;
    /** @todo should it be nBufferCountMin? */
    port->num_buffers = omx_port->nBufferCountActual;
    port->port_index = omx_port->nPortIndex;

    DEBUG (port, "type=%d, num_buffers=%d, port_index=%d",
        port->type, port->num_buffers, port->port_index);

    /* I don't think it is valid for buffers to be allocated at this point..
     * if there is a case where it is, then call g_omx_port_free_buffers()
     * here instead:
     */
    g_return_if_fail (!port->buffers);
}

static GstBuffer *
buffer_alloc (GOmxPort *port, gint len)
{
    GstBuffer *buf = NULL;

    if (port->buffer_alloc)
        buf = port->buffer_alloc (port, len);

    if (!buf)
        buf = gst_buffer_new_and_alloc (len);

    return buf;
}


void
g_omx_port_allocate_buffers (GOmxPort *port)
{
    OMX_PARAM_PORTDEFINITIONTYPE param;
    guint i;
    guint size;

    if (port->buffers)
        return;

    if (!port->enabled)
        return;

    DEBUG (port, "begin");

    G_OMX_PORT_GET_DEFINITION (port, &param);
    size = param.nBufferSize;

    port->buffers = g_new0 (OMX_BUFFERHEADERTYPE *, port->num_buffers);

    for (i = 0; i < port->num_buffers; i++)
    {

        if (port->omx_allocate)
        {
            DEBUG (port, "%d: OMX_AllocateBuffer(), size=%d", i, size);
            OMX_AllocateBuffer (port->core->omx_handle,
                                &port->buffers[i],
                                port->port_index,
                                NULL,
                                size);

            g_return_if_fail (port->buffers[i]);
        }
        else
        {
            GstBuffer *buf = NULL;
            gpointer buffer_data;
            if (port->share_buffer)
            {
                buf = buffer_alloc (port, size);
                buffer_data = GST_BUFFER_DATA (buf);

                if (i == 0)
                {
                    /* note: first buffer allocation may have triggered caps
                     * to be renegotiated to use row-stride.. which in turn
                     * changes the size of the requested buffer.  So let's
                     * check that, and if necessary start-over:
                     */
                    G_OMX_PORT_GET_DEFINITION (port, &param);

                    if (size != param.nBufferSize)
                    {
                        gst_buffer_unref (buf);
                        g_omx_port_allocate_buffers (port);
                        return;
                    }
                }
            }
            else
            {
                buffer_data = g_malloc (size);
            }

            DEBUG (port, "%d: OMX_UseBuffer(), size=%d, share_buffer=%d", i, size, port->share_buffer);
            OMX_UseBuffer (port->core->omx_handle,
                           &port->buffers[i],
                           port->port_index,<commit_msg>Fix for allocating buffers when the first buffer_alloc() triggers a change in caps<commit_after>/*
 * Copyright (C) 2006-2009 Texas Instruments, Incorporated
 * Copyright (C) 2007-2009 Nokia Corporation.
 *
 * Author: <NAME> <<EMAIL>>
 *
 * 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
 * version 2.1 of the License.
 *
 * 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
 *
 */

#include <string.h>

#include "gstomx_util.h"
#include "gstomx_port.h"
#include "gstomx.h"

GST_DEBUG_CATEGORY_EXTERN (gstomx_util_debug);

#define CODEC_DATA_FLAG 0x00000080 /* special nFlags field to use to indicated codec-data */

static OMX_BUFFERHEADERTYPE * request_buffer (GOmxPort *port);
static void release_buffer (GOmxPort *port, OMX_BUFFERHEADERTYPE *omx_buffer);

#define DEBUG(port, fmt, args...) \
    GST_DEBUG ("<%s:%s> "fmt, GST_OBJECT_NAME ((port)->core->object), (port)->name, ##args)
#define LOG(port, fmt, args...) \
    GST_LOG ("<%s:%s> "fmt, GST_OBJECT_NAME ((port)->core->object), (port)->name, ##args)
#define WARNING(port, fmt, args...) \
    GST_WARNING ("<%s:%s> "fmt, GST_OBJECT_NAME ((port)->core->object), (port)->name, ##args)

/*
 * Port
 */

GOmxPort *
g_omx_port_new (GOmxCore *core, const gchar *name, guint index)
{
    GOmxPort *port = g_new0 (GOmxPort, 1);

    port->core = core;
    port->name = g_strdup_printf ("%s:%d", name, index);
    port->port_index = index;
    port->num_buffers = 0;
    port->buffers = NULL;

    port->enabled = TRUE;
    port->queue = async_queue_new ();
    port->mutex = g_mutex_new ();

    return port;
}

void
g_omx_port_free (GOmxPort *port)
{
    DEBUG (port, "begin");

    g_mutex_free (port->mutex);
    async_queue_free (port->queue);

    g_free (port->name);

    g_free (port->buffers);
    g_free (port);

    DEBUG (port, "end");
}

void
g_omx_port_setup (GOmxPort *port,
                  OMX_PARAM_PORTDEFINITIONTYPE *omx_port)
{
    GOmxPortType type = -1;

    switch (omx_port->eDir)
    {
        case OMX_DirInput:
            type = GOMX_PORT_INPUT;
            break;
        case OMX_DirOutput:
            type = GOMX_PORT_OUTPUT;
            break;
        default:
            break;
    }

    port->type = type;
    /** @todo should it be nBufferCountMin? */
    port->num_buffers = omx_port->nBufferCountActual;
    port->port_index = omx_port->nPortIndex;

    DEBUG (port, "type=%d, num_buffers=%d, port_index=%d",
        port->type, port->num_buffers, port->port_index);

    /* I don't think it is valid for buffers to be allocated at this point..
     * if there is a case where it is, then call g_omx_port_free_buffers()
     * here instead:
     */
    g_return_if_fail (!port->buffers);
}

static GstBuffer *
buffer_alloc (GOmxPort *port, gint len)
{
    GstBuffer *buf = NULL;

    if (port->buffer_alloc)
        buf = port->buffer_alloc (port, len);

    if (!buf)
        buf = gst_buffer_new_and_alloc (len);

    return buf;
}


void
g_omx_port_allocate_buffers (GOmxPort *port)
{
    OMX_PARAM_PORTDEFINITIONTYPE param;
    guint i;
    guint size;

    if (port->buffers)
        return;

    if (!port->enabled)
        return;

    DEBUG (port, "begin");

    G_OMX_PORT_GET_DEFINITION (port, &param);
    size = param.nBufferSize;

    port->buffers = g_new0 (OMX_BUFFERHEADERTYPE *, port->num_buffers);

    for (i = 0; i < port->num_buffers; i++)
    {

        if (port->omx_allocate)
        {
            DEBUG (port, "%d: OMX_AllocateBuffer(), size=%d", i, size);
            OMX_AllocateBuffer (port->core->omx_handle,
                                &port->buffers[i],
                                port->port_index,
                                NULL,
                                size);

            g_return_if_fail (port->buffers[i]);
        }
        else
        {
            GstBuffer *buf = NULL;
            gpointer buffer_data;
            if (port->share_buffer)
            {
                buf = buffer_alloc (port, size);
                buffer_data = GST_BUFFER_DATA (buf);

                if (i == 0)
                {
                    /* note: first buffer allocation may have triggered caps
                     * to be renegotiated to use row-stride.. which in turn
                     * changes the size of the requested buffer.  So let's
                     * check that, and if necessary start-over:
                     */
                    G_OMX_PORT_GET_DEFINITION (port, &param);

                    if (size != param.nBufferSize)
                    {
                        size = param.nBufferSize;
                        gst_buffer_unref (buf);
                        i -= 1;
                        continue;
                    }
                }
            }
            else
            {
                buffer_data = g_malloc (size);
            }

            DEBUG (port, "%d: OMX_UseBuffer(), size=%d, share_buffer=%d", i, size, port->share_buffer);
            OMX_UseBuffer (port->core->omx_handle,
                           &port->buffers[i],
                           port->port_index,
{'fraction_non_alphanumeric': 0.11282372972488575, 'fraction_numerical': 0.00815485258535711, 'mean_word_length': 2.0701513067400277, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 117, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2594152', 'n_tokens_mistral': 3665, 'n_tokens_neox': 3426, 'n_words': 949}