diff options
author | Krzysztof HaĆasa <khalasa@piap.pl> | 2013-09-12 07:43:34 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2013-10-14 05:33:22 -0400 |
commit | 39e30a22d2f03feba7fd8cbb79e3c1d93e812c2e (patch) | |
tree | ce49ce1cc573c36e23a8c3aac5344cbcc7cada7e | |
parent | 4a61ad3c4a2c8b50f6b5835d0d36bd8639b9f7ee (diff) |
[media] SOLO6x10: Fix video headers on certain hardware
On certain platforms a sequence of dma_map_sg() and dma_unmap_sg()
discards data previously stored in the buffers. Build video headers
only after the DMA is completed.
Signed-off-by: Krzysztof Ha?asa <khalasa@piap.pl>
[hans.verkuil@cisco.com: fix merge problems due to the recent solo sg_table changes]
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r-- | drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c b/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c index 9bf878d57af4..51200a3e4bd7 100644 --- a/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c +++ b/drivers/staging/media/solo6x10/solo6x10-v4l2-enc.c | |||
@@ -472,14 +472,11 @@ static int solo_fill_jpeg(struct solo_enc_dev *solo_enc, | |||
472 | if (vb2_plane_size(vb, 0) < vop_jpeg_size(vh) + solo_enc->jpeg_len) | 472 | if (vb2_plane_size(vb, 0) < vop_jpeg_size(vh) + solo_enc->jpeg_len) |
473 | return -EIO; | 473 | return -EIO; |
474 | 474 | ||
475 | sg_copy_from_buffer(vbuf->sgl, vbuf->nents, | ||
476 | solo_enc->jpeg_header, | ||
477 | solo_enc->jpeg_len); | ||
478 | |||
479 | frame_size = (vop_jpeg_size(vh) + solo_enc->jpeg_len + (DMA_ALIGN - 1)) | 475 | frame_size = (vop_jpeg_size(vh) + solo_enc->jpeg_len + (DMA_ALIGN - 1)) |
480 | & ~(DMA_ALIGN - 1); | 476 | & ~(DMA_ALIGN - 1); |
481 | vb2_set_plane_payload(vb, 0, vop_jpeg_size(vh) + solo_enc->jpeg_len); | 477 | vb2_set_plane_payload(vb, 0, vop_jpeg_size(vh) + solo_enc->jpeg_len); |
482 | 478 | ||
479 | /* may discard all previous data in vbuf->sgl */ | ||
483 | dma_map_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents, | 480 | dma_map_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents, |
484 | DMA_FROM_DEVICE); | 481 | DMA_FROM_DEVICE); |
485 | ret = solo_send_desc(solo_enc, solo_enc->jpeg_len, vbuf, | 482 | ret = solo_send_desc(solo_enc, solo_enc->jpeg_len, vbuf, |
@@ -488,6 +485,11 @@ static int solo_fill_jpeg(struct solo_enc_dev *solo_enc, | |||
488 | SOLO_JPEG_EXT_SIZE(solo_dev)); | 485 | SOLO_JPEG_EXT_SIZE(solo_dev)); |
489 | dma_unmap_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents, | 486 | dma_unmap_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents, |
490 | DMA_FROM_DEVICE); | 487 | DMA_FROM_DEVICE); |
488 | |||
489 | /* add the header only after dma_unmap_sg() */ | ||
490 | sg_copy_from_buffer(vbuf->sgl, vbuf->nents, | ||
491 | solo_enc->jpeg_header, solo_enc->jpeg_len); | ||
492 | |||
491 | return ret; | 493 | return ret; |
492 | } | 494 | } |
493 | 495 | ||
@@ -505,12 +507,7 @@ static int solo_fill_mpeg(struct solo_enc_dev *solo_enc, | |||
505 | 507 | ||
506 | /* If this is a key frame, add extra header */ | 508 | /* If this is a key frame, add extra header */ |
507 | if (!vop_type(vh)) { | 509 | if (!vop_type(vh)) { |
508 | sg_copy_from_buffer(vbuf->sgl, vbuf->nents, | ||
509 | solo_enc->vop, | ||
510 | solo_enc->vop_len); | ||
511 | |||
512 | skip = solo_enc->vop_len; | 510 | skip = solo_enc->vop_len; |
513 | |||
514 | vb->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME; | 511 | vb->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME; |
515 | vb2_set_plane_payload(vb, 0, vop_mpeg_size(vh) + solo_enc->vop_len); | 512 | vb2_set_plane_payload(vb, 0, vop_mpeg_size(vh) + solo_enc->vop_len); |
516 | } else { | 513 | } else { |
@@ -524,6 +521,7 @@ static int solo_fill_mpeg(struct solo_enc_dev *solo_enc, | |||
524 | frame_size = (vop_mpeg_size(vh) + skip + (DMA_ALIGN - 1)) | 521 | frame_size = (vop_mpeg_size(vh) + skip + (DMA_ALIGN - 1)) |
525 | & ~(DMA_ALIGN - 1); | 522 | & ~(DMA_ALIGN - 1); |
526 | 523 | ||
524 | /* may discard all previous data in vbuf->sgl */ | ||
527 | dma_map_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents, | 525 | dma_map_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents, |
528 | DMA_FROM_DEVICE); | 526 | DMA_FROM_DEVICE); |
529 | ret = solo_send_desc(solo_enc, skip, vbuf, frame_off, frame_size, | 527 | ret = solo_send_desc(solo_enc, skip, vbuf, frame_off, frame_size, |
@@ -531,6 +529,11 @@ static int solo_fill_mpeg(struct solo_enc_dev *solo_enc, | |||
531 | SOLO_MP4E_EXT_SIZE(solo_dev)); | 529 | SOLO_MP4E_EXT_SIZE(solo_dev)); |
532 | dma_unmap_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents, | 530 | dma_unmap_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents, |
533 | DMA_FROM_DEVICE); | 531 | DMA_FROM_DEVICE); |
532 | |||
533 | /* add the header only after dma_unmap_sg() */ | ||
534 | if (!vop_type(vh)) | ||
535 | sg_copy_from_buffer(vbuf->sgl, vbuf->nents, | ||
536 | solo_enc->vop, solo_enc->vop_len); | ||
534 | return ret; | 537 | return ret; |
535 | } | 538 | } |
536 | 539 | ||