/* * main() */ int main(int argc, char *argv[]) { pj_caching_pool cp; pjmedia_endpt *med_endpt; pj_pool_t *pool; pj_status_t status; /* Codec */ char *codec_id = (char*)"H264"; const pjmedia_vid_codec_info *codec_info; pjmedia_vid_codec_param codec_param; pjmedia_vid_codec *codec = NULL; //const char *save_filename = // "/home/bennylp/Desktop/opt/src/openh264-svn/testbin/test.264"; const char *save_filename = NULL; /* File */ enum { WIDTH = 320, HEIGHT = 192, FPS = 12, YUV_SIZE = WIDTH * HEIGHT * 3 >> 1, YUV_BUF_SIZE = YUV_SIZE + WIDTH, MAX_FRAMES = 32, MTU = 1500 }; FILE *fyuv = NULL; FILE *f264 = NULL; typedef pj_uint8_t enc_buf_type[MTU]; pj_uint8_t yuv_frame[YUV_BUF_SIZE]; enc_buf_type enc_buf[MAX_FRAMES]; unsigned read_cnt = 0, pkt_cnt = 0, dec_cnt = 0, enc_cnt; if (0) { diff_file(); return 1; } /* init PJLIB : */ status = pj_init(); PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1); /* Must create a pool factory before we can allocate any memory. */ pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0); /* Initialize media endpoint. */ status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt); PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1); /* Create memory pool for application purpose */ pool = pj_pool_create( &cp.factory, /* pool factory */ "app", /* pool name. */ 4000, /* init size */ 4000, /* increment size */ NULL /* callback on error */ ); /* Init video format manager */ pjmedia_video_format_mgr_create(pool, 64, 0, NULL); /* Init video converter manager */ pjmedia_converter_mgr_create(pool, NULL); /* Init event manager */ pjmedia_event_mgr_create(pool, 0, NULL); /* Init video codec manager */ pjmedia_vid_codec_mgr_create(pool, NULL); /* Register all supported codecs */ status = init_codecs(&cp.factory); PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1); /* Open YUV file */ fyuv = fopen("pjsip-apps/bin/CiscoVT2people_320x192_12fps.yuv", "rb"); if (!fyuv) { puts("Unable to open ../CiscoVT2people_320x192_12fps.yuv"); status = -1; goto on_exit; } /* Write 264 file if wanted */ if (save_filename) { f264 = fopen(save_filename, "wb"); } /* Find which codec to use. */ if (codec_id) { unsigned count = 1; pj_str_t str_codec_id = pj_str(codec_id); status = pjmedia_vid_codec_mgr_find_codecs_by_id(NULL, &str_codec_id, &count, &codec_info, NULL); if (status != PJ_SUCCESS) { printf("Error: unable to find codec %s\n", codec_id); return 1; } } else { static pjmedia_vid_codec_info info[1]; unsigned count = PJ_ARRAY_SIZE(info); /* Default to first codec */ pjmedia_vid_codec_mgr_enum_codecs(NULL, &count, info, NULL); codec_info = &info[0]; } /* Get codec default param for info */ status = pjmedia_vid_codec_mgr_get_default_param(NULL, codec_info, &codec_param); pj_assert(status == PJ_SUCCESS); /* Alloc encoder */ status = pjmedia_vid_codec_mgr_alloc_codec(NULL, codec_info, &codec); if (status != PJ_SUCCESS) { PJ_PERROR(3,(THIS_FILE, status, "Error allocating codec")); goto on_exit; } codec_param.dir = PJMEDIA_DIR_ENCODING_DECODING; codec_param.packing = PJMEDIA_VID_PACKING_PACKETS; codec_param.enc_mtu = MTU; codec_param.enc_fmt.det.vid.size.w = WIDTH; codec_param.enc_fmt.det.vid.size.h = HEIGHT; codec_param.enc_fmt.det.vid.fps.num = FPS; codec_param.enc_fmt.det.vid.avg_bps = WIDTH * HEIGHT * FPS; status = pjmedia_vid_codec_init(codec, pool); if (status != PJ_SUCCESS) { PJ_PERROR(3,(THIS_FILE, status, "Error initializing codec")); goto on_exit; } status = pjmedia_vid_codec_open(codec, &codec_param); if (status != PJ_SUCCESS) { PJ_PERROR(3,(THIS_FILE, status, "Error opening codec")); goto on_exit; } while (fread(yuv_frame, 1, YUV_SIZE, fyuv) == YUV_SIZE) { pjmedia_frame frm_yuv, frm_enc[MAX_FRAMES]; pj_bool_t has_more = PJ_FALSE; const pj_uint8_t start_nal[] = { 0, 0, 1 }; unsigned i; ++ read_cnt; pj_bzero(&frm_enc, sizeof(frm_enc)); pj_bzero(&frm_yuv, sizeof(frm_yuv)); frm_yuv.buf = yuv_frame; frm_yuv.size = YUV_SIZE; enc_cnt = 0; frm_enc[enc_cnt].buf = enc_buf[enc_cnt]; frm_enc[enc_cnt].size = MTU; status = pjmedia_vid_codec_encode_begin(codec, NULL, &frm_yuv, MTU, &frm_enc[enc_cnt], &has_more); if (status != PJ_SUCCESS) { PJ_PERROR(3,(THIS_FILE, status, "Codec encode error")); goto on_exit; } if (frm_enc[enc_cnt].size) { if (f264) { fwrite(start_nal, 1, sizeof(start_nal), f264); fwrite(frm_enc[enc_cnt].buf, 1, frm_enc[enc_cnt].size, f264); } ++pkt_cnt; ++enc_cnt; } while (has_more) { if (enc_cnt >= MAX_FRAMES) { status = -1; puts("Error: too many encoded frames"); goto on_exit; } has_more = PJ_FALSE; frm_enc[enc_cnt].buf = enc_buf[enc_cnt]; frm_enc[enc_cnt].size = MTU; status = pjmedia_vid_codec_encode_more(codec, MTU, &frm_enc[enc_cnt], &has_more); if (status != PJ_SUCCESS) { PJ_PERROR(3,(THIS_FILE, status, "Codec encode error")); goto on_exit; } if (frm_enc[enc_cnt].size) { if (f264) { fwrite(start_nal, 1, sizeof(start_nal), f264); fwrite(frm_enc[enc_cnt].buf, 1, frm_enc[enc_cnt].size, f264); } ++pkt_cnt; ++enc_cnt; } } if (enc_cnt) { frm_yuv.buf = yuv_frame; frm_yuv.size = YUV_BUF_SIZE; status = pjmedia_vid_codec_decode(codec, enc_cnt, frm_enc, YUV_BUF_SIZE, &frm_yuv); if (status != PJ_SUCCESS) { PJ_PERROR(3,(THIS_FILE, status, "Codec decode error")); goto on_exit; } if (frm_yuv.size != 0) { ++dec_cnt; } } } printf("Done.\n" " Read YUV frames: %d\n" " Encoded packets: %d\n" " Decoded YUV frames: %d\n", read_cnt, pkt_cnt, dec_cnt); /* Start deinitialization: */ on_exit: if (codec) { pjmedia_vid_codec_close(codec); pjmedia_vid_codec_mgr_dealloc_codec(NULL, codec); } if (f264) fclose(f264); if (fyuv) fclose(fyuv); /* Deinit codecs */ deinit_codecs(); /* Destroy event manager */ pjmedia_event_mgr_destroy(NULL); /* Release application pool */ pj_pool_release( pool ); /* Destroy media endpoint. */ pjmedia_endpt_destroy( med_endpt ); /* Destroy pool factory */ pj_caching_pool_destroy( &cp ); /* Shutdown PJLIB */ pj_shutdown(); return (status == PJ_SUCCESS) ? 0 : 1; } #else int main(int argc, char *argv[]) { PJ_UNUSED_ARG(argc); PJ_UNUSED_ARG(argv); puts("Error: this sample requires video capability " "(PJMEDIA_HAS_VIDEO == 1)"); return -1; }
static pj_status_t codec_put_frame(pjmedia_port *port, pjmedia_frame *frame) { enum { MAX_PACKETS = 50 }; codec_port_data_t *port_data = (codec_port_data_t*)port->port_data.pdata; pj_status_t status; pjmedia_vid_codec *codec = port_data->codec; unsigned enc_cnt = 0; pj_uint8_t *enc_buf; unsigned enc_size_left; pjmedia_frame enc_frames[MAX_PACKETS]; pj_bool_t has_more = PJ_FALSE; enc_buf = port_data->enc_buf; enc_size_left = port_data->enc_buf_size; /* * Encode */ enc_frames[enc_cnt].buf = enc_buf; enc_frames[enc_cnt].size = enc_size_left; status = pjmedia_vid_codec_encode_begin(codec, NULL, frame, enc_size_left, &enc_frames[enc_cnt], &has_more); if (status != PJ_SUCCESS) goto on_error; enc_buf += enc_frames[enc_cnt].size; enc_size_left -= enc_frames[enc_cnt].size; ++enc_cnt; while (has_more) { enc_frames[enc_cnt].buf = enc_buf; enc_frames[enc_cnt].size = enc_size_left; status = pjmedia_vid_codec_encode_more(codec, enc_size_left, &enc_frames[enc_cnt], &has_more); if (status != PJ_SUCCESS) break; enc_buf += enc_frames[enc_cnt].size; enc_size_left -= enc_frames[enc_cnt].size; ++enc_cnt; if (enc_cnt >= MAX_PACKETS) { assert(!"Too many packets!"); break; } } /* * Decode */ status = pjmedia_vid_codec_decode(codec, enc_cnt, enc_frames, frame->size, frame); if (status != PJ_SUCCESS) goto on_error; /* Display */ status = pjmedia_port_put_frame( pjmedia_vid_port_get_passive_port(port_data->rdr_port), frame); if (status != PJ_SUCCESS) goto on_error; return PJ_SUCCESS; on_error: pj_perror(3, THIS_FILE, status, "codec_put_frame() error"); return status; }