Libav
vda_h264.c
Go to the documentation of this file.
1 /*
2  * VDA H.264 hardware acceleration
3  *
4  * copyright (c) 2011 Sebastien Zwickert
5  *
6  * This file is part of Libav.
7  *
8  * Libav is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * Libav is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with Libav; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include <CoreFoundation/CFNumber.h>
24 #include <CoreFoundation/CFData.h>
25 #include <CoreFoundation/CFString.h>
26 
27 #include "libavutil/avutil.h"
28 #include "h264.h"
29 #include "vda.h"
30 
31 /* Decoder callback that adds the VDA frame to the queue in display order. */
32 static void vda_decoder_callback(void *vda_hw_ctx,
33  CFDictionaryRef user_info,
34  OSStatus status,
35  uint32_t infoFlags,
36  CVImageBufferRef image_buffer)
37 {
38  struct vda_context *vda_ctx = vda_hw_ctx;
39 
40  if (!image_buffer)
41  return;
42 
43  if (vda_ctx->cv_pix_fmt_type != CVPixelBufferGetPixelFormatType(image_buffer))
44  return;
45 
46  vda_ctx->cv_buffer = CVPixelBufferRetain(image_buffer);
47 }
48 
49 static int vda_sync_decode(struct vda_context *vda_ctx)
50 {
51  OSStatus status;
52  CFDataRef coded_frame;
53  uint32_t flush_flags = 1 << 0;
54 
55  coded_frame = CFDataCreate(kCFAllocatorDefault,
56  vda_ctx->priv_bitstream,
57  vda_ctx->priv_bitstream_size);
58 
59  status = VDADecoderDecode(vda_ctx->decoder, 0, coded_frame, NULL);
60 
61  if (kVDADecoderNoErr == status)
62  status = VDADecoderFlush(vda_ctx->decoder, flush_flags);
63 
64  CFRelease(coded_frame);
65 
66  return status;
67 }
68 
69 
71  av_unused const uint8_t *buffer,
72  av_unused uint32_t size)
73 {
74  struct vda_context *vda_ctx = avctx->hwaccel_context;
75 
76  if (!vda_ctx->decoder)
77  return -1;
78 
79  vda_ctx->priv_bitstream_size = 0;
80 
81  return 0;
82 }
83 
85  const uint8_t *buffer,
86  uint32_t size)
87 {
88  struct vda_context *vda_ctx = avctx->hwaccel_context;
89  void *tmp;
90 
91  if (!vda_ctx->decoder)
92  return -1;
93 
94  tmp = av_fast_realloc(vda_ctx->priv_bitstream,
95  &vda_ctx->priv_allocated_size,
96  vda_ctx->priv_bitstream_size + size + 4);
97  if (!tmp)
98  return AVERROR(ENOMEM);
99 
100  vda_ctx->priv_bitstream = tmp;
101 
102  AV_WB32(vda_ctx->priv_bitstream + vda_ctx->priv_bitstream_size, size);
103  memcpy(vda_ctx->priv_bitstream + vda_ctx->priv_bitstream_size + 4, buffer, size);
104 
105  vda_ctx->priv_bitstream_size += size + 4;
106 
107  return 0;
108 }
109 
111 {
112  H264Context *h = avctx->priv_data;
113  struct vda_context *vda_ctx = avctx->hwaccel_context;
114  AVFrame *frame = &h->cur_pic_ptr->f;
115  int status;
116 
117  if (!vda_ctx->decoder || !vda_ctx->priv_bitstream)
118  return -1;
119 
120  status = vda_sync_decode(vda_ctx);
121  frame->data[3] = (void*)vda_ctx->cv_buffer;
122 
123  if (status)
124  av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%d)\n", status);
125 
126  return status;
127 }
128 
129 int ff_vda_create_decoder(struct vda_context *vda_ctx,
130  uint8_t *extradata,
131  int extradata_size)
132 {
133  OSStatus status = kVDADecoderNoErr;
134  CFNumberRef height;
135  CFNumberRef width;
136  CFNumberRef format;
137  CFDataRef avc_data;
138  CFMutableDictionaryRef config_info;
139  CFMutableDictionaryRef buffer_attributes;
140  CFMutableDictionaryRef io_surface_properties;
141  CFNumberRef cv_pix_fmt;
142 
143  /* Each VCL NAL in the bistream sent to the decoder
144  * is preceded by a 4 bytes length header.
145  * Change the avcC atom header if needed, to signal headers of 4 bytes. */
146  if (extradata_size >= 4 && (extradata[4] & 0x03) != 0x03) {
147  uint8_t *rw_extradata;
148 
149  if (!(rw_extradata = av_malloc(extradata_size)))
150  return AVERROR(ENOMEM);
151 
152  memcpy(rw_extradata, extradata, extradata_size);
153 
154  rw_extradata[4] |= 0x03;
155 
156  avc_data = CFDataCreate(kCFAllocatorDefault, rw_extradata, extradata_size);
157 
158  av_freep(&rw_extradata);
159  } else {
160  avc_data = CFDataCreate(kCFAllocatorDefault, extradata, extradata_size);
161  }
162 
163  config_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
164  4,
165  &kCFTypeDictionaryKeyCallBacks,
166  &kCFTypeDictionaryValueCallBacks);
167 
168  height = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->height);
169  width = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->width);
170  format = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vda_ctx->format);
171 
172  CFDictionarySetValue(config_info, kVDADecoderConfiguration_Height, height);
173  CFDictionarySetValue(config_info, kVDADecoderConfiguration_Width, width);
174  CFDictionarySetValue(config_info, kVDADecoderConfiguration_SourceFormat, format);
175  CFDictionarySetValue(config_info, kVDADecoderConfiguration_avcCData, avc_data);
176 
177  buffer_attributes = CFDictionaryCreateMutable(kCFAllocatorDefault,
178  2,
179  &kCFTypeDictionaryKeyCallBacks,
180  &kCFTypeDictionaryValueCallBacks);
181  io_surface_properties = CFDictionaryCreateMutable(kCFAllocatorDefault,
182  0,
183  &kCFTypeDictionaryKeyCallBacks,
184  &kCFTypeDictionaryValueCallBacks);
185  cv_pix_fmt = CFNumberCreate(kCFAllocatorDefault,
186  kCFNumberSInt32Type,
187  &vda_ctx->cv_pix_fmt_type);
188  CFDictionarySetValue(buffer_attributes,
189  kCVPixelBufferPixelFormatTypeKey,
190  cv_pix_fmt);
191  CFDictionarySetValue(buffer_attributes,
192  kCVPixelBufferIOSurfacePropertiesKey,
193  io_surface_properties);
194 
195  status = VDADecoderCreate(config_info,
196  buffer_attributes,
198  vda_ctx,
199  &vda_ctx->decoder);
200 
201  CFRelease(height);
202  CFRelease(width);
203  CFRelease(format);
204  CFRelease(avc_data);
205  CFRelease(config_info);
206  CFRelease(io_surface_properties);
207  CFRelease(cv_pix_fmt);
208  CFRelease(buffer_attributes);
209 
210  return status;
211 }
212 
214 {
215  OSStatus status = kVDADecoderNoErr;
216 
217  if (vda_ctx->decoder)
218  status = VDADecoderDestroy(vda_ctx->decoder);
219 
220  av_freep(&vda_ctx->priv_bitstream);
221 
222  return status;
223 }
224 
226  .name = "h264_vda",
227  .type = AVMEDIA_TYPE_VIDEO,
228  .id = AV_CODEC_ID_H264,
229  .pix_fmt = AV_PIX_FMT_VDA_VLD,
230  .start_frame = vda_h264_start_frame,
231  .decode_slice = vda_h264_decode_slice,
232  .end_frame = vda_h264_end_frame,
233 };
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:62
int size
This structure describes decoded (raw) audio or video data.
Definition: frame.h:107
static int vda_sync_decode(struct vda_context *vda_ctx)
Definition: vda_h264.c:49
static int vda_h264_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition: vda_h264.c:84
external API header
H264Context.
Definition: h264.h:258
int format
The frame format.
Definition: vda.h:104
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
OSType cv_pix_fmt_type
The pixel format for output image buffers.
Definition: vda.h:112
uint8_t
void * hwaccel_context
Hardware accelerator context.
Definition: avcodec.h:2429
#define AV_WB32(p, d)
Definition: intreadwrite.h:239
int width
The frame width.
Definition: vda.h:88
CVPixelBufferRef cv_buffer
The Core Video pixel buffer that contains the current image data.
Definition: vda.h:72
H.264 / AVC / MPEG4 part10 codec.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:123
static int vda_h264_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size)
Definition: vda_h264.c:70
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given block if it is not large enough, otherwise do nothing.
Definition: mem.c:349
VDADecoder decoder
VDA decoder object.
Definition: vda.h:64
#define AVERROR(e)
Definition: error.h:43
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:148
This structure is used to provide the necessary configurations and data to the VDA Libav HWAccel impl...
Definition: vda.h:57
const char * name
Name of the hardware accelerated codec.
Definition: avcodec.h:2858
static char buffer[20]
Definition: seek-test.c:31
if(ac->has_optimized_func)
NULL
Definition: eval.c:55
static int width
Definition: utils.c:156
AVHWAccel.
Definition: avcodec.h:2852
Public libavcodec VDA header.
int ff_vda_destroy_decoder(struct vda_context *vda_ctx)
Destroy the video decoder.
Definition: vda_h264.c:213
main external API structure.
Definition: avcodec.h:1054
static void vda_decoder_callback(void *vda_hw_ctx, CFDictionaryRef user_info, OSStatus status, uint32_t infoFlags, CVImageBufferRef image_buffer)
Definition: vda_h264.c:32
AVHWAccel ff_h264_vda_hwaccel
Definition: vda_h264.c:225
uint8_t * priv_bitstream
The current bitstream buffer.
Definition: vda.h:117
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:113
int height
Definition: gxfenc.c:72
hardware decoding through VDA
Definition: pixfmt.h:159
static int vda_h264_end_frame(AVCodecContext *avctx)
Definition: vda_h264.c:110
void * priv_data
Definition: avcodec.h:1090
Picture * cur_pic_ptr
Definition: h264.h:271
int ff_vda_create_decoder(struct vda_context *vda_ctx, uint8_t *extradata, int extradata_size)
Create the video decoder.
Definition: vda_h264.c:129
struct AVFrame f
Definition: mpegvideo.h:100
int priv_allocated_size
The reference size used for fast reallocation.
Definition: vda.h:127
int height
The frame height.
Definition: vda.h:96
int priv_bitstream_size
The current size of the bitstream.
Definition: vda.h:122
#define av_unused
Definition: attributes.h:86