I’m building a streaming application that captures screen content and sends it to Twitch using RTMP protocol. The encoded video data gets processed by x264 and then transmitted to Twitch servers. While the servers accept my data stream, the video won’t play properly. It shows a brief loading screen before displaying error 2000 (network error). Here’s my current approach for handling the encoded frames:
int encoded_size = x264_encoder_encode(h264_encoder, &nal_units, &nal_count, &input_pic, &output_pic);
// Process each NAL unit based on its type
int pts_dts_offset = int(output_pic.i_pts - output_pic.i_dts);
pts_dts_offset = htonl(pts_dts_offset);
BYTE *offset_ptr = ((BYTE*)&pts_dts_offset) + 1;
FrameData frame_data;
bool has_video_frame = false;
uint8_t *sequence_params = NULL;
int sps_length = 0;
for (int j = 0; j < nal_count; j++) {
x264_nal_t ¤t_nal = nal_units[j];
if (current_nal.i_type == NAL_SPS) {
sps_length = current_nal.i_payload;
sequence_params = (uint8_t*)malloc(sps_length);
memcpy(sequence_params, current_nal.p_payload, sps_length);
} else if (current_nal.i_type == NAL_PPS) {
uint8_t *combined_data = (uint8_t*)malloc(current_nal.i_payload + sps_length);
memcpy(combined_data, sequence_params, sps_length);
memcpy(combined_data + sps_length, current_nal.p_payload, current_nal.i_payload);
frame_data = {current_nal.i_payload + sps_length, combined_data, current_nal.i_type};
video_queue->push(frame_data);
}
}
The processed data goes into this structure:
struct FrameData {
int data_size;
uint8_t* video_data;
int nal_type;
};
Then my broadcast module sends it via RTMP:
FrameData current_frame = video_queue->front();
video_queue->pop();
RTMPPacket *rtmp_packet = (RTMPPacket*)malloc(sizeof(RTMPPacket) + RTMP_MAX_HEADER_SIZE + current_frame.data_size + 9);
rtmp_packet->m_body = (char*)rtmp_packet + sizeof(RTMPPacket) + RTMP_MAX_HEADER_SIZE;
rtmp_packet->m_nBodySize = current_frame.data_size + 9;
unsigned char *packet_body = (unsigned char*)rtmp_packet->m_body;
packet_body[0] = (current_frame.nal_type == NAL_SLICE_IDR) ? 0x17 : 0x27;
packet_body[1] = 0x01;
packet_body[2] = 0x00;
packet_body[3] = 0x00;
packet_body[4] = 0x00;
memcpy(&packet_body[9], current_frame.video_data, current_frame.data_size);
RTMP_SendPacket(rtmp_connection, rtmp_packet, TRUE);
Twitch receives the stream at about 3kbps but won’t play the video. What could be wrong with my packet formatting?