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

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.0.1/pjmedia/src/test/vid_codec_test.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: vid_codec_test.c 4084 2012-04-25 07:13:05Z ming $ */
2
 
/*
3
 
 * Copyright (C) 2011 Teluu Inc. (http://www.teluu.com)
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or modify
6
 
 * it under the terms of the GNU General Public License as published by
7
 
 * the Free Software Foundation; either version 2 of the License, or
8
 
 * (at your option) any later version.
9
 
 *
10
 
 * This program is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 * GNU General Public License for more details.
14
 
 *
15
 
 * You should have received a copy of the GNU General Public License
16
 
 * along with this program; if not, write to the Free Software
17
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 
 */
19
 
#include "test.h"
20
 
#include <pjmedia-codec/ffmpeg_vid_codecs.h>
21
 
#include <pjmedia-videodev/videodev.h>
22
 
#include <pjmedia/vid_codec.h>
23
 
#include <pjmedia/port.h>
24
 
 
25
 
 
26
 
#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
27
 
 
28
 
 
29
 
#define THIS_FILE "vid_codec.c"
30
 
 
31
 
/*
32
 
 * Capture device setting:
33
 
 *   -1 = colorbar,
34
 
 *   -2 = any non-colorbar capture device (first found)
35
 
 *    x = specified capture device id
36
 
 */
37
 
#define CAPTURE_DEV         -1
38
 
 
39
 
 
40
 
typedef struct codec_port_data_t
41
 
{
42
 
    pjmedia_vid_codec   *codec;
43
 
    pjmedia_vid_port    *rdr_port;
44
 
    pj_uint8_t          *enc_buf;
45
 
    pj_size_t            enc_buf_size;
46
 
    pj_uint8_t          *pack_buf;
47
 
    pj_size_t            pack_buf_size;
48
 
} codec_port_data_t;
49
 
 
50
 
static pj_status_t codec_on_event(pjmedia_event *event,
51
 
                                  void *user_data)
52
 
{
53
 
    codec_port_data_t *port_data = (codec_port_data_t*)user_data;
54
 
 
55
 
    if (event->type == PJMEDIA_EVENT_FMT_CHANGED) {
56
 
        pjmedia_vid_codec *codec = port_data->codec;
57
 
        pjmedia_vid_codec_param codec_param;
58
 
        pj_status_t status;
59
 
 
60
 
        status = pjmedia_vid_codec_get_param(codec, &codec_param);
61
 
        if (status != PJ_SUCCESS)
62
 
            return status;
63
 
 
64
 
        status = pjmedia_vid_dev_stream_set_cap(
65
 
                        pjmedia_vid_port_get_stream(port_data->rdr_port),
66
 
                        PJMEDIA_VID_DEV_CAP_FORMAT,
67
 
                        &codec_param.dec_fmt);
68
 
        if (status != PJ_SUCCESS)
69
 
            return status;
70
 
    }
71
 
 
72
 
    return PJ_SUCCESS;
73
 
}
74
 
 
75
 
static pj_status_t codec_put_frame(pjmedia_port *port,
76
 
                                   pjmedia_frame *frame)
77
 
{
78
 
    enum { MAX_PACKETS = 50 };
79
 
    codec_port_data_t *port_data = (codec_port_data_t*)port->port_data.pdata;
80
 
    pj_status_t status;
81
 
    pjmedia_vid_codec *codec = port_data->codec;
82
 
    unsigned enc_cnt = 0;
83
 
    pj_uint8_t *enc_buf;
84
 
    unsigned enc_size_left;
85
 
    pjmedia_frame enc_frames[MAX_PACKETS];
86
 
    pj_bool_t has_more = PJ_FALSE;
87
 
 
88
 
    enc_buf = port_data->enc_buf;
89
 
    enc_size_left = port_data->enc_buf_size;
90
 
 
91
 
    /*
92
 
     * Encode
93
 
     */
94
 
    enc_frames[enc_cnt].buf = enc_buf;
95
 
    enc_frames[enc_cnt].size = enc_size_left;
96
 
 
97
 
    status = pjmedia_vid_codec_encode_begin(codec, NULL, frame, enc_size_left,
98
 
                                            &enc_frames[enc_cnt], &has_more);
99
 
    if (status != PJ_SUCCESS) goto on_error;
100
 
 
101
 
    enc_buf += enc_frames[enc_cnt].size;
102
 
    enc_size_left -= enc_frames[enc_cnt].size;
103
 
 
104
 
    ++enc_cnt;
105
 
    while (has_more) {
106
 
        enc_frames[enc_cnt].buf = enc_buf;
107
 
        enc_frames[enc_cnt].size = enc_size_left;
108
 
 
109
 
        status = pjmedia_vid_codec_encode_more(codec, enc_size_left,
110
 
                                                &enc_frames[enc_cnt],
111
 
                                                &has_more);
112
 
        if (status != PJ_SUCCESS)
113
 
            break;
114
 
 
115
 
        enc_buf += enc_frames[enc_cnt].size;
116
 
        enc_size_left -= enc_frames[enc_cnt].size;
117
 
 
118
 
        ++enc_cnt;
119
 
 
120
 
        if (enc_cnt >= MAX_PACKETS) {
121
 
            assert(!"Too many packets!");
122
 
            break;
123
 
        }
124
 
    }
125
 
 
126
 
    /*
127
 
     * Decode
128
 
     */
129
 
    status = pjmedia_vid_codec_decode(codec, enc_cnt, enc_frames,
130
 
                                      frame->size, frame);
131
 
    if (status != PJ_SUCCESS) goto on_error;
132
 
 
133
 
    /* Display */
134
 
    status = pjmedia_port_put_frame(
135
 
                        pjmedia_vid_port_get_passive_port(port_data->rdr_port),
136
 
                        frame);
137
 
    if (status != PJ_SUCCESS) goto on_error;
138
 
 
139
 
    return PJ_SUCCESS;
140
 
 
141
 
on_error:
142
 
    pj_perror(3, THIS_FILE, status, "codec_put_frame() error");
143
 
    return status;
144
 
}
145
 
 
146
 
static const char* dump_codec_info(const pjmedia_vid_codec_info *info)
147
 
{
148
 
    static char str[80];
149
 
    unsigned i;
150
 
    char *p = str;
151
 
 
152
 
    /* Raw format ids */
153
 
    for (i=0; (i<info->dec_fmt_id_cnt) && (p-str+5<sizeof(str)); ++i) {
154
 
        pj_memcpy(p, &info->dec_fmt_id[i], 4);
155
 
        p += 4;
156
 
        *p++ = ' ';
157
 
    }
158
 
    *p = '\0';
159
 
 
160
 
    return str;
161
 
}
162
 
 
163
 
static int enum_codecs()
164
 
{
165
 
    unsigned i, cnt;
166
 
    pjmedia_vid_codec_info info[PJMEDIA_CODEC_MGR_MAX_CODECS];
167
 
    pj_status_t status;
168
 
 
169
 
    PJ_LOG(3, (THIS_FILE, "  codec enums"));
170
 
    cnt = PJ_ARRAY_SIZE(info);
171
 
    status = pjmedia_vid_codec_mgr_enum_codecs(NULL, &cnt, info, NULL);
172
 
    if (status != PJ_SUCCESS)
173
 
        return 100;
174
 
 
175
 
    for (i = 0; i < cnt; ++i) {
176
 
        PJ_LOG(3, (THIS_FILE, "  %-16.*s %c%c %s",
177
 
                   info[i].encoding_name.slen, info[i].encoding_name.ptr,
178
 
                   (info[i].dir & PJMEDIA_DIR_ENCODING? 'E' : ' '),
179
 
                   (info[i].dir & PJMEDIA_DIR_DECODING? 'D' : ' '),
180
 
                   dump_codec_info(&info[i])));
181
 
    }
182
 
 
183
 
    return PJ_SUCCESS;
184
 
}
185
 
 
186
 
static int encode_decode_test(pj_pool_t *pool, const char *codec_id,
187
 
                              pjmedia_vid_packing packing)
188
 
{
189
 
    const pj_str_t port_name = {"codec", 5};
190
 
 
191
 
    pjmedia_vid_codec *codec=NULL;
192
 
    pjmedia_port codec_port;
193
 
    codec_port_data_t codec_port_data;
194
 
    pjmedia_vid_codec_param codec_param;
195
 
    const pjmedia_vid_codec_info *codec_info;
196
 
    const char *packing_name;
197
 
    pjmedia_vid_dev_index cap_idx, rdr_idx;
198
 
    pjmedia_vid_port *capture=NULL, *renderer=NULL;
199
 
    pjmedia_vid_port_param vport_param;
200
 
    pjmedia_video_format_detail *vfd;
201
 
    char codec_name[5];
202
 
    pj_status_t status;
203
 
    int rc = 0;
204
 
 
205
 
    switch (packing) {
206
 
    case PJMEDIA_VID_PACKING_PACKETS:
207
 
        packing_name = "framed";
208
 
        break;
209
 
    case PJMEDIA_VID_PACKING_WHOLE:
210
 
        packing_name = "whole";
211
 
        break;
212
 
    default:
213
 
        packing_name = "unknown";
214
 
        break;
215
 
    }
216
 
 
217
 
    PJ_LOG(3, (THIS_FILE, "  encode decode test: codec=%s, packing=%s",
218
 
               codec_id, packing_name));
219
 
 
220
 
    /* Lookup codec */
221
 
    {
222
 
        pj_str_t codec_id_st;
223
 
        unsigned info_cnt = 1;
224
 
 
225
 
        /* Lookup codec */
226
 
        pj_cstr(&codec_id_st, codec_id);
227
 
        status = pjmedia_vid_codec_mgr_find_codecs_by_id(NULL, &codec_id_st,
228
 
                                                         &info_cnt,
229
 
                                                         &codec_info, NULL);
230
 
        if (status != PJ_SUCCESS) {
231
 
            rc = 205; goto on_return;
232
 
        }
233
 
    }
234
 
 
235
 
 
236
 
#if CAPTURE_DEV == -1
237
 
    /* Lookup colorbar source */
238
 
    status = pjmedia_vid_dev_lookup("Colorbar", "Colorbar generator", &cap_idx);
239
 
    if (status != PJ_SUCCESS) {
240
 
        rc = 206; goto on_return;
241
 
    }
242
 
#elif CAPTURE_DEV == -2
243
 
    /* Lookup any first non-colorbar source */
244
 
    {
245
 
        unsigned i, cnt;
246
 
        pjmedia_vid_dev_info info;
247
 
 
248
 
        cap_idx = -1;
249
 
        cnt = pjmedia_vid_dev_count();
250
 
        for (i = 0; i < cnt; ++i) {
251
 
            status = pjmedia_vid_dev_get_info(i, &info);
252
 
            if (status != PJ_SUCCESS) {
253
 
                rc = 206; goto on_return;
254
 
            }
255
 
            if (info.dir & PJMEDIA_DIR_CAPTURE &&
256
 
                pj_ansi_stricmp(info.driver, "Colorbar"))
257
 
            {
258
 
                cap_idx = i;
259
 
                break;
260
 
            }
261
 
        }
262
 
 
263
 
        if (cap_idx == -1) {
264
 
            status = PJ_ENOTFOUND;
265
 
            rc = 206; goto on_return;
266
 
        }
267
 
    }
268
 
#else
269
 
    cap_idx = CAPTURE_DEV;
270
 
#endif
271
 
 
272
 
    /* Lookup SDL renderer */
273
 
    status = pjmedia_vid_dev_lookup("SDL", "SDL renderer", &rdr_idx);
274
 
    if (status != PJ_SUCCESS) {
275
 
        rc = 207; goto on_return;
276
 
    }
277
 
 
278
 
    /* Prepare codec */
279
 
    {
280
 
        pj_str_t codec_id_st;
281
 
        unsigned info_cnt = 1;
282
 
        const pjmedia_vid_codec_info *codec_info;
283
 
 
284
 
        /* Lookup codec */
285
 
        pj_cstr(&codec_id_st, codec_id);
286
 
        status = pjmedia_vid_codec_mgr_find_codecs_by_id(NULL, &codec_id_st,
287
 
                                                         &info_cnt,
288
 
                                                         &codec_info, NULL);
289
 
        if (status != PJ_SUCCESS) {
290
 
            rc = 245; goto on_return;
291
 
        }
292
 
        status = pjmedia_vid_codec_mgr_get_default_param(NULL, codec_info,
293
 
                                                         &codec_param);
294
 
        if (status != PJ_SUCCESS) {
295
 
            rc = 246; goto on_return;
296
 
        }
297
 
 
298
 
        codec_param.packing = packing;
299
 
 
300
 
        /* Open codec */
301
 
        status = pjmedia_vid_codec_mgr_alloc_codec(NULL, codec_info,
302
 
                                                   &codec);
303
 
        if (status != PJ_SUCCESS) {
304
 
            rc = 250; goto on_return;
305
 
        }
306
 
 
307
 
        status = pjmedia_vid_codec_init(codec, pool);
308
 
        if (status != PJ_SUCCESS) {
309
 
            rc = 251; goto on_return;
310
 
        }
311
 
 
312
 
        status = pjmedia_vid_codec_open(codec, &codec_param);
313
 
        if (status != PJ_SUCCESS) {
314
 
            rc = 252; goto on_return;
315
 
        }
316
 
 
317
 
        /* After opened, codec will update the param, let's sync encoder &
318
 
         * decoder format detail.
319
 
         */
320
 
        codec_param.dec_fmt.det = codec_param.enc_fmt.det;
321
 
 
322
 
        /* Subscribe to codec events */
323
 
        pjmedia_event_subscribe(NULL, &codec_on_event, &codec_port_data,
324
 
                                codec);
325
 
    }
326
 
 
327
 
    pjmedia_vid_port_param_default(&vport_param);
328
 
 
329
 
    /* Create capture, set it to active (master) */
330
 
    status = pjmedia_vid_dev_default_param(pool, cap_idx,
331
 
                                           &vport_param.vidparam);
332
 
    if (status != PJ_SUCCESS) {
333
 
        rc = 220; goto on_return;
334
 
    }
335
 
    pjmedia_format_copy(&vport_param.vidparam.fmt, &codec_param.dec_fmt);
336
 
    vport_param.vidparam.dir = PJMEDIA_DIR_CAPTURE;
337
 
    vport_param.active = PJ_TRUE;
338
 
 
339
 
    if (vport_param.vidparam.fmt.detail_type != PJMEDIA_FORMAT_DETAIL_VIDEO) {
340
 
        rc = 221; goto on_return;
341
 
    }
342
 
 
343
 
    vfd = pjmedia_format_get_video_format_detail(&vport_param.vidparam.fmt,
344
 
                                                 PJ_TRUE);
345
 
    if (vfd == NULL) {
346
 
        rc = 225; goto on_return;
347
 
    }
348
 
 
349
 
    status = pjmedia_vid_port_create(pool, &vport_param, &capture);
350
 
    if (status != PJ_SUCCESS) {
351
 
        rc = 226; goto on_return;
352
 
    }
353
 
 
354
 
    /* Create renderer, set it to passive (slave)  */
355
 
    vport_param.active = PJ_FALSE;
356
 
    vport_param.vidparam.dir = PJMEDIA_DIR_RENDER;
357
 
    vport_param.vidparam.rend_id = rdr_idx;
358
 
    vport_param.vidparam.disp_size = vfd->size;
359
 
 
360
 
    status = pjmedia_vid_port_create(pool, &vport_param, &renderer);
361
 
    if (status != PJ_SUCCESS) {
362
 
        rc = 230; goto on_return;
363
 
    }
364
 
 
365
 
    /* Init codec port */
366
 
    pj_bzero(&codec_port, sizeof(codec_port));
367
 
    status = pjmedia_port_info_init2(&codec_port.info, &port_name, 0x1234,
368
 
                                     PJMEDIA_DIR_ENCODING,
369
 
                                     &codec_param.dec_fmt);
370
 
    if (status != PJ_SUCCESS) {
371
 
        rc = 260; goto on_return;
372
 
    }
373
 
 
374
 
    codec_port_data.codec = codec;
375
 
    codec_port_data.rdr_port = renderer;
376
 
    codec_port_data.enc_buf_size = codec_param.dec_fmt.det.vid.size.w *
377
 
                                   codec_param.dec_fmt.det.vid.size.h * 4;
378
 
    codec_port_data.enc_buf = pj_pool_alloc(pool,
379
 
                                            codec_port_data.enc_buf_size);
380
 
    codec_port_data.pack_buf_size = codec_port_data.enc_buf_size;
381
 
    codec_port_data.pack_buf = pj_pool_alloc(pool,
382
 
                                             codec_port_data.pack_buf_size);
383
 
 
384
 
    codec_port.put_frame = &codec_put_frame;
385
 
    codec_port.port_data.pdata = &codec_port_data;
386
 
 
387
 
    /* Connect capture to codec port */
388
 
    status = pjmedia_vid_port_connect(capture,
389
 
                                      &codec_port,
390
 
                                      PJ_FALSE);
391
 
    if (status != PJ_SUCCESS) {
392
 
        rc = 270; goto on_return;
393
 
    }
394
 
 
395
 
    PJ_LOG(3, (THIS_FILE, "    starting codec test: %s<->%.*s %dx%d",
396
 
        pjmedia_fourcc_name(codec_param.dec_fmt.id, codec_name),
397
 
        codec_info->encoding_name.slen,
398
 
        codec_info->encoding_name.ptr,
399
 
        codec_param.dec_fmt.det.vid.size.w,
400
 
        codec_param.dec_fmt.det.vid.size.h
401
 
        ));
402
 
 
403
 
    /* Start streaming.. */
404
 
    status = pjmedia_vid_port_start(renderer);
405
 
    if (status != PJ_SUCCESS) {
406
 
        rc = 275; goto on_return;
407
 
    }
408
 
    status = pjmedia_vid_port_start(capture);
409
 
    if (status != PJ_SUCCESS) {
410
 
        rc = 280; goto on_return;
411
 
    }
412
 
 
413
 
    /* Sleep while the video is being displayed... */
414
 
    pj_thread_sleep(10000);
415
 
 
416
 
on_return:
417
 
    if (status != PJ_SUCCESS) {
418
 
        PJ_PERROR(3, (THIS_FILE, status, "  error"));
419
 
    }
420
 
    if (capture)
421
 
        pjmedia_vid_port_stop(capture);
422
 
    if (renderer)
423
 
        pjmedia_vid_port_stop(renderer);
424
 
    if (capture)
425
 
        pjmedia_vid_port_destroy(capture);
426
 
    if (renderer)
427
 
        pjmedia_vid_port_destroy(renderer);
428
 
    if (codec) {
429
 
        pjmedia_event_unsubscribe(NULL, &codec_on_event, &codec_port_data,
430
 
                                  codec);
431
 
        pjmedia_vid_codec_close(codec);
432
 
        pjmedia_vid_codec_mgr_dealloc_codec(NULL, codec);
433
 
    }
434
 
 
435
 
    return rc;
436
 
}
437
 
 
438
 
int vid_codec_test(void)
439
 
{
440
 
    pj_pool_t *pool;
441
 
    int rc = 0;
442
 
    pj_status_t status;
443
 
    int orig_log_level;
444
 
 
445
 
    orig_log_level = pj_log_get_level();
446
 
    pj_log_set_level(3);
447
 
 
448
 
    PJ_LOG(3, (THIS_FILE, "Performing video codec tests.."));
449
 
 
450
 
    pool = pj_pool_create(mem, "Vid codec test", 256, 256, 0);
451
 
 
452
 
    status = pjmedia_vid_dev_subsys_init(mem);
453
 
    if (status != PJ_SUCCESS)
454
 
        return -10;
455
 
 
456
 
#if PJMEDIA_HAS_FFMPEG_VID_CODEC
457
 
    status = pjmedia_codec_ffmpeg_vid_init(NULL, mem);
458
 
    if (status != PJ_SUCCESS)
459
 
        return -20;
460
 
#endif
461
 
 
462
 
    rc = enum_codecs();
463
 
    if (rc != 0)
464
 
        goto on_return;
465
 
 
466
 
    rc = encode_decode_test(pool, "h263-1998", PJMEDIA_VID_PACKING_WHOLE);
467
 
    if (rc != 0)
468
 
        goto on_return;
469
 
 
470
 
    rc = encode_decode_test(pool, "h263-1998", PJMEDIA_VID_PACKING_PACKETS);
471
 
    if (rc != 0)
472
 
        goto on_return;
473
 
 
474
 
on_return:
475
 
#if PJMEDIA_HAS_FFMPEG_VID_CODEC
476
 
    pjmedia_codec_ffmpeg_vid_deinit();
477
 
#endif
478
 
    pjmedia_vid_dev_subsys_shutdown();
479
 
    pj_pool_release(pool);
480
 
    pj_log_set_level(orig_log_level);
481
 
 
482
 
    return rc;
483
 
}
484
 
 
485
 
 
486
 
#endif /* PJMEDIA_HAS_VIDEO */