ffmpeg/libavcodec/vda_h264.c

100 lines
3.0 KiB
C
Raw Normal View History

/*
* VDA H.264 hardware acceleration
*
* copyright (c) 2011 Sebastien Zwickert
*
* This file is part of Libav.
*
* Libav is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* Libav is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "h264.h"
#include "vda_internal.h"
static int start_frame(AVCodecContext *avctx,
av_unused const uint8_t *buffer,
av_unused uint32_t size)
{
struct vda_context *vda_ctx = avctx->hwaccel_context;
if (!vda_ctx->decoder)
return -1;
vda_ctx->priv_bitstream_size = 0;
return 0;
}
static int decode_slice(AVCodecContext *avctx,
const uint8_t *buffer,
uint32_t size)
{
struct vda_context *vda_ctx = avctx->hwaccel_context;
void *tmp;
if (!vda_ctx->decoder)
return -1;
tmp = av_fast_realloc(vda_ctx->priv_bitstream,
&vda_ctx->priv_allocated_size,
vda_ctx->priv_bitstream_size + size + 4);
if (!tmp)
return AVERROR(ENOMEM);
vda_ctx->priv_bitstream = tmp;
AV_WB32(vda_ctx->priv_bitstream + vda_ctx->priv_bitstream_size, size);
memcpy(vda_ctx->priv_bitstream + vda_ctx->priv_bitstream_size + 4, buffer, size);
vda_ctx->priv_bitstream_size += size + 4;
return 0;
}
static int end_frame(AVCodecContext *avctx)
{
H264Context *h = avctx->priv_data;
struct vda_context *vda_ctx = avctx->hwaccel_context;
AVFrame *frame = &h->s.current_picture_ptr->f;
int status;
if (!vda_ctx->decoder || !vda_ctx->priv_bitstream)
return -1;
if (vda_ctx->use_sync_decoding) {
status = ff_vda_sync_decode(vda_ctx);
frame->data[3] = (void*)vda_ctx->cv_buffer;
} else {
status = ff_vda_decoder_decode(vda_ctx, vda_ctx->priv_bitstream,
vda_ctx->priv_bitstream_size,
frame->reordered_opaque);
}
if (status)
av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%d)\n", status);
return status;
}
AVHWAccel ff_h264_vda_hwaccel = {
.name = "h264_vda",
.type = AVMEDIA_TYPE_VIDEO,
.id = AV_CODEC_ID_H264,
.pix_fmt = PIX_FMT_VDA_VLD,
.start_frame = start_frame,
.decode_slice = decode_slice,
.end_frame = end_frame,
};