This sample shows how to use codec.
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00031 #include <pjlib.h>
00032 #include <pjmedia.h>
00033 #include <pjmedia-codec.h>
00034
00035 #define THIS_FILE "encdec.c"
00036
00037 static const char *desc =
00038 " encdec \n"
00039 " \n"
00040 " PURPOSE: \n"
00041 " Encode input WAV with a codec, and decode the result to another WAV \n"
00042 "\n"
00043 "\n"
00044 " USAGE: \n"
00045 " encdec codec input.wav output.wav \n"
00046 "\n"
00047 "\n"
00048 " where:\n"
00049 " codec Set the codec name. \n"
00050 " input.wav Set the input WAV filename. \n"
00051 " output.wav Set the output WAV filename. \n"
00052
00053 "\n"
00054 ;
00055
00056
00057
00058
00059 #ifndef PJ_TRACE
00060 # define PJ_TRACE 0
00061 #endif
00062
00063 #if PJ_TRACE
00064 # define TRACE_(expr) PJ_LOG(4,expr)
00065 #else
00066 # define TRACE_(expr)
00067 #endif
00068
00069
00070 static void err(const char *op, pj_status_t status)
00071 {
00072 char errmsg[PJ_ERR_MSG_SIZE];
00073 pj_strerror(status, errmsg, sizeof(errmsg));
00074 PJ_LOG(3,("", "%s error: %s", op, errmsg));
00075 }
00076
00077 #define CHECK(op) do { \
00078 status = op; \
00079 if (status != PJ_SUCCESS) { \
00080 err(#op, status); \
00081 return status; \
00082 } \
00083 } \
00084 while (0)
00085
00086 static pjmedia_endpt *mept;
00087 static unsigned file_msec_duration;
00088
00089 static pj_status_t enc_dec_test(const char *codec_id,
00090 const char *filein,
00091 const char *fileout)
00092 {
00093 pj_pool_t *pool;
00094 pjmedia_codec_mgr *cm;
00095 pjmedia_codec *codec;
00096 const pjmedia_codec_info *pci;
00097 pjmedia_codec_param param;
00098 unsigned cnt, samples_per_frame;
00099 pj_str_t tmp;
00100 pjmedia_port *wavin, *wavout;
00101 unsigned lost_pct;
00102 pj_status_t status;
00103
00104 #define T file_msec_duration/1000, file_msec_duration%1000
00105
00106 pool = pjmedia_endpt_create_pool(mept, "encdec", 1000, 1000);
00107
00108 cm = pjmedia_endpt_get_codec_mgr(mept);
00109
00110 #ifdef LOST_PCT
00111 lost_pct = LOST_PCT;
00112 #else
00113 lost_pct = 0;
00114 #endif
00115
00116 cnt = 1;
00117 CHECK( pjmedia_codec_mgr_find_codecs_by_id(cm, pj_cstr(&tmp, codec_id),
00118 &cnt, &pci, NULL) );
00119 CHECK( pjmedia_codec_mgr_get_default_param(cm, pci, ¶m) );
00120
00121 samples_per_frame = param.info.clock_rate * param.info.frm_ptime / 1000;
00122
00123
00124 param.setting.vad = 1;
00125
00126
00127 CHECK( pjmedia_wav_player_port_create(pool, filein,
00128 param.info.frm_ptime,
00129 PJMEDIA_FILE_NO_LOOP, 0, &wavin) );
00130
00131
00132 CHECK( pjmedia_wav_writer_port_create(pool, fileout,
00133 param.info.clock_rate,
00134 param.info.channel_cnt,
00135 samples_per_frame,
00136 16, 0, 0, &wavout) );
00137
00138
00139 CHECK( pjmedia_codec_mgr_alloc_codec(cm, pci, &codec) );
00140 CHECK( pjmedia_codec_init(codec, pool) );
00141 CHECK( pjmedia_codec_open(codec, ¶m) );
00142
00143 for (;;) {
00144 pjmedia_frame frm_pcm, frm_bit, out_frm, frames[4];
00145 pj_int16_t pcmbuf[320];
00146 pj_timestamp ts;
00147 pj_uint8_t bitstream[160];
00148
00149 frm_pcm.buf = (char*)pcmbuf;
00150 frm_pcm.size = samples_per_frame * 2;
00151
00152
00153 if (pjmedia_port_get_frame(wavin, &frm_pcm) != PJ_SUCCESS)
00154 break;
00155 if (frm_pcm.type != PJMEDIA_FRAME_TYPE_AUDIO)
00156 break;;
00157
00158
00159 file_msec_duration += samples_per_frame * 1000 /
00160 param.info.clock_rate;
00161
00162
00163 frm_bit.buf = bitstream;
00164 frm_bit.size = sizeof(bitstream);
00165 CHECK(pjmedia_codec_encode(codec, &frm_pcm, sizeof(bitstream),
00166 &frm_bit));
00167
00168
00169 if (frm_bit.size == 0 || frm_bit.type != PJMEDIA_FRAME_TYPE_AUDIO) {
00170 out_frm.buf = (char*)pcmbuf;
00171 out_frm.size = 160;
00172 CHECK( pjmedia_port_put_frame(wavout, &out_frm) );
00173 TRACE_((THIS_FILE, "%d.%03d read: %u, enc: %u",
00174 T, frm_pcm.size, frm_bit.size));
00175 continue;
00176 }
00177
00178
00179
00180
00181
00182 ts.u64 = 0;
00183 cnt = PJ_ARRAY_SIZE(frames);
00184 CHECK( pjmedia_codec_parse(codec, bitstream, frm_bit.size, &ts, &cnt,
00185 frames) );
00186 CHECK( (cnt==1 ? PJ_SUCCESS : -1) );
00187
00188
00189 out_frm.buf = (char*)pcmbuf;
00190 out_frm.size = sizeof(pcmbuf);
00191
00192 if ((pj_rand() % 100) < (int)lost_pct) {
00193
00194 CHECK( pjmedia_codec_recover(codec, sizeof(pcmbuf), &out_frm) );
00195 TRACE_((THIS_FILE, "%d.%03d Packet lost", T));
00196 } else {
00197
00198 CHECK( pjmedia_codec_decode(codec, &frames[0], sizeof(pcmbuf),
00199 &out_frm) );
00200 }
00201
00202
00203 CHECK( pjmedia_port_put_frame(wavout, &out_frm) );
00204
00205 TRACE_((THIS_FILE, "%d.%03d read: %u, enc: %u, dec/write: %u",
00206 T, frm_pcm.size, frm_bit.size, out_frm.size));
00207 }
00208
00209
00210 pjmedia_port_destroy(wavout);
00211 pjmedia_port_destroy(wavin);
00212
00213
00214 pjmedia_codec_close(codec);
00215 pjmedia_codec_mgr_dealloc_codec(cm, codec);
00216
00217
00218 pj_pool_release(pool);
00219
00220 return PJ_SUCCESS;
00221 }
00222
00223
00224 int main(int argc, char *argv[])
00225 {
00226 pj_caching_pool cp;
00227 pj_time_val t0, t1;
00228 pj_status_t status;
00229
00230 if (argc != 4) {
00231 puts(desc);
00232 return 1;
00233 }
00234
00235 CHECK( pj_init() );
00236
00237 pj_caching_pool_init(&cp, NULL, 0);
00238
00239 CHECK( pjmedia_endpt_create(&cp.factory, NULL, 1, &mept) );
00240
00241
00242 CHECK( pjmedia_codec_register_audio_codecs(mept, NULL) );
00243
00244 pj_gettimeofday(&t0);
00245 status = enc_dec_test(argv[1], argv[2], argv[3]);
00246 pj_gettimeofday(&t1);
00247 PJ_TIME_VAL_SUB(t1, t0);
00248
00249 pjmedia_endpt_destroy(mept);
00250 pj_caching_pool_destroy(&cp);
00251 pj_shutdown();
00252
00253 if (status == PJ_SUCCESS) {
00254 puts("");
00255 puts("Success");
00256 printf("Duration: %ds.%03d\n", file_msec_duration/1000,
00257 file_msec_duration%1000);
00258 printf("Time: %lds.%03ld\n", t1.sec, t1.msec);
00259 }
00260
00261 return 0;
00262 }
00263