📄 rtp_pck_3gpp.c
字号:
builder->bytesInPacket += size; offset += size; rtp_ts += 160; assert(builder->bytesInPacket<=builder->Path_MTU); /*take care of aggregation, flush if needed*/ if (builder->last_au_sn==builder->auh_size) rtp_evrc_smv_flush(builder); } return GF_OK;}GF_Err gp_rtp_builder_do_h264(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize){ GF_BitStream *bs; char hdr[2]; Bool Pbit; u32 offset, size, max_size; builder->rtp_header.TimeStamp = (u32) builder->sl_header.compositionTimeStamp; /*the H263 hinter doesn't perform inter-sample concatenation*/ if (!data) return GF_OK; Pbit = 1; /*skip 16 0'ed bits of start code*/ offset = 2; data_size -= 2; max_size = builder->Path_MTU - 2; while(data_size > 0) { if(data_size > max_size){ size = max_size; builder->rtp_header.Marker = 0; }else{ size = data_size; builder->rtp_header.Marker = 1; } data_size -= size; /*create new RTP Packet */ builder->rtp_header.SequenceNumber += 1; builder->OnNewPacket(builder->cbk_obj, &builder->rtp_header); bs = gf_bs_new(hdr, 2, GF_BITSTREAM_WRITE); gf_bs_write_int(bs, 0, 5); gf_bs_write_int(bs, Pbit, 1); gf_bs_write_int(bs, 0, 10); gf_bs_del(bs); /*add header*/ builder->OnData(builder->cbk_obj, (char*) hdr, 2, 1); /*add payload*/ if (builder->OnDataReference) builder->OnDataReference(builder->cbk_obj, size, offset); else builder->OnData(builder->cbk_obj, data + offset, size, 0); builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header); offset += size; Pbit = 0; } return GF_OK;}GF_Err gp_rtp_builder_do_tx3g(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize, u32 duration, u8 descIndex){ GF_BitStream *bs; char *hdr; u32 samp_size, txt_size, pay_start, hdr_size, txt_done, cur_frag, nb_frag; Bool is_utf_16 = 0; if (!data) { /*flush packet*/ if (builder->bytesInPacket) { builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header); builder->bytesInPacket = 0; } return GF_OK; } /*cfg packet*/ txt_size = data[0]; txt_size <<= 8; txt_size |= (unsigned char) data[1]; /*remove BOM*/ pay_start = 2; if (txt_size>2) { /*seems 3GP only accepts BE UTF-16 (no LE, no UTF32)*/ if (((u8) data[2]==(u8) 0xFE) && ((u8) data[3]==(u8) 0xFF)) { is_utf_16 = 1; pay_start = 4; txt_size -= 2; } } samp_size = data_size - pay_start; /*if TTU does not fit in packet flush packet*/ if (builder->bytesInPacket && (builder->bytesInPacket + 3 + 6 + samp_size > builder->Path_MTU)) { builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header); builder->bytesInPacket = 0; } /*first TTU in packet*/ if (!builder->bytesInPacket) { builder->rtp_header.TimeStamp = (u32) builder->sl_header.compositionTimeStamp; builder->rtp_header.Marker = 1; builder->rtp_header.SequenceNumber += 1; builder->OnNewPacket(builder->cbk_obj, &builder->rtp_header); } /*fits entirely*/ if (builder->bytesInPacket + 3 + 6 + samp_size <= builder->Path_MTU) { bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_bs_write_int(bs, is_utf_16, 1); gf_bs_write_int(bs, 0, 4); gf_bs_write_int(bs, 1, 3); gf_bs_write_u16(bs, 8 + samp_size); gf_bs_write_u8(bs, descIndex); gf_bs_write_u24(bs, duration); gf_bs_write_u16(bs, txt_size); gf_bs_get_content(bs, &hdr, &hdr_size); gf_bs_del(bs); builder->OnData(builder->cbk_obj, (char *) hdr, hdr_size, 0); builder->bytesInPacket += hdr_size; free(hdr); if (txt_size) { if (builder->OnDataReference) { builder->OnDataReference(builder->cbk_obj, samp_size, pay_start); } else { builder->OnData(builder->cbk_obj, data + pay_start, samp_size, 0); } builder->bytesInPacket += samp_size; } /*disable aggregation*/ if (!(builder->flags & GP_RTP_PCK_USE_MULTI)) { builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header); builder->bytesInPacket = 0; } return GF_OK; } /*doesn't fit and already data, flush packet*/ if (builder->bytesInPacket) { builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header); builder->rtp_header.TimeStamp = (u32) builder->sl_header.compositionTimeStamp; /*split unit*/ builder->rtp_header.Marker = 0; builder->rtp_header.SequenceNumber += 1; builder->OnNewPacket(builder->cbk_obj, &builder->rtp_header); builder->bytesInPacket = 0; } /*write all type2 units (text only) - FIXME: split at char boundaries, NOT SUPPORTED YET*/ txt_done = 0; nb_frag = 1; /*all fragments needed for Type2 units*/ while (txt_done + (builder->Path_MTU-10) < txt_size) { txt_done += (builder->Path_MTU-10); nb_frag += 1; } /*all fragments needed for Type3/4 units*/ txt_done = txt_size; while (txt_done + (builder->Path_MTU-7) < samp_size) { txt_done += (builder->Path_MTU-7); nb_frag += 1; } cur_frag = 0; txt_done = 0; while (txt_done<txt_size) { u32 size; if (txt_done + (builder->Path_MTU-10) < txt_size) { size = builder->Path_MTU-10; } else { size = txt_size - txt_done; } bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_bs_write_int(bs, is_utf_16, 1); gf_bs_write_int(bs, 0, 4); gf_bs_write_int(bs, 2, 3); gf_bs_write_u16(bs, 9 + size); gf_bs_write_int(bs, nb_frag, 4); gf_bs_write_int(bs, cur_frag, 4); gf_bs_write_u24(bs, duration); gf_bs_write_u8(bs, descIndex); /*SLEN is the full original length minus text len and BOM (put here for buffer allocation purposes)*/ gf_bs_write_u16(bs, samp_size); gf_bs_get_content(bs, &hdr, &hdr_size); gf_bs_del(bs); builder->OnData(builder->cbk_obj, (char *) hdr, hdr_size, 0); builder->bytesInPacket += hdr_size; free(hdr); if (builder->OnDataReference) { builder->OnDataReference(builder->cbk_obj, size, pay_start + txt_done); } else { builder->OnData(builder->cbk_obj, data + pay_start + txt_done, size, 0); } builder->bytesInPacket += size; cur_frag++; /*flush packet*/ if (cur_frag == nb_frag) { txt_done = txt_size; if (pay_start + txt_done == data_size) { builder->rtp_header.Marker = 1; builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header); builder->bytesInPacket = 0; } } else { txt_done += size; builder->rtp_header.Marker = 0; builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header); builder->rtp_header.SequenceNumber += 1; builder->OnNewPacket(builder->cbk_obj, &builder->rtp_header); builder->bytesInPacket = 0; } } txt_done = txt_size; /*write all modifiers - OPT: split at modifiers boundaries*/ while (txt_done<samp_size) { u32 size, type; type = (txt_done == txt_size) ? 3 : 4; if (txt_done + (builder->Path_MTU-7) < samp_size) { size = builder->Path_MTU-10; } else { size = samp_size - txt_done; } bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_bs_write_int(bs, is_utf_16, 1); gf_bs_write_int(bs, 0, 4); gf_bs_write_int(bs, type, 3); gf_bs_write_u16(bs, 6 + size); gf_bs_write_int(bs, nb_frag, 4); gf_bs_write_int(bs, cur_frag, 4); gf_bs_write_u24(bs, duration); gf_bs_get_content(bs, &hdr, &hdr_size); gf_bs_del(bs); builder->OnData(builder->cbk_obj, (char *) hdr, hdr_size, 0); builder->bytesInPacket += hdr_size; free(hdr); if (builder->OnDataReference) { builder->OnDataReference(builder->cbk_obj, size, pay_start + txt_done); } else { builder->OnData(builder->cbk_obj, data + pay_start + txt_done, size, 0); } builder->bytesInPacket += size; cur_frag++; if (cur_frag==nb_frag) { builder->rtp_header.Marker = 1; builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header); builder->bytesInPacket = 0; } else { builder->rtp_header.Marker = 0; builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header); builder->rtp_header.SequenceNumber += 1; builder->OnNewPacket(builder->cbk_obj, &builder->rtp_header); builder->bytesInPacket = 0; } txt_done += size; } return GF_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -