Browse code

hwaccel: OS X Video Decoder Acceleration (VDA) support.

Signed-off-by: Luca Barbato <lu_zero@gentoo.org>

Sebastien Zwickert authored on 2011/11/11 23:48:21
Showing 14 changed files
... ...
@@ -101,6 +101,7 @@ easier to use. The changes are:
101 101
 - Encrypted OMA files support
102 102
 - Discworld II BMV decoding support
103 103
 - VBLE Decoder
104
+- OS X Video Decoder Acceleration (VDA) support
104 105
 
105 106
 
106 107
 version 0.7:
... ...
@@ -108,6 +108,7 @@ Configuration options:
108 108
   --disable-mdct           disable MDCT code
109 109
   --disable-rdft           disable RDFT code
110 110
   --enable-vaapi           enable VAAPI code
111
+  --enable-vda             enable VDA code
111 112
   --enable-vdpau           enable VDPAU code
112 113
   --disable-dxva2          disable DXVA2 code
113 114
   --enable-runtime-cpudetect detect cpu capabilities at runtime (bigger binary)
... ...
@@ -978,6 +979,7 @@ CONFIG_LIST="
978 978
     swscale_alpha
979 979
     thumb
980 980
     vaapi
981
+    vda
981 982
     vdpau
982 983
     version3
983 984
     x11grab
... ...
@@ -1294,6 +1296,7 @@ h264_decoder_select="golomb h264dsp h264pred"
1294 1294
 h264_dxva2_hwaccel_deps="dxva2api_h"
1295 1295
 h264_dxva2_hwaccel_select="dxva2 h264_decoder"
1296 1296
 h264_vaapi_hwaccel_select="vaapi h264_decoder"
1297
+h264_vda_hwaccel_select="vda h264_decoder"
1297 1298
 h264_vdpau_decoder_select="vdpau h264_decoder"
1298 1299
 imc_decoder_select="fft mdct sinewin"
1299 1300
 jpegls_decoder_select="golomb"
... ...
@@ -1390,6 +1393,7 @@ zmbv_decoder_select="zlib"
1390 1390
 zmbv_encoder_select="zlib"
1391 1391
 
1392 1392
 vaapi_deps="va_va_h"
1393
+vda_deps="VideoDecodeAcceleration_VDADecoder_h pthreads"
1393 1394
 vdpau_deps="vdpau_vdpau_h vdpau_vdpau_x11_h"
1394 1395
 
1395 1396
 # parsers
... ...
@@ -2988,6 +2992,11 @@ check_func XOpenDisplay -lX11           &&
2988 2988
 check_func XShmCreateImage -lX11 -lXext &&
2989 2989
 check_func XFixesGetCursorImage -lX11 -lXext -lXfixes
2990 2990
 
2991
+# check for VDA header
2992
+if ! disabled vda && check_header VideoDecodeAcceleration/VDADecoder.h; then
2993
+    enable vda && add_ldflags -framework CoreFoundation -framework VideoDecodeAcceleration -framework QuartzCore
2994
+fi
2995
+
2991 2996
 if ! disabled vdpau && enabled vdpau_vdpau_h; then
2992 2997
 check_cpp_condition \
2993 2998
     vdpau/vdpau.h "defined VDP_DECODER_PROFILE_MPEG4_PART2_ASP" ||
... ...
@@ -1,7 +1,7 @@
1 1
 NAME = avcodec
2 2
 FFLIBS = avutil
3 3
 
4
-HEADERS = avcodec.h avfft.h dxva2.h opt.h vaapi.h vdpau.h version.h xvmc.h
4
+HEADERS = avcodec.h avfft.h dxva2.h opt.h vaapi.h vda.h vdpau.h version.h xvmc.h
5 5
 
6 6
 OBJS = allcodecs.o                                                      \
7 7
        audioconvert.o                                                   \
... ...
@@ -45,6 +45,7 @@ RDFT-OBJS-$(CONFIG_HARDCODED_TABLES)   += sin_tables.o
45 45
 OBJS-$(CONFIG_RDFT)                    += rdft.o $(RDFT-OBJS-yes)
46 46
 OBJS-$(CONFIG_SINEWIN)                 += sinewin.o
47 47
 OBJS-$(CONFIG_VAAPI)                   += vaapi.o
48
+OBJS-$(CONFIG_VDA)                     += vda.o
48 49
 OBJS-$(CONFIG_VDPAU)                   += vdpau.o
49 50
 
50 51
 # decoders/encoders/hardware accelerators
... ...
@@ -180,6 +181,7 @@ OBJS-$(CONFIG_H264_DECODER)            += h264.o                               \
180 180
                                           mpegvideo.o error_resilience.o
181 181
 OBJS-$(CONFIG_H264_DXVA2_HWACCEL)      += dxva2_h264.o
182 182
 OBJS-$(CONFIG_H264_VAAPI_HWACCEL)      += vaapi_h264.o
183
+OBJS-$(CONFIG_H264_VDA_HWACCEL)        += vda_h264.o
183 184
 OBJS-$(CONFIG_HUFFYUV_DECODER)         += huffyuv.o
184 185
 OBJS-$(CONFIG_HUFFYUV_ENCODER)         += huffyuv.o
185 186
 OBJS-$(CONFIG_IDCIN_DECODER)           += idcinvideo.o
... ...
@@ -670,6 +672,7 @@ SKIPHEADERS-$(CONFIG_DXVA2)            += dxva2.h dxva2_internal.h
670 670
 SKIPHEADERS-$(CONFIG_LIBDIRAC)         += libdirac.h
671 671
 SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER)  += libschroedinger.h
672 672
 SKIPHEADERS-$(CONFIG_VAAPI)            += vaapi_internal.h
673
+SKIPHEADERS-$(CONFIG_VDA)              += vda.h vda_internal.h
673 674
 SKIPHEADERS-$(CONFIG_VDPAU)            += vdpau.h
674 675
 SKIPHEADERS-$(CONFIG_XVMC)             += xvmc.h
675 676
 SKIPHEADERS-$(HAVE_W32THREADS)         += w32pthreads.h
... ...
@@ -57,6 +57,7 @@ void avcodec_register_all(void)
57 57
     REGISTER_HWACCEL (H263_VAAPI, h263_vaapi);
58 58
     REGISTER_HWACCEL (H264_DXVA2, h264_dxva2);
59 59
     REGISTER_HWACCEL (H264_VAAPI, h264_vaapi);
60
+    REGISTER_HWACCEL (H264_VDA, h264_vda);
60 61
     REGISTER_HWACCEL (MPEG2_DXVA2, mpeg2_dxva2);
61 62
     REGISTER_HWACCEL (MPEG2_VAAPI, mpeg2_vaapi);
62 63
     REGISTER_HWACCEL (MPEG4_VAAPI, mpeg4_vaapi);
... ...
@@ -56,6 +56,7 @@ static const uint8_t div6[QP_MAX_NUM+1]={
56 56
 static const enum PixelFormat hwaccel_pixfmt_list_h264_jpeg_420[] = {
57 57
     PIX_FMT_DXVA2_VLD,
58 58
     PIX_FMT_VAAPI_VLD,
59
+    PIX_FMT_VDA_VLD,
59 60
     PIX_FMT_YUVJ420P,
60 61
     PIX_FMT_NONE
61 62
 };
... ...
@@ -118,6 +118,7 @@ const enum PixelFormat ff_pixfmt_list_420[] = {
118 118
 const enum PixelFormat ff_hwaccel_pixfmt_list_420[] = {
119 119
     PIX_FMT_DXVA2_VLD,
120 120
     PIX_FMT_VAAPI_VLD,
121
+    PIX_FMT_VDA_VLD,
121 122
     PIX_FMT_YUV420P,
122 123
     PIX_FMT_NONE
123 124
 };
124 125
new file mode 100644
... ...
@@ -0,0 +1,259 @@
0
+/*
1
+ * VDA hardware acceleration
2
+ *
3
+ * copyright (c) 2011 Sebastien Zwickert
4
+ *
5
+ * This file is part of Libav.
6
+ *
7
+ * Libav is free software; you can redistribute it and/or
8
+ * modify it under the terms of the GNU Lesser General Public
9
+ * License as published by the Free Software Foundation; either
10
+ * version 2.1 of the License, or (at your option) any later version.
11
+ *
12
+ * Libav is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
+ * Lesser General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU Lesser General Public
18
+ * License along with Libav; if not, write to the Free Software
19
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
+ */
21
+
22
+#include <pthread.h>
23
+#include <CoreFoundation/CFDictionary.h>
24
+#include <CoreFoundation/CFNumber.h>
25
+#include <CoreFoundation/CFData.h>
26
+#include <CoreFoundation/CFString.h>
27
+
28
+#include "libavutil/avutil.h"
29
+#include "vda_internal.h"
30
+
31
+/* helper to create a dictionary according to the given pts */
32
+static CFDictionaryRef vda_dictionary_with_pts(int64_t i_pts)
33
+{
34
+    CFStringRef key           = CFSTR("FF_VDA_DECODER_PTS_KEY");
35
+    CFNumberRef value         = CFNumberCreate(kCFAllocatorDefault,
36
+                                               kCFNumberSInt64Type, &i_pts);
37
+    CFDictionaryRef user_info = CFDictionaryCreate(kCFAllocatorDefault,
38
+                                                   (const void **)&key,
39
+                                                   (const void **)&value,
40
+                                                   1,
41
+                                                   &kCFTypeDictionaryKeyCallBacks,
42
+                                                   &kCFTypeDictionaryValueCallBacks);
43
+    CFRelease(value);
44
+    return user_info;
45
+}
46
+
47
+/* helper to retrieve the pts from the given dictionary */
48
+static int64_t vda_pts_from_dictionary(CFDictionaryRef user_info)
49
+{
50
+    CFNumberRef pts;
51
+    int64_t outValue = 0;
52
+
53
+    if (!user_info)
54
+        return 0;
55
+
56
+    pts = CFDictionaryGetValue(user_info, CFSTR("FF_VDA_DECODER_PTS_KEY"));
57
+
58
+    if (pts)
59
+        CFNumberGetValue(pts, kCFNumberSInt64Type, &outValue);
60
+
61
+    return outValue;
62
+}
63
+
64
+/* Remove and release all frames from the queue. */
65
+static void vda_clear_queue(struct vda_context *vda_ctx)
66
+{
67
+    vda_frame *top_frame;
68
+
69
+    pthread_mutex_lock(&vda_ctx->queue_mutex);
70
+
71
+    while (vda_ctx->queue) {
72
+        top_frame      = vda_ctx->queue;
73
+        vda_ctx->queue = top_frame->next_frame;
74
+        ff_vda_release_vda_frame(top_frame);
75
+    }
76
+
77
+    pthread_mutex_unlock(&vda_ctx->queue_mutex);
78
+}
79
+
80
+/* Decoder callback that adds the VDA frame to the queue in display order. */
81
+static void vda_decoder_callback(void *vda_hw_ctx,
82
+                                 CFDictionaryRef user_info,
83
+                                 OSStatus status,
84
+                                 uint32_t infoFlags,
85
+                                 CVImageBufferRef image_buffer)
86
+{
87
+    struct vda_context *vda_ctx = vda_hw_ctx;
88
+    vda_frame *new_frame;
89
+    vda_frame *queue_walker;
90
+
91
+    if (!image_buffer)
92
+        return;
93
+
94
+    if (vda_ctx->cv_pix_fmt_type != CVPixelBufferGetPixelFormatType(image_buffer))
95
+        return;
96
+
97
+    if (!(new_frame = av_mallocz(sizeof(vda_frame))))
98
+        return;
99
+    new_frame->next_frame = NULL;
100
+    new_frame->cv_buffer  = CVPixelBufferRetain(image_buffer);
101
+    new_frame->pts        = vda_pts_from_dictionary(user_info);
102
+
103
+    pthread_mutex_lock(&vda_ctx->queue_mutex);
104
+
105
+    queue_walker = vda_ctx->queue;
106
+
107
+    if (!queue_walker || new_frame->pts < queue_walker->pts) {
108
+        /* we have an empty queue, or this frame earlier than the current queue head */
109
+        new_frame->next_frame = queue_walker;
110
+        vda_ctx->queue        = new_frame;
111
+    } else {
112
+        /* walk the queue and insert this frame where it belongs in display order */
113
+        vda_frame *next_frame;
114
+        while (1) {
115
+            next_frame = queue_walker->next_frame;
116
+            if (!next_frame || new_frame->pts < next_frame->pts) {
117
+                new_frame->next_frame    = next_frame;
118
+                queue_walker->next_frame = new_frame;
119
+                break;
120
+            }
121
+            queue_walker = next_frame;
122
+        }
123
+    }
124
+
125
+    pthread_mutex_unlock(&vda_ctx->queue_mutex);
126
+}
127
+
128
+int ff_vda_create_decoder(struct vda_context *vda_ctx,
129
+                          uint8_t *extradata,
130
+                          int extradata_size)
131
+{
132
+    OSStatus status = kVDADecoderNoErr;
133
+    CFNumberRef height;
134
+    CFNumberRef width;
135
+    CFNumberRef format;
136
+    CFDataRef avc_data;
137
+    CFMutableDictionaryRef config_info;
138
+    CFMutableDictionaryRef buffer_attributes;
139
+    CFMutableDictionaryRef io_surface_properties;
140
+    CFNumberRef cv_pix_fmt;
141
+
142
+    pthread_mutex_init(&vda_ctx->queue_mutex, NULL);
143
+
144
+    config_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
145
+                                            4,
146
+                                            &kCFTypeDictionaryKeyCallBacks,
147
+                                            &kCFTypeDictionaryValueCallBacks);
148
+
149
+    height   = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->height);
150
+    width    = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->width);
151
+    format   = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->format);
152
+    avc_data = CFDataCreate(kCFAllocatorDefault, extradata, extradata_size);
153
+
154
+    CFDictionarySetValue(config_info, kVDADecoderConfiguration_Height, height);
155
+    CFDictionarySetValue(config_info, kVDADecoderConfiguration_Width, width);
156
+    CFDictionarySetValue(config_info, kVDADecoderConfiguration_SourceFormat, format);
157
+    CFDictionarySetValue(config_info, kVDADecoderConfiguration_avcCData, avc_data);
158
+
159
+    buffer_attributes = CFDictionaryCreateMutable(kCFAllocatorDefault,
160
+                                                  2,
161
+                                                  &kCFTypeDictionaryKeyCallBacks,
162
+                                                  &kCFTypeDictionaryValueCallBacks);
163
+    io_surface_properties = CFDictionaryCreateMutable(kCFAllocatorDefault,
164
+                                                      0,
165
+                                                      &kCFTypeDictionaryKeyCallBacks,
166
+                                                      &kCFTypeDictionaryValueCallBacks);
167
+    cv_pix_fmt      = CFNumberCreate(kCFAllocatorDefault,
168
+                                     kCFNumberSInt32Type,
169
+                                     &vda_ctx->cv_pix_fmt_type);
170
+    CFDictionarySetValue(buffer_attributes,
171
+                         kCVPixelBufferPixelFormatTypeKey,
172
+                         cv_pix_fmt);
173
+    CFDictionarySetValue(buffer_attributes,
174
+                         kCVPixelBufferIOSurfacePropertiesKey,
175
+                         io_surface_properties);
176
+
177
+    status = VDADecoderCreate(config_info,
178
+                              buffer_attributes,
179
+                              vda_decoder_callback,
180
+                              vda_ctx,
181
+                              &vda_ctx->decoder);
182
+
183
+    CFRelease(height);
184
+    CFRelease(width);
185
+    CFRelease(format);
186
+    CFRelease(avc_data);
187
+    CFRelease(config_info);
188
+    CFRelease(io_surface_properties);
189
+    CFRelease(cv_pix_fmt);
190
+    CFRelease(buffer_attributes);
191
+
192
+    if (kVDADecoderNoErr != status)
193
+        return status;
194
+
195
+    return 0;
196
+}
197
+
198
+int ff_vda_destroy_decoder(struct vda_context *vda_ctx)
199
+{
200
+    OSStatus status = kVDADecoderNoErr;
201
+
202
+    if (vda_ctx->decoder)
203
+        status = VDADecoderDestroy(vda_ctx->decoder);
204
+
205
+    vda_clear_queue(vda_ctx);
206
+
207
+    pthread_mutex_destroy(&vda_ctx->queue_mutex);
208
+
209
+    if (kVDADecoderNoErr != status)
210
+        return status;
211
+
212
+    return 0;
213
+}
214
+
215
+vda_frame *ff_vda_queue_pop(struct vda_context *vda_ctx)
216
+{
217
+    vda_frame *top_frame;
218
+
219
+    if (!vda_ctx->queue)
220
+        return NULL;
221
+
222
+    pthread_mutex_lock(&vda_ctx->queue_mutex);
223
+    top_frame      = vda_ctx->queue;
224
+    vda_ctx->queue = top_frame->next_frame;
225
+    pthread_mutex_unlock(&vda_ctx->queue_mutex);
226
+
227
+    return top_frame;
228
+}
229
+
230
+void ff_vda_release_vda_frame(vda_frame *frame)
231
+{
232
+    if (frame) {
233
+        CVPixelBufferRelease(frame->cv_buffer);
234
+        av_freep(&frame);
235
+    }
236
+}
237
+
238
+int ff_vda_decoder_decode(struct vda_context *vda_ctx,
239
+                          uint8_t *bitstream,
240
+                          int bitstream_size,
241
+                          int64_t frame_pts)
242
+{
243
+    OSStatus status = kVDADecoderNoErr;
244
+    CFDictionaryRef user_info;
245
+    CFDataRef coded_frame;
246
+
247
+    coded_frame = CFDataCreate(kCFAllocatorDefault, bitstream, bitstream_size);
248
+    user_info   = vda_dictionary_with_pts(frame_pts);
249
+    status      = VDADecoderDecode(vda_ctx->decoder, 0, coded_frame, user_info);
250
+
251
+    CFRelease(user_info);
252
+    CFRelease(coded_frame);
253
+
254
+    if (kVDADecoderNoErr != status)
255
+        return status;
256
+
257
+    return 0;
258
+}
0 259
new file mode 100644
... ...
@@ -0,0 +1,144 @@
0
+/*
1
+ * VDA HW acceleration
2
+ *
3
+ * copyright (c) 2011 Sebastien Zwickert
4
+ *
5
+ * This file is part of Libav.
6
+ *
7
+ * Libav is free software; you can redistribute it and/or
8
+ * modify it under the terms of the GNU Lesser General Public
9
+ * License as published by the Free Software Foundation; either
10
+ * version 2.1 of the License, or (at your option) any later version.
11
+ *
12
+ * Libav is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
+ * Lesser General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU Lesser General Public
18
+ * License along with Libav; if not, write to the Free Software
19
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
+ */
21
+
22
+#ifndef AVCODEC_VDA_H
23
+#define AVCODEC_VDA_H
24
+
25
+#include <pthread.h>
26
+#include <stdint.h>
27
+
28
+// emmintrin.h is unable to compile with -std=c99 -Werror=missing-prototypes
29
+// http://openradar.appspot.com/8026390
30
+#undef __GNUC_STDC_INLINE__
31
+
32
+#define Picture QuickdrawPicture
33
+#include <VideoDecodeAcceleration/VDADecoder.h>
34
+#undef Picture
35
+
36
+/**
37
+ *  This structure is used to store a decoded frame information and data.
38
+ */
39
+typedef struct vda_frame {
40
+    /**
41
+    * The PTS of the frame.
42
+    *
43
+    * - encoding: unused
44
+    * - decoding: Set/Unset by libavcodec.
45
+    */
46
+    int64_t             pts;
47
+
48
+    /**
49
+    * The CoreVideo buffer that contains the decoded data.
50
+    *
51
+    * - encoding: unused
52
+    * - decoding: Set/Unset by libavcodec.
53
+    */
54
+    CVPixelBufferRef    cv_buffer;
55
+
56
+    /**
57
+    * A pointer to the next frame.
58
+    *
59
+    * - encoding: unused
60
+    * - decoding: Set/Unset by libavcodec.
61
+    */
62
+    struct vda_frame    *next_frame;
63
+} vda_frame;
64
+
65
+/**
66
+ * This structure is used to provide the necessary configurations and data
67
+ * to the VDA Libav HWAccel implementation.
68
+ *
69
+ * The application must make it available as AVCodecContext.hwaccel_context.
70
+ */
71
+struct vda_context {
72
+    /**
73
+    * VDA decoder object.
74
+    *
75
+    * - encoding: unused
76
+    * - decoding: Set/Unset by libavcodec.
77
+    */
78
+    VDADecoder          decoder;
79
+
80
+    /**
81
+    * VDA frames queue ordered by presentation timestamp.
82
+    *
83
+    * - encoding: unused
84
+    * - decoding: Set/Unset by libavcodec.
85
+    */
86
+    vda_frame           *queue;
87
+
88
+    /**
89
+    * Mutex for locking queue operations.
90
+    *
91
+    * - encoding: unused
92
+    * - decoding: Set/Unset by libavcodec.
93
+    */
94
+    pthread_mutex_t     queue_mutex;
95
+
96
+    /**
97
+    * The frame width.
98
+    *
99
+    * - encoding: unused
100
+    * - decoding: Set/Unset by user.
101
+    */
102
+    int                 width;
103
+
104
+    /**
105
+    * The frame height.
106
+    *
107
+    * - encoding: unused
108
+    * - decoding: Set/Unset by user.
109
+    */
110
+    int                 height;
111
+
112
+    /**
113
+    * The frame format.
114
+    *
115
+    * - encoding: unused
116
+    * - decoding: Set/Unset by user.
117
+    */
118
+    int                 format;
119
+
120
+    /**
121
+    * The pixel format for output image buffers.
122
+    *
123
+    * - encoding: unused
124
+    * - decoding: Set/Unset by user.
125
+    */
126
+    OSType              cv_pix_fmt_type;
127
+};
128
+
129
+/** Create the video decoder. */
130
+int ff_vda_create_decoder(struct vda_context *vda_ctx,
131
+                          uint8_t *extradata,
132
+                          int extradata_size);
133
+
134
+/** Destroy the video decoder. */
135
+int ff_vda_destroy_decoder(struct vda_context *vda_ctx);
136
+
137
+/** Return the top frame of the queue. */
138
+vda_frame *ff_vda_queue_pop(struct vda_context *vda_ctx);
139
+
140
+/** Release the given frame. */
141
+void ff_vda_release_vda_frame(vda_frame *frame);
142
+
143
+#endif /* AVCODEC_VDA_H */
0 144
new file mode 100644
... ...
@@ -0,0 +1,110 @@
0
+/*
1
+ * VDA H.264 hardware acceleration
2
+ *
3
+ * copyright (c) 2011 Sebastien Zwickert
4
+ *
5
+ * This file is part of Libav.
6
+ *
7
+ * Libav is free software; you can redistribute it and/or
8
+ * modify it under the terms of the GNU Lesser General Public
9
+ * License as published by the Free Software Foundation; either
10
+ * version 2.1 of the License, or (at your option) any later version.
11
+ *
12
+ * Libav is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
+ * Lesser General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU Lesser General Public
18
+ * License along with Libav; if not, write to the Free Software
19
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
+ */
21
+
22
+#include "h264.h"
23
+#include "h264data.h"
24
+
25
+#include "vda_internal.h"
26
+
27
+/* This structure is used to store the bitstream of the current frame. */
28
+struct vda_picture_context {
29
+    uint8_t *bitstream;
30
+    int      bitstream_size;
31
+};
32
+
33
+static int start_frame(AVCodecContext *avctx,
34
+                       av_unused const uint8_t *buffer,
35
+                       av_unused uint32_t size)
36
+{
37
+    const H264Context *h                = avctx->priv_data;
38
+    struct vda_context *vda_ctx         = avctx->hwaccel_context;
39
+    struct vda_picture_context *pic_ctx = h->s.current_picture_ptr->f.hwaccel_picture_private;
40
+
41
+    if (!vda_ctx->decoder)
42
+        return -1;
43
+
44
+    pic_ctx->bitstream      = NULL;
45
+    pic_ctx->bitstream_size = 0;
46
+
47
+    return 0;
48
+}
49
+
50
+static int decode_slice(AVCodecContext *avctx,
51
+                        const uint8_t *buffer,
52
+                        uint32_t size)
53
+{
54
+    H264Context *h                      = avctx->priv_data;
55
+    struct vda_context *vda_ctx         = avctx->hwaccel_context;
56
+    struct vda_picture_context *pic_ctx = h->s.current_picture_ptr->f.hwaccel_picture_private;
57
+    void *tmp;
58
+
59
+    if (!vda_ctx->decoder)
60
+        return -1;
61
+
62
+    tmp = av_realloc(pic_ctx->bitstream, pic_ctx->bitstream_size+size+4);
63
+    if (!tmp)
64
+        return AVERROR(ENOMEM);
65
+
66
+    pic_ctx->bitstream = tmp;
67
+
68
+    AV_WB32(pic_ctx->bitstream + pic_ctx->bitstream_size, size);
69
+    memcpy(pic_ctx->bitstream + pic_ctx->bitstream_size + 4, buffer, size);
70
+
71
+    pic_ctx->bitstream_size += size + 4;
72
+
73
+    return 0;
74
+}
75
+
76
+static int end_frame(AVCodecContext *avctx)
77
+{
78
+    H264Context *h                      = avctx->priv_data;
79
+    struct vda_context *vda_ctx         = avctx->hwaccel_context;
80
+    struct vda_picture_context *pic_ctx = h->s.current_picture_ptr->f.hwaccel_picture_private;
81
+    AVFrame *frame                      = &h->s.current_picture_ptr->f;
82
+    int status;
83
+
84
+    if (!vda_ctx->decoder || !pic_ctx->bitstream)
85
+        return -1;
86
+
87
+    status = ff_vda_decoder_decode(vda_ctx, pic_ctx->bitstream,
88
+                                   pic_ctx->bitstream_size,
89
+                                   frame->reordered_opaque);
90
+
91
+    if (status)
92
+        av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%d)\n", status);
93
+
94
+    av_freep(&pic_ctx->bitstream);
95
+
96
+    return status;
97
+}
98
+
99
+AVHWAccel ff_h264_vda_hwaccel = {
100
+    .name           = "h264_vda",
101
+    .type           = AVMEDIA_TYPE_VIDEO,
102
+    .id             = CODEC_ID_H264,
103
+    .pix_fmt        = PIX_FMT_VDA_VLD,
104
+    .capabilities   = 0,
105
+    .start_frame    = start_frame,
106
+    .decode_slice   = decode_slice,
107
+    .end_frame      = end_frame,
108
+    .priv_data_size = sizeof(struct vda_picture_context),
109
+};
0 110
new file mode 100644
... ...
@@ -0,0 +1,42 @@
0
+/*
1
+ * VDA hardware acceleration
2
+ *
3
+ * copyright (c) 2011 Sebastien Zwickert
4
+ *
5
+ * This file is part of Libav.
6
+ *
7
+ * Libav is free software; you can redistribute it and/or
8
+ * modify it under the terms of the GNU Lesser General Public
9
+ * License as published by the Free Software Foundation; either
10
+ * version 2.1 of the License, or (at your option) any later version.
11
+ *
12
+ * Libav is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
+ * Lesser General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU Lesser General Public
18
+ * License along with Libav; if not, write to the Free Software
19
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
+ */
21
+
22
+#ifndef AVCODEC_VDA_INTERNAL_H
23
+#define AVCODEC_VDA_INTERNAL_H
24
+
25
+#include "vda.h"
26
+
27
+/**
28
+ * @addtogroup VDA_Decoding
29
+ *
30
+ * @{
31
+ */
32
+
33
+/** Send frame data to the hardware decoder. */
34
+int ff_vda_decoder_decode(struct vda_context *vda_ctx,
35
+                          uint8_t *bitstream,
36
+                          int bitstream_size,
37
+                          int64_t frame_pts);
38
+
39
+/* @} */
40
+
41
+#endif /* AVCODEC_VDA_INTERNAL_H */
... ...
@@ -21,7 +21,7 @@
21 21
 #define AVCODEC_VERSION_H
22 22
 
23 23
 #define LIBAVCODEC_VERSION_MAJOR 53
24
-#define LIBAVCODEC_VERSION_MINOR 19
24
+#define LIBAVCODEC_VERSION_MINOR 20
25 25
 #define LIBAVCODEC_VERSION_MICRO  0
26 26
 
27 27
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
... ...
@@ -40,7 +40,7 @@
40 40
 #define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c)
41 41
 
42 42
 #define LIBAVUTIL_VERSION_MAJOR 51
43
-#define LIBAVUTIL_VERSION_MINOR 14
43
+#define LIBAVUTIL_VERSION_MINOR 15
44 44
 #define LIBAVUTIL_VERSION_MICRO  0
45 45
 
46 46
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
... ...
@@ -740,6 +740,12 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[PIX_FMT_NB] = {
740 740
         .log2_chroma_h = 1,
741 741
         .flags = PIX_FMT_HWACCEL,
742 742
     },
743
+    [PIX_FMT_VDA_VLD] = {
744
+        .name = "vda_vld",
745
+        .log2_chroma_w = 1,
746
+        .log2_chroma_h = 1,
747
+        .flags = PIX_FMT_HWACCEL,
748
+    },
743 749
     [PIX_FMT_YUV420P9LE] = {
744 750
         .name = "yuv420p9le",
745 751
         .nb_components= 3,
... ...
@@ -147,6 +147,7 @@ enum PixelFormat {
147 147
     PIX_FMT_YUV444P10LE,///< planar YUV 4:4:4, 30bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian
148 148
     PIX_FMT_YUV422P9BE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian
149 149
     PIX_FMT_YUV422P9LE, ///< planar YUV 4:2:2, 18bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian
150
+    PIX_FMT_VDA_VLD,    ///< hardware decoding through VDA
150 151
     PIX_FMT_NB,        ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions
151 152
 };
152 153