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

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.1.0/pjsip-apps/src/samples/aviplay.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: aviplay.c 4051 2012-04-13 08:16:30Z ming $ */
2
 
/* 
3
 
 * Copyright (C) 2010-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
 
 
20
 
#include <pjmedia.h>
21
 
#include <pjmedia/converter.h>
22
 
#include <pjmedia-codec.h>
23
 
#include <pjlib-util.h>
24
 
#include <pjlib.h>
25
 
#include <stdio.h>
26
 
#include <stdlib.h>
27
 
 
28
 
#include "util.h"
29
 
 
30
 
/**
31
 
 * \page page_pjmedia_samples_aviplay_c Samples: Playing AVI File to
32
 
 * Video and Sound Devices
33
 
 *
34
 
 * This is a very simple example to use the @ref PJMEDIA_FILE_PLAY,
35
 
 * @ref PJMED_SND_PORT, and @ref PJMEDIA_VID_PORT. In this example, we
36
 
 * open the file, video, and sound devices, then connect the file to both
37
 
 * video and sound devices to play the contents of the file.
38
 
 *
39
 
 *
40
 
 * This file is pjsip-apps/src/samples/aviplay.c
41
 
 *
42
 
 * \includelineno aviplay.c
43
 
 */
44
 
 
45
 
 
46
 
/*
47
 
 * aviplay.c
48
 
 *
49
 
 * PURPOSE:
50
 
 *  Play a AVI file to video and sound devices.
51
 
 *
52
 
 * USAGE:
53
 
 *  aviplay FILE.AVI
54
 
 */
55
 
 
56
 
 
57
 
#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
58
 
 
59
 
 
60
 
/* For logging purpose. */
61
 
#define THIS_FILE   "aviplay.c"
62
 
 
63
 
static const char *desc = 
64
 
" FILE                                                              \n"
65
 
"                                                                   \n"
66
 
"  aviplay.c                                                        \n"
67
 
"                                                                   \n"
68
 
" PURPOSE                                                           \n"
69
 
"                                                                   \n"
70
 
"  Demonstrate how to play a AVI file.                              \n"
71
 
"                                                                   \n"
72
 
" USAGE                                                             \n"
73
 
"                                                                   \n"
74
 
"  aviplay FILE.AVI                                                 \n";
75
 
 
76
 
struct codec_fmt {
77
 
    pj_uint32_t         pjmedia_id;
78
 
    const char         *codec_id;
79
 
    /* Do we need to convert the decoded frame? */
80
 
    pj_bool_t           need_conversion;
81
 
    /* If conversion is needed, dst_fmt indicates the destination format */
82
 
    pjmedia_format_id   dst_fmt;
83
 
} codec_fmts[] = {{PJMEDIA_FORMAT_MJPEG, "mjpeg",
84
 
                   PJ_TRUE , PJMEDIA_FORMAT_I420},
85
 
                  {PJMEDIA_FORMAT_H263 , "h263" ,
86
 
                   PJ_FALSE, 0},
87
 
                  {PJMEDIA_FORMAT_MPEG4, "mp4v"}, 
88
 
                  {PJMEDIA_FORMAT_H264 , "h264"}
89
 
                 };
90
 
 
91
 
typedef struct avi_port_t
92
 
{
93
 
    pjmedia_vid_port   *vid_port;
94
 
    pjmedia_snd_port   *snd_port;
95
 
    pj_bool_t           is_running;
96
 
    pj_bool_t           is_quitting;
97
 
} avi_port_t;
98
 
 
99
 
typedef struct codec_port_data_t
100
 
{
101
 
    pjmedia_vid_codec   *codec;
102
 
    pjmedia_port        *src_port;
103
 
    pj_uint8_t          *enc_buf;
104
 
    pj_size_t            enc_buf_size;
105
 
    
106
 
    pjmedia_converter   *conv;
107
 
} codec_port_data_t;
108
 
 
109
 
static pj_status_t avi_event_cb(pjmedia_event *event,
110
 
                                void *user_data)
111
 
{
112
 
    avi_port_t *ap = (avi_port_t *)user_data;
113
 
    
114
 
    switch (event->type) {
115
 
    case PJMEDIA_EVENT_WND_CLOSED:
116
 
        ap->is_quitting = PJ_TRUE;
117
 
        break;
118
 
    case PJMEDIA_EVENT_MOUSE_BTN_DOWN:
119
 
        if (ap->is_running) {
120
 
            pjmedia_vid_port_stop(ap->vid_port);
121
 
            if (ap->snd_port)
122
 
                pjmedia_aud_stream_stop(
123
 
                    pjmedia_snd_port_get_snd_stream(ap->snd_port));
124
 
        } else {
125
 
            pjmedia_vid_port_start(ap->vid_port);
126
 
            if (ap->snd_port)
127
 
                pjmedia_aud_stream_start(
128
 
                    pjmedia_snd_port_get_snd_stream(ap->snd_port));
129
 
        }
130
 
        ap->is_running = !ap->is_running;
131
 
        break;
132
 
    default:
133
 
        return PJ_SUCCESS;
134
 
    }
135
 
    
136
 
    /* We handled the event on our own, so return non-PJ_SUCCESS here */
137
 
    return -1;
138
 
}
139
 
 
140
 
static pj_status_t codec_get_frame(pjmedia_port *port,
141
 
                                   pjmedia_frame *frame)
142
 
{
143
 
    codec_port_data_t *port_data = (codec_port_data_t*)port->port_data.pdata;
144
 
    pjmedia_vid_codec *codec = port_data->codec;
145
 
    pjmedia_frame enc_frame;
146
 
    pj_status_t status;
147
 
    
148
 
    enc_frame.buf = port_data->enc_buf;
149
 
    enc_frame.size = port_data->enc_buf_size;
150
 
    
151
 
    if (port_data->conv) {
152
 
        pj_size_t frame_size = frame->size;
153
 
        
154
 
        status = pjmedia_port_get_frame(port_data->src_port, frame);
155
 
        if (status != PJ_SUCCESS) goto on_error;
156
 
        
157
 
        status = pjmedia_vid_codec_decode(codec, 1, frame,
158
 
                                          frame->size, &enc_frame);
159
 
        if (status != PJ_SUCCESS) goto on_error;
160
 
        
161
 
        frame->size = frame_size;
162
 
        status = pjmedia_converter_convert(port_data->conv, &enc_frame, frame);
163
 
        if (status != PJ_SUCCESS) goto on_error;
164
 
        
165
 
        return PJ_SUCCESS;
166
 
    }
167
 
    
168
 
    status = pjmedia_port_get_frame(port_data->src_port, &enc_frame);
169
 
    if (status != PJ_SUCCESS) goto on_error;
170
 
    
171
 
    status = pjmedia_vid_codec_decode(codec, 1, &enc_frame,
172
 
                                      frame->size, frame);
173
 
    if (status != PJ_SUCCESS) goto on_error;
174
 
    
175
 
    return PJ_SUCCESS;
176
 
    
177
 
on_error:
178
 
    pj_perror(3, THIS_FILE, status, "codec_get_frame() error");
179
 
    return status;
180
 
}
181
 
 
182
 
static int aviplay(pj_pool_t *pool, const char *fname)
183
 
{
184
 
    pjmedia_vid_port *renderer=NULL;
185
 
    pjmedia_vid_port_param param;
186
 
    const pjmedia_video_format_info *vfi;
187
 
    pjmedia_video_format_detail *vfd;
188
 
    pjmedia_snd_port *snd_port = NULL;
189
 
    pj_status_t status;
190
 
    int rc = 0;
191
 
    pjmedia_avi_streams *avi_streams;
192
 
    pjmedia_avi_stream *vid_stream, *aud_stream;
193
 
    pjmedia_port *vid_port = NULL, *aud_port = NULL;
194
 
    pjmedia_vid_codec *codec=NULL;
195
 
    avi_port_t avi_port;
196
 
    
197
 
    pj_bzero(&avi_port, sizeof(avi_port));
198
 
    
199
 
    status = pjmedia_avi_player_create_streams(pool, fname, 0, &avi_streams);
200
 
    if (status != PJ_SUCCESS) {
201
 
        PJ_PERROR(2,("", status, "    Error playing %s", fname));
202
 
        rc = 210; goto on_return;
203
 
    }
204
 
    
205
 
    vid_stream = pjmedia_avi_streams_get_stream_by_media(avi_streams,
206
 
                                                         0,
207
 
                                                         PJMEDIA_TYPE_VIDEO);
208
 
    vid_port = pjmedia_avi_stream_get_port(vid_stream);
209
 
    
210
 
    if (vid_port) {
211
 
        pjmedia_vid_port_param_default(&param);
212
 
        
213
 
        status = pjmedia_vid_dev_default_param(pool,
214
 
                                               PJMEDIA_VID_DEFAULT_RENDER_DEV,
215
 
                                               &param.vidparam);
216
 
        if (status != PJ_SUCCESS) {
217
 
            rc = 220; goto on_return;
218
 
        }
219
 
        
220
 
        /* Create renderer, set it to active  */
221
 
        param.active = PJ_TRUE;
222
 
        param.vidparam.dir = PJMEDIA_DIR_RENDER;
223
 
        vfd = pjmedia_format_get_video_format_detail(&vid_port->info.fmt,
224
 
                                                     PJ_TRUE);
225
 
        pjmedia_format_init_video(&param.vidparam.fmt, 
226
 
                                  vid_port->info.fmt.id,
227
 
                                  vfd->size.w, vfd->size.h,
228
 
                                  vfd->fps.num, vfd->fps.denum);
229
 
        
230
 
        vfi = pjmedia_get_video_format_info(
231
 
                  pjmedia_video_format_mgr_instance(),
232
 
                  vid_port->info.fmt.id);
233
 
        /* Check whether the frame is encoded */
234
 
        if (!vfi || vfi->bpp == 0) {
235
 
            /* Yes, prepare codec */
236
 
            pj_str_t codec_id_st;
237
 
            unsigned info_cnt = 1, i, k;
238
 
            const pjmedia_vid_codec_info *codec_info;
239
 
            pj_str_t port_name = {"codec", 5};
240
 
            pj_uint8_t *enc_buf = NULL;
241
 
            pj_size_t enc_buf_size = 0;
242
 
            pjmedia_vid_dev_info rdr_info;
243
 
            pjmedia_port codec_port;
244
 
            codec_port_data_t codec_port_data;
245
 
            pjmedia_vid_codec_param codec_param;
246
 
            struct codec_fmt *codecp = NULL;
247
 
            
248
 
            /* Lookup codec */
249
 
            for (i = 0; i < sizeof(codec_fmts)/sizeof(codec_fmts[0]); i++) {
250
 
                if (vid_port->info.fmt.id == codec_fmts[i].pjmedia_id) {
251
 
                    codecp = &codec_fmts[i];
252
 
                    break;
253
 
                }
254
 
            }
255
 
            if (!codecp) {
256
 
                rc = 242; goto on_return;
257
 
            }
258
 
            pj_cstr(&codec_id_st, codecp->codec_id);
259
 
            status = pjmedia_vid_codec_mgr_find_codecs_by_id(NULL,
260
 
                                                             &codec_id_st, 
261
 
                                                             &info_cnt, 
262
 
                                                             &codec_info,
263
 
                                                             NULL);
264
 
            if (status != PJ_SUCCESS) {
265
 
                rc = 245; goto on_return;
266
 
            }
267
 
            status = pjmedia_vid_codec_mgr_get_default_param(NULL, codec_info,
268
 
                                                             &codec_param);
269
 
            if (status != PJ_SUCCESS) {
270
 
                rc = 246; goto on_return;
271
 
            }
272
 
            
273
 
            pjmedia_format_copy(&codec_param.enc_fmt, &param.vidparam.fmt);
274
 
 
275
 
            pjmedia_vid_dev_get_info(param.vidparam.rend_id, &rdr_info);
276
 
            for (i=0; i<codec_info->dec_fmt_id_cnt; ++i) {
277
 
                for (k=0; k<rdr_info.fmt_cnt; ++k) {
278
 
                    if (codec_info->dec_fmt_id[i]==(int)rdr_info.fmt[k].id)
279
 
                    {
280
 
                        param.vidparam.fmt.id = codec_info->dec_fmt_id[i];
281
 
                        i = codec_info->dec_fmt_id_cnt;
282
 
                        break;
283
 
                    }
284
 
                }
285
 
            }
286
 
            
287
 
            /* Open codec */
288
 
            status = pjmedia_vid_codec_mgr_alloc_codec(NULL, codec_info,
289
 
                                                       &codec);
290
 
            if (status != PJ_SUCCESS) {
291
 
                rc = 250; goto on_return;
292
 
            }
293
 
            
294
 
            status = pjmedia_vid_codec_init(codec, pool);
295
 
            if (status != PJ_SUCCESS) {
296
 
                rc = 251; goto on_return;
297
 
            }
298
 
            
299
 
            pjmedia_format_copy(&codec_param.dec_fmt, &param.vidparam.fmt);
300
 
            codec_param.dir = PJMEDIA_DIR_DECODING;
301
 
            codec_param.packing = PJMEDIA_VID_PACKING_WHOLE;
302
 
            status = pjmedia_vid_codec_open(codec, &codec_param);
303
 
            if (status != PJ_SUCCESS) {
304
 
                rc = 252; goto on_return;
305
 
            }
306
 
            
307
 
            /* Alloc encoding buffer */
308
 
            enc_buf_size =  codec_param.dec_fmt.det.vid.size.w *
309
 
            codec_param.dec_fmt.det.vid.size.h * 4
310
 
            + 16; /*< padding, just in case */
311
 
            enc_buf = pj_pool_alloc(pool,enc_buf_size);
312
 
            
313
 
            /* Init codec port */
314
 
            pj_bzero(&codec_port, sizeof(codec_port));
315
 
            status = pjmedia_port_info_init2(&codec_port.info, &port_name,
316
 
                                             0x1234,
317
 
                                             PJMEDIA_DIR_ENCODING, 
318
 
                                             &codec_param.dec_fmt);
319
 
            if (status != PJ_SUCCESS) {
320
 
                rc = 260; goto on_return;
321
 
            }
322
 
            pj_bzero(&codec_port_data, sizeof(codec_port_data));
323
 
            codec_port_data.codec = codec;
324
 
            codec_port_data.src_port = vid_port;
325
 
            codec_port_data.enc_buf = enc_buf;
326
 
            codec_port_data.enc_buf_size = enc_buf_size;
327
 
            
328
 
            codec_port.get_frame = &codec_get_frame;
329
 
            codec_port.port_data.pdata = &codec_port_data;
330
 
            
331
 
            /* Check whether we need to convert the decoded frame */
332
 
            if (codecp->need_conversion) {
333
 
                pjmedia_conversion_param conv_param;
334
 
                
335
 
                pjmedia_format_copy(&conv_param.src, &param.vidparam.fmt);
336
 
                pjmedia_format_copy(&conv_param.dst, &param.vidparam.fmt);
337
 
                conv_param.dst.id = codecp->dst_fmt;
338
 
                param.vidparam.fmt.id = conv_param.dst.id;
339
 
                
340
 
                status = pjmedia_converter_create(NULL, pool, &conv_param,
341
 
                                                  &codec_port_data.conv);
342
 
                if (status != PJ_SUCCESS) {
343
 
                    rc = 270; goto on_return;
344
 
                }
345
 
            }
346
 
            
347
 
            status = pjmedia_vid_port_create(pool, &param, &renderer);
348
 
            if (status != PJ_SUCCESS) {
349
 
                rc = 230; goto on_return;
350
 
            }
351
 
            
352
 
            status = pjmedia_vid_port_connect(renderer, &codec_port,
353
 
                                              PJ_FALSE);
354
 
        } else {
355
 
            status = pjmedia_vid_port_create(pool, &param, &renderer);
356
 
            if (status != PJ_SUCCESS) {
357
 
                rc = 230; goto on_return;
358
 
            }
359
 
            
360
 
            /* Connect avi port to renderer */
361
 
            status = pjmedia_vid_port_connect(renderer, vid_port,
362
 
                                              PJ_FALSE);
363
 
        }
364
 
        
365
 
        if (status != PJ_SUCCESS) {
366
 
            rc = 240; goto on_return;
367
 
        }
368
 
    }
369
 
    
370
 
    aud_stream = pjmedia_avi_streams_get_stream_by_media(avi_streams,
371
 
                                                         0,
372
 
                                                         PJMEDIA_TYPE_AUDIO);
373
 
    aud_port = pjmedia_avi_stream_get_port(aud_stream);
374
 
    
375
 
    if (aud_port) {
376
 
        /* Create sound player port. */
377
 
        status = pjmedia_snd_port_create_player( 
378
 
                 pool,                              /* pool                 */
379
 
                 -1,                                /* use default dev.     */
380
 
                 PJMEDIA_PIA_SRATE(&aud_port->info),/* clock rate.          */
381
 
                 PJMEDIA_PIA_CCNT(&aud_port->info), /* # of channels.       */
382
 
                 PJMEDIA_PIA_SPF(&aud_port->info),  /* samples per frame.   */
383
 
                 PJMEDIA_PIA_BITS(&aud_port->info), /* bits per sample.     */
384
 
                 0,                                 /* options              */
385
 
                 &snd_port                          /* returned port        */
386
 
                 );
387
 
        if (status != PJ_SUCCESS) {
388
 
            rc = 310; goto on_return;
389
 
        }
390
 
        
391
 
        /* Connect file port to the sound player.
392
 
         * Stream playing will commence immediately.
393
 
         */
394
 
        status = pjmedia_snd_port_connect(snd_port, aud_port);
395
 
        if (status != PJ_SUCCESS) {
396
 
            rc = 330; goto on_return;
397
 
        }
398
 
    }
399
 
    
400
 
    if (vid_port) {
401
 
        pjmedia_vid_dev_cb cb;
402
 
        
403
 
        pj_bzero(&cb, sizeof(cb));
404
 
        avi_port.snd_port = snd_port;
405
 
        avi_port.vid_port = renderer;
406
 
        avi_port.is_running = PJ_TRUE;
407
 
        pjmedia_vid_port_set_cb(renderer, &cb, &avi_port);
408
 
 
409
 
        /* subscribe events */
410
 
        pjmedia_event_subscribe(NULL, &avi_event_cb, &avi_port,
411
 
                                renderer);
412
 
 
413
 
        if (snd_port) {
414
 
            /* Synchronize video rendering and audio playback */
415
 
            pjmedia_vid_port_set_clock_src(
416
 
                renderer,
417
 
                pjmedia_snd_port_get_clock_src(
418
 
                    snd_port, PJMEDIA_DIR_PLAYBACK));
419
 
        }
420
 
                                              
421
 
        
422
 
        /* Start video streaming.. */
423
 
        status = pjmedia_vid_port_start(renderer);
424
 
        if (status != PJ_SUCCESS) {
425
 
            rc = 270; goto on_return;
426
 
        }
427
 
    }
428
 
    
429
 
    while (!avi_port.is_quitting) {
430
 
        pj_thread_sleep(100);
431
 
    }
432
 
 
433
 
on_return:
434
 
    if (snd_port) {
435
 
        pjmedia_snd_port_disconnect(snd_port);
436
 
        /* Without this sleep, Windows/DirectSound will repeteadly
437
 
         * play the last frame during destroy.
438
 
         */
439
 
        pj_thread_sleep(100);
440
 
        pjmedia_snd_port_destroy(snd_port);
441
 
    }
442
 
    if (renderer) {
443
 
        pjmedia_event_unsubscribe(NULL, &avi_event_cb, &avi_port,
444
 
                                  renderer);
445
 
        pjmedia_vid_port_destroy(renderer);
446
 
    }
447
 
    if (aud_port)
448
 
        pjmedia_port_destroy(aud_port);
449
 
    if (vid_port)
450
 
        pjmedia_port_destroy(vid_port);
451
 
    if (codec) {
452
 
        pjmedia_vid_codec_close(codec);
453
 
        pjmedia_vid_codec_mgr_dealloc_codec(NULL, codec);
454
 
    }
455
 
    
456
 
    return rc;
457
 
}
458
 
 
459
 
 
460
 
static int main_func(int argc, char *argv[])
461
 
{
462
 
    pj_caching_pool cp;
463
 
    pj_pool_t *pool;
464
 
    int rc = 0;
465
 
    pj_status_t status = PJ_SUCCESS;
466
 
    
467
 
    if (argc != 2) {
468
 
        puts("Error: filename required");
469
 
        puts(desc);
470
 
        return 1;
471
 
    }
472
 
 
473
 
 
474
 
    /* Must init PJLIB first: */
475
 
    status = pj_init();
476
 
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
477
 
 
478
 
    /* Must create a pool factory before we can allocate any memory. */
479
 
    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
480
 
 
481
 
    /* Create memory pool for our file player */
482
 
    pool = pj_pool_create( &cp.factory,     /* pool factory         */
483
 
                           "AVI",           /* pool name.           */
484
 
                           4000,            /* init size            */
485
 
                           4000,            /* increment size       */
486
 
                           NULL             /* callback on error    */
487
 
                           );
488
 
 
489
 
    pjmedia_video_format_mgr_create(pool, 64, 0, NULL);
490
 
    pjmedia_converter_mgr_create(pool, NULL);
491
 
    pjmedia_event_mgr_create(pool, 0, NULL);
492
 
    pjmedia_vid_codec_mgr_create(pool, NULL);
493
 
    
494
 
    status = pjmedia_vid_dev_subsys_init(&cp.factory);
495
 
    if (status != PJ_SUCCESS)
496
 
        goto on_return;
497
 
    
498
 
    status = pjmedia_aud_subsys_init(&cp.factory);
499
 
    if (status != PJ_SUCCESS) {
500
 
        goto on_return;
501
 
    }
502
 
    
503
 
#if PJMEDIA_HAS_FFMPEG_VID_CODEC
504
 
    status = pjmedia_codec_ffmpeg_vid_init(NULL, &cp.factory);
505
 
    if (status != PJ_SUCCESS)
506
 
        goto on_return;    
507
 
#endif
508
 
 
509
 
    rc = aviplay(pool, argv[1]);
510
 
    
511
 
    /* 
512
 
     * File should be playing and looping now 
513
 
     */
514
 
 
515
 
    /* Without this sleep, Windows/DirectSound will repeteadly
516
 
     * play the last frame during destroy.
517
 
     */
518
 
    pj_thread_sleep(100);
519
 
 
520
 
on_return:    
521
 
#if PJMEDIA_HAS_FFMPEG_VID_CODEC
522
 
    pjmedia_codec_ffmpeg_vid_deinit();
523
 
#endif
524
 
    pjmedia_aud_subsys_shutdown();
525
 
    pjmedia_vid_dev_subsys_shutdown();
526
 
    
527
 
    pjmedia_video_format_mgr_destroy(pjmedia_video_format_mgr_instance());
528
 
    pjmedia_converter_mgr_destroy(pjmedia_converter_mgr_instance());
529
 
    pjmedia_event_mgr_destroy(pjmedia_event_mgr_instance());
530
 
    pjmedia_vid_codec_mgr_destroy(pjmedia_vid_codec_mgr_instance());    
531
 
    
532
 
    /* Release application pool */
533
 
    pj_pool_release( pool );
534
 
 
535
 
    /* Destroy pool factory */
536
 
    pj_caching_pool_destroy( &cp );
537
 
 
538
 
    /* Shutdown PJLIB */
539
 
    pj_shutdown();
540
 
 
541
 
    /* Done. */
542
 
    return 0;
543
 
}
544
 
 
545
 
int main(int argc, char *argv[])
546
 
{
547
 
    return pj_run_app(&main_func, argc, argv, 0);
548
 
}
549
 
 
550
 
#else
551
 
 
552
 
int main(int argc, char *argv[])
553
 
{
554
 
    PJ_UNUSED_ARG(argc);
555
 
    PJ_UNUSED_ARG(argv);
556
 
    puts("Error: this sample requires video capability (PJMEDIA_HAS_VIDEO == 1)");
557
 
    return -1;
558
 
}
559
 
 
560
 
#endif /* PJMEDIA_HAS_VIDEO */