00001 #include "fadeengine.h"
00002 #include "vframe.h"
00003
00004 #include <stdint.h>
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 FadeUnit::FadeUnit(FadeEngine *server)
00015 : LoadClient(server)
00016 {
00017 this->engine = server;
00018 }
00019
00020 FadeUnit::~FadeUnit()
00021 {
00022 }
00023
00024
00025 #define APPLY_FADE(equivalent, \
00026 input_rows, \
00027 output_rows, \
00028 max, \
00029 type, \
00030 temp_type, \
00031 chroma_zero, \
00032 components) \
00033 { \
00034 temp_type opacity = (temp_type)(alpha * max); \
00035 temp_type transparency = (temp_type)(max - opacity); \
00036 temp_type product = (temp_type) (chroma_zero * transparency); \
00037 \
00038 for(int i = row1; i < row2; i++) \
00039 { \
00040 type *in_row = (type*)input_rows[i]; \
00041 type *out_row = (type*)output_rows[i]; \
00042 \
00043 for(int j = 0; j < width; j++, out_row += components, in_row += components) \
00044 { \
00045 if(components == 3) \
00046 { \
00047 out_row[0] = \
00048 (type)((temp_type)in_row[0] * opacity / max); \
00049 out_row[1] = \
00050 (type)(((temp_type)in_row[1] * opacity + \
00051 product) / max); \
00052 out_row[2] = \
00053 (type)(((temp_type)in_row[2] * opacity + \
00054 product) / max); \
00055 } \
00056 else \
00057 { \
00058 if(!equivalent) \
00059 { \
00060 out_row[0] = in_row[0]; \
00061 out_row[1] = in_row[1]; \
00062 out_row[2] = in_row[2]; \
00063 } \
00064 \
00065 if(in_row[3] == max) \
00066 out_row[3] = opacity; \
00067 else \
00068 out_row[3] = \
00069 (type)((temp_type)in_row[3] * opacity / max); \
00070 } \
00071 } \
00072 } \
00073 }
00074
00075
00076
00077 void FadeUnit::process_package(LoadPackage *package)
00078 {
00079 FadePackage *pkg = (FadePackage*)package;
00080 VFrame *output = engine->output;
00081 VFrame *input = engine->input;
00082 float alpha = engine->alpha;
00083 int row1 = pkg->out_row1;
00084 int row2 = pkg->out_row2;
00085 unsigned char **in_rows = input->get_rows();
00086 unsigned char **out_rows = output->get_rows();
00087 int width = input->get_w();
00088
00089 if(input->get_rows()[0] == output->get_rows()[0])
00090 {
00091 switch(input->get_color_model())
00092 {
00093 case BC_RGB888:
00094 APPLY_FADE(1, out_rows, in_rows, 0xff, unsigned char, uint16_t, 0x0, 3);
00095 break;
00096 case BC_RGBA8888:
00097 APPLY_FADE(1, out_rows, in_rows, 0xff, unsigned char, uint16_t, 0x0, 4);
00098 break;
00099 case BC_RGB_FLOAT:
00100 APPLY_FADE(1, out_rows, in_rows, 1.0, float, float, 0x0, 3);
00101 break;
00102 case BC_RGBA_FLOAT:
00103 APPLY_FADE(1, out_rows, in_rows, 1.0, float, float, 0x0, 4);
00104 break;
00105 case BC_RGB161616:
00106 APPLY_FADE(1, out_rows, in_rows, 0xffff, uint16_t, uint32_t, 0x0, 3);
00107 break;
00108 case BC_RGBA16161616:
00109 APPLY_FADE(1, out_rows, in_rows, 0xffff, uint16_t, uint32_t, 0x0, 4);
00110 break;
00111 case BC_YUV888:
00112 APPLY_FADE(1, out_rows, in_rows, 0xff, unsigned char, uint16_t, 0x80, 3);
00113 break;
00114 case BC_YUVA8888:
00115 APPLY_FADE(1, out_rows, in_rows, 0xff, unsigned char, uint16_t, 0x80, 4);
00116 break;
00117 case BC_YUV161616:
00118 APPLY_FADE(1, out_rows, in_rows, 0xffff, uint16_t, uint32_t, 0x8000, 3);
00119 break;
00120 case BC_YUVA16161616:
00121 APPLY_FADE(1, out_rows, in_rows, 0xffff, uint16_t, uint32_t, 0x8000, 4);
00122 break;
00123 }
00124 }
00125 else
00126 {
00127 switch(input->get_color_model())
00128 {
00129 case BC_RGB888:
00130 APPLY_FADE(0, out_rows, in_rows, 0xff, unsigned char, uint16_t, 0x0, 3);
00131 break;
00132 case BC_RGBA8888:
00133 APPLY_FADE(0, out_rows, in_rows, 0xff, unsigned char, uint16_t, 0x0, 4);
00134 break;
00135 case BC_RGB_FLOAT:
00136 APPLY_FADE(0, out_rows, in_rows, 1.0, float, float, 0x0, 3);
00137 break;
00138 case BC_RGBA_FLOAT:
00139 APPLY_FADE(0, out_rows, in_rows, 1.0, float, float, 0x0, 4);
00140 break;
00141 case BC_RGB161616:
00142 APPLY_FADE(0, out_rows, in_rows, 0xffff, uint16_t, uint32_t, 0x0, 3);
00143 break;
00144 case BC_RGBA16161616:
00145 APPLY_FADE(0, out_rows, in_rows, 0xffff, uint16_t, uint32_t, 0x0, 4);
00146 break;
00147 case BC_YUV888:
00148 APPLY_FADE(0, out_rows, in_rows, 0xff, unsigned char, uint16_t, 0x80, 3);
00149 break;
00150 case BC_YUVA8888:
00151 APPLY_FADE(0, out_rows, in_rows, 0xff, unsigned char, uint16_t, 0x80, 4);
00152 break;
00153 case BC_YUV161616:
00154 APPLY_FADE(0, out_rows, in_rows, 0xffff, uint16_t, uint32_t, 0x8000, 3);
00155 break;
00156 case BC_YUVA16161616:
00157 APPLY_FADE(0, out_rows, in_rows, 0xffff, uint16_t, uint32_t, 0x8000, 4);
00158 break;
00159 }
00160 }
00161 }
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 FadeEngine::FadeEngine(int cpus)
00172 : LoadServer(cpus, cpus)
00173 {
00174 }
00175
00176 FadeEngine::~FadeEngine()
00177 {
00178 }
00179
00180 void FadeEngine::do_fade(VFrame *output, VFrame *input, float alpha)
00181 {
00182 this->output = output;
00183 this->input = input;
00184 this->alpha = alpha;
00185
00186
00187 if(alpha == 1)
00188 output->copy_from(input);
00189 else
00190 process_packages();
00191 }
00192
00193
00194 void FadeEngine::init_packages()
00195 {
00196 for(int i = 0; i < total_packages; i++)
00197 {
00198 FadePackage *package = (FadePackage*)packages[i];
00199 package->out_row1 = input->get_h() * i / total_packages;
00200 package->out_row2 = input->get_h() * (i + 1) / total_packages;
00201 }
00202 }
00203
00204 LoadClient* FadeEngine::new_client()
00205 {
00206 return new FadeUnit(this);
00207 }
00208
00209 LoadPackage* FadeEngine::new_package()
00210 {
00211 return new FadePackage;
00212 }
00213
00214
00215 FadePackage::FadePackage()
00216 {
00217 }
00218