st/vdpau: implement VideoSurfaceGetBitsYCbCr
authorChristian König <deathsimple@vodafone.de>
Sun, 26 Feb 2012 14:00:00 +0000 (15:00 +0100)
committerChristian König <deathsimple@vodafone.de>
Fri, 2 Mar 2012 12:38:12 +0000 (13:38 +0100)
Signed-off-by: Christian König <deathsimple@vodafone.de>
src/gallium/state_trackers/vdpau/surface.c

index 04832426a1048e76b9a9f638d3eb86274dd1b00f..5ed5c9d88a578592f942cbf5dac5d71cecacc771 100644 (file)
@@ -168,18 +168,63 @@ vlVdpVideoSurfaceGetBitsYCbCr(VdpVideoSurface surface,
                               void *const *destination_data,
                               uint32_t const *destination_pitches)
 {
-   if (!vlCreateHTAB())
-      return VDP_STATUS_RESOURCES;
+   vlVdpSurface *vlsurface;
+   struct pipe_context *pipe;
+   enum pipe_format format;
+   struct pipe_sampler_view **sampler_views;
+   unsigned i, j;
 
-   vlVdpSurface *p_surf = vlGetDataHTAB(surface);
-   if (!p_surf)
+   vlsurface = vlGetDataHTAB(surface);
+   if (!vlsurface)
       return VDP_STATUS_INVALID_HANDLE;
 
-   //if (!p_surf->psurface)
-   //   return VDP_STATUS_RESOURCES;
+   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) */
+
+   sampler_views = vlsurface->video_buffer->get_sampler_view_planes(vlsurface->video_buffer);
+   if (!sampler_views)
+      return VDP_STATUS_RESOURCES;
+
+   for (i = 0; i < 3; ++i) {
+      struct pipe_sampler_view *sv = sampler_views[i];
+      if (!sv) continue;
+
+      for (j = 0; j < sv->texture->depth0; ++j) {
+         struct pipe_box box = {
+            0, 0, j,
+            sv->texture->width0, sv->texture->height0, 1
+         };
+         struct pipe_transfer *transfer;
+         uint8_t *map;
 
-   //return VDP_STATUS_OK;
-   return VDP_STATUS_NO_IMPLEMENTATION;
+         transfer = pipe->get_transfer(pipe, sv->texture, 0, PIPE_TRANSFER_READ, &box);
+         if (transfer == NULL)
+            return VDP_STATUS_RESOURCES;
+
+         map = pipe_transfer_map(pipe, transfer);
+         if (map == NULL) {
+            pipe_transfer_destroy(pipe, transfer);
+            return VDP_STATUS_RESOURCES;
+         }
+
+         util_copy_rect(destination_data[i] + destination_pitches[i] * j, sv->texture->format,
+                        destination_pitches[i] * sv->texture->depth0, 0, 0,
+                        box.width, box.height, map, transfer->stride, 0, 0);
+
+         pipe_transfer_unmap(pipe, transfer);
+         pipe_transfer_destroy(pipe, transfer);
+      }
+   }
+
+   return VDP_STATUS_OK;
 }
 
 /**