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

Commit 5f97e60d authored by Hamad Kadmany's avatar Hamad Kadmany
Browse files

media: dvb: Fix video framing



When frame pattern splits over TS packets,
the pattern start-code was regarded part
of the previous video frame instead of the
new video frame.

Change-Id: I453706aa3cd53c368379f2555a9e492f5a21cbeb
Signed-off-by: default avatarHamad Kadmany <hkadmany@codeaurora.org>
parent abedad47
Loading
Loading
Loading
Loading
+57 −6
Original line number Diff line number Diff line
@@ -2518,8 +2518,7 @@ static int mpq_dmx_process_video_packet_framing(
		ts_payload_offset += buf[ts_payload_offset] + 1;
	}

	/* 188 bytes: the size of a TS packet including the TS packet header */
	bytes_avail = 188 - ts_payload_offset;
	bytes_avail = TS_PACKET_SIZE - ts_payload_offset;

	/* Get the mandatory fields of the video PES header */
	if (mpq_dmx_parse_mandatory_pes_header(feed, feed_data,
@@ -2747,7 +2746,8 @@ static int mpq_dmx_process_video_packet_framing(
				&(meta_data.info.framing.pts_dts_info));
			mpq_dmx_save_pts_dts(feed_data);

			packet.raw_data_len = feed_data->pending_pattern_len;
			packet.raw_data_len = feed_data->pending_pattern_len -
				framing_res.info[i].used_prefix_size;
			packet.raw_data_offset = feed_data->frame_offset;
			meta_data.info.framing.pattern_type =
				feed_data->last_framing_match_type;
@@ -2790,11 +2790,51 @@ static int mpq_dmx_process_video_packet_framing(

			feed->data_ready_cb.ts(&feed->feed.ts, &data);

			feed_data->pending_pattern_len = 0;
			mpq_streambuffer_get_data_rw_offset(
				feed_data->video_buffer,
				NULL,
				&feed_data->frame_offset);

			/*
			 * In linear buffers, after writing the packet
			 * we switched over to a new linear buffer for the new
			 * frame. In that case, we should re-write the prefix
			 * of the existing frame if any exists.
			 */
			if ((MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR ==
				 feed_data->video_buffer->mode) &&
				framing_res.info[i].used_prefix_size) {
				ret = mpq_streambuffer_data_write(stream_buffer,
					feed_data->prev_pattern +
					 DVB_DMX_MAX_PATTERN_LEN -
					 framing_res.info[i].used_prefix_size,
					framing_res.info[i].used_prefix_size);

				if (ret < 0) {
					feed_data->pending_pattern_len = 0;
					mpq_demux->decoder_drop_count +=
					 framing_res.info[i].used_prefix_size;
					feed_data->ts_dropped_bytes +=
					 framing_res.info[i].used_prefix_size;
				} else {
					feed_data->pending_pattern_len =
					 framing_res.info[i].used_prefix_size;
				}
			} else {
				s32 offset = (s32)feed_data->frame_offset;
				u32 buff_size =
				 feed_data->video_buffer->buffers[0].size;

				offset -= framing_res.info[i].used_prefix_size;
				offset += (offset < 0) ? buff_size : 0;
				feed_data->pending_pattern_len =
					framing_res.info[i].used_prefix_size;

				if (MPQ_STREAMBUFFER_BUFFER_MODE_RING ==
					feed_data->video_buffer->mode) {
					feed_data->frame_offset = (u32)offset;
				}
			}
		}

		/* save the last match for next time */
@@ -2811,11 +2851,23 @@ static int mpq_dmx_process_video_packet_framing(
	feed_data->prev_stc = curr_stc;
	feed_data->first_prefix_size = 0;

	/*
	 * Save the trailing of the TS packet as we might have a pattern
	 * split that we need to re-use when closing the next
	 * video linear buffer.
	 */
	if (MPQ_STREAMBUFFER_BUFFER_MODE_LINEAR ==
		feed_data->video_buffer->mode)
		memcpy(feed_data->prev_pattern,
			buf + TS_PACKET_SIZE - DVB_DMX_MAX_PATTERN_LEN,
			DVB_DMX_MAX_PATTERN_LEN);

	if (pending_data_len) {
		ret = mpq_streambuffer_data_write(
			stream_buffer,
			(buf + ts_payload_offset + bytes_written),
			pending_data_len);

		if (ret < 0) {
			mpq_demux->decoder_drop_count += pending_data_len;
			feed_data->ts_dropped_bytes += pending_data_len;
@@ -2983,8 +3035,7 @@ static int mpq_dmx_process_video_packet_no_framing(
		ts_payload_offset += buf[ts_payload_offset] + 1;
	}

	/* 188 bytes: size of a TS packet including the TS packet header */
	bytes_avail = 188 - ts_payload_offset;
	bytes_avail = TS_PACKET_SIZE - ts_payload_offset;

	/* Get the mandatory fields of the video PES header */
	if (mpq_dmx_parse_mandatory_pes_header(feed, feed_data,
+2 −0
Original line number Diff line number Diff line
@@ -262,6 +262,7 @@ struct mpq_decoder_buffers_desc {
 * with this stream buffer.
 * @patterns: pointer to the framing patterns to look for.
 * @patterns_num: number of framing patterns.
 * @prev_pattern: holds the trailing data of the last processed video packet.
 * @frame_offset: Saves data buffer offset to which a new frame will be written
 * @last_pattern_offset: Holds the previous pattern offset
 * @pending_pattern_len: Accumulated number of data bytes that will be
@@ -312,6 +313,7 @@ struct mpq_video_feed_info {
	const struct dvb_dmx_video_patterns
		*patterns[DVB_DMX_MAX_SEARCH_PATTERN_NUM];
	int patterns_num;
	char prev_pattern[DVB_DMX_MAX_PATTERN_LEN];
	u32 frame_offset;
	u32 last_pattern_offset;
	u32 pending_pattern_len;