00001
00002
00003
00004 #include <stdlib.h>
00005 #include <stdio.h>
00006
00007 #if HAVE_STDINT_H
00008 #include <stdint.h>
00009 #endif
00010
00011 #include <string.h>
00012 #include <math.h>
00013
00014 #include "filter.h"
00015 #include "frame.h"
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 typedef struct ThisFilter
00032 {
00033 VideoFilter vf;
00034
00035 int uoff;
00036 int cwidth;
00037 int cheight;
00038 int icsize;
00039 int ocsize;
00040 int osize;
00041 TF_STRUCT;
00042 } ThisFilter;
00043
00044 static int
00045 Cvt422420 (VideoFilter * f, VideoFrame * frame, int field)
00046 {
00047 (void)field;
00048 ThisFilter * filter = (ThisFilter *) f;
00049 int X, Y, field;
00050 unsigned char * lineout, * linein0, * linein1;
00051 TF_VARS;
00052
00053 TF_START;
00054 for (field = 0; field < 2; field++)
00055 {
00056 lineout = frame->buf + filter->uoff + field * filter->ocsize;
00057 linein0 = frame->buf + filter->uoff + field * filter->icsize;
00058 linein1 = linein0 + filter->cwidth;
00059 for (Y = 0; Y < filter->cheight; Y++)
00060 {
00061 for (X = 0; X < filter->cwidth; X++)
00062 lineout[X] = (linein0[X] + linein1[X]) / 2;
00063 lineout += filter->cwidth;
00064 linein0 += filter->cwidth * 2;
00065 linein1 += filter->cwidth * 2;
00066 }
00067 }
00068 frame->size = filter->osize;
00069 frame->codec = FMT_YV12;
00070 TF_END(filter, "ConvertYUV422P->YV12: ");
00071 return 0;
00072 }
00073
00074 static int
00075 Cvt420422 (VideoFilter * f, VideoFrame * frame, int field)
00076 {
00077 (void)field;
00078 ThisFilter * filter = (ThisFilter *) f;
00079 int X, Y, field;
00080 unsigned char * lineout0, * lineout1, * linein;
00081 TF_VARS;
00082
00083 TF_START;
00084 for (field = 1; field > -1; field--)
00085 {
00086 lineout0 = frame->buf + filter->uoff + filter->ocsize + field * filter->ocsize;
00087 lineout1 = lineout0 + filter->cwidth;
00088 linein = frame->buf + filter->uoff + filter->icsize + field * filter->icsize;
00089 for (Y = 0; Y < filter->cheight; Y++)
00090 {
00091 lineout0 -= filter->cwidth * 2;
00092 lineout1 -= filter->cwidth * 2;
00093 linein -= filter->cwidth;
00094 for (X = 0; X < filter->cwidth; X++)
00095 lineout0[X] = lineout1[X] = linein[X];
00096 }
00097 }
00098 frame->size = filter->osize;
00099 frame->codec = FMT_YUV422P;
00100 TF_END(filter, "ConvertYV12->YUV420P: ");
00101 return 0;
00102 }
00103
00104 VideoFilter *
00105 newConvertFilter (VideoFrameType inpixfmt, VideoFrameType outpixfmt,
00106 int *width, int *height, char *options, int threads)
00107 {
00108 ThisFilter *filter;
00109
00110 (void) threads;
00111 (void) options;
00112 if ((inpixfmt != FMT_YUV422P || outpixfmt != FMT_YV12) &&
00113 (inpixfmt != FMT_YV12 || outpixfmt != FMT_YUV422P) &&
00114 (inpixfmt != outpixfmt))
00115 return NULL;
00116
00117 filter = malloc (sizeof (ThisFilter));
00118 if (filter == NULL)
00119 {
00120 fprintf (stderr, "Convert: failed to allocate memory for filter\n");
00121 return NULL;
00122 }
00123
00124 if (inpixfmt == FMT_YV12 && outpixfmt == FMT_YUV422P)
00125 {
00126 filter->vf.filter = &Cvt420422;
00127 filter->uoff = *width * *height;
00128 filter->cwidth = *width / 2;
00129 filter->cheight = *height / 2;
00130 filter->icsize = *width * *height / 4;
00131 filter->ocsize = *width * *height / 2;
00132 filter->osize = *width * *height * 2;
00133 }
00134 else if (inpixfmt == FMT_YUV422P && outpixfmt == FMT_YV12)
00135 {
00136 filter->vf.filter = &Cvt422420;
00137 filter->uoff = *width * *height;
00138 filter->cwidth = *width / 2;
00139 filter->cheight = *height / 2;
00140 filter->icsize = *width * *height / 2;
00141 filter->ocsize = *width * *height / 4;
00142 filter->osize = *width * *height * 3 / 2;
00143 }
00144 else if (inpixfmt == outpixfmt)
00145 filter->vf.filter = NULL;
00146 filter->vf.cleanup = NULL;
00147 TF_INIT(filter);
00148 return (VideoFilter *) filter;
00149 }
00150
00151 #if 0
00152 static FmtConv FmtList[] =
00153 {
00154 { FMT_YV12, FMT_YUV422P },
00155 { FMT_YUV422P, FMT_YV12 },
00156 FMT_NULL
00157 };
00158
00159 FilterInfo filter_table[] =
00160 {
00161 {
00162 filter_init: &newConvertFilter,
00163 name: "convert",
00164 descript: "converts between various video types",
00165 formats: FmtList,
00166 libname: NULL
00167 },
00168 FILT_NULL
00169 };
00170 #endif