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

Reply via email to