vda: use fast reallocation.
[ffmpeg.git] / libavcodec / vda_h264.c
1 /*
2  * VDA H264 HW acceleration.
3  *
4  * copyright (c) 2011 Sebastien Zwickert
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg 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  * FFmpeg 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 FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22
23 #include "vda_internal.h"
24
25 static int start_frame(AVCodecContext *avctx,
26                        av_unused const uint8_t *buffer,
27                        av_unused uint32_t size)
28 {
29     struct vda_context *vda_ctx = avctx->hwaccel_context;
30
31     if (!vda_ctx->decoder)
32         return -1;
33
34     vda_ctx->bitstream_size = 0;
35
36     return 0;
37 }
38
39 static int decode_slice(AVCodecContext *avctx,
40                         const uint8_t *buffer,
41                         uint32_t size)
42 {
43     struct vda_context *vda_ctx = avctx->hwaccel_context;
44     void *tmp;
45
46     if (!vda_ctx->decoder)
47         return -1;
48
49     tmp = av_fast_realloc(vda_ctx->bitstream, &vda_ctx->ref_size, vda_ctx->bitstream_size+size+4);
50     if (!tmp)
51         return AVERROR(ENOMEM);
52
53     vda_ctx->bitstream = tmp;
54
55     AV_WB32(vda_ctx->bitstream+vda_ctx->bitstream_size, size);
56     memcpy(vda_ctx->bitstream+vda_ctx->bitstream_size+4, buffer, size);
57
58     vda_ctx->bitstream_size += size + 4;
59
60     return 0;
61 }
62
63 static int end_frame(AVCodecContext *avctx)
64 {
65     H264Context *h = avctx->priv_data;
66     struct vda_context *vda_ctx = avctx->hwaccel_context;
67     AVFrame *frame = (AVFrame*)h->s.current_picture_ptr;
68     int status;
69
70     if (!vda_ctx->decoder || !vda_ctx->bitstream)
71         return -1;
72
73     status = ff_vda_decoder_decode(vda_ctx, vda_ctx->bitstream,
74                                    vda_ctx->bitstream_size,
75                                    frame->reordered_opaque);
76
77     if (status)
78         av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%d)\n", status);
79
80     return status;
81 }
82
83 AVHWAccel ff_h264_vda_hwaccel = {
84     .name           = "h264_vda",
85     .type           = AVMEDIA_TYPE_VIDEO,
86     .id             = CODEC_ID_H264,
87     .pix_fmt        = PIX_FMT_VDA_VLD,
88     .capabilities   = 0,
89     .start_frame    = start_frame,
90     .decode_slice   = decode_slice,
91     .end_frame      = end_frame,
92     .priv_data_size = 0,
93 };