[gegl] ff-load: accept more pix_format outputs
- From: Øyvind Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl] ff-load: accept more pix_format outputs
- Date: Fri, 27 Nov 2015 14:26:31 +0000 (UTC)
commit 477f001be396ec3df676b1c715232e4d91ed77bc
Author: Øyvind Kolås <pippin gimp org>
Date: Fri Nov 27 15:25:40 2015 +0100
ff-load: accept more pix_format outputs
operations/external/ff-load.c | 86 ++++++++++++++++++++++-------------------
1 files changed, 46 insertions(+), 40 deletions(-)
---
diff --git a/operations/external/ff-load.c b/operations/external/ff-load.c
index c62993d..63ca9dc 100644
--- a/operations/external/ff-load.c
+++ b/operations/external/ff-load.c
@@ -55,6 +55,8 @@ property_audio_fragment (audio, _("audio"), 0)
#include <errno.h>
#include <libavformat/avformat.h>
+#include <libswscale/swscale.h>
+
typedef struct
{
@@ -81,6 +83,7 @@ typedef struct
AVStream *audio_stream;
AVCodec *video_codec;
AVFrame *lavc_frame;
+ AVFrame *rgb_frame;
glong prevframe; /* previously decoded frame number */
gdouble prevpts; /* timestamp in seconds of last decoded frame */
@@ -135,12 +138,15 @@ ff_cleanup (GeglProperties *o)
avformat_close_input(&p->video_fcontext);
if (p->audio_fcontext)
avformat_close_input(&p->audio_fcontext);
+ if (p->rgb_frame)
+ av_free (p->rgb_frame);
if (p->lavc_frame)
av_free (p->lavc_frame);
p->video_fcontext = NULL;
p->audio_fcontext = NULL;
p->lavc_frame = NULL;
+ p->rgb_frame = NULL;
p->loadedfilename = NULL;
}
}
@@ -374,9 +380,10 @@ AV_TIME_BASE_Q) * 1.0 / AV_TIME_BASE ;
decodeframe = roundf ( p->prevpts * o->frame_rate);
}
}
-
+#if 0
if (decoded_bytes != pkt.size)
fprintf (stderr, "bytes left!\n");
+#endif
av_free_packet (&pkt);
}
while (!got_picture);
@@ -399,8 +406,7 @@ prepare (GeglOperation *operation)
g_assert (o->user_data != NULL);
- gegl_operation_set_format (operation, "output", babl_format ("R'G'B'A u8"));
-
+ gegl_operation_set_format (operation, "output", babl_format ("R'G'B' u8"));
if (!p->loadedfilename ||
strcmp (p->loadedfilename, o->path))
@@ -642,6 +648,27 @@ static void get_sample_data (Priv *p, long sample_no, float *left, float *right)
*right = 0;
}
+static AVFrame *
+alloc_picture (int pix_fmt, int width, int height)
+{
+ AVFrame *picture;
+ uint8_t *picture_buf;
+ int size;
+
+ picture = av_frame_alloc ();
+ if (!picture)
+ return NULL;
+ size = avpicture_get_size (pix_fmt, width + 1, height + 1);
+ picture_buf = malloc (size);
+ if (!picture_buf)
+ {
+ av_free (picture);
+ return NULL;
+ }
+ avpicture_fill ((AVPicture *) picture, picture_buf, pix_fmt, width, height);
+ return picture;
+}
+
static gboolean
process (GeglOperation *operation,
GeglBuffer *output,
@@ -654,10 +681,6 @@ process (GeglOperation *operation,
{
if (p->video_fcontext && !decode_frame (operation, o->frame))
{
- guchar *buf;
- gint pxsize = 4;
- gint x,y;
-
long sample_start = 0;
if (p->audio_stream && p->audio_stream->codec) // XXX: remove second clause
@@ -683,42 +706,25 @@ process (GeglOperation *operation,
}
}
- buf = g_new (guchar, p->width * p->height * pxsize);
-
- for (y=0; y < p->height; y++)
- {
- guchar *dst = buf + y * p->width * 4;
- const guchar *ysrc = p->lavc_frame->data[0] + y * p->lavc_frame->linesize[0];
- const guchar *usrc = p->lavc_frame->data[1] + y / 2 * p->lavc_frame->linesize[1];
- const guchar *vsrc = p->lavc_frame->data[2] + y / 2 * p->lavc_frame->linesize[2];
-
- for (x=0;x < p->width; x++)
- {
- gint R,G,B;
-#ifndef byteclamp
-#define byteclamp(j) j=j<0?0:j>255?255:j
-#endif
-#define YUV82RGB8(Y,U,V,R,G,B)do{\
- R= ((Y<<15) + 37355*(V-128))>>15;\
- G= ((Y<<15) -12911* (U-128) - 19038*(V-128))>>15;\
- B= ((Y<<15) +66454* (U-128) )>>15;\
- byteclamp(R);\
- byteclamp(G);\
- byteclamp(B);\
- } while(0)
- YUV82RGB8 (*ysrc, *usrc, *vsrc, R, G, B);
- *(unsigned int *) dst = R + G * 256 + B * 256 * 256 + 0xff000000;
- dst += 4;
- usrc += x%2;
- vsrc += x%2;
- ysrc ++;
- }
- }
+ if (p->video_stream->codec->pix_fmt == AV_PIX_FMT_RGB24)
{
GeglRectangle extent = {0,0,p->width,p->height};
- gegl_buffer_set (output, &extent, 0, NULL, buf, GEGL_AUTO_ROWSTRIDE);
+ gegl_buffer_set (output, &extent, 0, babl_format("R'G'B' u8"), p->lavc_frame->data[0],
GEGL_AUTO_ROWSTRIDE);
+ }
+ else
+ {
+ struct SwsContext *img_convert_ctx;
+ GeglRectangle extent = {0,0,p->width,p->height};
+
+ img_convert_ctx = sws_getContext(p->width, p->height, p->video_stream->codec->pix_fmt,
+ p->width, p->height, AV_PIX_FMT_RGB24,
+ SWS_BICUBIC, NULL, NULL, NULL);
+ p->rgb_frame = alloc_picture (AV_PIX_FMT_RGB24, p->width, p->height);
+ sws_scale (img_convert_ctx, (void*)p->lavc_frame->data,
+ p->lavc_frame->linesize, 0, p->height, p->rgb_frame->data, p->rgb_frame->linesize);
+ gegl_buffer_set (output, &extent, 0, babl_format("R'G'B' u8"), p->rgb_frame->data[0],
GEGL_AUTO_ROWSTRIDE);
+ sws_freeContext (img_convert_ctx);
}
- g_free (buf);
}
}
return TRUE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]