~ubuntu-branches/ubuntu/trusty/sflphone/trusty

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.1.0/pjsip-apps/src/samples/encdec.c

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (4.3.4 sid)
  • Revision ID: package-import@ubuntu.com-20140128182336-jrsv0k9u6cawc068
Tags: 1.3.0-1
* 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: encdec.c 3664 2011-07-19 03:42:28Z 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
 
 
21
 /**
 
22
 * \page page_pjmedia_samples_encdec_c Samples: Encoding and Decoding
 
23
 *
 
24
 * This sample shows how to use codec.
 
25
 *
 
26
 * This file is pjsip-apps/src/samples/encdec.c
 
27
 *
 
28
 * \includelineno encdec.c
 
29
 */
 
30
 
 
31
#include <pjlib.h>
 
32
#include <pjmedia.h>
 
33
#include <pjmedia-codec.h>
 
34
 
 
35
#define THIS_FILE   "encdec.c"
 
36
 
 
37
static const char *desc = 
 
38
 " encdec                                                               \n"
 
39
 "                                                                      \n"
 
40
 " PURPOSE:                                                             \n"
 
41
 "  Encode input WAV with a codec, and decode the result to another WAV \n"
 
42
 "\n"
 
43
 "\n"
 
44
 " USAGE:                                                               \n"
 
45
 "  encdec codec input.wav output.wav                                   \n"
 
46
 "\n"
 
47
 "\n"
 
48
 " where:\n"
 
49
 "  codec         Set the codec name.                                   \n"
 
50
 "  input.wav     Set the input WAV filename.                           \n"
 
51
 "  output.wav    Set the output WAV filename.                          \n"
 
52
 
 
53
 "\n"
 
54
;
 
55
 
 
56
//#undef PJ_TRACE
 
57
//#define PJ_TRACE 1
 
58
 
 
59
#ifndef PJ_TRACE
 
60
#       define PJ_TRACE 0
 
61
#endif
 
62
 
 
63
#if PJ_TRACE
 
64
#   define TRACE_(expr)     PJ_LOG(4,expr)
 
65
#else
 
66
#   define TRACE_(expr)
 
67
#endif
 
68
 
 
69
 
 
70
static void err(const char *op, pj_status_t status)
 
71
{
 
72
    char errmsg[PJ_ERR_MSG_SIZE];
 
73
    pj_strerror(status, errmsg, sizeof(errmsg));
 
74
    PJ_LOG(3,("", "%s error: %s", op, errmsg));
 
75
}
 
76
 
 
77
#define CHECK(op)   do { \
 
78
                        status = op; \
 
79
                        if (status != PJ_SUCCESS) { \
 
80
                            err(#op, status); \
 
81
                            return status; \
 
82
                        } \
 
83
                    } \
 
84
                    while (0)
 
85
 
 
86
static pjmedia_endpt *mept;
 
87
static unsigned file_msec_duration;
 
88
 
 
89
static pj_status_t enc_dec_test(const char *codec_id,
 
90
                                const char *filein,
 
91
                                const char *fileout)
 
92
{
 
93
    pj_pool_t *pool;
 
94
    pjmedia_codec_mgr *cm;
 
95
    pjmedia_codec *codec;
 
96
    const pjmedia_codec_info *pci;
 
97
    pjmedia_codec_param param;
 
98
    unsigned cnt, samples_per_frame;
 
99
    pj_str_t tmp;
 
100
    pjmedia_port *wavin, *wavout;
 
101
    unsigned lost_pct;
 
102
    pj_status_t status;
 
103
 
 
104
#define T   file_msec_duration/1000, file_msec_duration%1000
 
105
    
 
106
    pool = pjmedia_endpt_create_pool(mept, "encdec", 1000, 1000);
 
107
 
 
108
    cm = pjmedia_endpt_get_codec_mgr(mept);
 
109
 
 
110
#ifdef LOST_PCT
 
111
    lost_pct = LOST_PCT;
 
112
#else
 
113
    lost_pct = 0;
 
114
#endif
 
115
    
 
116
    cnt = 1;
 
117
    CHECK( pjmedia_codec_mgr_find_codecs_by_id(cm, pj_cstr(&tmp, codec_id), 
 
118
                                               &cnt, &pci, NULL) );
 
119
    CHECK( pjmedia_codec_mgr_get_default_param(cm, pci, &param) );
 
120
 
 
121
    samples_per_frame = param.info.clock_rate * param.info.frm_ptime / 1000;
 
122
 
 
123
    /* Control VAD */
 
124
    param.setting.vad = 1;
 
125
 
 
126
    /* Open wav for reading */
 
127
    CHECK( pjmedia_wav_player_port_create(pool, filein, 
 
128
                                          param.info.frm_ptime, 
 
129
                                          PJMEDIA_FILE_NO_LOOP, 0, &wavin) );
 
130
 
 
131
    /* Open wav for writing */
 
132
    CHECK( pjmedia_wav_writer_port_create(pool, fileout,
 
133
                                          param.info.clock_rate, 
 
134
                                          param.info.channel_cnt,
 
135
                                          samples_per_frame,
 
136
                                          16, 0, 0, &wavout) );
 
137
 
 
138
    /* Alloc codec */
 
139
    CHECK( pjmedia_codec_mgr_alloc_codec(cm, pci, &codec) );
 
140
    CHECK( pjmedia_codec_init(codec, pool) );
 
141
    CHECK( pjmedia_codec_open(codec, &param) );
 
142
    
 
143
    for (;;) {
 
144
        pjmedia_frame frm_pcm, frm_bit, out_frm, frames[4];
 
145
        pj_int16_t pcmbuf[320];
 
146
        pj_timestamp ts;
 
147
        pj_uint8_t bitstream[160];
 
148
 
 
149
        frm_pcm.buf = (char*)pcmbuf;
 
150
        frm_pcm.size = samples_per_frame * 2;
 
151
 
 
152
        /* Read from WAV */
 
153
        if (pjmedia_port_get_frame(wavin, &frm_pcm) != PJ_SUCCESS)
 
154
            break;
 
155
        if (frm_pcm.type != PJMEDIA_FRAME_TYPE_AUDIO)
 
156
            break;;
 
157
 
 
158
        /* Update duration */
 
159
        file_msec_duration += samples_per_frame * 1000 / 
 
160
                              param.info.clock_rate;
 
161
 
 
162
        /* Encode */
 
163
        frm_bit.buf = bitstream;
 
164
        frm_bit.size = sizeof(bitstream);
 
165
        CHECK(pjmedia_codec_encode(codec, &frm_pcm, sizeof(bitstream), 
 
166
                                   &frm_bit));
 
167
 
 
168
        /* On DTX, write zero frame to wavout to maintain duration */
 
169
        if (frm_bit.size == 0 || frm_bit.type != PJMEDIA_FRAME_TYPE_AUDIO) {
 
170
            out_frm.buf = (char*)pcmbuf;
 
171
            out_frm.size = 160;
 
172
            CHECK( pjmedia_port_put_frame(wavout, &out_frm) );
 
173
            TRACE_((THIS_FILE, "%d.%03d read: %u, enc: %u",
 
174
                    T, frm_pcm.size, frm_bit.size));
 
175
            continue;
 
176
        }
 
177
        
 
178
        /* Parse the bitstream (not really necessary for this case
 
179
         * since we always decode 1 frame, but it's still good
 
180
         * for testing)
 
181
         */
 
182
        ts.u64 = 0;
 
183
        cnt = PJ_ARRAY_SIZE(frames);
 
184
        CHECK( pjmedia_codec_parse(codec, bitstream, frm_bit.size, &ts, &cnt, 
 
185
                                   frames) );
 
186
        CHECK( (cnt==1 ? PJ_SUCCESS : -1) );
 
187
 
 
188
        /* Decode or simulate packet loss */
 
189
        out_frm.buf = (char*)pcmbuf;
 
190
        out_frm.size = sizeof(pcmbuf);
 
191
        
 
192
        if ((pj_rand() % 100) < (int)lost_pct) {
 
193
            /* Simulate loss */
 
194
            CHECK( pjmedia_codec_recover(codec, sizeof(pcmbuf), &out_frm) );
 
195
            TRACE_((THIS_FILE, "%d.%03d Packet lost", T));
 
196
        } else {
 
197
            /* Decode */
 
198
            CHECK( pjmedia_codec_decode(codec, &frames[0], sizeof(pcmbuf), 
 
199
                                     &out_frm) );
 
200
        }
 
201
 
 
202
        /* Write to WAV */
 
203
        CHECK( pjmedia_port_put_frame(wavout, &out_frm) );
 
204
 
 
205
        TRACE_((THIS_FILE, "%d.%03d read: %u, enc: %u, dec/write: %u",
 
206
                T, frm_pcm.size, frm_bit.size, out_frm.size));
 
207
    }
 
208
 
 
209
    /* Close wavs */
 
210
    pjmedia_port_destroy(wavout);
 
211
    pjmedia_port_destroy(wavin);
 
212
 
 
213
    /* Close codec */
 
214
    pjmedia_codec_close(codec);
 
215
    pjmedia_codec_mgr_dealloc_codec(cm, codec);
 
216
 
 
217
    /* Release pool */
 
218
    pj_pool_release(pool);
 
219
 
 
220
    return PJ_SUCCESS;
 
221
}
 
222
 
 
223
 
 
224
int main(int argc, char *argv[])
 
225
{
 
226
    pj_caching_pool cp;
 
227
    pj_time_val t0, t1;
 
228
    pj_status_t status;
 
229
 
 
230
    if (argc != 4) {
 
231
        puts(desc);
 
232
        return 1;
 
233
    }
 
234
 
 
235
    CHECK( pj_init() );
 
236
    
 
237
    pj_caching_pool_init(&cp, NULL, 0);
 
238
 
 
239
    CHECK( pjmedia_endpt_create(&cp.factory, NULL, 1, &mept) );
 
240
 
 
241
    /* Register all codecs */
 
242
    CHECK( pjmedia_codec_register_audio_codecs(mept, NULL) );
 
243
 
 
244
    pj_gettimeofday(&t0);
 
245
    status = enc_dec_test(argv[1], argv[2], argv[3]);
 
246
    pj_gettimeofday(&t1);
 
247
    PJ_TIME_VAL_SUB(t1, t0);
 
248
 
 
249
    pjmedia_endpt_destroy(mept);
 
250
    pj_caching_pool_destroy(&cp);
 
251
    pj_shutdown();
 
252
 
 
253
    if (status == PJ_SUCCESS) {
 
254
        puts("");
 
255
        puts("Success");
 
256
        printf("Duration: %ds.%03d\n", file_msec_duration/1000, 
 
257
                                       file_msec_duration%1000);
 
258
        printf("Time: %lds.%03ld\n", t1.sec, t1.msec);
 
259
    }
 
260
 
 
261
    return 0;
 
262
}
 
263