summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Stembridge <jstembridge@users.sourceforge.net>2003-03-14 17:46:05 +0000
committerJames Stembridge <jstembridge@users.sourceforge.net>2003-03-14 17:46:05 +0000
commitbc31d1761224b340fdfc0f8bf7f55069fee6ea4f (patch)
treea05ed58397a09cfbecfa5c2bff4d44089eb1f76c
parent298a8fdd0137cb97df44c4730f848f5b881cb4ab (diff)
downloadxine-lib-bc31d1761224b340fdfc0f8bf7f55069fee6ea4f.tar.gz
xine-lib-bc31d1761224b340fdfc0f8bf7f55069fee6ea4f.tar.bz2
mpeg-4 post processing :)
CVS patchset: 4411 CVS date: 2003/03/14 17:46:05
-rw-r--r--src/libffmpeg/Makefile.am3
-rw-r--r--src/libffmpeg/xine_decoder.c141
2 files changed, 135 insertions, 9 deletions
diff --git a/src/libffmpeg/Makefile.am b/src/libffmpeg/Makefile.am
index 0068f18ad..acdfd6c08 100644
--- a/src/libffmpeg/Makefile.am
+++ b/src/libffmpeg/Makefile.am
@@ -19,7 +19,8 @@ lib_LTLIBRARIES = xineplug_decode_ff.la
xineplug_decode_ff_la_SOURCES = xine_decoder.c
xineplug_decode_ff_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@
xineplug_decode_ff_la_LIBADD = $(XINE_LIB) \
- $(top_builddir)/src/libffmpeg/libavcodec/libavcodec.la
+ $(top_builddir)/src/libffmpeg/libavcodec/libavcodec.la \
+ $(top_builddir)/src/libffmpeg/libavcodec/libpostproc/libpostprocess.la
debug:
@list='$(SUBDIRS)'; for subdir in $$list; do \
diff --git a/src/libffmpeg/xine_decoder.c b/src/libffmpeg/xine_decoder.c
index 36988d383..e873c4069 100644
--- a/src/libffmpeg/xine_decoder.c
+++ b/src/libffmpeg/xine_decoder.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xine_decoder.c,v 1.99 2003/03/07 01:22:54 miguelfreitas Exp $
+ * $Id: xine_decoder.c,v 1.100 2003/03/14 17:46:05 jstembridge Exp $
*
* xine decoder plugin using ffmpeg
*
@@ -42,6 +42,7 @@
#include "libavcodec/avcodec.h"
#include "libavcodec/dsputil.h"
+#include "libavcodec/libpostproc/postprocess.h"
/*
#define LOG
@@ -50,11 +51,16 @@
#define SLICE_BUFFER_SIZE (1194 * 1024)
#define abs_float(x) ( ((x)<0) ? -(x) : (x) )
-typedef struct {
+typedef struct ff_video_decoder_s ff_video_decoder_t;
+
+typedef struct ff_video_class_s {
video_decoder_class_t decoder_class;
+
+ ff_video_decoder_t *ip;
+ xine_t *xine;
} ff_video_class_t;
-typedef struct ff_decoder_s {
+struct ff_video_decoder_s {
video_decoder_t video_decoder;
ff_video_class_t *class;
@@ -72,6 +78,12 @@ typedef struct ff_decoder_s {
AVFrame *av_frame;
AVCodecContext *context;
AVCodec *codec;
+
+ int pp_available;
+ int pp_quality;
+ pp_context_t *pp_context;
+ pp_mode_t *pp_mode;
+ uint8_t *pp_data[3];
/* mpeg sequence header parsing, stolen from libmpeg2 */
@@ -88,7 +100,7 @@ typedef struct ff_decoder_s {
int output_format;
yuv_planes_t yuv;
-} ff_video_decoder_t;
+};
typedef struct {
audio_decoder_class_t decoder_class;
@@ -174,6 +186,46 @@ static void init_video_codec (ff_video_decoder_t *this, xine_bmiheader *bih) {
this->output_format = XINE_IMGFMT_YV12;
}
+static void init_postprocess (ff_video_decoder_t *this) {
+ int flags;
+ uint32_t cpu_caps;
+
+ /* Detect what cpu accel we have */
+ cpu_caps = xine_mm_accel();
+ flags = PP_FORMAT_420;
+
+ if(cpu_caps & MM_ACCEL_X86_MMX)
+ flags |= PP_CPU_CAPS_MMX;
+
+ if(cpu_caps & MM_ACCEL_X86_MMXEXT)
+ flags |= PP_CPU_CAPS_MMX2;
+
+ if(cpu_caps & MM_ACCEL_X86_3DNOW)
+ flags |= PP_CPU_CAPS_3DNOW;
+
+ /* Set up post processer */
+ this->pp_context = pp_get_context(this->bih.biWidth, this->bih.biHeight, flags);
+
+ /* Config mode - using libpostproc default minus autolevels */
+ this->pp_mode = pp_get_mode_by_name_and_quality("hb:a,vb:a,dr:a",
+ this->pp_quality);
+}
+
+static void pp_quality_cb(void *user_data, xine_cfg_entry_t *entry) {
+ ff_video_class_t *class = (ff_video_class_t *) user_data;
+
+ if(class->ip) {
+ ff_video_decoder_t *this = class->ip;
+
+ this->pp_quality = entry->num_value;
+ if(this->pp_mode) {
+ pp_free_mode(this->pp_mode);
+ this->pp_mode = pp_get_mode_by_name_and_quality("hb:a,vb:a,dr:a",
+ this->pp_quality);
+ }
+ }
+}
+
static void find_sequence_header (ff_video_decoder_t *this,
uint8_t * current, uint8_t * end){
@@ -431,6 +483,21 @@ static void ff_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
init_video_codec (this, (xine_bmiheader *)buf->content );
+ /* Allow post processing on mpeg-4 (based) codecs */
+ switch(this->codec->id) {
+ case CODEC_ID_MPEG4:
+ case CODEC_ID_MSMPEG4V1:
+ case CODEC_ID_MSMPEG4V2:
+ case CODEC_ID_MSMPEG4V3:
+ case CODEC_ID_WMV1:
+ case CODEC_ID_WMV2:
+ this->pp_available = 1;
+ break;
+ default:
+ this->pp_available = 0;
+ break;
+ }
+
} else if (this->decoder_ok) {
if( this->size + buf->size > this->bufsize ) {
@@ -559,9 +626,32 @@ static void ff_decode_data (video_decoder_t *this_gen, buf_element_t *buf) {
dy = img->base[0];
du = img->base[1];
dv = img->base[2];
- sy = this->av_frame->data[0];
- su = this->av_frame->data[1];
- sv = this->av_frame->data[2];
+
+ if(this->pp_quality > 0 && this->pp_available) {
+ if(this->pp_context == NULL) {
+ init_postprocess(this);
+
+ this->pp_data[0] = xine_xmalloc(this->av_frame->linesize[0] * this->bih.biHeight);
+ this->pp_data[1] = xine_xmalloc(this->av_frame->linesize[1] * this->bih.biHeight / 2);
+ this->pp_data[2] = xine_xmalloc(this->av_frame->linesize[2] * this->bih.biHeight / 2);
+ }
+
+ pp_postprocess(this->av_frame->data, this->av_frame->linesize,
+ this->pp_data, this->av_frame->linesize,
+ this->bih.biWidth, this->bih.biHeight,
+ this->av_frame->qscale_table, this->av_frame->qstride,
+ this->pp_mode, this->pp_context,
+ this->av_frame->pict_type);
+
+ sy = this->pp_data[0];
+ su = this->pp_data[1];
+ sv = this->pp_data[2];
+
+ } else {
+ sy = this->av_frame->data[0];
+ su = this->av_frame->data[1];
+ sv = this->av_frame->data[2];
+ }
if (this->context->pix_fmt == PIX_FMT_YUV410P) {
@@ -795,6 +885,19 @@ static void ff_dispose (video_decoder_t *this_gen) {
if (this->buf)
free(this->buf);
this->buf = NULL;
+
+ if(this->pp_context)
+ pp_free_context(this->pp_context);
+
+ if(this->pp_mode)
+ pp_free_mode(this->pp_mode);
+
+ if(this->pp_data[0])
+ free(this->pp_data[0]);
+ if(this->pp_data[1])
+ free(this->pp_data[1]);
+ if(this->pp_data[2])
+ free(this->pp_data[2]);
free (this->chunk_buffer);
free (this_gen);
@@ -803,6 +906,7 @@ static void ff_dispose (video_decoder_t *this_gen) {
static video_decoder_t *ff_video_open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) {
ff_video_decoder_t *this ;
+ xine_cfg_entry_t quality_entry;
#ifdef LOG
printf ("ffmpeg: open_plugin\n");
@@ -819,6 +923,7 @@ static video_decoder_t *ff_video_open_plugin (video_decoder_class_t *class_gen,
this->stream = stream;
this->class = (ff_video_class_t *) class_gen;
+ this->class->ip = this;
this->chunk_buffer = xine_xmalloc (SLICE_BUFFER_SIZE + 4);
@@ -833,6 +938,16 @@ static video_decoder_t *ff_video_open_plugin (video_decoder_class_t *class_gen,
this->aspect_ratio = 0;
this->xine_aspect_ratio = XINE_VO_ASPECT_DONT_TOUCH;
+ this->pp_context = NULL;
+ this->pp_mode = NULL;
+ this->pp_data[0] = NULL;
+ this->pp_data[1] = NULL;
+ this->pp_data[2] = NULL;
+
+ if(xine_config_lookup_entry(this->class->xine, "codec.ffmpeg_pp_quality",
+ &quality_entry))
+ this->pp_quality = quality_entry.num_value;
+
return &this->video_decoder;
}
@@ -860,6 +975,7 @@ static void init_once_routine(void) {
static void *init_video_plugin (xine_t *xine, void *data) {
ff_video_class_t *this;
+ config_values_t *config;
this = (ff_video_class_t *) malloc (sizeof (ff_video_class_t));
@@ -867,9 +983,18 @@ static void *init_video_plugin (xine_t *xine, void *data) {
this->decoder_class.get_identifier = ff_video_get_identifier;
this->decoder_class.get_description = ff_video_get_description;
this->decoder_class.dispose = ff_video_dispose_class;
+ this->ip = NULL;
+ this->xine = xine;
pthread_once( &once_control, init_once_routine );
+ /* Configuration for post processing quality - default to mid (3) for the
+ * moment */
+ config = xine->config;
+ xine->config->register_range(config, "codec.ffmpeg_pp_quality", 3,
+ 0, PP_QUALITY_MAX, _("ffmpeg mpeg-4 postprocessing quality"), NULL,
+ 10, pp_quality_cb, this);
+
return this;
}
@@ -1171,7 +1296,7 @@ static decoder_info_t dec_info_ffmpeg_audio = {
plugin_info_t xine_plugin_info[] = {
/* type, API, "name", version, special_info, init_function */
- { PLUGIN_VIDEO_DECODER, 14, "ffmpegvideo", XINE_VERSION_CODE, &dec_info_ffmpeg_video, init_video_plugin },
+ { PLUGIN_VIDEO_DECODER | PLUGIN_MUST_PRELOAD, 14, "ffmpegvideo", XINE_VERSION_CODE, &dec_info_ffmpeg_video, init_video_plugin },
{ PLUGIN_AUDIO_DECODER, 13, "ffmpegaudio", XINE_VERSION_CODE, &dec_info_ffmpeg_audio, init_audio_plugin },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};