/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Copyright (C) 2018, Google Inc. * * byte_stream_buffer.cpp - ByteStreamBuffer tests */ #include <array> #include <iostream> #include "libcamera/internal/byte_stream_buffer.h" #include "test.h" using namespace std; using namespace libcamera; class ByteStreamBufferTest : public Test { protected: int run() { /* * gcc 11.1.0 incorrectly raises a maybe-uninitialized warning * when calling data.size() below (if the address sanitizer is * disabled). Silence it by initializing the array. */ std::array<uint8_t, 100> data = {}; unsigned int i; uint32_t value; int ret; /* * Write mode. */ ByteStreamBuffer wbuf(data.data(), data.size()); if (wbuf.base() != data.data() || wbuf.size() != data.size() || wbuf.offset() != 0 || wbuf.overflow()) { cerr << "Write buffer incorrectly constructed" << endl; return TestFail; } /* Test write. */ value = 0x12345678; ret = wbuf.write(&value); if (ret || wbuf.offset() != 4 || wbuf.overflow() || *reinterpret_cast<uint32_t *>(data.data()) != 0x12345678) { cerr << "Write failed on write buffer" << endl; return TestFail; } /* Test write carve out. */ ByteStreamBuffer wco = wbuf.carveOut(10); if (wco.base() != wbuf.base() + 4 || wco.size() != 10 || wco.offset() != 0 || wco.overflow() || wbuf.offset() != 14 || wbuf.overflow()) { cerr << "Carving out write buffer failed" << endl; return TestFail; } /* Test write on the carved out buffer. */ value = 0x87654321; ret = wco.write(&value); if (ret || wco.offset() != 4 || wco.overflow() || *reinterpret_cast<uint32_t *>(data.data() + 4) != 0x87654321) { cerr << "Write failed on carve out buffer" << endl; return TestFail; } if (wbuf.offset() != 14 || wbuf.overflow()) { cerr << "Write on carve out buffer modified write buffer" << endl; return TestFail; } /* Test read, this should fail. */ ret = wbuf.read(&value); if (!ret || wbuf.overflow()) { cerr << "Read should fail on write buffer" << endl; return TestFail; } /* Test overflow on carved out buffer. */ for (i = 0; i < 2; ++i) { ret = wco.write(&value); if (ret < 0) break; } if (i != 1 || !wco.overflow() || !wbuf.overflow()) { cerr << "Write on carve out buffer failed to overflow" << endl; return TestFail; } /* Test reinitialization of the buffer. */ wbuf = ByteStreamBuffer(data.data(), data.size()); if (wbuf.overflow() || wbuf.base() != data.data() || wbuf.offset() != 0) { cerr << "Write buffer reinitialization failed" << endl; return TestFail; } /* * Read mode. */ ByteStreamBuffer rbuf(const_cast<const uint8_t *>(data.data()), data.size()); if (rbuf.base() != data.data() || rbuf.size() != data.size() || rbuf.offset() != 0 || rbuf.overflow()) { cerr << "Read buffer incorrectly constructed" << endl; return TestFail; } /* Test read. */ value = 0; ret = rbuf.read(&value); if (ret || rbuf.offset() != 4 || rbuf.overflow() || value != 0x12345678) { cerr << "Write failed on write buffer" << endl; return TestFail; } /* Test read carve out. */ ByteStreamBuffer rco = rbuf.carveOut(10); if (rco.base() != rbuf.base() + 4 || rco.size() != 10 || rco.offset() != 0 || rco.overflow() || rbuf.offset() != 14 || rbuf.overflow()) { cerr << "Carving out read buffer failed" << endl; return TestFail; } /* Test read on the carved out buffer. */ value = 0; ret = rco.read(&value); if (ret || rco.offset() != 4 || rco.overflow() || value != 0x87654321) { cerr << "Read failed on carve out buffer" << endl; return TestFail; } if (rbuf.offset() != 14 || rbuf.overflow()) { cerr << "Read on carve out buffer modified read buffer" << endl; return TestFail; } /* Test write, this should fail. */ ret = rbuf.write(&value); if (!ret || rbuf.overflow()) { cerr << "Write should fail on read buffer" << endl; return TestFail; } /* Test overflow on carved out buffer. */ for (i = 0; i < 2; ++i) { ret = rco.read(&value); if (ret < 0) break; } if (i != 1 || !rco.overflow() || !rbuf.overflow()) { cerr << "Read on carve out buffer failed to overflow" << endl; return TestFail; } /* Test reinitialization of the buffer. */ rbuf = ByteStreamBuffer(const_cast<const uint8_t *>(data.data()), data.size()); if (rbuf.overflow() || rbuf.base() != data.data() || rbuf.offset() != 0) { cerr << "Read buffer reinitialization failed" << endl; return TestFail; } return TestPass; } }; TEST_REGISTER(ByteStreamBufferTest) <a id='n44' href='#n44'>44</a> <a id='n45' href='#n45'>45</a> <a id='n46' href='#n46'>46</a> <a id='n47' href='#n47'>47</a> <a id='n48' href='#n48'>48</a> <a id='n49' href='#n49'>49</a> <a id='n50' href='#n50'>50</a> <a id='n51' href='#n51'>51</a> <a id='n52' href='#n52'>52</a> <a id='n53' href='#n53'>53</a> <a id='n54' href='#n54'>54</a> <a id='n55' href='#n55'>55</a> <a id='n56' href='#n56'>56</a> <a id='n57' href='#n57'>57</a> <a id='n58' href='#n58'>58</a> <a id='n59' href='#n59'>59</a> <a id='n60' href='#n60'>60</a> <a id='n61' href='#n61'>61</a> <a id='n62' href='#n62'>62</a> <a id='n63' href='#n63'>63</a> <a id='n64' href='#n64'>64</a> <a id='n65' href='#n65'>65</a> <a id='n66' href='#n66'>66</a> <a id='n67' href='#n67'>67</a> <a id='n68' href='#n68'>68</a> <a id='n69' href='#n69'>69</a> <a id='n70' href='#n70'>70</a> <a id='n71' href='#n71'>71</a> <a id='n72' href='#n72'>72</a> <a id='n73' href='#n73'>73</a> <a id='n74' href='#n74'>74</a> <a id='n75' href='#n75'>75</a> <a id='n76' href='#n76'>76</a> <a id='n77' href='#n77'>77</a> <a id='n78' href='#n78'>78</a> <a id='n79' href='#n79'>79</a> <a id='n80' href='#n80'>80</a> <a id='n81' href='#n81'>81</a> <a id='n82' href='#n82'>82</a> <a id='n83' href='#n83'>83</a> <a id='n84' href='#n84'>84</a> <a id='n85' href='#n85'>85</a> <a id='n86' href='#n86'>86</a> <a id='n87' href='#n87'>87</a> <a id='n88' href='#n88'>88</a> <a id='n89' href='#n89'>89</a> <a id='n90' href='#n90'>90</a> <a id='n91' href='#n91'>91</a> <a id='n92' href='#n92'>92</a> <a id='n93' href='#n93'>93</a> <a id='n94' href='#n94'>94</a> <a id='n95' href='#n95'>95</a> <a id='n96' href='#n96'>96</a> <a id='n97' href='#n97'>97</a> <a id='n98' href='#n98'>98</a> <a id='n99' href='#n99'>99</a> <a id='n100' href='#n100'>100</a> <a id='n101' href='#n101'>101</a> <a id='n102' href='#n102'>102</a> </pre></td> <td class='lines'><pre><code><span class="hl com">/* SPDX-License-Identifier: GPL-2.0-or-later */</span> <span class="hl com">/*</span> <span class="hl com"> * Copyright (C) 2019, Google Inc.</span> <span class="hl com"> *</span> <span class="hl com"> * libcamera V4L2 API tests</span> <span class="hl com"> */</span> <span class="hl ppc">#include <iostream></span> <span class="hl ppc">#include <linux/media-bus-format.h></span> <span class="hl ppc">#include</span> <span class="hl pps">"v4l2_videodevice_test.h"</span><span class="hl ppc"></span> <span class="hl ppc">#include</span> <span class="hl pps">"device_enumerator.h"</span><span class="hl ppc"></span> <span class="hl ppc">#include</span> <span class="hl pps">"media_device.h"</span><span class="hl ppc"></span> <span class="hl kwa">using namespace</span> std<span class="hl opt">;</span> <span class="hl kwa">using namespace</span> libcamera<span class="hl opt">;</span> <span class="hl kwb">int</span> <span class="hl kwc">V4L2VideoDeviceTest</span><span class="hl opt">::</span><span class="hl kwd">init</span><span class="hl opt">()</span> <span class="hl opt">{</span> enumerator_ <span class="hl opt">=</span> <span class="hl kwc">DeviceEnumerator</span><span class="hl opt">::</span><span class="hl kwd">create</span><span class="hl opt">();</span> <span class="hl kwa">if</span> <span class="hl opt">(!</span>enumerator_<span class="hl opt">) {</span> cerr <span class="hl opt"><<</span> <span class="hl str">"Failed to create device enumerator"</span> <span class="hl opt"><<</span> endl<span class="hl opt">;</span> <span class="hl kwa">return</span> TestFail<span class="hl opt">;</span> <span class="hl opt">}</span> <span class="hl kwa">if</span> <span class="hl opt">(</span>enumerator_<span class="hl opt">-></span><span class="hl kwd">enumerate</span><span class="hl opt">()) {</span> cerr <span class="hl opt"><<</span> <span class="hl str">"Failed to enumerate media devices"</span> <span class="hl opt"><<</span> endl<span class="hl opt">;</span> <span class="hl kwa">return</span> TestFail<span class="hl opt">;</span> <span class="hl opt">}</span> DeviceMatch <span class="hl kwd">dm</span><span class="hl opt">(</span>driver_<span class="hl opt">);</span> dm<span class="hl opt">.</span><span class="hl kwd">add</span><span class="hl opt">(</span>entity_<span class="hl opt">);</span> media_ <span class="hl opt">=</span> enumerator_<span class="hl opt">-></span><span class="hl kwd">search</span><span class="hl opt">(</span>dm<span class="hl opt">);</span> <span class="hl kwa">if</span> <span class="hl opt">(!</span>media_<span class="hl opt">)</span> <span class="hl kwa">return</span> TestSkip<span class="hl opt">;</span> MediaEntity <span class="hl opt">*</span>entity <span class="hl opt">=</span> media_<span class="hl opt">-></span><span class="hl kwd">getEntityByName</span><span class="hl opt">(</span>entity_<span class="hl opt">);</span> <span class="hl kwa">if</span> <span class="hl opt">(!</span>entity<span class="hl opt">)</span> <span class="hl kwa">return</span> TestSkip<span class="hl opt">;</span> capture_ <span class="hl opt">=</span> <span class="hl kwa">new</span> <span class="hl kwd">V4L2VideoDevice</span><span class="hl opt">(</span>entity<span class="hl opt">);</span> <span class="hl kwa">if</span> <span class="hl opt">(!</span>capture_<span class="hl opt">)</span> <span class="hl kwa">return</span> TestFail<span class="hl opt">;</span> <span class="hl kwa">if</span> <span class="hl opt">(!</span>media_<span class="hl opt">-></span><span class="hl kwd">acquire</span><span class="hl opt">())</span> <span class="hl kwa">return</span> TestFail<span class="hl opt">;</span> <span class="hl kwb">int</span> ret <span class="hl opt">=</span> media_<span class="hl opt">-></span><span class="hl kwd">disableLinks</span><span class="hl opt">();</span> media_<span class="hl opt">-></span><span class="hl kwd">release</span><span class="hl opt">();</span> <span class="hl kwa">if</span> <span class="hl opt">(</span>ret<span class="hl opt">)</span> <span class="hl kwa">return</span> TestFail<span class="hl opt">;</span> <span class="hl kwa">if</span> <span class="hl opt">(</span>capture_<span class="hl opt">-></span><span class="hl kwd">open</span><span class="hl opt">())</span> <span class="hl kwa">return</span> TestFail<span class="hl opt">;</span> V4L2DeviceFormat format <span class="hl opt">= {};</span> <span class="hl kwa">if</span> <span class="hl opt">(</span>capture_<span class="hl opt">-></span><span class="hl kwd">getFormat</span><span class="hl opt">(&</span>format<span class="hl opt">))</span> <span class="hl kwa">return</span> TestFail<span class="hl opt">;</span> <span class="hl kwa">if</span> <span class="hl opt">(</span>driver_ <span class="hl opt">==</span> <span class="hl str">"vimc"</span><span class="hl opt">) {</span> sensor_ <span class="hl opt">=</span> <span class="hl kwa">new</span> <span class="hl kwd">CameraSensor</span><span class="hl opt">(</span>media_<span class="hl opt">-></span><span class="hl kwd">getEntityByName</span><span class="hl opt">(</span><span class="hl str">"Sensor A"</span><span class="hl opt">));</span> <span class="hl kwa">if</span> <span class="hl opt">(</span>sensor_<span class="hl opt">-></span><span class="hl kwd">init</span><span class="hl opt">())</span> <span class="hl kwa">return</span> TestFail<span class="hl opt">;</span> debayer_ <span class="hl opt">=</span> <span class="hl kwa">new</span> <span class="hl kwd">V4L2Subdevice</span><span class="hl opt">(</span>media_<span class="hl opt">-></span><span class="hl kwd">getEntityByName</span><span class="hl opt">(</span><span class="hl str">"Debayer A"</span><span class="hl opt">));</span> <span class="hl kwa">if</span> <span class="hl opt">(</span>debayer_<span class="hl opt">-></span><span class="hl kwd">open</span><span class="hl opt">())</span> <span class="hl kwa">return</span> TestFail<span class="hl opt">;</span> format<span class="hl opt">.</span>fourcc <span class="hl opt">=</span> V4L2_PIX_FMT_SBGGR8<span class="hl opt">;</span> V4L2SubdeviceFormat subformat <span class="hl opt">= {};</span> subformat<span class="hl opt">.</span>mbus_code <span class="hl opt">=</span> MEDIA_BUS_FMT_SBGGR8_1X8<span class="hl opt">;</span> subformat<span class="hl opt">.</span>size <span class="hl opt">=</span> format<span class="hl opt">.</span>size<span class="hl opt">;</span> <span class="hl kwa">if</span> <span class="hl opt">(</span>sensor_<span class="hl opt">-></span><span class="hl kwd">setFormat</span><span class="hl opt">(&</span>subformat<span class="hl opt">))</span> <span class="hl kwa">return</span> TestFail<span class="hl opt">;</span> <span class="hl kwa">if</span> <span class="hl opt">(</span>debayer_<span class="hl opt">-></span><span class="hl kwd">setFormat</span><span class="hl opt">(</span><span class="hl num">0</span><span class="hl opt">, &</span>subformat<span class="hl opt">))</span> <span class="hl kwa">return</span> TestFail<span class="hl opt">;</span> <span class="hl opt">}</span> format<span class="hl opt">.</span>size<span class="hl opt">.</span>width <span class="hl opt">=</span> <span class="hl num">640</span><span class="hl opt">;</span> format<span class="hl opt">.</span>size<span class="hl opt">.</span>height <span class="hl opt">=</span> <span class="hl num">480</span><span class="hl opt">;</span> <span class="hl kwa">if</span> <span class="hl opt">(</span>capture_<span class="hl opt">-></span><span class="hl kwd">setFormat</span><span class="hl opt">(&</span>format<span class="hl opt">))</span> <span class="hl kwa">return</span> TestFail<span class="hl opt">;</span> <span class="hl kwa">return</span> TestPass<span class="hl opt">;</span> <span class="hl opt">}</span> <span class="hl kwb">void</span> <span class="hl kwc">V4L2VideoDeviceTest</span><span class="hl opt">::</span><span class="hl kwd">cleanup</span><span class="hl opt">()</span> <span class="hl opt">{</span> capture_<span class="hl opt">-></span><span class="hl kwd">streamOff</span><span class="hl opt">();</span> capture_<span class="hl opt">-></span><span class="hl kwd">releaseBuffers</span><span class="hl opt">();</span> capture_<span class="hl opt">-></span><span class="hl kwd">close</span><span class="hl opt">();</span> <span class="hl kwa">delete</span> debayer_<span class="hl opt">;</span> <span class="hl kwa">delete</span> sensor_<span class="hl opt">;</span> <span class="hl kwa">delete</span> capture_<span class="hl opt">;</span> <span class="hl opt">};</span> </code></pre></td></tr></table> </div> <!-- class=content --> <div class='footer'>generated by <a href='https://git.zx2c4.com/cgit/about/'>cgit v1.2.1</a> (<a href='https://git-scm.com/'>git 2.18.0</a>) at 2025-03-04 04:58:24 +0000</div> </div> <!-- id=cgit --> </body> </html>