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