| /* |
| * 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(¶ms, 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; |
| GST_DEBUG_OBJECT(vpu_internal_mem, "sub block %d type: %s size: %d", i, \ |
| (vpu_internal_mem->mem_info.MemSubBlock[i].MemType == VPU_MEM_VIRT) ? \ |
| "virtual" : "phys", size); |
| |
| 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, ¶ms); |
| 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_COMP_DATA (&frame, 0); |
| vpu_frame->pbufVirtCb = GST_VIDEO_FRAME_COMP_DATA (&frame, 1); |
| vpu_frame->pbufVirtCr = GST_VIDEO_FRAME_COMP_DATA (&frame, 2); |
| |
| gst_video_frame_unmap (&frame); |
| } |
| |
| return TRUE; |
| } |
| |