void OMXReader::setSpeed(int iSpeed) { if(!avFormatContext) return; if(speed != DVD_PLAYSPEED_PAUSE && iSpeed == DVD_PLAYSPEED_PAUSE) { av_read_pause(avFormatContext); } else if(speed == DVD_PLAYSPEED_PAUSE && iSpeed != DVD_PLAYSPEED_PAUSE) { av_read_play(avFormatContext); } speed = iSpeed; AVDiscard discard = AVDISCARD_NONE; if(speed > 4*DVD_PLAYSPEED_NORMAL) discard = AVDISCARD_NONKEY; else if(speed > 2*DVD_PLAYSPEED_NORMAL) discard = AVDISCARD_BIDIR; else if(speed < DVD_PLAYSPEED_PAUSE) discard = AVDISCARD_NONKEY; for(unsigned int i = 0; i < avFormatContext->nb_streams; i++) { if(avFormatContext->streams[i]) { if(avFormatContext->streams[i]->discard != AVDISCARD_ALL) avFormatContext->streams[i]->discard = discard; } } }
void ExternalInput::receiveLoop() { av_read_play(context_); // play RTSP int gotDecodedFrame = 0; int length; startTime_ = av_gettime(); ELOG_DEBUG("Start playing external input %s", url_.c_str() ); while (av_read_frame(context_, &avpacket_) >= 0&& running_ == true) { AVPacket orig_pkt = avpacket_; if (needTranscoding_) { if (avpacket_.stream_index == video_stream_index_) { // packet is video inCodec_.decodeVideo(avpacket_.data, avpacket_.size, decodedBuffer_.get(), bufflen_, &gotDecodedFrame); RawDataPacket packetR; if (gotDecodedFrame) { packetR.data = decodedBuffer_.get(); packetR.length = bufflen_; packetR.type = VIDEO; queueMutex_.lock(); packetQueue_.push(packetR); queueMutex_.unlock(); gotDecodedFrame = 0; } } } else { if (avpacket_.stream_index == video_stream_index_) { // packet is video // av_rescale(input, new_scale, old_scale) int64_t pts = av_rescale(lastPts_, 1000000, (long int) video_time_base_); // NOLINT int64_t now = av_gettime() - startTime_; if (pts > now) { av_usleep(pts - now); } lastPts_ = avpacket_.pts; op_->packageVideo(avpacket_.data, avpacket_.size, decodedBuffer_.get(), avpacket_.pts); } else if (avpacket_.stream_index == audio_stream_index_) { // packet is audio int64_t pts = av_rescale(lastAudioPts_, 1000000, (long int)audio_time_base_); // NOLINT int64_t now = av_gettime() - startTime_; if (pts > now) { av_usleep(pts - now); } lastAudioPts_ = avpacket_.pts; length = op_->packageAudio(avpacket_.data, avpacket_.size, decodedBuffer_.get(), avpacket_.pts); if (length > 0) { audioSink_->deliverAudioData(reinterpret_cast<char*>(decodedBuffer_.get()), length); } } } av_free_packet(&orig_pkt); } ELOG_DEBUG("Ended stream to play %s", url_.c_str()); running_ = false; av_read_pause(context_); }
// pause video bool VideoFFmpeg::pause (void) { try { if (VideoBase::pause()) { if (m_isStreaming) { av_read_pause(m_formatCtx); } return true; } } CATCH_EXCP; return false; }
int internel_decoder::buffer_limit(int videobuffersize,int audiobuffersize,stream_context *streamcontext){ stream_context *sc = streamcontext; int mode2; if(sc->videostream != -1 && sc->audiostream != -1) mode2 = (sc->audiobuffer.size() > audiobuffersize || sc->videobuffer.size() > videobuffersize); if(sc->videostream == -1) mode2 = (sc->audiobuffer.size() > audiobuffersize); if(sc->audiostream == -1) mode2 = (sc->videobuffer.size() > videobuffersize); if(mode2){ av_read_pause(sc->pFormatCtx); pthread_mutex_lock(&sc->demuxlock); pthread_cond_wait(&sc->demuxcond, &sc->demuxlock); pthread_mutex_unlock(&sc->demuxlock); av_read_play(sc->pFormatCtx); return 1; } return 0; }
void PlayerInner::seekTo(long msec) { if(mediaFileHandle == NULL){ return ; } if(this->mediaFileHandle->seekpos > this->mediaFileHandle->duration_ms){ this->mediaFileHandle->seekpos = this->mediaFileHandle->duration_ms; } XLog::e(TAG ,"====>PlayerInner::seekTo position = %ld\n",msec); this->mediaFileHandle->seeking_mark = true; this->mediaFileHandle->seekpos = msec; av_read_pause(this->mediaFileHandle->format_context); mediaFileHandle->message_queue_video_decode->push_front(EVT_SEEK); // start to decode video packet data . mediaFileHandle->message_queue_audio_decode->push_front(EVT_SEEK); // 第一次起播之前如果seek的话 不执行这里 if(mediaFileHandle->isPlayedBefore){ // first loading end mediaFileHandle->notify(MEDIA_INFO ,MEDIA_INFO_BUFFERING_END ,0); // mediaFileHandle->notify(MEDIA_INFO ,MEDIA_INFO_BUFFERING_START ,0); // disappear loading } }
/* decode and play stream. returns 0 or av error code. */ static int play (player_t * const player) { assert (player != NULL); AVPacket pkt; av_init_packet (&pkt); pkt.data = NULL; pkt.size = 0; AVFrame *frame = NULL, *filteredFrame = NULL; frame = av_frame_alloc (); assert (frame != NULL); filteredFrame = av_frame_alloc (); assert (filteredFrame != NULL); while (!player->doQuit) { int ret = av_read_frame (player->fctx, &pkt); if (ret < 0) { av_free_packet (&pkt); return ret; } else if (pkt.stream_index != player->streamIdx) { av_free_packet (&pkt); continue; } AVPacket pkt_orig = pkt; /* pausing */ pthread_mutex_lock (&player->pauseMutex); if (player->doPause) { av_read_pause (player->fctx); do { pthread_cond_wait (&player->pauseCond, &player->pauseMutex); } while (player->doPause); av_read_play (player->fctx); } pthread_mutex_unlock (&player->pauseMutex); while (pkt.size > 0 && !player->doQuit) { int got_frame = 0; const int decoded = avcodec_decode_audio4 (player->st->codec, frame, &got_frame, &pkt); if (decoded < 0) { /* skip this one */ break; } if (got_frame != 0) { /* XXX: suppresses warning from resample filter */ if (frame->pts == (int64_t) AV_NOPTS_VALUE) { frame->pts = 0; } ret = av_buffersrc_write_frame (player->fabuf, frame); assert (ret >= 0); while (true) { if (av_buffersink_get_frame (player->fbufsink, filteredFrame) < 0) { /* try again next frame */ break; } const int numChannels = av_get_channel_layout_nb_channels ( filteredFrame->channel_layout); const int bps = av_get_bytes_per_sample(filteredFrame->format); ao_play (player->aoDev, (char *) filteredFrame->data[0], filteredFrame->nb_samples * numChannels * bps); av_frame_unref (filteredFrame); } } pkt.data += decoded; pkt.size -= decoded; }; av_free_packet (&pkt_orig); player->songPlayed = av_q2d (player->st->time_base) * (double) pkt.pts; player->lastTimestamp = pkt.pts; } av_frame_free (&filteredFrame); av_frame_free (&frame); return 0; }
/* decode and play stream. returns 0 or av error code. */ static int play (player_t * const player) { assert (player != NULL); AVPacket pkt; av_init_packet (&pkt); pkt.data = NULL; pkt.size = 0; AVFrame *frame = NULL, *filteredFrame = NULL; frame = avcodec_alloc_frame (); assert (frame != NULL); filteredFrame = avcodec_alloc_frame (); assert (filteredFrame != NULL); while (!player->doQuit) { ping (); int ret = av_read_frame (player->fctx, &pkt); if (ret < 0) { av_free_packet (&pkt); return ret; } else if (pkt.stream_index != player->streamIdx) { av_free_packet (&pkt); continue; } AVPacket pkt_orig = pkt; /* pausing */ pthread_mutex_lock (&player->pauseMutex); while (true) { if (!player->doPause) { av_read_play (player->fctx); break; } else { av_read_pause (player->fctx); } pthread_cond_wait (&player->pauseCond, &player->pauseMutex); } pthread_mutex_unlock (&player->pauseMutex); do { int got_frame = 0; const int decoded = avcodec_decode_audio4 (player->st->codec, frame, &got_frame, &pkt); if (decoded < 0) { /* skip this one */ break; } if (got_frame != 0) { /* XXX: suppresses warning from resample filter */ if (frame->pts == (int64_t) AV_NOPTS_VALUE) { frame->pts = 0; } ret = av_buffersrc_write_frame (player->fabuf, frame); assert (ret >= 0); while (true) { AVFilterBufferRef *audioref = NULL; #ifdef HAVE_AV_BUFFERSINK_GET_BUFFER_REF /* ffmpeg’s compatibility layer is broken in some releases */ if (av_buffersink_get_buffer_ref (player->fbufsink, &audioref, 0) < 0) { #else if (av_buffersink_read (player->fbufsink, &audioref) < 0) { #endif /* try again next frame */ break; } ret = avfilter_copy_buf_props (filteredFrame, audioref); assert (ret >= 0); const int numChannels = av_get_channel_layout_nb_channels ( filteredFrame->channel_layout); const int bps = av_get_bytes_per_sample(filteredFrame->format); ao_play (player->aoDev, (char *) filteredFrame->data[0], filteredFrame->nb_samples * numChannels * bps); avfilter_unref_bufferp (&audioref); } } pkt.data += decoded; pkt.size -= decoded; } while (pkt.size > 0); av_free_packet (&pkt_orig); player->songPlayed = av_q2d (player->st->time_base) * (double) pkt.pts; player->lastTimestamp = pkt.pts; } avcodec_free_frame (&filteredFrame); avcodec_free_frame (&frame); return 0; } static void finish (player_t * const player) { ao_close (player->aoDev); player->aoDev = NULL; if (player->fgraph != NULL) { avfilter_graph_free (&player->fgraph); player->fgraph = NULL; } if (player->st != NULL && player->st->codec != NULL) { avcodec_close (player->st->codec); player->st = NULL; } if (player->fctx != NULL) { avformat_close_input (&player->fctx); } }
void player_decode(void *data) { State *state = (State *) data; int ret; int eof = 0; for (;;) { if (state->abort_request) { break; } if (state->paused != state->last_paused) { state->last_paused = state->paused; if (state->paused) { state->read_pause_return = av_read_pause(state->pFormatCtx); } else { av_read_play(state->pFormatCtx); } } if (state->seek_req) { int64_t seek_target = state->seek_pos; int64_t seek_min = state->seek_rel > 0 ? seek_target - state->seek_rel + 2: INT64_MIN; int64_t seek_max = state->seek_rel < 0 ? seek_target - state->seek_rel - 2: INT64_MAX; ret = avformat_seek_file(state->pFormatCtx, -1, seek_min, seek_target, seek_max, state->seek_flags); if (ret < 0) { fprintf(stderr, "%s: error while seeking\n", state->pFormatCtx->filename); } else { if (state->audio_stream >= 0) { avcodec_flush_buffers(state->audio_st->codec); } state->notify_callback(state->clazz, MEDIA_SEEK_COMPLETE, 0, 0, FROM_THREAD); } state->seek_req = 0; eof = 0; } if (state->paused) { goto sleep; } AVPacket packet; memset(&packet, 0, sizeof(packet)); //make sure we can safely free it int i; for (i = 0; i < state->pFormatCtx->nb_streams; ++i) { //av_init_packet(&packet); ret = av_read_frame(state->pFormatCtx, &packet); if (ret < 0) { if (ret == AVERROR_EOF || url_feof(state->pFormatCtx->pb)) { eof = 1; break; } } int frame_size_ptr; ret = decode_frame_from_packet(state, &packet, &frame_size_ptr, FROM_THREAD); av_free_packet(&packet); if (ret != 0) { //an error or a frame decoded // TODO add this bacl=k } } if (eof) { break; } sleep: usleep(100); } if (eof) { state->notify_callback(state->clazz, MEDIA_PLAYBACK_COMPLETE, 0, 0, FROM_THREAD); } }
void RtspStreamWorker::pause() { av_read_pause(m_ctx); m_threadPause.pause(); av_read_play(m_ctx); }
static int decode_one_frame(struct GroovePlaylist *playlist, struct GrooveFile *file) { struct GroovePlaylistPrivate *p = (struct GroovePlaylistPrivate *) playlist; struct GrooveFilePrivate *f = (struct GrooveFilePrivate *) file; AVPacket *pkt = &f->audio_pkt; // might need to rebuild the filter graph if certain things changed if (maybe_init_filter_graph(playlist, file) < 0) return -1; // abort_request is set if we are destroying the file if (f->abort_request) return -1; // handle pause requests // only read p->paused once so that we don't need a mutex int paused = p->paused; if (paused != p->last_paused) { p->last_paused = paused; if (paused) { av_read_pause(f->ic); } else { av_read_play(f->ic); } } // handle seek requests pthread_mutex_lock(&f->seek_mutex); if (f->seek_pos >= 0) { if (av_seek_frame(f->ic, f->audio_stream_index, f->seek_pos, 0) < 0) { av_log(NULL, AV_LOG_ERROR, "%s: error while seeking\n", f->ic->filename); } else if (f->seek_flush) { every_sink_flush(playlist); } avcodec_flush_buffers(f->audio_st->codec); f->seek_pos = -1; f->eof = 0; } pthread_mutex_unlock(&f->seek_mutex); if (f->eof) { if (f->audio_st->codec->codec->capabilities & CODEC_CAP_DELAY) { av_init_packet(pkt); pkt->data = NULL; pkt->size = 0; pkt->stream_index = f->audio_stream_index; if (audio_decode_frame(playlist, file) > 0) { // keep flushing return 0; } } // this file is complete. move on return -1; } int err = av_read_frame(f->ic, pkt); if (err < 0) { // treat all errors as EOF, but log non-EOF errors. if (err != AVERROR_EOF) { av_log(NULL, AV_LOG_WARNING, "error reading frames\n"); } f->eof = 1; return 0; } if (pkt->stream_index != f->audio_stream_index) { // we're only interested in the One True Audio Stream av_free_packet(pkt); return 0; } audio_decode_frame(playlist, file); av_free_packet(pkt); return 0; }
void FormatContext::pause() { av_read_pause(formatCtx); isPaused = true; }