[FFmpeg-devel] [RFC/PATCH 8/8] tidsp: process buffers
Felipe Contreras
felipe.contreras
Mon Sep 6 00:15:35 CEST 2010
Now it's fully functional. Could be organized a bit better though.
Signed-off-by: Felipe Contreras <felipe.contreras at gmail.com>
---
libavcodec/tidsp_mpeg4.c | 89 +++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 84 insertions(+), 5 deletions(-)
diff --git a/libavcodec/tidsp_mpeg4.c b/libavcodec/tidsp_mpeg4.c
index 4c72dfb..935a376 100644
--- a/libavcodec/tidsp_mpeg4.c
+++ b/libavcodec/tidsp_mpeg4.c
@@ -9,13 +9,28 @@
*/
#include "tidsp/tidsp.h"
+#include "tidsp/dmm_buffer.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;
@@ -27,6 +42,7 @@ static av_cold int init(AVCodecContext *avctx)
td_ctx->codec = &td_mp4v_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);
@@ -46,16 +62,79 @@ static av_cold int close(AVCodecContext *avctx)
return 0;
}
-static int start_frame(av_unused AVCodecContext *avctx,
- av_unused const uint8_t *buffer,
- av_unused uint32_t size)
+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->size = size;
+ td_send_buffer(ctx->td_ctx, b);
+
return 0;
}
-static int end_frame(av_unused AVCodecContext *avctx)
+static int end_frame(AVCodecContext *avctx)
{
- return 0;
+ 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,
--
1.7.2.2
More information about the ffmpeg-devel
mailing list