android librtmp 推送h264流 aac流 基本過程總結四 推流x264
阿新 • • 發佈:2019-01-04
{ RTMPPacket * packet; unsigned char * body; int i; int ret = 0; if (m_pRtmp == NULL) return -1; packet = (RTMPPacket *) malloc(RTMP_HEAD_SIZE + 1024); memset(packet, 0, RTMP_HEAD_SIZE); packet->m_body = (char *) packet + RTMP_HEAD_SIZE; body = (unsigned char *) packet->m_body; i = 0; body[i++] = 0x17; body[i++] = 0x00; body[i++] = 0x00; body[i++] = 0x00; body[i++] = 0x00; /*AVCDecoderConfigurationRecord*/ body[i++] = 0x01; body[i++] = sps[1]; body[i++] = sps[2]; body[i++] = sps[3]; body[i++] = 0xff; /*sps*/ body[i++] = 0xe1; body[i++] = (sps_len >> 8) & 0xff; body[i++] = sps_len & 0xff; memcpy(&body[i], sps, sps_len); i += sps_len; /*pps*/ body[i++] = 0x01; body[i++] = (pps_len >> 8) & 0xff; body[i++] = (pps_len) & 0xff; memcpy(&body[i], pps, pps_len); i += pps_len; packet->m_packetType = RTMP_PACKET_TYPE_VIDEO; packet->m_nBodySize = i; packet->m_nChannel = 0x04; packet->m_nTimeStamp = 0; packet->m_hasAbsTimestamp = 0; packet->m_headerType = RTMP_PACKET_SIZE_MEDIUM; packet->m_nInfoField2 = m_pRtmp->m_stream_id; if (RTMP_IsConnected(m_pRtmp)) { //呼叫傳送介面 int success = RTMP_SendPacket(m_pRtmp, packet, TRUE); if (success != 1) { dm_printf("send_video_sps_pps fail"); ret = -1; } } else ret = -1; free(packet); return ret; }
5.rtmp傳送普通的NAL
static int send_rtmp_video(RTMP* m_pRtmp, unsigned char *data, int data_len, int timestamp) { int type; RTMPPacket * packet; unsigned char * body; unsigned char* buffer = data; unsigned int length = data_len; int ret = 0; if (m_pRtmp == NULL) return -1; /*去掉幀界定符(這裡可能2種,但是sps or pps只能為 00 00 00 01)*/ if (buffer[2] == 0x00) { /*00 00 00 01*/ buffer += 4; length -= 4; } else if (buffer[2] == 0x01) { /*00 00 01*/ buffer += 3; length -= 3; } type = buffer[0] & 0x1f; packet = (RTMPPacket *) malloc(RTMP_HEAD_SIZE + length + 9); memset(packet, 0, RTMP_HEAD_SIZE); packet->m_body = (char *) packet + RTMP_HEAD_SIZE; packet->m_nBodySize = length + 9; /*send video packet*/ body = (unsigned char *) packet->m_body; memset(body, 0, length + 9); /*key frame*/ body[0] = 0x27; if (type == NAL_SLICE_IDR) //此為關鍵幀 { body[0] = 0x17; } body[1] = 0x01; /*nal unit*/ body[2] = 0x00; body[3] = 0x00; body[4] = 0x00; body[5] = (length >> 24) & 0xff; body[6] = (length >> 16) & 0xff; body[7] = (length >> 8) & 0xff; body[8] = (length) & 0xff; /*copy data*/ memcpy(&body[9], buffer, length); packet->m_nTimeStamp = timestamp; packet->m_hasAbsTimestamp = 0; packet->m_packetType = RTMP_PACKET_TYPE_VIDEO; packet->m_nInfoField2 = m_pRtmp->m_stream_id; packet->m_nChannel = 0x04; packet->m_headerType = RTMP_PACKET_SIZE_MEDIUM; if (RTMP_IsConnected(m_pRtmp)) { // 呼叫傳送介面 ret = RTMP_SendPacket(m_pRtmp, packet, TRUE); if (ret != 1) { dm_printf("send_rtmp_video fail"); ret = -1; } } else { dm_printf("send_rtmp_video RTMP is not ready"); ret = -1; } free(packet); return ret; }
6. 初始化rtmp
定義結構體
typedef struct rtmp_infor { char *aac_buf; char *x264_buf; int nal_len[20]; int nal_count; int audio_first; int video_first; int init_flag; RTMP *prtmp ; X264Args x264args; AudioEncodeFaac aacargs; }RTMPInfor;
int RTMP_Send_Init(char *url, int width, int height, int sample_rate, int channel) { int ret = 0; if (rtmp_infor.init_flag == 1) { dm_printf("RTMP_Send_Init again init"); return -1; } if (url == NULL) { dm_printf("url is NULL"); return -1; } if (width <= 0 || height <= 0 || channel <= 0) { dm_printf("width or height or channel is error"); return -1; } pthread_mutex_lock(&thread_lock_rtmp_send); memset(&rtmp_infor, 0, sizeof(rtmp_infor)); ret = RTMP_Connect(&rtmp_infor.prtmp, url); if (ret < 0) { dm_printf("RTMP_Connect fail"); goto end; } ret = Audio_Encode_Init_Faac(&rtmp_infor.aacargs, sample_rate, channel); if (ret < 0) { dm_printf("Audio_Encode_Init_Faac fail"); goto end; } ret = X264encode_Init_Args_ForRtmp(&rtmp_infor.x264args, NULL, width, height); if (ret < 0) { dm_printf("Audio_Encode_Init_Faac fail"); goto end; } rtmp_infor.aac_buf = (char *)malloc(NB_SAMPLE << channel); rtmp_infor.x264_buf = (char *)malloc(width * height * 3 >> 1); if (rtmp_infor.aac_buf == NULL || rtmp_infor.x264_buf == NULL) { dm_printf("aac_buf or 264_buf alloc fail"); ret = -1; goto end; } rtmp_infor.init_flag = 1; end: if (ret < 0) { X264encode_Finish_Args_ForRtmp(&rtmp_infor.x264args); Audio_Encode_Release_Faac(&rtmp_infor.aacargs); RTMP_Close(&rtmp_infor.prtmp); if (rtmp_infor.aac_buf != NULL) free(rtmp_infor.aac_buf); if (rtmp_infor.x264_buf != NULL) free(rtmp_infor.x264_buf); memset(&rtmp_infor, 0, sizeof(rtmp_infor)); } pthread_mutex_unlock(&thread_lock_rtmp_send); return ret; }