~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.0.1/pjmedia/src/pjmedia/format.c

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (1.1.11)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: package-import@ubuntu.com-20140128182336-3xenud1kbnwmf3mz
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: format.c 4158 2012-06-06 09:56:14Z nanang $ */
2
 
/*
3
 
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
 
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5
 
 *
6
 
 * This program is free software; you can redistribute it and/or modify
7
 
 * it under the terms of the GNU General Public License as published by
8
 
 * the Free Software Foundation; either version 2 of the License, or
9
 
 * (at your option) any later version.
10
 
 *
11
 
 * This program is distributed in the hope that it will be useful,
12
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 * GNU General Public License for more details.
15
 
 *
16
 
 * You should have received a copy of the GNU General Public License
17
 
 * along with this program; if not, write to the Free Software
18
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 
 */
20
 
#include <pjmedia/format.h>
21
 
#include <pj/assert.h>
22
 
#include <pj/errno.h>
23
 
#include <pj/pool.h>
24
 
#include <pj/string.h>
25
 
 
26
 
 
27
 
PJ_DEF(void) pjmedia_format_init_audio( pjmedia_format *fmt,
28
 
                                        pj_uint32_t fmt_id,
29
 
                                        unsigned clock_rate,
30
 
                                        unsigned channel_count,
31
 
                                        unsigned bits_per_sample,
32
 
                                        unsigned frame_time_usec,
33
 
                                        pj_uint32_t avg_bps,
34
 
                                        pj_uint32_t max_bps)
35
 
{
36
 
    fmt->id = fmt_id;
37
 
    fmt->type = PJMEDIA_TYPE_AUDIO;
38
 
    fmt->detail_type = PJMEDIA_FORMAT_DETAIL_AUDIO;
39
 
 
40
 
    fmt->det.aud.clock_rate = clock_rate;
41
 
    fmt->det.aud.channel_count = channel_count;
42
 
    fmt->det.aud.bits_per_sample = bits_per_sample;
43
 
    fmt->det.aud.frame_time_usec = frame_time_usec;
44
 
    fmt->det.aud.avg_bps = avg_bps;
45
 
    fmt->det.aud.max_bps = max_bps;
46
 
}
47
 
 
48
 
 
49
 
PJ_DEF(pjmedia_audio_format_detail*)
50
 
pjmedia_format_get_audio_format_detail(const pjmedia_format *fmt,
51
 
                                       pj_bool_t assert_valid)
52
 
{
53
 
    if (fmt->detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO) {
54
 
        return (pjmedia_audio_format_detail*) &fmt->det.aud;
55
 
    } else {
56
 
        /* Get rid of unused var compiler warning if pj_assert()
57
 
         * macro does not do anything
58
 
         */
59
 
        PJ_UNUSED_ARG(assert_valid);
60
 
        pj_assert(!assert_valid || !"Invalid audio format detail");
61
 
        return NULL;
62
 
    }
63
 
}
64
 
 
65
 
 
66
 
PJ_DEF(pjmedia_format*) pjmedia_format_copy(pjmedia_format *dst,
67
 
                                            const pjmedia_format *src)
68
 
{
69
 
    return (pjmedia_format*)pj_memcpy(dst, src, sizeof(*src));
70
 
}
71
 
 
72
 
 
73
 
#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
74
 
 
75
 
 
76
 
static pj_status_t apply_packed_fmt(const pjmedia_video_format_info *fi,
77
 
                                    pjmedia_video_apply_fmt_param *aparam);
78
 
 
79
 
static pj_status_t apply_planar_420(const pjmedia_video_format_info *fi,
80
 
                                    pjmedia_video_apply_fmt_param *aparam);
81
 
 
82
 
static pj_status_t apply_planar_422(const pjmedia_video_format_info *fi,
83
 
                                    pjmedia_video_apply_fmt_param *aparam);
84
 
 
85
 
static pj_status_t apply_planar_444(const pjmedia_video_format_info *fi,
86
 
                                    pjmedia_video_apply_fmt_param *aparam);
87
 
 
88
 
struct pjmedia_video_format_mgr
89
 
{
90
 
    unsigned                    max_info;
91
 
    unsigned                    info_cnt;
92
 
    pjmedia_video_format_info **infos;
93
 
};
94
 
 
95
 
static pjmedia_video_format_mgr *video_format_mgr_instance;
96
 
static pjmedia_video_format_info built_in_vid_fmt_info[] =
97
 
{
98
 
    {PJMEDIA_FORMAT_RGB24, "RGB24", PJMEDIA_COLOR_MODEL_RGB, 24, 1, &apply_packed_fmt},
99
 
    {PJMEDIA_FORMAT_RGBA,  "RGBA", PJMEDIA_COLOR_MODEL_RGB, 32, 1, &apply_packed_fmt},
100
 
    {PJMEDIA_FORMAT_BGRA,  "BGRA", PJMEDIA_COLOR_MODEL_RGB, 32, 1, &apply_packed_fmt},
101
 
    {PJMEDIA_FORMAT_DIB ,  "DIB ", PJMEDIA_COLOR_MODEL_RGB, 24, 1, &apply_packed_fmt},
102
 
    {PJMEDIA_FORMAT_GBRP,  "GBRP", PJMEDIA_COLOR_MODEL_RGB, 24, 3, &apply_planar_444},
103
 
    {PJMEDIA_FORMAT_AYUV,  "AYUV", PJMEDIA_COLOR_MODEL_YUV, 32, 1, &apply_packed_fmt},
104
 
    {PJMEDIA_FORMAT_YUY2,  "YUY2", PJMEDIA_COLOR_MODEL_YUV, 16, 1, &apply_packed_fmt},
105
 
    {PJMEDIA_FORMAT_UYVY,  "UYVY", PJMEDIA_COLOR_MODEL_YUV, 16, 1, &apply_packed_fmt},
106
 
    {PJMEDIA_FORMAT_YVYU,  "YVYU", PJMEDIA_COLOR_MODEL_YUV, 16, 1, &apply_packed_fmt},
107
 
    {PJMEDIA_FORMAT_I420,  "I420", PJMEDIA_COLOR_MODEL_YUV, 12, 3, &apply_planar_420},
108
 
    {PJMEDIA_FORMAT_YV12,  "YV12", PJMEDIA_COLOR_MODEL_YUV, 12, 3, &apply_planar_420},
109
 
    {PJMEDIA_FORMAT_I422,  "I422", PJMEDIA_COLOR_MODEL_YUV, 16, 3, &apply_planar_422},
110
 
    {PJMEDIA_FORMAT_I420JPEG, "I420JPG", PJMEDIA_COLOR_MODEL_YUV, 12, 3, &apply_planar_420},
111
 
    {PJMEDIA_FORMAT_I422JPEG, "I422JPG", PJMEDIA_COLOR_MODEL_YUV, 16, 3, &apply_planar_422},
112
 
};
113
 
 
114
 
PJ_DEF(void) pjmedia_format_init_video( pjmedia_format *fmt,
115
 
                                        pj_uint32_t fmt_id,
116
 
                                        unsigned width,
117
 
                                        unsigned height,
118
 
                                        unsigned fps_num,
119
 
                                        unsigned fps_denum)
120
 
{
121
 
    pj_assert(fps_denum);
122
 
    fmt->id = fmt_id;
123
 
    fmt->type = PJMEDIA_TYPE_VIDEO;
124
 
    fmt->detail_type = PJMEDIA_FORMAT_DETAIL_VIDEO;
125
 
 
126
 
    fmt->det.vid.size.w = width;
127
 
    fmt->det.vid.size.h = height;
128
 
    fmt->det.vid.fps.num = fps_num;
129
 
    fmt->det.vid.fps.denum = fps_denum;
130
 
    fmt->det.vid.avg_bps = fmt->det.vid.max_bps = 0;
131
 
 
132
 
    if (pjmedia_video_format_mgr_instance()) {
133
 
        const pjmedia_video_format_info *vfi;
134
 
        pjmedia_video_apply_fmt_param vafp;
135
 
        pj_uint32_t bps;
136
 
 
137
 
        vfi = pjmedia_get_video_format_info(NULL, fmt->id);
138
 
        if (vfi) {
139
 
            pj_bzero(&vafp, sizeof(vafp));
140
 
            vafp.size = fmt->det.vid.size;
141
 
            vfi->apply_fmt(vfi, &vafp);
142
 
 
143
 
            bps = vafp.framebytes * fps_num * (pj_size_t)8 / fps_denum;
144
 
            fmt->det.vid.avg_bps = fmt->det.vid.max_bps = bps;
145
 
        }
146
 
    }
147
 
}
148
 
 
149
 
PJ_DEF(pjmedia_video_format_detail*)
150
 
pjmedia_format_get_video_format_detail(const pjmedia_format *fmt,
151
 
                                       pj_bool_t assert_valid)
152
 
{
153
 
    if (fmt->detail_type==PJMEDIA_FORMAT_DETAIL_VIDEO) {
154
 
        return (pjmedia_video_format_detail*)&fmt->det.vid;
155
 
    } else {
156
 
        pj_assert(!assert_valid || !"Invalid video format detail");
157
 
        return NULL;
158
 
    }
159
 
}
160
 
 
161
 
 
162
 
static pj_status_t apply_packed_fmt(const pjmedia_video_format_info *fi,
163
 
                                    pjmedia_video_apply_fmt_param *aparam)
164
 
{
165
 
    unsigned i;
166
 
    pj_size_t stride;
167
 
 
168
 
    stride = (pj_size_t)((aparam->size.w*fi->bpp) >> 3);
169
 
 
170
 
    /* Calculate memsize */
171
 
    aparam->framebytes = stride * aparam->size.h;
172
 
 
173
 
    /* Packed formats only use 1 plane */
174
 
    aparam->planes[0] = aparam->buffer;
175
 
    aparam->strides[0] = stride;
176
 
    aparam->plane_bytes[0] = aparam->framebytes;
177
 
 
178
 
    /* Zero unused planes */
179
 
    for (i=1; i<PJMEDIA_MAX_VIDEO_PLANES; ++i) {
180
 
        aparam->strides[i] = 0;
181
 
        aparam->planes[i] = NULL;
182
 
    }
183
 
 
184
 
    return PJ_SUCCESS;
185
 
}
186
 
 
187
 
static pj_status_t apply_planar_420(const pjmedia_video_format_info *fi,
188
 
                                     pjmedia_video_apply_fmt_param *aparam)
189
 
{
190
 
    unsigned i;
191
 
    pj_size_t Y_bytes;
192
 
 
193
 
    PJ_UNUSED_ARG(fi);
194
 
 
195
 
    /* Calculate memsize */
196
 
    Y_bytes = (pj_size_t)(aparam->size.w * aparam->size.h);
197
 
    aparam->framebytes = Y_bytes + (Y_bytes>>1);
198
 
 
199
 
    /* Planar formats use 3 plane */
200
 
    aparam->strides[0] = aparam->size.w;
201
 
    aparam->strides[1] = aparam->strides[2] = (aparam->size.w>>1);
202
 
 
203
 
    aparam->planes[0] = aparam->buffer;
204
 
    aparam->planes[1] = aparam->planes[0] + Y_bytes;
205
 
    aparam->planes[2] = aparam->planes[1] + (Y_bytes>>2);
206
 
 
207
 
    aparam->plane_bytes[0] = Y_bytes;
208
 
    aparam->plane_bytes[1] = aparam->plane_bytes[2] = (Y_bytes>>2);
209
 
 
210
 
    /* Zero unused planes */
211
 
    for (i=3; i<PJMEDIA_MAX_VIDEO_PLANES; ++i) {
212
 
        aparam->strides[i] = 0;
213
 
        aparam->planes[i] = NULL;
214
 
        aparam->plane_bytes[i] = 0;
215
 
    }
216
 
 
217
 
    return PJ_SUCCESS;
218
 
}
219
 
 
220
 
static pj_status_t apply_planar_422(const pjmedia_video_format_info *fi,
221
 
                                     pjmedia_video_apply_fmt_param *aparam)
222
 
{
223
 
    unsigned i;
224
 
    pj_size_t Y_bytes;
225
 
 
226
 
    PJ_UNUSED_ARG(fi);
227
 
 
228
 
    /* Calculate memsize */
229
 
    Y_bytes = (pj_size_t)(aparam->size.w * aparam->size.h);
230
 
    aparam->framebytes = (Y_bytes << 1);
231
 
 
232
 
    /* Planar formats use 3 plane */
233
 
    aparam->strides[0] = aparam->size.w;
234
 
    aparam->strides[1] = aparam->strides[2] = (aparam->size.w>>1);
235
 
 
236
 
    aparam->planes[0] = aparam->buffer;
237
 
    aparam->planes[1] = aparam->planes[0] + Y_bytes;
238
 
    aparam->planes[2] = aparam->planes[1] + (Y_bytes>>1);
239
 
 
240
 
    aparam->plane_bytes[0] = Y_bytes;
241
 
    aparam->plane_bytes[1] = aparam->plane_bytes[2] = (Y_bytes>>1);
242
 
 
243
 
    /* Zero unused planes */
244
 
    for (i=3; i<PJMEDIA_MAX_VIDEO_PLANES; ++i) {
245
 
        aparam->strides[i] = 0;
246
 
        aparam->planes[i] = NULL;
247
 
        aparam->plane_bytes[i] = 0;
248
 
    }
249
 
 
250
 
    return PJ_SUCCESS;
251
 
}
252
 
 
253
 
static pj_status_t apply_planar_444(const pjmedia_video_format_info *fi,
254
 
                                    pjmedia_video_apply_fmt_param *aparam)
255
 
{
256
 
    unsigned i;
257
 
    pj_size_t Y_bytes;
258
 
 
259
 
    PJ_UNUSED_ARG(fi);
260
 
 
261
 
    /* Calculate memsize */
262
 
    Y_bytes = (pj_size_t)(aparam->size.w * aparam->size.h);
263
 
    aparam->framebytes = (Y_bytes * 3);
264
 
 
265
 
    /* Planar formats use 3 plane */
266
 
    aparam->strides[0] = aparam->strides[1] =
267
 
                         aparam->strides[2] = aparam->size.w;
268
 
 
269
 
    aparam->planes[0] = aparam->buffer;
270
 
    aparam->planes[1] = aparam->planes[0] + Y_bytes;
271
 
    aparam->planes[2] = aparam->planes[1] + Y_bytes;
272
 
 
273
 
    aparam->plane_bytes[0] = aparam->plane_bytes[1] =
274
 
                             aparam->plane_bytes[2] = Y_bytes;
275
 
 
276
 
    /* Zero unused planes */
277
 
    for (i=3; i<PJMEDIA_MAX_VIDEO_PLANES; ++i) {
278
 
        aparam->strides[i] = 0;
279
 
        aparam->planes[i] = NULL;
280
 
        aparam->plane_bytes[i] = 0;
281
 
    }
282
 
 
283
 
    return PJ_SUCCESS;
284
 
}
285
 
 
286
 
PJ_DEF(pj_status_t)
287
 
pjmedia_video_format_mgr_create(pj_pool_t *pool,
288
 
                                unsigned max_fmt,
289
 
                                unsigned options,
290
 
                                pjmedia_video_format_mgr **p_mgr)
291
 
{
292
 
    pjmedia_video_format_mgr *mgr;
293
 
    unsigned i;
294
 
 
295
 
    PJ_ASSERT_RETURN(pool && options==0, PJ_EINVAL);
296
 
 
297
 
    PJ_UNUSED_ARG(options);
298
 
 
299
 
    mgr = PJ_POOL_ALLOC_T(pool, pjmedia_video_format_mgr);
300
 
    mgr->max_info = max_fmt;
301
 
    mgr->info_cnt = 0;
302
 
    mgr->infos = pj_pool_calloc(pool, max_fmt, sizeof(pjmedia_video_format_info *));
303
 
 
304
 
    if (video_format_mgr_instance == NULL)
305
 
        video_format_mgr_instance = mgr;
306
 
 
307
 
    for (i=0; i<PJ_ARRAY_SIZE(built_in_vid_fmt_info); ++i) {
308
 
        pjmedia_register_video_format_info(mgr,
309
 
                                           &built_in_vid_fmt_info[i]);
310
 
    }
311
 
 
312
 
    if (p_mgr)
313
 
        *p_mgr = mgr;
314
 
 
315
 
    return PJ_SUCCESS;
316
 
}
317
 
 
318
 
 
319
 
PJ_DEF(const pjmedia_video_format_info*)
320
 
pjmedia_get_video_format_info(pjmedia_video_format_mgr *mgr,
321
 
                              pj_uint32_t id)
322
 
{
323
 
    pjmedia_video_format_info **first;
324
 
    int          comp;
325
 
    unsigned     n;
326
 
 
327
 
    if (!mgr)
328
 
        mgr = pjmedia_video_format_mgr_instance();
329
 
 
330
 
    PJ_ASSERT_RETURN(mgr != NULL, NULL);
331
 
 
332
 
    /* Binary search for the appropriate format id */
333
 
    comp = -1;
334
 
    first = &mgr->infos[0];
335
 
    n = mgr->info_cnt;
336
 
    for (; n > 0; ) {
337
 
        unsigned half = n / 2;
338
 
        pjmedia_video_format_info **mid = first + half;
339
 
 
340
 
        if ((*mid)->id < id) {
341
 
            first = ++mid;
342
 
            n -= half + 1;
343
 
        } else if ((*mid)->id==id) {
344
 
            return *mid;
345
 
        } else {
346
 
            n = half;
347
 
        }
348
 
    }
349
 
 
350
 
    return NULL;
351
 
}
352
 
 
353
 
 
354
 
PJ_DEF(pj_status_t)
355
 
pjmedia_register_video_format_info(pjmedia_video_format_mgr *mgr,
356
 
                                   pjmedia_video_format_info *info)
357
 
{
358
 
    unsigned i;
359
 
 
360
 
    if (!mgr)
361
 
        mgr = pjmedia_video_format_mgr_instance();
362
 
 
363
 
    PJ_ASSERT_RETURN(mgr != NULL, PJ_EINVALIDOP);
364
 
 
365
 
    if (mgr->info_cnt >= mgr->max_info)
366
 
        return PJ_ETOOMANY;
367
 
 
368
 
    /* Insert to the array, sorted */
369
 
    for (i=0; i<mgr->info_cnt; ++i) {
370
 
        if (mgr->infos[i]->id >= info->id)
371
 
            break;
372
 
    }
373
 
 
374
 
    if (i < mgr->info_cnt) {
375
 
        if (mgr->infos[i]->id == info->id) {
376
 
            /* just overwrite */
377
 
            mgr->infos[i] = info;
378
 
            return PJ_SUCCESS;
379
 
        }
380
 
 
381
 
        pj_memmove(&mgr->infos[i+1], &mgr->infos[i],
382
 
                   (mgr->info_cnt - i) * sizeof(pjmedia_video_format_info*));
383
 
    }
384
 
 
385
 
    mgr->infos[i] = info;
386
 
    mgr->info_cnt++;
387
 
 
388
 
    return PJ_SUCCESS;
389
 
}
390
 
 
391
 
PJ_DEF(pjmedia_video_format_mgr*) pjmedia_video_format_mgr_instance(void)
392
 
{
393
 
    pj_assert(video_format_mgr_instance != NULL);
394
 
    return video_format_mgr_instance;
395
 
}
396
 
 
397
 
PJ_DEF(void)
398
 
pjmedia_video_format_mgr_set_instance(pjmedia_video_format_mgr *mgr)
399
 
{
400
 
    video_format_mgr_instance = mgr;
401
 
}
402
 
 
403
 
 
404
 
PJ_DEF(void) pjmedia_video_format_mgr_destroy(pjmedia_video_format_mgr *mgr)
405
 
{
406
 
    if (!mgr)
407
 
        mgr = pjmedia_video_format_mgr_instance();
408
 
 
409
 
    PJ_ASSERT_ON_FAIL(mgr != NULL, return);
410
 
 
411
 
    mgr->info_cnt = 0;
412
 
    if (video_format_mgr_instance == mgr)
413
 
        video_format_mgr_instance = NULL;
414
 
}
415
 
 
416
 
#endif /* PJMEDIA_HAS_VIDEO */