void Rtmp::sendTag(FlvTag &tag) { if( ! RTMP_IsConnected(m_rtmp) || RTMP_IsTimedout(m_rtmp) ) { qDebug() << "RTMP error"; exit(0); } RTMP_Write(m_rtmp,tag.constData(),tag.size()); // Handle RTMP ping and such fd_set sockset; struct timeval timeout = {0,0}; FD_ZERO(&sockset); FD_SET(RTMP_Socket(m_rtmp), &sockset); register int result = select(RTMP_Socket(m_rtmp) + 1, &sockset, NULL, NULL, &timeout); if (result == 1 && FD_ISSET(RTMP_Socket(m_rtmp), &sockset) ) { // qDebug() << "RTMP_ReadPacket"; RTMP_ReadPacket(m_rtmp, &m_rtmpPacket); if( ! RTMPPacket_IsReady(&m_rtmpPacket) ) { qDebug() << "Received RTMP packet"; RTMP_ClientPacket(m_rtmp,&m_rtmpPacket); RTMPPacket_Free(&m_rtmpPacket); } } }
static int RtmpPktHandle(RTMP_SESSION *pSession) { RTMP *pRtmp = pSession->prtmp; RTMPPacket *pPkt = pSession->pPkt; int readok = FALSE; if(!RTMP_IsConnected(pRtmp)) { return -1; } /* 收包逻辑处理 */ while(readok = RTMP_ReadPacket(pRtmp, pPkt)) { if(pPkt->m_nBodySize != pPkt->m_nBytesRead) { continue; } RtmpDispatchPkt(pSession, pPkt); } return 0; }
int CRtmpdSession::ReadPacket() {_STT(); // Ensure we have a session if ( !isSession() ) return -1; // Ensure we still have a connection if ( !RTMP_IsConnected( &m_session ) ) { Destroy(); return -2; } // end if // Free previous packet if needed if ( m_nPacketReady ) oexZero( m_packet ), // RTMPPacket_Free( &m_packet ), // +++ No, don't do that m_nPacketReady = 0; // Non-blocking? if ( m_nNonBlockingMode ) { fd_set rset; FD_ZERO( &rset ); FD_SET( m_session.m_sb.sb_socket, &rset ); struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 0; int ret = select( m_session.m_sb.sb_socket + 1, &rset, NULL, NULL, &tv ); if ( 0 > ret ) return -3; if ( !FD_ISSET( m_session.m_sb.sb_socket, &rset ) ) return 0; } // end if // See if we can get a packet if ( !RTMP_ReadPacket( &m_session, &m_packet ) || !RTMPPacket_IsReady( &m_packet ) ) return 0; // We have a packet m_nPacketReady = 1; return m_packet.m_packetType; }
void doServe(STREAMING_SERVER * server, // server socket and state (our listening socket) int sockfd // client connection socket ) { server->state = STREAMING_IN_PROGRESS; RTMP rtmp = { 0 }; /* our session with the real client */ RTMPPacket packet = { 0 }; // timeout for http requests fd_set fds; struct timeval tv; memset(&tv, 0, sizeof(struct timeval)); tv.tv_sec = 5; FD_ZERO(&fds); FD_SET(sockfd, &fds); if (select(sockfd + 1, &fds, NULL, NULL, &tv) <= 0) { RTMP_Log(RTMP_LOGERROR, "Request timeout/select failed, ignoring request"); goto quit; } else { RTMP_Init(&rtmp); rtmp.m_sb.sb_socket = sockfd; if (!RTMP_Serve(&rtmp)) { RTMP_Log(RTMP_LOGERROR, "Handshake failed"); goto cleanup; } } server->arglen = 0; while (RTMP_IsConnected(&rtmp) && RTMP_ReadPacket(&rtmp, &packet)) { if (!RTMPPacket_IsReady(&packet)) continue; ServePacket(server, &rtmp, &packet); RTMPPacket_Free(&packet); } cleanup: RTMP_LogPrintf("Closing connection... "); RTMP_Close(&rtmp); /* Should probably be done by RTMP_Close() ... */ rtmp.Link.playpath.av_val = NULL; rtmp.Link.tcUrl.av_val = NULL; rtmp.Link.swfUrl.av_val = NULL; rtmp.Link.pageUrl.av_val = NULL; rtmp.Link.app.av_val = NULL; rtmp.Link.flashVer.av_val = NULL; RTMP_LogPrintf("done!\n\n"); quit: if (server->state == STREAMING_IN_PROGRESS) server->state = STREAMING_ACCEPTING; return; }
int main(int argc, char* argv[]) { char c, *inFile; inFile = NULL; sc_frame_rect rect; #ifndef _WIN32 signal(SIGPIPE, sig_pipe_handler); #endif while ((c = getopt (argc, argv, "w:h:u:r:f:")) != -1) { switch (c) { case 'w': rect.width = (uint16_t) atoi(optarg); break; case 'h': rect.height = (uint16_t) atoi(optarg); break; case 'u': streamUri = optarg; break; case 'r': roomName = optarg; break; case 'f': inFile = optarg; break; } } int fd; if(inFile) { printf("Started streamer with width: %i, height: %i, URI: %s, roomName: %s, File: %s\n", rect.width, rect.height, streamUri, roomName, inFile); fd = open(inFile, O_RDONLY); } else { printf("Started streamer with width: %i, height: %i, URI: %s, roomName: %s \n", rect.width, rect.height, streamUri, roomName); fd = fileno(stdin); } // main processing loop while(TRUE) { sc_bytestream_packet packet = sc_bytestream_get_event(fd); sc_mouse_coords coords; sc_frame frame; if(streamer.rtmp_setup == 1 && (!RTMP_IsConnected(streamer.rtmp) || RTMP_IsTimedout(streamer.rtmp))) { #ifdef _WIN32 sc_streamer_die(); #else sc_streamer_reconnect(&streamer); #endif } RTMPPacket rp = { 0 }; if(streamer.rtmp_setup == 1 && streamer.so_name != NULL && streamer.have_inital_SO != 1 && RTMP_ReadPacket(streamer.rtmp, &rp)) { if (RTMPPacket_IsReady(&rp) && rp.m_packetType == RTMP_PACKET_TYPE_SHARED_OBJECT) { AVal SO_name; AMF_DecodeString(rp.m_body, &SO_name); streamer.so_version = AMF_DecodeInt32(rp.m_body+2+SO_name.av_len); streamer.have_inital_SO = 1; } } switch(packet.header.type) { case STARTVIDEO: capture_rect = rect; start_time_stamp = packet.header.timestamp; streamer = sc_streamer_init_video(streamUri, roomName, capture_rect, start_time_stamp); break; case STOPVIDEO: sc_streamer_stop_video(&streamer); sc_streamer_teardown_windows(); exit(1); break; case STARTCURSOR: start_time_stamp = packet.header.timestamp; streamer = sc_streamer_init_cursor(streamUri, roomName, start_time_stamp); break; case STOPCURSOR: sc_streamer_stop_cursor(&streamer); sc_streamer_teardown_windows(); exit(1); break; case MOUSE: coords = parse_mouse_coords(packet); streamer.so_version++; sc_streamer_send_mouse_data(&streamer, &coords, packet.header.timestamp); break; case VIDEO: frame = parse_frame(packet); if((RTMP_IsConnected(streamer.rtmp) && !RTMP_IsTimedout(streamer.rtmp))) sc_streamer_send_frame(&streamer, &frame, packet.header.timestamp); free(frame.framePtr); break; case NO_DATA: default: exit(0); break; // maybe a wait is in order } } return 0; }