Merge commit '36ef5369ee9b336febc2c270f8718cec4476cb85'
[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 "h264.h"
24 #include "vda_internal.h"
25
26 static int start_frame(AVCodecContext *avctx,
27                        av_unused const uint8_t *buffer,
28                        av_unused uint32_t size)
29 {
30     struct vda_context *vda_ctx = avctx->hwaccel_context;
31
32     if (!vda_ctx->decoder)
33         return -1;
34
35     vda_ctx->bitstream_size = 0;
36
37     return 0;
38 }
39
40 static int decode_slice(AVCodecContext *avctx,
41                         const uint8_t *buffer,
42                         uint32_t size)
43 {
44     struct vda_context *vda_ctx = avctx->hwaccel_context;
45     void *tmp;
46
47     if (!vda_ctx->decoder)
48         return -1;
49
50     tmp = av_fast_realloc(vda_ctx->bitstream, &vda_ctx->ref_size, vda_ctx->bitstream_size+size+4);
51     if (!tmp)
52         return AVERROR(ENOMEM);
53
54     vda_ctx->bitstream = tmp;
55
56     AV_WB32(vda_ctx->bitstream+vda_ctx->bitstream_size, size);
57     memcpy(vda_ctx->bitstream+vda_ctx->bitstream_size+4, buffer, size);
58
59     vda_ctx->bitstream_size += size + 4;
60
61     return 0;
62 }
63
64 static int end_frame(AVCodecContext *avctx)
65 {
66     H264Context *h = avctx->priv_data;
67     struct vda_context *vda_ctx = avctx->hwaccel_context;
68     AVFrame *frame = &h->s.current_picture_ptr->f;
69     int status;
70
71     if (!vda_ctx->decoder || !vda_ctx->bitstream)
72         return -1;
73
74     status = ff_vda_decoder_decode(vda_ctx, vda_ctx->bitstream,
75                                    vda_ctx->bitstream_size,
76                                    frame->reordered_opaque);
77
78     if (status)
79         av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%d)\n", status);
80
81     return status;
82 }
83
84 AVHWAccel ff_h264_vda_hwaccel = {
85     .name           = "h264_vda",
86     .type           = AVMEDIA_TYPE_VIDEO,
87     .id             = AV_CODEC_ID_H264,
88     .pix_fmt        = PIX_FMT_VDA_VLD,
89     .start_frame    = start_frame,
90     .decode_slice   = decode_slice,
91     .end_frame      = end_frame,
92     .priv_data_size = 0,
93 };