| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383 |
- #include "precompile.h"
- #include "videortp.h"
- #include "videocommon.h"
- #include "bs.h"
- #ifdef _WIN32
- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #else
- #include <semaphore.h>
- #endif // _WIN32
- #include <assert.h>
- #include <malloc.h>
- #include <stdint.h>
- #include "list.h"
- #include "rtp.h"
- #include "rtpsession.h"
- #include "memutil.h"
- #include "../../rvcmediacommon/rvc_media_common.h"
- #include "x264.h"
- #include "video_common/ffmpeg_api_adapter.h"
- #include "video_coding/video_encoder_api.h"
- #include "video_coding/video_decoder.h"
- #include "video_coding/base/video_coding_clock.h"
- #include "video_coding/base/video_coding_log.h"
- #include "congestion_control/sim_transport/sim_external.h"
- #include "adaptive_jitter_buffer/video_jbuff_api.h"
- #include "adaptive_jitter_buffer/video_jbuff_log.h"
- #include "rtp_header_extension/rtp_header_extension_api.h"
- #include "h264_packetizer/h264_packetizer.h"
- #include "video_statics/video_stats.h"
- #include "video_common/videodebugfile.h"
- //接收缓冲区要大于MAX_MTU_SIZE,还要存储rtp头、udp头等
- #define MAX_RECV_BUFFER_SIZE 1500
- #define MAX_PLAYLOAD_SIZE 1400
- #define MAX_ASSEMBLE_EXTRA_SIZE 128
- #define FRAME_WIN_SIZE 20
- #define RTP_SEQ_GT(x, y, n) ((x > y && x-y<=n) || (y+n<n && x<=y+n))
- #define RTP_MAX_JUMP 128
- #define DIR_TX 1
- #define DIR_RX 2
- #define DIR_NONE 0
- #define DIR_BOTH 3
- #define VIDEO_CLOCK 90000
- #define PEER_UPDATE_INTERVAL 1500 // ms
- #define FIRST_KEY_FRAME_SIZE 40
- //DEBUG log开关
- #define DEBUG_TX 0
- #define DEBUG_ENCODER 0
- #define DEBUG_RX 0
- #define DEBUG_DECODER 0
- #define DEBUG_CC 0
- typedef unsigned char bool_t;
- typedef struct rtpframe_part_t {
- struct list_head entry;
- char buf[MAX_RECV_BUFFER_SIZE];
- int offset;
- int actual_len;
- int mb_in_slice;
- unsigned short seq;
- unsigned short mark : 1;
- unsigned short psc : 1;
- }rtpframe_part_t;
- typedef struct rtpframe_t {
- unsigned int used;
- unsigned int key;
- unsigned int ts;
- int id;
- int cur_max_mb;
- struct list_head part_list;
- }rtpframe_t;
- struct videortp_t
- {
- videortp_config_t config;
- rtp_session_t *rtp_sess;
- LONG force_key_frames;
- DWORD last_peer_update_tick;
- /******************************接收端*/
- VideoDecoder *decoder;
- rtpframe_part_t *sps;
- rtpframe_part_t *pps;
- /*接收缓冲*/
- struct list_head free_part_list;
- rtpframe_t frame_win[FRAME_WIN_SIZE];
- unsigned int frame_win_start;
- int frame_win_ptr;
- unsigned int frame_duration;
- unsigned int prev_dec_ts;
- unsigned short prev_dec_seq;
- uint64_t prev_dec_ms;
- //抖动缓冲
- VideoJBufferApi* jbuffer;
- //拥塞控制
- int send_cc_feedback;
-
- #ifdef _WIN32
- HANDLE recv_thread;
- HANDLE evt;
- #else
- pthread_t recv_threadid;
- sem_t sem_evt;
- #endif
- /******************************发送端 */
- VideoEncoderApi *encoder;
- x264_t* enc_params;
- //发送打包
- unsigned delta_ts;
- int64_t rtp_start_ms;
- RtpHeaderExtensionApi *rtp_header_extension;
- //拥塞控制
- int remote_support_cc;
- int recv_cc_feedback;
- int64_t recv_cc_feedback_ms;
-
- uint64_t framenum;
- //h264_packetizer
- h264_packetizer *h264_packetizer;
- //...
- };
- typedef struct _MSPicture {
- int w, h;
- uint8_t *planes[4]; // we usually use 3 planes, 4th is for compatibility
- int strides[4]; // with ffmpeg's swscale.h
- }MSPicture;
- static void rtpDbg(videortp_t *rtp, const char *fmt, ...)
- {
- int n;
- va_list arg;
- va_start(arg, fmt);
- if (rtp->config.dbg) {
- (*rtp->config.dbg)(rtp->config.user_data, fmt, arg);
- } else {
- n = vsnprintf(NULL, 0, fmt, arg);
- if (n > 0) {
- char *buf = (char*)_alloca((size_t)(n+3));
- vsprintf(buf, fmt, arg);
- strcat(buf, "\r\n");
- #ifdef _WIN32
- OutputDebugStringA((LPCSTR)buf);
- #endif
- printf(buf);
- }
- }
- va_end(arg);
- }
- static void rtpLogevent(videortp_t* rtp, int itype, const char* strmessage)
- {
- if (rtp->config.logevent) {
- (*rtp->config.logevent)(rtp->config.user_data, itype, strmessage);
- }
- }
- static void get_start_config_bitrate(videortp_config_t *config, int *max_bitrate, int *target_bitrate, int *min_bitrate){
- *max_bitrate = config->bit_rate; //bps
- *min_bitrate = 50*1000 > config->bit_rate ? config->bit_rate : 50*1000; //bps
- *target_bitrate = *max_bitrate; //bps
- *target_bitrate = (*target_bitrate < *min_bitrate) ? *min_bitrate : *target_bitrate; //bps
- }
- static int get_mtu(int config_mtu){
- int mtu = config_mtu > MAX_PLAYLOAD_SIZE ? MAX_PLAYLOAD_SIZE : config_mtu;
- return mtu;
- }
- //interval 单位为ms
- static unsigned convert_to_rtp_timestamp_increment(int64_t interval) {
- // 时间戳增量
- unsigned timestampIncrement = (VIDEO_CLOCK/1000*interval);
- return timestampIncrement;
- }
- static void yuv_buffers_combine_to_one(const video_frame *vframe, unsigned char *buffer)
- {
- int i =0, j =0, k =0;
- for(i = 0; i < vframe->height; i++)
- {
- memcpy((void *)(buffer+vframe->width*i),
- (const void *)(vframe->data[0]+vframe->linesize[0]*i),
- (size_t)(vframe->width));
-
- }
- for(j = 0; j < vframe->height/2; j++)
- {
- memcpy((void *)(buffer+vframe->width*i+vframe->width/2*j),
- (const void *)(vframe->data[1]+vframe->linesize[1]*j),
- (size_t)(vframe->width/2));
- }
- for(k =0; k < vframe->height/2; k++)
- {
- memcpy((void *)(buffer+vframe->width*i+vframe->width/2*j+vframe->width/2*k),
- (const void *)(vframe->data[2]+vframe->linesize[2]*k),
- (size_t)(vframe->width/2));
- }
- }
- static rtpframe_part_t *rtpframe_part_create(videortp_t *vrtp)
- {
- rtpframe_part_t *part;
- if (!list_empty((const struct list_head *)(&vrtp->free_part_list))) {
- part = list_first_entry(&vrtp->free_part_list, rtpframe_part_t, entry);
- list_del((struct list_head *)(&part->entry));
- } else {
- part = MALLOC_T(rtpframe_part_t);
- }
- return part;
- }
- static void rtpframe_part_destroy(videortp_t *vrtp, rtpframe_part_t *part)
- {
- list_add((struct list_head *)(&part->entry), (struct list_head *)(&vrtp->free_part_list));
- }
- rtpframe_part_t *rtpframe_part_dupb(rtpframe_part_t *mp){
- rtpframe_part_t *part = MALLOC_T(rtpframe_part_t);
- if (part){
- part->entry = mp->entry;
- memcpy((void *)(part->buf), (const void *)(mp->buf), strlen((const char *)(mp->buf)));
- part->offset = mp->offset;
- part->actual_len = mp->actual_len;
- part->mb_in_slice = mp->mb_in_slice;
- part->seq = mp->seq;
- part->mark = mp->mark;
- part->psc = mp->psc;
- }
- return part;
- }
- static void rtpframe_clear(videortp_t *vrtp, rtpframe_t *frame)
- {
- if (frame->used) {
- list_splice_init((struct list_head *)(&frame->part_list), (struct list_head *)(&vrtp->free_part_list));
- frame->used = 0;
- }
- }
- static unsigned short rtpframe_get_last_seq(rtpframe_t *frame)
- {
- if (!list_empty((const struct list_head *)(&frame->part_list))) {
- rtpframe_part_t *part = list_last_entry(&frame->part_list, rtpframe_part_t, entry);
- return part->seq;
- } else {
- assert(0);
- return 0;
- }
- }
- static unsigned short rtpframe_get_first_seq(rtpframe_t *frame)
- {
- if (!list_empty((const struct list_head *)(&frame->part_list))) {
- rtpframe_part_t *part = list_first_entry(&frame->part_list, rtpframe_part_t, entry);
- return part->seq;
- } else {
- assert(0);
- return 0;
- }
- }
- static int rtpframe_is_empty(rtpframe_t *frame)
- {
- if (list_empty((const struct list_head *)(&frame->part_list))) {
- return 1;
- }
- return 0;
- }
- static __inline void receiver_notify_peer_fast_update(videortp_t *vrtp)
- {
- DWORD dwNow = GetTickCount();
- if (dwNow - vrtp->last_peer_update_tick >= PEER_UPDATE_INTERVAL) {
- //rtpDbg(vrtp,"%I64d receiver_notify_peer_fast_update!", TimeInMilliseconds());
- rtp_session_send_rtcp_h261_fir(vrtp->rtp_sess);
- vrtp->last_peer_update_tick = dwNow;
- }
- }
- static __inline void receiver_notify_peer_fast_update_now(videortp_t *vrtp)
- {
- DWORD dwNow = GetTickCount();
- //rtpDbg(vrtp,"%I64d receiver_notify_peer_fast_update_now!", TimeInMilliseconds());
- rtp_session_send_rtcp_h261_fir(vrtp->rtp_sess);
- vrtp->last_peer_update_tick = dwNow;
- }
- static __inline void receiver_force_key_frame(videortp_t *vrtp)
- {
- rtpDbg(vrtp,"%I64d receiver_force_key_frame!", TimeInMilliseconds());
- #ifdef _WIN32
- InterlockedCompareExchange(&vrtp->force_key_frames, 1, 0);
- #else
- LONG* plTemp = &vrtp->force_key_frames;
- if (0 == *plTemp){
- *plTemp = 1;
- rtpDbg(vrtp,"%s:%d force_key_frames = %lu", __FUNCTION__, __LINE__, vrtp->force_key_frames);
- }
- #endif // _WIN32
- }
- static void receiver_clear_window(videortp_t *vrtp)
- {
- int i;
- for (i = 0; i < FRAME_WIN_SIZE; ++i) {
- rtpframe_t *frame = &vrtp->frame_win[i];
- rtpframe_clear(vrtp, frame);
- }
- vrtp->frame_duration = 0;
- }
- int receiver_msgdsize(const rtpframe_part_t *mp)
- {
- int msgsize = 0;
- {
- msgsize += (int) mp->actual_len;
- }
- return msgsize;
- }
- int video_coding_on_log(void *userdata, int level, const char* file, int line, const char* fmt, va_list vl){
- videortp_t *vrtp = (videortp_t *)userdata;
- int n;
- n = vsnprintf(NULL, 0, fmt, vl);
- if ((DEBUG_ENCODER || DEBUG_DECODER) && n > 0 && vrtp && level >= VIDEO_CODING_DEBUG_INFO) {
- char *buf = (char*)_alloca((size_t)(n+3));
- vsprintf(buf, fmt, vl);
- rtpDbg(vrtp,"%s.", buf);
- }
- return 0;
- }
- static int decoder_process(videortp_t *vrtp, uint8_t *input_buf, int input_len){
- int64_t before_decode_ms;
- int64_t after_decode_ms;
- int64_t before_render_ms;
- int64_t after_render_ms;
- //decode
- while (input_len > 0) {
- video_frame *decodered_frame = NULL;
- int key_frame = 0;
- video_debug_write_play_file(AUDIO_DEC_IN, input_buf, input_len);
- if(DEBUG_DECODER){
- rtpDbg(vrtp,"%s:%d: receiver_do_decode before decode data_len:%d.", __FILE__, __LINE__, input_len);
- }
- before_decode_ms = TimeInMilliseconds();
-
- decodered_frame = video_decoder_process(vrtp->decoder, input_buf, input_len, &input_len, &key_frame);
- if(DEBUG_DECODER){
- rtpDbg(vrtp,"%s:%d: receiver_do_decode after decode data_len:%d.", __FILE__, __LINE__, input_len);
- }
- after_decode_ms = TimeInMilliseconds();
- if (decodered_frame == NULL){
- rtpDbg(vrtp,"receiver_do_decode decode failed.");
- video_stats_receiver_on_decoded_frame(after_decode_ms, after_decode_ms - before_decode_ms, 0);
- return 0;
- }
- vrtp->prev_dec_ms = after_decode_ms;
- video_stats_receiver_on_decoded_frame(after_decode_ms, after_decode_ms - before_decode_ms, key_frame);
- //debug render file
- if (vrtp->config.rx_height)
- {
- if (VIDEO_FORMAT_RGB24 != decodered_frame->format)
- {
- unsigned char* video_debug_buf;
- int length = vrtp->config.rx_height * vrtp->config.rx_width * 3 / 2;
- video_debug_buf = (unsigned char*)malloc(length);
- yuv_buffers_combine_to_one(decodered_frame, video_debug_buf);
- video_debug_write_play_file(VIDEO_RENDER_IN, video_debug_buf, length);
- free(video_debug_buf);
- }
- }
- //notify render
- before_render_ms = TimeInMilliseconds();
- if(vrtp->config.on_rx_frame){
- int iret = vrtp->config.on_rx_frame(decodered_frame, vrtp->config.user_data);
- if (1 == iret){
- #ifdef _WIN32
- #else
- video_frame_delete(decodered_frame);
- decodered_frame = NULL;
- #endif
- }
- }
- else {
- //render is null, we need delete self.
- video_frame_delete(decodered_frame);
- decodered_frame = NULL;
- }
- after_render_ms = TimeInMilliseconds();
- video_stats_receiver_on_rendered_frame(after_render_ms, after_render_ms - before_render_ms);
- }
- return input_len == 0;
- }
- void decoder_create(videortp_t *vrtp, const videortp_config_t *config){
- VideoCodingLogCallBack log_func;
- DecoderConfig decoder_config;
- decoder_config.color_space = VIDEO_FORMAT_RGB24;
- decoder_config.decode_id = CODEC_ID_H264;
- decoder_config.width = config->rx_width;
- decoder_config.height = config->rx_height;
- log_func.log_fn = &video_coding_on_log;
- log_func.userdata = vrtp;
- vrtp->decoder = video_decoder_open(&decoder_config, &log_func);
- //rtpDbg(vrtp,"decoder_create color_space: %d decode_id: %d width: %d height: %d.",
- // decoder_config.color_space, decoder_config.decode_id, decoder_config.width, decoder_config.height);
- }
- void decoder_destroy(videortp_t *vrtp){
- if (vrtp->decoder != NULL) {
- video_decoder_close(vrtp->decoder);
- }
- //rtpDbg(vrtp,"decoder_destroy.");
- }
- /******************************standard_h264接收处理 start***************************/
- static void receiver_standard_h264_update_sps(videortp_t *d, rtpframe_part_t *sps){
- if (d->sps){
- free((void *)(d->sps));
- }
- d->sps = rtpframe_part_dupb(sps);
- }
- static void receiver_standard_h264_update_pps(videortp_t *d, rtpframe_part_t *pps){
- if (d->pps){
- free((void *)(d->pps));
- }
- if (pps){
- d->pps=rtpframe_part_dupb(pps);
- }
- else{
- d->pps=NULL;
- }
- }
- static bool_t receiver_standard_h264_check_sps_pps_change(videortp_t *d, rtpframe_part_t *sps, rtpframe_part_t *pps){
- bool_t ret1=FALSE,ret2=FALSE;
- if (d->sps){
- if (sps){
- ret1=(receiver_msgdsize(sps)!=receiver_msgdsize(d->sps)) ||
- (memcmp((const void *)(d->sps->buf),(const void *)(sps->buf),(size_t)receiver_msgdsize(sps))!=0);
- if (ret1) {
- receiver_standard_h264_update_sps(d,sps);
- receiver_standard_h264_update_pps(d,NULL);
- }
- }
- }else if (sps) {
- receiver_standard_h264_update_sps(d,sps);
- }
- if (d->pps){
- if (pps){
- ret2=(receiver_msgdsize(pps)!=receiver_msgdsize(d->pps)) ||
- (memcmp((const void *)(d->pps->buf), (const void *)(pps->buf), (size_t)receiver_msgdsize(pps))!=0);
- if (ret2) {
- receiver_standard_h264_update_pps(d,pps);
- }
- }
- }else if (pps) {
- receiver_standard_h264_update_pps(d,pps);
- }
- return ret1 || ret2;
- }
- static int receiver_standard_h264_add_startcode(videortp_t *vrtp, rtpframe_t *frame,
- uint8_t *output_buf, bool_t *new_sps_pps)
- {
- rtpframe_part_t *pos = NULL;
- uint8_t *dst = NULL;
- bool_t start_picture=TRUE;
- int output_len = 0;
- dst = output_buf;
- list_for_each_entry(pos, &frame->part_list, rtpframe_part_t, entry)
- {
- x264_hdr *hdr = (x264_hdr*)&pos->buf[pos->offset];
- unsigned char* src = (unsigned char*)&pos->buf[pos->offset];
- uint8_t nalu_type = hdr->id;
- if (nalu_type==NAL_SPS){
- *new_sps_pps=receiver_standard_h264_check_sps_pps_change(vrtp,pos,NULL) || *new_sps_pps;
- }
- if (nalu_type==NAL_PPS){
- *new_sps_pps=receiver_standard_h264_check_sps_pps_change(vrtp,NULL,pos) || *new_sps_pps;
- }
- if (start_picture || nalu_type==NAL_SPS || nalu_type==NAL_PPS ){
- *dst++=0;
- start_picture=FALSE;
- }
- *dst++ = 0;
- *dst++ = 0;
- *dst++ = 1;
- *dst++=*src++;
- while(src < (unsigned char*)&(pos->buf[pos->offset]) + pos->actual_len - 3){
- if (src[0]==0 && src[1]==0 && src[2]<3){
- *dst++=0;
- *dst++=0;
- *dst++=3;
- src+=2;
- }
- *dst++=*src++;
- }
- *dst++=*src++;
- *dst++=*src++;
- *dst++=*src++;
- }
- output_len = dst - output_buf;
- return output_len;
- }
- static int receiver_standard_h264_add_encoded_buffer_startcode(videortp_t *vrtp, EncodedImage *encoded_image,
- uint8_t *output_buf)
- {
- uint8_t *dst = NULL;
- bool_t start_picture=true;
- int output_len = 0;
- int i = 0;
- dst = output_buf;
- for (i = 0; i < encoded_image->fragmentation_header_.fragmentationVectorSize; i++)
- {
- x264_hdr *hdr = (x264_hdr*)&encoded_image->encoded_data_[encoded_image->fragmentation_header_.fragmentationOffset[i]];
- unsigned char* src = (unsigned char*)&encoded_image->encoded_data_[encoded_image->fragmentation_header_.fragmentationOffset[i]];
- uint8_t nalu_type = hdr->id;
- if (start_picture || nalu_type==NAL_SPS || nalu_type==NAL_PPS){
- *dst++=0;
- start_picture=false;
- }
- *dst++ = 0;
- *dst++ = 0;
- *dst++ = 1;
- *dst++=*src++;
- while(src < (unsigned char*)&encoded_image->encoded_data_[encoded_image->fragmentation_header_.fragmentationOffset[i]] +
- encoded_image->fragmentation_header_.fragmentationLength[i] - 3){
- if (src[0]==0 && src[1]==0 && src[2]<3){
- *dst++=0;
- *dst++=0;
- *dst++=3;
- src+=2;
- }
- *dst++=*src++;
- }
- *dst++=*src++;
- *dst++=*src++;
- *dst++=*src++;
- }
- output_len = dst - output_buf;
- return output_len;
- }
- static int receiver_standard_h264_calculate_mb_in_slice(char* psrc, size_t ulen)
- {
- int ret = -1;
- bs_t bs_data;
- if (NULL == psrc || 0 == ulen){
- return ret;
- }
- bs_init(&bs_data, psrc, ulen);
- ret = bs_read_ue(&bs_data);
- return ret;
- }
- static int receiver_standard_h264_append_rtpframe_part(videortp_t *rtp, rtpframe_t *frame,
- unsigned ts, unsigned key, rtpframe_part_t *new_part)
- {
- if (frame->used && frame->ts != ts)
- {
- rtpframe_clear(rtp, frame);
- }
- if (frame->used == 0){
- frame->ts = ts;
- frame->key = key;
- frame->cur_max_mb = 0;
- }
- if (frame->cur_max_mb <= new_part->mb_in_slice)
- {
- frame->cur_max_mb = new_part->mb_in_slice;
- list_add_tail(&new_part->entry, &frame->part_list);
- frame->used++;
- }
- else
- {
- rtpframe_part_t *pos;
- unsigned short temp_seq;
- list_for_each_entry(pos, &frame->part_list, rtpframe_part_t, entry)
- {
- if (pos->mb_in_slice > new_part->mb_in_slice)
- {
- break;
- }
- }
- temp_seq = new_part->seq;
- new_part->seq = pos->seq;
- pos->seq = temp_seq;
- __list_add(&new_part->entry, pos->entry.prev, &pos->entry);
- frame->used++;
- }
- return 1;
- }
- //ts不同, 一帧结束,返回此帧
- static int receiver_standard_h264_find_frame(videortp_t *rtp, rtpframe_part_t* part_data,
- unsigned mark, unsigned ts, unsigned key)
- {
- int i = rtp->frame_win_start;
- if (rtp->frame_win[i].ts == ts)
- {
- receiver_standard_h264_append_rtpframe_part(rtp, &rtp->frame_win[i], ts, key, part_data);
- return -1;
- }
- else{
- int index = (rtp->frame_win_start + 1)%FRAME_WIN_SIZE;
- rtpframe_t *frame = &rtp->frame_win[i];
- receiver_standard_h264_append_rtpframe_part(rtp, &rtp->frame_win[index], ts, key, part_data);
- rtp->frame_win_start = index;
- return i;
- }
- }
- static int receiver_standard_h264_on_jbuffer_request_key_frame(void *userdata){
-
- videortp_t *vrtp = (videortp_t *)userdata;
- if (vrtp) {
- receiver_notify_peer_fast_update_now((vrtp));
- }
- }
- static int receiver_h264_on_receive_encoded_image(EncodedImage *encoded_image,
- unsigned int timestamp, unsigned short first_seq, unsigned short last_seq, void *userdata){
-
- videortp_t *vrtp = (videortp_t *)userdata;
- if (vrtp) {
- uint8_t *input_buf = NULL;
- int input_len = 0;
- int i = 0;
- int decoded;
- if(DEBUG_RX){
- rtpDbg(vrtp,"%s:%d: receiver_h264_on_receive_encoded_image timestamp:%u first_seq:%u last_seq:%u key: %d len: %d.", __FILE__, __LINE__,
- timestamp, first_seq, last_seq, encoded_image->key_frame, encoded_image->size_);
- rtpDbg(vrtp,"%s:%d: receiver_h264_on_receive_encoded_image fragmentationSize: %d.", __FILE__, __LINE__,
- encoded_image->fragmentation_header_.fragmentationVectorSize);
- for (i = 0;i < encoded_image->fragmentation_header_.fragmentationVectorSize;++i){
- rtpDbg(vrtp,"%s:%d: receiver_h264_on_receive_encoded_image index: %d fragmentationLength: %d fragmentationOffset: %d.", __FILE__, __LINE__,
- i, encoded_image->fragmentation_header_.fragmentationLength[i], encoded_image->fragmentation_header_.fragmentationOffset[i]);
- }
- }
- if (encoded_image->key_frame || vrtp->prev_dec_seq+1 == first_seq) {
- input_len = encoded_image->size_ + MAX_ASSEMBLE_EXTRA_SIZE;
- input_buf = (uint8_t*)_alloca(input_len);
- memset(input_buf, 0, input_len);
-
- //00->003,同时加上startcode
- if (encoded_image->pt_ == REC_COMMON_VIDEO_PT){
- memcpy(input_buf, encoded_image->encoded_data_, encoded_image->size_);
- input_len = encoded_image->size_;
- } else {
- if (vrtp->h264_packetizer){
- int status;
- unsigned int whole_len = 0;
- for (i=0; i<encoded_image->fragmentation_header_.fragmentationVectorSize; ++i) {
- if (whole_len + encoded_image->fragmentation_header_.fragmentationLength[i] > input_len) {
- return 0;
- }
- status = h264_unpacketize( vrtp->h264_packetizer,
- &encoded_image->encoded_data_[encoded_image->fragmentation_header_.fragmentationOffset[i]],
- encoded_image->fragmentation_header_.fragmentationLength[i],
- input_buf,
- input_len,
- &whole_len);
- if (status != 0) {
- continue;
- }
- }
- input_len = whole_len;
- }else {
- input_len = receiver_standard_h264_add_encoded_buffer_startcode(vrtp, encoded_image, input_buf);
- }
- }
- if(DEBUG_RX){
- rtpDbg(vrtp,"%s:%d: receiver_h264_on_receive_encoded_image encoded_size:%d frame_len:%d now:%I64d.", __FILE__, __LINE__,
- encoded_image->size_, input_len, TimeInMilliseconds());
- }
-
- //decode
- decoded = decoder_process(vrtp, input_buf, input_len);
- if (decoded) {
- vrtp->prev_dec_seq = last_seq;
- vrtp->prev_dec_ts = timestamp;
- } else {
- rtpDbg(vrtp,"receiver_h264_on_receive_encoded_image decode_frame failed!");
- }
- }
- }
- return 0;
- }
- static int receiver_standard_h264_decode(videortp_t *vrtp, rtpframe_t *frame)
- {
- if (frame->used) {
- rtpframe_part_t *pos = NULL;
- int got_picture = 0;
- uint8_t *input_buf = NULL;
- int input_len = 0;
- input_buf = (uint8_t*)_alloca(frame->used * MAX_RECV_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
- memset(input_buf, 0, frame->used * MAX_RECV_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
- //00->003,同时加上startcode
- {
- bool_t need_reinit=FALSE;
- input_len = receiver_standard_h264_add_startcode(vrtp, frame, input_buf, &need_reinit);
- }
- if(DEBUG_RX){
- rtpDbg(vrtp,"%s:%d: receiver_standard_h264_decode frame_used:%d frame_len:%d now:%I64d.", __FILE__, __LINE__, frame->used, input_len, TimeInMilliseconds());
- }
-
- //decode
- return decoder_process(vrtp, input_buf, input_len);
- }
- return 0;
- }
- rtpframe_t *receiver_standard_h264_assemble(videortp_t *vrtp,
- rtpframe_part_t *part_data, int len,
- unsigned short seq, unsigned mark, unsigned ts){
- int ret = -1;
- int iret = -1;
- //rtpframe_t *frame = NULL;
- int key = 0;
- x264_hdr *hdr = (x264_hdr*)&part_data->buf[0];
- uint8_t nalu_type = hdr->id;
- if(NAL_SPS == nalu_type || NAL_PPS == nalu_type){
- part_data->mb_in_slice = 0;
- key = 1;
- }else{
- part_data->mb_in_slice = receiver_standard_h264_calculate_mb_in_slice(&part_data->buf[1], part_data->actual_len - 1);
- }
- if (NAL_SLICE_IDR == nalu_type){
- key = 1;
- }
- part_data->actual_len = len;
- part_data->offset = 0;
- part_data->mark = mark;
- part_data->seq = seq;
- if(DEBUG_RX){
- rtpDbg(vrtp,"%s:%d: receiver_standard_h264_assemble actual_len:%d seq:%d key:%d.", __FILE__, __LINE__, len, seq, key);
- }
-
- iret = receiver_standard_h264_find_frame(vrtp, part_data, mark, ts, key);
- if (iret != -1) {
- return &vrtp->frame_win[iret];
- }
- return NULL;
- }
- static int receiver_process_standard_h264_packet(
- videortp_t *vrtp, rtpframe_part_t *part_data, int len,
- unsigned short seq, unsigned mark, unsigned ts, unsigned pt)
- {
- #if 1
- VideoJBufferPacketInfo packet_info = {0};
- x264_hdr *hdr = (x264_hdr*)&part_data->buf[part_data->offset];
- uint8_t nalu_type = NAL_UNKNOWN;
- int actual_len = part_data->actual_len;
- int offset = part_data->offset;
- packet_info.length = actual_len;
- packet_info.packet_type = NORMAL_PACKET_IN_FRAME;
- if(mark){
- packet_info.packet_type = LAST_PACKET_IN_FRAME;
- }
- packet_info.seq = seq;
- packet_info.timestamp = ts;
- nalu_type = hdr->id;
- if (vrtp->h264_packetizer) {
- h264_unpacketize_get_original_nal_type(vrtp->h264_packetizer, &part_data->buf[offset], actual_len, &nalu_type);
- }
- if(NAL_SPS == nalu_type || NAL_PPS == nalu_type || NAL_SLICE_IDR == nalu_type){
- packet_info.is_key = 1;
- }
- packet_info.pt = pt;
- if(DEBUG_RX){
- rtpDbg(vrtp,"%s:%d: receiver_process_standard_h264_packet len:%d seq:%d mark:%d ts:%d nalu_type:%u offset:%d actual_len:%d.", __FILE__, __LINE__,
- len, seq, mark, ts, nalu_type, offset, actual_len);
- }
-
- video_jbuffer_api_receive_packet(vrtp->jbuffer, &part_data->buf[offset], &packet_info);
- rtpframe_part_destroy(vrtp, part_data);
-
- #else
- rtpframe_t *frame = NULL;
- frame = receiver_standard_h264_assemble(vrtp, part_data, len, seq, mark, ts);
- if (frame != NULL) {
- int decoded = 0;
- //取出的frame可能为空(在第一次收数据时),需要先判空
- if (!rtpframe_is_empty(frame)
- && (frame->key || vrtp->prev_dec_seq+1 == rtpframe_get_first_seq(frame))){
-
- decoded = receiver_standard_h264_decode(vrtp, frame);
- if (decoded) {
- //rtpDbg(vrtp,"decode_frame ok!");
- if (vrtp->frame_duration==0 && vrtp->prev_dec_seq+1 == rtpframe_get_first_seq(frame)) {
- vrtp->frame_duration = frame->ts - vrtp->prev_dec_ts;
- rtpDbg(vrtp,"decode frame duration: %d", vrtp->frame_duration);
- }
- vrtp->prev_dec_seq = rtpframe_get_last_seq(frame);
- vrtp->prev_dec_ts = frame->ts;
- } else {
- rtpDbg(vrtp,"decode_frame failed!");
- }
- }
-
- rtpframe_clear(vrtp, frame);
- }
- #endif
-
- return 0;
- }
- /******************************standard_h264接收处理 end***************************/
- #if 0
- #endif
- /******************************custom_h264接收处理 start***************************/
- static int receiver_custom_h264_check_rtpframe_integrated(rtpframe_t *frame)
- {
- if (!list_empty((const struct list_head *)(&frame->part_list))) {
- rtpframe_part_t *first = list_first_entry(&frame->part_list, rtpframe_part_t, entry);
- rtpframe_part_t *last = list_last_entry(&frame->part_list, rtpframe_part_t, entry);
- if (first->psc && last->mark) {
- rtpframe_part_t *pos;
- unsigned short seq = first->seq;
- list_for_each_entry(pos, &frame->part_list, rtpframe_part_t, entry) {
- if (seq == pos->seq) {
- ++seq;
- } else {
- return 0;
- }
- }
- return 1;
- }
- }
- return 0;
- }
- static int receiver_custom_h264_check_rtpframe_partleft(rtpframe_t *frame)
- {
- if (!list_empty((const struct list_head *)(&frame->part_list))) {
- rtpframe_part_t *first = list_first_entry(&frame->part_list, rtpframe_part_t, entry);
- rtpframe_part_t *last = list_last_entry(&frame->part_list, rtpframe_part_t, entry);
- if (last->mark && (0 != first->psc)) {
- return 1;
- }
- }
- return 0;
- }
- //根据ts查找缓存rtpframe_t位置
- static rtpframe_t *receiver_custom_h264_find_rtpframe(videortp_t *rtp, unsigned ts)
- {
- if (rtp->frame_duration == 0) {
- return &rtp->frame_win[rtp->frame_win_ptr];
- } else {
- unsigned int frame_win_duration = rtp->frame_duration*FRAME_WIN_SIZE;
- if (RTP_SEQ_GT(ts, rtp->prev_dec_ts, frame_win_duration)) {
- unsigned int idx = (ts - rtp->prev_dec_ts) / rtp->frame_duration;
- idx = (rtp->frame_win_ptr + idx + FRAME_WIN_SIZE - 1) % FRAME_WIN_SIZE;
- return &rtp->frame_win[idx];
- }
- }
- return NULL;
- }
- static int receiver_custom_h264_append_rtpframe_part(videortp_t *rtp, rtpframe_t *frame, unsigned key, unsigned ts, rtpframe_part_t *new_part)
- {
- if (frame->used && frame->ts != ts) {
- rtpframe_clear(rtp, frame);
- }
- if (frame->used == 0) {
- frame->ts = ts;
- frame->key = key;
- } else {
- rtpframe_part_t *pos;
- if (frame->used >= 1 && !key) {
- OutputDebugStringA("a");
- }
- list_for_each_entry(pos, &frame->part_list, rtpframe_part_t, entry) {
- if (pos->seq == new_part->seq) {
- return 0;
- } else if (RTP_SEQ_GT(pos->seq, new_part->seq, RTP_MAX_JUMP)) {
- __list_add(&new_part->entry, pos->entry.prev, &pos->entry);
- frame->used++;
- return 1;
- } else if (RTP_SEQ_GT(new_part->seq, pos->seq, RTP_MAX_JUMP)) {
- continue;
- } else {
- return 0;
- }
- }
- }
- list_add_tail(&new_part->entry, &frame->part_list);
- frame->used++;
- return 1;
- }
- static int receiver_custom_h264_decode(videortp_t *vrtp, rtpframe_t *frame)
- {
- if (frame->used) {
- rtpframe_part_t *pos = NULL;
- //int got_picture = 0;
- uint8_t *input_buf = NULL;
- int input_len = 0;
- input_buf = (uint8_t*)_alloca(frame->used * MAX_RECV_BUFFER_SIZE+FF_INPUT_BUFFER_PADDING_SIZE);
- list_for_each_entry(pos, &frame->part_list, rtpframe_part_t, entry) {
- memcpy(input_buf+input_len, &pos->buf[pos->offset], pos->actual_len);
- input_len += pos->actual_len;
- }
- memset(input_buf+input_len, 0, FF_INPUT_BUFFER_PADDING_SIZE);
- if(DEBUG_RX){
- rtpDbg(vrtp,"%s:%d: receiver_custom_h264_decode frame_used:%d frame_len:%d now:%I64d.", __FILE__, __LINE__, frame->used, input_len, TimeInMilliseconds());
- }
- //decode
- return decoder_process(vrtp, input_buf, input_len);
- }
- return 0;
- }
- rtpframe_t *receiver_custom_h264_assemble(videortp_t *vrtp,
- rtpframe_part_t *part_data, int len,
- unsigned short seq, unsigned mark, unsigned ts){
- h26x_hdr *hdr = (h26x_hdr*)&part_data->buf[0];
- char *raw_data = (char*)(hdr + 1);
- rtpframe_t *frame = NULL;
- int actual_len = len - sizeof(h26x_hdr) + 2;
- int appended;
- int key = hdr->key;
- int sno = hdr->id;
- int end = hdr->end;
- if(DEBUG_RX){
- rtpDbg(vrtp,"%s:%d: receiver_custom_h264_assemble actual_len:%d seq:%d key:%d sno:%d end: %d.", __FILE__, __LINE__, actual_len, seq, !!key, sno, end);
- }
- part_data->actual_len = actual_len;
- part_data->offset = sizeof(h26x_hdr)-2;
- part_data->mark = mark;
- part_data->seq = seq;
- part_data->psc = (sno == 0);
- frame = receiver_custom_h264_find_rtpframe(vrtp, ts);
- if (!frame) {
- receiver_clear_window(vrtp);
- frame = &vrtp->frame_win[vrtp->frame_win_ptr];
- }
- appended = receiver_custom_h264_append_rtpframe_part(vrtp, frame, key, ts, part_data);
- if (!appended) {
- rtpframe_part_destroy(vrtp, part_data);
- } else if(receiver_custom_h264_check_rtpframe_integrated(frame)) {
- return frame;
- }
- return NULL;
- }
- static int receiver_process_custom_h264_packet(videortp_t *vrtp,
- rtpframe_part_t *part_data, int len,
- unsigned short seq, unsigned mark, unsigned ts, unsigned pt)
- {
- #if 1
- VideoJBufferPacketInfo packet_info = {0};
- h26x_hdr *hdr = (h26x_hdr*)&part_data->buf[part_data->offset];
- int actual_len = part_data->actual_len - sizeof(h26x_hdr) + 2;
- int key = hdr->key;
- int sno = hdr->id;
- int end = hdr->end;
- int offset = part_data->offset + sizeof(h26x_hdr)-2;
- packet_info.length = actual_len;
- packet_info.packet_type = NORMAL_PACKET_IN_FRAME;
- if (sno == 0){
- packet_info.packet_type = FIRST_PACKET_IN_FRAME;
- }
- if(end){
- packet_info.packet_type = LAST_PACKET_IN_FRAME;
- }
- packet_info.seq = seq;
- packet_info.timestamp = ts;
- packet_info.is_key = key;
- packet_info.pt = pt;
- if(DEBUG_RX){
- rtpDbg(vrtp,"%s:%d: receiver_process_custom_h264_packet len:%d seq:%d mark:%d ts:%d pt:%u key:%d sno:%d end:%d offset:%d actual_len:%d.", __FILE__, __LINE__,
- len, seq, mark, ts, pt, key, sno, end, offset, actual_len);
- }
-
- video_jbuffer_api_receive_packet(vrtp->jbuffer, &part_data->buf[offset], &packet_info);
- rtpframe_part_destroy(vrtp, part_data);
- #else
- rtpframe_t *frame = NULL;
- if(DEBUG_RX){
- rtpDbg(vrtp,"%s:%d: receiver_process_custom_h264_packet len:%d seq:%d mark:%d ts:%d.", __FILE__, __LINE__, len, seq, mark, ts);
- }
-
- frame = receiver_custom_h264_assemble(vrtp, part_data, len, seq, mark, ts);
- if (frame != NULL) {
- int decoded;
- do {
- decoded = 0;
- if (frame->key || vrtp->prev_dec_seq+1 == rtpframe_get_first_seq(frame)) {
- decoded = receiver_custom_h264_decode(vrtp, frame);
- if (decoded) {
- if (vrtp->frame_duration==0 && vrtp->prev_dec_seq+1 == rtpframe_get_first_seq(frame)) {
- vrtp->frame_duration = frame->ts - vrtp->prev_dec_ts;
- rtpDbg(vrtp,"%s:%d: receiver_process_custom_h264_packet decode frame duration: %d.", __FILE__, __LINE__, vrtp->frame_duration);
- }
- vrtp->prev_dec_seq = rtpframe_get_last_seq(frame);
- vrtp->prev_dec_ts = frame->ts;
- } else {
- rtpDbg(vrtp,"%s:%d: receiver_process_custom_h264_packet decode_frame failed!", __FILE__, __LINE__);
- }
- rtpframe_clear(vrtp, frame);
- vrtp->frame_win_ptr = (frame->id+1) % FRAME_WIN_SIZE;
- frame = &vrtp->frame_win[vrtp->frame_win_ptr];
- } else {
- if (!frame->key) {
- receiver_notify_peer_fast_update(vrtp);
- }
- }
- } while (decoded && frame->used && receiver_custom_h264_check_rtpframe_integrated(frame));
- }
- #endif
-
- return 0;
- }
- /******************************custom_h264接收处理 end***************************/
- #if 0
- #endif
- static void receiver_process_rtcp_packet(videortp_t *vrtp, unsigned rtcp_flags){
- if (rtcp_flags & RTP_SESSION_HAS_FIR){
- receiver_force_key_frame(vrtp);
- }
- if (rtcp_flags & RTP_SESSION_HAS_RTPFB_TMMBR) {
- rtcp_statistics rtcp_stats = {0};
- rtp_session_get_rtcp_stat(vrtp->rtp_sess, &rtcp_stats);
- sim_recv_bitrate_feedback(rtcp_stats.tmmbr_max_bitrate);
- vrtp->recv_cc_feedback_ms = TimeInMilliseconds();
- vrtp->recv_cc_feedback = TRUE;
- vrtp->remote_support_cc = TRUE;
- }
- if ((rtcp_flags & RTP_SESSION_HAS_RR) || (rtcp_flags & RTP_SESSION_HAS_SR)) {
- rtcp_statistics rtcp_stats = {0};
- rtp_session_get_rtcp_stat(vrtp->rtp_sess, &rtcp_stats);
- sim_update_rtt((uint32_t)(rtcp_stats.rtt*1000));
- sim_recv_fraction_loss_feedback(rtcp_stats.fraction_lost, rtcp_stats.report_block_last_number_of_packets);
- }
- }
- #ifdef _WIN32
- static unsigned int __stdcall recv_proc(void* arg)
- #else
- void* recv_proc(void* arg)
- #endif
- {
- videortp_t *vrtp = (videortp_t*)arg;
- int rtp_timeout_cnt = 0;
- int64_t pre_500_ms = TimeInMilliseconds();
- #ifdef _WIN32
- SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
- #else
- struct sched_param param;
- int policy;
- pthread_getschedparam(pthread_self(), &policy, ¶m);
- rtpDbg(vrtp,"current thread policy is %d, priority is %d.", policy, param.sched_priority);
- #endif
- receiver_notify_peer_fast_update_now(vrtp);
- for (;;) {
- #ifdef _WIN32
- DWORD dwRet = WaitForSingleObject(vrtp->evt, 10);
- if (dwRet == WAIT_TIMEOUT)
- #else
- struct timespec ts;
- //int ivalue = -1;
- clock_gettime(CLOCK_REALTIME, &ts);
- long unsec = ts.tv_nsec + (1000 * 1000 * 10);
- ts.tv_sec += (unsec / 1000000000);
- ts.tv_nsec = (unsec % 1000000000);
- if (0 != sem_timedwait(&vrtp->sem_evt, &ts) && (ETIMEDOUT == errno))
- #endif
- {
- int n;
- {
- #ifdef _WIN32
- unsigned rtcp_flags = 0;
- int result = rtp_session_recv_rtcp(vrtp->rtp_sess, &rtcp_flags);
- if (result >= 0) {
- receiver_process_rtcp_packet(vrtp, rtcp_flags);
- }
- #endif
- }
- do {
- unsigned short seq = 0;
- unsigned mark = 0;
- unsigned extension = 0;
- unsigned ts = 0;
- unsigned pt = 0;
- rtp_hdr hdr = {0};
- rtpframe_part_t *part_data = rtpframe_part_create(vrtp);
- rtp_session_t *rtp_sess = vrtp->rtp_sess;
- part_data->actual_len = 0;
- part_data->mark = 0;
- part_data->psc = 0;
- part_data->seq = 0;
- part_data->offset = 0;
- part_data->mb_in_slice = -1;
- n = rtp_session_recv_hook2(rtp_sess, &hdr, part_data->buf, sizeof(part_data->buf), vrtp->config.on_rx_udp, vrtp->config.user_data);
- seq = ntohs(hdr.seq);
- mark = hdr.m;
- extension = hdr.x;
- ts = ntohl(hdr.ts);
- pt = hdr.pt;
- #if 0 // for testing
- #define PACKET_LOSS_RATIO 30
- if (n > 0 && rand()%1000 >= PACKET_LOSS_RATIO) {
- rtpDbg(vrtp,"%s:%d rtp_session_recv_hook2 pt = %u, mark = %u, ts = %u, seq = %u, size = %d", __FUNCTION__, __LINE__, pt, mark, ts, seq, n);
- #else
- if (n > 0) {
- #endif
- {
- uint32_t send_time = 0;
- if (vrtp->rtp_header_extension && extension){
- int extension_length = 0;
- rtp_header_extension_api_decode_absolute_send_time(vrtp->rtp_header_extension,
- (uint8_t *)part_data->buf, n, &send_time, &extension_length);
- part_data->actual_len = n - extension_length;
- part_data->offset = extension_length;
- if(DEBUG_RX){
- rtpDbg(vrtp,"%s:%d: recv_proc rtp_header_extension send_time:%u length:%d actual_len:%d offset:%d.",
- __FILE__, __LINE__, send_time, extension_length,
- part_data->actual_len, part_data->offset);
- }
- }else {
- part_data->actual_len = n;
- part_data->offset = 0;
- }
- //huchen add for video cc
- #ifdef _WIN32
- {
- sim_segment_t seg = { 0 };
- seg.transport_seq = seq;
- //注意,cc中的ts是以真实时间毫秒为单位,rtp的时间戳是90000为1秒,这里需要转换
- seg.timestamp = (send_time == 0 ? (ts / (VIDEO_CLOCK / 1000)) : send_time);
- seg.data_size = n;
- sim_recv_video(&seg);
- }
- #endif
- }
- video_stats_bandwidth_update_recv_rtp_bytes(n);
- video_stats_receiver_on_incoming_packet(TimeInMilliseconds());
- if (REC_COMMON_VIDEO_PT == pt){
- receiver_process_custom_h264_packet(vrtp, part_data, n, seq, mark, ts, pt);
- }else{
- receiver_process_standard_h264_packet(vrtp, part_data, n, seq, mark, ts, pt);
- }
- rtp_timeout_cnt = 0;
- }
- else {
- rtpframe_part_destroy(vrtp, part_data);
- }
- } while (n > 0);
- {
- //1s没有解码到视频数据,请求I帧
- int64_t now_ms = TimeInMilliseconds();
- if (now_ms - vrtp->prev_dec_ms >= 1000){
- //rtpDbg(vrtp,"recv_proc now:%I64d > prev_dec_ms:%I64d 1s.", TimeInMilliseconds(), vrtp->prev_dec_ms);
- receiver_notify_peer_fast_update_now(vrtp);
- vrtp->prev_dec_ms = now_ms;
- }
- if (now_ms - pre_500_ms >= 500){
- //发送流控信令,表明接收端支持拥塞控制,让发送端发送加上send time(rtp header extension)
- if (vrtp->send_cc_feedback == FALSE){
- int max_bitrate, target_bitrate, min_bitrate;
- get_start_config_bitrate(&vrtp->config, &max_bitrate, &target_bitrate, &min_bitrate);
- rtp_session_send_rtcp_fb_tmmbr(vrtp->rtp_sess, target_bitrate);
- }
- pre_500_ms = now_ms;
- }
- }
- } else {
- break;
- }
- }
- //rtpDbg(vrtp, "exit recv_proc.");
- return 0;
- }
- /******************************custom_h264发送处理 start***************************/
- static void sender_custom_h264_packetize_and_send(videortp_t *vrtp, int key, unsigned pt, const uint8_t *buf, int n)
- {
- const char *ptr = (const char*)buf;
- int left = n;
- unsigned delta_ts = vrtp->delta_ts;
- int id = 0;
- int mtu = get_mtu(vrtp->config.mtu);
- mtu = mtu-20-8-12-sizeof(h26x_hdr)+2; // ip hdr: 20, udp hdr: 8, rtp hdr: 12
- if(DEBUG_TX){
- rtpDbg(vrtp,"%s:%d: sender_custom_h264_packetize_and_send key: %d len: %d delta_ts: %d now: %I64d.",
- __FILE__, __LINE__, key, n, delta_ts, TimeInMilliseconds());
- }
- video_debug_write_record_file(VIDEO_ENC_OUT, buf, n);
-
- while (left > 0) {
- int rc;
- char tx_buf[MAX_PLAYLOAD_SIZE];
- h26x_hdr *hdr = (h26x_hdr*)&tx_buf[0];
- unsigned rtcp_flag;
- int tn = min(left, mtu);
- unsigned mark = (tn == left);
- hdr->key = !!key;
- hdr->end = mark;
- hdr->id = id++;
- memcpy((void *)(&tx_buf[0]+sizeof(h26x_hdr)-2), (const void *)ptr, (size_t)tn);
- if (DEBUG_TX) {
- rtpDbg(vrtp,"end = %d, id = %d, tn = %d", hdr->end, hdr->id, tn);
- }
- rc = rtp_session_send_hook(vrtp->rtp_sess, &rtcp_flag, pt, mark, delta_ts, tx_buf, tn+sizeof(h26x_hdr)-2, vrtp->config.on_tx_udp, vrtp->config.user_data);
- if (rc == 0) {
- receiver_process_rtcp_packet(vrtp, rtcp_flag);
- delta_ts = 0;
- left -= tn;
- ptr += tn;
- } else {
- break;
- }
- }
- }
- static void sender_custom_h264_send_fragment(videortp_t *vrtp, int index, int key_frame, unsigned mark, unsigned pt, uint8_t *fragment, int length)
- {
- char tx_buf[MAX_PLAYLOAD_SIZE] = {0};
- video_debug_write_record_file(VIDEO_ENC_OUT, fragment, length);
- video_stats_bandwidth_update_send_rtp_bytes(length);
- video_stats_sender_on_sent_packet(TimeInMilliseconds());
- if (MAX_PLAYLOAD_SIZE > length + sizeof(h26x_hdr)-2 + 32/*rtp_header_extension_length*/){
- int rc;
- unsigned rtcp_flag;
- h26x_hdr *hdr;
- int rtp_extension = 0;
- char rtp_header_extension_buf[32] = {0};
- int rtp_header_extension_length = 0;
- unsigned int delta_ts = vrtp->delta_ts;
- if(DEBUG_TX){
- rtpDbg(vrtp,"%s:%d: sender_custom_h264_send_fragment mark: %d length: %d delta_ts: %d now: %I64d.",
- __FILE__, __LINE__, mark, length, delta_ts, TimeInMilliseconds());
- }
- //rtp_header_extension
- if (vrtp->rtp_header_extension && vrtp->remote_support_cc){
- uint32_t interval_ms = TimeInMilliseconds() - vrtp->rtp_start_ms;
- rtp_header_extension_api_encode_absolute_send_time(vrtp->rtp_header_extension,
- interval_ms, (uint8_t *)rtp_header_extension_buf, &rtp_header_extension_length);
- memcpy((void *)(&tx_buf[0]), (const void *)rtp_header_extension_buf, (size_t)rtp_header_extension_length);
- rtp_extension = 1;
- if(DEBUG_TX){
- rtpDbg(vrtp,"%s:%d: sender_custom_h264_send_fragment rtp_header_extension interval_ms:%u length:%d.", __FILE__, __LINE__, interval_ms, rtp_header_extension_length);
- }
- }
- //custom header
- hdr = (h26x_hdr*)&tx_buf[rtp_header_extension_length];
- hdr->key = !!key_frame;
- hdr->end = mark;
- hdr->id = index;
- //playload
- memcpy((void *)(&tx_buf[rtp_header_extension_length]+sizeof(h26x_hdr)-2), (const void *)fragment, (size_t)length);
- { rtp_hdr rtp_hdr;
- rtp_state *rtp_state;
- rtp_state = rtp_session_get_rtp_state(vrtp->rtp_sess);
- rtp_state_fill_rtp(rtp_state, &rtp_hdr, pt, mark, delta_ts);
- rtp_hdr.x = rtp_extension;
- rc = rtp_session_send_hook2(vrtp->rtp_sess, &rtcp_flag, &rtp_hdr,
- tx_buf, length+sizeof(h26x_hdr)-2+rtp_header_extension_length,
- vrtp->config.on_tx_udp, vrtp->config.user_data);
- if (rc == 0) {
- receiver_process_rtcp_packet(vrtp, rtcp_flag);
- }
- }
- }
- }
- /******************************custom_h264发送处理 end***************************/
- /******************************standard_h264发送处理 start***************************/
- static int sender_standard_h264_send_packet(videortp_t *vrtp, unsigned mark, unsigned pt, const uint8_t *packet, int length)
- {
- char tx_buf[MAX_PLAYLOAD_SIZE] = {0};
- if (MAX_PLAYLOAD_SIZE > length + 32/*rtp_header_extension_length*/){
- int rc;
- unsigned rtcp_flag;
- int rtp_extension = 0;
- char rtp_header_extension_buf[32] = {0};
- int rtp_header_extension_length = 0;
- unsigned int delta_ts = vrtp->delta_ts;
-
- if(DEBUG_TX){
- rtpDbg(vrtp,"%s:%d: sender_standard_h264_send_packet mark: %d length: %d delta_ts: %d now: %I64d.",
- __FILE__, __LINE__, mark, length, delta_ts, TimeInMilliseconds());
- }
-
- //rtp_header_extension
- if (vrtp->rtp_header_extension && vrtp->remote_support_cc){
- uint32_t interval_ms = TimeInMilliseconds() - vrtp->rtp_start_ms;
- rtp_header_extension_api_encode_absolute_send_time(vrtp->rtp_header_extension,
- interval_ms, (uint8_t *)rtp_header_extension_buf, &rtp_header_extension_length);
- memcpy(&tx_buf[0], rtp_header_extension_buf, rtp_header_extension_length);
- rtp_extension = 1;
- if(DEBUG_TX){
- rtpDbg(vrtp,"%s:%d: sender_standard_h264_send_packet rtp_header_extension interval_ms:%u length:%d.", __FILE__, __LINE__, interval_ms, rtp_header_extension_length);
- }
- }
- //playload
- memcpy(&tx_buf[rtp_header_extension_length], packet, length);
- {
- rtp_hdr rtp_hdr;
- rtp_state *rtp_state;
- rtp_state = rtp_session_get_rtp_state(vrtp->rtp_sess);
- rtp_state_fill_rtp(rtp_state, &rtp_hdr, pt, mark, delta_ts);
- rtp_hdr.x = rtp_extension;
- rc = rtp_session_send_hook2(vrtp->rtp_sess, &rtcp_flag, &rtp_hdr,
- tx_buf, length + rtp_header_extension_length,
- vrtp->config.on_tx_udp, vrtp->config.user_data);
- if (rc == 0) {
- receiver_process_rtcp_packet(vrtp, rtcp_flag);
- }
- }
- }
-
- return 0;
- }
- // unsigned short id : 5;
- // unsigned short end : 2;
- // unsigned short key : 1;
- static int sender_standard_h264_send_nal(videortp_t *vrtp, unsigned mark, unsigned pt, uint8_t *nal_payload, int length)
- {
- video_debug_write_record_file(VIDEO_ENC_OUT, nal_payload, length);
- video_stats_bandwidth_update_send_rtp_bytes(length);
- video_stats_sender_on_sent_packet(TimeInMilliseconds());
- if(vrtp->h264_packetizer){
- const uint8_t *payload;
- size_t payload_len;
- int status;
- unsigned tmp_mark;
- //h264_packetize func change nal_payload, so we need copy it to tx_buf first, let nal_payload unchanged.
- unsigned int processed = 0;
- uint8_t *tx_buf = (uint8_t*)_alloca(length);
- memcpy(tx_buf, nal_payload, length);
- while(processed < length){
- status = h264_packetize(vrtp->h264_packetizer, (uint8_t *)tx_buf, length, &processed, &payload, &payload_len);
- if (status != 0) {
- return status;
- }
- if(DEBUG_TX){
- rtpDbg(vrtp,"%s:%d: sender_standard_h264_send_nal mark: %d processed: %u payload_len: %d.",
- __FILE__, __LINE__, mark, processed, payload_len);
- }
- //input mark =1, means last nal, rtp mark = 1, we need last nal 's last packet.
- if (mark && (processed >= length)){
- tmp_mark = 1;
- } else {
- tmp_mark = 0;
- }
- sender_standard_h264_send_packet(vrtp, tmp_mark, pt, payload, payload_len);
- }
- } else {
- int tn = length;
- int start_code_length = 0;
-
- //comment, remove nal start code
- if (nal_payload && nal_payload[0] == 0 && nal_payload[1] == 0 && nal_payload[2] == 0 && nal_payload[3] == 1) {
- start_code_length = 4;
- if (length - start_code_length > 0) {
- tn = length - start_code_length;
- } else {
- return -1;
- }
- }
- else if (nal_payload && nal_payload[0] == 0 && nal_payload[1] == 0 && nal_payload[2] == 1) {
- start_code_length = 3;
- if (length - start_code_length > 0) {
- tn = length - start_code_length;
- } else {
- return -1;
- }
- }
-
- sender_standard_h264_send_packet(vrtp, mark, pt, nal_payload + start_code_length, tn);
- }
- return 0;
- }
- static void sender_standard_h264_packetize_x264_nals(videortp_t *vrtp, unsigned pt, x264_nal_t *xnals, int num_nals)
- {
- int i;
- if(DEBUG_TX){
- rtpDbg(vrtp,"%s:%d: sender_standard_h264_packetize_x264_nals num_nals: %d.", __FILE__, __LINE__, num_nals);
- }
-
- for (i = 0;i < num_nals;++i){
- unsigned mark = 0;
- x264_nal_t* nal = &xnals[i];
- if (xnals[i].i_type == NAL_SPS) {
- if (DEBUG_TX) {
- rtpDbg(vrtp,"A SPS is being sent.");
- }
- }else if (xnals[i].i_type == NAL_PPS) {
- if (DEBUG_TX) {
- rtpDbg(vrtp,"A PPS is being sent.");
- }
- }else if (xnals[i].i_type == NAL_SLICE_IDR) {
- if (DEBUG_TX) {
- rtpDbg(vrtp,"A IDR is being sent.");
- }
- }
- if (i == num_nals -1){
- mark = 1;
- if (DEBUG_TX) {
- rtpDbg(vrtp,"A frame end.");
- }
- }
- sender_standard_h264_send_nal(vrtp, mark , pt, nal->p_payload, nal->i_payload);
- }
- }
- void sender_h264_packetize_nal(videortp_t *vrtp, int index, int total, int key_frame, unsigned pt, uint8_t *data, int data_size){
- int i;
- unsigned mark = 0;
- if(DEBUG_TX){
- rtpDbg(vrtp,"%s:%d: sender_h264_packetize_nal index: %d total: %d key_frame: %d data_size: %d.", __FILE__, __LINE__,
- index, total, key_frame, data_size);
- }
-
- if (index == total -1){
- mark = 1;
- if(DEBUG_TX){
- rtpDbg(vrtp,"A frame end.");
- }
- }
- //pt=97 rtp ts = vrtp->delta_ts
- //pt=101 rtp ts += vrtp->delta_ts
- if (index == 0){
- if (pt == REC_COMMON_VIDEO_PT){
- vrtp->delta_ts = VIDEO_CLOCK * vrtp->config.fps_den / vrtp->config.fps_num;
- } else {
- vrtp->delta_ts += VIDEO_CLOCK * vrtp->config.fps_den / vrtp->config.fps_num;
- }
- }else {
- if (pt == REC_COMMON_VIDEO_PT){
- vrtp->delta_ts = 0;
- } else {
- //do nothing
- }
- }
- if (pt == REC_COMMON_VIDEO_PT){
- sender_custom_h264_send_fragment(vrtp, index, key_frame, mark, pt, data, data_size);
- } else {
- sender_standard_h264_send_nal(vrtp, mark, pt, data, data_size);
- }
- }
- /******************************standard_h264发送处理 end***************************/
- #if 0
- #endif
- /******************************congestion control处理 start***************************/
- int congestion_control_on_log(void *userdata, int level, const char* file, int line, const char* fmt, va_list vl){
- videortp_t *vrtp = (videortp_t *)userdata;
- int n;
- n = vsnprintf(NULL, 0, fmt, vl);
- if (DEBUG_CC && n > 0 && level >= 1 && vrtp) {
- char *buf = (char*)_alloca((size_t)(n+3));
- vsprintf(buf, fmt, vl);
- rtpDbg(vrtp,"%s.", buf);
- }
- }
- /* 发送端回调。运行在sim_heartbeat方法调用线程。sim_send_video->cc缓存,然后sim_heartbeat->pacing判断可以发送->回调 */
- void congestion_control_sender_on_send_fragment(sim_segment_t* seg, void *userdata){
- videortp_t *vrtp = (videortp_t *)userdata;
-
- if(DEBUG_TX){
- rtpDbg(vrtp,"%s:%d: congestion_control_sender_on_send_fragment.", __FILE__, __LINE__);
- }
- sender_h264_packetize_nal(vrtp, seg->index, seg->total, seg->key_frame, seg->payload_type, seg->data, seg->data_size);
- }
- /* 发送端回调。运行在sim_heartbeat方法调用线程。 sim_heartbeat->cc判断带宽估计是否变化->回调 */
- /* 或者sim_recv_bitrate_feedback调用线程 . sim_recv_bitrate_feedback->cc判断带宽估计是否变化->回调 */
- /*bw 估计码率,单位:kbps*/
- void congestion_control_sender_on_change_bitrate(uint32_t bw, int lost, void *userdata){
- videortp_t *vrtp = (videortp_t *)userdata;
- if(DEBUG_CC){
- rtpDbg(vrtp,"%s:%d: congestion_control_sender_on_change_bitrate bw: %d lost: %d.", __FILE__, __LINE__, bw, lost);
- }
-
- //回调时编码器可能未创建
- if (vrtp->encoder) {
- video_encoder_api_on_bitrate_updated(vrtp->encoder, bw*1000, lost, 0);
- }
- }
- /* 接收端回调。运行在sim_heartbeat方法调用线程,sim_heartbeat->cc判断需要发送remb->回调 */
- void congestion_control_receiver_on_send_bitrate_feedback(uint32_t estimate_bitrate, void *userdata){
- videortp_t *vrtp = (videortp_t *)userdata;
- if(DEBUG_CC){
- rtpDbg(vrtp,"%s:%d: congestion_control_receiver_on_send_bitrate_feedback estimate_bitrate: %d.", __FILE__, __LINE__, estimate_bitrate);
- }
- video_stats_receiver_on_report_cc_bitrate(estimate_bitrate);
-
- rtp_session_send_rtcp_fb_tmmbr(vrtp->rtp_sess, estimate_bitrate);
- vrtp->send_cc_feedback = TRUE;
- }
- void congestion_control_create(videortp_t *vrtp, const videortp_config_t *config){
- int max_bitrate, target_bitrate, min_bitrate;
- get_start_config_bitrate(config, &max_bitrate, &target_bitrate, &min_bitrate);
- {
- sim_callback_t callback = {0};
- callback.userdata = vrtp;
- callback.log_cb = &congestion_control_on_log;
- callback.send_fragment_cb = &congestion_control_sender_on_send_fragment;
- callback.change_bitrate_cb = &congestion_control_sender_on_change_bitrate;
- callback.send_bitrate_feedback_cb = &congestion_control_receiver_on_send_bitrate_feedback;
- sim_init(gcc_transport, 0, min_bitrate, target_bitrate, max_bitrate, &callback);
- }
- rtpDbg(vrtp,"congestion_control_create min_bitrate: %d target_bitrate: %d max_bitrate: %d.", min_bitrate, target_bitrate, max_bitrate);
- }
- void congestion_control_destroy(videortp_t *vrtp){
- sim_destroy();
- rtpDbg(vrtp,"congestion_control_destroy.");
- }
- /******************************congestion control处理 end***************************/
- #if 0
- #endif
- /******************************x264 encoder处理 start***************************/
- #ifndef IDR_INTERVAL
- #define IDR_INTERVAL 8
- #endif
- #ifndef NAL_TIMESTAP_ENC
- #define NAL_TIMESTAP_ENC 3000
- #endif
- #ifndef SEND_WIDTH
- #define SEND_WIDTH 320
- #endif
- #ifndef SEND_HEIGHT
- #define SEND_HEIGHT 320
- #endif
- #ifndef SEND_FPS
- #define SEND_FPS 15
- #endif
- #ifndef SEND_BITRATE
- #define SEND_BITRATE 180*1000
- #endif
- #ifndef RC_MARGIN
- #define RC_MARGIN 10000
- #endif
- #define DEFAULT_MAX_PAYLOAD_SIZE 1440
- static int max_payload_size = DEFAULT_MAX_PAYLOAD_SIZE;
- int x264_encoder_get_payload_max_size(){
- return max_payload_size;
- }
- static void x264_encoder_set_linephone_param(x264_param_t* params)
- {
- float bitrate;
- int csp = X264_CSP_I420;
- int iframerate = REC_COMMON_VIDEO_FPS_NUM;
- params->i_threads=1;
- params->i_sync_lookahead=0;
- params->i_width = SEND_WIDTH;
- params->i_height = SEND_HEIGHT;
- params->i_fps_num=(int)iframerate;
- params->i_fps_den=1;
- params->i_slice_max_size=x264_encoder_get_payload_max_size()-100; /*-100 security margin*/
- params->i_level_idc=13;
- bitrate=(float)SEND_BITRATE*0.92;
- if (bitrate>RC_MARGIN)
- bitrate-=RC_MARGIN;
- #ifndef ANDROID
- params->rc.i_rc_method = X264_RC_ABR;
- params->rc.i_bitrate=(int)(bitrate/1000);
- params->rc.f_rate_tolerance=0.1;
- params->rc.i_vbv_max_bitrate=(int) ((bitrate+RC_MARGIN/2)/1000);
- params->rc.i_vbv_buffer_size=params->rc.i_vbv_max_bitrate;
- params->rc.f_vbv_buffer_init=0.5;
- #else
- params.rc.i_rc_method = X264_RC_CQP;
- params.rc.i_bitrate=(int)(bitrate/1000);
- #endif
- params->rc.i_lookahead=0;
- params->b_repeat_headers=1;
- params->b_annexb=0;
- //these parameters must be set so that our stream is baseline
- params->analyse.b_transform_8x8 = 0;
- params->b_cabac = 0;
- params->i_cqm_preset = X264_CQM_FLAT;
- params->i_bframe = 0;
- params->analyse.i_weighted_pred = X264_WEIGHTP_NONE;
- }
- static void x264_encoder_set_param_t(x264_param_t* params)
- {
- float bitrate;
- int csp = X264_CSP_I420;
- int iframerate = REC_COMMON_VIDEO_FPS_NUM;
- x264_param_default(params);
- x264_param_default_preset(params, "slow" , "zerolatency" );
- params->i_threads=1;
- params->i_sync_lookahead=0;
- params->i_width = SEND_WIDTH;
- params->i_height = SEND_HEIGHT;
- params->i_fps_num = iframerate;
- params->i_fps_den = 1;
- params->i_slice_max_size=x264_encoder_get_payload_max_size()-100; /*-100 security margin*/
- bitrate=(float)SEND_BITRATE*0.92;
- if (bitrate>RC_MARGIN){
- bitrate-=RC_MARGIN;
- }
- // rc
- params->rc.i_rc_method = X264_RC_ABR;
- params->rc.i_bitrate = (int)bitrate/1000;
- //must i_vbv_max_bitrate <= i_bitrate reconfig available
- params->rc.i_vbv_max_bitrate = (int)((bitrate)/1000) ;
- params->rc.i_vbv_buffer_size = (int)((bitrate*2)/1000) ;
- params->rc.f_vbv_buffer_init=0.5;
- params->rc.b_mb_tree=0;//
- params->rc.f_rf_constant = 25;
- params->rc.f_rf_constant_max = 45;
- params->rc.f_rate_tolerance=0.1;
- params->rc.b_stat_write = 1;
- params->rc.i_lookahead=0;
- params->i_keyint_max = iframerate * 2;
- params->i_keyint_min = iframerate * 2;
- params->b_repeat_headers = 1; //
- params->b_annexb= 1;
- params->b_cabac = 1;
- params->i_cqm_preset = X264_CQM_FLAT;
- params->i_bframe = 0;
- params->analyse.i_weighted_pred = X264_WEIGHTP_NONE;
- params->i_csp=csp;
- params->i_level_idc = 30;
- x264_param_apply_profile(params, x264_profile_names[0]);
-
- params->i_log_level = X264_LOG_WARNING;
- }
- void x264_encoder_create(videortp_t *vrtp, const videortp_config_t *config){
- x264_param_t params = {0};
- x264_param_t params_print = {0};
-
- x264_encoder_set_param_t(¶ms);
- vrtp->enc_params = x264_encoder_open(¶ms);
- x264_encoder_parameters(vrtp->enc_params, ¶ms_print);
- rtpDbg(vrtp,"x264_encoder_create bit_rate: %d kb/s, i_rc_method: %d ", params_print.rc.i_bitrate, params_print.rc.i_rc_method);
- rtpDbg(vrtp,"x264_encoder_create i_vbv_max_bitrate: %d kb/s, i_vbv_buffer_size: %d ", params_print.rc.i_vbv_max_bitrate, params_print.rc.i_vbv_buffer_size);
- rtpDbg(vrtp,"x264_encoder_create keyint_max: %d, i_keyint_min: %d ", params_print.i_keyint_max, params_print.i_keyint_min);
- }
- void x264_encoder_destroy(videortp_t *vrtp){
- if (vrtp->enc_params){
- x264_encoder_close(vrtp->enc_params);
- }
- rtpDbg(vrtp,"x264_encoder_destroy.");
- }
- /******************************x264 encoder处理 end***************************/
- #if 0
- #endif
- /******************************ffmpeg encoder处理 start***************************/
- void ffmpeg_encoder_on_encoder_encoded_image(const EncodedImage *encoded_image, void *userdata){
- int i;
- videortp_t *vrtp = (videortp_t *)userdata;
-
- if (encoded_image != NULL && vrtp != NULL) {
- if(DEBUG_TX){
- rtpDbg(vrtp,"%s:%d: ffmpeg_encoder_on_encoder_encoded_image key: %d len: %d qp: %d, PT:%u.", __FILE__, __LINE__,
- encoded_image->key_frame, encoded_image->size_, encoded_image->qp_, encoded_image->pt_);
- rtpDbg(vrtp,"%s:%d: ffmpeg_encoder_on_encoder_encoded_image encode_start_ms: %I64d encode_finish_ms: %I64d fragmentationSize: %d.", __FILE__, __LINE__,
- encoded_image->encode_start_ms, encoded_image->encode_finish_ms, encoded_image->fragmentation_header_.fragmentationVectorSize);
-
- }
- if(DEBUG_TX){
- for (i = 0;i < encoded_image->fragmentation_header_.fragmentationVectorSize;++i){
- rtpDbg(vrtp,"%s:%d: ffmpeg_encoder_on_encoder_encoded_image index: %d fragmentationLength: %d.", __FILE__, __LINE__,
- i, encoded_image->fragmentation_header_.fragmentationLength[i]);
- }
- }
- video_stats_sender_on_encoded_frame(encoded_image->encode_finish_ms,
- encoded_image->encode_finish_ms - encoded_image->encode_start_ms, encoded_image->key_frame);
-
- //采用cc控制发送
- if(vrtp->remote_support_cc){
- sim_send_video((EncodedImage *)encoded_image);
- }
- //不采用cc直接发送
- else {
- int use_fragment_send = 1;
- //采用新分片发送
- if (use_fragment_send){
- for (i = 0;i < encoded_image->fragmentation_header_.fragmentationVectorSize;++i){
- sender_h264_packetize_nal(vrtp, i,
- encoded_image->fragmentation_header_.fragmentationVectorSize,
- encoded_image->key_frame,
- encoded_image->pt_,
- &(encoded_image->encoded_data_[encoded_image->fragmentation_header_.fragmentationOffset[i]]),
- encoded_image->fragmentation_header_.fragmentationLength[i]);
- }
- }
- //采用旧分片发送
- else {
- if (encoded_image->pt_ == REC_COMMON_VIDEO_PT){
- sender_custom_h264_packetize_and_send(vrtp, encoded_image->key_frame, encoded_image->pt_,
- encoded_image->encoded_data_, encoded_image->size_);
- } else {
- for (i = 0;i < encoded_image->fragmentation_header_.fragmentationVectorSize;++i){
- sender_h264_packetize_nal(vrtp, i,
- encoded_image->fragmentation_header_.fragmentationVectorSize,
- encoded_image->key_frame,
- encoded_image->pt_,
- &(encoded_image->encoded_data_[encoded_image->fragmentation_header_.fragmentationOffset[i]]),
- encoded_image->fragmentation_header_.fragmentationLength[i]);
- }
- }
- }
- }
- }
- }
- void ffmpeg_encoder_create(videortp_t *vrtp, const videortp_config_t *config){
- int max_bitrate, target_bitrate, min_bitrate;
- VideoEncoderObserver video_encoder_observer = {0};
- VideoEncoderConfig encoder_config = {0};
- VideoCodingLogCallBack log_func = {0};
- get_start_config_bitrate(config, &max_bitrate, &target_bitrate, &min_bitrate);
-
- video_encoder_observer.OnEncodedImage = &ffmpeg_encoder_on_encoder_encoded_image;
- video_encoder_observer.userdata = vrtp;
- log_func.log_fn = &video_coding_on_log;
- log_func.userdata = vrtp;
- vrtp->encoder = video_encoder_api_new(&video_encoder_observer, &log_func);
-
- encoder_config.color_space = VIDEO_FORMAT_I420;
- encoder_config.encode_id = CODEC_ID_H264;
- encoder_config.width = config->tx_width;
- encoder_config.height = config->tx_height;
- encoder_config.max_bitrate = max_bitrate/1000; //kbps
- encoder_config.target_bitrate = target_bitrate/1000; //kbps
- encoder_config.min_bitrate = min_bitrate/1000; //kbps
- encoder_config.max_framerate = config->fps_num;
- encoder_config.target_framerate = config->fps_num;
- encoder_config.min_framerate = config->fps_num > 3 ? 3 : config->fps_num;
- encoder_config.key_frame_interval = config->fps_num * 2;
- encoder_config.target_qp = 24;
- encoder_config.max_qp = 37;
- encoder_config.min_qp = 10;
- video_encoder_api_configure_encoder(vrtp->encoder, &encoder_config, get_mtu(config->mtu) - 5/*padding*/ - ((sizeof(h26x_hdr)-2 + 32/*rtp_header_extension_length*/)));
- //rtpDbg(vrtp,"ffmpeg_encoder_create color_space: %d encode_id: %d width: %d height: %d.",
- // encoder_config.color_space, encoder_config.encode_id, encoder_config.width, encoder_config.height);
- //rtpDbg(vrtp,"ffmpeg_encoder_create max_bitrate: %d min_bitrate: %d target_bitrate: %d.",
- // max_bitrate, min_bitrate, target_bitrate);
- //rtpDbg(vrtp,"ffmpeg_encoder_create min_framerate: %d key_frame_interval: %d target_qp: %d.",
- // encoder_config.min_framerate, encoder_config.key_frame_interval, encoder_config.target_qp);
- }
- void ffmpeg_encoder_destory(videortp_t *vrtp){
- if (vrtp->encoder != NULL) {
- video_encoder_api_stop(vrtp->encoder);
- video_encoder_api_destroy(vrtp->encoder);
- }
- //rtpDbg(vrtp,"ffmpeg_encoder_destory.");
- }
- /******************************ffmpeg encoder处理 end***************************/
- #if 0
- #endif
- /******************************jitter buffer处理 start***************************/
- int jitter_buffer_on_log(void *userdata, int level, const char* file, int line, const char* fmt, va_list vl){
- videortp_t *vrtp = (videortp_t *)userdata;
- int n;
- n = vsnprintf(NULL, 0, fmt, vl);
- if (DEBUG_RX && n > 0 && vrtp && level >= VIDEO_JBUFFER_DEBUG_TRACE) {
- char *buf = (char*)_alloca((size_t)(n+3));
- vsprintf(buf, fmt, vl);
- rtpDbg(vrtp,"%s.", buf);
- }
- }
- void jitter_buffer_create(videortp_t *vrtp, const videortp_config_t *config){
- VideoJBufferObserver video_jbuffer_observer;
- VideoJBufferLogCallBack log_func = {0};
-
- video_jbuffer_observer.OnReceiveEncodedImage = &receiver_h264_on_receive_encoded_image;
- video_jbuffer_observer.RequestKeyFrame = &receiver_standard_h264_on_jbuffer_request_key_frame;
- video_jbuffer_observer.userdata = vrtp;
- log_func.log_fn = &jitter_buffer_on_log;
- log_func.userdata = vrtp;
- vrtp->jbuffer = video_jbuffer_api_new(&video_jbuffer_observer, &log_func);
-
- //rtpDbg(vrtp,"jitter_buffer_create.");
- }
- void jitter_buffer_destory(videortp_t *vrtp){
- if (vrtp->jbuffer != NULL) {
- video_jbuffer_api_destroy(vrtp->jbuffer);
- }
- //rtpDbg(vrtp,"jitter_buffer_destory.");
- }
- /******************************jitter buffer处理 end***************************/
- static rtp_session_t *videortp_internal_create_rtp_session(const videortp_config_t *config)
- {
- rtp_session_t *rtp_sess;
- struct in_addr addr;
- int rc;
- addr.s_addr = config->local_ip;
- rc = rtp_session_create(inet_ntoa(addr), config->local_rtp_port, 2, &rtp_sess);
- if (rc != 0){
- return 0;
- }
- addr.s_addr = config->remote_ip;
- rtp_session_reset(rtp_sess, config->dir, inet_ntoa(addr), config->remote_rtp_port, config->remote_rtp_port+1);
- {
- // set to a larger recv buffer, so that it will not overflow
- int rtp_fd = -1/*INVALID_SOCKET*/;
- int buf_size = 1<<20;
- rtp_session_get_raw_fd(rtp_sess, &rtp_fd, NULL);
- if (rtp_fd != -1/*INVALID_SOCKET*/) {
- setsockopt(rtp_fd, SOL_SOCKET, SO_RCVBUF, (const char*)&buf_size, sizeof(buf_size));
- setsockopt(rtp_fd, SOL_SOCKET, SO_SNDBUF, (const char*)&buf_size, sizeof(buf_size));
- }
- }
- return rtp_sess;
- }
- int video_stats_on_log(void *userdata, int level, const char* file, int line, const char* fmt, va_list vl){
- videortp_t *vrtp = (videortp_t *)userdata;
- int n;
- n = vsnprintf(NULL, 0, fmt, vl);
- if (n > 0 && vrtp) {
- char *buf = (char*)_alloca((size_t)(n+3));
- vsprintf(buf, fmt, vl);
- rtpDbg(vrtp,"%s.", buf);
- }
- }
- /******************************对外api start***************************/
- int videortp_create(const videortp_config_t *config, videortp_t **p_rtp)
- {
- int i, rc;
- videortp_t *vrtp = ZALLOC_T(videortp_t);
- vrtp->prev_dec_ms = TimeInMilliseconds();
- vrtp->recv_cc_feedback_ms = TimeInMilliseconds();
- vrtp->send_cc_feedback = 0;
- vrtp->recv_cc_feedback = 0;
- vrtp->remote_support_cc = 0;
- memcpy((void *)(&vrtp->config), (const void *)config, sizeof(videortp_config_t));
- //rtpDbg(vrtp,"videortp_create local_pt: %d local_ip: %d local_rtp_port: %d.", config->local_pt, config->local_ip, config->local_rtp_port);
- //rtpDbg(vrtp,"videortp_create remote_pt: %d remote_ip: %d remote_rtp_port: %d.", config->remote_pt, config->remote_ip, config->remote_rtp_port);
- //rtpDbg(vrtp,"videortp_create tx_width: %d tx_height: %d.", config->tx_width, config->tx_height);
- //rtpDbg(vrtp,"videortp_create rx_width: %d rx_height: %d.", config->rx_width, config->rx_height);
- //rtpDbg(vrtp,"videortp_create capture_width: %d capture_height: %d.", config->capture_width, config->capture_height);
- //rtpDbg(vrtp,"videortp_create fps_num: %d bit_rate: %d dir: %d.", config->fps_num, config->bit_rate, config->dir);
- INIT_LIST_HEAD(&vrtp->free_part_list);
- for (i = 0; i < FRAME_WIN_SIZE; ++i) {
- rtpframe_t *frame = &vrtp->frame_win[i];
- INIT_LIST_HEAD(&frame->part_list);
- frame->id = i;
- }
- vrtp->delta_ts = VIDEO_CLOCK * config->fps_den / config->fps_num;
- vrtp->rtp_sess = videortp_internal_create_rtp_session(config);
- if (!vrtp->rtp_sess) {
- char strMessage[MAX_PATH] = { 0 };
- snprintf(strMessage, MAX_PATH, "video rtp create failed and local port is %d.", config->local_rtp_port);
- rtpLogevent(vrtp, 0, strMessage);
- goto on_error;
- }
- //else {
- // char strmsg[MAX_PATH] = { 0 };
- // _snprintf(strmsg, MAX_PATH, "video rtp create success and local port is %d.", config->local_rtp_port);
- // rtpLogevent(vrtp, 0, strmsg);
- //}
- {
- VideoStatsLogCallBack log_func;
- log_func.log_fn = &video_stats_on_log;
- log_func.userdata = vrtp;
- video_stats_init(&log_func);
- }
- jitter_buffer_create(vrtp, config);
- vrtp->rtp_header_extension = rtp_header_extension_api_new();
-
- if (config->dir & DIR_RX) {
- decoder_create(vrtp, config);
- video_debug_open_play_file();
- }
- if (config->dir & DIR_TX) {
- ffmpeg_encoder_create(vrtp, config);
- video_debug_open_record_file();
- vrtp->framenum = 0;
- }
- #ifdef _WIN32
- congestion_control_create(vrtp, config);
- #endif
- {
- h264_packetizer_cfg cfg;
- cfg.mtu = get_mtu(config->mtu);
- cfg.mode = H264_PACKETIZER_MODE_NON_INTERLEAVED;
- cfg.unpack_nal_start = 3;
- h264_packetizer_create(&cfg, &(vrtp->h264_packetizer));
- }
-
- *p_rtp = vrtp;
- return 0;
- on_error:
- videortp_destroy(vrtp);
- return -1;
- }
- void videortp_destroy(videortp_t *vrtp)
- {
- videortp_config_t *config;
- unsigned short ilocal_port = 0;
- if (!vrtp){
- return;
- }
- config = &vrtp->config;
- //rtpDbg(vrtp,"videortp_destroy.");
- receiver_clear_window(vrtp);
- while (!list_empty(&vrtp->free_part_list)) {
- rtpframe_part_t *part = list_first_entry(&vrtp->free_part_list, rtpframe_part_t, entry);
- list_del(&part->entry);
- free(part);
- }
- #ifdef _WIN32
- congestion_control_destroy(vrtp);
- #endif
- video_stats_uninit();
- jitter_buffer_destory(vrtp);
- rtp_header_extension_api_destroy(vrtp->rtp_header_extension);
- h264_packetizer_destroy(vrtp->h264_packetizer);
-
- rtp_session_get_local_rtp_port(vrtp->rtp_sess, &ilocal_port);
-
- rtp_session_destroy(vrtp->rtp_sess);
- //{
- // char strmsg[MAX_PATH] = { 0 };
- // _snprintf(strmsg, MAX_PATH, "video rtp destroy and local port is %u.", ilocal_port);
- // rtpLogevent(vrtp, 1, strmsg);
- //}
- vrtp->rtp_sess = NULL;
- if (config->dir & DIR_RX) {
- decoder_destroy(vrtp);
-
- video_debug_close_play_file();
- }
- if (config->dir & DIR_TX) {
- ffmpeg_encoder_destory(vrtp);
- video_debug_close_record_file();
- }
- free(vrtp);
- }
- int videortp_start(videortp_t *vrtp)
- {
- int rc;
- ReceiverConfigStats receiver_config_stats;
- SenderConfigStats sender_config_stats;
- int64_t now = TimeInMilliseconds();
- vrtp->rtp_start_ms = now;
-
- video_jbuffer_api_start(vrtp->jbuffer);
- if (vrtp->config.dir & DIR_RX) {
- #ifdef _WIN32
- vrtp->evt = CreateEventA(NULL, FALSE, FALSE, NULL);
- vrtp->recv_thread = (HANDLE)_beginthreadex(NULL, 0, &recv_proc, vrtp, 0, NULL);
- #else
- sem_init(&vrtp->sem_evt, 0, 0);
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- struct sched_param param;
- param.sched_priority = sched_get_priority_max(SCHED_RR);
- pthread_attr_setschedpolicy(&attr, SCHED_RR);
- pthread_attr_setschedparam(&attr, ¶m);
- pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
- int err = pthread_create(&vrtp->recv_threadid, NULL, recv_proc, vrtp);
- if (0 != err) {
- rtpDbg(vrtp,"create vrtp recv thread failed for %s.", strerror(errno));
- }
- #endif
- }
- receiver_config_stats.remote_pt = vrtp->config.remote_pt;
- receiver_config_stats.local_ip = vrtp->config.local_ip;
- receiver_config_stats.local_rtp_port = vrtp->config.local_rtp_port;
- receiver_config_stats.rx_width = vrtp->config.rx_width;
- receiver_config_stats.rx_height = vrtp->config.rx_height;
- receiver_config_stats.bit_rate = vrtp->config.bit_rate;
- video_stats_receiver_on_started(now, &receiver_config_stats);
- sender_config_stats.local_pt = vrtp->config.local_pt;
- sender_config_stats.remote_ip = vrtp->config.remote_ip;
- sender_config_stats.remote_rtp_port = vrtp->config.remote_rtp_port;
- sender_config_stats.mtu = vrtp->config.mtu;
- sender_config_stats.tx_height = vrtp->config.tx_height;
- sender_config_stats.tx_width = vrtp->config.tx_width;
- sender_config_stats.capture_width = vrtp->config.capture_width;
- sender_config_stats.capture_height = vrtp->config.capture_height;
- sender_config_stats.fps_den = vrtp->config.fps_den;
- sender_config_stats.fps_num = vrtp->config.fps_num;
- sender_config_stats.fps_num = vrtp->config.fps_num;
- sender_config_stats.bit_rate = vrtp->config.bit_rate;
- video_stats_sender_on_started(now, &sender_config_stats);
- return 0;
- }
- void videortp_stop(videortp_t* vrtp)
- {
- int64_t now = TimeInMilliseconds();
- //rtpDbg(vrtp,"start call videortp_stop.");
- #ifdef _WIN32
- if (vrtp->evt) {
- SetEvent(vrtp->evt);
- if (vrtp->recv_thread) {
- WaitForSingleObject(vrtp->recv_thread, INFINITE);
- CloseHandle(vrtp->recv_thread);
- vrtp->recv_thread = NULL;
- }
- CloseHandle(vrtp->evt);
- vrtp->evt = NULL;
- }
- #else
- if (&vrtp->sem_evt) {
- sem_post(&vrtp->sem_evt);
- if (0 != vrtp->recv_threadid) {
- if (0 == pthread_join(vrtp->recv_threadid, NULL)){
- vrtp->recv_threadid = 0;
- }
- else {
- rtpDbg(vrtp, "%s:%d vrtp receive thread thread join failed for %s.", __FUNCTION__, __LINE__, strerror(errno));
- }
- }
- sem_destroy(&vrtp->sem_evt);
- }
- #endif
- video_stats_receiver_on_stopped(now);
- video_stats_sender_on_stopped(now);
-
- video_jbuffer_api_stop(vrtp->jbuffer);
- }
- int videortp_send_frame(videortp_t *vrtp, const video_frame *frame)
- {
- if (vrtp && (vrtp->config.dir & DIR_TX)) {
- int64_t now;
- if(DEBUG_TX){
- rtpDbg(vrtp,"%s:%d: videortp_send_frame width: %d height: %d format: %d.", __FILE__, __LINE__, frame->width, frame->height, frame->format);
- }
-
- if (VIDEO_FORMAT_RGB24 != frame->format)
- {
- unsigned char *video_debug_buf;
- int length = frame->width*frame->height*3/2;
- video_debug_buf = (unsigned char *)malloc(length);
- yuv_buffers_combine_to_one(frame, video_debug_buf);
- video_debug_write_record_file(VIDEO_CAPTURE_OUT, video_debug_buf, length);
- free(video_debug_buf);
- }
- if (vrtp->force_key_frames) {
- video_encoder_api_send_key_frame(vrtp->encoder);
- vrtp->force_key_frames = 0;
- if(DEBUG_TX){
- rtpDbg(vrtp,"%s:%d: videortp_send_frame force_key_frames.", __FILE__, __LINE__);
- }
- }
- //在编码器中固定i帧间隔为2s,不再需要自己主动设置了
- #if 0
- else {
- int start_key_interval = vrtp->config.fps_num / vrtp->config.fps_den / 2;
- if (start_key_interval == 0)
- start_key_interval = 1;
- if (vrtp->framenum/start_key_interval <= FIRST_KEY_FRAME_SIZE) {
- if (vrtp->framenum % start_key_interval == 0) {
- video_encoder_api_send_key_frame(vrtp->encoder);
- if(DEBUG_TX){
- rtpDbg(vrtp,"%s:%d: videortp_send_frame framenum: %d force_key_frames.", __FILE__, __LINE__, vrtp->framenum);
- }
- }
- }
- }
- #endif
-
- video_encoder_api_on_frame(vrtp->encoder, vrtp->config.local_pt, frame);
- vrtp->framenum++;
- //从未收到cc_feedback估计带宽,远端不支持流量控制,将码率设为配置值
- #ifdef _WIN32
- now = TimeInMilliseconds();
- if ((vrtp->recv_cc_feedback == FALSE) && (now - vrtp->recv_cc_feedback_ms >= 10 * 1000)) {
- rtpDbg(vrtp, "videortp_send_frame, never receive cc feedback, remote don't support .");
- sim_recv_bitrate_feedback(vrtp->config.bit_rate/*bps*/);
- vrtp->recv_cc_feedback = TRUE;
- }
- #endif
- } else {
- return -1;
- }
- return 0;
- }
- int videortp_send_yuvframe(videortp_t *vrtp, const video_frame *vframe)
- {
- videortp_send_frame(vrtp, vframe);
- //static int itest = 0;
- //if (itest == 0) {
- // video_frame_save_bmpfile("videortp_send_yuvframe.bmp", vframe);
- // itest++;
- //}
- return 0;
- }
- int videortp_reconfig_local_pt(videortp_t *vrtp, unsigned int local_pt)
- {
- //rtpDbg(vrtp,"videortp_reconfig_local_pt:%u .", local_pt);
- vrtp->config.local_pt = local_pt;
- }
- bool videortp_thread_valid(videortp_t* vrtp)
- {
- bool bret = true;
- #ifdef _WIN32
- bret = vrtp->recv_thread != NULL ? true : false;
- #else
- bret = vrtp->recv_threadid != 0 ? true : false;
- #endif
- return bret;
- }
- int videortp_force_key_frame(videortp_t *vrtp)
- {
- int iret = -1;
- if (videortp_thread_valid(vrtp))
- {
- receiver_force_key_frame(vrtp);
- iret = 0;
- }
- return iret;
- }
- /******************************对外api end***************************/
|