diff options
author | John Sheu <sheu@google.com> | 2014-03-11 18:52:02 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-05-23 13:56:34 -0400 |
commit | e933cefa0f6e9cf40c8f4ae6d4da8ebb3f765ba0 (patch) | |
tree | 17c16c78ddfd88e7a4d3aa85d6f0bd42938081a4 /drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | |
parent | 535ec214e23adaf72c775938e9e9c6c1cf6fc5b9 (diff) |
[media] s5p-mfc: fix encoder crash after VIDIOC_STREAMOFF
VIDIOC_STREAMOFF clears the encoder's destination queue -- routines run
from the interrupt handler cannot assume that the queue is non-empty.
Signed-off-by: John Sheu <sheu@google.com>
Signed-off-by: Kamil Debski <k.debski@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media/platform/s5p-mfc/s5p_mfc_enc.c')
-rw-r--r-- | drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c index 458279e5dc80..704e37c07903 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c | |||
@@ -772,13 +772,16 @@ static int enc_post_seq_start(struct s5p_mfc_ctx *ctx) | |||
772 | 772 | ||
773 | if (p->seq_hdr_mode == V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) { | 773 | if (p->seq_hdr_mode == V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) { |
774 | spin_lock_irqsave(&dev->irqlock, flags); | 774 | spin_lock_irqsave(&dev->irqlock, flags); |
775 | dst_mb = list_entry(ctx->dst_queue.next, | 775 | if (!list_empty(&ctx->dst_queue)) { |
776 | struct s5p_mfc_buf, list); | 776 | dst_mb = list_entry(ctx->dst_queue.next, |
777 | list_del(&dst_mb->list); | 777 | struct s5p_mfc_buf, list); |
778 | ctx->dst_queue_cnt--; | 778 | list_del(&dst_mb->list); |
779 | vb2_set_plane_payload(dst_mb->b, 0, | 779 | ctx->dst_queue_cnt--; |
780 | s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, dev)); | 780 | vb2_set_plane_payload(dst_mb->b, 0, |
781 | vb2_buffer_done(dst_mb->b, VB2_BUF_STATE_DONE); | 781 | s5p_mfc_hw_call(dev->mfc_ops, get_enc_strm_size, |
782 | dev)); | ||
783 | vb2_buffer_done(dst_mb->b, VB2_BUF_STATE_DONE); | ||
784 | } | ||
782 | spin_unlock_irqrestore(&dev->irqlock, flags); | 785 | spin_unlock_irqrestore(&dev->irqlock, flags); |
783 | } | 786 | } |
784 | 787 | ||
@@ -883,8 +886,7 @@ static int enc_post_frame_start(struct s5p_mfc_ctx *ctx) | |||
883 | mfc_debug(2, "enc src count: %d, enc ref count: %d\n", | 886 | mfc_debug(2, "enc src count: %d, enc ref count: %d\n", |
884 | ctx->src_queue_cnt, ctx->ref_queue_cnt); | 887 | ctx->src_queue_cnt, ctx->ref_queue_cnt); |
885 | } | 888 | } |
886 | if (strm_size > 0) { | 889 | if ((ctx->dst_queue_cnt > 0) && (strm_size > 0)) { |
887 | /* at least one more dest. buffers exist always */ | ||
888 | mb_entry = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, | 890 | mb_entry = list_entry(ctx->dst_queue.next, struct s5p_mfc_buf, |
889 | list); | 891 | list); |
890 | list_del(&mb_entry->list); | 892 | list_del(&mb_entry->list); |