Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7b51551c authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "media: dvb: Add buffer flushing API"

parents 6031da66 4addb3e1
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -63,7 +63,6 @@
/*
 * enum dmx_success: Success codes for the Demux Callback API.
 */

enum dmx_success {
	DMX_OK = 0, /* Received Ok */
	DMX_OK_PES_END, /* Received OK, data reached end of PES packet */
@@ -219,6 +218,7 @@ struct dmx_ts_feed {
	int (*ts_insertion_insert_buffer)(struct dmx_ts_feed *feed,
			char *data, size_t size);
	int (*get_scrambling_bits)(struct dmx_ts_feed *feed, u8 *value);
	int (*flush_buffer)(struct dmx_ts_feed *feed, size_t length);
};

/*--------------------------------------------------------------------------*/
@@ -272,6 +272,7 @@ struct dmx_section_feed {
	int (*oob_command) (struct dmx_section_feed *feed,
				struct dmx_oob_command *cmd);
	int (*get_scrambling_bits)(struct dmx_section_feed *feed, u8 *value);
	int (*flush_buffer)(struct dmx_section_feed *feed, size_t length);
};

/*--------------------------------------------------------------------------*/
+309 −270

File changed.

Preview size limit exceeded, changes collapsed.

+57 −7
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
 *		       & Marcus Metzler <marcus@convergence.de>
 *			 for convergence integrated media GmbH
 *
 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
@@ -523,6 +523,7 @@ static inline int dvb_dmx_swfilter_payload(struct dvb_demux_feed *feed,
	int p;
	int ccok;
	u8 cc;
	int ret;

	if (count == 0)
		return -1;
@@ -544,20 +545,24 @@ static inline int dvb_dmx_swfilter_payload(struct dvb_demux_feed *feed,
		feed->pusi_seen = 1;
		feed->peslen = 0;
		feed->pes_tei_counter = 0;
		feed->pes_ts_packets_num = 0;
		feed->pes_cont_err_counter = 0;
		feed->pes_ts_packets_num = 0;
	}

	if (feed->pusi_seen == 0)
		return 0;

	feed->pes_ts_packets_num++;
	ret = feed->cb.ts(&buf[p], count, NULL, 0, &feed->feed.ts, DMX_OK);

	/* Verify TS packet was copied successfully */
	if (!ret) {
		feed->pes_cont_err_counter += !ccok;
		feed->pes_tei_counter += (buf[1] & 0x80) ? 1 : 0;

		feed->pes_ts_packets_num++;
		feed->peslen += count;
	}

	return feed->cb.ts(&buf[p], count, NULL, 0, &feed->feed.ts, DMX_OK);
	return ret;
}

static int dvb_dmx_swfilter_sectionfilter(struct dvb_demux_feed *feed,
@@ -2540,6 +2545,49 @@ static int dmx_ts_set_tsp_out_format(
	return 0;
}

/**
 * dvbdmx_ts_reset_pes_state() - Reset the current PES length and PES counters
 *
 * @feed: dvb demux feed object
 */
void dvbdmx_ts_reset_pes_state(struct dvb_demux_feed *feed)
{
	unsigned long flags;

	/*
	 * Reset PES state.
	 * PUSI seen indication is kept so we can get partial PES.
	 */
	spin_lock_irqsave(&feed->demux->lock, flags);

	feed->peslen = 0;
	feed->pes_tei_counter = 0;
	feed->pes_cont_err_counter = 0;
	feed->pes_ts_packets_num = 0;

	spin_unlock_irqrestore(&feed->demux->lock, flags);
}
EXPORT_SYMBOL(dvbdmx_ts_reset_pes_state);

static int dvbdmx_ts_flush_buffer(struct dmx_ts_feed *ts_feed, size_t length)
{
	struct dvb_demux_feed *feed = (struct dvb_demux_feed *)ts_feed;
	struct dvb_demux *demux = feed->demux;
	int ret = 0;

	if (mutex_lock_interruptible(&demux->mutex))
		return -ERESTARTSYS;

	dvbdmx_ts_reset_pes_state(feed);

	if ((feed->ts_type & TS_DECODER) && demux->flush_decoder_buffer)
		/* Call decoder specific flushing if one exists */
		ret = demux->flush_decoder_buffer(feed, length);

	mutex_unlock(&demux->mutex);
	return ret;
}

static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx,
				   struct dmx_ts_feed **ts_feed,
				   dmx_ts_cb callback)
@@ -2597,6 +2645,7 @@ static int dvbdmx_allocate_ts_feed(struct dmx_demux *dmx,
	(*ts_feed)->ts_insertion_terminate = NULL;
	(*ts_feed)->ts_insertion_insert_buffer =
		dvbdmx_ts_insertion_insert_buffer;
	(*ts_feed)->flush_buffer = dvbdmx_ts_flush_buffer;

	if (!(feed->filter = dvb_dmx_filter_alloc(demux))) {
		feed->state = DMX_STATE_FREE;
@@ -3013,6 +3062,7 @@ static int dvbdmx_allocate_section_feed(struct dmx_demux *demux,
	(*feed)->set_cipher_ops = dmx_section_set_cipher_ops;
	(*feed)->oob_command = dvbdmx_section_feed_oob_cmd;
	(*feed)->get_scrambling_bits = dvbdmx_section_get_scrambling_bits;
	(*feed)->flush_buffer = NULL;

	mutex_unlock(&dvbdmx->mutex);
	return 0;
+2 −0
Original line number Diff line number Diff line
@@ -250,6 +250,7 @@ struct dvb_demux {
			 const u8 timestamp[TIMESTAMP_LEN],
			 u64 *timestampIn27Mhz);
	int (*set_indexing)(struct dvb_demux_feed *feed);
	int (*flush_decoder_buffer)(struct dvb_demux_feed *feed, size_t length);

	int users;
#define MAX_DVB_DEMUX_USERS 10
@@ -335,6 +336,7 @@ void dvb_dmx_process_idx_pattern(struct dvb_demux_feed *feed,
void dvb_dmx_notify_idx_events(struct dvb_demux_feed *feed, int should_lock);
int dvb_dmx_notify_section_event(struct dvb_demux_feed *feed,
	struct dmx_data_ready *event, int should_lock);
void dvbdmx_ts_reset_pes_state(struct dvb_demux_feed *feed);

/**
 * dvb_dmx_is_video_feed - Returns whether the PES feed
+62 −8
Original line number Diff line number Diff line
/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -246,6 +246,14 @@ int mpq_streambuffer_pkt_write(
		return -ENODEV;
	}

	/* Make sure we can go to the next linear buffer */
	if (sbuff->mode == MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR &&
		sbuff->pending_buffers_count == sbuff->buffers_num &&
		packet->raw_data_len) {
		spin_unlock(&sbuff->packet_data.lock);
		return -ENOSPC;
	}

	len = sizeof(struct mpq_streambuffer_packet_header) +
		packet->user_data_len;

@@ -272,12 +280,8 @@ int mpq_streambuffer_pkt_write(
	dvb_ringbuffer_pkt_close(&sbuff->packet_data, idx);

	/* Move write pointer to next linear buffer for subsequent writes */
	if ((MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR == sbuff->mode) &&
		(packet->raw_data_len > 0)) {
		if (sbuff->pending_buffers_count == sbuff->buffers_num) {
			spin_unlock(&sbuff->packet_data.lock);
			return -ENOSPC;
		}
	if (MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR == sbuff->mode &&
		packet->raw_data_len) {
		DVB_RINGBUFFER_PUSH(&sbuff->raw_data,
				sizeof(struct mpq_streambuffer_buffer_desc));
		sbuff->pending_buffers_count++;
@@ -340,7 +344,7 @@ ssize_t mpq_streambuffer_data_write(

		if ((sbuff->pending_buffers_count == sbuff->buffers_num) ||
			((desc->size - desc->write_ptr) < len)) {
			MPQ_DVB_ERR_PRINT(
			MPQ_DVB_DBG_PRINT(
				"%s: No space available! %d pending buffers out of %d total buffers. write_ptr=%d, size=%d\n",
				__func__,
				sbuff->pending_buffers_count,
@@ -771,3 +775,53 @@ ssize_t mpq_streambuffer_metadata_free(struct mpq_streambuffer *sbuff)
}
EXPORT_SYMBOL(mpq_streambuffer_metadata_free);

int mpq_streambuffer_flush(struct mpq_streambuffer *sbuff)
{
	struct mpq_streambuffer_buffer_desc *desc;
	size_t len;
	int idx;
	int ret = 0;

	if (NULL == sbuff)
		return -EINVAL;

	spin_lock(&sbuff->packet_data.lock);
	spin_lock(&sbuff->raw_data.lock);

	/* Check if buffer was released */
	if (sbuff->packet_data.error == -ENODEV ||
		sbuff->raw_data.error == -ENODEV) {
		ret = -ENODEV;
		goto end;
	}

	if (sbuff->mode == MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR)
		while (sbuff->pending_buffers_count) {
			desc = (struct mpq_streambuffer_buffer_desc *)
				&sbuff->raw_data.data[sbuff->raw_data.pread];
			desc->write_ptr = 0;
			desc->read_ptr = 0;
			DVB_RINGBUFFER_SKIP(&sbuff->raw_data,
				sizeof(struct mpq_streambuffer_buffer_desc));
			sbuff->pending_buffers_count--;
		}
	else
		dvb_ringbuffer_flush(&sbuff->raw_data);

	/*
	 * Dispose all packets (simply flushing is not enough since we want
	 * the packets' status to move to disposed).
	 */
	do {
		idx = dvb_ringbuffer_pkt_next(&sbuff->packet_data, -1, &len);
		if (idx >= 0)
			dvb_ringbuffer_pkt_dispose(&sbuff->packet_data, idx);
	} while (idx >= 0);

end:
	spin_unlock(&sbuff->raw_data.lock);
	spin_unlock(&sbuff->packet_data.lock);
	return ret;
}
EXPORT_SYMBOL(mpq_streambuffer_flush);
Loading