aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c')
-rw-r--r--drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c50
1 files changed, 22 insertions, 28 deletions
diff --git a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c
index 4f6bfba58065..6e933d383fa2 100644
--- a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c
+++ b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c
@@ -463,7 +463,6 @@ static int solo_fill_jpeg(struct solo_enc_dev *solo_enc,
463 struct solo_dev *solo_dev = solo_enc->solo_dev; 463 struct solo_dev *solo_dev = solo_enc->solo_dev;
464 struct sg_table *vbuf = vb2_dma_sg_plane_desc(vb, 0); 464 struct sg_table *vbuf = vb2_dma_sg_plane_desc(vb, 0);
465 int frame_size; 465 int frame_size;
466 int ret;
467 466
468 vb->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME; 467 vb->v4l2_buf.flags |= V4L2_BUF_FLAG_KEYFRAME;
469 468
@@ -473,22 +472,10 @@ static int solo_fill_jpeg(struct solo_enc_dev *solo_enc,
473 frame_size = ALIGN(vop_jpeg_size(vh) + solo_enc->jpeg_len, DMA_ALIGN); 472 frame_size = ALIGN(vop_jpeg_size(vh) + solo_enc->jpeg_len, DMA_ALIGN);
474 vb2_set_plane_payload(vb, 0, vop_jpeg_size(vh) + solo_enc->jpeg_len); 473 vb2_set_plane_payload(vb, 0, vop_jpeg_size(vh) + solo_enc->jpeg_len);
475 474
476 /* may discard all previous data in vbuf->sgl */ 475 return solo_send_desc(solo_enc, solo_enc->jpeg_len, vbuf,
477 if (!dma_map_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents,
478 DMA_FROM_DEVICE))
479 return -ENOMEM;
480 ret = solo_send_desc(solo_enc, solo_enc->jpeg_len, vbuf,
481 vop_jpeg_offset(vh) - SOLO_JPEG_EXT_ADDR(solo_dev), 476 vop_jpeg_offset(vh) - SOLO_JPEG_EXT_ADDR(solo_dev),
482 frame_size, SOLO_JPEG_EXT_ADDR(solo_dev), 477 frame_size, SOLO_JPEG_EXT_ADDR(solo_dev),
483 SOLO_JPEG_EXT_SIZE(solo_dev)); 478 SOLO_JPEG_EXT_SIZE(solo_dev));
484 dma_unmap_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents,
485 DMA_FROM_DEVICE);
486
487 /* add the header only after dma_unmap_sg() */
488 sg_copy_from_buffer(vbuf->sgl, vbuf->nents,
489 solo_enc->jpeg_header, solo_enc->jpeg_len);
490
491 return ret;
492} 479}
493 480
494static int solo_fill_mpeg(struct solo_enc_dev *solo_enc, 481static int solo_fill_mpeg(struct solo_enc_dev *solo_enc,
@@ -498,7 +485,6 @@ static int solo_fill_mpeg(struct solo_enc_dev *solo_enc,
498 struct sg_table *vbuf = vb2_dma_sg_plane_desc(vb, 0); 485 struct sg_table *vbuf = vb2_dma_sg_plane_desc(vb, 0);
499 int frame_off, frame_size; 486 int frame_off, frame_size;
500 int skip = 0; 487 int skip = 0;
501 int ret;
502 488
503 if (vb2_plane_size(vb, 0) < vop_mpeg_size(vh)) 489 if (vb2_plane_size(vb, 0) < vop_mpeg_size(vh))
504 return -EIO; 490 return -EIO;
@@ -521,21 +507,9 @@ static int solo_fill_mpeg(struct solo_enc_dev *solo_enc,
521 sizeof(*vh)) % SOLO_MP4E_EXT_SIZE(solo_dev); 507 sizeof(*vh)) % SOLO_MP4E_EXT_SIZE(solo_dev);
522 frame_size = ALIGN(vop_mpeg_size(vh) + skip, DMA_ALIGN); 508 frame_size = ALIGN(vop_mpeg_size(vh) + skip, DMA_ALIGN);
523 509
524 /* may discard all previous data in vbuf->sgl */ 510 return solo_send_desc(solo_enc, skip, vbuf, frame_off, frame_size,
525 if (!dma_map_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents,
526 DMA_FROM_DEVICE))
527 return -ENOMEM;
528 ret = solo_send_desc(solo_enc, skip, vbuf, frame_off, frame_size,
529 SOLO_MP4E_EXT_ADDR(solo_dev), 511 SOLO_MP4E_EXT_ADDR(solo_dev),
530 SOLO_MP4E_EXT_SIZE(solo_dev)); 512 SOLO_MP4E_EXT_SIZE(solo_dev));
531 dma_unmap_sg(&solo_dev->pdev->dev, vbuf->sgl, vbuf->nents,
532 DMA_FROM_DEVICE);
533
534 /* add the header only after dma_unmap_sg() */
535 if (!vop_type(vh))
536 sg_copy_from_buffer(vbuf->sgl, vbuf->nents,
537 solo_enc->vop, solo_enc->vop_len);
538 return ret;
539} 513}
540 514
541static int solo_enc_fillbuf(struct solo_enc_dev *solo_enc, 515static int solo_enc_fillbuf(struct solo_enc_dev *solo_enc,
@@ -793,9 +767,29 @@ static void solo_enc_stop_streaming(struct vb2_queue *q)
793 spin_unlock_irqrestore(&solo_enc->av_lock, flags); 767 spin_unlock_irqrestore(&solo_enc->av_lock, flags);
794} 768}
795 769
770static void solo_enc_buf_finish(struct vb2_buffer *vb)
771{
772 struct solo_enc_dev *solo_enc = vb2_get_drv_priv(vb->vb2_queue);
773 struct sg_table *vbuf = vb2_dma_sg_plane_desc(vb, 0);
774
775 switch (solo_enc->fmt) {
776 case V4L2_PIX_FMT_MPEG4:
777 case V4L2_PIX_FMT_H264:
778 if (vb->v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME)
779 sg_copy_from_buffer(vbuf->sgl, vbuf->nents,
780 solo_enc->vop, solo_enc->vop_len);
781 break;
782 default: /* V4L2_PIX_FMT_MJPEG */
783 sg_copy_from_buffer(vbuf->sgl, vbuf->nents,
784 solo_enc->jpeg_header, solo_enc->jpeg_len);
785 break;
786 }
787}
788
796static struct vb2_ops solo_enc_video_qops = { 789static struct vb2_ops solo_enc_video_qops = {
797 .queue_setup = solo_enc_queue_setup, 790 .queue_setup = solo_enc_queue_setup,
798 .buf_queue = solo_enc_buf_queue, 791 .buf_queue = solo_enc_buf_queue,
792 .buf_finish = solo_enc_buf_finish,
799 .start_streaming = solo_enc_start_streaming, 793 .start_streaming = solo_enc_start_streaming,
800 .stop_streaming = solo_enc_stop_streaming, 794 .stop_streaming = solo_enc_stop_streaming,
801 .wait_prepare = vb2_ops_wait_prepare, 795 .wait_prepare = vb2_ops_wait_prepare,