Example #1
2
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;
        }
    }
}
Example #2
0
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(&params, 0, sizeof(params));
  if ((ret = av_open_input_file(&ffmpeg->ctxt, ft->filename, NULL, 0, &params)) < 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;
}
Example #3
0
File: IoAVCodec.c Project: BMeph/io
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;
}
Example #4
0
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_);
}
Example #5
0
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;
}
Example #6
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;
}
Example #7
0
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;
}
Example #8
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;
}
Example #9
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 = 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;
}
Example #10
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);
}
Example #13
0
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;
}
Example #14
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;
}
Example #15
0
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;
}