Skip to content

Commit

Permalink
ci: Ubuntu 22.04, clang-format-15, esp32cam
Browse files Browse the repository at this point in the history
  • Loading branch information
yoursunny committed Jan 11, 2024
1 parent 3fc245b commit cbb2e56
Show file tree
Hide file tree
Showing 22 changed files with 131 additions and 244 deletions.
8 changes: 6 additions & 2 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ BasedOnStyle: Mozilla
AllowShortFunctionsOnASingleLine: Empty
BinPackArguments: true
BinPackParameters: true
BreakBeforeBraces: Attach
ColumnLimit: 100
Cpp11BracedListStyle: true
FixNamespaceComments: true
IncludeIsMainRegex: '(\.t)?$'
InsertBraces: true
QualifierAlignment: Custom
QualifierOrder: ['static', 'inline', 'const', 'constexpr', 'volatile', 'type', 'restrict']
ReflowComments: false
SortIncludes: true
SortUsingDeclarations: true
ShortNamespaceLines: 1000000
SpacesInContainerLiterals: false
12 changes: 6 additions & 6 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
permissions: {}
jobs:
build:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- uses: arduino/setup-arduino-cli@v1
- id: cores
Expand All @@ -26,8 +26,8 @@ jobs:
arduino-cli core install esp32:esp32 --additional-urls "$(<~/arduino-cores.txt)"
- name: Install dependencies
run: |
sudo apt-get install -y --no-install-recommends clang-format-11 doxygen
- uses: actions/checkout@v3
sudo apt-get install -y --no-install-recommends clang-format-15 doxygen
- uses: actions/checkout@v4
- name: Check code style
run: |
mk/format-code.sh
Expand All @@ -50,13 +50,13 @@ jobs:
ODROIDGO_VERSION: 4a496e337d16bca4ddedbeca3486d7b60662d017
- name: Compile examples
run: |
arduino-cli compile -b esp32:esp32:esp32wrover ./examples/WifiCam
arduino-cli compile -b esp32:esp32:esp32wrover ./examples/AsyncCam
arduino-cli compile -b esp32:esp32:esp32cam ./examples/WifiCam
arduino-cli compile -b esp32:esp32:esp32cam ./examples/AsyncCam
arduino-cli compile -b esp32:esp32:odroid_esp32 ./examples/GoDisplay
- name: Build docs
run: docs/build.sh
- name: Deploy docs
uses: nwtgck/actions-netlify@30aa80fe8d5eec30813fc8b17b77e0a6663f09b5
uses: nwtgck/actions-netlify@v2.1.0
with:
publish-dir: ./docs/html/
production-deploy: true
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ This library has been tested with AI Thinker [ESP32-CAM](http://www.ai-thinker.c

1. Clone this repository under `$HOME/Arduino/libraries` directory.
2. Add `#include <esp32cam.h>` to your sketch.
3. In *Tools* - *Board* menu, select **ESP32 Wrover Module** to enable 4MB external PSRAM.
3. In *Tools* - *Board* menu, select **AI Thinker ESP32-CAM** to enable 4MB external PSRAM.
4. Check out the [examples](examples/) for how to use.
6 changes: 2 additions & 4 deletions examples/AsyncCam/AsyncCam.ino
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ esp32cam::Resolution currentResolution;
AsyncWebServer server(80);

void
setup()
{
setup() {
Serial.begin(115200);
Serial.println();
delay(2000);
Expand Down Expand Up @@ -55,8 +54,7 @@ setup()
}

void
loop()
{
loop() {
// esp32cam-asyncweb.h depends on FreeRTOS task API including vTaskDelete, so you must have a
// non-zero delay in the loop() function; otherwise, FreeRTOS kernel memory cannot be freed
// properly and the system would run out of memory.
Expand Down
6 changes: 2 additions & 4 deletions examples/AsyncCam/handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,7 @@ for (const $ctrl of document.querySelectorAll("#controls button")) {
)EOT";

static String
rewriteFrontpage(const String& var)
{
rewriteFrontpage(const String& var) {
StreamString b;
if (var == "RESOLUTION_OPTIONS") {
for (const auto& r : esp32cam::Camera.listResolutions()) {
Expand All @@ -85,8 +84,7 @@ rewriteFrontpage(const String& var)
}

void
addRequestHandlers()
{
addRequestHandlers() {
server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) {
request->send_P(200, "text/html", reinterpret_cast<const uint8_t*>(FRONTPAGE),
sizeof(FRONTPAGE), rewriteFrontpage);
Expand Down
6 changes: 2 additions & 4 deletions examples/GoDisplay/GoDisplay.ino
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ static const uint16_t CAM_PORT = 80;
static const char* CAM_URI = "/320x240.jpg";

void
setup()
{
setup() {
GO.begin(115200);

WiFi.persistent(false);
Expand All @@ -26,8 +25,7 @@ setup()
}

void
loop()
{
loop() {
WiFiClient tcp;
HTTPClient http;
http.begin(tcp, CAM_SERVER, CAM_PORT, CAM_URI);
Expand Down
30 changes: 10 additions & 20 deletions examples/GoDisplay/SpiRamOStream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,55 +4,45 @@
#include <Arduino.h>

/** @brief write-only Stream backed by fixed-size SPIRAM buffer. */
class SpiRamOStream : public Stream
{
class SpiRamOStream : public Stream {
public:
explicit SpiRamOStream(size_t cap)
: m_buf(reinterpret_cast<uint8_t*>(heap_caps_malloc(cap, MALLOC_CAP_SPIRAM)))
, m_len(0)
, m_cap(cap)
{}
, m_cap(cap) {}

~SpiRamOStream()
{
~SpiRamOStream() {
free(m_buf);
}

const uint8_t* data() const
{
const uint8_t* data() const {
return m_buf;
}

const size_t size() const
{
const size_t size() const {
return m_len;
}

size_t write(const uint8_t* buffer, size_t size) override
{
size_t write(const uint8_t* buffer, size_t size) override {
size_t count = min(size, m_cap - m_len);
memcpy(m_buf + m_len, buffer, count);
m_len += count;
return count;
}

size_t write(uint8_t data) override
{
size_t write(uint8_t data) override {
return write(&data, 1);
}

int available() override
{
int available() override {
return 0;
}

int read() override
{
int read() override {
return -1;
}

int peek() override
{
int peek() override {
return -1;
}

Expand Down
6 changes: 2 additions & 4 deletions examples/WifiCam/WifiCam.ino
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ esp32cam::Resolution initialResolution;
WebServer server(80);

void
setup()
{
setup() {
Serial.begin(115200);
Serial.println();
delay(2000);
Expand Down Expand Up @@ -53,7 +52,6 @@ setup()
}

void
loop()
{
loop() {
server.handleClient();
}
9 changes: 3 additions & 6 deletions examples/WifiCam/handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ try {
)EOT";

static void
serveStill(bool wantBmp)
{
serveStill(bool wantBmp) {
auto frame = esp32cam::capture();
if (frame == nullptr) {
Serial.println("capture() failure");
Expand All @@ -69,8 +68,7 @@ serveStill(bool wantBmp)
}

static void
serveMjpeg()
{
serveMjpeg() {
Serial.println("MJPEG streaming begin");
WiFiClient client = server.client();
auto startTime = millis();
Expand All @@ -80,8 +78,7 @@ serveMjpeg()
}

void
addRequestHandlers()
{
addRequestHandlers() {
server.on("/", HTTP_GET, [] {
server.setContentLength(sizeof(FRONTPAGE));
server.send(200, "text/html");
Expand Down
2 changes: 1 addition & 1 deletion mk/format-code.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ set -eo pipefail
cd "$( dirname "${BASH_SOURCE[0]}" )"/..

find -name '*.h' -or -name '*.[hc]pp' -or -name '*.ino' | \
xargs clang-format-11 -i -style=file
xargs clang-format-15 -i -style=file
48 changes: 16 additions & 32 deletions src/esp32cam-asyncweb.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,25 @@ namespace esp32cam {
namespace asyncweb {

/** @brief HTTP response of one still image. */
class StillResponse : public AsyncAbstractResponse
{
class StillResponse : public AsyncAbstractResponse {
public:
/**
* @brief Constructor.
* @param frame a frame of still image.
*/
explicit StillResponse(std::unique_ptr<Frame> frame)
: m_frame(std::move(frame))
{
: m_frame(std::move(frame)) {
_code = 200;
_contentType = determineMineType(*m_frame);
_contentLength = m_frame->size();
_sendContentLength = true;
}

bool _sourceValid() const override
{
bool _sourceValid() const override {
return true;
}

size_t _fillBuffer(uint8_t* buf, size_t buflen) override
{
size_t _fillBuffer(uint8_t* buf, size_t buflen) override {
if (m_index >= m_frame->size()) {
return 0;
}
Expand All @@ -55,8 +51,7 @@ class StillResponse : public AsyncAbstractResponse
*
* This function must run as a FreeRTOS task. It self-deletes upon completion.
*/
static void captureTask(void* ctx)
{
static void captureTask(void* ctx) {
auto request = reinterpret_cast<AsyncWebServerRequest*>(ctx);

auto frame = Camera.capture();
Expand All @@ -70,8 +65,7 @@ class StillResponse : public AsyncAbstractResponse
}

private:
static const char* determineMineType(const Frame& frame)
{
static const char* determineMineType(const Frame& frame) {
if (frame.isJpeg()) {
return "image/jpeg";
}
Expand Down Expand Up @@ -99,8 +93,7 @@ class StillResponse : public AsyncAbstractResponse
* to do these, and then call this function.
*/
inline void
handleStill(AsyncWebServerRequest* request)
{
handleStill(AsyncWebServerRequest* request) {
TaskHandle_t task;
auto res = xTaskCreatePinnedToCore(StillResponse::captureTask, "esp32cam-still", 2048, request, 1,
&task, xPortGetCoreID());
Expand All @@ -119,12 +112,10 @@ handleStill(AsyncWebServerRequest* request)
* If task creation fails, respond with HTTP 500 error.
* If image capture fails, the stream is stopped.
*/
class MjpegResponse : public AsyncAbstractResponse
{
class MjpegResponse : public AsyncAbstractResponse {
public:
explicit MjpegResponse(const MjpegConfig& cfg = MjpegConfig())
: m_ctrl(cfg)
{
: m_ctrl(cfg) {
m_queue = xQueueCreate(4, sizeof(Frame*));
if (xTaskCreatePinnedToCore(captureTask, "esp32cam-mjpeg", 2048, this, 1, &m_task,
xPortGetCoreID()) != pdPASS) {
Expand All @@ -142,8 +133,7 @@ class MjpegResponse : public AsyncAbstractResponse
_sendContentLength = false;
}

~MjpegResponse() override
{
~MjpegResponse() override {
if (m_task != nullptr) {
vTaskDelete(m_task);
m_task = nullptr;
Expand All @@ -159,13 +149,11 @@ class MjpegResponse : public AsyncAbstractResponse
}
}

bool _sourceValid() const override
{
bool _sourceValid() const override {
return true;
}

size_t _fillBuffer(uint8_t* buf, size_t buflen) override
{
size_t _fillBuffer(uint8_t* buf, size_t buflen) override {
auto act = m_ctrl.decideAction();
switch (act) {
case Ctrl::CAPTURE: {
Expand Down Expand Up @@ -201,8 +189,7 @@ class MjpegResponse : public AsyncAbstractResponse
}

private:
static void captureTask(void* ctx)
{
static void captureTask(void* ctx) {
auto self = reinterpret_cast<MjpegResponse*>(ctx);
while (true) {
uint32_t value = 0;
Expand All @@ -218,8 +205,7 @@ class MjpegResponse : public AsyncAbstractResponse
}
}

size_t sendPart(uint8_t* buf, size_t buflen)
{
size_t sendPart(uint8_t* buf, size_t buflen) {
if (m_sendRemain == 0) {
switch (m_sendNext) {
case SIPartHeader:
Expand Down Expand Up @@ -259,8 +245,7 @@ class MjpegResponse : public AsyncAbstractResponse
Ctrl m_ctrl;
detail::MjpegHeader m_hdr;

enum SendItem
{
enum SendItem {
SINone,
SIPartHeader,
SIFrame,
Expand All @@ -277,8 +262,7 @@ class MjpegResponse : public AsyncAbstractResponse
* To specify MjpegConfig, construct MjpegResponse directly.
*/
inline void
handleMjpeg(AsyncWebServerRequest* request)
{
handleMjpeg(AsyncWebServerRequest* request) {
request->send(new MjpegResponse());
}

Expand Down
Loading

0 comments on commit cbb2e56

Please sign in to comment.