00001
00002
00003
00004
00005 #include <stdio.h>
00006 #include <stdlib.h>
00007 #include <unistd.h>
00008
00009 #include "mythconfig.h"
00010
00011 #if HAVE_STDINT_H
00012 #include <stdint.h>
00013 #endif
00014
00015 #include "libavcodec/avcodec.h"
00016 #include "filter.h"
00017 #include "frame.h"
00018 #include "libpostproc/postprocess.h"
00019
00020
00021
00022 typedef struct ThisFilter
00023 {
00024 VideoFilter vf;
00025
00026 pp_mode *mode;
00027 pp_context *context;
00028 int width;
00029 int height;
00030 int ysize;
00031 int csize;
00032 unsigned char *src[3];
00033 unsigned char *dst[3];
00034 int srcStride[3];
00035 int dstStride[3];
00036 int eprint;
00037 TF_STRUCT;
00038 } ThisFilter;
00039
00040
00041 static int pp(VideoFilter *vf, VideoFrame *frame, int field)
00042 {
00043 (void)field;
00044 ThisFilter* tf = (ThisFilter*)vf;
00045 TF_VARS;
00046
00047 TF_START;
00048
00049 tf->src[0] = tf->dst[0] = frame->buf;
00050 tf->src[1] = tf->dst[1] = frame->buf + tf->ysize;
00051 tf->src[2] = tf->dst[2] = frame->buf + tf->ysize + tf->csize;
00052
00053 if (frame->qscale_table == NULL)
00054 frame->qstride = 0;
00055
00056 tf->ysize = (frame->width) * (frame->height);
00057 tf->csize = tf->ysize / 4;
00058
00059 tf->width = frame->width;
00060 tf->height = frame->height;
00061
00062 tf->srcStride[0] = tf->ysize / (tf->height);
00063 tf->srcStride[1] = tf->csize / (tf->height) * 2;
00064 tf->srcStride[2] = tf->csize / (tf->height) * 2;
00065
00066 tf->dstStride[0] = tf->ysize / (tf->height);
00067 tf->dstStride[1] = tf->csize / (tf->height) * 2;
00068 tf->dstStride[2] = tf->csize / (tf->height) * 2;
00069
00070 pp_postprocess( (const uint8_t**)tf->src, tf->srcStride,
00071 tf->dst, tf->dstStride,
00072 frame->width, frame->height,
00073 (signed char *)(frame->qscale_table), frame->qstride,
00074 tf->mode, tf->context, PP_FORMAT_420);
00075
00076 TF_END(tf, "PostProcess: ");
00077 return 0;
00078 }
00079
00080 static void cleanup(VideoFilter *filter)
00081 {
00082 pp_free_context(((ThisFilter*)filter)->context);
00083 pp_free_mode(((ThisFilter*)filter)->mode);
00084 }
00085
00086 static VideoFilter *new_filter(VideoFrameType inpixfmt,
00087 VideoFrameType outpixfmt,
00088 int *width, int *height, char *options,
00089 int threads)
00090 {
00091 (void) threads;
00092 ThisFilter *filter;
00093
00094 if ( inpixfmt != FMT_YV12 || outpixfmt != FMT_YV12 )
00095 return NULL;
00096
00097 filter = (ThisFilter*) malloc(sizeof(ThisFilter));
00098 if (filter == NULL)
00099 {
00100 fprintf(stderr,"Couldn't allocate memory for filter\n");
00101 return NULL;
00102 }
00103
00104 filter->context = pp_get_context(*width, *height,
00105 PP_CPU_CAPS_MMX|PP_CPU_CAPS_MMX2|PP_CPU_CAPS_3DNOW);
00106 if (filter->context == NULL)
00107 {
00108 fprintf(stderr,"PostProc: failed to get PP context\n");
00109 free(filter);
00110 return NULL;
00111 }
00112
00113 printf("Filteroptions: %s\n", options);
00114 filter->mode = pp_get_mode_by_name_and_quality(options, PP_QUALITY_MAX);
00115 if (filter->mode == NULL)
00116 {
00117 printf("%s", pp_help);
00118 free(filter);
00119 return NULL;
00120 }
00121
00122 filter->eprint = 0;
00123
00124 filter->vf.filter = &pp;
00125 filter->vf.cleanup = &cleanup;
00126 TF_INIT(filter);
00127 return (VideoFilter *)filter;
00128 }
00129
00130 FmtConv FmtList[] =
00131 {
00132 { FMT_YV12, FMT_YV12 },
00133 FMT_NULL
00134 };
00135
00136 ConstFilterInfo filter_table[] =
00137 {
00138 {
00139 filter_init: &new_filter,
00140 name: "postprocess",
00141 descript: "FFMPEG's postprocessing filters",
00142 formats: FmtList,
00143 libname: NULL
00144 },
00145 FILT_NULL
00146 };