vivid-tpg.c 65 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282
  1. /*
  2. * vivid-tpg.c - Test Pattern Generator
  3. *
  4. * Note: gen_twopix and tpg_gen_text are based on code from vivi.c. See the
  5. * vivi.c source for the copyright information of those functions.
  6. *
  7. * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
  8. *
  9. * This program is free software; you may redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; version 2 of the License.
  12. *
  13. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  14. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  15. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  16. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  17. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  18. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  19. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. * SOFTWARE.
  21. */
  22. #include "vivid-tpg.h"
  23. /* Must remain in sync with enum tpg_pattern */
  24. const char * const tpg_pattern_strings[] = {
  25. "75% Colorbar",
  26. "100% Colorbar",
  27. "CSC Colorbar",
  28. "Horizontal 100% Colorbar",
  29. "100% Color Squares",
  30. "100% Black",
  31. "100% White",
  32. "100% Red",
  33. "100% Green",
  34. "100% Blue",
  35. "16x16 Checkers",
  36. "2x2 Checkers",
  37. "1x1 Checkers",
  38. "2x2 Red/Green Checkers",
  39. "1x1 Red/Green Checkers",
  40. "Alternating Hor Lines",
  41. "Alternating Vert Lines",
  42. "One Pixel Wide Cross",
  43. "Two Pixels Wide Cross",
  44. "Ten Pixels Wide Cross",
  45. "Gray Ramp",
  46. "Noise",
  47. NULL
  48. };
  49. /* Must remain in sync with enum tpg_aspect */
  50. const char * const tpg_aspect_strings[] = {
  51. "Source Width x Height",
  52. "4x3",
  53. "14x9",
  54. "16x9",
  55. "16x9 Anamorphic",
  56. NULL
  57. };
  58. /*
  59. * Sine table: sin[0] = 127 * sin(-180 degrees)
  60. * sin[128] = 127 * sin(0 degrees)
  61. * sin[256] = 127 * sin(180 degrees)
  62. */
  63. static const s8 sin[257] = {
  64. 0, -4, -7, -11, -13, -18, -20, -22, -26, -29, -33, -35, -37, -41, -43, -48,
  65. -50, -52, -56, -58, -62, -63, -65, -69, -71, -75, -76, -78, -82, -83, -87, -88,
  66. -90, -93, -94, -97, -99, -101, -103, -104, -107, -108, -110, -111, -112, -114, -115, -117,
  67. -118, -119, -120, -121, -122, -123, -123, -124, -125, -125, -126, -126, -127, -127, -127, -127,
  68. -127, -127, -127, -127, -126, -126, -125, -125, -124, -124, -123, -122, -121, -120, -119, -118,
  69. -117, -116, -114, -113, -111, -110, -109, -107, -105, -103, -101, -100, -97, -96, -93, -91,
  70. -90, -87, -85, -82, -80, -76, -75, -73, -69, -67, -63, -62, -60, -56, -54, -50,
  71. -48, -46, -41, -39, -35, -33, -31, -26, -24, -20, -18, -15, -11, -9, -4, -2,
  72. 0, 2, 4, 9, 11, 15, 18, 20, 24, 26, 31, 33, 35, 39, 41, 46,
  73. 48, 50, 54, 56, 60, 62, 64, 67, 69, 73, 75, 76, 80, 82, 85, 87,
  74. 90, 91, 93, 96, 97, 100, 101, 103, 105, 107, 109, 110, 111, 113, 114, 116,
  75. 117, 118, 119, 120, 121, 122, 123, 124, 124, 125, 125, 126, 126, 127, 127, 127,
  76. 127, 127, 127, 127, 127, 126, 126, 125, 125, 124, 123, 123, 122, 121, 120, 119,
  77. 118, 117, 115, 114, 112, 111, 110, 108, 107, 104, 103, 101, 99, 97, 94, 93,
  78. 90, 88, 87, 83, 82, 78, 76, 75, 71, 69, 65, 64, 62, 58, 56, 52,
  79. 50, 48, 43, 41, 37, 35, 33, 29, 26, 22, 20, 18, 13, 11, 7, 4,
  80. 0,
  81. };
  82. #define cos(idx) sin[((idx) + 64) % sizeof(sin)]
  83. /* Global font descriptor */
  84. static const u8 *font8x16;
  85. void tpg_set_font(const u8 *f)
  86. {
  87. font8x16 = f;
  88. }
  89. void tpg_init(struct tpg_data *tpg, unsigned w, unsigned h)
  90. {
  91. memset(tpg, 0, sizeof(*tpg));
  92. tpg->scaled_width = tpg->src_width = w;
  93. tpg->src_height = tpg->buf_height = h;
  94. tpg->crop.width = tpg->compose.width = w;
  95. tpg->crop.height = tpg->compose.height = h;
  96. tpg->recalc_colors = true;
  97. tpg->recalc_square_border = true;
  98. tpg->brightness = 128;
  99. tpg->contrast = 128;
  100. tpg->saturation = 128;
  101. tpg->hue = 0;
  102. tpg->mv_hor_mode = TPG_MOVE_NONE;
  103. tpg->mv_vert_mode = TPG_MOVE_NONE;
  104. tpg->field = V4L2_FIELD_NONE;
  105. tpg_s_fourcc(tpg, V4L2_PIX_FMT_RGB24);
  106. tpg->colorspace = V4L2_COLORSPACE_SRGB;
  107. tpg->perc_fill = 100;
  108. }
  109. int tpg_alloc(struct tpg_data *tpg, unsigned max_w)
  110. {
  111. unsigned pat;
  112. unsigned plane;
  113. tpg->max_line_width = max_w;
  114. for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++) {
  115. for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
  116. unsigned pixelsz = plane ? 2 : 4;
  117. tpg->lines[pat][plane] = vzalloc(max_w * 2 * pixelsz);
  118. if (!tpg->lines[pat][plane])
  119. return -ENOMEM;
  120. if (plane == 0)
  121. continue;
  122. tpg->downsampled_lines[pat][plane] = vzalloc(max_w * 2 * pixelsz);
  123. if (!tpg->downsampled_lines[pat][plane])
  124. return -ENOMEM;
  125. }
  126. }
  127. for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
  128. unsigned pixelsz = plane ? 2 : 4;
  129. tpg->contrast_line[plane] = vzalloc(max_w * pixelsz);
  130. if (!tpg->contrast_line[plane])
  131. return -ENOMEM;
  132. tpg->black_line[plane] = vzalloc(max_w * pixelsz);
  133. if (!tpg->black_line[plane])
  134. return -ENOMEM;
  135. tpg->random_line[plane] = vzalloc(max_w * 2 * pixelsz);
  136. if (!tpg->random_line[plane])
  137. return -ENOMEM;
  138. }
  139. return 0;
  140. }
  141. void tpg_free(struct tpg_data *tpg)
  142. {
  143. unsigned pat;
  144. unsigned plane;
  145. for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++)
  146. for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
  147. vfree(tpg->lines[pat][plane]);
  148. tpg->lines[pat][plane] = NULL;
  149. if (plane == 0)
  150. continue;
  151. vfree(tpg->downsampled_lines[pat][plane]);
  152. tpg->downsampled_lines[pat][plane] = NULL;
  153. }
  154. for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
  155. vfree(tpg->contrast_line[plane]);
  156. vfree(tpg->black_line[plane]);
  157. vfree(tpg->random_line[plane]);
  158. tpg->contrast_line[plane] = NULL;
  159. tpg->black_line[plane] = NULL;
  160. tpg->random_line[plane] = NULL;
  161. }
  162. }
  163. bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
  164. {
  165. tpg->fourcc = fourcc;
  166. tpg->planes = 1;
  167. tpg->buffers = 1;
  168. tpg->recalc_colors = true;
  169. tpg->interleaved = false;
  170. tpg->vdownsampling[0] = 1;
  171. tpg->hdownsampling[0] = 1;
  172. tpg->hmask[0] = ~0;
  173. tpg->hmask[1] = ~0;
  174. tpg->hmask[2] = ~0;
  175. switch (fourcc) {
  176. case V4L2_PIX_FMT_SBGGR8:
  177. case V4L2_PIX_FMT_SGBRG8:
  178. case V4L2_PIX_FMT_SGRBG8:
  179. case V4L2_PIX_FMT_SRGGB8:
  180. case V4L2_PIX_FMT_SBGGR10:
  181. case V4L2_PIX_FMT_SGBRG10:
  182. case V4L2_PIX_FMT_SGRBG10:
  183. case V4L2_PIX_FMT_SRGGB10:
  184. case V4L2_PIX_FMT_SBGGR12:
  185. case V4L2_PIX_FMT_SGBRG12:
  186. case V4L2_PIX_FMT_SGRBG12:
  187. case V4L2_PIX_FMT_SRGGB12:
  188. tpg->interleaved = true;
  189. tpg->vdownsampling[1] = 1;
  190. tpg->hdownsampling[1] = 1;
  191. tpg->planes = 2;
  192. /* fall through */
  193. case V4L2_PIX_FMT_RGB332:
  194. case V4L2_PIX_FMT_RGB565:
  195. case V4L2_PIX_FMT_RGB565X:
  196. case V4L2_PIX_FMT_RGB444:
  197. case V4L2_PIX_FMT_XRGB444:
  198. case V4L2_PIX_FMT_ARGB444:
  199. case V4L2_PIX_FMT_RGB555:
  200. case V4L2_PIX_FMT_XRGB555:
  201. case V4L2_PIX_FMT_ARGB555:
  202. case V4L2_PIX_FMT_RGB555X:
  203. case V4L2_PIX_FMT_XRGB555X:
  204. case V4L2_PIX_FMT_ARGB555X:
  205. case V4L2_PIX_FMT_BGR666:
  206. case V4L2_PIX_FMT_RGB24:
  207. case V4L2_PIX_FMT_BGR24:
  208. case V4L2_PIX_FMT_RGB32:
  209. case V4L2_PIX_FMT_BGR32:
  210. case V4L2_PIX_FMT_XRGB32:
  211. case V4L2_PIX_FMT_XBGR32:
  212. case V4L2_PIX_FMT_ARGB32:
  213. case V4L2_PIX_FMT_ABGR32:
  214. case V4L2_PIX_FMT_GREY:
  215. case V4L2_PIX_FMT_Y16:
  216. case V4L2_PIX_FMT_Y16_BE:
  217. tpg->is_yuv = false;
  218. break;
  219. case V4L2_PIX_FMT_YUV444:
  220. case V4L2_PIX_FMT_YUV555:
  221. case V4L2_PIX_FMT_YUV565:
  222. case V4L2_PIX_FMT_YUV32:
  223. tpg->is_yuv = true;
  224. break;
  225. case V4L2_PIX_FMT_YUV420M:
  226. case V4L2_PIX_FMT_YVU420M:
  227. tpg->buffers = 3;
  228. /* fall through */
  229. case V4L2_PIX_FMT_YUV420:
  230. case V4L2_PIX_FMT_YVU420:
  231. tpg->vdownsampling[1] = 2;
  232. tpg->vdownsampling[2] = 2;
  233. tpg->hdownsampling[1] = 2;
  234. tpg->hdownsampling[2] = 2;
  235. tpg->planes = 3;
  236. tpg->is_yuv = true;
  237. break;
  238. case V4L2_PIX_FMT_YUV422P:
  239. tpg->vdownsampling[1] = 1;
  240. tpg->vdownsampling[2] = 1;
  241. tpg->hdownsampling[1] = 2;
  242. tpg->hdownsampling[2] = 2;
  243. tpg->planes = 3;
  244. tpg->is_yuv = true;
  245. break;
  246. case V4L2_PIX_FMT_NV16M:
  247. case V4L2_PIX_FMT_NV61M:
  248. tpg->buffers = 2;
  249. /* fall through */
  250. case V4L2_PIX_FMT_NV16:
  251. case V4L2_PIX_FMT_NV61:
  252. tpg->vdownsampling[1] = 1;
  253. tpg->hdownsampling[1] = 1;
  254. tpg->hmask[1] = ~1;
  255. tpg->planes = 2;
  256. tpg->is_yuv = true;
  257. break;
  258. case V4L2_PIX_FMT_NV12M:
  259. case V4L2_PIX_FMT_NV21M:
  260. tpg->buffers = 2;
  261. /* fall through */
  262. case V4L2_PIX_FMT_NV12:
  263. case V4L2_PIX_FMT_NV21:
  264. tpg->vdownsampling[1] = 2;
  265. tpg->hdownsampling[1] = 1;
  266. tpg->hmask[1] = ~1;
  267. tpg->planes = 2;
  268. tpg->is_yuv = true;
  269. break;
  270. case V4L2_PIX_FMT_NV24:
  271. case V4L2_PIX_FMT_NV42:
  272. tpg->vdownsampling[1] = 1;
  273. tpg->hdownsampling[1] = 1;
  274. tpg->planes = 2;
  275. tpg->is_yuv = true;
  276. break;
  277. case V4L2_PIX_FMT_YUYV:
  278. case V4L2_PIX_FMT_UYVY:
  279. case V4L2_PIX_FMT_YVYU:
  280. case V4L2_PIX_FMT_VYUY:
  281. tpg->hmask[0] = ~1;
  282. tpg->is_yuv = true;
  283. break;
  284. default:
  285. return false;
  286. }
  287. switch (fourcc) {
  288. case V4L2_PIX_FMT_GREY:
  289. case V4L2_PIX_FMT_RGB332:
  290. tpg->twopixelsize[0] = 2;
  291. break;
  292. case V4L2_PIX_FMT_RGB565:
  293. case V4L2_PIX_FMT_RGB565X:
  294. case V4L2_PIX_FMT_RGB444:
  295. case V4L2_PIX_FMT_XRGB444:
  296. case V4L2_PIX_FMT_ARGB444:
  297. case V4L2_PIX_FMT_RGB555:
  298. case V4L2_PIX_FMT_XRGB555:
  299. case V4L2_PIX_FMT_ARGB555:
  300. case V4L2_PIX_FMT_RGB555X:
  301. case V4L2_PIX_FMT_XRGB555X:
  302. case V4L2_PIX_FMT_ARGB555X:
  303. case V4L2_PIX_FMT_YUYV:
  304. case V4L2_PIX_FMT_UYVY:
  305. case V4L2_PIX_FMT_YVYU:
  306. case V4L2_PIX_FMT_VYUY:
  307. case V4L2_PIX_FMT_YUV444:
  308. case V4L2_PIX_FMT_YUV555:
  309. case V4L2_PIX_FMT_YUV565:
  310. case V4L2_PIX_FMT_Y16:
  311. case V4L2_PIX_FMT_Y16_BE:
  312. tpg->twopixelsize[0] = 2 * 2;
  313. break;
  314. case V4L2_PIX_FMT_RGB24:
  315. case V4L2_PIX_FMT_BGR24:
  316. tpg->twopixelsize[0] = 2 * 3;
  317. break;
  318. case V4L2_PIX_FMT_BGR666:
  319. case V4L2_PIX_FMT_RGB32:
  320. case V4L2_PIX_FMT_BGR32:
  321. case V4L2_PIX_FMT_XRGB32:
  322. case V4L2_PIX_FMT_XBGR32:
  323. case V4L2_PIX_FMT_ARGB32:
  324. case V4L2_PIX_FMT_ABGR32:
  325. case V4L2_PIX_FMT_YUV32:
  326. tpg->twopixelsize[0] = 2 * 4;
  327. break;
  328. case V4L2_PIX_FMT_NV12:
  329. case V4L2_PIX_FMT_NV21:
  330. case V4L2_PIX_FMT_NV12M:
  331. case V4L2_PIX_FMT_NV21M:
  332. case V4L2_PIX_FMT_NV16:
  333. case V4L2_PIX_FMT_NV61:
  334. case V4L2_PIX_FMT_NV16M:
  335. case V4L2_PIX_FMT_NV61M:
  336. case V4L2_PIX_FMT_SBGGR8:
  337. case V4L2_PIX_FMT_SGBRG8:
  338. case V4L2_PIX_FMT_SGRBG8:
  339. case V4L2_PIX_FMT_SRGGB8:
  340. tpg->twopixelsize[0] = 2;
  341. tpg->twopixelsize[1] = 2;
  342. break;
  343. case V4L2_PIX_FMT_SRGGB10:
  344. case V4L2_PIX_FMT_SGRBG10:
  345. case V4L2_PIX_FMT_SGBRG10:
  346. case V4L2_PIX_FMT_SBGGR10:
  347. case V4L2_PIX_FMT_SRGGB12:
  348. case V4L2_PIX_FMT_SGRBG12:
  349. case V4L2_PIX_FMT_SGBRG12:
  350. case V4L2_PIX_FMT_SBGGR12:
  351. tpg->twopixelsize[0] = 4;
  352. tpg->twopixelsize[1] = 4;
  353. break;
  354. case V4L2_PIX_FMT_YUV422P:
  355. case V4L2_PIX_FMT_YUV420:
  356. case V4L2_PIX_FMT_YVU420:
  357. case V4L2_PIX_FMT_YUV420M:
  358. case V4L2_PIX_FMT_YVU420M:
  359. tpg->twopixelsize[0] = 2;
  360. tpg->twopixelsize[1] = 2;
  361. tpg->twopixelsize[2] = 2;
  362. break;
  363. case V4L2_PIX_FMT_NV24:
  364. case V4L2_PIX_FMT_NV42:
  365. tpg->twopixelsize[0] = 2;
  366. tpg->twopixelsize[1] = 4;
  367. break;
  368. }
  369. return true;
  370. }
  371. void tpg_s_crop_compose(struct tpg_data *tpg, const struct v4l2_rect *crop,
  372. const struct v4l2_rect *compose)
  373. {
  374. tpg->crop = *crop;
  375. tpg->compose = *compose;
  376. tpg->scaled_width = (tpg->src_width * tpg->compose.width +
  377. tpg->crop.width - 1) / tpg->crop.width;
  378. tpg->scaled_width &= ~1;
  379. if (tpg->scaled_width > tpg->max_line_width)
  380. tpg->scaled_width = tpg->max_line_width;
  381. if (tpg->scaled_width < 2)
  382. tpg->scaled_width = 2;
  383. tpg->recalc_lines = true;
  384. }
  385. void tpg_reset_source(struct tpg_data *tpg, unsigned width, unsigned height,
  386. u32 field)
  387. {
  388. unsigned p;
  389. tpg->src_width = width;
  390. tpg->src_height = height;
  391. tpg->field = field;
  392. tpg->buf_height = height;
  393. if (V4L2_FIELD_HAS_T_OR_B(field))
  394. tpg->buf_height /= 2;
  395. tpg->scaled_width = width;
  396. tpg->crop.top = tpg->crop.left = 0;
  397. tpg->crop.width = width;
  398. tpg->crop.height = height;
  399. tpg->compose.top = tpg->compose.left = 0;
  400. tpg->compose.width = width;
  401. tpg->compose.height = tpg->buf_height;
  402. for (p = 0; p < tpg->planes; p++)
  403. tpg->bytesperline[p] = (width * tpg->twopixelsize[p]) /
  404. (2 * tpg->hdownsampling[p]);
  405. tpg->recalc_square_border = true;
  406. }
  407. static enum tpg_color tpg_get_textbg_color(struct tpg_data *tpg)
  408. {
  409. switch (tpg->pattern) {
  410. case TPG_PAT_BLACK:
  411. return TPG_COLOR_100_WHITE;
  412. case TPG_PAT_CSC_COLORBAR:
  413. return TPG_COLOR_CSC_BLACK;
  414. default:
  415. return TPG_COLOR_100_BLACK;
  416. }
  417. }
  418. static enum tpg_color tpg_get_textfg_color(struct tpg_data *tpg)
  419. {
  420. switch (tpg->pattern) {
  421. case TPG_PAT_75_COLORBAR:
  422. case TPG_PAT_CSC_COLORBAR:
  423. return TPG_COLOR_CSC_WHITE;
  424. case TPG_PAT_BLACK:
  425. return TPG_COLOR_100_BLACK;
  426. default:
  427. return TPG_COLOR_100_WHITE;
  428. }
  429. }
  430. static inline int rec709_to_linear(int v)
  431. {
  432. v = clamp(v, 0, 0xff0);
  433. return tpg_rec709_to_linear[v];
  434. }
  435. static inline int linear_to_rec709(int v)
  436. {
  437. v = clamp(v, 0, 0xff0);
  438. return tpg_linear_to_rec709[v];
  439. }
  440. static void rgb2ycbcr(const int m[3][3], int r, int g, int b,
  441. int y_offset, int *y, int *cb, int *cr)
  442. {
  443. *y = ((m[0][0] * r + m[0][1] * g + m[0][2] * b) >> 16) + (y_offset << 4);
  444. *cb = ((m[1][0] * r + m[1][1] * g + m[1][2] * b) >> 16) + (128 << 4);
  445. *cr = ((m[2][0] * r + m[2][1] * g + m[2][2] * b) >> 16) + (128 << 4);
  446. }
  447. static void color_to_ycbcr(struct tpg_data *tpg, int r, int g, int b,
  448. int *y, int *cb, int *cr)
  449. {
  450. #define COEFF(v, r) ((int)(0.5 + (v) * (r) * 256.0))
  451. static const int bt601[3][3] = {
  452. { COEFF(0.299, 219), COEFF(0.587, 219), COEFF(0.114, 219) },
  453. { COEFF(-0.169, 224), COEFF(-0.331, 224), COEFF(0.5, 224) },
  454. { COEFF(0.5, 224), COEFF(-0.419, 224), COEFF(-0.081, 224) },
  455. };
  456. static const int bt601_full[3][3] = {
  457. { COEFF(0.299, 255), COEFF(0.587, 255), COEFF(0.114, 255) },
  458. { COEFF(-0.169, 255), COEFF(-0.331, 255), COEFF(0.5, 255) },
  459. { COEFF(0.5, 255), COEFF(-0.419, 255), COEFF(-0.081, 255) },
  460. };
  461. static const int rec709[3][3] = {
  462. { COEFF(0.2126, 219), COEFF(0.7152, 219), COEFF(0.0722, 219) },
  463. { COEFF(-0.1146, 224), COEFF(-0.3854, 224), COEFF(0.5, 224) },
  464. { COEFF(0.5, 224), COEFF(-0.4542, 224), COEFF(-0.0458, 224) },
  465. };
  466. static const int rec709_full[3][3] = {
  467. { COEFF(0.2126, 255), COEFF(0.7152, 255), COEFF(0.0722, 255) },
  468. { COEFF(-0.1146, 255), COEFF(-0.3854, 255), COEFF(0.5, 255) },
  469. { COEFF(0.5, 255), COEFF(-0.4542, 255), COEFF(-0.0458, 255) },
  470. };
  471. static const int smpte240m[3][3] = {
  472. { COEFF(0.212, 219), COEFF(0.701, 219), COEFF(0.087, 219) },
  473. { COEFF(-0.116, 224), COEFF(-0.384, 224), COEFF(0.5, 224) },
  474. { COEFF(0.5, 224), COEFF(-0.445, 224), COEFF(-0.055, 224) },
  475. };
  476. static const int smpte240m_full[3][3] = {
  477. { COEFF(0.212, 255), COEFF(0.701, 255), COEFF(0.087, 255) },
  478. { COEFF(-0.116, 255), COEFF(-0.384, 255), COEFF(0.5, 255) },
  479. { COEFF(0.5, 255), COEFF(-0.445, 255), COEFF(-0.055, 255) },
  480. };
  481. static const int bt2020[3][3] = {
  482. { COEFF(0.2627, 219), COEFF(0.6780, 219), COEFF(0.0593, 219) },
  483. { COEFF(-0.1396, 224), COEFF(-0.3604, 224), COEFF(0.5, 224) },
  484. { COEFF(0.5, 224), COEFF(-0.4598, 224), COEFF(-0.0402, 224) },
  485. };
  486. static const int bt2020_full[3][3] = {
  487. { COEFF(0.2627, 255), COEFF(0.6780, 255), COEFF(0.0593, 255) },
  488. { COEFF(-0.1396, 255), COEFF(-0.3604, 255), COEFF(0.5, 255) },
  489. { COEFF(0.5, 255), COEFF(-0.4698, 255), COEFF(-0.0402, 255) },
  490. };
  491. static const int bt2020c[4] = {
  492. COEFF(1.0 / 1.9404, 224), COEFF(1.0 / 1.5816, 224),
  493. COEFF(1.0 / 1.7184, 224), COEFF(1.0 / 0.9936, 224),
  494. };
  495. static const int bt2020c_full[4] = {
  496. COEFF(1.0 / 1.9404, 255), COEFF(1.0 / 1.5816, 255),
  497. COEFF(1.0 / 1.7184, 255), COEFF(1.0 / 0.9936, 255),
  498. };
  499. bool full = tpg->real_quantization == V4L2_QUANTIZATION_FULL_RANGE;
  500. unsigned y_offset = full ? 0 : 16;
  501. int lin_y, yc;
  502. switch (tpg->real_ycbcr_enc) {
  503. case V4L2_YCBCR_ENC_601:
  504. case V4L2_YCBCR_ENC_SYCC:
  505. rgb2ycbcr(full ? bt601_full : bt601, r, g, b, y_offset, y, cb, cr);
  506. break;
  507. case V4L2_YCBCR_ENC_XV601:
  508. /* Ignore quantization range, there is only one possible
  509. * Y'CbCr encoding. */
  510. rgb2ycbcr(bt601, r, g, b, 16, y, cb, cr);
  511. break;
  512. case V4L2_YCBCR_ENC_XV709:
  513. /* Ignore quantization range, there is only one possible
  514. * Y'CbCr encoding. */
  515. rgb2ycbcr(rec709, r, g, b, 16, y, cb, cr);
  516. break;
  517. case V4L2_YCBCR_ENC_BT2020:
  518. rgb2ycbcr(full ? bt2020_full : bt2020, r, g, b, y_offset, y, cb, cr);
  519. break;
  520. case V4L2_YCBCR_ENC_BT2020_CONST_LUM:
  521. lin_y = (COEFF(0.2627, 255) * rec709_to_linear(r) +
  522. COEFF(0.6780, 255) * rec709_to_linear(g) +
  523. COEFF(0.0593, 255) * rec709_to_linear(b)) >> 16;
  524. yc = linear_to_rec709(lin_y);
  525. *y = full ? yc : (yc * 219) / 255 + (16 << 4);
  526. if (b <= yc)
  527. *cb = (((b - yc) * (full ? bt2020c_full[0] : bt2020c[0])) >> 16) + (128 << 4);
  528. else
  529. *cb = (((b - yc) * (full ? bt2020c_full[1] : bt2020c[1])) >> 16) + (128 << 4);
  530. if (r <= yc)
  531. *cr = (((r - yc) * (full ? bt2020c_full[2] : bt2020c[2])) >> 16) + (128 << 4);
  532. else
  533. *cr = (((r - yc) * (full ? bt2020c_full[3] : bt2020c[3])) >> 16) + (128 << 4);
  534. break;
  535. case V4L2_YCBCR_ENC_SMPTE240M:
  536. rgb2ycbcr(full ? smpte240m_full : smpte240m, r, g, b, y_offset, y, cb, cr);
  537. break;
  538. case V4L2_YCBCR_ENC_709:
  539. default:
  540. rgb2ycbcr(full ? rec709_full : rec709, r, g, b, y_offset, y, cb, cr);
  541. break;
  542. }
  543. }
  544. static void ycbcr2rgb(const int m[3][3], int y, int cb, int cr,
  545. int y_offset, int *r, int *g, int *b)
  546. {
  547. y -= y_offset << 4;
  548. cb -= 128 << 4;
  549. cr -= 128 << 4;
  550. *r = m[0][0] * y + m[0][1] * cb + m[0][2] * cr;
  551. *g = m[1][0] * y + m[1][1] * cb + m[1][2] * cr;
  552. *b = m[2][0] * y + m[2][1] * cb + m[2][2] * cr;
  553. *r = clamp(*r >> 12, 0, 0xff0);
  554. *g = clamp(*g >> 12, 0, 0xff0);
  555. *b = clamp(*b >> 12, 0, 0xff0);
  556. }
  557. static void ycbcr_to_color(struct tpg_data *tpg, int y, int cb, int cr,
  558. int *r, int *g, int *b)
  559. {
  560. #undef COEFF
  561. #define COEFF(v, r) ((int)(0.5 + (v) * ((255.0 * 255.0 * 16.0) / (r))))
  562. static const int bt601[3][3] = {
  563. { COEFF(1, 219), COEFF(0, 224), COEFF(1.4020, 224) },
  564. { COEFF(1, 219), COEFF(-0.3441, 224), COEFF(-0.7141, 224) },
  565. { COEFF(1, 219), COEFF(1.7720, 224), COEFF(0, 224) },
  566. };
  567. static const int bt601_full[3][3] = {
  568. { COEFF(1, 255), COEFF(0, 255), COEFF(1.4020, 255) },
  569. { COEFF(1, 255), COEFF(-0.3441, 255), COEFF(-0.7141, 255) },
  570. { COEFF(1, 255), COEFF(1.7720, 255), COEFF(0, 255) },
  571. };
  572. static const int rec709[3][3] = {
  573. { COEFF(1, 219), COEFF(0, 224), COEFF(1.5748, 224) },
  574. { COEFF(1, 219), COEFF(-0.1873, 224), COEFF(-0.4681, 224) },
  575. { COEFF(1, 219), COEFF(1.8556, 224), COEFF(0, 224) },
  576. };
  577. static const int rec709_full[3][3] = {
  578. { COEFF(1, 255), COEFF(0, 255), COEFF(1.5748, 255) },
  579. { COEFF(1, 255), COEFF(-0.1873, 255), COEFF(-0.4681, 255) },
  580. { COEFF(1, 255), COEFF(1.8556, 255), COEFF(0, 255) },
  581. };
  582. static const int smpte240m[3][3] = {
  583. { COEFF(1, 219), COEFF(0, 224), COEFF(1.5756, 224) },
  584. { COEFF(1, 219), COEFF(-0.2253, 224), COEFF(-0.4767, 224) },
  585. { COEFF(1, 219), COEFF(1.8270, 224), COEFF(0, 224) },
  586. };
  587. static const int smpte240m_full[3][3] = {
  588. { COEFF(1, 255), COEFF(0, 255), COEFF(1.5756, 255) },
  589. { COEFF(1, 255), COEFF(-0.2253, 255), COEFF(-0.4767, 255) },
  590. { COEFF(1, 255), COEFF(1.8270, 255), COEFF(0, 255) },
  591. };
  592. static const int bt2020[3][3] = {
  593. { COEFF(1, 219), COEFF(0, 224), COEFF(1.4746, 224) },
  594. { COEFF(1, 219), COEFF(-0.1646, 224), COEFF(-0.5714, 224) },
  595. { COEFF(1, 219), COEFF(1.8814, 224), COEFF(0, 224) },
  596. };
  597. static const int bt2020_full[3][3] = {
  598. { COEFF(1, 255), COEFF(0, 255), COEFF(1.4746, 255) },
  599. { COEFF(1, 255), COEFF(-0.1646, 255), COEFF(-0.5714, 255) },
  600. { COEFF(1, 255), COEFF(1.8814, 255), COEFF(0, 255) },
  601. };
  602. static const int bt2020c[4] = {
  603. COEFF(1.9404, 224), COEFF(1.5816, 224),
  604. COEFF(1.7184, 224), COEFF(0.9936, 224),
  605. };
  606. static const int bt2020c_full[4] = {
  607. COEFF(1.9404, 255), COEFF(1.5816, 255),
  608. COEFF(1.7184, 255), COEFF(0.9936, 255),
  609. };
  610. bool full = tpg->real_quantization == V4L2_QUANTIZATION_FULL_RANGE;
  611. unsigned y_offset = full ? 0 : 16;
  612. int y_fac = full ? COEFF(1.0, 255) : COEFF(1.0, 219);
  613. int lin_r, lin_g, lin_b, lin_y;
  614. switch (tpg->real_ycbcr_enc) {
  615. case V4L2_YCBCR_ENC_601:
  616. case V4L2_YCBCR_ENC_SYCC:
  617. ycbcr2rgb(full ? bt601_full : bt601, y, cb, cr, y_offset, r, g, b);
  618. break;
  619. case V4L2_YCBCR_ENC_XV601:
  620. /* Ignore quantization range, there is only one possible
  621. * Y'CbCr encoding. */
  622. ycbcr2rgb(bt601, y, cb, cr, 16, r, g, b);
  623. break;
  624. case V4L2_YCBCR_ENC_XV709:
  625. /* Ignore quantization range, there is only one possible
  626. * Y'CbCr encoding. */
  627. ycbcr2rgb(rec709, y, cb, cr, 16, r, g, b);
  628. break;
  629. case V4L2_YCBCR_ENC_BT2020:
  630. ycbcr2rgb(full ? bt2020_full : bt2020, y, cb, cr, y_offset, r, g, b);
  631. break;
  632. case V4L2_YCBCR_ENC_BT2020_CONST_LUM:
  633. y -= full ? 0 : 16 << 4;
  634. cb -= 128 << 4;
  635. cr -= 128 << 4;
  636. if (cb <= 0)
  637. *b = y_fac * y + (full ? bt2020c_full[0] : bt2020c[0]) * cb;
  638. else
  639. *b = y_fac * y + (full ? bt2020c_full[1] : bt2020c[1]) * cb;
  640. *b = *b >> 12;
  641. if (cr <= 0)
  642. *r = y_fac * y + (full ? bt2020c_full[2] : bt2020c[2]) * cr;
  643. else
  644. *r = y_fac * y + (full ? bt2020c_full[3] : bt2020c[3]) * cr;
  645. *r = *r >> 12;
  646. lin_r = rec709_to_linear(*r);
  647. lin_b = rec709_to_linear(*b);
  648. lin_y = rec709_to_linear((y * 255) / (full ? 255 : 219));
  649. lin_g = COEFF(1.0 / 0.6780, 255) * lin_y -
  650. COEFF(0.2627 / 0.6780, 255) * lin_r -
  651. COEFF(0.0593 / 0.6780, 255) * lin_b;
  652. *g = linear_to_rec709(lin_g >> 12);
  653. break;
  654. case V4L2_YCBCR_ENC_SMPTE240M:
  655. ycbcr2rgb(full ? smpte240m_full : smpte240m, y, cb, cr, y_offset, r, g, b);
  656. break;
  657. case V4L2_YCBCR_ENC_709:
  658. default:
  659. ycbcr2rgb(full ? rec709_full : rec709, y, cb, cr, y_offset, r, g, b);
  660. break;
  661. }
  662. }
  663. /* precalculate color bar values to speed up rendering */
  664. static void precalculate_color(struct tpg_data *tpg, int k)
  665. {
  666. int col = k;
  667. int r = tpg_colors[col].r;
  668. int g = tpg_colors[col].g;
  669. int b = tpg_colors[col].b;
  670. if (k == TPG_COLOR_TEXTBG) {
  671. col = tpg_get_textbg_color(tpg);
  672. r = tpg_colors[col].r;
  673. g = tpg_colors[col].g;
  674. b = tpg_colors[col].b;
  675. } else if (k == TPG_COLOR_TEXTFG) {
  676. col = tpg_get_textfg_color(tpg);
  677. r = tpg_colors[col].r;
  678. g = tpg_colors[col].g;
  679. b = tpg_colors[col].b;
  680. } else if (tpg->pattern == TPG_PAT_NOISE) {
  681. r = g = b = prandom_u32_max(256);
  682. } else if (k == TPG_COLOR_RANDOM) {
  683. r = g = b = tpg->qual_offset + prandom_u32_max(196);
  684. } else if (k >= TPG_COLOR_RAMP) {
  685. r = g = b = k - TPG_COLOR_RAMP;
  686. }
  687. if (tpg->pattern == TPG_PAT_CSC_COLORBAR && col <= TPG_COLOR_CSC_BLACK) {
  688. r = tpg_csc_colors[tpg->colorspace][tpg->real_xfer_func][col].r;
  689. g = tpg_csc_colors[tpg->colorspace][tpg->real_xfer_func][col].g;
  690. b = tpg_csc_colors[tpg->colorspace][tpg->real_xfer_func][col].b;
  691. } else {
  692. r <<= 4;
  693. g <<= 4;
  694. b <<= 4;
  695. }
  696. if (tpg->qual == TPG_QUAL_GRAY || tpg->fourcc == V4L2_PIX_FMT_GREY ||
  697. tpg->fourcc == V4L2_PIX_FMT_Y16 ||
  698. tpg->fourcc == V4L2_PIX_FMT_Y16_BE) {
  699. /* Rec. 709 Luma function */
  700. /* (0.2126, 0.7152, 0.0722) * (255 * 256) */
  701. r = g = b = (13879 * r + 46688 * g + 4713 * b) >> 16;
  702. }
  703. /*
  704. * The assumption is that the RGB output is always full range,
  705. * so only if the rgb_range overrides the 'real' rgb range do
  706. * we need to convert the RGB values.
  707. *
  708. * Remember that r, g and b are still in the 0 - 0xff0 range.
  709. */
  710. if (tpg->real_rgb_range == V4L2_DV_RGB_RANGE_LIMITED &&
  711. tpg->rgb_range == V4L2_DV_RGB_RANGE_FULL) {
  712. /*
  713. * Convert from full range (which is what r, g and b are)
  714. * to limited range (which is the 'real' RGB range), which
  715. * is then interpreted as full range.
  716. */
  717. r = (r * 219) / 255 + (16 << 4);
  718. g = (g * 219) / 255 + (16 << 4);
  719. b = (b * 219) / 255 + (16 << 4);
  720. } else if (tpg->real_rgb_range != V4L2_DV_RGB_RANGE_LIMITED &&
  721. tpg->rgb_range == V4L2_DV_RGB_RANGE_LIMITED) {
  722. /*
  723. * Clamp r, g and b to the limited range and convert to full
  724. * range since that's what we deliver.
  725. */
  726. r = clamp(r, 16 << 4, 235 << 4);
  727. g = clamp(g, 16 << 4, 235 << 4);
  728. b = clamp(b, 16 << 4, 235 << 4);
  729. r = (r - (16 << 4)) * 255 / 219;
  730. g = (g - (16 << 4)) * 255 / 219;
  731. b = (b - (16 << 4)) * 255 / 219;
  732. }
  733. if (tpg->brightness != 128 || tpg->contrast != 128 ||
  734. tpg->saturation != 128 || tpg->hue) {
  735. /* Implement these operations */
  736. int y, cb, cr;
  737. int tmp_cb, tmp_cr;
  738. /* First convert to YCbCr */
  739. color_to_ycbcr(tpg, r, g, b, &y, &cb, &cr);
  740. y = (16 << 4) + ((y - (16 << 4)) * tpg->contrast) / 128;
  741. y += (tpg->brightness << 4) - (128 << 4);
  742. cb -= 128 << 4;
  743. cr -= 128 << 4;
  744. tmp_cb = (cb * cos(128 + tpg->hue)) / 127 + (cr * sin[128 + tpg->hue]) / 127;
  745. tmp_cr = (cr * cos(128 + tpg->hue)) / 127 - (cb * sin[128 + tpg->hue]) / 127;
  746. cb = (128 << 4) + (tmp_cb * tpg->contrast * tpg->saturation) / (128 * 128);
  747. cr = (128 << 4) + (tmp_cr * tpg->contrast * tpg->saturation) / (128 * 128);
  748. if (tpg->is_yuv) {
  749. tpg->colors[k][0] = clamp(y >> 4, 1, 254);
  750. tpg->colors[k][1] = clamp(cb >> 4, 1, 254);
  751. tpg->colors[k][2] = clamp(cr >> 4, 1, 254);
  752. return;
  753. }
  754. ycbcr_to_color(tpg, y, cb, cr, &r, &g, &b);
  755. }
  756. if (tpg->is_yuv) {
  757. /* Convert to YCbCr */
  758. int y, cb, cr;
  759. color_to_ycbcr(tpg, r, g, b, &y, &cb, &cr);
  760. if (tpg->real_quantization == V4L2_QUANTIZATION_LIM_RANGE) {
  761. y = clamp(y, 16 << 4, 235 << 4);
  762. cb = clamp(cb, 16 << 4, 240 << 4);
  763. cr = clamp(cr, 16 << 4, 240 << 4);
  764. }
  765. y = clamp(y >> 4, 1, 254);
  766. cb = clamp(cb >> 4, 1, 254);
  767. cr = clamp(cr >> 4, 1, 254);
  768. switch (tpg->fourcc) {
  769. case V4L2_PIX_FMT_YUV444:
  770. y >>= 4;
  771. cb >>= 4;
  772. cr >>= 4;
  773. break;
  774. case V4L2_PIX_FMT_YUV555:
  775. y >>= 3;
  776. cb >>= 3;
  777. cr >>= 3;
  778. break;
  779. case V4L2_PIX_FMT_YUV565:
  780. y >>= 3;
  781. cb >>= 2;
  782. cr >>= 3;
  783. break;
  784. }
  785. tpg->colors[k][0] = y;
  786. tpg->colors[k][1] = cb;
  787. tpg->colors[k][2] = cr;
  788. } else {
  789. if (tpg->real_quantization == V4L2_QUANTIZATION_LIM_RANGE) {
  790. r = (r * 219) / 255 + (16 << 4);
  791. g = (g * 219) / 255 + (16 << 4);
  792. b = (b * 219) / 255 + (16 << 4);
  793. }
  794. switch (tpg->fourcc) {
  795. case V4L2_PIX_FMT_RGB332:
  796. r >>= 9;
  797. g >>= 9;
  798. b >>= 10;
  799. break;
  800. case V4L2_PIX_FMT_RGB565:
  801. case V4L2_PIX_FMT_RGB565X:
  802. r >>= 7;
  803. g >>= 6;
  804. b >>= 7;
  805. break;
  806. case V4L2_PIX_FMT_RGB444:
  807. case V4L2_PIX_FMT_XRGB444:
  808. case V4L2_PIX_FMT_ARGB444:
  809. r >>= 8;
  810. g >>= 8;
  811. b >>= 8;
  812. break;
  813. case V4L2_PIX_FMT_RGB555:
  814. case V4L2_PIX_FMT_XRGB555:
  815. case V4L2_PIX_FMT_ARGB555:
  816. case V4L2_PIX_FMT_RGB555X:
  817. case V4L2_PIX_FMT_XRGB555X:
  818. case V4L2_PIX_FMT_ARGB555X:
  819. r >>= 7;
  820. g >>= 7;
  821. b >>= 7;
  822. break;
  823. case V4L2_PIX_FMT_BGR666:
  824. r >>= 6;
  825. g >>= 6;
  826. b >>= 6;
  827. break;
  828. default:
  829. r >>= 4;
  830. g >>= 4;
  831. b >>= 4;
  832. break;
  833. }
  834. tpg->colors[k][0] = r;
  835. tpg->colors[k][1] = g;
  836. tpg->colors[k][2] = b;
  837. }
  838. }
  839. static void tpg_precalculate_colors(struct tpg_data *tpg)
  840. {
  841. int k;
  842. for (k = 0; k < TPG_COLOR_MAX; k++)
  843. precalculate_color(tpg, k);
  844. }
  845. /* 'odd' is true for pixels 1, 3, 5, etc. and false for pixels 0, 2, 4, etc. */
  846. static void gen_twopix(struct tpg_data *tpg,
  847. u8 buf[TPG_MAX_PLANES][8], int color, bool odd)
  848. {
  849. unsigned offset = odd * tpg->twopixelsize[0] / 2;
  850. u8 alpha = tpg->alpha_component;
  851. u8 r_y, g_u, b_v;
  852. if (tpg->alpha_red_only && color != TPG_COLOR_CSC_RED &&
  853. color != TPG_COLOR_100_RED &&
  854. color != TPG_COLOR_75_RED)
  855. alpha = 0;
  856. if (color == TPG_COLOR_RANDOM)
  857. precalculate_color(tpg, color);
  858. r_y = tpg->colors[color][0]; /* R or precalculated Y */
  859. g_u = tpg->colors[color][1]; /* G or precalculated U */
  860. b_v = tpg->colors[color][2]; /* B or precalculated V */
  861. switch (tpg->fourcc) {
  862. case V4L2_PIX_FMT_GREY:
  863. buf[0][offset] = r_y;
  864. break;
  865. case V4L2_PIX_FMT_Y16:
  866. /*
  867. * Ideally both bytes should be set to r_y, but then you won't
  868. * be able to detect endian problems. So keep it 0 except for
  869. * the corner case where r_y is 0xff so white really will be
  870. * white (0xffff).
  871. */
  872. buf[0][offset] = r_y == 0xff ? r_y : 0;
  873. buf[0][offset+1] = r_y;
  874. break;
  875. case V4L2_PIX_FMT_Y16_BE:
  876. /* See comment for V4L2_PIX_FMT_Y16 above */
  877. buf[0][offset] = r_y;
  878. buf[0][offset+1] = r_y == 0xff ? r_y : 0;
  879. break;
  880. case V4L2_PIX_FMT_YUV422P:
  881. case V4L2_PIX_FMT_YUV420:
  882. case V4L2_PIX_FMT_YUV420M:
  883. buf[0][offset] = r_y;
  884. if (odd) {
  885. buf[1][0] = (buf[1][0] + g_u) / 2;
  886. buf[2][0] = (buf[2][0] + b_v) / 2;
  887. buf[1][1] = buf[1][0];
  888. buf[2][1] = buf[2][0];
  889. break;
  890. }
  891. buf[1][0] = g_u;
  892. buf[2][0] = b_v;
  893. break;
  894. case V4L2_PIX_FMT_YVU420:
  895. case V4L2_PIX_FMT_YVU420M:
  896. buf[0][offset] = r_y;
  897. if (odd) {
  898. buf[1][0] = (buf[1][0] + b_v) / 2;
  899. buf[2][0] = (buf[2][0] + g_u) / 2;
  900. buf[1][1] = buf[1][0];
  901. buf[2][1] = buf[2][0];
  902. break;
  903. }
  904. buf[1][0] = b_v;
  905. buf[2][0] = g_u;
  906. break;
  907. case V4L2_PIX_FMT_NV12:
  908. case V4L2_PIX_FMT_NV12M:
  909. case V4L2_PIX_FMT_NV16:
  910. case V4L2_PIX_FMT_NV16M:
  911. buf[0][offset] = r_y;
  912. if (odd) {
  913. buf[1][0] = (buf[1][0] + g_u) / 2;
  914. buf[1][1] = (buf[1][1] + b_v) / 2;
  915. break;
  916. }
  917. buf[1][0] = g_u;
  918. buf[1][1] = b_v;
  919. break;
  920. case V4L2_PIX_FMT_NV21:
  921. case V4L2_PIX_FMT_NV21M:
  922. case V4L2_PIX_FMT_NV61:
  923. case V4L2_PIX_FMT_NV61M:
  924. buf[0][offset] = r_y;
  925. if (odd) {
  926. buf[1][0] = (buf[1][0] + b_v) / 2;
  927. buf[1][1] = (buf[1][1] + g_u) / 2;
  928. break;
  929. }
  930. buf[1][0] = b_v;
  931. buf[1][1] = g_u;
  932. break;
  933. case V4L2_PIX_FMT_NV24:
  934. buf[0][offset] = r_y;
  935. buf[1][2 * offset] = g_u;
  936. buf[1][2 * offset + 1] = b_v;
  937. break;
  938. case V4L2_PIX_FMT_NV42:
  939. buf[0][offset] = r_y;
  940. buf[1][2 * offset] = b_v;
  941. buf[1][2 * offset + 1] = g_u;
  942. break;
  943. case V4L2_PIX_FMT_YUYV:
  944. buf[0][offset] = r_y;
  945. if (odd) {
  946. buf[0][1] = (buf[0][1] + g_u) / 2;
  947. buf[0][3] = (buf[0][3] + b_v) / 2;
  948. break;
  949. }
  950. buf[0][1] = g_u;
  951. buf[0][3] = b_v;
  952. break;
  953. case V4L2_PIX_FMT_UYVY:
  954. buf[0][offset + 1] = r_y;
  955. if (odd) {
  956. buf[0][0] = (buf[0][0] + g_u) / 2;
  957. buf[0][2] = (buf[0][2] + b_v) / 2;
  958. break;
  959. }
  960. buf[0][0] = g_u;
  961. buf[0][2] = b_v;
  962. break;
  963. case V4L2_PIX_FMT_YVYU:
  964. buf[0][offset] = r_y;
  965. if (odd) {
  966. buf[0][1] = (buf[0][1] + b_v) / 2;
  967. buf[0][3] = (buf[0][3] + g_u) / 2;
  968. break;
  969. }
  970. buf[0][1] = b_v;
  971. buf[0][3] = g_u;
  972. break;
  973. case V4L2_PIX_FMT_VYUY:
  974. buf[0][offset + 1] = r_y;
  975. if (odd) {
  976. buf[0][0] = (buf[0][0] + b_v) / 2;
  977. buf[0][2] = (buf[0][2] + g_u) / 2;
  978. break;
  979. }
  980. buf[0][0] = b_v;
  981. buf[0][2] = g_u;
  982. break;
  983. case V4L2_PIX_FMT_RGB332:
  984. buf[0][offset] = (r_y << 5) | (g_u << 2) | b_v;
  985. break;
  986. case V4L2_PIX_FMT_YUV565:
  987. case V4L2_PIX_FMT_RGB565:
  988. buf[0][offset] = (g_u << 5) | b_v;
  989. buf[0][offset + 1] = (r_y << 3) | (g_u >> 3);
  990. break;
  991. case V4L2_PIX_FMT_RGB565X:
  992. buf[0][offset] = (r_y << 3) | (g_u >> 3);
  993. buf[0][offset + 1] = (g_u << 5) | b_v;
  994. break;
  995. case V4L2_PIX_FMT_RGB444:
  996. case V4L2_PIX_FMT_XRGB444:
  997. alpha = 0;
  998. /* fall through */
  999. case V4L2_PIX_FMT_YUV444:
  1000. case V4L2_PIX_FMT_ARGB444:
  1001. buf[0][offset] = (g_u << 4) | b_v;
  1002. buf[0][offset + 1] = (alpha & 0xf0) | r_y;
  1003. break;
  1004. case V4L2_PIX_FMT_RGB555:
  1005. case V4L2_PIX_FMT_XRGB555:
  1006. alpha = 0;
  1007. /* fall through */
  1008. case V4L2_PIX_FMT_YUV555:
  1009. case V4L2_PIX_FMT_ARGB555:
  1010. buf[0][offset] = (g_u << 5) | b_v;
  1011. buf[0][offset + 1] = (alpha & 0x80) | (r_y << 2) | (g_u >> 3);
  1012. break;
  1013. case V4L2_PIX_FMT_RGB555X:
  1014. case V4L2_PIX_FMT_XRGB555X:
  1015. alpha = 0;
  1016. /* fall through */
  1017. case V4L2_PIX_FMT_ARGB555X:
  1018. buf[0][offset] = (alpha & 0x80) | (r_y << 2) | (g_u >> 3);
  1019. buf[0][offset + 1] = (g_u << 5) | b_v;
  1020. break;
  1021. case V4L2_PIX_FMT_RGB24:
  1022. buf[0][offset] = r_y;
  1023. buf[0][offset + 1] = g_u;
  1024. buf[0][offset + 2] = b_v;
  1025. break;
  1026. case V4L2_PIX_FMT_BGR24:
  1027. buf[0][offset] = b_v;
  1028. buf[0][offset + 1] = g_u;
  1029. buf[0][offset + 2] = r_y;
  1030. break;
  1031. case V4L2_PIX_FMT_BGR666:
  1032. buf[0][offset] = (b_v << 2) | (g_u >> 4);
  1033. buf[0][offset + 1] = (g_u << 4) | (r_y >> 2);
  1034. buf[0][offset + 2] = r_y << 6;
  1035. buf[0][offset + 3] = 0;
  1036. break;
  1037. case V4L2_PIX_FMT_RGB32:
  1038. case V4L2_PIX_FMT_XRGB32:
  1039. alpha = 0;
  1040. /* fall through */
  1041. case V4L2_PIX_FMT_YUV32:
  1042. case V4L2_PIX_FMT_ARGB32:
  1043. buf[0][offset] = alpha;
  1044. buf[0][offset + 1] = r_y;
  1045. buf[0][offset + 2] = g_u;
  1046. buf[0][offset + 3] = b_v;
  1047. break;
  1048. case V4L2_PIX_FMT_BGR32:
  1049. case V4L2_PIX_FMT_XBGR32:
  1050. alpha = 0;
  1051. /* fall through */
  1052. case V4L2_PIX_FMT_ABGR32:
  1053. buf[0][offset] = b_v;
  1054. buf[0][offset + 1] = g_u;
  1055. buf[0][offset + 2] = r_y;
  1056. buf[0][offset + 3] = alpha;
  1057. break;
  1058. case V4L2_PIX_FMT_SBGGR8:
  1059. buf[0][offset] = odd ? g_u : b_v;
  1060. buf[1][offset] = odd ? r_y : g_u;
  1061. break;
  1062. case V4L2_PIX_FMT_SGBRG8:
  1063. buf[0][offset] = odd ? b_v : g_u;
  1064. buf[1][offset] = odd ? g_u : r_y;
  1065. break;
  1066. case V4L2_PIX_FMT_SGRBG8:
  1067. buf[0][offset] = odd ? r_y : g_u;
  1068. buf[1][offset] = odd ? g_u : b_v;
  1069. break;
  1070. case V4L2_PIX_FMT_SRGGB8:
  1071. buf[0][offset] = odd ? g_u : r_y;
  1072. buf[1][offset] = odd ? b_v : g_u;
  1073. break;
  1074. case V4L2_PIX_FMT_SBGGR10:
  1075. buf[0][offset] = odd ? g_u << 2 : b_v << 2;
  1076. buf[0][offset + 1] = odd ? g_u >> 6 : b_v >> 6;
  1077. buf[1][offset] = odd ? r_y << 2 : g_u << 2;
  1078. buf[1][offset + 1] = odd ? r_y >> 6 : g_u >> 6;
  1079. buf[0][offset] |= (buf[0][offset] >> 2) & 3;
  1080. buf[1][offset] |= (buf[1][offset] >> 2) & 3;
  1081. break;
  1082. case V4L2_PIX_FMT_SGBRG10:
  1083. buf[0][offset] = odd ? b_v << 2 : g_u << 2;
  1084. buf[0][offset + 1] = odd ? b_v >> 6 : g_u >> 6;
  1085. buf[1][offset] = odd ? g_u << 2 : r_y << 2;
  1086. buf[1][offset + 1] = odd ? g_u >> 6 : r_y >> 6;
  1087. buf[0][offset] |= (buf[0][offset] >> 2) & 3;
  1088. buf[1][offset] |= (buf[1][offset] >> 2) & 3;
  1089. break;
  1090. case V4L2_PIX_FMT_SGRBG10:
  1091. buf[0][offset] = odd ? r_y << 2 : g_u << 2;
  1092. buf[0][offset + 1] = odd ? r_y >> 6 : g_u >> 6;
  1093. buf[1][offset] = odd ? g_u << 2 : b_v << 2;
  1094. buf[1][offset + 1] = odd ? g_u >> 6 : b_v >> 6;
  1095. buf[0][offset] |= (buf[0][offset] >> 2) & 3;
  1096. buf[1][offset] |= (buf[1][offset] >> 2) & 3;
  1097. break;
  1098. case V4L2_PIX_FMT_SRGGB10:
  1099. buf[0][offset] = odd ? g_u << 2 : r_y << 2;
  1100. buf[0][offset + 1] = odd ? g_u >> 6 : r_y >> 6;
  1101. buf[1][offset] = odd ? b_v << 2 : g_u << 2;
  1102. buf[1][offset + 1] = odd ? b_v >> 6 : g_u >> 6;
  1103. buf[0][offset] |= (buf[0][offset] >> 2) & 3;
  1104. buf[1][offset] |= (buf[1][offset] >> 2) & 3;
  1105. break;
  1106. case V4L2_PIX_FMT_SBGGR12:
  1107. buf[0][offset] = odd ? g_u << 4 : b_v << 4;
  1108. buf[0][offset + 1] = odd ? g_u >> 4 : b_v >> 4;
  1109. buf[1][offset] = odd ? r_y << 4 : g_u << 4;
  1110. buf[1][offset + 1] = odd ? r_y >> 4 : g_u >> 4;
  1111. buf[0][offset] |= (buf[0][offset] >> 4) & 0xf;
  1112. buf[1][offset] |= (buf[1][offset] >> 4) & 0xf;
  1113. break;
  1114. case V4L2_PIX_FMT_SGBRG12:
  1115. buf[0][offset] = odd ? b_v << 4 : g_u << 4;
  1116. buf[0][offset + 1] = odd ? b_v >> 4 : g_u >> 4;
  1117. buf[1][offset] = odd ? g_u << 4 : r_y << 4;
  1118. buf[1][offset + 1] = odd ? g_u >> 4 : r_y >> 4;
  1119. buf[0][offset] |= (buf[0][offset] >> 4) & 0xf;
  1120. buf[1][offset] |= (buf[1][offset] >> 4) & 0xf;
  1121. break;
  1122. case V4L2_PIX_FMT_SGRBG12:
  1123. buf[0][offset] = odd ? r_y << 4 : g_u << 4;
  1124. buf[0][offset + 1] = odd ? r_y >> 4 : g_u >> 4;
  1125. buf[1][offset] = odd ? g_u << 4 : b_v << 4;
  1126. buf[1][offset + 1] = odd ? g_u >> 4 : b_v >> 4;
  1127. buf[0][offset] |= (buf[0][offset] >> 4) & 0xf;
  1128. buf[1][offset] |= (buf[1][offset] >> 4) & 0xf;
  1129. break;
  1130. case V4L2_PIX_FMT_SRGGB12:
  1131. buf[0][offset] = odd ? g_u << 4 : r_y << 4;
  1132. buf[0][offset + 1] = odd ? g_u >> 4 : r_y >> 4;
  1133. buf[1][offset] = odd ? b_v << 4 : g_u << 4;
  1134. buf[1][offset + 1] = odd ? b_v >> 4 : g_u >> 4;
  1135. buf[0][offset] |= (buf[0][offset] >> 4) & 0xf;
  1136. buf[1][offset] |= (buf[1][offset] >> 4) & 0xf;
  1137. break;
  1138. }
  1139. }
  1140. unsigned tpg_g_interleaved_plane(const struct tpg_data *tpg, unsigned buf_line)
  1141. {
  1142. switch (tpg->fourcc) {
  1143. case V4L2_PIX_FMT_SBGGR8:
  1144. case V4L2_PIX_FMT_SGBRG8:
  1145. case V4L2_PIX_FMT_SGRBG8:
  1146. case V4L2_PIX_FMT_SRGGB8:
  1147. case V4L2_PIX_FMT_SBGGR10:
  1148. case V4L2_PIX_FMT_SGBRG10:
  1149. case V4L2_PIX_FMT_SGRBG10:
  1150. case V4L2_PIX_FMT_SRGGB10:
  1151. case V4L2_PIX_FMT_SBGGR12:
  1152. case V4L2_PIX_FMT_SGBRG12:
  1153. case V4L2_PIX_FMT_SGRBG12:
  1154. case V4L2_PIX_FMT_SRGGB12:
  1155. return buf_line & 1;
  1156. default:
  1157. return 0;
  1158. }
  1159. }
  1160. /* Return how many pattern lines are used by the current pattern. */
  1161. static unsigned tpg_get_pat_lines(const struct tpg_data *tpg)
  1162. {
  1163. switch (tpg->pattern) {
  1164. case TPG_PAT_CHECKERS_16X16:
  1165. case TPG_PAT_CHECKERS_2X2:
  1166. case TPG_PAT_CHECKERS_1X1:
  1167. case TPG_PAT_COLOR_CHECKERS_2X2:
  1168. case TPG_PAT_COLOR_CHECKERS_1X1:
  1169. case TPG_PAT_ALTERNATING_HLINES:
  1170. case TPG_PAT_CROSS_1_PIXEL:
  1171. case TPG_PAT_CROSS_2_PIXELS:
  1172. case TPG_PAT_CROSS_10_PIXELS:
  1173. return 2;
  1174. case TPG_PAT_100_COLORSQUARES:
  1175. case TPG_PAT_100_HCOLORBAR:
  1176. return 8;
  1177. default:
  1178. return 1;
  1179. }
  1180. }
  1181. /* Which pattern line should be used for the given frame line. */
  1182. static unsigned tpg_get_pat_line(const struct tpg_data *tpg, unsigned line)
  1183. {
  1184. switch (tpg->pattern) {
  1185. case TPG_PAT_CHECKERS_16X16:
  1186. return (line >> 4) & 1;
  1187. case TPG_PAT_CHECKERS_1X1:
  1188. case TPG_PAT_COLOR_CHECKERS_1X1:
  1189. case TPG_PAT_ALTERNATING_HLINES:
  1190. return line & 1;
  1191. case TPG_PAT_CHECKERS_2X2:
  1192. case TPG_PAT_COLOR_CHECKERS_2X2:
  1193. return (line & 2) >> 1;
  1194. case TPG_PAT_100_COLORSQUARES:
  1195. case TPG_PAT_100_HCOLORBAR:
  1196. return (line * 8) / tpg->src_height;
  1197. case TPG_PAT_CROSS_1_PIXEL:
  1198. return line == tpg->src_height / 2;
  1199. case TPG_PAT_CROSS_2_PIXELS:
  1200. return (line + 1) / 2 == tpg->src_height / 4;
  1201. case TPG_PAT_CROSS_10_PIXELS:
  1202. return (line + 10) / 20 == tpg->src_height / 40;
  1203. default:
  1204. return 0;
  1205. }
  1206. }
  1207. /*
  1208. * Which color should be used for the given pattern line and X coordinate.
  1209. * Note: x is in the range 0 to 2 * tpg->src_width.
  1210. */
  1211. static enum tpg_color tpg_get_color(const struct tpg_data *tpg,
  1212. unsigned pat_line, unsigned x)
  1213. {
  1214. /* Maximum number of bars are TPG_COLOR_MAX - otherwise, the input print code
  1215. should be modified */
  1216. static const enum tpg_color bars[3][8] = {
  1217. /* Standard ITU-R 75% color bar sequence */
  1218. { TPG_COLOR_CSC_WHITE, TPG_COLOR_75_YELLOW,
  1219. TPG_COLOR_75_CYAN, TPG_COLOR_75_GREEN,
  1220. TPG_COLOR_75_MAGENTA, TPG_COLOR_75_RED,
  1221. TPG_COLOR_75_BLUE, TPG_COLOR_100_BLACK, },
  1222. /* Standard ITU-R 100% color bar sequence */
  1223. { TPG_COLOR_100_WHITE, TPG_COLOR_100_YELLOW,
  1224. TPG_COLOR_100_CYAN, TPG_COLOR_100_GREEN,
  1225. TPG_COLOR_100_MAGENTA, TPG_COLOR_100_RED,
  1226. TPG_COLOR_100_BLUE, TPG_COLOR_100_BLACK, },
  1227. /* Color bar sequence suitable to test CSC */
  1228. { TPG_COLOR_CSC_WHITE, TPG_COLOR_CSC_YELLOW,
  1229. TPG_COLOR_CSC_CYAN, TPG_COLOR_CSC_GREEN,
  1230. TPG_COLOR_CSC_MAGENTA, TPG_COLOR_CSC_RED,
  1231. TPG_COLOR_CSC_BLUE, TPG_COLOR_CSC_BLACK, },
  1232. };
  1233. switch (tpg->pattern) {
  1234. case TPG_PAT_75_COLORBAR:
  1235. case TPG_PAT_100_COLORBAR:
  1236. case TPG_PAT_CSC_COLORBAR:
  1237. return bars[tpg->pattern][((x * 8) / tpg->src_width) % 8];
  1238. case TPG_PAT_100_COLORSQUARES:
  1239. return bars[1][(pat_line + (x * 8) / tpg->src_width) % 8];
  1240. case TPG_PAT_100_HCOLORBAR:
  1241. return bars[1][pat_line];
  1242. case TPG_PAT_BLACK:
  1243. return TPG_COLOR_100_BLACK;
  1244. case TPG_PAT_WHITE:
  1245. return TPG_COLOR_100_WHITE;
  1246. case TPG_PAT_RED:
  1247. return TPG_COLOR_100_RED;
  1248. case TPG_PAT_GREEN:
  1249. return TPG_COLOR_100_GREEN;
  1250. case TPG_PAT_BLUE:
  1251. return TPG_COLOR_100_BLUE;
  1252. case TPG_PAT_CHECKERS_16X16:
  1253. return (((x >> 4) & 1) ^ (pat_line & 1)) ?
  1254. TPG_COLOR_100_BLACK : TPG_COLOR_100_WHITE;
  1255. case TPG_PAT_CHECKERS_1X1:
  1256. return ((x & 1) ^ (pat_line & 1)) ?
  1257. TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK;
  1258. case TPG_PAT_COLOR_CHECKERS_1X1:
  1259. return ((x & 1) ^ (pat_line & 1)) ?
  1260. TPG_COLOR_100_RED : TPG_COLOR_100_BLUE;
  1261. case TPG_PAT_CHECKERS_2X2:
  1262. return (((x >> 1) & 1) ^ (pat_line & 1)) ?
  1263. TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK;
  1264. case TPG_PAT_COLOR_CHECKERS_2X2:
  1265. return (((x >> 1) & 1) ^ (pat_line & 1)) ?
  1266. TPG_COLOR_100_RED : TPG_COLOR_100_BLUE;
  1267. case TPG_PAT_ALTERNATING_HLINES:
  1268. return pat_line ? TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK;
  1269. case TPG_PAT_ALTERNATING_VLINES:
  1270. return (x & 1) ? TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK;
  1271. case TPG_PAT_CROSS_1_PIXEL:
  1272. if (pat_line || (x % tpg->src_width) == tpg->src_width / 2)
  1273. return TPG_COLOR_100_BLACK;
  1274. return TPG_COLOR_100_WHITE;
  1275. case TPG_PAT_CROSS_2_PIXELS:
  1276. if (pat_line || ((x % tpg->src_width) + 1) / 2 == tpg->src_width / 4)
  1277. return TPG_COLOR_100_BLACK;
  1278. return TPG_COLOR_100_WHITE;
  1279. case TPG_PAT_CROSS_10_PIXELS:
  1280. if (pat_line || ((x % tpg->src_width) + 10) / 20 == tpg->src_width / 40)
  1281. return TPG_COLOR_100_BLACK;
  1282. return TPG_COLOR_100_WHITE;
  1283. case TPG_PAT_GRAY_RAMP:
  1284. return TPG_COLOR_RAMP + ((x % tpg->src_width) * 256) / tpg->src_width;
  1285. default:
  1286. return TPG_COLOR_100_RED;
  1287. }
  1288. }
  1289. /*
  1290. * Given the pixel aspect ratio and video aspect ratio calculate the
  1291. * coordinates of a centered square and the coordinates of the border of
  1292. * the active video area. The coordinates are relative to the source
  1293. * frame rectangle.
  1294. */
  1295. static void tpg_calculate_square_border(struct tpg_data *tpg)
  1296. {
  1297. unsigned w = tpg->src_width;
  1298. unsigned h = tpg->src_height;
  1299. unsigned sq_w, sq_h;
  1300. sq_w = (w * 2 / 5) & ~1;
  1301. if (((w - sq_w) / 2) & 1)
  1302. sq_w += 2;
  1303. sq_h = sq_w;
  1304. tpg->square.width = sq_w;
  1305. if (tpg->vid_aspect == TPG_VIDEO_ASPECT_16X9_ANAMORPHIC) {
  1306. unsigned ana_sq_w = (sq_w / 4) * 3;
  1307. if (((w - ana_sq_w) / 2) & 1)
  1308. ana_sq_w += 2;
  1309. tpg->square.width = ana_sq_w;
  1310. }
  1311. tpg->square.left = (w - tpg->square.width) / 2;
  1312. if (tpg->pix_aspect == TPG_PIXEL_ASPECT_NTSC)
  1313. sq_h = sq_w * 10 / 11;
  1314. else if (tpg->pix_aspect == TPG_PIXEL_ASPECT_PAL)
  1315. sq_h = sq_w * 59 / 54;
  1316. tpg->square.height = sq_h;
  1317. tpg->square.top = (h - sq_h) / 2;
  1318. tpg->border.left = 0;
  1319. tpg->border.width = w;
  1320. tpg->border.top = 0;
  1321. tpg->border.height = h;
  1322. switch (tpg->vid_aspect) {
  1323. case TPG_VIDEO_ASPECT_4X3:
  1324. if (tpg->pix_aspect)
  1325. return;
  1326. if (3 * w >= 4 * h) {
  1327. tpg->border.width = ((4 * h) / 3) & ~1;
  1328. if (((w - tpg->border.width) / 2) & ~1)
  1329. tpg->border.width -= 2;
  1330. tpg->border.left = (w - tpg->border.width) / 2;
  1331. break;
  1332. }
  1333. tpg->border.height = ((3 * w) / 4) & ~1;
  1334. tpg->border.top = (h - tpg->border.height) / 2;
  1335. break;
  1336. case TPG_VIDEO_ASPECT_14X9_CENTRE:
  1337. if (tpg->pix_aspect) {
  1338. tpg->border.height = tpg->pix_aspect == TPG_PIXEL_ASPECT_NTSC ? 420 : 506;
  1339. tpg->border.top = (h - tpg->border.height) / 2;
  1340. break;
  1341. }
  1342. if (9 * w >= 14 * h) {
  1343. tpg->border.width = ((14 * h) / 9) & ~1;
  1344. if (((w - tpg->border.width) / 2) & ~1)
  1345. tpg->border.width -= 2;
  1346. tpg->border.left = (w - tpg->border.width) / 2;
  1347. break;
  1348. }
  1349. tpg->border.height = ((9 * w) / 14) & ~1;
  1350. tpg->border.top = (h - tpg->border.height) / 2;
  1351. break;
  1352. case TPG_VIDEO_ASPECT_16X9_CENTRE:
  1353. if (tpg->pix_aspect) {
  1354. tpg->border.height = tpg->pix_aspect == TPG_PIXEL_ASPECT_NTSC ? 368 : 442;
  1355. tpg->border.top = (h - tpg->border.height) / 2;
  1356. break;
  1357. }
  1358. if (9 * w >= 16 * h) {
  1359. tpg->border.width = ((16 * h) / 9) & ~1;
  1360. if (((w - tpg->border.width) / 2) & ~1)
  1361. tpg->border.width -= 2;
  1362. tpg->border.left = (w - tpg->border.width) / 2;
  1363. break;
  1364. }
  1365. tpg->border.height = ((9 * w) / 16) & ~1;
  1366. tpg->border.top = (h - tpg->border.height) / 2;
  1367. break;
  1368. default:
  1369. break;
  1370. }
  1371. }
  1372. static void tpg_precalculate_line(struct tpg_data *tpg)
  1373. {
  1374. enum tpg_color contrast;
  1375. u8 pix[TPG_MAX_PLANES][8];
  1376. unsigned pat;
  1377. unsigned p;
  1378. unsigned x;
  1379. switch (tpg->pattern) {
  1380. case TPG_PAT_GREEN:
  1381. contrast = TPG_COLOR_100_RED;
  1382. break;
  1383. case TPG_PAT_CSC_COLORBAR:
  1384. contrast = TPG_COLOR_CSC_GREEN;
  1385. break;
  1386. default:
  1387. contrast = TPG_COLOR_100_GREEN;
  1388. break;
  1389. }
  1390. for (pat = 0; pat < tpg_get_pat_lines(tpg); pat++) {
  1391. /* Coarse scaling with Bresenham */
  1392. unsigned int_part = tpg->src_width / tpg->scaled_width;
  1393. unsigned fract_part = tpg->src_width % tpg->scaled_width;
  1394. unsigned src_x = 0;
  1395. unsigned error = 0;
  1396. for (x = 0; x < tpg->scaled_width * 2; x += 2) {
  1397. unsigned real_x = src_x;
  1398. enum tpg_color color1, color2;
  1399. real_x = tpg->hflip ? tpg->src_width * 2 - real_x - 2 : real_x;
  1400. color1 = tpg_get_color(tpg, pat, real_x);
  1401. src_x += int_part;
  1402. error += fract_part;
  1403. if (error >= tpg->scaled_width) {
  1404. error -= tpg->scaled_width;
  1405. src_x++;
  1406. }
  1407. real_x = src_x;
  1408. real_x = tpg->hflip ? tpg->src_width * 2 - real_x - 2 : real_x;
  1409. color2 = tpg_get_color(tpg, pat, real_x);
  1410. src_x += int_part;
  1411. error += fract_part;
  1412. if (error >= tpg->scaled_width) {
  1413. error -= tpg->scaled_width;
  1414. src_x++;
  1415. }
  1416. gen_twopix(tpg, pix, tpg->hflip ? color2 : color1, 0);
  1417. gen_twopix(tpg, pix, tpg->hflip ? color1 : color2, 1);
  1418. for (p = 0; p < tpg->planes; p++) {
  1419. unsigned twopixsize = tpg->twopixelsize[p];
  1420. unsigned hdiv = tpg->hdownsampling[p];
  1421. u8 *pos = tpg->lines[pat][p] + tpg_hdiv(tpg, p, x);
  1422. memcpy(pos, pix[p], twopixsize / hdiv);
  1423. }
  1424. }
  1425. }
  1426. if (tpg->vdownsampling[tpg->planes - 1] > 1) {
  1427. unsigned pat_lines = tpg_get_pat_lines(tpg);
  1428. for (pat = 0; pat < pat_lines; pat++) {
  1429. unsigned next_pat = (pat + 1) % pat_lines;
  1430. for (p = 1; p < tpg->planes; p++) {
  1431. unsigned w = tpg_hdiv(tpg, p, tpg->scaled_width * 2);
  1432. u8 *pos1 = tpg->lines[pat][p];
  1433. u8 *pos2 = tpg->lines[next_pat][p];
  1434. u8 *dest = tpg->downsampled_lines[pat][p];
  1435. for (x = 0; x < w; x++, pos1++, pos2++, dest++)
  1436. *dest = ((u16)*pos1 + (u16)*pos2) / 2;
  1437. }
  1438. }
  1439. }
  1440. gen_twopix(tpg, pix, contrast, 0);
  1441. gen_twopix(tpg, pix, contrast, 1);
  1442. for (p = 0; p < tpg->planes; p++) {
  1443. unsigned twopixsize = tpg->twopixelsize[p];
  1444. u8 *pos = tpg->contrast_line[p];
  1445. for (x = 0; x < tpg->scaled_width; x += 2, pos += twopixsize)
  1446. memcpy(pos, pix[p], twopixsize);
  1447. }
  1448. gen_twopix(tpg, pix, TPG_COLOR_100_BLACK, 0);
  1449. gen_twopix(tpg, pix, TPG_COLOR_100_BLACK, 1);
  1450. for (p = 0; p < tpg->planes; p++) {
  1451. unsigned twopixsize = tpg->twopixelsize[p];
  1452. u8 *pos = tpg->black_line[p];
  1453. for (x = 0; x < tpg->scaled_width; x += 2, pos += twopixsize)
  1454. memcpy(pos, pix[p], twopixsize);
  1455. }
  1456. for (x = 0; x < tpg->scaled_width * 2; x += 2) {
  1457. gen_twopix(tpg, pix, TPG_COLOR_RANDOM, 0);
  1458. gen_twopix(tpg, pix, TPG_COLOR_RANDOM, 1);
  1459. for (p = 0; p < tpg->planes; p++) {
  1460. unsigned twopixsize = tpg->twopixelsize[p];
  1461. u8 *pos = tpg->random_line[p] + x * twopixsize / 2;
  1462. memcpy(pos, pix[p], twopixsize);
  1463. }
  1464. }
  1465. gen_twopix(tpg, tpg->textbg, TPG_COLOR_TEXTBG, 0);
  1466. gen_twopix(tpg, tpg->textbg, TPG_COLOR_TEXTBG, 1);
  1467. gen_twopix(tpg, tpg->textfg, TPG_COLOR_TEXTFG, 0);
  1468. gen_twopix(tpg, tpg->textfg, TPG_COLOR_TEXTFG, 1);
  1469. }
  1470. /* need this to do rgb24 rendering */
  1471. typedef struct { u16 __; u8 _; } __packed x24;
  1472. #define PRINTSTR(PIXTYPE) do { \
  1473. unsigned vdiv = tpg->vdownsampling[p]; \
  1474. unsigned hdiv = tpg->hdownsampling[p]; \
  1475. int line; \
  1476. PIXTYPE fg; \
  1477. PIXTYPE bg; \
  1478. memcpy(&fg, tpg->textfg[p], sizeof(PIXTYPE)); \
  1479. memcpy(&bg, tpg->textbg[p], sizeof(PIXTYPE)); \
  1480. \
  1481. for (line = first; line < 16; line += vdiv * step) { \
  1482. int l = tpg->vflip ? 15 - line : line; \
  1483. PIXTYPE *pos = (PIXTYPE *)(basep[p][(line / vdiv) & 1] + \
  1484. ((y * step + l) / (vdiv * div)) * tpg->bytesperline[p] + \
  1485. (x / hdiv) * sizeof(PIXTYPE)); \
  1486. unsigned s; \
  1487. \
  1488. for (s = 0; s < len; s++) { \
  1489. u8 chr = font8x16[text[s] * 16 + line]; \
  1490. \
  1491. if (hdiv == 2 && tpg->hflip) { \
  1492. pos[3] = (chr & (0x01 << 6) ? fg : bg); \
  1493. pos[2] = (chr & (0x01 << 4) ? fg : bg); \
  1494. pos[1] = (chr & (0x01 << 2) ? fg : bg); \
  1495. pos[0] = (chr & (0x01 << 0) ? fg : bg); \
  1496. } else if (hdiv == 2) { \
  1497. pos[0] = (chr & (0x01 << 7) ? fg : bg); \
  1498. pos[1] = (chr & (0x01 << 5) ? fg : bg); \
  1499. pos[2] = (chr & (0x01 << 3) ? fg : bg); \
  1500. pos[3] = (chr & (0x01 << 1) ? fg : bg); \
  1501. } else if (tpg->hflip) { \
  1502. pos[7] = (chr & (0x01 << 7) ? fg : bg); \
  1503. pos[6] = (chr & (0x01 << 6) ? fg : bg); \
  1504. pos[5] = (chr & (0x01 << 5) ? fg : bg); \
  1505. pos[4] = (chr & (0x01 << 4) ? fg : bg); \
  1506. pos[3] = (chr & (0x01 << 3) ? fg : bg); \
  1507. pos[2] = (chr & (0x01 << 2) ? fg : bg); \
  1508. pos[1] = (chr & (0x01 << 1) ? fg : bg); \
  1509. pos[0] = (chr & (0x01 << 0) ? fg : bg); \
  1510. } else { \
  1511. pos[0] = (chr & (0x01 << 7) ? fg : bg); \
  1512. pos[1] = (chr & (0x01 << 6) ? fg : bg); \
  1513. pos[2] = (chr & (0x01 << 5) ? fg : bg); \
  1514. pos[3] = (chr & (0x01 << 4) ? fg : bg); \
  1515. pos[4] = (chr & (0x01 << 3) ? fg : bg); \
  1516. pos[5] = (chr & (0x01 << 2) ? fg : bg); \
  1517. pos[6] = (chr & (0x01 << 1) ? fg : bg); \
  1518. pos[7] = (chr & (0x01 << 0) ? fg : bg); \
  1519. } \
  1520. \
  1521. pos += (tpg->hflip ? -8 : 8) / hdiv; \
  1522. } \
  1523. } \
  1524. } while (0)
  1525. static noinline void tpg_print_str_2(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
  1526. unsigned p, unsigned first, unsigned div, unsigned step,
  1527. int y, int x, char *text, unsigned len)
  1528. {
  1529. PRINTSTR(u8);
  1530. }
  1531. static noinline void tpg_print_str_4(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
  1532. unsigned p, unsigned first, unsigned div, unsigned step,
  1533. int y, int x, char *text, unsigned len)
  1534. {
  1535. PRINTSTR(u16);
  1536. }
  1537. static noinline void tpg_print_str_6(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
  1538. unsigned p, unsigned first, unsigned div, unsigned step,
  1539. int y, int x, char *text, unsigned len)
  1540. {
  1541. PRINTSTR(x24);
  1542. }
  1543. static noinline void tpg_print_str_8(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
  1544. unsigned p, unsigned first, unsigned div, unsigned step,
  1545. int y, int x, char *text, unsigned len)
  1546. {
  1547. PRINTSTR(u32);
  1548. }
  1549. void tpg_gen_text(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
  1550. int y, int x, char *text)
  1551. {
  1552. unsigned step = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1;
  1553. unsigned div = step;
  1554. unsigned first = 0;
  1555. unsigned len = strlen(text);
  1556. unsigned p;
  1557. if (font8x16 == NULL || basep == NULL)
  1558. return;
  1559. /* Checks if it is possible to show string */
  1560. if (y + 16 >= tpg->compose.height || x + 8 >= tpg->compose.width)
  1561. return;
  1562. if (len > (tpg->compose.width - x) / 8)
  1563. len = (tpg->compose.width - x) / 8;
  1564. if (tpg->vflip)
  1565. y = tpg->compose.height - y - 16;
  1566. if (tpg->hflip)
  1567. x = tpg->compose.width - x - 8;
  1568. y += tpg->compose.top;
  1569. x += tpg->compose.left;
  1570. if (tpg->field == V4L2_FIELD_BOTTOM)
  1571. first = 1;
  1572. else if (tpg->field == V4L2_FIELD_SEQ_TB || tpg->field == V4L2_FIELD_SEQ_BT)
  1573. div = 2;
  1574. for (p = 0; p < tpg->planes; p++) {
  1575. /* Print text */
  1576. switch (tpg->twopixelsize[p]) {
  1577. case 2:
  1578. tpg_print_str_2(tpg, basep, p, first, div, step, y, x,
  1579. text, len);
  1580. break;
  1581. case 4:
  1582. tpg_print_str_4(tpg, basep, p, first, div, step, y, x,
  1583. text, len);
  1584. break;
  1585. case 6:
  1586. tpg_print_str_6(tpg, basep, p, first, div, step, y, x,
  1587. text, len);
  1588. break;
  1589. case 8:
  1590. tpg_print_str_8(tpg, basep, p, first, div, step, y, x,
  1591. text, len);
  1592. break;
  1593. }
  1594. }
  1595. }
  1596. void tpg_update_mv_step(struct tpg_data *tpg)
  1597. {
  1598. int factor = tpg->mv_hor_mode > TPG_MOVE_NONE ? -1 : 1;
  1599. if (tpg->hflip)
  1600. factor = -factor;
  1601. switch (tpg->mv_hor_mode) {
  1602. case TPG_MOVE_NEG_FAST:
  1603. case TPG_MOVE_POS_FAST:
  1604. tpg->mv_hor_step = ((tpg->src_width + 319) / 320) * 4;
  1605. break;
  1606. case TPG_MOVE_NEG:
  1607. case TPG_MOVE_POS:
  1608. tpg->mv_hor_step = ((tpg->src_width + 639) / 640) * 4;
  1609. break;
  1610. case TPG_MOVE_NEG_SLOW:
  1611. case TPG_MOVE_POS_SLOW:
  1612. tpg->mv_hor_step = 2;
  1613. break;
  1614. case TPG_MOVE_NONE:
  1615. tpg->mv_hor_step = 0;
  1616. break;
  1617. }
  1618. if (factor < 0)
  1619. tpg->mv_hor_step = tpg->src_width - tpg->mv_hor_step;
  1620. factor = tpg->mv_vert_mode > TPG_MOVE_NONE ? -1 : 1;
  1621. switch (tpg->mv_vert_mode) {
  1622. case TPG_MOVE_NEG_FAST:
  1623. case TPG_MOVE_POS_FAST:
  1624. tpg->mv_vert_step = ((tpg->src_width + 319) / 320) * 4;
  1625. break;
  1626. case TPG_MOVE_NEG:
  1627. case TPG_MOVE_POS:
  1628. tpg->mv_vert_step = ((tpg->src_width + 639) / 640) * 4;
  1629. break;
  1630. case TPG_MOVE_NEG_SLOW:
  1631. case TPG_MOVE_POS_SLOW:
  1632. tpg->mv_vert_step = 1;
  1633. break;
  1634. case TPG_MOVE_NONE:
  1635. tpg->mv_vert_step = 0;
  1636. break;
  1637. }
  1638. if (factor < 0)
  1639. tpg->mv_vert_step = tpg->src_height - tpg->mv_vert_step;
  1640. }
  1641. /* Map the line number relative to the crop rectangle to a frame line number */
  1642. static unsigned tpg_calc_frameline(const struct tpg_data *tpg, unsigned src_y,
  1643. unsigned field)
  1644. {
  1645. switch (field) {
  1646. case V4L2_FIELD_TOP:
  1647. return tpg->crop.top + src_y * 2;
  1648. case V4L2_FIELD_BOTTOM:
  1649. return tpg->crop.top + src_y * 2 + 1;
  1650. default:
  1651. return src_y + tpg->crop.top;
  1652. }
  1653. }
  1654. /*
  1655. * Map the line number relative to the compose rectangle to a destination
  1656. * buffer line number.
  1657. */
  1658. static unsigned tpg_calc_buffer_line(const struct tpg_data *tpg, unsigned y,
  1659. unsigned field)
  1660. {
  1661. y += tpg->compose.top;
  1662. switch (field) {
  1663. case V4L2_FIELD_SEQ_TB:
  1664. if (y & 1)
  1665. return tpg->buf_height / 2 + y / 2;
  1666. return y / 2;
  1667. case V4L2_FIELD_SEQ_BT:
  1668. if (y & 1)
  1669. return y / 2;
  1670. return tpg->buf_height / 2 + y / 2;
  1671. default:
  1672. return y;
  1673. }
  1674. }
  1675. static void tpg_recalc(struct tpg_data *tpg)
  1676. {
  1677. if (tpg->recalc_colors) {
  1678. tpg->recalc_colors = false;
  1679. tpg->recalc_lines = true;
  1680. tpg->real_xfer_func = tpg->xfer_func;
  1681. tpg->real_ycbcr_enc = tpg->ycbcr_enc;
  1682. tpg->real_quantization = tpg->quantization;
  1683. if (tpg->xfer_func == V4L2_XFER_FUNC_DEFAULT)
  1684. tpg->real_xfer_func =
  1685. V4L2_MAP_XFER_FUNC_DEFAULT(tpg->colorspace);
  1686. if (tpg->ycbcr_enc == V4L2_YCBCR_ENC_DEFAULT)
  1687. tpg->real_ycbcr_enc =
  1688. V4L2_MAP_YCBCR_ENC_DEFAULT(tpg->colorspace);
  1689. if (tpg->quantization == V4L2_QUANTIZATION_DEFAULT)
  1690. tpg->real_quantization =
  1691. V4L2_MAP_QUANTIZATION_DEFAULT(!tpg->is_yuv,
  1692. tpg->colorspace, tpg->real_ycbcr_enc);
  1693. tpg_precalculate_colors(tpg);
  1694. }
  1695. if (tpg->recalc_square_border) {
  1696. tpg->recalc_square_border = false;
  1697. tpg_calculate_square_border(tpg);
  1698. }
  1699. if (tpg->recalc_lines) {
  1700. tpg->recalc_lines = false;
  1701. tpg_precalculate_line(tpg);
  1702. }
  1703. }
  1704. void tpg_calc_text_basep(struct tpg_data *tpg,
  1705. u8 *basep[TPG_MAX_PLANES][2], unsigned p, u8 *vbuf)
  1706. {
  1707. unsigned stride = tpg->bytesperline[p];
  1708. unsigned h = tpg->buf_height;
  1709. tpg_recalc(tpg);
  1710. basep[p][0] = vbuf;
  1711. basep[p][1] = vbuf;
  1712. h /= tpg->vdownsampling[p];
  1713. if (tpg->field == V4L2_FIELD_SEQ_TB)
  1714. basep[p][1] += h * stride / 2;
  1715. else if (tpg->field == V4L2_FIELD_SEQ_BT)
  1716. basep[p][0] += h * stride / 2;
  1717. if (p == 0 && tpg->interleaved)
  1718. tpg_calc_text_basep(tpg, basep, 1, vbuf);
  1719. }
  1720. static int tpg_pattern_avg(const struct tpg_data *tpg,
  1721. unsigned pat1, unsigned pat2)
  1722. {
  1723. unsigned pat_lines = tpg_get_pat_lines(tpg);
  1724. if (pat1 == (pat2 + 1) % pat_lines)
  1725. return pat2;
  1726. if (pat2 == (pat1 + 1) % pat_lines)
  1727. return pat1;
  1728. return -1;
  1729. }
  1730. void tpg_log_status(struct tpg_data *tpg)
  1731. {
  1732. pr_info("tpg source WxH: %ux%u (%s)\n",
  1733. tpg->src_width, tpg->src_height,
  1734. tpg->is_yuv ? "YCbCr" : "RGB");
  1735. pr_info("tpg field: %u\n", tpg->field);
  1736. pr_info("tpg crop: %ux%u@%dx%d\n", tpg->crop.width, tpg->crop.height,
  1737. tpg->crop.left, tpg->crop.top);
  1738. pr_info("tpg compose: %ux%u@%dx%d\n", tpg->compose.width, tpg->compose.height,
  1739. tpg->compose.left, tpg->compose.top);
  1740. pr_info("tpg colorspace: %d\n", tpg->colorspace);
  1741. pr_info("tpg transfer function: %d/%d\n", tpg->xfer_func, tpg->real_xfer_func);
  1742. pr_info("tpg Y'CbCr encoding: %d/%d\n", tpg->ycbcr_enc, tpg->real_ycbcr_enc);
  1743. pr_info("tpg quantization: %d/%d\n", tpg->quantization, tpg->real_quantization);
  1744. pr_info("tpg RGB range: %d/%d\n", tpg->rgb_range, tpg->real_rgb_range);
  1745. }
  1746. /*
  1747. * This struct contains common parameters used by both the drawing of the
  1748. * test pattern and the drawing of the extras (borders, square, etc.)
  1749. */
  1750. struct tpg_draw_params {
  1751. /* common data */
  1752. bool is_tv;
  1753. bool is_60hz;
  1754. unsigned twopixsize;
  1755. unsigned img_width;
  1756. unsigned stride;
  1757. unsigned hmax;
  1758. unsigned frame_line;
  1759. unsigned frame_line_next;
  1760. /* test pattern */
  1761. unsigned mv_hor_old;
  1762. unsigned mv_hor_new;
  1763. unsigned mv_vert_old;
  1764. unsigned mv_vert_new;
  1765. /* extras */
  1766. unsigned wss_width;
  1767. unsigned wss_random_offset;
  1768. unsigned sav_eav_f;
  1769. unsigned left_pillar_width;
  1770. unsigned right_pillar_start;
  1771. };
  1772. static void tpg_fill_params_pattern(const struct tpg_data *tpg, unsigned p,
  1773. struct tpg_draw_params *params)
  1774. {
  1775. params->mv_hor_old =
  1776. tpg_hscale_div(tpg, p, tpg->mv_hor_count % tpg->src_width);
  1777. params->mv_hor_new =
  1778. tpg_hscale_div(tpg, p, (tpg->mv_hor_count + tpg->mv_hor_step) %
  1779. tpg->src_width);
  1780. params->mv_vert_old = tpg->mv_vert_count % tpg->src_height;
  1781. params->mv_vert_new =
  1782. (tpg->mv_vert_count + tpg->mv_vert_step) % tpg->src_height;
  1783. }
  1784. static void tpg_fill_params_extras(const struct tpg_data *tpg,
  1785. unsigned p,
  1786. struct tpg_draw_params *params)
  1787. {
  1788. unsigned left_pillar_width = 0;
  1789. unsigned right_pillar_start = params->img_width;
  1790. params->wss_width = tpg->crop.left < tpg->src_width / 2 ?
  1791. tpg->src_width / 2 - tpg->crop.left : 0;
  1792. if (params->wss_width > tpg->crop.width)
  1793. params->wss_width = tpg->crop.width;
  1794. params->wss_width = tpg_hscale_div(tpg, p, params->wss_width);
  1795. params->wss_random_offset =
  1796. params->twopixsize * prandom_u32_max(tpg->src_width / 2);
  1797. if (tpg->crop.left < tpg->border.left) {
  1798. left_pillar_width = tpg->border.left - tpg->crop.left;
  1799. if (left_pillar_width > tpg->crop.width)
  1800. left_pillar_width = tpg->crop.width;
  1801. left_pillar_width = tpg_hscale_div(tpg, p, left_pillar_width);
  1802. }
  1803. params->left_pillar_width = left_pillar_width;
  1804. if (tpg->crop.left + tpg->crop.width >
  1805. tpg->border.left + tpg->border.width) {
  1806. right_pillar_start =
  1807. tpg->border.left + tpg->border.width - tpg->crop.left;
  1808. right_pillar_start =
  1809. tpg_hscale_div(tpg, p, right_pillar_start);
  1810. if (right_pillar_start > params->img_width)
  1811. right_pillar_start = params->img_width;
  1812. }
  1813. params->right_pillar_start = right_pillar_start;
  1814. params->sav_eav_f = tpg->field ==
  1815. (params->is_60hz ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
  1816. }
  1817. static void tpg_fill_plane_extras(const struct tpg_data *tpg,
  1818. const struct tpg_draw_params *params,
  1819. unsigned p, unsigned h, u8 *vbuf)
  1820. {
  1821. unsigned twopixsize = params->twopixsize;
  1822. unsigned img_width = params->img_width;
  1823. unsigned frame_line = params->frame_line;
  1824. const struct v4l2_rect *sq = &tpg->square;
  1825. const struct v4l2_rect *b = &tpg->border;
  1826. const struct v4l2_rect *c = &tpg->crop;
  1827. if (params->is_tv && !params->is_60hz &&
  1828. frame_line == 0 && params->wss_width) {
  1829. /*
  1830. * Replace the first half of the top line of a 50 Hz frame
  1831. * with random data to simulate a WSS signal.
  1832. */
  1833. u8 *wss = tpg->random_line[p] + params->wss_random_offset;
  1834. memcpy(vbuf, wss, params->wss_width);
  1835. }
  1836. if (tpg->show_border && frame_line >= b->top &&
  1837. frame_line < b->top + b->height) {
  1838. unsigned bottom = b->top + b->height - 1;
  1839. unsigned left = params->left_pillar_width;
  1840. unsigned right = params->right_pillar_start;
  1841. if (frame_line == b->top || frame_line == b->top + 1 ||
  1842. frame_line == bottom || frame_line == bottom - 1) {
  1843. memcpy(vbuf + left, tpg->contrast_line[p],
  1844. right - left);
  1845. } else {
  1846. if (b->left >= c->left &&
  1847. b->left < c->left + c->width)
  1848. memcpy(vbuf + left,
  1849. tpg->contrast_line[p], twopixsize);
  1850. if (b->left + b->width > c->left &&
  1851. b->left + b->width <= c->left + c->width)
  1852. memcpy(vbuf + right - twopixsize,
  1853. tpg->contrast_line[p], twopixsize);
  1854. }
  1855. }
  1856. if (tpg->qual != TPG_QUAL_NOISE && frame_line >= b->top &&
  1857. frame_line < b->top + b->height) {
  1858. memcpy(vbuf, tpg->black_line[p], params->left_pillar_width);
  1859. memcpy(vbuf + params->right_pillar_start, tpg->black_line[p],
  1860. img_width - params->right_pillar_start);
  1861. }
  1862. if (tpg->show_square && frame_line >= sq->top &&
  1863. frame_line < sq->top + sq->height &&
  1864. sq->left < c->left + c->width &&
  1865. sq->left + sq->width >= c->left) {
  1866. unsigned left = sq->left;
  1867. unsigned width = sq->width;
  1868. if (c->left > left) {
  1869. width -= c->left - left;
  1870. left = c->left;
  1871. }
  1872. if (c->left + c->width < left + width)
  1873. width -= left + width - c->left - c->width;
  1874. left -= c->left;
  1875. left = tpg_hscale_div(tpg, p, left);
  1876. width = tpg_hscale_div(tpg, p, width);
  1877. memcpy(vbuf + left, tpg->contrast_line[p], width);
  1878. }
  1879. if (tpg->insert_sav) {
  1880. unsigned offset = tpg_hdiv(tpg, p, tpg->compose.width / 3);
  1881. u8 *p = vbuf + offset;
  1882. unsigned vact = 0, hact = 0;
  1883. p[0] = 0xff;
  1884. p[1] = 0;
  1885. p[2] = 0;
  1886. p[3] = 0x80 | (params->sav_eav_f << 6) |
  1887. (vact << 5) | (hact << 4) |
  1888. ((hact ^ vact) << 3) |
  1889. ((hact ^ params->sav_eav_f) << 2) |
  1890. ((params->sav_eav_f ^ vact) << 1) |
  1891. (hact ^ vact ^ params->sav_eav_f);
  1892. }
  1893. if (tpg->insert_eav) {
  1894. unsigned offset = tpg_hdiv(tpg, p, tpg->compose.width * 2 / 3);
  1895. u8 *p = vbuf + offset;
  1896. unsigned vact = 0, hact = 1;
  1897. p[0] = 0xff;
  1898. p[1] = 0;
  1899. p[2] = 0;
  1900. p[3] = 0x80 | (params->sav_eav_f << 6) |
  1901. (vact << 5) | (hact << 4) |
  1902. ((hact ^ vact) << 3) |
  1903. ((hact ^ params->sav_eav_f) << 2) |
  1904. ((params->sav_eav_f ^ vact) << 1) |
  1905. (hact ^ vact ^ params->sav_eav_f);
  1906. }
  1907. }
  1908. static void tpg_fill_plane_pattern(const struct tpg_data *tpg,
  1909. const struct tpg_draw_params *params,
  1910. unsigned p, unsigned h, u8 *vbuf)
  1911. {
  1912. unsigned twopixsize = params->twopixsize;
  1913. unsigned img_width = params->img_width;
  1914. unsigned mv_hor_old = params->mv_hor_old;
  1915. unsigned mv_hor_new = params->mv_hor_new;
  1916. unsigned mv_vert_old = params->mv_vert_old;
  1917. unsigned mv_vert_new = params->mv_vert_new;
  1918. unsigned frame_line = params->frame_line;
  1919. unsigned frame_line_next = params->frame_line_next;
  1920. unsigned line_offset = tpg_hscale_div(tpg, p, tpg->crop.left);
  1921. bool even;
  1922. bool fill_blank = false;
  1923. unsigned pat_line_old;
  1924. unsigned pat_line_new;
  1925. u8 *linestart_older;
  1926. u8 *linestart_newer;
  1927. u8 *linestart_top;
  1928. u8 *linestart_bottom;
  1929. even = !(frame_line & 1);
  1930. if (h >= params->hmax) {
  1931. if (params->hmax == tpg->compose.height)
  1932. return;
  1933. if (!tpg->perc_fill_blank)
  1934. return;
  1935. fill_blank = true;
  1936. }
  1937. if (tpg->vflip) {
  1938. frame_line = tpg->src_height - frame_line - 1;
  1939. frame_line_next = tpg->src_height - frame_line_next - 1;
  1940. }
  1941. if (fill_blank) {
  1942. linestart_older = tpg->contrast_line[p];
  1943. linestart_newer = tpg->contrast_line[p];
  1944. } else if (tpg->qual != TPG_QUAL_NOISE &&
  1945. (frame_line < tpg->border.top ||
  1946. frame_line >= tpg->border.top + tpg->border.height)) {
  1947. linestart_older = tpg->black_line[p];
  1948. linestart_newer = tpg->black_line[p];
  1949. } else if (tpg->pattern == TPG_PAT_NOISE || tpg->qual == TPG_QUAL_NOISE) {
  1950. linestart_older = tpg->random_line[p] +
  1951. twopixsize * prandom_u32_max(tpg->src_width / 2);
  1952. linestart_newer = tpg->random_line[p] +
  1953. twopixsize * prandom_u32_max(tpg->src_width / 2);
  1954. } else {
  1955. unsigned frame_line_old =
  1956. (frame_line + mv_vert_old) % tpg->src_height;
  1957. unsigned frame_line_new =
  1958. (frame_line + mv_vert_new) % tpg->src_height;
  1959. unsigned pat_line_next_old;
  1960. unsigned pat_line_next_new;
  1961. pat_line_old = tpg_get_pat_line(tpg, frame_line_old);
  1962. pat_line_new = tpg_get_pat_line(tpg, frame_line_new);
  1963. linestart_older = tpg->lines[pat_line_old][p] + mv_hor_old;
  1964. linestart_newer = tpg->lines[pat_line_new][p] + mv_hor_new;
  1965. if (tpg->vdownsampling[p] > 1 && frame_line != frame_line_next) {
  1966. int avg_pat;
  1967. /*
  1968. * Now decide whether we need to use downsampled_lines[].
  1969. * That's necessary if the two lines use different patterns.
  1970. */
  1971. pat_line_next_old = tpg_get_pat_line(tpg,
  1972. (frame_line_next + mv_vert_old) % tpg->src_height);
  1973. pat_line_next_new = tpg_get_pat_line(tpg,
  1974. (frame_line_next + mv_vert_new) % tpg->src_height);
  1975. switch (tpg->field) {
  1976. case V4L2_FIELD_INTERLACED:
  1977. case V4L2_FIELD_INTERLACED_BT:
  1978. case V4L2_FIELD_INTERLACED_TB:
  1979. avg_pat = tpg_pattern_avg(tpg, pat_line_old, pat_line_new);
  1980. if (avg_pat < 0)
  1981. break;
  1982. linestart_older = tpg->downsampled_lines[avg_pat][p] + mv_hor_old;
  1983. linestart_newer = linestart_older;
  1984. break;
  1985. case V4L2_FIELD_NONE:
  1986. case V4L2_FIELD_TOP:
  1987. case V4L2_FIELD_BOTTOM:
  1988. case V4L2_FIELD_SEQ_BT:
  1989. case V4L2_FIELD_SEQ_TB:
  1990. avg_pat = tpg_pattern_avg(tpg, pat_line_old, pat_line_next_old);
  1991. if (avg_pat >= 0)
  1992. linestart_older = tpg->downsampled_lines[avg_pat][p] +
  1993. mv_hor_old;
  1994. avg_pat = tpg_pattern_avg(tpg, pat_line_new, pat_line_next_new);
  1995. if (avg_pat >= 0)
  1996. linestart_newer = tpg->downsampled_lines[avg_pat][p] +
  1997. mv_hor_new;
  1998. break;
  1999. }
  2000. }
  2001. linestart_older += line_offset;
  2002. linestart_newer += line_offset;
  2003. }
  2004. if (tpg->field_alternate) {
  2005. linestart_top = linestart_bottom = linestart_older;
  2006. } else if (params->is_60hz) {
  2007. linestart_top = linestart_newer;
  2008. linestart_bottom = linestart_older;
  2009. } else {
  2010. linestart_top = linestart_older;
  2011. linestart_bottom = linestart_newer;
  2012. }
  2013. switch (tpg->field) {
  2014. case V4L2_FIELD_INTERLACED:
  2015. case V4L2_FIELD_INTERLACED_TB:
  2016. case V4L2_FIELD_SEQ_TB:
  2017. case V4L2_FIELD_SEQ_BT:
  2018. if (even)
  2019. memcpy(vbuf, linestart_top, img_width);
  2020. else
  2021. memcpy(vbuf, linestart_bottom, img_width);
  2022. break;
  2023. case V4L2_FIELD_INTERLACED_BT:
  2024. if (even)
  2025. memcpy(vbuf, linestart_bottom, img_width);
  2026. else
  2027. memcpy(vbuf, linestart_top, img_width);
  2028. break;
  2029. case V4L2_FIELD_TOP:
  2030. memcpy(vbuf, linestart_top, img_width);
  2031. break;
  2032. case V4L2_FIELD_BOTTOM:
  2033. memcpy(vbuf, linestart_bottom, img_width);
  2034. break;
  2035. case V4L2_FIELD_NONE:
  2036. default:
  2037. memcpy(vbuf, linestart_older, img_width);
  2038. break;
  2039. }
  2040. }
  2041. void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std,
  2042. unsigned p, u8 *vbuf)
  2043. {
  2044. struct tpg_draw_params params;
  2045. unsigned factor = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1;
  2046. /* Coarse scaling with Bresenham */
  2047. unsigned int_part = (tpg->crop.height / factor) / tpg->compose.height;
  2048. unsigned fract_part = (tpg->crop.height / factor) % tpg->compose.height;
  2049. unsigned src_y = 0;
  2050. unsigned error = 0;
  2051. unsigned h;
  2052. tpg_recalc(tpg);
  2053. params.is_tv = std;
  2054. params.is_60hz = std & V4L2_STD_525_60;
  2055. params.twopixsize = tpg->twopixelsize[p];
  2056. params.img_width = tpg_hdiv(tpg, p, tpg->compose.width);
  2057. params.stride = tpg->bytesperline[p];
  2058. params.hmax = (tpg->compose.height * tpg->perc_fill) / 100;
  2059. tpg_fill_params_pattern(tpg, p, &params);
  2060. tpg_fill_params_extras(tpg, p, &params);
  2061. vbuf += tpg_hdiv(tpg, p, tpg->compose.left);
  2062. for (h = 0; h < tpg->compose.height; h++) {
  2063. unsigned buf_line;
  2064. params.frame_line = tpg_calc_frameline(tpg, src_y, tpg->field);
  2065. params.frame_line_next = params.frame_line;
  2066. buf_line = tpg_calc_buffer_line(tpg, h, tpg->field);
  2067. src_y += int_part;
  2068. error += fract_part;
  2069. if (error >= tpg->compose.height) {
  2070. error -= tpg->compose.height;
  2071. src_y++;
  2072. }
  2073. /*
  2074. * For line-interleaved formats determine the 'plane'
  2075. * based on the buffer line.
  2076. */
  2077. if (tpg_g_interleaved(tpg))
  2078. p = tpg_g_interleaved_plane(tpg, buf_line);
  2079. if (tpg->vdownsampling[p] > 1) {
  2080. /*
  2081. * When doing vertical downsampling the field setting
  2082. * matters: for SEQ_BT/TB we downsample each field
  2083. * separately (i.e. lines 0+2 are combined, as are
  2084. * lines 1+3), for the other field settings we combine
  2085. * odd and even lines. Doing that for SEQ_BT/TB would
  2086. * be really weird.
  2087. */
  2088. if (tpg->field == V4L2_FIELD_SEQ_BT ||
  2089. tpg->field == V4L2_FIELD_SEQ_TB) {
  2090. unsigned next_src_y = src_y;
  2091. if ((h & 3) >= 2)
  2092. continue;
  2093. next_src_y += int_part;
  2094. if (error + fract_part >= tpg->compose.height)
  2095. next_src_y++;
  2096. params.frame_line_next =
  2097. tpg_calc_frameline(tpg, next_src_y, tpg->field);
  2098. } else {
  2099. if (h & 1)
  2100. continue;
  2101. params.frame_line_next =
  2102. tpg_calc_frameline(tpg, src_y, tpg->field);
  2103. }
  2104. buf_line /= tpg->vdownsampling[p];
  2105. }
  2106. tpg_fill_plane_pattern(tpg, &params, p, h,
  2107. vbuf + buf_line * params.stride);
  2108. tpg_fill_plane_extras(tpg, &params, p, h,
  2109. vbuf + buf_line * params.stride);
  2110. }
  2111. }
  2112. void tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8 *vbuf)
  2113. {
  2114. unsigned offset = 0;
  2115. unsigned i;
  2116. if (tpg->buffers > 1) {
  2117. tpg_fill_plane_buffer(tpg, std, p, vbuf);
  2118. return;
  2119. }
  2120. for (i = 0; i < tpg_g_planes(tpg); i++) {
  2121. tpg_fill_plane_buffer(tpg, std, i, vbuf + offset);
  2122. offset += tpg_calc_plane_size(tpg, i);
  2123. }
  2124. }