QCamera3Channel.cpp revision e6ab32d89cf169705236988f0f74309f914c88b7
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 <system/camera_metadata.h>
34#include <gralloc_priv.h>
35#include <utils/Log.h>
36#include <utils/Errors.h>
37#include "QCamera3Channel.h"
38
39using namespace android;
40
41#define MIN_STREAMING_BUFFER_NUM 3
42
43namespace qcamera {
44
45/*===========================================================================
46 * FUNCTION   : QCamera3Channel
47 *
48 * DESCRIPTION: constrcutor of QCamera3Channel
49 *
50 * PARAMETERS :
51 *   @cam_handle : camera handle
52 *   @cam_ops    : ptr to camera ops table
53 *
54 * RETURN     : none
55 *==========================================================================*/
56QCamera3Channel::QCamera3Channel(uint32_t cam_handle,
57                               mm_camera_ops_t *cam_ops,
58                               channel_cb_routine cb_routine,
59                               cam_padding_info_t *paddingInfo,
60                               void *userData)
61{
62    m_camHandle = cam_handle;
63    m_camOps = cam_ops;
64    mChannelCB = cb_routine;
65    mPaddingInfo = paddingInfo;
66    mUserData = userData;
67    m_bIsActive = false;
68
69    m_handle = 0;
70    m_numStreams = 0;
71    memset(mStreams, 0, sizeof(mStreams));
72}
73
74/*===========================================================================
75 * FUNCTION   : QCamera3Channel
76 *
77 * DESCRIPTION: default constrcutor of QCamera3Channel
78 *
79 * PARAMETERS : none
80 *
81 * RETURN     : none
82 *==========================================================================*/
83QCamera3Channel::QCamera3Channel()
84{
85    m_camHandle = 0;
86    m_camOps = NULL;
87    mPaddingInfo = NULL;
88    mUserData = NULL;
89    m_bIsActive = false;
90
91    m_handle = 0;
92    m_numStreams = 0;
93    memset(mStreams, 0, sizeof(mStreams));
94}
95
96/*===========================================================================
97 * FUNCTION   : ~QCamera3Channel
98 *
99 * DESCRIPTION: destructor of QCamera3Channel
100 *
101 * PARAMETERS : none
102 *
103 * RETURN     : none
104 *==========================================================================*/
105QCamera3Channel::~QCamera3Channel()
106{
107    if (m_bIsActive)
108        stop();
109
110    for (int i = 0; i < m_numStreams; i++) {
111        if (mStreams[i] != NULL) {
112            delete mStreams[i];
113            mStreams[i] = 0;
114        }
115    }
116    m_numStreams = 0;
117    m_camOps->delete_channel(m_camHandle, m_handle);
118    m_handle = 0;
119}
120
121/*===========================================================================
122 * FUNCTION   : init
123 *
124 * DESCRIPTION: initialization of channel
125 *
126 * PARAMETERS :
127 *   @attr    : channel bundle attribute setting
128 *   @dataCB  : data notify callback
129 *   @userData: user data ptr
130 *
131 * RETURN     : int32_t type of status
132 *              NO_ERROR  -- success
133 *              none-zero failure code
134 *==========================================================================*/
135int32_t QCamera3Channel::init(mm_camera_channel_attr_t *attr,
136                             mm_camera_buf_notify_t dataCB)
137{
138    m_handle = m_camOps->add_channel(m_camHandle,
139                                      attr,
140                                      dataCB,
141                                      mUserData);
142    if (m_handle == 0) {
143        ALOGE("%s: Add channel failed", __func__);
144        return UNKNOWN_ERROR;
145    }
146    return NO_ERROR;
147}
148
149/*===========================================================================
150 * FUNCTION   : addStream
151 *
152 * DESCRIPTION: add a stream into channel
153 *
154 * PARAMETERS :
155 *   @allocator      : stream related buffer allocator
156 *   @streamInfoBuf  : ptr to buf that constains stream info
157 *   @minStreamBufNum: number of stream buffers needed
158 *   @paddingInfo    : padding information
159 *   @stream_cb      : stream data notify callback
160 *   @userdata       : user data ptr
161 *
162 * RETURN     : int32_t type of status
163 *              NO_ERROR  -- success
164 *              none-zero failure code
165 *==========================================================================*/
166int32_t QCamera3Channel::addStream(cam_stream_type_t streamType,
167                                  cam_format_t streamFormat,
168                                  cam_dimension_t streamDim,
169                                  uint8_t minStreamBufNum)
170{
171    int32_t rc = NO_ERROR;
172    if (m_numStreams >= MAX_STREAM_NUM_IN_BUNDLE) {
173        ALOGE("%s: stream number (%d) exceeds max limit (%d)",
174              __func__, m_numStreams, MAX_STREAM_NUM_IN_BUNDLE);
175        return BAD_VALUE;
176    }
177    QCamera3Stream *pStream = new QCamera3Stream(m_camHandle,
178                                               m_handle,
179                                               m_camOps,
180                                               mPaddingInfo,
181                                               this);
182    if (pStream == NULL) {
183        ALOGE("%s: No mem for Stream", __func__);
184        return NO_MEMORY;
185    }
186
187    rc = pStream->init(streamType, streamFormat, streamDim, minStreamBufNum,
188                                                    streamCbRoutine, this);
189    if (rc == 0) {
190        mStreams[m_numStreams] = pStream;
191        m_numStreams++;
192    } else {
193        delete pStream;
194    }
195    return rc;
196}
197
198/*===========================================================================
199 * FUNCTION   : start
200 *
201 * DESCRIPTION: start channel, which will start all streams belong to this channel
202 *
203 * PARAMETERS :
204 *
205 * RETURN     : int32_t type of status
206 *              NO_ERROR  -- success
207 *              none-zero failure code
208 *==========================================================================*/
209int32_t QCamera3Channel::start()
210{
211    int32_t rc = NO_ERROR;
212
213    if (m_numStreams > 1) {
214        ALOGE("%s: bundle not supported", __func__);
215    }
216
217    for (int i = 0; i < m_numStreams; i++) {
218        if (mStreams[i] != NULL) {
219            mStreams[i]->start();
220        }
221    }
222    rc = m_camOps->start_channel(m_camHandle, m_handle);
223
224    if (rc != NO_ERROR) {
225        for (int i = 0; i < m_numStreams; i++) {
226            if (mStreams[i] != NULL) {
227                mStreams[i]->stop();
228            }
229        }
230    } else {
231        m_bIsActive = true;
232    }
233
234    return rc;
235}
236
237/*===========================================================================
238 * FUNCTION   : stop
239 *
240 * DESCRIPTION: stop a channel, which will stop all streams belong to this channel
241 *
242 * PARAMETERS : none
243 *
244 * RETURN     : int32_t type of status
245 *              NO_ERROR  -- success
246 *              none-zero failure code
247 *==========================================================================*/
248int32_t QCamera3Channel::stop()
249{
250    int32_t rc = NO_ERROR;
251    rc = m_camOps->stop_channel(m_camHandle, m_handle);
252
253    for (int i = 0; i < m_numStreams; i++) {
254        if (mStreams[i] != NULL) {
255            mStreams[i]->stop();
256        }
257    }
258
259    m_bIsActive = false;
260    return rc;
261}
262
263/*===========================================================================
264 * FUNCTION   : bufDone
265 *
266 * DESCRIPTION: return a stream buf back to kernel
267 *
268 * PARAMETERS :
269 *   @recvd_frame  : stream buf frame to be returned
270 *
271 * RETURN     : int32_t type of status
272 *              NO_ERROR  -- success
273 *              none-zero failure code
274 *==========================================================================*/
275int32_t QCamera3Channel::bufDone(mm_camera_super_buf_t *recvd_frame)
276{
277    int32_t rc = NO_ERROR;
278    for (int i = 0; i < recvd_frame->num_bufs; i++) {
279         if (recvd_frame->bufs[i] != NULL) {
280             for (int j = 0; j < m_numStreams; j++) {
281                 if (mStreams[j] != NULL &&
282                     mStreams[j]->getMyHandle() == recvd_frame->bufs[i]->stream_id) {
283                     rc = mStreams[j]->bufDone(recvd_frame->bufs[i]->buf_idx);
284                     break; // break loop j
285                 }
286             }
287         }
288    }
289
290    return rc;
291}
292
293/*===========================================================================
294 * FUNCTION   : getStreamByHandle
295 *
296 * DESCRIPTION: return stream object by stream handle
297 *
298 * PARAMETERS :
299 *   @streamHandle : stream handle
300 *
301 * RETURN     : stream object. NULL if not found
302 *==========================================================================*/
303QCamera3Stream *QCamera3Channel::getStreamByHandle(uint32_t streamHandle)
304{
305    for (int i = 0; i < m_numStreams; i++) {
306        if (mStreams[i] != NULL && mStreams[i]->getMyHandle() == streamHandle) {
307            return mStreams[i];
308        }
309    }
310    return NULL;
311}
312
313/*===========================================================================
314 * FUNCTION   : getStreamByHandle
315 *
316 * DESCRIPTION: return stream object by stream handle
317 *
318 * PARAMETERS :
319 *   @streamHandle : stream handle
320 *
321 * RETURN     : stream object. NULL if not found
322 *==========================================================================*/
323QCamera3Stream *QCamera3Channel::getStreamByIndex(uint8_t index)
324{
325    if (index < m_numStreams) {
326        return mStreams[index];
327    }
328    return NULL;
329}
330
331/*===========================================================================
332 * FUNCTION   : streamCbRoutine
333 *
334 * DESCRIPTION: callback routine for stream
335 *
336 * PARAMETERS :
337 *   @streamHandle : stream handle
338 *
339 * RETURN     : stream object. NULL if not found
340 *==========================================================================*/
341void QCamera3Channel::streamCbRoutine(mm_camera_super_buf_t *super_frame,
342                QCamera3Stream *stream, void *userdata)
343{
344    QCamera3Channel *channel = (QCamera3Channel *)userdata;
345    if (channel == NULL) {
346        ALOGE("%s: invalid channel pointer", __func__);
347        return;
348    }
349    channel->streamCbRoutine(super_frame, stream);
350}
351
352/*===========================================================================
353 * FUNCTION   : QCamera3RegularChannel
354 *
355 * DESCRIPTION: constrcutor of QCamera3RegularChannel
356 *
357 * PARAMETERS :
358 *   @cam_handle : camera handle
359 *   @cam_ops    : ptr to camera ops table
360 *   @cb_routine : callback routine to frame aggregator
361 *   @stream     : camera3_stream_t structure
362 *
363 * RETURN     : none
364 *==========================================================================*/
365QCamera3RegularChannel::QCamera3RegularChannel(uint32_t cam_handle,
366                    mm_camera_ops_t *cam_ops,
367                    channel_cb_routine cb_routine,
368                    cam_padding_info_t *paddingInfo,
369                    void *userData,
370                    camera3_stream_t *stream) :
371                        QCamera3Channel(cam_handle, cam_ops, cb_routine,
372                                                paddingInfo, userData),
373                        mCamera3Stream(stream),
374                        mNumBufs(0),
375                        mCamera3Buffers(NULL),
376                        mMemory(NULL)
377{
378}
379
380/*===========================================================================
381 * FUNCTION   : ~QCamera3RegularChannel
382 *
383 * DESCRIPTION: destructor of QCamera3RegularChannel
384 *
385 * PARAMETERS : none
386 *
387 * RETURN     : none
388 *==========================================================================*/
389QCamera3RegularChannel::~QCamera3RegularChannel()
390{
391    if (mCamera3Buffers) {
392        delete[] mCamera3Buffers;
393    }
394}
395
396/*===========================================================================
397 * FUNCTION   : request
398 *
399 * DESCRIPTION: process a request from camera service. Stream on if ncessary.
400 *
401 * PARAMETERS :
402 *   @buffer  : buffer to be filled for this request
403 *
404 * RETURN     : 0 on a success start of capture
405 *              -EINVAL on invalid input
406 *              -ENODEV on serious error
407 *==========================================================================*/
408int32_t QCamera3RegularChannel::request(buffer_handle_t *buffer, uint32_t frameNumber)
409{
410    //FIX ME: Return buffer back in case of failures below.
411
412    int32_t rc = NO_ERROR;
413    int index;
414    if(!m_bIsActive) {
415        ALOGD("%s: First request on this channel starting stream",__func__);
416        start();
417        if(rc != NO_ERROR) {
418            ALOGE("%s: Failed to start the stream on the request",__func__);
419            return rc;
420        }
421    } else {
422        ALOGV("%s: Request on an existing stream",__func__);
423    }
424
425    if(!mMemory) {
426        ALOGE("%s: error, Gralloc Memory object not yet created for this stream",__func__);
427        return NO_MEMORY;
428    }
429
430    index = mMemory->getMatchBufIndex((void*)buffer);
431    if(index < 0) {
432        ALOGE("%s: Could not find object among registered buffers",__func__);
433        return DEAD_OBJECT;
434    }
435
436    rc = mStreams[0]->bufDone(index);
437    if(rc != NO_ERROR) {
438        ALOGE("%s: Failed to Q new buffer to stream",__func__);
439        return rc;
440    }
441
442    rc = mMemory->markFrameNumber(index, frameNumber);
443    return rc;
444}
445
446/*===========================================================================
447 * FUNCTION   : registerBuffers
448 *
449 * DESCRIPTION: register streaming buffers to the channel object
450 *
451 * PARAMETERS :
452 *   @num_buffers : number of buffers to be registered
453 *   @buffers     : buffer to be registered
454 *
455 * RETURN     : 0 on a success start of capture
456 *              -EINVAL on invalid input
457 *              -ENOMEM on failure to register the buffer
458 *              -ENODEV on serious error
459 *==========================================================================*/
460int32_t QCamera3RegularChannel::registerBuffers(uint32_t num_buffers, buffer_handle_t **buffers)
461{
462    int rc = 0;
463    struct private_handle_t *priv_handle = (struct private_handle_t *)(*buffers[0]);
464    cam_stream_type_t streamType;
465    cam_format_t streamFormat;
466    cam_dimension_t streamDim;
467
468    rc = init(NULL, NULL);
469    if (rc < 0) {
470        ALOGE("%s: init failed", __func__);
471        return rc;
472    }
473
474    if (mCamera3Stream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
475        if (priv_handle->flags & private_handle_t::PRIV_FLAGS_VIDEO_ENCODER) {
476            streamType = CAM_STREAM_TYPE_VIDEO;
477            streamFormat = CAM_FORMAT_YUV_420_NV12;
478        } else if (priv_handle->flags & private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY) {
479            streamType = CAM_STREAM_TYPE_PREVIEW;
480            streamFormat = CAM_FORMAT_YUV_420_NV21;
481        } else {
482            ALOGE("%s: priv_handle->flags 0x%x not supported",
483                    __func__, priv_handle->flags);
484            return -EINVAL;
485        }
486    } else {
487        //TODO: Fail for other types of streams for now
488        ALOGE("%s: format is not IMPLEMENTATION_DEFINED", __func__);
489        return -EINVAL;
490    }
491
492    /* Bookkeep buffer set because they go out of scope after register call */
493    mNumBufs = num_buffers;
494    mCamera3Buffers = new buffer_handle_t*[num_buffers];
495    if (mCamera3Buffers == NULL) {
496        ALOGE("%s: Failed to allocate buffer_handle_t*", __func__);
497        return -ENOMEM;
498    }
499    for (size_t i = 0; i < num_buffers; i++)
500        mCamera3Buffers[i] = buffers[i];
501
502    streamDim.width = mCamera3Stream->width;
503    streamDim.height = mCamera3Stream->height;
504    rc = QCamera3Channel::addStream(streamType, streamFormat, streamDim,
505        num_buffers);
506
507    return rc;
508}
509
510void QCamera3RegularChannel::streamCbRoutine(
511                            mm_camera_super_buf_t *super_frame,
512                            QCamera3Stream *stream)
513{
514    //FIXME Q Buf back in case of error?
515    uint8_t frameIndex;
516    buffer_handle_t *resultBuffer;
517    int32_t resultFrameNumber;
518    camera3_stream_buffer_t result;
519
520    if(!super_frame) {
521         ALOGE("%s: Invalid Super buffer",__func__);
522         return;
523    }
524
525    if(super_frame->num_bufs != 1) {
526         ALOGE("%s: Multiple streams are not supported",__func__);
527         return;
528    }
529    if(super_frame->bufs[0] == NULL ) {
530         ALOGE("%s: Error, Super buffer frame does not contain valid buffer",
531                  __func__);
532         return;
533    }
534
535    frameIndex = (uint8_t)super_frame->bufs[0]->buf_idx;
536    if(frameIndex >= mNumBufs) {
537         ALOGE("%s: Error, Invalid index for buffer",__func__);
538         if(stream) {
539             stream->bufDone(frameIndex);
540         }
541         return;
542    }
543
544    ////Use below data to issue framework callback
545    resultBuffer = mCamera3Buffers[frameIndex];
546    resultFrameNumber = mMemory->getFrameNumber(frameIndex);
547
548    result.stream = mCamera3Stream;
549    result.buffer = resultBuffer;
550    result.status = CAMERA3_BUFFER_STATUS_OK;
551    result.acquire_fence = -1;
552    result.release_fence = -1;
553
554    mChannelCB(NULL, &result, resultFrameNumber, mUserData);
555    return;
556}
557
558QCamera3Memory* QCamera3RegularChannel::getStreamBufs(uint32_t len)
559{
560    if (mNumBufs == 0 || mCamera3Buffers == NULL) {
561        ALOGE("%s: buffers not registered yet", __func__);
562        return NULL;
563    }
564
565    mMemory = new QCamera3GrallocMemory();
566    if (mMemory == NULL) {
567        return NULL;
568    }
569
570    if (mMemory->registerBuffers(mNumBufs, mCamera3Buffers) < 0) {
571        delete mMemory;
572        mMemory = NULL;
573        return NULL;
574    }
575    return mMemory;
576}
577
578void QCamera3RegularChannel::putStreamBufs()
579{
580    mMemory->unregisterBuffers();
581    delete mMemory;
582    mMemory = NULL;
583}
584
585int QCamera3RegularChannel::kMaxBuffers = 3;
586
587QCamera3MetadataChannel::QCamera3MetadataChannel(uint32_t cam_handle,
588                    mm_camera_ops_t *cam_ops,
589                    channel_cb_routine cb_routine,
590                    cam_padding_info_t *paddingInfo,
591                    void *userData) :
592                        QCamera3Channel(cam_handle, cam_ops,
593                                cb_routine, paddingInfo, userData),
594                        mMemory(NULL)
595{
596#ifdef FAKE_FRAME_NUMBERS
597    startingFrameNumber=0;
598#endif
599}
600
601QCamera3MetadataChannel::~QCamera3MetadataChannel()
602{
603    if (m_bIsActive)
604        stop();
605
606    if (mMemory) {
607        mMemory->deallocate();
608        delete mMemory;
609        mMemory = NULL;
610    }
611}
612
613int32_t QCamera3MetadataChannel::initialize()
614{
615    int32_t rc;
616    cam_dimension_t streamDim;
617
618    if (mMemory || m_numStreams > 0) {
619        ALOGE("%s: metadata channel already initialized", __func__);
620        return -EINVAL;
621    }
622
623    rc = init(NULL, NULL);
624    if (rc < 0) {
625        ALOGE("%s: init failed", __func__);
626        return rc;
627    }
628
629    streamDim.width = sizeof(parm_buffer_t),
630    streamDim.height = 1;
631    rc = QCamera3Channel::addStream(CAM_STREAM_TYPE_METADATA, CAM_FORMAT_MAX,
632        streamDim, MIN_STREAMING_BUFFER_NUM);
633    if (rc < 0) {
634        ALOGE("%s: addStream failed", __func__);
635    }
636    return rc;
637}
638
639int32_t QCamera3MetadataChannel::request(buffer_handle_t *buffer, uint32_t frameNumber)
640{
641    if (!m_bIsActive) {
642#ifdef FAKE_FRAME_NUMBERS
643        startingFrameNumber=frameNumber;
644#endif
645        return start();
646    }
647    else
648        return 0;
649}
650
651int32_t QCamera3MetadataChannel::registerBuffers(uint32_t /*num_buffers*/,
652                                        buffer_handle_t ** /*buffers*/)
653{
654    // no registerBuffers are supported for metadata channel
655    return -EINVAL;
656}
657
658void QCamera3MetadataChannel::streamCbRoutine(
659                        mm_camera_super_buf_t *super_frame,
660                        QCamera3Stream *stream)
661{
662    uint32_t requestNumber = 0;
663    if (super_frame == NULL || super_frame->num_bufs != 1) {
664        ALOGE("%s: super_frame is not valid", __func__);
665        return;
666    }
667#ifdef FAKE_FRAME_NUMBERS
668    requestNumber = startingFrameNumber++;
669#endif
670    mChannelCB((metadata_buffer_t *)(super_frame->bufs[0]->buffer),
671                                            NULL, requestNumber, mUserData);
672
673    //Return the buffer
674    stream->bufDone(super_frame->bufs[0]->buf_idx);
675}
676
677QCamera3Memory* QCamera3MetadataChannel::getStreamBufs(uint32_t len)
678{
679    int rc;
680    if (len != sizeof(parm_buffer_t)) {
681        ALOGE("%s: size doesn't match %d vs %d", __func__,
682                len, sizeof(parm_buffer_t));
683        return NULL;
684    }
685    mMemory = new QCamera3HeapMemory();
686    if (!mMemory) {
687        ALOGE("%s: unable to create metadata memory", __func__);
688        return NULL;
689    }
690    rc = mMemory->allocate(MIN_STREAMING_BUFFER_NUM, len, true);
691    if (rc < 0) {
692        ALOGE("%s: unable to allocate metadata memory", __func__);
693        delete mMemory;
694        mMemory = NULL;
695        return NULL;
696    }
697    memset(mMemory->getPtr(0), 0, sizeof(parm_buffer_t));
698    return mMemory;
699}
700
701void QCamera3MetadataChannel::putStreamBufs()
702{
703    mMemory->deallocate();
704    delete mMemory;
705    mMemory = NULL;
706}
707
708QCamera3PicChannel::QCamera3PicChannel(uint32_t cam_handle,
709                    mm_camera_ops_t *cam_ops,
710                    channel_cb_routine cb_routine,
711                    cam_padding_info_t *paddingInfo,
712                    void *userData,
713                    camera3_stream_t *stream) :
714                        QCamera3Channel(cam_handle, cam_ops, cb_routine,
715                                paddingInfo, userData)
716{
717    //TODO
718}
719
720QCamera3PicChannel::~QCamera3PicChannel()
721{
722}
723
724int32_t QCamera3PicChannel::request(buffer_handle_t *buffer, uint32_t frameNumber)
725{
726    //TODO
727    return 0;
728}
729
730int32_t QCamera3PicChannel::registerBuffers(uint32_t num_buffers,
731                        buffer_handle_t **buffers)
732{
733    //TODO
734    return 0;
735}
736
737void QCamera3PicChannel::streamCbRoutine(mm_camera_super_buf_t *super_frame,
738                            QCamera3Stream *stream)
739{
740    //TODO
741    return;
742}
743
744QCamera3Memory* QCamera3PicChannel::getStreamBufs(uint32_t len)
745{
746    int rc = 0;
747    mYuvMemory = new QCamera3HeapMemory();
748    if (!mYuvMemory) {
749        ALOGE("%s: unable to create metadata memory", __func__);
750        return NULL;
751    }
752
753    rc = mYuvMemory->allocate(1, len, false);
754    if (rc < 0) {
755        ALOGE("%s: unable to allocate metadata memory", __func__);
756        delete mYuvMemory;
757        mYuvMemory = NULL;
758        return NULL;
759    }
760    return mYuvMemory;
761}
762
763void QCamera3PicChannel::putStreamBufs()
764{
765    mYuvMemory->deallocate();
766    delete mYuvMemory;
767    mYuvMemory = NULL;
768}
769
770int QCamera3PicChannel::kMaxBuffers = 1;
771}; // namespace qcamera
772