Notice the library is called libtidsp, and the name libtidspbridge is abusrdly long, inconvenient, and inconsistent with the actual library name, but that's what was requested on the mailing list.
Signed-off-by: Felipe Contreras <[email protected]> --- configure | 5 ++ libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 1 + libavcodec/tidspbridge_mpeg4.c | 173 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 180 insertions(+) create mode 100644 libavcodec/tidspbridge_mpeg4.c diff --git a/configure b/configure index 6278b9a..b56c357 100755 --- a/configure +++ b/configure @@ -105,6 +105,7 @@ Configuration options: --disable-lpc disable LPC code --disable-mdct disable MDCT code --disable-rdft disable RDFT code + --enable-tidspbridge enable TIDSPBRIDGE code --enable-vaapi enable VAAPI code --enable-vda enable VDA code --enable-vdpau enable VDPAU code @@ -985,6 +986,7 @@ CONFIG_LIST=" swscale swscale_alpha thumb + tidspbridge vaapi vda vdpau @@ -1341,6 +1343,7 @@ mpeg2_vaapi_hwaccel_select="vaapi mpeg2video_decoder" mpeg2video_encoder_select="aandct" mpeg4_decoder_select="h263_decoder mpeg4video_parser" mpeg4_encoder_select="h263_encoder" +mpeg4_tidspbridge_hwaccel_select="tidspbridge mpeg4_decoder" mpeg4_vaapi_hwaccel_select="vaapi mpeg4_decoder" mpeg4_vdpau_decoder_select="vdpau mpeg4_decoder" msmpeg4v1_decoder_select="h263_decoder" @@ -2917,6 +2920,7 @@ done check_lib math.h sin -lm && LIBM="-lm" enabled vaapi && require vaapi va/va.h vaInitialize -lva +enabled tidspbridge && require_pkg_config libtidsp tidsp.h td_init check_mathfunc exp2 check_mathfunc exp2f @@ -3224,6 +3228,7 @@ echo "threading support ${thread_type-no}" echo "safe bitstream reader ${safe_bitstream_reader-no}" echo "SDL support ${sdl-no}" echo "libdxva2 enabled ${dxva2-no}" +echo "libtidspbridge enabled ${tidspbridge-no}" echo "libva enabled ${vaapi-no}" echo "libvdpau enabled ${vdpau-no}" echo "AVISynth enabled ${avisynth-no}" diff --git a/libavcodec/Makefile b/libavcodec/Makefile index b177450..276eed1 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -268,6 +268,7 @@ OBJS-$(CONFIG_MPEG2VIDEO_ENCODER) += mpeg12enc.o mpegvideo_enc.o \ motion_est.o ratecontrol.o \ mpeg12.o mpeg12data.o \ mpegvideo.o error_resilience.o +OBJS-$(CONFIG_MPEG4_TIDSPBRIDGE_HWACCEL) += tidspbridge_mpeg4.o OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL) += vaapi_mpeg4.o OBJS-$(CONFIG_MSMPEG4V1_DECODER) += msmpeg4.o msmpeg4data.o OBJS-$(CONFIG_MSMPEG4V2_DECODER) += msmpeg4.o msmpeg4data.o h263dec.o \ diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 3d3289c..6fc4690 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -60,6 +60,7 @@ void avcodec_register_all(void) REGISTER_HWACCEL (H264_VDA, h264_vda); REGISTER_HWACCEL (MPEG2_DXVA2, mpeg2_dxva2); REGISTER_HWACCEL (MPEG2_VAAPI, mpeg2_vaapi); + REGISTER_HWACCEL (MPEG4_TIDSPBRIDGE, mpeg4_tidspbridge); REGISTER_HWACCEL (MPEG4_VAAPI, mpeg4_vaapi); REGISTER_HWACCEL (VC1_DXVA2, vc1_dxva2); REGISTER_HWACCEL (VC1_VAAPI, vc1_vaapi); diff --git a/libavcodec/tidspbridge_mpeg4.c b/libavcodec/tidspbridge_mpeg4.c new file mode 100644 index 0000000..77ee448 --- /dev/null +++ b/libavcodec/tidspbridge_mpeg4.c @@ -0,0 +1,173 @@ +/* + * MPEG-4 / H.263 HW decode acceleration through TI DSP + * + * 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 <tidsp.h> + +#include "avcodec.h" +#include "internal.h" +#include "mpegvideo.h" + +struct td_av_context { + struct td_context *td_ctx; + struct td_buffer *output_buffer; +}; + +static void handle_buffer(struct td_context *td_ctx, struct td_buffer *b) +{ + AVCodecContext *avctx = td_ctx->client; + struct td_av_context *ctx = avctx->internal->hwaccel_private; + + if (b->port->id == 0) + return; + if (ctx->output_buffer) + av_log(avctx, AV_LOG_ERROR, "overriding buffer\n"); + ctx->output_buffer = b; +} + +static av_cold int init(AVCodecContext *avctx) +{ + struct td_av_context *ctx; + struct td_context *td_ctx; + + avctx->internal->hwaccel_private = ctx = av_mallocz(sizeof(*ctx)); + if (!ctx) + return -1; + ctx->td_ctx = td_ctx = td_new(avctx); + + td_ctx->codec = &td_mp4vdec_codec; + td_ctx->width = avctx->width; + td_ctx->height = avctx->height; + td_ctx->handle_buffer = handle_buffer; + + if (!td_init(ctx->td_ctx)) { + av_freep(&avctx->internal->hwaccel_private); + return -1; + } + return 0; +} + +static av_cold int close(AVCodecContext *avctx) +{ + struct td_av_context *ctx = avctx->internal->hwaccel_private; + + td_close(ctx->td_ctx); + td_free(ctx->td_ctx); + av_freep(&avctx->internal->hwaccel_private); + + return 0; +} + +static int start_frame(AVCodecContext *avctx, const uint8_t *buffer, + uint32_t size) +{ + struct td_av_context *ctx = avctx->internal->hwaccel_private; + struct td_port *p; + struct td_buffer *b; + + p = ctx->td_ctx->ports[0]; + + b = &p->buffers[0]; + if (b->used) + b = &p->buffers[1]; + if (b->used) + return -1; + + memcpy(b->data->data, buffer, size); + b->data->len = size; + td_send_buffer(ctx->td_ctx, b); + + return 0; +} + +static int end_frame(AVCodecContext *avctx) +{ + struct td_av_context *ctx = avctx->internal->hwaccel_private; + MpegEncContext *s = avctx->priv_data; + AVFrame *f; + uint8_t *p1, *p2, *p3; + unsigned i; + int ret = -1; + struct td_port *p; + struct td_buffer *b; + bool ready; + +again: + if (!td_get_event(ctx->td_ctx)) + goto leave; + + b = ctx->output_buffer; + if (!b) + goto leave; + + ctx->output_buffer = NULL; + f = &s->current_picture.f; + + p1 = b->data->data; + p2 = p1 + avctx->width * avctx->height; + p3 = p2 + (avctx->width * avctx->height / 4); + + for (i = 0; i < avctx->height; i++) + memcpy(f->data[0] + i * f->linesize[0], p1 + i * avctx->width, + avctx->width); + for (i = 0; i < avctx->height / 2; i++) + memcpy(f->data[1] + i * f->linesize[1], p2 + i * avctx->width / 2, + avctx->width / 2); + for (i = 0; i < avctx->height / 2; i++) + memcpy(f->data[2] + i * f->linesize[2], p3 + i * avctx->width / 2, + avctx->width / 2); + + td_send_buffer(ctx->td_ctx, b); + + ret = 0; + +leave: + + p = ctx->td_ctx->ports[0]; + ready = false; + for (i = 0; i < p->nr_buffers; i++) { + if (!p->buffers[i].used) { + ready = true; + break; + } + } + if (!ready) + goto again; + + return ret; +} + +static int decode_slice(av_unused AVCodecContext *avctx, + av_unused const uint8_t *buffer, + av_unused uint32_t size) +{ + return 0; +} + +AVHWAccel ff_mpeg4_tidspbridge_hwaccel = { + .name = "mpeg4_tidspbridge", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_MPEG4, + .pix_fmt = PIX_FMT_YUV420P, + .start_frame = start_frame, + .end_frame = end_frame, + .decode_slice = decode_slice, + .init = init, + .close = close, +}; -- 1.7.9.2 _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
