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