1
/* $Id: format.c 4158 2012-06-06 09:56:14Z nanang $ */
3
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
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.
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.
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
20
#include <pjmedia/format.h>
21
#include <pj/assert.h>
24
#include <pj/string.h>
27
PJ_DEF(void) pjmedia_format_init_audio( pjmedia_format *fmt,
30
unsigned channel_count,
31
unsigned bits_per_sample,
32
unsigned frame_time_usec,
37
fmt->type = PJMEDIA_TYPE_AUDIO;
38
fmt->detail_type = PJMEDIA_FORMAT_DETAIL_AUDIO;
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;
49
PJ_DEF(pjmedia_audio_format_detail*)
50
pjmedia_format_get_audio_format_detail(const pjmedia_format *fmt,
51
pj_bool_t assert_valid)
53
if (fmt->detail_type==PJMEDIA_FORMAT_DETAIL_AUDIO) {
54
return (pjmedia_audio_format_detail*) &fmt->det.aud;
56
/* Get rid of unused var compiler warning if pj_assert()
57
* macro does not do anything
59
PJ_UNUSED_ARG(assert_valid);
60
pj_assert(!assert_valid || !"Invalid audio format detail");
66
PJ_DEF(pjmedia_format*) pjmedia_format_copy(pjmedia_format *dst,
67
const pjmedia_format *src)
69
return (pjmedia_format*)pj_memcpy(dst, src, sizeof(*src));
73
#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
76
static pj_status_t apply_packed_fmt(const pjmedia_video_format_info *fi,
77
pjmedia_video_apply_fmt_param *aparam);
79
static pj_status_t apply_planar_420(const pjmedia_video_format_info *fi,
80
pjmedia_video_apply_fmt_param *aparam);
82
static pj_status_t apply_planar_422(const pjmedia_video_format_info *fi,
83
pjmedia_video_apply_fmt_param *aparam);
85
static pj_status_t apply_planar_444(const pjmedia_video_format_info *fi,
86
pjmedia_video_apply_fmt_param *aparam);
88
struct pjmedia_video_format_mgr
92
pjmedia_video_format_info **infos;
95
static pjmedia_video_format_mgr *video_format_mgr_instance;
96
static pjmedia_video_format_info built_in_vid_fmt_info[] =
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},
114
PJ_DEF(void) pjmedia_format_init_video( pjmedia_format *fmt,
121
pj_assert(fps_denum);
123
fmt->type = PJMEDIA_TYPE_VIDEO;
124
fmt->detail_type = PJMEDIA_FORMAT_DETAIL_VIDEO;
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;
132
if (pjmedia_video_format_mgr_instance()) {
133
const pjmedia_video_format_info *vfi;
134
pjmedia_video_apply_fmt_param vafp;
137
vfi = pjmedia_get_video_format_info(NULL, fmt->id);
139
pj_bzero(&vafp, sizeof(vafp));
140
vafp.size = fmt->det.vid.size;
141
vfi->apply_fmt(vfi, &vafp);
143
bps = vafp.framebytes * fps_num * (pj_size_t)8 / fps_denum;
144
fmt->det.vid.avg_bps = fmt->det.vid.max_bps = bps;
149
PJ_DEF(pjmedia_video_format_detail*)
150
pjmedia_format_get_video_format_detail(const pjmedia_format *fmt,
151
pj_bool_t assert_valid)
153
if (fmt->detail_type==PJMEDIA_FORMAT_DETAIL_VIDEO) {
154
return (pjmedia_video_format_detail*)&fmt->det.vid;
156
pj_assert(!assert_valid || !"Invalid video format detail");
162
static pj_status_t apply_packed_fmt(const pjmedia_video_format_info *fi,
163
pjmedia_video_apply_fmt_param *aparam)
168
stride = (pj_size_t)((aparam->size.w*fi->bpp) >> 3);
170
/* Calculate memsize */
171
aparam->framebytes = stride * aparam->size.h;
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;
178
/* Zero unused planes */
179
for (i=1; i<PJMEDIA_MAX_VIDEO_PLANES; ++i) {
180
aparam->strides[i] = 0;
181
aparam->planes[i] = NULL;
187
static pj_status_t apply_planar_420(const pjmedia_video_format_info *fi,
188
pjmedia_video_apply_fmt_param *aparam)
195
/* Calculate memsize */
196
Y_bytes = (pj_size_t)(aparam->size.w * aparam->size.h);
197
aparam->framebytes = Y_bytes + (Y_bytes>>1);
199
/* Planar formats use 3 plane */
200
aparam->strides[0] = aparam->size.w;
201
aparam->strides[1] = aparam->strides[2] = (aparam->size.w>>1);
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);
207
aparam->plane_bytes[0] = Y_bytes;
208
aparam->plane_bytes[1] = aparam->plane_bytes[2] = (Y_bytes>>2);
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;
220
static pj_status_t apply_planar_422(const pjmedia_video_format_info *fi,
221
pjmedia_video_apply_fmt_param *aparam)
228
/* Calculate memsize */
229
Y_bytes = (pj_size_t)(aparam->size.w * aparam->size.h);
230
aparam->framebytes = (Y_bytes << 1);
232
/* Planar formats use 3 plane */
233
aparam->strides[0] = aparam->size.w;
234
aparam->strides[1] = aparam->strides[2] = (aparam->size.w>>1);
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);
240
aparam->plane_bytes[0] = Y_bytes;
241
aparam->plane_bytes[1] = aparam->plane_bytes[2] = (Y_bytes>>1);
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;
253
static pj_status_t apply_planar_444(const pjmedia_video_format_info *fi,
254
pjmedia_video_apply_fmt_param *aparam)
261
/* Calculate memsize */
262
Y_bytes = (pj_size_t)(aparam->size.w * aparam->size.h);
263
aparam->framebytes = (Y_bytes * 3);
265
/* Planar formats use 3 plane */
266
aparam->strides[0] = aparam->strides[1] =
267
aparam->strides[2] = aparam->size.w;
269
aparam->planes[0] = aparam->buffer;
270
aparam->planes[1] = aparam->planes[0] + Y_bytes;
271
aparam->planes[2] = aparam->planes[1] + Y_bytes;
273
aparam->plane_bytes[0] = aparam->plane_bytes[1] =
274
aparam->plane_bytes[2] = Y_bytes;
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;
287
pjmedia_video_format_mgr_create(pj_pool_t *pool,
290
pjmedia_video_format_mgr **p_mgr)
292
pjmedia_video_format_mgr *mgr;
295
PJ_ASSERT_RETURN(pool && options==0, PJ_EINVAL);
297
PJ_UNUSED_ARG(options);
299
mgr = PJ_POOL_ALLOC_T(pool, pjmedia_video_format_mgr);
300
mgr->max_info = max_fmt;
302
mgr->infos = pj_pool_calloc(pool, max_fmt, sizeof(pjmedia_video_format_info *));
304
if (video_format_mgr_instance == NULL)
305
video_format_mgr_instance = mgr;
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]);
319
PJ_DEF(const pjmedia_video_format_info*)
320
pjmedia_get_video_format_info(pjmedia_video_format_mgr *mgr,
323
pjmedia_video_format_info **first;
328
mgr = pjmedia_video_format_mgr_instance();
330
PJ_ASSERT_RETURN(mgr != NULL, NULL);
332
/* Binary search for the appropriate format id */
334
first = &mgr->infos[0];
337
unsigned half = n / 2;
338
pjmedia_video_format_info **mid = first + half;
340
if ((*mid)->id < id) {
343
} else if ((*mid)->id==id) {
355
pjmedia_register_video_format_info(pjmedia_video_format_mgr *mgr,
356
pjmedia_video_format_info *info)
361
mgr = pjmedia_video_format_mgr_instance();
363
PJ_ASSERT_RETURN(mgr != NULL, PJ_EINVALIDOP);
365
if (mgr->info_cnt >= mgr->max_info)
368
/* Insert to the array, sorted */
369
for (i=0; i<mgr->info_cnt; ++i) {
370
if (mgr->infos[i]->id >= info->id)
374
if (i < mgr->info_cnt) {
375
if (mgr->infos[i]->id == info->id) {
377
mgr->infos[i] = info;
381
pj_memmove(&mgr->infos[i+1], &mgr->infos[i],
382
(mgr->info_cnt - i) * sizeof(pjmedia_video_format_info*));
385
mgr->infos[i] = info;
391
PJ_DEF(pjmedia_video_format_mgr*) pjmedia_video_format_mgr_instance(void)
393
pj_assert(video_format_mgr_instance != NULL);
394
return video_format_mgr_instance;
398
pjmedia_video_format_mgr_set_instance(pjmedia_video_format_mgr *mgr)
400
video_format_mgr_instance = mgr;
404
PJ_DEF(void) pjmedia_video_format_mgr_destroy(pjmedia_video_format_mgr *mgr)
407
mgr = pjmedia_video_format_mgr_instance();
409
PJ_ASSERT_ON_FAIL(mgr != NULL, return);
412
if (video_format_mgr_instance == mgr)
413
video_format_mgr_instance = NULL;
416
#endif /* PJMEDIA_HAS_VIDEO */