📄 videodevx.c
字号:
v4l2_q_init(struct v4l2_queue *q){ if (q == NULL) return; q->qlock = rw_lock_unlocked; q->forw = (struct v4l2_q_node *)q; q->back = (struct v4l2_q_node *)q;}voidv4l2_q_add_head(struct v4l2_queue *q, struct v4l2_q_node *node){ unsigned long flags; if (q == NULL || node == NULL) return; if (q->forw == NULL || q->back == NULL) v4l2_q_init(q); write_lock_irqsave(&(q->qlock), flags); node->forw = q->forw; node->back = (struct v4l2_q_node *)q; q->forw->back = node; q->forw = node; write_unlock_irqrestore(&(q->qlock), flags);}voidv4l2_q_add_tail(struct v4l2_queue *q, struct v4l2_q_node *node){ unsigned long flags; if (q == NULL || node == NULL) return; if (q->forw == NULL || q->back == NULL) v4l2_q_init(q); write_lock_irqsave(&(q->qlock), flags); node->forw = (struct v4l2_q_node *)q; node->back = q->back; q->back->forw = node; q->back = node; write_unlock_irqrestore(&(q->qlock), flags);}void *v4l2_q_del_head(struct v4l2_queue *q){ unsigned long flags; struct v4l2_q_node *node; if (q == NULL) return NULL; write_lock_irqsave(&(q->qlock), flags); if (q->forw == NULL || q->back == NULL || q->forw == (struct v4l2_q_node *)q || q->back == (struct v4l2_q_node *)q) { write_unlock_irqrestore(&(q->qlock), flags); return NULL; } node = q->forw; node->forw->back = (struct v4l2_q_node *)q; q->forw = node->forw; node->forw = NULL; node->back = NULL; write_unlock_irqrestore(&(q->qlock), flags); return node;}void *v4l2_q_del_tail(struct v4l2_queue *q){ unsigned long flags; struct v4l2_q_node *node; if (q == NULL) return NULL; write_lock_irqsave(&(q->qlock), flags); if (q->forw == NULL || q->back == NULL || q->forw == (struct v4l2_q_node *)q || q->back == (struct v4l2_q_node *)q) { write_unlock_irqrestore(&(q->qlock), flags); return NULL; } node = q->back; node->back->forw = (struct v4l2_q_node *)q; q->back = node->back; node->forw = NULL; node->back = NULL; write_unlock_irqrestore(&(q->qlock), flags); return node;}void *v4l2_q_peek_head(struct v4l2_queue *q){ unsigned long flags; struct v4l2_q_node *node; read_lock_irqsave(&(q->qlock), flags); if (q == NULL || q->forw == NULL || q->forw == (struct v4l2_q_node *)q) { read_unlock_irqrestore(&(q->qlock), flags); return NULL; } node = q->forw; read_unlock_irqrestore(&(q->qlock), flags); return node;}void *v4l2_q_peek_tail(struct v4l2_queue *q){ unsigned long flags; struct v4l2_q_node *node; read_lock_irqsave(&(q->qlock), flags); if (q == NULL || q->back == NULL || q->back == (struct v4l2_q_node *)q) { read_unlock_irqrestore(&(q->qlock), flags); return NULL; } node = q->back; read_unlock_irqrestore(&(q->qlock), flags); return node;}void *v4l2_q_yank_node(struct v4l2_queue *q, struct v4l2_q_node *node){ unsigned long flags; struct v4l2_q_node *t; if (v4l2_q_peek_head(q) == NULL || node == NULL) return NULL; write_lock_irqsave(&(q->qlock), flags); for (t = q->forw; t != (struct v4l2_q_node *)q; t = t->forw) if (t == node) { node->back->forw = node->forw; node->forw->back = node->back; node->forw = NULL; node->back = NULL; write_unlock_irqrestore(&(q->qlock), flags); return node; } write_unlock_irqrestore(&(q->qlock), flags); return NULL;}intv4l2_q_last(struct v4l2_queue *q){/* This function by Olivier Carmona */ unsigned long flags; read_lock_irqsave(&(q->qlock), flags); if (q == NULL) { read_unlock_irqrestore(&(q->qlock), flags); return -1; } if (q->forw == NULL || q->back == NULL || q->forw == (struct v4l2_q_node *)q || q->back == (struct v4l2_q_node *)q) { read_unlock_irqrestore(&(q->qlock), flags); return -1; } if (q->forw == q->back) { read_unlock_irqrestore(&(q->qlock), flags); return 1; } read_unlock_irqrestore(&(q->qlock), flags); return 0;}/* * Math functions */u32v4l2_math_div6432(u64 a, u32 d, u32 *r){ u32 m = do_div(a, d); if (r) *r = m; return (u32)a;}unsigned longv4l2_timestamp_divide(stamp_t t, unsigned long p_100ns){ /* Note: 't' is in 1ns units, 'p_100ns' is in 100ns units, */ /* and the quotient is rounded */ u64 p; p = (u64)p_100ns * 100; /* 1ns units */ t >>= 6; /* /64 to allow p_100ns longer than 4 secs. */ p >>= 6; /* to keep quotient the same */ return v4l2_math_div6432((u64)t + (p >> 1), (u32)p, NULL);}/* Force the timestamp to be an integer multiple of p_100ns */unsigned longv4l2_timestamp_correct(stamp_t *t, unsigned long p_100ns){ /* Note: 't' is in 1ns units, 'p_100ns' is in 100ns units */ unsigned long n; n = v4l2_timestamp_divide((u64)*t, p_100ns); *t = (u64)p_100ns * n * 100; return n;}/* * Master clock operations */intv4l2_masterclock_register(struct v4l2_clock *clock){ if (clock == NULL || clock->gettime == NULL) return -1; if (masterclock != NULL) return -1; masterclock = clock; MOD_INC_USE_COUNT; return 0;}voidv4l2_masterclock_unregister(struct v4l2_clock *clock){ if (clock != masterclock) return; masterclock = NULL; MOD_DEC_USE_COUNT;}voidv4l2_masterclock_gettime(stamp_t *curr){ if (masterclock) masterclock->gettime(curr); else {#if defined(CONFIG_UST) || defined(CONFIG_UST_MODULE) ust_gettime(curr);#else struct timeval t; stamp_t stamp; do_gettimeofday(&t); stamp = (stamp_t)t.tv_sec * 1000000 + t.tv_usec; stamp *= 1000; *curr = stamp;#endif }}/* * Video Standard Operations (contributed by Michael Schimek) *//* This is the recommended method to deal with the framerate fields. More sophisticated drivers will access the fields directly. */unsigned intv4l2_video_std_fps(struct v4l2_standard *vs){ if (vs->framerate.numerator > 0) return (((vs->framerate.denominator << 8) / vs->framerate.numerator) + (1 << 7)) / (1 << 8); return 0;}/* Compute the time per frame in 100ns units */unsigned longv4l2_video_std_tpf(struct v4l2_standard *vs){ return v4l2_math_div6432( (u64)vs->framerate.numerator * 10000000 + vs->framerate.denominator / 2, vs->framerate.denominator, NULL);}/* Used only in v4l2_video_std_confirm() */static voidcatc1p2e6(__u8 *s, char c, int n){ n /= 10000; sprintf(s + strlen(s), "%c%d.%02d", c, n / 100, n % 100);}/* Verify the validity of the parameters of a v4l2_standard structure and create the name and id from the other fields. It does not relieve a driver from examining if it can fulfill the request. Returns an errno < 0 if inconsistent, 0 if an unknown but maybe usable format, or the V4L2_STD_XXX_X value if a known standard. */intv4l2_video_std_confirm(struct v4l2_standard *vs){ unsigned int rate = 0; unsigned int lines = vs->framelines; int std = 0; strcpy(vs->name, "Unknown"); if (vs->reserved1 || vs->reserved2) return -EINVAL; if (vs->framerate.numerator > 0 && vs->framerate.denominator > 0) rate = v4l2_video_std_fps(vs); if (vs->framelines >= 624 && vs->framelines <= 626) lines = 625; else if (vs->framelines >= 524 && vs->framelines <= 526) lines = 525; if (rate == 0 || lines == 0 || rate > 200) return -EINVAL; switch (vs->colorstandard) { case V4L2_COLOR_STD_PAL: strcpy(vs->name, "PAL"); if (rate == 25 && lines == 625) switch (vs->colorstandard_data.pal.colorsubcarrier) { case V4L2_COLOR_SUBC_PAL_N: strcpy(vs->name, "PAL-N"); if (vs->transmission & ~V4L2_TRANSM_STD_N) return -EINVAL; return V4L2_STD_PAL_N; case V4L2_COLOR_SUBC_PAL: if (vs->transmission & ~(V4L2_TRANSM_STD_B | V4L2_TRANSM_STD_G | V4L2_TRANSM_STD_H | V4L2_TRANSM_STD_I | V4L2_TRANSM_STD_D)) return -EINVAL; std = V4L2_STD_PAL; goto addtransm; } else if (rate == 30 && lines == 525) switch (vs->colorstandard_data.pal.colorsubcarrier) { case V4L2_COLOR_SUBC_PAL_M: strcpy(vs->name, "PAL-M"); if (vs->transmission & ~V4L2_TRANSM_STD_M) return -EINVAL; return V4L2_STD_PAL_M; case V4L2_COLOR_SUBC_PAL: strcpy(vs->name, "PAL-60"); if (vs->transmission) return -EINVAL; return V4L2_STD_PAL_60; } if (vs->transmission) return -EINVAL; catc1p2e6(vs->name, ' ', vs->colorstandard_data.pal.colorsubcarrier); break; case V4L2_COLOR_STD_NTSC: strcpy(vs->name, "NTSC"); if (rate == 25 && lines == 625) switch (vs->colorstandard_data.ntsc.colorsubcarrier) { case V4L2_COLOR_SUBC_NTSC: strcpy(vs->name, "NTSC-N"); if (vs->transmission & ~V4L2_TRANSM_STD_N) return -EINVAL; return V4L2_STD_NTSC_N; } else if (rate == 30 && lines == 525) switch (vs->colorstandard_data.ntsc.colorsubcarrier) { case V4L2_COLOR_SUBC_NTSC: if (vs->transmission & ~V4L2_TRANSM_STD_M) return -EINVAL; std = V4L2_STD_NTSC; goto addtransm; case V4L2_COLOR_SUBC_PAL: strcpy(vs->name, "NTSC-44"); if (vs->transmission) return -EINVAL; return V4L2_STD_NTSC_44; } if (vs->transmission) return -EINVAL; catc1p2e6(vs->name, ' ', vs->colorstandard_data.ntsc.colorsubcarrier); break; case V4L2_COLOR_STD_SECAM: strcpy(vs->name, "SECAM"); if (rate == 25 && lines == 625) if (vs->colorstandard_data.secam.f0b == V4L2_COLOR_SUBC_SECAMB && vs->colorstandard_data.secam.f0r == V4L2_COLOR_SUBC_SECAMR) { if (vs->transmission & ~(V4L2_TRANSM_STD_B | V4L2_TRANSM_STD_D | V4L2_TRANSM_STD_G | V4L2_TRANSM_STD_K | V4L2_TRANSM_STD_K1 | V4L2_TRANSM_STD_L)) return -EINVAL; std = V4L2_STD_SECAM; goto addtransm; } if (vs->transmission) return -EINVAL; catc1p2e6(vs->name, ' ', vs->colorstandard_data.secam.f0b); catc1p2e6(vs->name, '/', vs->colorstandard_data.secam.f0r); break; default: return -EINVAL; } sprintf(vs->name + strlen(vs->name), " %d/%d", vs->framelines, rate); return std; addtransm: if (vs->transmission) strcat(vs->name, "-"); if (vs->transmission & V4L2_TRANSM_STD_B) strcat(vs->name, "B/"); if (vs->transmission & V4L2_TRANSM_STD_G) strcat(vs->name, "G/"); if (vs->transmission & V4L2_TRANSM_STD_H) strcat(vs->name, "H/"); if (vs->transmission & V4L2_TRANSM_STD_I) strcat(vs->name, "I/"); if (vs->transmission & V4L2_TRANSM_STD_D) strcat(vs->name, "D/"); if (vs->transmission & V4L2_TRANSM_STD_K) strcat(vs->name, "K/"); if (vs->transmission & V4L2_TRANSM_STD_K1) strcat(vs->name, "K1/"); if (vs->transmission & V4L2_TRANSM_STD_L) strcat(vs->name, "L/"); if (vs->transmission & V4L2_TRANSM_STD_M) strcat(vs->name, "M/"); if (vs->transmission & V4L2_TRANSM_STD_N) strcat(vs->name, "N/"); if (vs->name[strlen(vs->name) - 1] == '/') vs->name[strlen(vs->name) - 1] = 0; return std;}/* Fill in the fields of a v4l2_standard structure according to the 'id' and 'transmission' parameters. Returns negative on error. */intv4l2_video_std_construct(struct v4l2_standard *vs, int id, __u32 transmission){ memset(vs, 0, sizeof(struct v4l2_standard)); vs->framerate.numerator = 1; vs->framerate.denominator = 25; vs->framelines = 625; switch (id) { case V4L2_STD_PAL_60: vs->framerate.numerator = 1001; vs->framerate.denominator = 30000; vs->framelines = 525; /* fall thru */ case V4L2_STD_PAL: vs->colorstandard = V4L2_COLOR_STD_PAL; vs->colorstandard_data.pal.colorsubcarrier = V4L2_COLOR_SUBC_PAL; break; case V4L2_STD_PAL_M: vs->framerate.numerator = 1001; vs->framerate.denominator = 30000; vs->framelines = 525; vs->colorstandard = V4L2_COLOR_STD_PAL; vs->colorstandard_data.pal.colorsubcarrier = V4L2_COLOR_SUBC_PAL_M; break; case V4L2_STD_PAL_N: vs->colorstandard = V4L2_COLOR_STD_PAL; vs->colorstandard_data.pal.colorsubcarrier = V4L2_COLOR_SUBC_PAL_N; break; case V4L2_STD_NTSC: vs->framerate.numerator = 1001; vs->framerate.denominator = 30000; vs->framelines = 525; /* fall thru */ case V4L2_STD_NTSC_N: vs->colorstandard = V4L2_COLOR_STD_NTSC; vs->colorstandard_data.ntsc.colorsubcarrier = V4L2_COLOR_SUBC_NTSC; break; case V4L2_STD_NTSC_44: vs->framerate.numerator = 1001; vs->framerate.denominator = 30000; vs->framelines = 525; vs->colorstandard = V4L2_COLOR_STD_NTSC; vs->colorstandard_data.ntsc.colorsubcarrier = V4L2_COLOR_SUBC_PAL; break; case V4L2_STD_SECAM: vs->colorstandard = V4L2_COLOR_STD_SECAM; vs->colorstandard_data.secam.f0b = V4L2_COLOR_SUBC_SECAMB; vs->colorstandard_data.secam.f0r = V4L2_COLOR_SUBC_SECAMR; break; default: return -EINVAL; } vs->transmission = transmission; return v4l2_video_std_confirm(vs);}/*---------------------------------------*/EXPORT_SYMBOL(v4l2_register_device);EXPORT_SYMBOL(v4l2_unregister_device);EXPORT_SYMBOL(v4l2_v4l_compat_register);EXPORT_SYMBOL(v4l2_v4l_compat_unregister);EXPORT_SYMBOL(v4l2_version);EXPORT_SYMBOL(v4l2_major_number);EXPORT_SYMBOL(v4l2_device_from_minor);EXPORT_SYMBOL(v4l2_device_from_file);EXPORT_SYMBOL(v4l2_openid_from_file);EXPORT_SYMBOL(v4l2_vmalloc_to_bus);EXPORT_SYMBOL(v4l2_vmalloc_to_page);EXPORT_SYMBOL(v4l2_q_init);EXPORT_SYMBOL(v4l2_q_add_head);EXPORT_SYMBOL(v4l2_q_add_tail);EXPORT_SYMBOL(v4l2_q_del_head);EXPORT_SYMBOL(v4l2_q_del_tail);EXPORT_SYMBOL(v4l2_q_peek_head);EXPORT_SYMBOL(v4l2_q_peek_tail);EXPORT_SYMBOL(v4l2_q_yank_node);EXPORT_SYMBOL(v4l2_q_last);EXPORT_SYMBOL(v4l2_math_div6432);EXPORT_SYMBOL(v4l2_timestamp_divide);EXPORT_SYMBOL(v4l2_timestamp_correct);EXPORT_SYMBOL(v4l2_masterclock_register);EXPORT_SYMBOL(v4l2_masterclock_unregister);EXPORT_SYMBOL(v4l2_masterclock_gettime);EXPORT_SYMBOL(v4l2_video_std_fps);EXPORT_SYMBOL(v4l2_video_std_tpf);EXPORT_SYMBOL(v4l2_video_std_confirm);EXPORT_SYMBOL(v4l2_video_std_construct);EXPORT_SYMBOL(video_register_device);EXPORT_SYMBOL(video_unregister_device);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -