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; } } }
static int startread(sox_format_t * ft) { priv_t * ffmpeg = (priv_t *)ft->priv; AVFormatParameters params; int ret; int i; ffmpeg->audio_buf_raw = lsx_calloc(1, (size_t)AVCODEC_MAX_AUDIO_FRAME_SIZE + 32); ffmpeg->audio_buf_aligned = ALIGN16(ffmpeg->audio_buf_raw); /* Signal audio stream not found */ ffmpeg->audio_index = -1; /* register all CODECs, demux and protocols */ av_register_all(); /* Open file and get format */ memset(¶ms, 0, sizeof(params)); if ((ret = av_open_input_file(&ffmpeg->ctxt, ft->filename, NULL, 0, ¶ms)) < 0) { lsx_fail("ffmpeg cannot open file for reading: %s (code %d)", ft->filename, ret); return SOX_EOF; } /* Get CODEC parameters */ if ((ret = av_find_stream_info(ffmpeg->ctxt)) < 0) { lsx_fail("ffmpeg could not find CODEC parameters for %s", ft->filename); return SOX_EOF; } /* Now we can begin to play (RTSP stream only) */ av_read_play(ffmpeg->ctxt); /* Find audio stream (FIXME: allow different stream to be selected) */ for (i = 0; (unsigned)i < ffmpeg->ctxt->nb_streams; i++) { AVCodecContext *enc = ffmpeg->ctxt->streams[i]->codec; if (enc->codec_type == CODEC_TYPE_AUDIO && ffmpeg->audio_index < 0) { ffmpeg->audio_index = i; break; } } /* Open the stream */ if (ffmpeg->audio_index < 0 || stream_component_open(ffmpeg, ffmpeg->audio_index) < 0 || ffmpeg->audio_stream < 0) { lsx_fail("ffmpeg could not open CODECs for %s", ft->filename); return SOX_EOF; } /* Copy format info */ ft->signal.rate = ffmpeg->audio_st->codec->sample_rate; ft->encoding.bits_per_sample = 16; ft->encoding.encoding = SOX_ENCODING_SIGN2; ft->signal.channels = ffmpeg->audio_st->codec->channels; ft->signal.length = 0; /* Currently we can't seek; no idea how to get this info from ffmpeg anyway (in time, yes, but not in samples); but ffmpeg *can* seek */ return SOX_SUCCESS; }
IoObject *IoAVCodec_open(IoAVCodec *self, IoObject *locals, IoMessage *m) { /*doc AVCodec open Opens the input file. Return self on success or raises an exception on error. */ int err; IoAVCodec_registerIfNeeded(self); IoAVCodec_freeContextIfNeeded(self); IoAVCodec_createContextIfNeeded(self); DATA(self)->isAtEnd = 0; err = IoAVCodec_openFile(self); if (err != 0) { IoObject *fileName = IoObject_symbolGetSlot_(self, IOSYMBOL("path")); IoState_error_(IOSTATE, m, "error %i opening file %s\n", err, CSTRING(fileName)); return IONIL(self); } IoAVCodec_findStreams(self); av_read_play(DATA(self)->formatContext); return self; }
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_); }
static int rtsp_connect(netcam_context_ptr netcam) { if (netcam->rtsp == NULL) { netcam->rtsp = rtsp_new_context(); if (netcam->rtsp == NULL) { MOTION_LOG(ALR, TYPE_NETCAM, NO_ERRNO, "%s: unable to create context(%s)", netcam->rtsp->path); return -1; } } // open the network connection AVDictionary *opts = 0; av_dict_set(&opts, "rtsp_transport", "tcp", 0); int ret = avformat_open_input(&netcam->rtsp->format_context, netcam->rtsp->path, NULL, &opts); if (ret < 0) { MOTION_LOG(ALR, TYPE_NETCAM, NO_ERRNO, "%s: unable to open input(%s): %d - %s", netcam->rtsp->path, ret, av_err2str(ret)); rtsp_free_context(netcam->rtsp); netcam->rtsp = NULL; return -1; } // fill out stream information ret = avformat_find_stream_info(netcam->rtsp->format_context, NULL); if (ret < 0) { MOTION_LOG(ALR, TYPE_NETCAM, NO_ERRNO, "%s: unable to find stream info: %d", ret); rtsp_free_context(netcam->rtsp); netcam->rtsp = NULL; return -1; } ret = open_codec_context(&netcam->rtsp->video_stream_index, netcam->rtsp->format_context, AVMEDIA_TYPE_VIDEO); if (ret < 0) { MOTION_LOG(ALR, TYPE_NETCAM, NO_ERRNO, "%s: unable to open codec context: %d", ret); rtsp_free_context(netcam->rtsp); netcam->rtsp = NULL; return -1; } netcam->rtsp->codec_context = netcam->rtsp->format_context->streams[netcam->rtsp->video_stream_index]->codec; // start up the feed av_read_play(netcam->rtsp->format_context); return 0; }
// play video bool VideoFFmpeg::play (void) { try { // if object is able to play if (VideoBase::play()) { // set video position setPositions(); if (m_isStreaming) { av_read_play(m_formatCtx); } // return success 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; }
static void *ffmpeg_open (const char *file) { struct ffmpeg_data *data; int err; unsigned int i; int audio_index = -1; data = (struct ffmpeg_data *)xmalloc (sizeof(struct ffmpeg_data)); data->ok = 0; decoder_error_init (&data->error); memset (&data->ap, 0, sizeof(data->ap)); err = av_open_input_file (&data->ic, file, NULL, 0, &data->ap); if (err < 0) { decoder_error (&data->error, ERROR_FATAL, 0, "Can't open file"); return data; } err = av_find_stream_info (data->ic); if (err < 0) { decoder_error (&data->error, ERROR_FATAL, 0, "Could not find codec parameters (err %d)", err); av_close_input_file (data->ic); return data; } av_read_play (data->ic); for (i = 0; i < data->ic->nb_streams; i++) { data->enc = data->ic->streams[i]->codec; if (data->enc->codec_type == CODEC_TYPE_AUDIO) { audio_index = i; break; } } if (audio_index == -1) { decoder_error (&data->error, ERROR_FATAL, 0, "No audio stream in file"); av_close_input_file (data->ic); return data; } /* hack for AC3 */ if (data->enc->channels > 2) data->enc->channels = 2; data->codec = avcodec_find_decoder (data->enc->codec_id); if (!data->codec || avcodec_open(data->enc, data->codec) < 0) { decoder_error (&data->error, ERROR_FATAL, 0, "No codec for this file."); av_close_input_file (data->ic); return data; } data->remain_buf = NULL; data->remain_buf_len = 0; data->ok = 1; data->avg_bitrate = (int) (data->ic->file_size / (data->ic->duration / 1000000) * 8); data->bitrate = data->ic->bit_rate / 1000; return data; }
/* 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; }
bool FormatContext::read(Packet &encoded, int &idx) { if (abortCtx->isAborted) { isError = true; return false; } if (isPaused) { isPaused = false; av_read_play(formatCtx); } AVPacketRAII avPacketRAII(packet); int ret; if (!maybeHasFrame) ret = av_read_frame(formatCtx, packet); else { maybeHasFrame = false; ret = errFromSeek; errFromSeek = 0; } if (ret == AVERROR_INVALIDDATA) { if (invalErrCount < 1000) { ++invalErrCount; return true; } isError = true; return false; } else invalErrCount = 0; if (ret == AVERROR(EAGAIN)) return true; else if (ret) { isError = true; return false; } const int ff_idx = packet->stream_index; if (ff_idx >= streams.count()) { QMPlay2Core.log("Stream index out of range: " + QString::number(ff_idx), ErrorLog | LogOnce | DontShowInGUI); return true; } const auto stream = streams.at(ff_idx); if (stream->event_flags & AVSTREAM_EVENT_FLAG_METADATA_UPDATED) { stream->event_flags = 0; isMetadataChanged = true; } if (fixMkvAss && stream->codecpar->codec_id == AV_CODEC_ID_ASS) matroska_fix_ass_packet(stream->time_base, packet); if (!packet->buf || forceCopy) //Buffer isn't reference-counted, so copy the data { encoded.assign(packet->data, packet->size, packet->size + AV_INPUT_BUFFER_PADDING_SIZE); } else { encoded.assign(packet->buf, packet->size, packet->data - packet->buf->data); packet->buf = nullptr; } if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && stream->codecpar->format == AV_PIX_FMT_PAL8) { int size = 0; const auto data = av_packet_get_side_data(packet, AV_PKT_DATA_PALETTE, &size); if (size > 0 && data) encoded.palette = QByteArray((const char *)data, size); } const double time_base = av_q2d(stream->time_base); encoded.ts.setInvalid(); if (packet->dts != QMPLAY2_NOPTS_VALUE) encoded.ts.setDts(packet->dts * time_base, startTime); if (packet->pts != QMPLAY2_NOPTS_VALUE) encoded.ts.setPts(packet->pts * time_base, startTime); if (packet->duration > 0) encoded.duration = packet->duration * time_base; else if (!encoded.ts || (encoded.duration = encoded.ts - streamsTS.at(ff_idx)) < 0.0 /* Calculate packet duration if doesn't exists */) encoded.duration = 0.0; streamsTS[ff_idx] = encoded.ts; if (isStreamed) { if (!isOneStreamOgg) encoded.ts += streamsOffset.at(ff_idx); else { encoded.ts = lastTime; lastTime += encoded.duration; } } else if (lengthToPlay > 0.0 && encoded.ts > lengthToPlay) { isError = true; return false; } encoded.hasKeyFrame = packet->flags & AV_PKT_FLAG_KEY; if (stream->sample_aspect_ratio.num) encoded.sampleAspectRatio = av_q2d(stream->sample_aspect_ratio); // Generate DTS for key frames if DTS doesn't exist (workaround for some M3U8 seekable streams) if (encoded.hasKeyFrame && !encoded.ts.hasDts()) encoded.ts.setDts(nextDts.at(ff_idx)); nextDts[ff_idx] = encoded.ts + encoded.duration; currPos = encoded.ts; idx = index_map.at(ff_idx); return true; }
bool VideoLayer::open(const char *file) { AVCodecContext *enc; // tmp int err=0; video_index=-1; func("VideoLayer::open(%s)",file); AVInputFormat *av_input_format = NULL; AVFormatParameters avp, *av_format_par = NULL; av_format_par = &avp; memset (av_format_par, 0, sizeof (*av_format_par)); av_format_par->width=0; av_format_par->width=0; av_format_par->time_base = (AVRational){1, 25}; av_format_par->pix_fmt=PIX_FMT_RGB32; /* handle firewire cam */ if( strncasecmp (file, "/dev/ieee1394/",14) == 0) { notice ("VideoLayer::found dv1394 device!\n"); grab_dv = true; av_input_format = av_find_input_format("dv1394"); /** shit XXX */ av_format_par -> width = 720; av_format_par -> height = 576; #if LIBAVCODEC_BUILD >= 4754 av_format_par -> time_base.num = 25; av_format_par -> time_base.den = 1; #else av_format_par -> frame_rate = 25; av_format_par -> frame_rate_base = 1; #endif // field removed in recent ffmpeg API (todo: check LIBAVCODEC_BUILD) // av_format_par -> device = file; av_format_par -> standard = "pal"; // av_format_par->channel=0; file=""; } /** * The callback is called in blocking functions to test regulary if * asynchronous interruption is needed. -EINTR is returned in this * case by the interrupted function. 'NULL' means no interrupt * callback is given. */ url_set_interrupt_cb(NULL); /** * Open media with libavformat */ err = av_open_input_file (&avformat_context, file, av_input_format, 0, av_format_par); if (err < 0) { error("VideoLayer :: open(%s) - can't open. Error %d", file, err); return false; } func("VideoLayer :: file opened with success"); /** * Find info with libavformat */ err = av_find_stream_info(avformat_context); if (err < 0) { error("VideoLayer :: could not find stream info"); return false; } func("VideoLayer :: stream info found"); /* now we can begin to play (RTSP stream only) */ av_read_play(avformat_context); /** * Open codec if we find a video stream */ unsigned int i; for(i=0; i < avformat_context -> nb_streams; i++) { avformat_stream = avformat_context -> streams[i]; enc = avformat_stream->codec; if(enc == NULL) error("%s: AVCodecContext is NULL", __PRETTY_FUNCTION__); switch(enc->codec_type) { /** * Here we look for a video stream */ // case CODEC_TYPE_VIDEO: // old FFMPEG case AVMEDIA_TYPE_VIDEO: // enc->flags |= CODEC_FLAG_LOOP_FILTER; video_index = i; video_codec_ctx = enc; video_codec = avcodec_find_decoder (video_codec_ctx -> codec_id); if(video_codec==NULL) { error("VideoLayer :: Could not find a suitable codec"); return false; } if (avcodec_open(video_codec_ctx, video_codec) < 0) { error("VideoLayer :: Could not open codec"); return false; } else { // correctly opened #if LIBAVCODEC_BUILD >= 4754 if(avformat_stream->r_frame_rate.den && avformat_stream->r_frame_rate.num) frame_rate = av_q2d(avformat_stream->r_frame_rate); else frame_rate = enc -> time_base.den / enc -> time_base.num; AVRational rational = enc -> time_base; func ("VideoLayer :: frame_rate den: %d", enc -> time_base .den); func ("VideoLayer :: frame_rate num: %d", enc -> time_base .num); #else frame_rate = video_codec_ctx->frame_rate / video_codec_ctx->frame_rate_base; #endif // set the layer fps fps.set(frame_rate); /* this saves only file without full path! */ set_filename (file); act ("%s (codec: %s) has resolution %dx%d and framerate %f", get_filename(), video_codec->name, video_codec_ctx->width, video_codec_ctx->height, frame_rate); break; } break; // //////////////// end of video section case AVMEDIA_TYPE_AUDIO: audio_index = i; audio_codec_ctx = enc; func ("VideoLayer :: audio id=%i", audio_index); audio_codec = avcodec_find_decoder(audio_codec_ctx -> codec_id); if(audio_codec==NULL) { error("VideoLayer :: Could not find a suitable codec for audio"); return false; } if (avcodec_open(audio_codec_ctx, audio_codec) < 0) { error("VideoLayer :: Could not open codec for audio"); return false; } else { // correctly opened //AVCODEC_MAX_AUDIO_FRAME_SIZE = 192000 audio_buf = (uint8_t*)calloc(AVCODEC_MAX_AUDIO_FRAME_SIZE, sizeof(int16_t)); audio_channels = audio_codec_ctx->channels; audio_samplerate = audio_codec_ctx->sample_rate; audio_float_buf = (float*) malloc(audio_channels * AVCODEC_MAX_AUDIO_FRAME_SIZE * sizeof(float)); act("VideoLayer :: audio stream (codec: %s) has %u channels at samplerate %u", audio_codec->name, audio_channels, audio_samplerate); } break; // /////// end of audio section case AVMEDIA_TYPE_SUBTITLE: act("stream has also subtitles"); break; case AVMEDIA_TYPE_ATTACHMENT: act("stream has also attachment"); break; case AVMEDIA_TYPE_DATA: act("stream has also a data carrier"); break; default: act("stream has also an unknown codec stream"); break; } } // done looking for streams if (video_index < 0) { error("VideoLayer :: Could not open codec"); return false; } full_filename = strdup (file); geo.init(video_codec_ctx->width, video_codec_ctx->height, 32); func("VideoLayer :: w[%u] h[%u] size[%u]", geo.w, geo.h, geo.bytesize); func("VideoLayer :: frame_rate[%f]",frame_rate); // initialize picture if( new_picture(rgba_picture) < 0) { error("VideoLayer::error allocating picture"); return false; } #ifdef WITH_SWSCALE img_convert_ctx = sws_getContext(geo.w, geo.h, video_codec_ctx->pix_fmt, geo.w, geo.h, PIX_FMT_RGB32, SWS_BICUBIC, NULL, NULL, NULL); #endif // initialize frame fifo if( new_fifo() < 0) { error("VideoLayer::error allocating fifo"); return false; } // feed() function is called 25 times for second so we must correct the speed // TODO user should be able to select the clock speed if (play_speed != 25) { play_speed -= (25 / frame_rate); // play_speed -= play_speed << 1; if ( frame_rate ==1) play_speed = 0; } func ("VideoLayer :: play_speed: %d",play_speed); opened = true; type = VIDEOLAYER; return true; }