diff options
Diffstat (limited to 'drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c')
-rw-r--r-- | drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c | 50 |
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 | ||
494 | static int solo_fill_mpeg(struct solo_enc_dev *solo_enc, | 481 | static 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 | ||
541 | static int solo_enc_fillbuf(struct solo_enc_dev *solo_enc, | 515 | static 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 | ||
770 | static 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 | |||
796 | static struct vb2_ops solo_enc_video_qops = { | 789 | static 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, |