aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx18/cx18-streams.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/cx18/cx18-streams.c')
-rw-r--r--drivers/media/video/cx18/cx18-streams.c72
1 files changed, 61 insertions, 11 deletions
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 987a9308d938..054450f65a60 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -319,11 +319,27 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister)
319 319
320 /* Teardown all streams */ 320 /* Teardown all streams */
321 for (type = 0; type < CX18_MAX_STREAMS; type++) { 321 for (type = 0; type < CX18_MAX_STREAMS; type++) {
322 if (cx->streams[type].dvb.enabled) { 322
323 cx18_dvb_unregister(&cx->streams[type]); 323 /* No struct video_device, but can have buffers allocated */
324 cx->streams[type].dvb.enabled = false; 324 if (type == CX18_ENC_STREAM_TYPE_TS) {
325 if (cx->streams[type].dvb.enabled) {
326 cx18_dvb_unregister(&cx->streams[type]);
327 cx->streams[type].dvb.enabled = false;
328 cx18_stream_free(&cx->streams[type]);
329 }
330 continue;
331 }
332
333 /* No struct video_device, but can have buffers allocated */
334 if (type == CX18_ENC_STREAM_TYPE_IDX) {
335 if (cx->stream_buffers[type] != 0) {
336 cx->stream_buffers[type] = 0;
337 cx18_stream_free(&cx->streams[type]);
338 }
339 continue;
325 } 340 }
326 341
342 /* If struct video_device exists, can have buffers allocated */
327 vdev = cx->streams[type].video_dev; 343 vdev = cx->streams[type].video_dev;
328 344
329 cx->streams[type].video_dev = NULL; 345 cx->streams[type].video_dev = NULL;
@@ -447,6 +463,32 @@ static void cx18_vbi_setup(struct cx18_stream *s)
447 cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data); 463 cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
448} 464}
449 465
466void cx18_stream_rotate_idx_mdls(struct cx18 *cx)
467{
468 struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
469 struct cx18_mdl *mdl;
470
471 if (!cx18_stream_enabled(s))
472 return;
473
474 /* Return if the firmware is not running low on MDLs */
475 if ((atomic_read(&s->q_free.depth) + atomic_read(&s->q_busy.depth)) >=
476 CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN)
477 return;
478
479 /* Return if there are no MDLs to rotate back to the firmware */
480 if (atomic_read(&s->q_full.depth) < 2)
481 return;
482
483 /*
484 * Take the oldest IDX MDL still holding data, and discard its index
485 * entries by scheduling the MDL to go back to the firmware
486 */
487 mdl = cx18_dequeue(s, &s->q_full);
488 if (mdl != NULL)
489 cx18_enqueue(s, mdl, &s->q_free);
490}
491
450static 492static
451struct cx18_queue *_cx18_stream_put_mdl_fw(struct cx18_stream *s, 493struct cx18_queue *_cx18_stream_put_mdl_fw(struct cx18_stream *s,
452 struct cx18_mdl *mdl) 494 struct cx18_mdl *mdl)
@@ -546,8 +588,9 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
546 struct cx18 *cx = s->cx; 588 struct cx18 *cx = s->cx;
547 int captype = 0; 589 int captype = 0;
548 struct cx18_api_func_private priv; 590 struct cx18_api_func_private priv;
591 struct cx18_stream *s_idx;
549 592
550 if (s->video_dev == NULL && s->dvb.enabled == 0) 593 if (!cx18_stream_enabled(s))
551 return -EINVAL; 594 return -EINVAL;
552 595
553 CX18_DEBUG_INFO("Start encoder stream %s\n", s->name); 596 CX18_DEBUG_INFO("Start encoder stream %s\n", s->name);
@@ -561,6 +604,9 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
561 cx->search_pack_header = 0; 604 cx->search_pack_header = 0;
562 break; 605 break;
563 606
607 case CX18_ENC_STREAM_TYPE_IDX:
608 captype = CAPTURE_CHANNEL_TYPE_INDEX;
609 break;
564 case CX18_ENC_STREAM_TYPE_TS: 610 case CX18_ENC_STREAM_TYPE_TS:
565 captype = CAPTURE_CHANNEL_TYPE_TS; 611 captype = CAPTURE_CHANNEL_TYPE_TS;
566 break; 612 break;
@@ -635,11 +681,13 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
635 cx18_vbi_setup(s); 681 cx18_vbi_setup(s);
636 682
637 /* 683 /*
638 * assign program index info. 684 * Select to receive I, P, and B frame index entries, if the
639 * Mask 7: select I/P/B, Num_req: 400 max 685 * index stream is enabled. Otherwise disable index entry
640 * FIXME - currently we have this hardcoded as disabled 686 * generation.
641 */ 687 */
642 cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 1, 0); 688 s_idx = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
689 cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 2,
690 s->handle, cx18_stream_enabled(s_idx) ? 7 : 0);
643 691
644 /* Call out to the common CX2341x API setup for user controls */ 692 /* Call out to the common CX2341x API setup for user controls */
645 priv.cx = cx; 693 priv.cx = cx;
@@ -697,6 +745,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
697 atomic_inc(&cx->tot_capturing); 745 atomic_inc(&cx->tot_capturing);
698 return 0; 746 return 0;
699} 747}
748EXPORT_SYMBOL(cx18_start_v4l2_encode_stream);
700 749
701void cx18_stop_all_captures(struct cx18 *cx) 750void cx18_stop_all_captures(struct cx18 *cx)
702{ 751{
@@ -705,7 +754,7 @@ void cx18_stop_all_captures(struct cx18 *cx)
705 for (i = CX18_MAX_STREAMS - 1; i >= 0; i--) { 754 for (i = CX18_MAX_STREAMS - 1; i >= 0; i--) {
706 struct cx18_stream *s = &cx->streams[i]; 755 struct cx18_stream *s = &cx->streams[i];
707 756
708 if (s->video_dev == NULL && s->dvb.enabled == 0) 757 if (!cx18_stream_enabled(s))
709 continue; 758 continue;
710 if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) 759 if (test_bit(CX18_F_S_STREAMING, &s->s_flags))
711 cx18_stop_v4l2_encode_stream(s, 0); 760 cx18_stop_v4l2_encode_stream(s, 0);
@@ -717,7 +766,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
717 struct cx18 *cx = s->cx; 766 struct cx18 *cx = s->cx;
718 unsigned long then; 767 unsigned long then;
719 768
720 if (s->video_dev == NULL && s->dvb.enabled == 0) 769 if (!cx18_stream_enabled(s))
721 return -EINVAL; 770 return -EINVAL;
722 771
723 /* This function assumes that you are allowed to stop the capture 772 /* This function assumes that you are allowed to stop the capture
@@ -762,6 +811,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
762 811
763 return 0; 812 return 0;
764} 813}
814EXPORT_SYMBOL(cx18_stop_v4l2_encode_stream);
765 815
766u32 cx18_find_handle(struct cx18 *cx) 816u32 cx18_find_handle(struct cx18 *cx)
767{ 817{
@@ -789,7 +839,7 @@ struct cx18_stream *cx18_handle_to_stream(struct cx18 *cx, u32 handle)
789 s = &cx->streams[i]; 839 s = &cx->streams[i];
790 if (s->handle != handle) 840 if (s->handle != handle)
791 continue; 841 continue;
792 if (s->video_dev || s->dvb.enabled) 842 if (cx18_stream_enabled(s))
793 return s; 843 return s;
794 } 844 }
795 return NULL; 845 return NULL;