Ticket #4466: input-switching-v1.patch

File input-switching-v1.patch, 2.8 KB (added by danielk, 13 years ago)

Patch for ivtv driver to address the problem

  • linux/drivers/media/video/ivtv/ivtv-ioctl.c

    diff -r 1a1258f9ba2d linux/drivers/media/video/ivtv/ivtv-ioctl.c
    a b int ivtv_v4l2_ioctls(struct ivtv *itv, s 
    932932
    933933        case VIDIOC_S_INPUT:{
    934934                int inp = *(int *)arg;
     935                int restart = 0;
     936                int restarts[IVTV_MAX_STREAMS];
    935937
    936938                if (inp < 0 || inp >= itv->nof_inputs)
    937939                        return -EINVAL;
    int ivtv_v4l2_ioctls(struct ivtv *itv, s 
    941943                        break;
    942944                }
    943945                if (atomic_read(&itv->capturing) > 0) {
    944                         return -EBUSY;
     946                        IVTV_DEBUG_INFO("We're doing an input switch "
     947                                        "while capturing..\n");
     948                        restart = ivtv_stop_all_captures_temp(itv,0,restarts);
    945949                }
    946950                IVTV_DEBUG_INFO("Changing input from %d to %d\n",
    947951                                itv->active_input, inp);
    int ivtv_v4l2_ioctls(struct ivtv *itv, s 
    957961                ivtv_video_set_io(itv);
    958962                ivtv_audio_set_io(itv);
    959963                ivtv_unmute(itv);
     964
     965                if (restart) {
     966                        int ok = ivtv_restart_all_captures(itv, restarts);
     967                        /* TODO handle errors */
     968                }
     969
    960970                break;
    961971        }
    962972
  • linux/drivers/media/video/ivtv/ivtv-streams.c

    diff -r 1a1258f9ba2d linux/drivers/media/video/ivtv/ivtv-streams.c
    a b void ivtv_stop_all_captures(struct ivtv  
    709709        }
    710710}
    711711
     712int ivtv_stop_all_captures_temp(struct ivtv *itv, int gop_end, int *stopped)
     713{
     714        int i;
     715        int total = 0;
     716
     717        for (i = IVTV_MAX_STREAMS - 1; i >= 0; i--) {
     718                struct ivtv_stream *s = &itv->streams[i];
     719
     720                stopped[i] = 0;
     721
     722                if (s->v4l2dev == NULL)
     723                        continue;
     724                if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
     725                        stopped[i] = 1;
     726                        total++;
     727                        ivtv_stop_v4l2_encode_stream(s, gop_end);
     728                }
     729        }
     730
     731        return total;
     732}
     733
     734int ivtv_restart_all_captures(struct ivtv *itv, int *stopped)
     735{
     736        int i;
     737        int errors = 0;
     738
     739        for (i = IVTV_MAX_STREAMS - 1; i >= 0; i--) {
     740                struct ivtv_stream *s = &itv->streams[i];
     741
     742                if (s->v4l2dev == NULL)
     743                        continue;
     744
     745                if (!stopped[i])
     746                        continue;
     747
     748                errors += (0 == ivtv_start_v4l2_encode_stream(s)) ? 0 : 1;
     749        }
     750
     751        return errors;
     752}
     753
    712754int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
    713755{
    714756        struct ivtv *itv = s->itv;
  • linux/drivers/media/video/ivtv/ivtv-streams.h

    diff -r 1a1258f9ba2d linux/drivers/media/video/ivtv/ivtv-streams.h
    a b void ivtv_stop_all_captures(struct ivtv  
    3434void ivtv_stop_all_captures(struct ivtv *itv);
    3535int ivtv_passthrough_mode(struct ivtv *itv, int enable);
    3636
     37int ivtv_stop_all_captures_temp(struct ivtv *itv, int gop_end, int *stopped);
     38int ivtv_restart_all_captures(struct ivtv *itv, int *stopped);
     39
    3740#endif