Hi, I've made two small patches to let cinelerra make use of swscale from ffmpeg when possible. This should fix bug #390.
There are two patches : the core one, swscale_ffmpeg.patch that applies
to cinelerra/ffmpeg.{C,h} and uses swscale api rather than the old
img_convert one, that has been declared as deprecated by ffmpeg
devs lately.
This will allow cinelerra to use newest ffmpeg's versions with swscaler
enabled, which seems to be the way ffmpeg is going.
With this patch, cinelerra scales finely yuv4mpeg imported files ;)
The other one, applies to configure.in and adds the needed checks :
if swscale is enabled in ffmpeg, it will not be possible to link
against img_convert, thus it defines HAVE_SWSCALER if (and
only if) img_convert is not present.
Those ugly checks are not needed with recent ffmpeg versions, it
is sufficient to always enable swscale because even if it has been
disabled at ffmpeg compile time, ffmpeg wraps swscale calls to the old
img_convert api.
But I think those checks are better for now rather than always enabling
swscale with external ffmpeg because older ffmpeg versions might not
wrap, or not correctly, swscale calls.
Regards,
Alexis.
Index: configure.in
===================================================================
--- configure.in (revision 1004)
+++ configure.in (working copy)
@@ -324,10 +324,31 @@
############ external ffmpeg
AC_ARG_WITH([external-ffmpeg], AC_HELP_STRING([--with-external-ffmpeg], [use external ffmpeg library]))
+AH_TEMPLATE(HAVE_SWSCALER, [Define to 1 if swscaler is available in ffmpeg.])
if test "x$with_external_ffmpeg" = "xyes"; then
- PKG_CHECK_MODULES([FFMPEG], [libavcodec libpostproc])
+ PKG_CHECK_MODULES([FFMPEG_TEMP], [libavcodec libpostproc])
FFMPEG_FOLDER=""
FFMPEG_EXTERNALTEXT="External ffmpeg"
+
+ dnl --------------------------------------------------------------
+ dnl check if libavcodec contains img_convert
+ dnl if not, that means that libswscale is compiled in
+
+ AC_MSG_CHECKING(for ffmpeg swscale support)
+ saved_LIBS="$LIBS"
+ LIBS="$saved_LIBS $FFMPEG_TEMP_LIBS"
+ AC_TRY_LINK([#include <ffmpeg/avcodec.h>],
+ [img_convert(0, 0, 0,0,0,0)],
+ enable_ffmpeg_swscale=no,enable_ffmpeg_swscale=yes)
+ LIBS="$saved_LIBS"
+ AC_MSG_RESULT($enable_ffmpeg_swscale)
+
+ if test x"$enable_ffmpeg_swscale" == xyes; then
+ AC_DEFINE(HAVE_SWSCALER)
+ PKG_CHECK_MODULES([FFMPEG], [libavcodec libpostproc libswscale])
+ else
+ PKG_CHECK_MODULES([FFMPEG], [libavcodec libpostproc])
+ fi
else
FFMPEG_FOLDER=ffmpeg
FFMPEG_CFLAGS="-I\$(top_srcdir)/quicktime/ffmpeg/libavcodec"
Index: ffmpeg.C
===================================================================
--- ffmpeg.C (revision 1004)
+++ ffmpeg.C (working copy)
@@ -140,6 +140,11 @@
PixelFormat pix_fmt_out =
color_model_to_pix_fmt(frame_out->get_color_model());
+#ifdef HAVE_SWSCALER
+ // We need a context for swscale
+ struct SwsContext *convert_ctx;
+#endif
+
// do conversion within libavcodec if possible
if (pix_fmt_in != PIX_FMT_NB && pix_fmt_out != PIX_FMT_NB) {
// set up a temporary pictures from frame_in and frame_out
@@ -147,7 +152,9 @@
init_picture_from_frame(&picture_in, frame_in);
init_picture_from_frame(&picture_out, frame_out);
- int result = img_convert(&picture_out,
+ int result;
+#ifndef HAVE_SWSCALER
+ result = img_convert(&picture_out,
pix_fmt_out,
&picture_in,
pix_fmt_in,
@@ -156,6 +163,28 @@
if (result) {
printf("FFMPEG::convert_cmodel img_convert() failed\n");
}
+#else
+ convert_ctx = sws_getContext(frame_in->get_w(), frame_in->get_h(),pix_fmt_in,
+ frame_out->get_w(),frame_out->get_h(),pix_fmt_out,
+ SWS_BICUBIC, NULL, NULL, NULL);
+
+ if(convert_ctx == NULL){
+ printf("FFMPEG::convert_cmodel : swscale context initialization failed\n");
+ return 1;
+ }
+
+ result = sws_scale(convert_ctx,
+ picture_in.data, picture_in.linesize,
+ frame_in->get_w(), frame_in->get_h(),
+ picture_out.data, picture_out.linesize);
+
+
+ sws_freeContext(convert_ctx);
+
+ if(result){
+ printf("FFMPEG::convert_cmodel sws_scale() failed\n");
+ }
+#endif
return result;
}
@@ -203,13 +232,19 @@
// set up a temporary picture_out from frame_out
AVPicture picture_out;
+#ifdef HAVE_SWSCALER
+ // We need a context for swscale
+ struct SwsContext *convert_ctx;
+#endif
init_picture_from_frame(&picture_out, frame_out);
int cmodel_out = frame_out->get_color_model();
PixelFormat pix_fmt_out = color_model_to_pix_fmt(cmodel_out);
// do conversion within libavcodec if possible
if (pix_fmt_out != PIX_FMT_NB) {
- int result = img_convert(&picture_out,
+ int result;
+#ifndef HAVE_SWSCALER
+ result = img_convert(&picture_out,
pix_fmt_out,
picture_in,
pix_fmt_in,
@@ -218,6 +253,28 @@
if (result) {
printf("FFMPEG::convert_cmodel img_convert() failed\n");
}
+#else
+ convert_ctx = sws_getContext(width_in, height_in,pix_fmt_in,
+ frame_out->get_w(),frame_out->get_h(),pix_fmt_out,
+ SWS_BICUBIC, NULL, NULL, NULL);
+
+ if(convert_ctx == NULL){
+ printf("FFMPEG::convert_cmodel : swscale context initialization failed\n");
+ return 1;
+ }
+
+ result = sws_scale(convert_ctx,
+ picture_in->data, picture_in->linesize,
+ width_in, height_in,
+ picture_out.data, picture_out.linesize);
+
+
+ sws_freeContext(convert_ctx);
+
+ if(result){
+ printf("FFMPEG::convert_cmodel sws_scale() failed\n");
+ }
+#endif
return result;
}
Index: ffmpeg.h
===================================================================
--- ffmpeg.h (revision 1004)
+++ ffmpeg.h (working copy)
@@ -2,6 +2,9 @@
#define FFMPEG_H
#include <avcodec.h>
+#ifdef HAVE_SWSCALER
+#include <swscale.h>
+#endif
#include "asset.h"
#include "guicast.h"
pgpoArF89jKxK.pgp
Description: PGP signature
