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

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.2.1/pjmedia/src/test/vid_codec_test.c

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2015-01-07 14:51:16 UTC
  • mfrom: (4.3.5 sid)
  • Revision ID: package-import@ubuntu.com-20150107145116-yxnafinf4lrdvrmx
Tags: 1.4.1-0.1ubuntu1
* Merge with Debian, remaining changes:
 - Drop soprano, nepomuk build-dep
* Drop ubuntu patches, now upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: vid_codec_test.c 4537 2013-06-19 06:47:43Z riza $ */
 
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 = (unsigned)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 -= (unsigned)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 -= (unsigned)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
                                      (unsigned)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 */