blob: c2454bc1c5675b9c9a59ace4e739527b570c16b4 [file] [log] [blame]
/*
* Copyright (c) 2013-2015, Freescale Semiconductor, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "gstvpuenc.h"
#include <gst/allocators/gstphysmemory.h>
#include "gstimxcommon.h"
gint
gst_vpu_find_std (GstCaps * caps)
{
VPUMapper *mapper = vpu_mappers;
while (mapper->mime) {
GstCaps *scaps = gst_caps_from_string (mapper->mime);
if (scaps) {
if (gst_caps_is_subset (caps, scaps)) {
gst_caps_unref (scaps);
return mapper->std;
}
gst_caps_unref (scaps);
}
mapper++;
}
return -1;
}
gboolean
gst_vpu_free_internal_mem (VpuInternalMem * vpu_internal_mem)
{
g_list_foreach (vpu_internal_mem->internal_virt_mem, (GFunc) g_free, NULL);
g_list_free (vpu_internal_mem->internal_virt_mem);
vpu_internal_mem->internal_virt_mem = NULL;
g_list_foreach (vpu_internal_mem->internal_phy_mem, (GFunc) gst_memory_unref, NULL);
g_list_free (vpu_internal_mem->internal_phy_mem);
vpu_internal_mem->internal_phy_mem = NULL;
return TRUE;
}
gboolean
gst_vpu_allocate_internal_mem (VpuInternalMem * vpu_internal_mem)
{
GstAllocationParams params;
GstMemory * gst_memory;
PhyMemBlock *memory;
gint size;
guint8 *ptr;
gint i;
memset(&params, 0, sizeof(GstAllocationParams));
for (i = 0; i < vpu_internal_mem->mem_info.nSubBlockNum; ++i) {
size = vpu_internal_mem->mem_info.MemSubBlock[i].nAlignment \
+ vpu_internal_mem->mem_info.MemSubBlock[i].nSize;
if (vpu_internal_mem->mem_info.MemSubBlock[i].MemType == VPU_MEM_VIRT) {
ptr = g_malloc(size);
if (ptr == NULL) {
GST_ERROR ("Could not allocate memory");
return FALSE;
}
vpu_internal_mem->mem_info.MemSubBlock[i].pVirtAddr = (unsigned char*)ALIGN( \
ptr, vpu_internal_mem->mem_info.MemSubBlock[i].nAlignment);
vpu_internal_mem->internal_virt_mem = g_list_append (vpu_internal_mem->internal_virt_mem, ptr);
} else if (vpu_internal_mem->mem_info.MemSubBlock[i].MemType == VPU_MEM_PHY) {
params.align = vpu_internal_mem->mem_info.MemSubBlock[i].nAlignment - 1;
gst_memory = gst_allocator_alloc (gst_vpu_allocator_obtain(), size, &params);
memory = gst_memory_query_phymem_block (gst_memory);
if (memory == NULL) {
GST_ERROR ("Could not allocate memory using VPU allocator");
return FALSE;
}
vpu_internal_mem->mem_info.MemSubBlock[i].pVirtAddr = memory->vaddr;
vpu_internal_mem->mem_info.MemSubBlock[i].pPhyAddr = memory->paddr;
vpu_internal_mem->internal_phy_mem = g_list_append (vpu_internal_mem->internal_phy_mem, gst_memory);
} else {
GST_WARNING ("sub block %d type is unknown - skipping", i);
}
}
return TRUE;
}
gboolean
gst_vpu_register_frame_buffer (GList * gstbuffer_in_vpudec, \
GstVideoInfo *info, VpuFrameBuffer * vpuframebuffers)
{
VpuFrameBuffer *vpu_frame;
GstVideoFrame frame;
PhyMemBlock * mem_block;
GstBuffer *buffer;
guint i;
for (i=0; i<g_list_length (gstbuffer_in_vpudec); i++) {
buffer = g_list_nth_data (gstbuffer_in_vpudec, i);
GST_DEBUG ("gstbuffer index: %d get from list: %x\n", \
i, buffer);
vpu_frame = &(vpuframebuffers[i]);
if (IS_HANTRO()) {
if (!gst_video_frame_map (&frame, info, buffer, GST_MAP_WRITE | GST_MAP_READ)) {
GST_ERROR ("Could not map video buffer");
return FALSE;
}
} else {
if (!gst_video_frame_map (&frame, info, buffer, GST_MAP_READ)) {
GST_ERROR ("Could not map video buffer");
return FALSE;
}
}
vpu_frame->nStrideY = GST_VIDEO_FRAME_COMP_STRIDE (&frame, 0);
vpu_frame->nStrideC = GST_VIDEO_FRAME_COMP_STRIDE (&frame, 1);
if (!(gst_buffer_is_phymem (buffer)
|| gst_is_phys_memory (gst_buffer_peek_memory (buffer, 0)))) {
GST_ERROR ("isn't physical memory allocator");
gst_video_frame_unmap (&frame);
return FALSE;
}
if (gst_is_phys_memory (gst_buffer_peek_memory (buffer, 0))) {
vpu_frame->pbufY = gst_phys_memory_get_phys_addr(gst_buffer_peek_memory (buffer, 0));
GST_DEBUG ("video buffer phys add: %p", vpu_frame->pbufY);
} else {
mem_block = gst_buffer_query_phymem_block (buffer);
vpu_frame->pbufY = mem_block->paddr;
GST_DEBUG ("video buffer phys add: %p", vpu_frame->pbufY);
}
vpu_frame->pbufCb = vpu_frame->pbufY + \
(GST_VIDEO_FRAME_COMP_DATA (&frame, 1) - GST_VIDEO_FRAME_COMP_DATA (&frame, 0));
vpu_frame->pbufCr = vpu_frame->pbufCb + \
(GST_VIDEO_FRAME_COMP_DATA (&frame, 2) - GST_VIDEO_FRAME_COMP_DATA (&frame, 1));
vpu_frame->pbufVirtY = GST_VIDEO_FRAME_PLANE_DATA (&frame, 0);
vpu_frame->pbufVirtCb = GST_VIDEO_FRAME_PLANE_DATA (&frame, 1);
vpu_frame->pbufVirtCr = GST_VIDEO_FRAME_PLANE_DATA (&frame, 2);
gst_video_frame_unmap (&frame);
}
return TRUE;
}