1/*
2 * smart_buffer_priv.cpp - smart buffer for XCamVideoBuffer
3 *
4 *  Copyright (c) 2016-2017 Intel Corporation
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *      http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * Author: Wind Yuan <feng.yuan@intel.com>
19 */
20
21#include <xcam_std.h>
22#include "base/xcam_buffer.h"
23#include "video_buffer.h"
24#if HAVE_LIBDRM
25#include "drm_bo_buffer.h"
26#endif
27
28namespace XCam {
29
30class SmartBufferPriv
31    : public XCamVideoBufferIntel
32{
33public:
34    SmartBufferPriv (const SmartPtr<VideoBuffer> &buf);
35    ~SmartBufferPriv ();
36
37    bool is_valid () const {
38        return _buf_ptr.ptr ();
39    }
40
41    static void     buf_ref (XCamVideoBuffer *data);
42    static void     buf_unref (XCamVideoBuffer *data);
43    static uint8_t *buf_map (XCamVideoBuffer *data);
44    static void     buf_unmap (XCamVideoBuffer *data);
45    static int      buf_get_fd (XCamVideoBuffer *data);
46    static void    *buf_get_bo (XCamVideoBufferIntel *data);
47
48private:
49    XCAM_DEAD_COPY (SmartBufferPriv);
50
51private:
52    mutable RefCount       *_ref;
53    SmartPtr<VideoBuffer>   _buf_ptr;
54};
55
56SmartBufferPriv::SmartBufferPriv (const SmartPtr<VideoBuffer> &buf)
57    : _ref (NULL)
58{
59    XCAM_ASSERT (buf.ptr ());
60    this->_buf_ptr = buf;
61
62    if (!buf.ptr ()) {
63        return;
64    }
65
66    _ref = new RefCount ();
67
68    const VideoBufferInfo& video_info = buf->get_video_info ();
69
70    this->base.info = *((const XCamVideoBufferInfo*)&video_info);
71    this->base.mem_type = XCAM_MEM_TYPE_PRIVATE_BO;
72    this->base.timestamp = buf->get_timestamp ();
73
74    this->base.ref = SmartBufferPriv::buf_ref;
75    this->base.unref = SmartBufferPriv::buf_unref;
76    this->base.map = SmartBufferPriv::buf_map;
77    this->base.unmap = SmartBufferPriv::buf_unmap;
78    this->base.get_fd = SmartBufferPriv::buf_get_fd;
79    this->get_bo = SmartBufferPriv::buf_get_bo;
80}
81
82SmartBufferPriv::~SmartBufferPriv ()
83{
84    delete _ref;
85}
86
87void
88SmartBufferPriv::buf_ref (XCamVideoBuffer *data)
89{
90    SmartBufferPriv *buf = (SmartBufferPriv*) data;
91    XCAM_ASSERT (buf->_ref);
92    if (buf->_ref)
93        buf->_ref->ref ();
94}
95
96void
97SmartBufferPriv::buf_unref (XCamVideoBuffer *data)
98{
99    SmartBufferPriv *buf = (SmartBufferPriv*) data;
100    XCAM_ASSERT (buf->_ref);
101    if (buf->_ref) {
102        if (!buf->_ref->unref()) {
103            delete buf;
104        }
105    }
106}
107
108uint8_t *
109SmartBufferPriv::buf_map (XCamVideoBuffer *data)
110{
111    SmartBufferPriv *buf = (SmartBufferPriv*) data;
112    XCAM_ASSERT (buf->_buf_ptr.ptr ());
113    return buf->_buf_ptr->map ();
114}
115
116void
117SmartBufferPriv::buf_unmap (XCamVideoBuffer *data)
118{
119    SmartBufferPriv *buf = (SmartBufferPriv*) data;
120    XCAM_ASSERT (buf->_buf_ptr.ptr ());
121    buf->_buf_ptr->unmap ();
122}
123
124int
125SmartBufferPriv::buf_get_fd (XCamVideoBuffer *data)
126{
127    SmartBufferPriv *buf = (SmartBufferPriv*) data;
128    XCAM_ASSERT (buf->_buf_ptr.ptr ());
129    return buf->_buf_ptr->get_fd ();
130}
131
132void *
133SmartBufferPriv::buf_get_bo (XCamVideoBufferIntel *data)
134{
135#if HAVE_LIBDRM
136    SmartBufferPriv *buf = (SmartBufferPriv*) data;
137    XCAM_ASSERT (buf->_buf_ptr.ptr ());
138
139    SmartPtr<DrmBoBuffer> bo_buf = buf->_buf_ptr.dynamic_cast_ptr<DrmBoBuffer> ();
140    XCAM_FAIL_RETURN (
141        ERROR,
142        bo_buf.ptr (),
143        NULL,
144        "get DrmBoBuffer failed");
145
146    return bo_buf->get_bo ();
147#else
148    XCAM_LOG_ERROR ("VideoBuffer doesn't support DrmBoBuffer");
149
150    XCAM_UNUSED (data);
151    return NULL;
152#endif
153}
154
155XCamVideoBuffer *
156convert_to_external_buffer (const SmartPtr<VideoBuffer> &buf)
157{
158    SmartBufferPriv *priv_buf = new SmartBufferPriv (buf);
159    XCAM_ASSERT (priv_buf);
160
161    if (priv_buf->is_valid ())
162        return (XCamVideoBuffer *)(priv_buf);
163
164    delete priv_buf;
165    return NULL;
166}
167
168}
169