@@ -70,6 +70,7 @@ public:
BufferPool vfPool;
BufferPool statPool;
+ BufferPool outputPool;
};
struct CIO2Device {
@@ -458,42 +459,70 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera, Stream *stream)
V4L2Device *input = data->imgu->input;
V4L2Device *cio2 = data->cio2.output;
V4L2Device *stat = data->imgu->stat;
+ ImgUDevice *imgu = data->imgu;
int ret;
- /* Share buffers between CIO2 output and ImgU input. */
- data->cio2.pool.createBuffers(IPU3_CIO2_BUFFER_COUNT);
- ret = cio2->exportBuffers(&data->cio2.pool);
- if (ret) {
- LOG(IPU3, Error) << "Failed to reserve CIO2 memory";
- return ret;
- }
+ if (data->cio2.pool.count() == 0) {
+ /* Share buffers between CIO2 output and ImgU input. */
+ data->cio2.pool.createBuffers(IPU3_CIO2_BUFFER_COUNT);
+ ret = cio2->exportBuffers(&data->cio2.pool);
+ if (ret) {
+ LOG(IPU3, Error) << "Failed to reserve CIO2 memory";
+ return ret;
+ }
- ret = input->importBuffers(&data->cio2.pool);
- if (ret) {
- LOG(IPU3, Error) << "Failed to import ImgU memory";
- return ret;
- }
+ ret = input->importBuffers(&data->cio2.pool);
+ if (ret) {
+ LOG(IPU3, Error) << "Failed to import ImgU memory";
+ return ret;
+ }
- /* Prepare the buffer pools for viewfinder and stat. */
- data->imgu->vfPool.createBuffers(IPU3_IMGU_BUFFER_COUNT);
- ret = viewfinder->exportBuffers(&data->imgu->vfPool);
- if (ret) {
- LOG(IPU3, Error) << "Failed to reserve ImgU viewfinder memory";
- return ret;
+ imgu->statPool.createBuffers(IPU3_IMGU_BUFFER_COUNT);
+ ret = stat->exportBuffers(&imgu->statPool);
+ if (ret) {
+ LOG(IPU3, Error) << "Failed to reserve ImgU stat memory";
+ return ret;
+ }
}
- data->imgu->statPool.createBuffers(IPU3_IMGU_BUFFER_COUNT);
- ret = stat->exportBuffers(&data->imgu->statPool);
- if (ret) {
- LOG(IPU3, Error) << "Failed to reserve ImgU stat memory";
- return ret;
- }
+ if (isOutput(data, stream)) {
+ /* Export ImgU output buffers to the stream's pool. */
+ ret = output->exportBuffers(&stream->bufferPool());
+ if (ret) {
+ LOG(IPU3, Error)
+ << "Failed to reserve ImgU output memory";
+ return ret;
+ }
- /* Export ImgU output buffers to the stream's pool. */
- ret = output->exportBuffers(&stream->bufferPool());
- if (ret) {
- LOG(IPU3, Error) << "Failed to reserve ImgU output memory";
- return ret;
+ if (!isViewfinderActive(data)) {
+ /* Internally allocate buffers for viewfinder. */
+ imgu->vfPool.createBuffers(IPU3_IMGU_BUFFER_COUNT);
+ ret = viewfinder->exportBuffers(&imgu->vfPool);
+ if (ret) {
+ LOG(IPU3, Error)
+ << "Failed to reserve ImgU viewfinder memory";
+ return ret;
+ }
+ }
+ } else if (isViewfinder(data, stream)) {
+ /* Export ImgU viewfinder buffers to the stream's pool. */
+ ret = viewfinder->exportBuffers(&stream->bufferPool());
+ if (ret) {
+ LOG(IPU3, Error)
+ << "Failed to reserve ImgU viewfinder memory";
+ return ret;
+ }
+
+ if (!isOutputActive(data)) {
+ /* Internally allocate buffers for output. */
+ imgu->outputPool.createBuffers(IPU3_IMGU_BUFFER_COUNT);
+ ret = output->exportBuffers(&imgu->outputPool);
+ if (ret) {
+ LOG(IPU3, Error)
+ << "Failed to reserve ImgU output memory";
+ return ret;
+ }
+ }
}
return 0;
@@ -509,25 +538,48 @@ int PipelineHandlerIPU3::freeBuffers(Camera *camera, Stream *stream)
V4L2Device *stat = data->imgu->stat;
int ret;
- ret = output->releaseBuffers();
- if (ret)
- LOG(IPU3, Error) << "Failed to release ImgU output memory";
+ if (data->cio2.pool.count()) {
+ ret = input->releaseBuffers();
+ if (ret)
+ LOG(IPU3, Error) << "Failed to release ImgU input memory";
- ret = stat->releaseBuffers();
- if (ret)
- LOG(IPU3, Error) << "Failed to release ImgU stat memory";
+ ret = cio2->releaseBuffers();
+ if (ret)
+ LOG(IPU3, Error) << "Failed to release CIO2 memory";
- ret = viewfinder->releaseBuffers();
- if (ret)
- LOG(IPU3, Error) << "Failed to release ImgU viewfinder memory";
+ ret = stat->releaseBuffers();
+ if (ret)
+ LOG(IPU3, Error) << "Failed to release ImgU stat memory";
- ret = input->releaseBuffers();
- if (ret)
- LOG(IPU3, Error) << "Failed to release ImgU input memory";
+ }
- ret = cio2->releaseBuffers();
- if (ret)
- LOG(IPU3, Error) << "Failed to release CIO2 memory";
+ if (isOutput(data, stream)) {
+ ret = output->releaseBuffers();
+ if (ret)
+ LOG(IPU3, Error)
+ << "Failed to release ImgU output memory";
+
+ if (isViewfinderActive(data))
+ return 0;
+
+ ret = viewfinder->releaseBuffers();
+ if (ret)
+ LOG(IPU3, Error)
+ << "Failed to release ImgU viewfinder memory";
+ } else if (isViewfinder(data, stream)) {
+ ret = viewfinder->releaseBuffers();
+ if (ret)
+ LOG(IPU3, Error)
+ << "Failed to release ImgU viewfinder memory";
+
+ if (isOutputActive(data))
+ return 0;
+
+ ret = output->releaseBuffers();
+ if (ret)
+ LOG(IPU3, Error)
+ << "Failed to release ImgU output memory";
+ }
return 0;
}