void SequencedOutputDatagramChannel::WritePacket(const std::vector<uint8_t>& packet) { // copy packet and write it back std::vector<uint8_t> nextPacket(packet.size() + 4); memcpy(&nextPacket[4], &packet[0], nextPacket.size()); // write sequence to the packet SetSequence(GetSequence() + 1); *reinterpret_cast<uint32_t*>(&nextPacket[0]) = GetSequence(); GetSink()->WritePacket(nextPacket); }
Packet *Server::waitForPacket(qint64 timeout) { if(m_socket == 0) { m_error = QObject::tr("No open connection"); return 0; } qint64 startTime = QDateTime::currentMSecsSinceEpoch(); while(QDateTime::currentMSecsSinceEpoch() - startTime < timeout) { m_socket->waitForReadyRead(20); Packet *result = nextPacket(); if(result != 0) return result; } m_error = QObject::tr("Host timeout"); return 0; }
void vineoDecode( Vineo *v ) { if( !v || !v->is_playing ) { return; } // fill the packet queue fillPacketQueue( v ); // update player time v->time = av_gettime() - v->time_offset + v->start_time; double pts = 0.0f; AVPacket pkt; int frame_finished = 0; // decode new video frame while( v->time > v->cur_pts || v->cur_pts == 0 ) { if( !nextPacket( v, v->idx_video, &pkt ) ) { break; } //v->vid_codec_ctx->reordered_opaque = packet.pts; avcodec_decode_video( v->vid_codec_ctx, v->frame, &frame_finished, pkt.data, pkt.size ); //printf( "pFrame->opaque: %i\n", pFrame->opaque ); /* NOTE FIXME moeten we hier wat mee? if( packet.dts == AV_NOPTS_VALUE && pFrame->opaque && *(uint64_t*)pFrame->opaque != AV_NOPTS_VALUE ) { printf( "FROM FRAME OPAQUE?," ); pts = *(uint64_t *)pFrame->opaque; } else*/ //printf( "reordered_opaque: %i, %i\n", packet.pts, pFrame->reordered_opaque ); /*if( packet.dts == AV_NOPTS_VALUE && v->frame->reordered_opaque != AV_NOPTS_VALUE ) { // NOTE FIXME ik weet niet of dit werkt? //printf( "FROM FRAME OPAQUE?," ); pts = v->frame->reordered_opaque; } else*/ if( pkt.dts != AV_NOPTS_VALUE ) { //printf( "FROM PACKET DTS, " ); pts = pkt.dts; } else { //printf( "NO PTS, " ); pts = 0; } pts *= av_q2d( v->fmt_ctx->streams[v->idx_video]->time_base ); v->cur_pts = pts * AV_TIME_BASE; //printf( "v->is_frame_finished: %i, v->cur_pts: %lli, v->time: %lli\n", v->is_frame_finished, v->cur_pts, v->time ); if( frame_finished && ( v->cur_pts >= v->time || v->cur_pts == 0 ) ) { sws_scale( v->sws, v->frame->data, v->frame->linesize, 0, v->vid_codec_ctx->height, v->frame_rgba->data, v->frame_rgba->linesize ); v->frame_data++; } av_free_packet( &pkt ); } // fill audio buffer ALuint buf = 0; ALint processed = 0; ALint state = 0; ALenum err; // NOTE FIXME ffplay.c /* sdl_audio_callback() audio_decode_frame() { pts = is->audio_clock; *pts_ptr = pts; n = 2 * dec->channels; is->audio_clock += (double)data_size /(double)(n * dec->sample_rate); } synchronize_audio(), AV_SYNC_EXTERNAL_CLOCK get_audio_clock() */ for(;;) { processed = 0; alGetSourcei( v->aud_src_al, AL_BUFFERS_PROCESSED, &processed ); if( processed == 0 ) { alGetSourcei( v->aud_src_al, AL_SOURCE_STATE, &state ); if( alGetError() != AL_NO_ERROR ) { printf( "Error checking source state...\n" ); break; } if( state != AL_PLAYING ) { alSourcePlay( v->aud_src_al ); if( alGetError() != AL_NO_ERROR ) { printf( "Error restarting playback...\n" ); break; } } else { //alGetSourcei( g_sndSrc, AL_SAMPLE_OFFSET, &offset ); //printf( "\roffset: %i", offset ); //alutSleep( 0.01 ); } break; } double clock = 0.0f; int fixAudioSync = 0; int count = 1; // kijken of we wel gesyncd lopen met de g_timeCur, anders droppen we wat frames do { if( clock > 0 ) { fixAudioSync = 1; printf( "Dropping audio frame\n" ); } count = nextDataAudio( v, v->data_tmp, VINEO_AUDIO_BUFFER_SIZE ); v->buffer_playing += count; clock = (float)v->buffer_playing / (float)( ( v->aud_bits / 8 ) * v->aud_channels * v->aud_rate ) * AV_TIME_BASE; } while( v->time > clock && count > 0 ); if( count > 0 ) { alSourceUnqueueBuffers( v->aud_src_al, 1, &buf ); if( buf != 0 ) { if( fixAudioSync ) { //double timeFix = clock - g_timeCur; double timeFix = clock - v->time; count = timeFix * ( (float)( ( v->aud_bits / 8 ) * v->aud_channels * v->aud_rate ) ); // round to nice buffer length count /= ( ( v->aud_bits / 8 ) * v->aud_channels ); count *= ( ( v->aud_bits / 8 ) * v->aud_channels ); //count = BUFFER_SIZE - count; printf( "- fix audio syncing, count: %i, time: %f\n", count, timeFix ); } alBufferData( buf, v->aud_format, v->data_tmp, count, v->aud_rate ); alSourceQueueBuffers( v->aud_src_al, 1, &buf ); } if( ( err = alGetError() ) != AL_NO_ERROR ) { printf( "Error buffering data (%i)...\n", err ); break; } } else { break; } } }
static void nextPacketAudio( Vineo *v ) { AVPacket pkt; //double pts = 0.0f; //while( getNextPacket( stream->fmt_ctx, stream->index, &pkt ) ) while( nextPacket( v, v->idx_audio, &pkt ) ) { //if( stream->index != pkt.stream_index ) //{ // av_av_free_packet( &pkt ); // continue; //} /* if( pkt.pts != AV_NOPTS_VALUE ) { //printf( "FROM PACKET DTS, " ); pts = pkt.pts; } else { //printf( "NO PTS, " ); pts = 0.0f; } pts *= av_q2d( stream->fmt_ctx->streams[stream->index]->time_base ); pts -= g_start_timeOffset; if( pts >= g_timeCur ) { printf( "getNextAudioPacket pts: %f, gpts: %f\n", pts, g_timeCur ); */ size_t idx = v->data_size; // Found the stream. Grow the input data buffer as needed to // hold the new packet's data. Additionally, some ffmpeg codecs // need some padding so they don't overread the allocated buffer if( idx + pkt.size > v->data_size_max ) { void *tmp = av_realloc( v->data, idx + pkt.size + FF_INPUT_BUFFER_PADDING_SIZE ); if( !tmp ) { break; } v->data = tmp; v->data_size_max = idx + pkt.size; } // Copy the packet and av_free it memcpy( &v->data[idx], pkt.data, pkt.size ); v->data_size += pkt.size; av_free_packet( &pkt ); break; /* } av_free_packet( &pkt ); */ } }