示例#1
0
文件: surface.c 项目: Unr34ler/mesa
/**
 * Copy image data from a VdpVideoSurface to application memory in a specified
 * YCbCr format.
 */
VdpStatus
vlVdpVideoSurfaceGetBitsYCbCr(VdpVideoSurface surface,
                              VdpYCbCrFormat destination_ycbcr_format,
                              void *const *destination_data,
                              uint32_t const *destination_pitches)
{
   vlVdpSurface *vlsurface;
   struct pipe_context *pipe;
   enum pipe_format format, buffer_format;
   struct pipe_sampler_view **sampler_views;
   enum getbits_conversion conversion = CONVERSION_NONE;
   unsigned i, j;

   vlsurface = vlGetDataHTAB(surface);
   if (!vlsurface)
      return VDP_STATUS_INVALID_HANDLE;

   pipe = vlsurface->device->context;
   if (!pipe)
      return VDP_STATUS_INVALID_HANDLE;

   if (!destination_data || !destination_pitches)
       return VDP_STATUS_INVALID_POINTER;

   format = FormatYCBCRToPipe(destination_ycbcr_format);
   if (format == PIPE_FORMAT_NONE)
      return VDP_STATUS_INVALID_Y_CB_CR_FORMAT;

   if (vlsurface->video_buffer == NULL)
      return VDP_STATUS_INVALID_VALUE;

   buffer_format = vlsurface->video_buffer->buffer_format;
   if (format != buffer_format) {
      if (format == PIPE_FORMAT_YV12 && buffer_format == PIPE_FORMAT_NV12)
         conversion = CONVERSION_NV12_TO_YV12;
      else if (format == PIPE_FORMAT_NV12 && buffer_format == PIPE_FORMAT_YV12)
         conversion = CONVERSION_YV12_TO_NV12;
      else if ((format == PIPE_FORMAT_YUYV && buffer_format == PIPE_FORMAT_UYVY) ||
               (format == PIPE_FORMAT_UYVY && buffer_format == PIPE_FORMAT_YUYV))
         conversion = CONVERSION_SWAP_YUYV_UYVY;
      else
         return VDP_STATUS_NO_IMPLEMENTATION;
   }

   pipe_mutex_lock(vlsurface->device->mutex);
   sampler_views = vlsurface->video_buffer->get_sampler_view_planes(vlsurface->video_buffer);
   if (!sampler_views) {
      pipe_mutex_unlock(vlsurface->device->mutex);
      return VDP_STATUS_RESOURCES;
   }

   for (i = 0; i < 3; ++i) {
      unsigned width, height;
      struct pipe_sampler_view *sv = sampler_views[i];
      if (!sv) continue;

      vlVdpVideoSurfaceSize(vlsurface, i, &width, &height);

      for (j = 0; j < sv->texture->array_size; ++j) {
         struct pipe_box box = {
            0, 0, j,
            width, height, 1
         };
         struct pipe_transfer *transfer;
         uint8_t *map;

         map = pipe->transfer_map(pipe, sv->texture, 0,
                                       PIPE_TRANSFER_READ, &box, &transfer);
         if (!map) {
            pipe_mutex_unlock(vlsurface->device->mutex);
            return VDP_STATUS_RESOURCES;
         }

         if (conversion == CONVERSION_NV12_TO_YV12 && i == 1) {
            u_copy_nv12_to_yv12(destination_data, destination_pitches,
                                i, j, transfer->stride, sv->texture->array_size,
                                map, box.width, box.height);
         } else if (conversion == CONVERSION_YV12_TO_NV12 && i > 0) {
            u_copy_yv12_to_nv12(destination_data, destination_pitches,
                                i, j, transfer->stride, sv->texture->array_size,
                                map, box.width, box.height);
         } else if (conversion == CONVERSION_SWAP_YUYV_UYVY) {
            u_copy_swap422_packed(destination_data, destination_pitches,
                                   i, j, transfer->stride, sv->texture->array_size,
                                   map, box.width, box.height);
         } else {
            util_copy_rect(destination_data[i] + destination_pitches[i] * j, sv->texture->format,
                           destination_pitches[i] * sv->texture->array_size, 0, 0,
                           box.width, box.height, map, transfer->stride, 0, 0);
         }

         pipe_transfer_unmap(pipe, transfer);
      }
   }
   pipe_mutex_unlock(vlsurface->device->mutex);

   return VDP_STATUS_OK;
}
示例#2
0
文件: surface.c 项目: Unr34ler/mesa
/**
 * Copy image data from application memory in a specific YCbCr format to
 * a VdpVideoSurface.
 */
VdpStatus
vlVdpVideoSurfacePutBitsYCbCr(VdpVideoSurface surface,
                              VdpYCbCrFormat source_ycbcr_format,
                              void const *const *source_data,
                              uint32_t const *source_pitches)
{
   enum pipe_format pformat = FormatYCBCRToPipe(source_ycbcr_format);
   struct pipe_context *pipe;
   struct pipe_sampler_view **sampler_views;
   unsigned i, j;

   vlVdpSurface *p_surf = vlGetDataHTAB(surface);
   if (!p_surf)
      return VDP_STATUS_INVALID_HANDLE;

   pipe = p_surf->device->context;
   if (!pipe)
      return VDP_STATUS_INVALID_HANDLE;

   if (!source_data || !source_pitches)
       return VDP_STATUS_INVALID_POINTER;

   pipe_mutex_lock(p_surf->device->mutex);
   if (p_surf->video_buffer == NULL || pformat != p_surf->video_buffer->buffer_format) {

      /* destroy the old one */
      if (p_surf->video_buffer)
         p_surf->video_buffer->destroy(p_surf->video_buffer);

      /* adjust the template parameters */
      p_surf->templat.buffer_format = pformat;

      /* and try to create the video buffer with the new format */
      p_surf->video_buffer = pipe->create_video_buffer(pipe, &p_surf->templat);

      /* stil no luck? ok forget it we don't support it */
      if (!p_surf->video_buffer) {
         pipe_mutex_unlock(p_surf->device->mutex);
         return VDP_STATUS_NO_IMPLEMENTATION;
      }
      vlVdpVideoSurfaceClear(p_surf);
   }

   sampler_views = p_surf->video_buffer->get_sampler_view_planes(p_surf->video_buffer);
   if (!sampler_views) {
      pipe_mutex_unlock(p_surf->device->mutex);
      return VDP_STATUS_RESOURCES;
   }

   for (i = 0; i < 3; ++i) {
      unsigned width, height;
      struct pipe_sampler_view *sv = sampler_views[i];
      if (!sv || !source_pitches[i]) continue;

      vlVdpVideoSurfaceSize(p_surf, i, &width, &height);

      for (j = 0; j < sv->texture->array_size; ++j) {
         struct pipe_box dst_box = {
            0, 0, j,
            width, height, 1
         };

         pipe->transfer_inline_write(pipe, sv->texture, 0,
                                     PIPE_TRANSFER_WRITE, &dst_box,
                                     source_data[i] + source_pitches[i] * j,
                                     source_pitches[i] * sv->texture->array_size,
                                     0);
      }
   }
   pipe_mutex_unlock(p_surf->device->mutex);

   return VDP_STATUS_OK;
}
示例#3
0
文件: surface.c 项目: CSRedRat/mesa-1
/**
 * Copy image data from a VdpVideoSurface to application memory in a specified
 * YCbCr format.
 */
VdpStatus
vlVdpVideoSurfaceGetBitsYCbCr(VdpVideoSurface surface,
                              VdpYCbCrFormat destination_ycbcr_format,
                              void *const *destination_data,
                              uint32_t const *destination_pitches)
{
   vlVdpSurface *vlsurface;
   struct pipe_context *pipe;
   enum pipe_format format;
   struct pipe_sampler_view **sampler_views;
   unsigned i, j;

   vlsurface = vlGetDataHTAB(surface);
   if (!vlsurface)
      return VDP_STATUS_INVALID_HANDLE;

   pipe = vlsurface->device->context;
   if (!pipe)
      return VDP_STATUS_INVALID_HANDLE;

   format = FormatYCBCRToPipe(destination_ycbcr_format);
   if (format == PIPE_FORMAT_NONE)
       return VDP_STATUS_INVALID_Y_CB_CR_FORMAT;

   if (vlsurface->video_buffer == NULL || format != vlsurface->video_buffer->buffer_format)
      return VDP_STATUS_NO_IMPLEMENTATION; /* TODO We don't support conversion (yet) */

   pipe_mutex_lock(vlsurface->device->mutex);
   sampler_views = vlsurface->video_buffer->get_sampler_view_planes(vlsurface->video_buffer);
   if (!sampler_views) {
      pipe_mutex_unlock(vlsurface->device->mutex);
      return VDP_STATUS_RESOURCES;
   }

   for (i = 0; i < 3; ++i) {
      unsigned width, height;
      struct pipe_sampler_view *sv = sampler_views[i];
      if (!sv) continue;

      vlVdpVideoSurfaceSize(vlsurface, i, &width, &height);

      for (j = 0; j < sv->texture->array_size; ++j) {
         struct pipe_box box = {
            0, 0, j,
            width, height, 1
         };
         struct pipe_transfer *transfer;
         uint8_t *map;

         map = pipe->transfer_map(pipe, sv->texture, 0,
                                       PIPE_TRANSFER_READ, &box, &transfer);
         if (!map) {
            pipe_mutex_unlock(vlsurface->device->mutex);
            return VDP_STATUS_RESOURCES;
         }

         util_copy_rect(destination_data[i] + destination_pitches[i] * j, sv->texture->format,
                        destination_pitches[i] * sv->texture->array_size, 0, 0,
                        box.width, box.height, map, transfer->stride, 0, 0);

         pipe_transfer_unmap(pipe, transfer);
      }
   }
   pipe_mutex_unlock(vlsurface->device->mutex);

   return VDP_STATUS_OK;
}