Skip to content

Commit

Permalink
Upshifting 10-bit raws and delay enabling encoder.
Browse files Browse the repository at this point in the history
Enabling encoder to just before exposuer seems to make the long
exposure to work also for v1-camera.
  • Loading branch information
lboclboc committed Jan 6, 2021
1 parent dec2368 commit d265fc2
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 28 deletions.
6 changes: 5 additions & 1 deletion indi-rpicam/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ PROJECT(indi_rpicam CXX C)
set(INDI_RPICAM_VERSION_MAJOR 1)
set(INDI_RPICAM_VERSION_MINOR 3)

set(CMAKE_PREFIX_PATH /opt/vc)
if (NOT DEFINED VC_ROOT)
set(VC_ROOT "/opt/vc")
endif(NOT DEFINED VC_ROOT)

set(CMAKE_PREFIX_PATH ${VC_ROOT})

# ISO does not seem to be supported by the camere. If used, the gain stops working. So leave it off
option(USE_ISO "Enable ISO settings Subsystem" OFF)
Expand Down
4 changes: 3 additions & 1 deletion indi-rpicam/cameracontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ CameraControl::CameraControl()

encoder.reset(new MMALEncoder());
encoder->add_buffer_listener(this);
encoder->activate();

camera->enableComponent();
}
Expand Down Expand Up @@ -71,6 +70,8 @@ void CameraControl::startCapture()
buffer_processing_time = std::chrono::duration<double>::zero();
#endif

encoder->enableOutput();

camera->startCapture();
is_capturing = true;

Expand All @@ -88,6 +89,7 @@ void CameraControl::stopCapture()
camera->stopCapture();
std::chrono::duration<double> diff = std::chrono::steady_clock::now() - start_time;
LOGF_TEST("exposure stopped after %f s", diff.count());
encoder->disableOutput();
camera->disconnect();
is_capturing = false;
}
Expand Down
19 changes: 15 additions & 4 deletions indi-rpicam/mmalcamera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ MMALCamera::MMALCamera(int n) : MMALComponent(MMAL_COMPONENT_DEFAULT_CAMERA), ca

getSensorInfo();

// FIXME #001
selectSensorConfig(0 /* What ever 0 means */);

configureCamera();
Expand All @@ -53,9 +52,7 @@ MMALCamera::MMALCamera(int n) : MMALComponent(MMAL_COMPONENT_DEFAULT_CAMERA), ca

MMALCamera::~MMALCamera()
{
if (component->output[CAPTURE_PORT_NO]->is_enabled) {
MMALException::throw_if(mmal_port_disable(component->output[CAPTURE_PORT_NO]), "Failed to disable capture port");
}
disableOutput();

if(component->control->is_enabled) {
MMALException::throw_if(mmal_port_disable(component->control), "Failed to disable control port");
Expand Down Expand Up @@ -316,3 +313,17 @@ void MMALCamera::getFPSRange()
fps_low = fps_range.fps_low;
fps_high = fps_range.fps_high;
}

void MMALCamera::enableOutput()
{
assert(component);
assert(component->output[0]);
enablePort(component->output[CAPTURE_PORT_NO], false);
}

void MMALCamera::disableOutput()
{
assert(component);
assert(component->output[0]);
disablePort(component->output[CAPTURE_PORT_NO]);
}
2 changes: 2 additions & 0 deletions indi-rpicam/mmalcamera.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ class MMALCamera : public MMALComponent
void configureCamera();
void getFPSRange();
void setFPSRange(MMAL_RATIONAL_T low, MMAL_RATIONAL_T high);
void enableOutput();
void disableOutput();

float xPixelSize {}, yPixelSize {};

Expand Down
9 changes: 9 additions & 0 deletions indi-rpicam/mmalcomponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ MMALComponent::~MMALComponent()

void MMALComponent::enablePort(MMAL_PORT_T *port, bool use_callback)
{
assert(!port->is_enabled);

if (use_callback) {
MMALException::throw_if(mmal_port_enable(port, c_port_callback), "Failed to enable port on component %s", component->name);
}
Expand All @@ -62,6 +64,13 @@ void MMALComponent::enablePort(MMAL_PORT_T *port, bool use_callback)
}
}

void MMALComponent::disablePort(MMAL_PORT_T *port)
{
assert(port->is_enabled);
MMALException::throw_if(mmal_port_flush(port), "Failed to flush port before disabling it");
MMALException::throw_if(mmal_port_disable(port), "Failed to enable port on component %s", component->name);
}

void MMALComponent::c_port_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{
MMALComponent *p = dynamic_cast<MMALComponent *>(port->component->userdata);
Expand Down
1 change: 1 addition & 0 deletions indi-rpicam/mmalcomponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class MMALComponent

/** Enable the port, if use_callback the class callback method is used. */
void enablePort(MMAL_PORT_T *port, bool use_callback);
void disablePort(MMAL_PORT_T *port);

virtual void return_buffer(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) = 0;
MMAL_COMPONENT_T *component {};
Expand Down
30 changes: 15 additions & 15 deletions indi-rpicam/mmalencoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ MMALEncoder::MMALEncoder() : MMALComponent(MMAL_COMPONENT_DEFAULT_IMAGE_ENCODER)
enableComponent();

pool = mmal_port_pool_create(output, output->buffer_num, output->buffer_size);
if (pool== nullptr) {
MMALException::throw_if(status, "To create pool");
if (pool == nullptr) {
MMALException::throw_if(status, "To create buffer pool");
}
}

Expand All @@ -76,34 +76,34 @@ MMALEncoder::MMALEncoder() : MMALComponent(MMAL_COMPONENT_DEFAULT_IMAGE_ENCODER)
*/
MMALEncoder::~MMALEncoder()
{
if (component->output[0]->is_enabled) {
mmal_port_disable(component->output[0]);
}
disableOutput();

if (pool) {
mmal_port_pool_destroy(component->output[0], pool);
pool = nullptr;
}
}

/**
* @brief Enables the output and activates the encoder.
*/
void MMALEncoder::activate()
void MMALEncoder::enableOutput()
{
MMAL_STATUS_T status;

assert(component);
assert(component->output[0]);
enablePort(component->output[0], true);

unsigned int num = mmal_queue_length(pool->queue);
for (unsigned int q = 0; q < num; q++)
for (unsigned int q = 0; q < mmal_queue_length(pool->queue); q++)
{
MMAL_BUFFER_HEADER_T *buffer = mmal_queue_get(pool->queue);
MMALException::throw_if(buffer == nullptr, "Failed to get pool buffer");
status = mmal_port_send_buffer(component->output[0], buffer);
MMALException::throw_if(status, "Failed to send buffer to port");
MMALException::throw_if(mmal_port_send_buffer(component->output[0], buffer), "Failed to send buffer to port");
}
}

void MMALEncoder::disableOutput()
{
assert(component->output[0]);
disablePort(component->output[0]);
}

/**
* @brief MMALEncoder::return_buffer Returns the buffer to the pool.
* Only the object that caused the callback can know which pool it belongs to since that info
Expand Down
3 changes: 2 additions & 1 deletion indi-rpicam/mmalencoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ class MMALEncoder : public MMALComponent
public:
MMALEncoder();
virtual ~MMALEncoder();
void activate();
void enableOutput();
void disableOutput();

private:
virtual void return_buffer(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) override;
Expand Down
12 changes: 6 additions & 6 deletions indi-rpicam/raw10tobayer16pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ void Raw10ToBayer16Pipeline::data_received(uint8_t *data, uint32_t length)
u32_01 |= (u32Temp & u32Mask); // combine lower 2 bits to bytes 0 and 1
u32Temp >>= 4; // shift down to access bits for bytes 2/3
u32_23 |= (u32Temp & u32Mask);
*pu32++ = u32_01; // store 4 16-bit pixels (10 significant bits)
*pu32++ = u32_23;
*pu32++ = u32_01 << (16-10); // store 4 16-bit pixels (10 significant bits). Upshifted so bit 9 -> bit 15.
*pu32++ = u32_23 << (16-10);
length -= 5;
x += 4;
raw_x += 5;
Expand Down Expand Up @@ -195,10 +195,10 @@ void Raw10ToBayer16Pipeline::data_received(uint8_t *data, uint32_t length)
break;

case 4:
cur_row[x-1] |= byte & 0x03;
cur_row[x-2] |= (byte >> 2) & 0x03;
cur_row[x-3] |= (byte >> 4) & 0x03;
cur_row[x-4] |= (byte >> 6) & 0x03;
cur_row[x-1] = (cur_row[x-1] | ((byte >> 0) & 0x03)) << (16-10); // Merge bits together and upshift from bit9 to bit15.
cur_row[x-2] = (cur_row[x-2] | ((byte >> 2) & 0x03)) << (16-10);
cur_row[x-3] = (cur_row[x-3] | ((byte >> 4) & 0x03)) << (16-10);
cur_row[x-4] = (cur_row[x-4] | ((byte >> 6) & 0x03)) << (16-10);
state = 0;
break;
}
Expand Down

0 comments on commit d265fc2

Please sign in to comment.