constexpr int kMaxPlane = 4;
tbm_surface_h CreateTbmSurfaceWithBuffer(GstBuffer* buffer, GstCaps* caps) {
- int width = 0;
- int height = 0;
- uint32_t bo_format = 0;
- const gchar* string_format = nullptr;
- GstStructure* structure = nullptr;
- GstMapInfo mapinfo = GST_MAP_INFO_INIT;
-
+ bool is_error = false;
TRACKRENDERER_ENTER;
+
+ if (!buffer) {
+ TRACKRENDERER_ERROR("invalid buffer");
+ return nullptr;
+ }
+
if (!caps) {
TRACKRENDERER_ERROR("invalid caps");
return nullptr;
}
GstMemory* mem = gst_buffer_peek_memory(buffer, 0);
- bool is_mapped = gst_memory_map(mem, &mapinfo, GST_MAP_READWRITE);
- if (!is_mapped) {
+ GstMapInfo mapinfo = GST_MAP_INFO_INIT;
+ if (!gst_memory_map(mem, &mapinfo, GST_MAP_READWRITE)) {
TRACKRENDERER_ERROR("gst_memory_map fail");
return nullptr;
}
gst_memory_unmap(mem, &mapinfo);
}
BOOST_SCOPE_EXIT_END
- if (!mapinfo.data) {
- TRACKRENDERER_ERROR("data pointer is wrong");
- return nullptr;
- }
-
- structure = gst_caps_get_structure(caps, 0);
- gst_structure_get_int(structure, "width", &width);
- gst_structure_get_int(structure, "height", &height);
- string_format = gst_structure_get_string(structure, "format");
- bo_format = internal::ConvertToTbmFormat(string_format);
+ GstStructure* structure = gst_caps_get_structure(caps, 0);
+ const gchar* string_format = gst_structure_get_string(structure, "format");
+ uint32_t bo_format = internal::ConvertToTbmFormat(string_format);
if (!bo_format) {
TRACKRENDERER_ERROR("not supported video format");
return nullptr;
}
+ int width = 0;
+ int height = 0;
+ gst_structure_get_int(structure, "width", &width);
+ gst_structure_get_int(structure, "height", &height);
+
tbm_surface_h tbm_surf =
tbm_surface_create(width, height, bo_format);
if (!tbm_surf) {
- TRACKRENDERER_ERROR("fail to create tbm surface");
+ TRACKRENDERER_ERROR("tbm_surface_create fail");
return nullptr;
}
+ BOOST_SCOPE_EXIT(&tbm_surf, &is_error) {
+ if (is_error)
+ tbm_surface_destroy(tbm_surf);
+ }
+ BOOST_SCOPE_EXIT_END
tbm_surface_info_s info;
- int ret = tbm_surface_get_info(tbm_surf, &info);
- if (ret != TBM_SURFACE_ERROR_NONE) {
- TRACKRENDERER_ERROR("fail to get tbm surface info");
- tbm_surface_destroy(tbm_surf);
+ if (tbm_surface_get_info(tbm_surf, &info) != TBM_SURFACE_ERROR_NONE) {
+ TRACKRENDERER_ERROR("tbm_surface_get_info fail");
+ is_error = true;
return nullptr;
}
uint32_t bo_size = tbm_bo_size(bo);
tbm_bo_handle thandle = tbm_bo_map(bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
if (!thandle.ptr) {
- TRACKRENDERER_ERROR("thandle pointer is wrong");
- tbm_surface_destroy(tbm_surf);
+ TRACKRENDERER_ERROR("invalid thandle pointer");
+ is_error = true;
return nullptr;
}
BOOST_SCOPE_EXIT(&thandle, &bo) {
- if (thandle.ptr) {
tbm_bo_unmap(bo);
- }
}
BOOST_SCOPE_EXIT_END
- int plane_stride[kMaxPlane] = { 0, };
- int plane_elevation[kMaxPlane] = { 0, };
- int src_stride[kMaxPlane] = { 0, };
- int src_offset[kMaxPlane] = { 0, };
- int dest_offset[kMaxPlane] = { 0, };
- int i = 0;
- int j = 0;
- int k = 0;
- unsigned char *src = NULL;
- unsigned char *dest = NULL;
+ TRACKRENDERER_INFO("width %d, height %d, size %" G_GSIZE_FORMAT ", bo_size %d",
+ width, height, mapinfo.size, bo_size);
- TRACKRENDERER_INFO("width %d, height %d, size %" G_GSIZE_FORMAT ", bo_size %d", width, height, mapinfo.size, bo_size);
+ unsigned char* src = NULL;
+ unsigned char* dest = NULL;
switch(bo_format) {
case TBM_FORMAT_YUV420:
- plane_stride[0] = info.planes[0].stride;
- plane_elevation[0] = info.planes[0].size / info.planes[0].stride;
- plane_stride[1] = info.planes[1].stride;
- plane_elevation[1] = info.planes[1].size / info.planes[1].stride;
- plane_stride[2] = info.planes[2].stride;
- plane_elevation[2] = info.planes[2].size / info.planes[2].stride;
+ {
+ int src_stride[kMaxPlane] = { 0, };
+ int src_offset[kMaxPlane] = { 0, };
+ int dest_offset[kMaxPlane] = { 0, };
src_stride[0] = GST_ROUND_UP_4(width);
src_stride[1] = src_stride[2] = GST_ROUND_UP_4(width >> 1);
+
src_offset[1] = src_stride[0] * GST_ROUND_UP_2(height);
src_offset[2] = src_offset[1] + (src_stride[1] * (GST_ROUND_UP_2(height) >> 1));
- dest_offset[0] = 0;
- dest_offset[1] = plane_stride[0] * plane_elevation[0];
- dest_offset[2] = dest_offset[1] + plane_stride[1] * plane_elevation[1];
+ dest_offset[1] = info.planes[0].size;
+ dest_offset[2] = dest_offset[1] + info.planes[1].size;
+
+ for (int i = 0; i < 3; i++) {
+ int h = (i == 0) ? (height) : (height >> 1); // Y and UV plane have different h and w
+ int w = (i == 0) ? (width) : (width >> 1);
- for (i = 0; i < 3; i++) {
src = mapinfo.data + src_offset[i];
dest = (unsigned char*)(thandle.ptr) + dest_offset[i];
- if (i > 0)
- k = 1;
-
- for (j = 0; j < height >> k; j++) {
- memcpy(dest, src, width>>k);
+ for (int j = 0; j < h; j++) {
+ memcpy(dest, src, w);
src += src_stride[i];
- dest += plane_stride[i];
+ dest += info.planes[i].stride;
}
}
break;
+ }
case TBM_FORMAT_BGRA8888:
case TBM_FORMAT_BGRX8888:
case TBM_FORMAT_ARGB8888:
int src_stride = (vmeta) ? (vmeta->stride[0]) : (width * 4);
int dest_stride = info.planes[0].stride;
- for (i = 0; i < height; i++) {
+ for (int i = 0; i < height; i++) {
dest = (unsigned char*)(thandle.ptr) + (i * dest_stride);
src = mapinfo.data + (i * src_stride);
memcpy(dest, src, width * 4);
}
+ break;
}
- break;
default:
TRACKRENDERER_ERROR("not supported format");
- tbm_surface_destroy(tbm_surf);
+ is_error = true;
return nullptr;
}