1 /*
2 * Copyright (c) 2012, Xidorn Quan
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * @file
23 * H.264 decoder via VDA
24 * @author Xidorn Quan <quanxunzhen@gmail.com>
25 */
26
27 #include <string.h>
28 #include <CoreFoundation/CoreFoundation.h>
29
33
34 #ifndef kCFCoreFoundationVersionNumber10_7
35 #define kCFCoreFoundationVersionNumber10_7 635.00
36 #endif
37
39
44 };
45
52 };
53
59
60 /* for backing-up fields set by user.
61 * we have to gain full control of such fields here */
65 #if FF_API_GET_BUFFER
67 #endif
69
72 {
74 }
75
79
81 {
83 CVPixelBufferUnlockBaseAddress(context->
cv_buffer, 0);
86 }
87
89 {
92 if (!context || !buffer) {
95 }
96
98 pic->
data[0] = (
void *)1;
99 return 0;
100 }
101
103 {
111 #if FF_API_GET_BUFFER
114 #endif
115 }
116
118 {
123 #if FF_API_GET_BUFFER
125 #endif
126 }
127
130 {
134
136 ret = ff_h264_decoder.
decode(avctx, data, got_frame, avpkt);
138 if (*got_frame) {
141 CVPixelBufferRef cv_buffer = (CVPixelBufferRef)pic->
data[3];
142
143 CVPixelBufferRetain(cv_buffer);
144 CVPixelBufferLockBaseAddress(cv_buffer, 0);
147 if (CVPixelBufferIsPlanar(cv_buffer)) {
148 int i,
count = CVPixelBufferGetPlaneCount(cv_buffer);
150 for (i = 0; i <
count; i++) {
151 pic->
data[i] = CVPixelBufferGetBaseAddressOfPlane(cv_buffer, i);
152 pic->
linesize[i] = CVPixelBufferGetBytesPerRowOfPlane(cv_buffer, i);
153 }
154 } else {
155 pic->
data[0] = CVPixelBufferGetBaseAddress(cv_buffer);
156 pic->
linesize[0] = CVPixelBufferGetBytesPerRow(cv_buffer);
157 }
158 }
160
162 }
163
165 {
167 /* release buffers and decoder */
169 /* close H.264 decoder */
172 ff_h264_decoder.
close(avctx);
174 }
175 return 0;
176 }
177
179 {
182 OSStatus status;
184
186
187 /* init pix_fmts of codec */
188 if (!ff_h264_vda_decoder.
pix_fmts) {
191 else
193 }
194
195 /* init vda */
206 break;
209 break;
212 break;
215 break;
216 default:
218 goto failed;
219 }
222 if (status != kVDADecoderNoErr) {
224 "Failed to init VDA decoder: %d.\n", status);
225 goto failed;
226 }
227
228 /* init H.264 decoder */
230 ret = ff_h264_decoder.
init(avctx);
232 if (ret < 0) {
234 goto failed;
235 }
237
244 goto failed;
245 }
246 }
247
248 return 0;
249
250 failed:
252 return -1;
253 }
254
256 {
258 ff_h264_decoder.
flush(avctx);
260 }
261
273 };