I am trying to create a VaSurface with an external buffer attached for RGBA format. I am using follwing code to create surfaces and dumping into file. When I looked dumped rgba data , it is purely black ( used ffplay to verify this)
please look following code and provide feedback to resolve this issue.
Thanks for your help..
static VAStatus va_encoder_setup_external_rgba(va_enc_t *venc)
{
VAStatus vas = VA_STATUS_ERROR_UNKNOWN;
int surface_type = VA_RT_FORMAT_RGB32;
int fourcc_buffer_format = venc->fourcc_buffer_format;
int num_formats = vaMaxNumImageFormats(venc->display);
VAImageFormat *format_list = malloc(num_formats * sizeof(VAImageFormat));
vas = vaQueryImageFormats(venc->display, format_list, &num_formats);
if ( vas != VA_STATUS_SUCCESS) {
LOGE("Failed vaQueryImageFormats");
return vas;
}
for (int i = 0; i < num_formats; i++) {
if (format_list[i].fourcc == fourcc_buffer_format) {
LOGE("Found format");
venc->rgba_format = format_list[i];
break;
}
}
if( (venc->va_external_sid = calloc(1, sizeof(VASurfaceID) * venc->ibufs.nbuffers)) == NULL ) {
LOGE("Couldn't allocate %zubytes", sizeof(VASurfaceID) * venc->ibufs.nbuffers);
} else {
VADRMPRIMESurfaceDescriptor ext_surface = { 0 };
VASurfaceAttrib attrs[2] = { 0 };
int width = venc->ibufs.width;
int height = venc->ibufs.height;
int frame_width_mbaligned = width;
int frame_height_mbaligned = height;
venc->config.frame_bitrate = (long long int) width * height * 12 * g_frame_rate / 50;
attrs[0].type = VASurfaceAttribMemoryType;
attrs[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
attrs[0].value.type = VAGenericValueTypeInteger;
attrs[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2;
attrs[1].type = VASurfaceAttribExternalBufferDescriptor;
attrs[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
attrs[1].value.type = VAGenericValueTypePointer;
attrs[1].value.value.p = &ext_surface;
ext_surface.fourcc = fourcc_buffer_format;
ext_surface.width = frame_width_mbaligned;
ext_surface.height = frame_height_mbaligned;
ext_surface.num_objects = 1;
ext_surface.objects[0].size = venc->ibufs.bsize;
ext_surface.objects[0].drm_format_modifier = 0;
ext_surface.num_layers = 1;
ext_surface.layers[0].drm_format = fourcc_buffer_format;
ext_surface.layers[0].num_planes = 1;
ext_surface.layers[0].object_index[0] = 0;
ext_surface.layers[0].offset[0] = venc->screen_buffer_planar_offset[0];
ext_surface.layers[0].pitch[0] = venc->screen_buffer_stride;
LOGE("marker bsize %d pitch0 %d offset %d",venc->ibufs.bsize, venc->screen_buffer_stride,venc->screen_buffer_planar_offset[0]);
/* create source surfaces */
for( int i = 0; i < venc->ibufs.nbuffers; i++ ) {
int fd = qnx_screen_get_dmabuf_fd(venc->ibufs.buffer_info[i].buf_handle);
LOGI("fd %d egle %d",fd,(int)venc->ibufs.buffer_info[i].buf_handle);
ext_surface.objects[0].fd = fd;
vas = vaCreateSurfaces(venc->display, surface_type, frame_width_mbaligned, frame_height_mbaligned, &(venc->va_external_sid[i]), 1, attrs, 2);
if ( vas != VA_STATUS_SUCCESS) {
LOGE("vaError: %s",vaErrorStr(vas));
if ( i > 0 ) {
vaDestroySurfaces(venc->display, venc->va_external_sid, i );
}
free(venc->va_external_sid);
venc->va_external_sid = NULL;
return vas;
}
LOGE("marker sid %d",venc->va_external_sid[i]);
}
}
return vas;
}
VAStatus va_encoder_dump_rgba_from_surface(va_enc_t *venc, VASurfaceID src_sid){
VAStatus vas = VA_STATUS_ERROR_UNKNOWN;
VAImage img;
VAImageFormat rgba_fmt;
unsigned char *map = NULL;
if ( venc->fprgba == NULL ) {
char name[256];
sprintf(name,"/tmp/va_enc.rgba");
venc->fprgba = fopen(name, "w");
if ( venc->fprgba == NULL ){
LOGE("Failed to open (%s)",name);
return vas;
}
}
VAStatus st = vaDeriveImage(venc->display, src_sid, &img);
if (st != VA_STATUS_SUCCESS) {
memset(&rgba_fmt, 0, sizeof(rgba_fmt));
rgba_fmt.fourcc = venc->fourcc_buffer_format;
rgba_fmt.byte_order = VA_LSB_FIRST;
rgba_fmt.bits_per_pixel = 32;
rgba_fmt.depth = 32;
rgba_fmt.red_mask = 0x000000FF;
rgba_fmt.green_mask = 0x0000FF00;
rgba_fmt.blue_mask = 0x00FF0000;
rgba_fmt.alpha_mask = 0xFF000000;
if (vaCreateImage(venc->display, &rgba_fmt, venc->width, venc->height, &img) != VA_STATUS_SUCCESS) {
return vas;
}
if (vaGetImage(venc->display, src_sid, 0, 0, venc->width, venc->height, img.image_id) != VA_STATUS_SUCCESS) {
vaDestroyImage(venc->display, img.image_id);
return vas;
}
}
if (vaMapBuffer(venc->display, img.buf, (void **)&map) != VA_STATUS_SUCCESS) {
vaDestroyImage(venc->display, img.image_id);
return vas;
}
uint8_t *rgba = (uint8_t *)map + img.offsets[0];
uint32_t stride = img.pitches[0];
if ((uint8_t *)map != rgba ) {
LOGE("offset %d",img.offsets[0]);
}
LOGE("Image: src_sid %d %ux%u, stride=%u, format=0x%08X", src_sid, img.width, img.height, stride , img.format.fourcc);
fwrite(rgba, 1, venc->width * venc->height * 4, venc->fprgba);
vaUnmapBuffer(venc->display, img.buf);
vaDestroyImage(venc->display, img.image_id);
return VA_STATUS_SUCCESS;
}
I am trying to create a VaSurface with an external buffer attached for RGBA format. I am using follwing code to create surfaces and dumping into file. When I looked dumped rgba data , it is purely black ( used ffplay to verify this)
please look following code and provide feedback to resolve this issue.
Thanks for your help..
static VAStatus va_encoder_setup_external_rgba(va_enc_t *venc)
{
VAStatus vas = VA_STATUS_ERROR_UNKNOWN;
int surface_type = VA_RT_FORMAT_RGB32;
int fourcc_buffer_format = venc->fourcc_buffer_format;
}
VAStatus va_encoder_dump_rgba_from_surface(va_enc_t *venc, VASurfaceID src_sid){
VAStatus vas = VA_STATUS_ERROR_UNKNOWN;
VAImage img;
VAImageFormat rgba_fmt;
unsigned char *map = NULL;
}