---
avconv_vdpau.c | 133 ++++++---------------------------------------------------
1 file changed, 12 insertions(+), 121 deletions(-)
diff --git a/avconv_vdpau.c b/avconv_vdpau.c
index 1bd1f48..a38865a 100644
--- a/avconv_vdpau.c
+++ b/avconv_vdpau.c
@@ -30,6 +30,8 @@
#include "libavutil/avassert.h"
#include "libavutil/buffer.h"
#include "libavutil/frame.h"
+#include "libavutil/hwframe.h"
+#include "libavutil/hwframe_vdpau.h"
#include "libavutil/pixfmt.h"
typedef struct VDPAUContext {
@@ -42,16 +44,9 @@ typedef struct VDPAUContext {
VdpGetErrorString *get_error_string;
VdpGetInformationString *get_information_string;
VdpDeviceDestroy *device_destroy;
- VdpVideoSurfaceCreate *video_surface_create;
- VdpVideoSurfaceDestroy *video_surface_destroy;
- VdpVideoSurfaceGetBitsYCbCr *video_surface_get_bits;
VdpVideoSurfaceGetParameters
*video_surface_get_parameters;
- VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *video_surface_query;
AVFrame *tmp_frame;
-
- enum AVPixelFormat pix_fmt;
- VdpYCbCrFormat vdpau_format;
} VDPAUContext;
static void vdpau_uninit(AVCodecContext *s)
@@ -75,107 +70,23 @@ static void vdpau_uninit(AVCodecContext *s)
av_freep(&s->hwaccel_context);
}
-static void vdpau_release_buffer(void *opaque, uint8_t *data)
-{
- VdpVideoSurface surface = *(VdpVideoSurface*)data;
- VDPAUContext *ctx = opaque;
-
- ctx->video_surface_destroy(surface);
- av_freep(&data);
-}
-
static int vdpau_get_buffer(AVCodecContext *s, AVFrame *frame, int flags)
{
- InputStream *ist = s->opaque;
- VDPAUContext *ctx = ist->hwaccel_ctx;
- VdpVideoSurface *surface;
- VdpStatus err;
- VdpChromaType chroma;
- uint32_t width, height;
-
- av_assert0(frame->format == AV_PIX_FMT_VDPAU);
-
- if (av_vdpau_get_surface_parameters(s, &chroma, &width, &height))
- return AVERROR(ENOSYS);
-
- surface = av_malloc(sizeof(*surface));
- if (!surface)
- return AVERROR(ENOMEM);
-
- frame->buf[0] = av_buffer_create((uint8_t*)surface, sizeof(*surface),
- vdpau_release_buffer, ctx,
- AV_BUFFER_FLAG_READONLY);
- if (!frame->buf[0]) {
- av_freep(&surface);
- return AVERROR(ENOMEM);
- }
-
- // properly we should keep a pool of surfaces instead of creating
- // them anew for each frame, but since we don't care about speed
- // much in this code, we don't bother
- err = ctx->video_surface_create(ctx->device, chroma, width, height,
- surface);
- if (err != VDP_STATUS_OK) {
- av_log(NULL, AV_LOG_ERROR, "Error allocating a VDPAU video surface:
%s\n",
- ctx->get_error_string(err));
- av_buffer_unref(&frame->buf[0]);
- return AVERROR_UNKNOWN;
- }
-
- frame->data[3] = (uint8_t*)(uintptr_t)*surface;
-
- return 0;
+ return avcodec_default_get_buffer2(s, frame, flags);
}
static int vdpau_retrieve_data(AVCodecContext *s, AVFrame *frame)
{
- VdpVideoSurface surface = (VdpVideoSurface)(uintptr_t)frame->data[3];
InputStream *ist = s->opaque;
VDPAUContext *ctx = ist->hwaccel_ctx;
- VdpStatus err;
- int ret, chroma_type;
+ int ret;
- err = ctx->video_surface_get_parameters(surface, &chroma_type,
- &ctx->tmp_frame->width,
- &ctx->tmp_frame->height);
- if (err != VDP_STATUS_OK) {
- av_log(NULL, AV_LOG_ERROR, "Error getting surface parameters: %s\n",
- ctx->get_error_string(err));
- return AVERROR_UNKNOWN;
- }
- ctx->tmp_frame->format = ctx->pix_fmt;
-
- ret = av_frame_get_buffer(ctx->tmp_frame, 32);
+ ret = av_hwframe_retrieve_data(ctx->tmp_frame, frame);
if (ret < 0)
return ret;
-
- ctx->tmp_frame->width = frame->width;
- ctx->tmp_frame->height = frame->height;
-
- err = ctx->video_surface_get_bits(surface, ctx->vdpau_format,
- (void * const *)ctx->tmp_frame->data,
- ctx->tmp_frame->linesize);
- if (err != VDP_STATUS_OK) {
- av_log(NULL, AV_LOG_ERROR, "Error retrieving frame data from VDPAU:
%s\n",
- ctx->get_error_string(err));
- ret = AVERROR_UNKNOWN;
- goto fail;
- }
-
- if (ctx->vdpau_format == VDP_YCBCR_FORMAT_YV12)
- FFSWAP(uint8_t*, ctx->tmp_frame->data[1], ctx->tmp_frame->data[2]);
-
- ret = av_frame_copy_props(ctx->tmp_frame, frame);
- if (ret < 0)
- goto fail;
-
av_frame_unref(frame);
av_frame_move_ref(frame, ctx->tmp_frame);
return 0;
-
-fail:
- av_frame_unref(ctx->tmp_frame);
- return ret;
}
static const int vdpau_formats[][2] = {
@@ -185,6 +96,11 @@ static const int vdpau_formats[][2] = {
{ VDP_YCBCR_FORMAT_UYVY, AV_PIX_FMT_UYVY422 },
};
+static void vdpau_hwctx_free(AVHWFramesContext *ctx)
+{
+ fprintf(stderr, "free ctx\n");
+}
+
static int vdpau_alloc(AVCodecContext *s)
{
InputStream *ist = s->opaque;
@@ -237,33 +153,6 @@ do {
GET_CALLBACK(VDP_FUNC_ID_GET_ERROR_STRING, get_error_string);
GET_CALLBACK(VDP_FUNC_ID_GET_INFORMATION_STRING,
get_information_string);
GET_CALLBACK(VDP_FUNC_ID_DEVICE_DESTROY, device_destroy);
- GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_CREATE,
video_surface_create);
- GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_DESTROY,
video_surface_destroy);
- GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR,
video_surface_get_bits);
- GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_GET_PARAMETERS,
video_surface_get_parameters);
-
GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES,
- video_surface_query);
-
- for (i = 0; i < FF_ARRAY_ELEMS(vdpau_formats); i++) {
- VdpBool supported;
- err = ctx->video_surface_query(ctx->device, VDP_CHROMA_TYPE_420,
- vdpau_formats[i][0], &supported);
- if (err != VDP_STATUS_OK) {
- av_log(NULL, loglevel,
- "Error querying VDPAU surface capabilities: %s\n",
- ctx->get_error_string(err));
- goto fail;
- }
- if (supported)
- break;
- }
- if (i == FF_ARRAY_ELEMS(vdpau_formats)) {
- av_log(NULL, loglevel,
- "No supported VDPAU format for retrieving the data.\n");
- return AVERROR(EINVAL);
- }
- ctx->vdpau_format = vdpau_formats[i][0];
- ctx->pix_fmt = vdpau_formats[i][1];
if (av_vdpau_bind_context(s, ctx->device, ctx->get_proc_address, 0))
goto fail;
@@ -295,5 +184,7 @@ int vdpau_init(AVCodecContext *s)
ist->hwaccel_get_buffer = vdpau_get_buffer;
ist->hwaccel_retrieve_data = vdpau_retrieve_data;
+ s->hwframe_ctx_free = vdpau_hwctx_free;
+
return 0;
}
--
2.0.0
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel