static void *send_thread(void *data) { struct rtmp_stream *stream = data; bool disconnected = false; while (os_sem_wait(stream->send_sem) == 0) { struct encoder_packet packet; if (os_event_try(stream->stop_event) != EAGAIN) break; if (!get_next_packet(stream, &packet)) continue; if (send_packet(stream, &packet, false) < 0) { disconnected = true; break; } } if (!disconnected && !send_remaining_packets(stream)) disconnected = true; if (disconnected) { blog(LOG_INFO, "Disconnected from %s", stream->path.array); free_packets(stream); } if (os_event_try(stream->stop_event) == EAGAIN) { pthread_detach(stream->send_thread); obs_output_signal_stop(stream->output, OBS_OUTPUT_DISCONNECTED); } stream->active = false; return NULL; }
FXbool VorbisDecoder::init_decoder() { const FXuchar * data_ptr = get_packet_offset(); // Initialize Info init_info(); while(get_next_packet()) { if (is_vorbis_header()) { if (vorbis_synthesis_headerin(&info,&comment,&op)<0) { GM_DEBUG_PRINT("[vorbis] vorbis_synthesis_headerin failed\n"); return false; } } else { // First non header if (vorbis_synthesis_init(&dsp,&info)<0) return false; if (vorbis_block_init(&dsp,&block)<0) { vorbis_dsp_clear(&dsp); return false; } has_dsp=true; push_back_packet(); return true; } } vorbis_info_clear(&info); set_packet_offset(data_ptr); return true; }
static bool send_remaining_packets(struct rtmp_stream *stream) { struct encoder_packet packet; uint64_t max_ns = (uint64_t)stream->max_shutdown_time_sec * 1000000000; uint64_t begin_time_ns = os_gettime_ns(); if (!stream->sent_headers) { if (!send_headers(stream)) return false; } while (get_next_packet(stream, &packet)) { if (send_packet(stream, &packet, false, packet.track_idx) < 0) return false; /* Just disconnect if it takes too long to shut down */ if ((os_gettime_ns() - begin_time_ns) > max_ns) { info("Took longer than %d second(s) to shut down, " "automatically stopping connection", stream->max_shutdown_time_sec); return false; } } return true; }
static void *send_thread(void *data) { struct rtmp_stream *stream = data; os_set_thread_name("rtmp-stream: send_thread"); while (os_sem_wait(stream->send_sem) == 0) { struct encoder_packet packet; if (stopping(stream) && stream->stop_ts == 0) { break; } if (!get_next_packet(stream, &packet)) continue; if (stopping(stream)) { if (can_shutdown_stream(stream, &packet)) { obs_free_encoder_packet(&packet); break; } } if (!stream->sent_headers) { if (!send_headers(stream)) { os_atomic_set_bool(&stream->disconnected, true); break; } } if (send_packet(stream, &packet, false, packet.track_idx) < 0) { os_atomic_set_bool(&stream->disconnected, true); break; } } if (disconnected(stream)) { info("Disconnected from %s", stream->path.array); } else { info("User stopped the stream"); } RTMP_Close(&stream->rtmp); if (!stopping(stream)) { pthread_detach(stream->send_thread); obs_output_signal_stop(stream->output, OBS_OUTPUT_DISCONNECTED); } else { obs_output_end_data_capture(stream->output); } free_packets(stream); os_event_reset(stream->stop_event); os_atomic_set_bool(&stream->active, false); stream->sent_headers = false; return NULL; }
static bool send_remaining_packets(struct rtmp_stream *stream) { struct encoder_packet packet; while (get_next_packet(stream, &packet)) if (send_packet(stream, &packet, false) < 0) return false; return true; }
static bool send_remaining_packets(struct rtmp_stream *stream) { struct encoder_packet packet; if (!stream->sent_headers) send_headers(stream); while (get_next_packet(stream, &packet)) if (send_packet(stream, &packet, false, packet.track_idx) < 0) return false; return true; }
int send_next_packet(int sock, struct sockaddr_in out) { int pkt_len = 0; void *pkt = get_next_packet(sent_sequence, &pkt_len); if (pkt == NULL) { return 0; } mylog("[send data] %d %d (%d)\n", read_hseq(pkt), sent_sequence, pkt_len - sizeof(header)); if (sendto(sock, pkt, pkt_len, 0, (struct sockaddr *) &out, (socklen_t) sizeof(out)) < 0) { perror("sendto"); exit(1); } return 1; }
FXbool VorbisDecoder::find_stream_position() { const FXuchar * data_ptr = get_packet_offset(); FXint cb,lb=-1,tb=0; while(get_next_packet()) { if (is_vorbis_header()){ reset_decoder(); goto reset; } cb=vorbis_packet_blocksize(&info,&op); if (lb!=-1) tb+=(lb+cb)>>2; lb=cb; if (op.granulepos!=-1) { stream_position=op.granulepos-tb; set_packet_offset(data_ptr); return true; } } reset: set_packet_offset(data_ptr); return false; }
int main(int argc, char *argv[]){ void *this_arte_packet; this_arte_packet = malloc(MAX_PACKET_BYTES); int sourcename; packetType_t sourcetype; int ok_packet; int packet_count = 0; char blank_data[MAX_PACKET_BYTES]; //this_arte_packet = (void *)&(blank_data[0]); char input_filename[200], output_filename[200]; init_filenames(argc, argv, input_filename, output_filename, &sourcename, &sourcetype); printf("sourcename:%d sourcetype:%c spike_sourcetype:%c\n", sourcename, sourcetype, NETCOM_UDP_SPIKE); if(this_arte_packet == NULL){ printf("Memory error, sorry :[\n"); exit(1); } in_f = fopen(input_filename, "rb"); out_f = fopen(output_filename, "wb"); if(in_f == NULL) printf("Bad in file: %s\n", input_filename); if(out_f == NULL) printf("Bad out_file: %s\n", output_filename); if(in_f == NULL || out_f == NULL) exit(1); ok_packet = false; while(!ok_packet & (feof(in_f) == 0) ){ ok_packet = get_next_packet(this_arte_packet, sourcename, sourcetype); } printf("finished looking...\n"); fflush(stdout); write_file_header(this_arte_packet, argc, argv, sourcetype); printf("Finished writing file header.\n"); fflush(stdout); if( sourcetype == NETCOM_UDP_SPIKE){ spike_net_t* test_spike = (spike_net_t*)this_arte_packet; printf("test before first write_mwl: name:%d n_chans:%d\n", test_spike->name, test_spike->n_chans); } write_mwl(this_arte_packet, sourcetype); printf("Finished writing first packet with write_mwl.\n"); fflush(stdout); if( sourcetype == NETCOM_UDP_SPIKE){ spike_net_t* test_spike = (spike_net_t*)this_arte_packet; printf("test before loop: name:%d n_chans:%d\n", test_spike->name, test_spike->n_chans); } if(true){ while( feof(in_f) == 0){ ok_packet = get_next_packet(this_arte_packet, sourcename, sourcetype); if(verbose){ if (ok_packet){ printf("This packet was ok:\n");} else { printf("This packet was not ok:\n");} print_packet(this_arte_packet, sourcetype); } if(ok_packet){ fflush(out_f); //printf("in loop...\n"); if( sourcetype == NETCOM_UDP_SPIKE){ spike_net_t* test_spike = (spike_net_t*)this_arte_packet; //printf("test before write_mwl in loop: name:%d n_chans:%d\n", // test_spike->name, test_spike->n_chans); } write_mwl(this_arte_packet, sourcetype); packet_count++; } interactive_wait("message1\n"); } } // end if(true) //free(this_arte_packet); printf("finished. Wrote %d packet(s)\n", packet_count); exit(0); }
DecoderStatus VorbisDecoder::process(Packet * packet) { FXASSERT(packet); #ifdef HAVE_VORBIS_PLUGIN FXfloat ** pcm=NULL; FXfloat * buf32=NULL; #else // HAVE_TREMOR_PLUGIN FXint ** pcm=NULL; FXshort * buf32=NULL; #endif FXint p,navail=0; FXint ngiven,ntotalsamples,nsamples,sample,c,s; FXbool eos=packet->flags&FLAG_EOS; FXuint id=packet->stream; FXlong len=packet->stream_length; OggDecoder::process(packet); /// Init Decoder if (!has_dsp) { if (!init_decoder()) return DecoderError; if (!has_dsp) return DecoderOk; } /// Find Stream Position if (stream_position==-1 && !find_stream_position()) return DecoderOk; if (out) { navail = out->availableFrames(); } while(get_next_packet()) { if (__unlikely(is_vorbis_header())) { GM_DEBUG_PRINT("[vorbis] unexpected vorbis header found. Resetting decoder\n"); push_back_packet(); reset_decoder(); return DecoderOk; } if (vorbis_synthesis(&block,&op)==0) vorbis_synthesis_blockin(&dsp,&block); while((ngiven=vorbis_synthesis_pcmout(&dsp,&pcm))>0) { if (len>0) FXASSERT(stream_position+ngiven<=len); if (__unlikely(stream_position<stream_decode_offset)) { FXlong offset = FXMIN(ngiven,stream_decode_offset - stream_position); GM_DEBUG_PRINT("[vorbis] stream decode offset %ld. Skipping %ld of %ld \n",stream_decode_offset,offset,stream_decode_offset-stream_position); ngiven-=offset; stream_position+=offset; sample=offset; vorbis_synthesis_read(&dsp,offset); if (ngiven==0) continue; } else { sample=0; } for (ntotalsamples=ngiven;ntotalsamples>0;) { /// Get new buffer if (out==NULL) { out = engine->decoder->get_output_packet(); if (out==NULL) return DecoderInterrupted; out->stream_position=stream_position; out->stream_length=len; out->af=af; navail = out->availableFrames(); } #ifdef HAVE_VORBIS_PLUGIN buf32 = out->flt(); #else // HAVE_TREMOR_PLUGIN buf32 = out->s16(); #endif /// Copy Samples nsamples = FXMIN(ntotalsamples,navail); for (p=0,s=sample;s<(nsamples+sample);s++){ for (c=0;c<info.channels;c++,p++) { #ifdef HAVE_VORBIS_PLUGIN buf32[p]=pcm[c][s]; #else buf32[p]=CLIP_TO_15(pcm[c][s]>>9); #endif } } /// Update sample counts out->wroteFrames(nsamples); sample+=nsamples; navail-=nsamples; ntotalsamples-=nsamples; stream_position+=nsamples; /// Send out packet if full ///FIXME handle EOS. if (navail==0) { engine->output->post(out); out=NULL; } } vorbis_synthesis_read(&dsp,ngiven); } } if (eos) { if (out && out->numFrames()) { engine->output->post(out); out=NULL; } engine->output->post(new ControlEvent(End,id)); } return DecoderOk; }