Signed-off-by: Felipe Contreras <[email protected]>
---
 configure                |    5 ++
 libavcodec/Makefile      |    1 +
 libavcodec/allcodecs.c   |    1 +
 libavcodec/tidsp_mpeg4.c |  156 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 163 insertions(+)
 create mode 100644 libavcodec/tidsp_mpeg4.c

diff --git a/configure b/configure
index 6278b9a..9b7f8e1 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-tidsp           enable TIDSP 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
+    tidsp
     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_tidsp_hwaccel_select="tidsp 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 tidsp && 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 "libtidsp enabled          ${tidsp-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..5865f15 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_TIDSP_HWACCEL)     += tidsp_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..58f95d1 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_TIDSP, mpeg4_tidsp);
     REGISTER_HWACCEL (MPEG4_VAAPI, mpeg4_vaapi);
     REGISTER_HWACCEL (VC1_DXVA2, vc1_dxva2);
     REGISTER_HWACCEL (VC1_VAAPI, vc1_vaapi);
diff --git a/libavcodec/tidsp_mpeg4.c b/libavcodec/tidsp_mpeg4.c
new file mode 100644
index 0000000..42327ab
--- /dev/null
+++ b/libavcodec/tidsp_mpeg4.c
@@ -0,0 +1,156 @@
+/*
+ * MPEG-4 / H.263 HW decode acceleration through TI DSP
+ *
+ * This file is part of FFmpeg.
+ *
+ * This file may be used under the terms of the GNU Lesser General Public
+ * License version 2.1, a copy of which is found in COPYING.LGPLv2.1 included
+ * in the packaging of this file.
+ */
+
+#include <tidsp.h>
+
+#include "avcodec.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->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->hwaccel_private = ctx = av_mallocz(sizeof(*ctx));
+       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->hwaccel_private);
+               return -1;
+       }
+       return 0;
+}
+
+static av_cold int close(AVCodecContext *avctx)
+{
+       struct td_av_context *ctx = avctx->hwaccel_private;
+
+       td_close(ctx->td_ctx);
+       td_free(ctx->td_ctx);
+       av_freep(&avctx->hwaccel_private);
+
+       return 0;
+}
+
+static int start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t 
size)
+{
+       struct td_av_context *ctx = avctx->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->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 = (AVFrame*) &s->current_picture;
+
+       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_tidsp_hwaccel = {
+       .name = "mpeg4_tidsp",
+       .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

Reply via email to