diff options
author | Philipp Zabel <p.zabel@pengutronix.de> | 2014-08-05 13:00:17 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-08-21 16:25:25 -0400 |
commit | 18fd0cceb99fdfd551bb6520703f8e1be4f3f364 (patch) | |
tree | cc82334f83e6fc73f2ba0c2b07cf1584955d3d0e | |
parent | 68fc31c5d29690685476ea3fbc7da8876f227792 (diff) |
[media] coda: fix timestamp list handling
Lock modification of the timestamp list with bitstream_mutex and do not
try to remove a timestamp element if the list is empty. This can happen
if the userspace feeds us garbage or multiple encoded frames in a single
buffer.
Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Kamil Debski <k.debski@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r-- | drivers/media/platform/coda/coda-bit.c | 28 | ||||
-rw-r--r-- | drivers/media/platform/coda/coda-common.c | 2 |
2 files changed, 21 insertions, 9 deletions
diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c index 529cc3e8acb0..18fa369d204d 100644 --- a/drivers/media/platform/coda/coda-bit.c +++ b/drivers/media/platform/coda/coda-bit.c | |||
@@ -1699,18 +1699,28 @@ static void coda_finish_decode(struct coda_ctx *ctx) | |||
1699 | v4l2_err(&dev->v4l2_dev, | 1699 | v4l2_err(&dev->v4l2_dev, |
1700 | "decoded frame index out of range: %d\n", decoded_idx); | 1700 | "decoded frame index out of range: %d\n", decoded_idx); |
1701 | } else { | 1701 | } else { |
1702 | ts = list_first_entry(&ctx->timestamp_list, | ||
1703 | struct coda_timestamp, list); | ||
1704 | list_del(&ts->list); | ||
1705 | val = coda_read(dev, CODA_RET_DEC_PIC_FRAME_NUM) - 1; | 1702 | val = coda_read(dev, CODA_RET_DEC_PIC_FRAME_NUM) - 1; |
1706 | val -= ctx->sequence_offset; | 1703 | val -= ctx->sequence_offset; |
1707 | if (val != (ts->sequence & 0xffff)) { | 1704 | mutex_lock(&ctx->bitstream_mutex); |
1708 | v4l2_err(&dev->v4l2_dev, | 1705 | if (!list_empty(&ctx->timestamp_list)) { |
1709 | "sequence number mismatch (%d(%d) != %d)\n", | 1706 | ts = list_first_entry(&ctx->timestamp_list, |
1710 | val, ctx->sequence_offset, ts->sequence); | 1707 | struct coda_timestamp, list); |
1708 | list_del(&ts->list); | ||
1709 | if (val != (ts->sequence & 0xffff)) { | ||
1710 | v4l2_err(&dev->v4l2_dev, | ||
1711 | "sequence number mismatch (%d(%d) != %d)\n", | ||
1712 | val, ctx->sequence_offset, | ||
1713 | ts->sequence); | ||
1714 | } | ||
1715 | ctx->frame_timestamps[decoded_idx] = *ts; | ||
1716 | kfree(ts); | ||
1717 | } else { | ||
1718 | v4l2_err(&dev->v4l2_dev, "empty timestamp list!\n"); | ||
1719 | memset(&ctx->frame_timestamps[decoded_idx], 0, | ||
1720 | sizeof(struct coda_timestamp)); | ||
1721 | ctx->frame_timestamps[decoded_idx].sequence = val; | ||
1711 | } | 1722 | } |
1712 | ctx->frame_timestamps[decoded_idx] = *ts; | 1723 | mutex_unlock(&ctx->bitstream_mutex); |
1713 | kfree(ts); | ||
1714 | 1724 | ||
1715 | val = coda_read(dev, CODA_RET_DEC_PIC_TYPE) & 0x7; | 1725 | val = coda_read(dev, CODA_RET_DEC_PIC_TYPE) & 0x7; |
1716 | if (val == 0) | 1726 | if (val == 0) |
diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index 0f8a2c970405..e84b32088fc0 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c | |||
@@ -1116,12 +1116,14 @@ static void coda_stop_streaming(struct vb2_queue *q) | |||
1116 | if (!ctx->streamon_out && !ctx->streamon_cap) { | 1116 | if (!ctx->streamon_out && !ctx->streamon_cap) { |
1117 | struct coda_timestamp *ts; | 1117 | struct coda_timestamp *ts; |
1118 | 1118 | ||
1119 | mutex_lock(&ctx->bitstream_mutex); | ||
1119 | while (!list_empty(&ctx->timestamp_list)) { | 1120 | while (!list_empty(&ctx->timestamp_list)) { |
1120 | ts = list_first_entry(&ctx->timestamp_list, | 1121 | ts = list_first_entry(&ctx->timestamp_list, |
1121 | struct coda_timestamp, list); | 1122 | struct coda_timestamp, list); |
1122 | list_del(&ts->list); | 1123 | list_del(&ts->list); |
1123 | kfree(ts); | 1124 | kfree(ts); |
1124 | } | 1125 | } |
1126 | mutex_unlock(&ctx->bitstream_mutex); | ||
1125 | kfifo_init(&ctx->bitstream_fifo, | 1127 | kfifo_init(&ctx->bitstream_fifo, |
1126 | ctx->bitstream.vaddr, ctx->bitstream.size); | 1128 | ctx->bitstream.vaddr, ctx->bitstream.size); |
1127 | ctx->runcounter = 0; | 1129 | ctx->runcounter = 0; |