Пример #1
0
void packet_queue_flush(struct ff_packet_queue *q)
{
	struct ff_packet_list *packet;

	pthread_mutex_lock(&q->mutex);

	for (packet = q->first_packet; packet != NULL;
			packet = q->first_packet) {
		q->first_packet = packet->next;
		av_free_packet(&packet->packet.base);
		if (packet->packet.clock != NULL)
			ff_clock_release(&packet->packet.clock);
		av_freep(&packet);
	}

	q->last_packet = q->first_packet = NULL;
	q->count = 0;
	q->total_size = 0;

	pthread_mutex_unlock(&q->mutex);
}
Пример #2
0
void ff_decoder_free(struct ff_decoder *decoder)
{
	void *decoder_thread_result;
	int i;

	assert(decoder != NULL);

	decoder->abort = true;

	ff_circular_queue_abort(&decoder->frame_queue);
	packet_queue_abort(&decoder->packet_queue);

	ff_timer_free(&decoder->refresh_timer);

	pthread_join(decoder->decoder_thread, &decoder_thread_result);

	for (i = 0; i < decoder->frame_queue.capacity; i++) {
		void *item = decoder->frame_queue.slots[i];
		struct ff_frame *frame = (struct ff_frame *)item;

		ff_callbacks_frame_free(frame, decoder->callbacks);

		if (frame != NULL) {
			if (frame->frame != NULL)
				av_frame_unref(frame->frame);
			if (frame->clock != NULL)
				ff_clock_release(&frame->clock);
			av_free(frame);
		}
	}

	packet_queue_free(&decoder->packet_queue);
	ff_circular_queue_free(&decoder->frame_queue);

	avcodec_close(decoder->codec);

	av_free(decoder);
}
Пример #3
0
void ff_decoder_refresh(void *opaque)
{
	struct ff_decoder *decoder = (struct ff_decoder *)opaque;

	struct ff_frame *frame;

	if (decoder->stream) {
		if (decoder->frame_queue.size == 0) {
			if (!decoder->eof || !decoder->finished) {
				// We expected a frame, but there were none
				// available
				
				// Schedule another call as soon as possible
				ff_decoder_schedule_refresh(decoder, 1);
			} else {
				ff_callbacks_frame(decoder->callbacks, NULL);
				decoder->refresh_timer.abort = true;
				// no more refreshes, we are at the eof
				av_log(NULL, AV_LOG_INFO,
						"refresh timer stopping; eof");
				return;
			}
		} else {
			double pts_diff;
			double delay_until_next_wake;
			bool late_first_frame = false;

			frame = ff_circular_queue_peek_read(
					&decoder->frame_queue);

			// Get frame clock and start it if needed
			ff_clock_t *clock = ff_clock_move(&frame->clock);
			if (!ff_clock_start(clock, decoder->natural_sync_clock,
					&decoder->refresh_timer.abort)) {
				ff_clock_release(&clock);

				// Our clock was never started and deleted or
				// aborted

				if (decoder->refresh_timer.abort) {
					av_log(NULL, AV_LOG_INFO,
						"refresh timer aborted");
					return;
				}

				// Drop this frame? The only way this can happen
				// is if one stream finishes before another and
				// the input is looping or canceled.  Until we
				// get another clock we will unable to continue

				ff_decoder_schedule_refresh(decoder, 100);

				// Drop this frame as we have no way of timing
				// it
				ff_circular_queue_advance_read(
						&decoder->frame_queue);
				return;
			}

			decoder->current_pts = frame->pts;
			decoder->current_pts_time = av_gettime();

			// the amount of time until we need to display this
			// frame
			pts_diff = frame->pts - decoder->previous_pts;

			// if the first frame is a very large value, we've most
			// likely started mid-stream, and the initial diff
			// should be ignored.
			if (decoder->first_frame) {
				late_first_frame = pts_diff >= 1.0;
				decoder->first_frame = false;
			}

			if (pts_diff <= 0 || late_first_frame) {
				// if diff is invalid, use previous
				pts_diff = decoder->previous_pts_diff;
			}

			// save for next time
			decoder->previous_pts_diff = pts_diff;
			decoder->previous_pts = frame->pts;

			// if not synced against natural clock
			if (clock->sync_type
					!= decoder->natural_sync_clock) {
				pts_diff = get_sync_adjusted_pts_diff(clock,
						frame->pts, pts_diff);
			}

			decoder->timer_next_wake += pts_diff;

			// compute the amount of time until next refresh
			delay_until_next_wake = decoder->timer_next_wake -
					(av_gettime() / 1000000.0L);
			if (delay_until_next_wake < 0.010L) {
				delay_until_next_wake = 0.010L;
			}

			if (delay_until_next_wake > pts_diff)
				delay_until_next_wake = pts_diff;

			ff_clock_release(&clock);
			ff_callbacks_frame(decoder->callbacks, frame);

			ff_decoder_schedule_refresh(decoder,
					(int)(delay_until_next_wake * 1000
						+ 0.5L));

			av_frame_free(&frame->frame);

			ff_circular_queue_advance_read(&decoder->frame_queue);
		}
	} else {
		ff_decoder_schedule_refresh(decoder, 100);
	}
}