msm: dvb: Pass STC attached to video packet in video stream-buffer
STC may be used by video consumer to notify applications on the
time of arrival of video frames.
Change-Id: If7a00f6412a73621a1c665f0586f786ed06ace61
Signed-off-by: Hamad Kadmany <hkadmany@codeaurora.org>
diff --git a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb/dvb-core/demux.h
index f0b9b05..89500f9 100644
--- a/drivers/media/dvb/dvb-core/demux.h
+++ b/drivers/media/dvb/dvb-core/demux.h
@@ -127,6 +127,7 @@
u32 cont_err_counter;
u32 ts_packets_num;
u32 ts_dropped_bytes;
+ u64 stc;
} buf;
struct {
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index 3f144d1..96dd0ef 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -2406,6 +2406,7 @@
event.params.es_data.pts = dmx_data_ready->buf.pts;
event.params.es_data.dts_valid = dmx_data_ready->buf.dts_exists;
event.params.es_data.dts = dmx_data_ready->buf.dts;
+ event.params.es_data.stc = dmx_data_ready->buf.stc;
event.params.es_data.transport_error_indicator_counter =
dmx_data_ready->buf.tei_counter;
event.params.es_data.continuity_error_counter =
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
index 36f7680..e3b5e3d 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
+++ b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.c
@@ -25,6 +25,9 @@
/* Length of mandatory fields that must exist in header of video PES */
#define PES_MANDATORY_FIELDS_LEN 9
+/* Index of first byte in TS packet holding STC */
+#define STC_LOCATION_IDX 188
+
#define MAX_PES_LENGTH (SZ_64K)
#define MAX_TS_PACKETS_FOR_SDMX_PROCESS (500)
@@ -2126,6 +2129,14 @@
size_t len = 0;
struct dmx_pts_dts_info *pts_dts;
+ if (meta_data->packet_type == DMX_PES_PACKET) {
+ pts_dts = &meta_data->info.pes.pts_dts_info;
+ data->buf.stc = meta_data->info.pes.stc;
+ } else {
+ pts_dts = &meta_data->info.framing.pts_dts_info;
+ data->buf.stc = meta_data->info.framing.stc;
+ }
+
pts_dts = meta_data->packet_type == DMX_PES_PACKET ?
&meta_data->info.pes.pts_dts_info :
&meta_data->info.framing.pts_dts_info;
@@ -2237,6 +2248,7 @@
packet.raw_data_offset = feed_data->frame_offset;
meta_data.info.framing.pattern_type =
feed_data->last_framing_match_type;
+ meta_data.info.framing.stc = feed_data->last_framing_match_stc;
mpq_streambuffer_get_buffer_handle(stream_buffer,
0, /* current write buffer handle */
@@ -2309,6 +2321,7 @@
mpq_dmx_save_pts_dts(feed_data);
meta_data.packet_type = DMX_PES_PACKET;
+ meta_data.info.pes.stc = feed_data->prev_stc;
mpq_dmx_update_decoder_stat(mpq_demux);
@@ -2335,7 +2348,8 @@
static int mpq_dmx_process_video_packet_framing(
struct dvb_demux_feed *feed,
- const u8 *buf)
+ const u8 *buf,
+ u64 curr_stc)
{
int bytes_avail;
u32 ts_payload_offset;
@@ -2520,7 +2534,8 @@
* pass data to decoder only after sequence header
* or equivalent is found. Otherwise the data is dropped.
*/
- if (!(feed_data->found_sequence_header_pattern)) {
+ if (!feed_data->found_sequence_header_pattern) {
+ feed_data->prev_stc = curr_stc;
spin_unlock(&feed_data->video_buffer_lock);
return 0;
}
@@ -2623,6 +2638,12 @@
framing_res.info[i].type;
feed_data->last_pattern_offset =
framing_res.info[i].offset;
+ if (framing_res.info[i].used_prefix_size)
+ feed_data->last_framing_match_stc =
+ feed_data->prev_stc;
+ else
+ feed_data->last_framing_match_stc =
+ curr_stc;
continue;
}
/*
@@ -2668,6 +2689,8 @@
packet.raw_data_offset = feed_data->frame_offset;
meta_data.info.framing.pattern_type =
feed_data->last_framing_match_type;
+ meta_data.info.framing.stc =
+ feed_data->last_framing_match_stc;
mpq_streambuffer_get_buffer_handle(
stream_buffer,
@@ -2708,8 +2731,13 @@
framing_res.info[i].type;
feed_data->last_pattern_offset =
framing_res.info[i].offset;
+ if (framing_res.info[i].used_prefix_size)
+ feed_data->last_framing_match_stc = feed_data->prev_stc;
+ else
+ feed_data->last_framing_match_stc = curr_stc;
}
+ feed_data->prev_stc = curr_stc;
feed_data->first_prefix_size = 0;
if (pending_data_len) {
@@ -2734,7 +2762,8 @@
static int mpq_dmx_process_video_packet_no_framing(
struct dvb_demux_feed *feed,
- const u8 *buf)
+ const u8 *buf,
+ u64 curr_stc)
{
int bytes_avail;
u32 ts_payload_offset;
@@ -2810,6 +2839,7 @@
mpq_dmx_save_pts_dts(feed_data);
meta_data.packet_type = DMX_PES_PACKET;
+ meta_data.info.pes.stc = feed_data->prev_stc;
mpq_dmx_update_decoder_stat(mpq_demux);
@@ -2852,6 +2882,8 @@
} else {
feed->pusi_seen = 1;
}
+
+ feed_data->prev_stc = curr_stc;
}
/*
@@ -3001,10 +3033,25 @@
struct dvb_demux_feed *feed,
const u8 *buf)
{
+ u64 curr_stc;
+ struct mpq_demux *mpq_demux = feed->demux->priv;
+
+ if ((mpq_demux->source >= DMX_SOURCE_DVR0) &&
+ (mpq_demux->demux.tsp_format != DMX_TSP_FORMAT_192_TAIL)) {
+ curr_stc = 0;
+ } else {
+ curr_stc = buf[STC_LOCATION_IDX + 2] << 16;
+ curr_stc += buf[STC_LOCATION_IDX + 1] << 8;
+ curr_stc += buf[STC_LOCATION_IDX];
+ curr_stc *= 256; /* convert from 105.47 KHZ to 27MHz */
+ }
+
if (mpq_dmx_info.decoder_framing)
- return mpq_dmx_process_video_packet_no_framing(feed, buf);
+ return mpq_dmx_process_video_packet_no_framing(feed, buf,
+ curr_stc);
else
- return mpq_dmx_process_video_packet_framing(feed, buf);
+ return mpq_dmx_process_video_packet_framing(feed, buf,
+ curr_stc);
}
EXPORT_SYMBOL(mpq_dmx_process_video_packet);
@@ -3075,9 +3122,9 @@
(mpq_demux->demux.tsp_format != DMX_TSP_FORMAT_192_TAIL)) {
stc = 0;
} else {
- stc = buf[190] << 16;
- stc += buf[189] << 8;
- stc += buf[188];
+ stc = buf[STC_LOCATION_IDX + 2] << 16;
+ stc += buf[STC_LOCATION_IDX + 1] << 8;
+ stc += buf[STC_LOCATION_IDX];
stc *= 256; /* convert from 105.47 KHZ to 27MHz */
}
@@ -4105,6 +4152,9 @@
pes_header = (struct pes_packet_header *)
&metadata_buf[pes_header_offset];
meta_data.packet_type = DMX_PES_PACKET;
+ /* TODO - set to real STC when SDMX supports it */
+ meta_data.info.pes.stc = 0;
+
if (pes_header->pts_dts_flag & 0x2) {
meta_data.info.pes.pts_dts_info.pts_exist = 1;
meta_data.info.pes.pts_dts_info.pts =
diff --git a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.h b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.h
index 90beb78..fd0c06b 100644
--- a/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.h
+++ b/drivers/media/platform/msm/dvb/demux/mpq_dmx_plugin_common.h
@@ -244,6 +244,8 @@
* reported for this frame.
* @last_framing_match_type: Used for saving the type of
* the previous pattern match found in this video feed.
+ * @last_framing_match_stc: Used for saving the STC attached to TS packet
+ * of the previous pattern match found in this video feed.
* @found_sequence_header_pattern: Flag used to note that an MPEG-2
* Sequence Header, H.264 SPS or VC-1 Sequence Header pattern
* (whichever is relevant according to the video standard) had already
@@ -272,6 +274,7 @@
* buffer space.
* @last_pkt_index: used to save the last streambuffer packet index reported in
* a new elementary stream data event.
+ * @prev_stc: STC attached to the previous video TS packet
*/
struct mpq_video_feed_info {
struct mpq_streambuffer *video_buffer;
@@ -289,6 +292,7 @@
u32 last_pattern_offset;
u32 pending_pattern_len;
u64 last_framing_match_type;
+ u64 last_framing_match_stc;
int found_sequence_header_pattern;
struct dvb_dmx_video_prefix_size_masks prefix_size;
u32 first_prefix_size;
@@ -303,6 +307,7 @@
u32 ts_packets_num;
u32 ts_dropped_bytes;
int last_pkt_index;
+ u64 prev_stc;
};
/**
diff --git a/drivers/media/platform/msm/dvb/include/mpq_adapter.h b/drivers/media/platform/msm/dvb/include/mpq_adapter.h
index 19abbbe..a2ade18 100644
--- a/drivers/media/platform/msm/dvb/include/mpq_adapter.h
+++ b/drivers/media/platform/msm/dvb/include/mpq_adapter.h
@@ -64,11 +64,17 @@
/** PTS/DTS information */
struct dmx_pts_dts_info pts_dts_info;
+
+ /** STC value attached to first TS packet holding the pattern */
+ u64 stc;
};
struct dmx_pes_packet_info {
/** PTS/DTS information */
struct dmx_pts_dts_info pts_dts_info;
+
+ /** STC value attached to first TS packet holding the PES */
+ u64 stc;
};
struct dmx_marker_info {
diff --git a/include/linux/dvb/dmx.h b/include/linux/dvb/dmx.h
index c2b35c8..c219725 100644
--- a/include/linux/dvb/dmx.h
+++ b/include/linux/dvb/dmx.h
@@ -368,6 +368,9 @@
/* DTS value associated with the buffer */
__u64 dts;
+ /* STC value associated with the buffer in 27MHz */
+ __u64 stc;
+
/*
* Number of TS packets with Transport Error Indicator (TEI) set
* in the TS packet header since last reported event