QCamera3Channel.cpp revision 9de643761e1282fb5af14a9249618efa9d8ac8fe
1/* Copyright (c) 2012-2013, The Linux Foundataion. All rights reserved.
2*
3* Redistribution and use in source and binary forms, with or without
4* modification, are permitted provided that the following conditions are
5* met:
6*     * Redistributions of source code must retain the above copyright
7*       notice, this list of conditions and the following disclaimer.
8*     * Redistributions in binary form must reproduce the above
9*       copyright notice, this list of conditions and the following
10*       disclaimer in the documentation and/or other materials provided
11*       with the distribution.
12*     * Neither the name of The Linux Foundation nor the names of its
13*       contributors may be used to endorse or promote products derived
14*       from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19* ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*
28*/
29
30#define LOG_TAG "QCamera3Channel"
31
32#include <hardware/camera3.h>
33#include <gralloc_priv.h>
34#include <utils/Log.h>
35#include <utils/Errors.h>
36#include "QCamera3Channel.h"
37
38using namespace android;
39
40#define MIN_STREAMING_BUFFER_NUM 3
41
42namespace qcamera {
43
44/*===========================================================================
45 * FUNCTION   : QCamera3Channel
46 *
47 * DESCRIPTION: constrcutor of QCamera3Channel
48 *
49 * PARAMETERS :
50 *   @cam_handle : camera handle
51 *   @cam_ops    : ptr to camera ops table
52 *
53 * RETURN     : none
54 *==========================================================================*/
55QCamera3Channel::QCamera3Channel(uint32_t cam_handle,
56                               mm_camera_ops_t *cam_ops,
57                               channel_cb_routine cb_routine)
58{
59    m_camHandle = cam_handle;
60    m_camOps = cam_ops;
61    mChannelCB = cb_routine;
62    m_bIsActive = false;
63
64    m_handle = 0;
65    m_numStreams = 0;
66    memset(mStreams, 0, sizeof(mStreams));
67}
68
69/*===========================================================================
70 * FUNCTION   : QCamera3Channel
71 *
72 * DESCRIPTION: default constrcutor of QCamera3Channel
73 *
74 * PARAMETERS : none
75 *
76 * RETURN     : none
77 *==========================================================================*/
78QCamera3Channel::QCamera3Channel()
79{
80    m_camHandle = 0;
81    m_camOps = NULL;
82    m_bIsActive = false;
83
84    m_handle = 0;
85    m_numStreams = 0;
86    memset(mStreams, 0, sizeof(mStreams));
87}
88
89/*===========================================================================
90 * FUNCTION   : ~QCamera3Channel
91 *
92 * DESCRIPTION: destructor of QCamera3Channel
93 *
94 * PARAMETERS : none
95 *
96 * RETURN     : none
97 *==========================================================================*/
98QCamera3Channel::~QCamera3Channel()
99{
100    if (m_bIsActive) {
101        stop();
102    }
103
104    for (int i = 0; i < m_numStreams; i++) {
105        if (mStreams[i] != NULL) {
106            delete mStreams[i];
107            mStreams[i] = 0;
108        }
109    }
110    m_numStreams = 0;
111    m_camOps->delete_channel(m_camHandle, m_handle);
112    m_handle = 0;
113}
114
115/*===========================================================================
116 * FUNCTION   : init
117 *
118 * DESCRIPTION: initialization of channel
119 *
120 * PARAMETERS :
121 *   @attr    : channel bundle attribute setting
122 *   @dataCB  : data notify callback
123 *   @userData: user data ptr
124 *
125 * RETURN     : int32_t type of status
126 *              NO_ERROR  -- success
127 *              none-zero failure code
128 *==========================================================================*/
129int32_t QCamera3Channel::init(mm_camera_channel_attr_t *attr,
130                             mm_camera_buf_notify_t dataCB,
131                             cam_padding_info_t *paddingInfo,
132                             void *userData)
133{
134    m_handle = m_camOps->add_channel(m_camHandle,
135                                      attr,
136                                      dataCB,
137                                      userData);
138    if (m_handle == 0) {
139        ALOGE("%s: Add channel failed", __func__);
140        return UNKNOWN_ERROR;
141    }
142    mPaddingInfo = paddingInfo;
143    mUserData = userData;
144    return NO_ERROR;
145}
146
147/*===========================================================================
148 * FUNCTION   : addStream
149 *
150 * DESCRIPTION: add a stream into channel
151 *
152 * PARAMETERS :
153 *   @allocator      : stream related buffer allocator
154 *   @streamInfoBuf  : ptr to buf that constains stream info
155 *   @minStreamBufNum: number of stream buffers needed
156 *   @paddingInfo    : padding information
157 *   @stream_cb      : stream data notify callback
158 *   @userdata       : user data ptr
159 *
160 * RETURN     : int32_t type of status
161 *              NO_ERROR  -- success
162 *              none-zero failure code
163 *==========================================================================*/
164int32_t QCamera3Channel::addStream(cam_stream_type_t streamType,
165                                  cam_format_t streamFormat,
166                                  cam_dimension_t streamDim,
167                                  uint8_t minStreamBufNum,
168                                  cam_padding_info_t *paddingInfo)
169{
170    int32_t rc = NO_ERROR;
171    if (m_numStreams >= MAX_STREAM_NUM_IN_BUNDLE) {
172        ALOGE("%s: stream number (%d) exceeds max limit (%d)",
173              __func__, m_numStreams, MAX_STREAM_NUM_IN_BUNDLE);
174        return BAD_VALUE;
175    }
176    QCamera3Stream *pStream = new QCamera3Stream(m_camHandle,
177                                               m_handle,
178                                               m_camOps,
179                                               paddingInfo,
180                                               this);
181    if (pStream == NULL) {
182        ALOGE("%s: No mem for Stream", __func__);
183        return NO_MEMORY;
184    }
185
186    rc = pStream->init(streamType, streamFormat, streamDim, minStreamBufNum, streamCbRoutine, this);
187    if (rc == 0) {
188        mStreams[m_numStreams] = pStream;
189        m_numStreams++;
190    } else {
191        delete pStream;
192    }
193    return rc;
194}
195
196/*===========================================================================
197 * FUNCTION   : start
198 *
199 * DESCRIPTION: start channel, which will start all streams belong to this channel
200 *
201 * PARAMETERS :
202 *
203 * RETURN     : int32_t type of status
204 *              NO_ERROR  -- success
205 *              none-zero failure code
206 *==========================================================================*/
207int32_t QCamera3Channel::start()
208{
209    int32_t rc = NO_ERROR;
210
211    if (m_numStreams > 1) {
212        ALOGE("%s: bundle not supported", __func__);
213    }
214
215    for (int i = 0; i < m_numStreams; i++) {
216        if (mStreams[i] != NULL) {
217            mStreams[i]->start();
218        }
219    }
220    rc = m_camOps->start_channel(m_camHandle, m_handle);
221
222    if (rc != NO_ERROR) {
223        for (int i = 0; i < m_numStreams; i++) {
224            if (mStreams[i] != NULL) {
225                mStreams[i]->stop();
226            }
227        }
228    } else {
229        m_bIsActive = true;
230    }
231
232    return rc;
233}
234
235/*===========================================================================
236 * FUNCTION   : stop
237 *
238 * DESCRIPTION: stop a channel, which will stop all streams belong to this channel
239 *
240 * PARAMETERS : none
241 *
242 * RETURN     : int32_t type of status
243 *              NO_ERROR  -- success
244 *              none-zero failure code
245 *==========================================================================*/
246int32_t QCamera3Channel::stop()
247{
248    int32_t rc = NO_ERROR;
249    rc = m_camOps->stop_channel(m_camHandle, m_handle);
250
251    for (int i = 0; i < m_numStreams; i++) {
252        if (mStreams[i] != NULL) {
253            mStreams[i]->stop();
254        }
255    }
256
257    m_bIsActive = false;
258    return rc;
259}
260
261/*===========================================================================
262 * FUNCTION   : bufDone
263 *
264 * DESCRIPTION: return a stream buf back to kernel
265 *
266 * PARAMETERS :
267 *   @recvd_frame  : stream buf frame to be returned
268 *
269 * RETURN     : int32_t type of status
270 *              NO_ERROR  -- success
271 *              none-zero failure code
272 *==========================================================================*/
273int32_t QCamera3Channel::bufDone(mm_camera_super_buf_t *recvd_frame)
274{
275    int32_t rc = NO_ERROR;
276    for (int i = 0; i < recvd_frame->num_bufs; i++) {
277         if (recvd_frame->bufs[i] != NULL) {
278             for (int j = 0; j < m_numStreams; j++) {
279                 if (mStreams[j] != NULL &&
280                     mStreams[j]->getMyHandle() == recvd_frame->bufs[i]->stream_id) {
281                     rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx);
282                     break; // break loop j
283                 }
284             }
285         }
286    }
287
288    return rc;
289}
290
291/*===========================================================================
292 * FUNCTION   : getStreamByHandle
293 *
294 * DESCRIPTION: return stream object by stream handle
295 *
296 * PARAMETERS :
297 *   @streamHandle : stream handle
298 *
299 * RETURN     : stream object. NULL if not found
300 *==========================================================================*/
301QCamera3Stream *QCamera3Channel::getStreamByHandle(uint32_t streamHandle)
302{
303    for (int i = 0; i < m_numStreams; i++) {
304        if (mStreams[i] != NULL && mStreams[i]->getMyHandle() == streamHandle) {
305            return mStreams[i];
306        }
307    }
308    return NULL;
309}
310
311/*===========================================================================
312 * FUNCTION   : getStreamByHandle
313 *
314 * DESCRIPTION: return stream object by stream handle
315 *
316 * PARAMETERS :
317 *   @streamHandle : stream handle
318 *
319 * RETURN     : stream object. NULL if not found
320 *==========================================================================*/
321QCamera3Stream *QCamera3Channel::getStreamByIndex(uint8_t index)
322{
323    if (index < m_numStreams) {
324        return mStreams[index];
325    }
326    return NULL;
327}
328
329/*===========================================================================
330 * FUNCTION   : streamCbRoutine
331 *
332 * DESCRIPTION: callback routine for stream
333 *
334 * PARAMETERS :
335 *   @streamHandle : stream handle
336 *
337 * RETURN     : stream object. NULL if not found
338 *==========================================================================*/
339void QCamera3Channel::streamCbRoutine(mm_camera_super_buf_t *super_frame,
340                QCamera3Stream *stream, void *userdata)
341{
342    QCamera3Channel *channel = (QCamera3Channel *)userdata;
343    if (channel == NULL) {
344        ALOGE("%s: invalid channel pointer", __func__);
345        return;
346    }
347    channel->streamCbRoutine(super_frame, stream);
348}
349
350/*===========================================================================
351 * FUNCTION   : QCamera3RegularChannel
352 *
353 * DESCRIPTION: constrcutor of QCamera3RegularChannel
354 *
355 * PARAMETERS :
356 *   @cam_handle : camera handle
357 *   @cam_ops    : ptr to camera ops table
358 *   @cb_routine : callback routine to frame aggregator
359 *   @stream     : camera3_stream_t structure
360 *
361 * RETURN     : none
362 *==========================================================================*/
363QCamera3RegularChannel::QCamera3RegularChannel(uint32_t cam_handle,
364                    mm_camera_ops_t *cam_ops,
365                    channel_cb_routine cb_routine,
366                    camera3_stream_t *stream) :
367                        QCamera3Channel(cam_handle, cam_ops, cb_routine),
368                        mCamera3Stream(stream),
369                        mNumBufs(0),
370                        mCamera3Buffers(NULL),
371                        mMemory(NULL)
372{
373    //TODO
374}
375
376/*===========================================================================
377 * FUNCTION   : ~QCamera3RegularChannel
378 *
379 * DESCRIPTION: destructor of QCamera3RegularChannel
380 *
381 * PARAMETERS : none
382 *
383 * RETURN     : none
384 *==========================================================================*/
385QCamera3RegularChannel::~QCamera3RegularChannel()
386{
387    //TODO
388}
389
390/*===========================================================================
391 * FUNCTION   : request
392 *
393 * DESCRIPTION: process a request from camera service. Stream on if ncessary.
394 *
395 * PARAMETERS :
396 *   @buffer  : buffer to be filled for this request
397 *
398 * RETURN     : 0 on a success start of capture
399 *              -EINVAL on invalid input
400 *              -ENODEV on serious error
401 *==========================================================================*/
402int32_t QCamera3RegularChannel::request(const camera3_stream_buffer_t *buffer)
403{
404    //TODO
405    return 0;
406}
407
408/*===========================================================================
409 * FUNCTION   : registerBuffers
410 *
411 * DESCRIPTION: register streaming buffers to the channel object
412 *
413 * PARAMETERS :
414 *   @num_buffers : number of buffers to be registered
415 *   @buffers     : buffer to be registered
416 *
417 * RETURN     : 0 on a success start of capture
418 *              -EINVAL on invalid input
419 *              -ENOMEM on failure to register the buffer
420 *              -ENODEV on serious error
421 *==========================================================================*/
422int32_t QCamera3RegularChannel::registerBuffers(uint32_t num_buffers, buffer_handle_t **buffers)
423{
424    int rc = 0;
425    struct private_handle_t *priv_handle = (struct private_handle_t *)(*buffers[0]);
426    cam_stream_type_t streamType;
427    cam_format_t streamFormat;
428    cam_dimension_t streamDim;
429
430    if (mCamera3Stream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
431        if (priv_handle->flags & private_handle_t::PRIV_FLAGS_VIDEO_ENCODER) {
432            streamType = CAM_STREAM_TYPE_VIDEO;
433            streamFormat = CAM_FORMAT_YUV_420_NV12;
434        } else if (priv_handle->flags & private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY) {
435            streamType = CAM_STREAM_TYPE_PREVIEW;
436            streamFormat = CAM_FORMAT_YUV_420_NV21;
437        } else {
438            ALOGE("%s: priv_handle->flags 0x%x not supported",
439                    __func__, priv_handle->flags);
440            return -EINVAL;
441        }
442    } else {
443        //TODO: Fail for other types of streams for now
444        ALOGE("%s: format is not IMPLEMENTATION_DEFINED", __func__);
445        return -EINVAL;
446    }
447
448    mNumBufs = num_buffers;
449    mCamera3Buffers = buffers;
450
451    streamDim.width = mCamera3Stream->width;
452    streamDim.height = mCamera3Stream->height;
453    rc = QCamera3Channel::addStream(streamType, streamFormat, streamDim,
454        num_buffers, mPaddingInfo);
455
456    return rc;
457}
458
459void QCamera3RegularChannel::streamCbRoutine(
460                            mm_camera_super_buf_t *super_frame,
461                            QCamera3Stream *stream)
462{
463    //TODO
464    return;
465}
466
467QCamera3Memory* QCamera3RegularChannel::getStreamBufs(uint32_t /*len*/)
468{
469    int rc;
470    mMemory = new QCamera3GrallocMemory();
471    if (mMemory == NULL) {
472        return NULL;
473    }
474
475    rc = mMemory->registerBuffers(mNumBufs, mCamera3Buffers);
476    if (rc < 0) {
477        delete mMemory;
478        mMemory = NULL;
479        return NULL;
480    }
481    return mMemory;
482}
483
484void QCamera3RegularChannel::putStreamBufs()
485{
486    mMemory->unregisterBuffers();
487    delete mMemory;
488    mMemory = NULL;
489}
490
491int QCamera3RegularChannel::kMaxBuffers = 3;
492
493QCamera3MetadataChannel::QCamera3MetadataChannel(uint32_t cam_handle,
494                    mm_camera_ops_t *cam_ops,
495                    channel_cb_routine cb_routine) :
496                        QCamera3Channel(cam_handle, cam_ops, cb_routine),
497                        mMemory(NULL),
498                        mStarted(false)
499{
500}
501
502QCamera3MetadataChannel::~QCamera3MetadataChannel()
503{
504    if (mStarted)
505        stop();
506
507    if (mMemory) {
508        mMemory->deallocate();
509        delete mMemory;
510        mMemory = NULL;
511    }
512}
513
514int32_t QCamera3MetadataChannel::initialize()
515{
516    int32_t rc;
517    cam_dimension_t streamDim;
518
519    if (mMemory || m_numStreams > 0) {
520        ALOGE("%s: metadata channel already initialized", __func__);
521        return -EINVAL;
522    }
523
524    streamDim.width = sizeof(parm_buffer_t),
525    streamDim.height = 1;
526    rc = QCamera3Channel::addStream(CAM_STREAM_TYPE_METADATA, CAM_FORMAT_MAX,
527        streamDim, MIN_STREAMING_BUFFER_NUM, mPaddingInfo);
528    if (rc < 0) {
529        ALOGE("%s: addStream failed", __func__);
530    }
531    return rc;
532}
533
534int32_t QCamera3MetadataChannel::request(const camera3_stream_buffer_t *buffer)
535{
536    if (!mStarted)
537        return start();
538    else
539        return 0;
540}
541
542int32_t QCamera3MetadataChannel::registerBuffers(uint32_t num_buffers,
543                                            buffer_handle_t **buffers)
544{
545    // no registerBuffers are supported for metadata channel
546    return -EINVAL;
547}
548
549void QCamera3MetadataChannel::streamCbRoutine(
550                        mm_camera_super_buf_t *super_frame,
551                        QCamera3Stream *stream)
552{
553    if (super_frame == NULL || super_frame->num_bufs != 1) {
554        ALOGE("%s: super_frame is not valid", __func__);
555        return;
556    }
557    mChannelCB(super_frame->bufs[0], NULL, mUserData);
558}
559
560QCamera3Memory* QCamera3MetadataChannel::getStreamBufs(uint32_t /*len*/)
561{
562    int rc;
563    mMemory = new QCamera3HeapMemory();
564    if (!mMemory) {
565        ALOGE("%s: unable to create metadata memory", __func__);
566        return NULL;
567    }
568    rc = mMemory->allocate(MIN_STREAMING_BUFFER_NUM, sizeof(parm_buffer_t), true);
569    if (rc < 0) {
570        ALOGE("%s: unable to allocate metadata memory", __func__);
571        delete mMemory;
572        mMemory = NULL;
573        return NULL;
574    }
575    memset(mMemory->getPtr(0), 0, sizeof(parm_buffer_t));
576    return mMemory;
577}
578
579void QCamera3MetadataChannel::putStreamBufs()
580{
581    mMemory->deallocate();
582    delete mMemory;
583    mMemory = NULL;
584}
585
586QCamera3PicChannel::QCamera3PicChannel(uint32_t cam_handle,
587                    mm_camera_ops_t *cam_ops,
588                    channel_cb_routine cb_routine,
589                    camera3_stream_t *stream) :
590                        QCamera3Channel(cam_handle, cam_ops, cb_routine)
591{
592    //TODO
593}
594
595QCamera3PicChannel::~QCamera3PicChannel()
596{
597}
598
599int32_t QCamera3PicChannel::request(const camera3_stream_buffer_t *buffer)
600{
601    //TODO
602    return 0;
603}
604
605int32_t QCamera3PicChannel::registerBuffers(uint32_t num_buffers,
606                        buffer_handle_t **buffers)
607{
608    //TODO
609    return 0;
610}
611
612void QCamera3PicChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame,
613                            QCamera3Stream *stream)
614{
615    //TODO
616    return;
617}
618
619QCamera3Memory* QCamera3PicChannel::getStreamBufs(uint32_t len)
620{
621    int rc = 0;
622    mYuvMemory = new QCamera3HeapMemory();
623    if (!mYuvMemory) {
624        ALOGE("%s: unable to create metadata memory", __func__);
625        return NULL;
626    }
627
628    rc = mYuvMemory->allocate(1, len, false);
629    if (rc < 0) {
630        ALOGE("%s: unable to allocate metadata memory", __func__);
631        delete mYuvMemory;
632        mYuvMemory = NULL;
633        return NULL;
634    }
635    return mYuvMemory;
636}
637
638void QCamera3PicChannel::putStreamBufs()
639{
640    mYuvMemory->deallocate();
641    delete mYuvMemory;
642    mYuvMemory = NULL;
643}
644
645int QCamera3PicChannel::kMaxBuffers = 1;
646}; // namespace qcamera
647