/*
 * libexplain - a library of system-call-specific strerror replacements
 * Copyright (C) 2011 Peter Miller
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include <libexplain/ac/errno.h>
#include <libexplain/ac/string.h>
#include <libexplain/ac/linux/videodev2.h>
#include <libexplain/ac/sys/ioctl.h>

#include <libexplain/buffer/v4l2_control_id.h>
#include <libexplain/parse_bits.h>


#ifdef HAVE_LINUX_VIDEODEV2_H

/*
 * awk '/#define.V4L2_CID_.*BASE/{
 *     print "#ifdef " 42
 *     print "        { \"" $2 "\", " $2 " },"
 *     print "#endif"
 * }
 * ' /usr/include/linux/videodev2.h
 */
static const explain_parse_bits_table_t table[] =
{
#ifdef V4L2_CID_BRIGHTNESS
    { "V4L2_CID_BRIGHTNESS", V4L2_CID_BRIGHTNESS },
#endif
#ifdef V4L2_CID_CONTRAST
    { "V4L2_CID_CONTRAST", V4L2_CID_CONTRAST },
#endif
#ifdef V4L2_CID_SATURATION
    { "V4L2_CID_SATURATION", V4L2_CID_SATURATION },
#endif
#ifdef V4L2_CID_HUE
    { "V4L2_CID_HUE", V4L2_CID_HUE },
#endif
#ifdef V4L2_CID_AUDIO_VOLUME
    { "V4L2_CID_AUDIO_VOLUME", V4L2_CID_AUDIO_VOLUME },
#endif
#ifdef V4L2_CID_AUDIO_BALANCE
    { "V4L2_CID_AUDIO_BALANCE", V4L2_CID_AUDIO_BALANCE },
#endif
#ifdef V4L2_CID_AUDIO_BASS
    { "V4L2_CID_AUDIO_BASS", V4L2_CID_AUDIO_BASS },
#endif
#ifdef V4L2_CID_AUDIO_TREBLE
    { "V4L2_CID_AUDIO_TREBLE", V4L2_CID_AUDIO_TREBLE },
#endif
#ifdef V4L2_CID_AUDIO_MUTE
    { "V4L2_CID_AUDIO_MUTE", V4L2_CID_AUDIO_MUTE },
#endif
#ifdef V4L2_CID_AUDIO_LOUDNESS
    { "V4L2_CID_AUDIO_LOUDNESS", V4L2_CID_AUDIO_LOUDNESS },
#endif
#ifdef V4L2_CID_BLACK_LEVEL
    { "V4L2_CID_BLACK_LEVEL", V4L2_CID_BLACK_LEVEL },
#endif
#ifdef V4L2_CID_AUTO_WHITE_BALANCE
    { "V4L2_CID_AUTO_WHITE_BALANCE", V4L2_CID_AUTO_WHITE_BALANCE },
#endif
#ifdef V4L2_CID_DO_WHITE_BALANCE
    { "V4L2_CID_DO_WHITE_BALANCE", V4L2_CID_DO_WHITE_BALANCE },
#endif
#ifdef V4L2_CID_RED_BALANCE
    { "V4L2_CID_RED_BALANCE", V4L2_CID_RED_BALANCE },
#endif
#ifdef V4L2_CID_BLUE_BALANCE
    { "V4L2_CID_BLUE_BALANCE", V4L2_CID_BLUE_BALANCE },
#endif
#ifdef V4L2_CID_GAMMA
    { "V4L2_CID_GAMMA", V4L2_CID_GAMMA },
#endif
#ifdef V4L2_CID_EXPOSURE
    { "V4L2_CID_EXPOSURE", V4L2_CID_EXPOSURE },
#endif
#ifdef V4L2_CID_AUTOGAIN
    { "V4L2_CID_AUTOGAIN", V4L2_CID_AUTOGAIN },
#endif
#ifdef V4L2_CID_GAIN
    { "V4L2_CID_GAIN", V4L2_CID_GAIN },
#endif
#ifdef V4L2_CID_HFLIP
    { "V4L2_CID_HFLIP", V4L2_CID_HFLIP },
#endif
#ifdef V4L2_CID_VFLIP
    { "V4L2_CID_VFLIP", V4L2_CID_VFLIP },
#endif
#ifdef V4L2_CID_HCENTER
    { "V4L2_CID_HCENTER", V4L2_CID_HCENTER },
#endif
#ifdef V4L2_CID_VCENTER
    { "V4L2_CID_VCENTER", V4L2_CID_VCENTER },
#endif
#ifdef V4L2_CID_POWER_LINE_FREQUENCY
    { "V4L2_CID_POWER_LINE_FREQUENCY", V4L2_CID_POWER_LINE_FREQUENCY },
#endif
#ifdef V4L2_CID_HUE_AUTO
    { "V4L2_CID_HUE_AUTO", V4L2_CID_HUE_AUTO },
#endif
#ifdef V4L2_CID_WHITE_BALANCE_TEMPERATURE
    { "V4L2_CID_WHITE_BALANCE_TEMPERATURE",
        V4L2_CID_WHITE_BALANCE_TEMPERATURE },
#endif
#ifdef V4L2_CID_SHARPNESS
    { "V4L2_CID_SHARPNESS", V4L2_CID_SHARPNESS },
#endif
#ifdef V4L2_CID_BACKLIGHT_COMPENSATION
    { "V4L2_CID_BACKLIGHT_COMPENSATION", V4L2_CID_BACKLIGHT_COMPENSATION },
#endif
#ifdef V4L2_CID_CHROMA_AGC
    { "V4L2_CID_CHROMA_AGC", V4L2_CID_CHROMA_AGC },
#endif
#ifdef V4L2_CID_COLOR_KILLER
    { "V4L2_CID_COLOR_KILLER", V4L2_CID_COLOR_KILLER },
#endif
#ifdef V4L2_CID_COLORFX
    { "V4L2_CID_COLORFX", V4L2_CID_COLORFX },
#endif
#ifdef V4L2_CID_AUTOBRIGHTNESS
    { "V4L2_CID_AUTOBRIGHTNESS", V4L2_CID_AUTOBRIGHTNESS },
#endif
#ifdef V4L2_CID_BAND_STOP_FILTER
    { "V4L2_CID_BAND_STOP_FILTER", V4L2_CID_BAND_STOP_FILTER },
#endif
#ifdef V4L2_CID_ROTATE
    { "V4L2_CID_ROTATE", V4L2_CID_ROTATE },
#endif
#ifdef V4L2_CID_BG_COLOR
    { "V4L2_CID_BG_COLOR", V4L2_CID_BG_COLOR },
#endif
#ifdef V4L2_CID_CHROMA_GAIN
    { "V4L2_CID_CHROMA_GAIN", V4L2_CID_CHROMA_GAIN },
#endif
#ifdef V4L2_CID_ILLUMINATORS_1
    { "V4L2_CID_ILLUMINATORS_1", V4L2_CID_ILLUMINATORS_1 },
#endif
#ifdef V4L2_CID_ILLUMINATORS_2
    { "V4L2_CID_ILLUMINATORS_2", V4L2_CID_ILLUMINATORS_2 },
#endif
#ifdef V4L2_CID_LASTP1
    { "V4L2_CID_LASTP1", V4L2_CID_LASTP1 },
#endif
#ifdef V4L2_CID_MPEG_STREAM_TYPE
    { "V4L2_CID_MPEG_STREAM_TYPE", V4L2_CID_MPEG_STREAM_TYPE },
#endif
#ifdef V4L2_CID_MPEG_STREAM_PID_PMT
    { "V4L2_CID_MPEG_STREAM_PID_PMT", V4L2_CID_MPEG_STREAM_PID_PMT },
#endif
#ifdef V4L2_CID_MPEG_STREAM_PID_AUDIO
    { "V4L2_CID_MPEG_STREAM_PID_AUDIO", V4L2_CID_MPEG_STREAM_PID_AUDIO },
#endif
#ifdef V4L2_CID_MPEG_STREAM_PID_VIDEO
    { "V4L2_CID_MPEG_STREAM_PID_VIDEO", V4L2_CID_MPEG_STREAM_PID_VIDEO },
#endif
#ifdef V4L2_CID_MPEG_STREAM_PID_PCR
    { "V4L2_CID_MPEG_STREAM_PID_PCR", V4L2_CID_MPEG_STREAM_PID_PCR },
#endif
#ifdef V4L2_CID_MPEG_STREAM_PES_ID_AUDIO
    { "V4L2_CID_MPEG_STREAM_PES_ID_AUDIO", V4L2_CID_MPEG_STREAM_PES_ID_AUDIO },
#endif
#ifdef V4L2_CID_MPEG_STREAM_PES_ID_VIDEO
    { "V4L2_CID_MPEG_STREAM_PES_ID_VIDEO", V4L2_CID_MPEG_STREAM_PES_ID_VIDEO },
#endif
#ifdef V4L2_CID_MPEG_STREAM_VBI_FMT
    { "V4L2_CID_MPEG_STREAM_VBI_FMT", V4L2_CID_MPEG_STREAM_VBI_FMT },
#endif
#ifdef V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ
    { "V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ", V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ },
#endif
#ifdef V4L2_CID_MPEG_AUDIO_ENCODING
    { "V4L2_CID_MPEG_AUDIO_ENCODING", V4L2_CID_MPEG_AUDIO_ENCODING },
#endif
#ifdef V4L2_CID_MPEG_AUDIO_L1_BITRATE
    { "V4L2_CID_MPEG_AUDIO_L1_BITRATE", V4L2_CID_MPEG_AUDIO_L1_BITRATE },
#endif
#ifdef V4L2_CID_MPEG_AUDIO_L2_BITRATE
    { "V4L2_CID_MPEG_AUDIO_L2_BITRATE", V4L2_CID_MPEG_AUDIO_L2_BITRATE },
#endif
#ifdef V4L2_CID_MPEG_AUDIO_L3_BITRATE
    { "V4L2_CID_MPEG_AUDIO_L3_BITRATE", V4L2_CID_MPEG_AUDIO_L3_BITRATE },
#endif
#ifdef V4L2_CID_MPEG_AUDIO_MODE
    { "V4L2_CID_MPEG_AUDIO_MODE", V4L2_CID_MPEG_AUDIO_MODE },
#endif
#ifdef V4L2_CID_MPEG_AUDIO_MODE_EXTENSION
    { "V4L2_CID_MPEG_AUDIO_MODE_EXTENSION",
        V4L2_CID_MPEG_AUDIO_MODE_EXTENSION },
#endif
#ifdef V4L2_CID_MPEG_AUDIO_EMPHASIS
    { "V4L2_CID_MPEG_AUDIO_EMPHASIS", V4L2_CID_MPEG_AUDIO_EMPHASIS },
#endif
#ifdef V4L2_CID_MPEG_AUDIO_CRC
    { "V4L2_CID_MPEG_AUDIO_CRC", V4L2_CID_MPEG_AUDIO_CRC },
#endif
#ifdef V4L2_CID_MPEG_AUDIO_MUTE
    { "V4L2_CID_MPEG_AUDIO_MUTE", V4L2_CID_MPEG_AUDIO_MUTE },
#endif
#ifdef V4L2_CID_MPEG_AUDIO_AAC_BITRATE
    { "V4L2_CID_MPEG_AUDIO_AAC_BITRATE", V4L2_CID_MPEG_AUDIO_AAC_BITRATE },
#endif
#ifdef V4L2_CID_MPEG_AUDIO_AC3_BITRATE
    { "V4L2_CID_MPEG_AUDIO_AC3_BITRATE", V4L2_CID_MPEG_AUDIO_AC3_BITRATE },
#endif
#ifdef V4L2_CID_MPEG_VIDEO_ENCODING
    { "V4L2_CID_MPEG_VIDEO_ENCODING", V4L2_CID_MPEG_VIDEO_ENCODING },
#endif
#ifdef V4L2_CID_MPEG_VIDEO_ASPECT
    { "V4L2_CID_MPEG_VIDEO_ASPECT", V4L2_CID_MPEG_VIDEO_ASPECT },
#endif
#ifdef V4L2_CID_MPEG_VIDEO_B_FRAMES
    { "V4L2_CID_MPEG_VIDEO_B_FRAMES", V4L2_CID_MPEG_VIDEO_B_FRAMES },
#endif
#ifdef V4L2_CID_MPEG_VIDEO_GOP_SIZE
    { "V4L2_CID_MPEG_VIDEO_GOP_SIZE", V4L2_CID_MPEG_VIDEO_GOP_SIZE },
#endif
#ifdef V4L2_CID_MPEG_VIDEO_GOP_CLOSURE
    { "V4L2_CID_MPEG_VIDEO_GOP_CLOSURE", V4L2_CID_MPEG_VIDEO_GOP_CLOSURE },
#endif
#ifdef V4L2_CID_MPEG_VIDEO_PULLDOWN
    { "V4L2_CID_MPEG_VIDEO_PULLDOWN", V4L2_CID_MPEG_VIDEO_PULLDOWN },
#endif
#ifdef V4L2_CID_MPEG_VIDEO_BITRATE_MODE
    { "V4L2_CID_MPEG_VIDEO_BITRATE_MODE", V4L2_CID_MPEG_VIDEO_BITRATE_MODE },
#endif
#ifdef V4L2_CID_MPEG_VIDEO_BITRATE
    { "V4L2_CID_MPEG_VIDEO_BITRATE", V4L2_CID_MPEG_VIDEO_BITRATE },
#endif
#ifdef V4L2_CID_MPEG_VIDEO_BITRATE_PEAK
    { "V4L2_CID_MPEG_VIDEO_BITRATE_PEAK", V4L2_CID_MPEG_VIDEO_BITRATE_PEAK },
#endif
#ifdef V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION
    { "V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION",
        V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION },
#endif
#ifdef V4L2_CID_MPEG_VIDEO_MUTE
    { "V4L2_CID_MPEG_VIDEO_MUTE", V4L2_CID_MPEG_VIDEO_MUTE },
#endif
#ifdef V4L2_CID_MPEG_VIDEO_MUTE_YUV
    { "V4L2_CID_MPEG_VIDEO_MUTE_YUV", V4L2_CID_MPEG_VIDEO_MUTE_YUV },
#endif
#ifdef V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE
    { "V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE",
        V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE },
#endif
#ifdef V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER
    { "V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER",
        V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER },
#endif
#ifdef V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE
    { "V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE",
        V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE },
#endif
#ifdef V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE
    { "V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE",
        V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE },
#endif
#ifdef V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE
    { "V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE",
        V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE },
#endif
#ifdef V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER
    { "V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER",
        V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER },
#endif
#ifdef V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE
    { "V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE",
        V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE },
#endif
#ifdef V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM
    { "V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM",
        V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM },
#endif
#ifdef V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP
    { "V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP",
        V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP },
#endif
#ifdef V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM
    { "V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM",
        V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM },
#endif
#ifdef V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP
    { "V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP",
        V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP },
#endif
#ifdef V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS
    { "V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS",
        V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS },
#endif
#ifdef V4L2_CID_EXPOSURE_AUTO
    { "V4L2_CID_EXPOSURE_AUTO", V4L2_CID_EXPOSURE_AUTO },
#endif
#ifdef V4L2_CID_EXPOSURE_ABSOLUTE
    { "V4L2_CID_EXPOSURE_ABSOLUTE", V4L2_CID_EXPOSURE_ABSOLUTE },
#endif
#ifdef V4L2_CID_EXPOSURE_AUTO_PRIORITY
    { "V4L2_CID_EXPOSURE_AUTO_PRIORITY", V4L2_CID_EXPOSURE_AUTO_PRIORITY },
#endif
#ifdef V4L2_CID_PAN_RELATIVE
    { "V4L2_CID_PAN_RELATIVE", V4L2_CID_PAN_RELATIVE },
#endif
#ifdef V4L2_CID_TILT_RELATIVE
    { "V4L2_CID_TILT_RELATIVE", V4L2_CID_TILT_RELATIVE },
#endif
#ifdef V4L2_CID_PAN_RESET
    { "V4L2_CID_PAN_RESET", V4L2_CID_PAN_RESET },
#endif
#ifdef V4L2_CID_TILT_RESET
    { "V4L2_CID_TILT_RESET", V4L2_CID_TILT_RESET },
#endif
#ifdef V4L2_CID_PAN_ABSOLUTE
    { "V4L2_CID_PAN_ABSOLUTE", V4L2_CID_PAN_ABSOLUTE },
#endif
#ifdef V4L2_CID_TILT_ABSOLUTE
    { "V4L2_CID_TILT_ABSOLUTE", V4L2_CID_TILT_ABSOLUTE },
#endif
#ifdef V4L2_CID_FOCUS_ABSOLUTE
    { "V4L2_CID_FOCUS_ABSOLUTE", V4L2_CID_FOCUS_ABSOLUTE },
#endif
#ifdef V4L2_CID_FOCUS_RELATIVE
    { "V4L2_CID_FOCUS_RELATIVE", V4L2_CID_FOCUS_RELATIVE },
#endif
#ifdef V4L2_CID_FOCUS_AUTO
    { "V4L2_CID_FOCUS_AUTO", V4L2_CID_FOCUS_AUTO },
#endif
#ifdef V4L2_CID_ZOOM_ABSOLUTE
    { "V4L2_CID_ZOOM_ABSOLUTE", V4L2_CID_ZOOM_ABSOLUTE },
#endif
#ifdef V4L2_CID_ZOOM_RELATIVE
    { "V4L2_CID_ZOOM_RELATIVE", V4L2_CID_ZOOM_RELATIVE },
#endif
#ifdef V4L2_CID_ZOOM_CONTINUOUS
    { "V4L2_CID_ZOOM_CONTINUOUS", V4L2_CID_ZOOM_CONTINUOUS },
#endif
#ifdef V4L2_CID_PRIVACY
    { "V4L2_CID_PRIVACY", V4L2_CID_PRIVACY },
#endif
#ifdef V4L2_CID_IRIS_ABSOLUTE
    { "V4L2_CID_IRIS_ABSOLUTE", V4L2_CID_IRIS_ABSOLUTE },
#endif
#ifdef V4L2_CID_IRIS_RELATIVE
    { "V4L2_CID_IRIS_RELATIVE", V4L2_CID_IRIS_RELATIVE },
#endif
#ifdef V4L2_CID_RDS_TX_DEVIATION
    { "V4L2_CID_RDS_TX_DEVIATION", V4L2_CID_RDS_TX_DEVIATION },
#endif
#ifdef V4L2_CID_RDS_TX_PI
    { "V4L2_CID_RDS_TX_PI", V4L2_CID_RDS_TX_PI },
#endif
#ifdef V4L2_CID_RDS_TX_PTY
    { "V4L2_CID_RDS_TX_PTY", V4L2_CID_RDS_TX_PTY },
#endif
#ifdef V4L2_CID_RDS_TX_PS_NAME
    { "V4L2_CID_RDS_TX_PS_NAME", V4L2_CID_RDS_TX_PS_NAME },
#endif
#ifdef V4L2_CID_RDS_TX_RADIO_TEXT
    { "V4L2_CID_RDS_TX_RADIO_TEXT", V4L2_CID_RDS_TX_RADIO_TEXT },
#endif
#ifdef V4L2_CID_AUDIO_LIMITER_ENABLED
    { "V4L2_CID_AUDIO_LIMITER_ENABLED", V4L2_CID_AUDIO_LIMITER_ENABLED },
#endif
#ifdef V4L2_CID_AUDIO_LIMITER_RELEASE_TIME
    { "V4L2_CID_AUDIO_LIMITER_RELEASE_TIME",
        V4L2_CID_AUDIO_LIMITER_RELEASE_TIME },
#endif
#ifdef V4L2_CID_AUDIO_LIMITER_DEVIATION
    { "V4L2_CID_AUDIO_LIMITER_DEVIATION", V4L2_CID_AUDIO_LIMITER_DEVIATION },
#endif
#ifdef V4L2_CID_AUDIO_COMPRESSION_ENABLED
    { "V4L2_CID_AUDIO_COMPRESSION_ENABLED",
        V4L2_CID_AUDIO_COMPRESSION_ENABLED },
#endif
#ifdef V4L2_CID_AUDIO_COMPRESSION_GAIN
    { "V4L2_CID_AUDIO_COMPRESSION_GAIN", V4L2_CID_AUDIO_COMPRESSION_GAIN },
#endif
#ifdef V4L2_CID_AUDIO_COMPRESSION_THRESHOLD
    { "V4L2_CID_AUDIO_COMPRESSION_THRESHOLD",
        V4L2_CID_AUDIO_COMPRESSION_THRESHOLD },
#endif
#ifdef V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME
    { "V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME",
        V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME },
#endif
#ifdef V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME
    { "V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME",
        V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME },
#endif
#ifdef V4L2_CID_PILOT_TONE_ENABLED
    { "V4L2_CID_PILOT_TONE_ENABLED", V4L2_CID_PILOT_TONE_ENABLED },
#endif
#ifdef V4L2_CID_PILOT_TONE_DEVIATION
    { "V4L2_CID_PILOT_TONE_DEVIATION", V4L2_CID_PILOT_TONE_DEVIATION },
#endif
#ifdef V4L2_CID_PILOT_TONE_FREQUENCY
    { "V4L2_CID_PILOT_TONE_FREQUENCY", V4L2_CID_PILOT_TONE_FREQUENCY },
#endif
#ifdef V4L2_CID_TUNE_PREEMPHASIS
    { "V4L2_CID_TUNE_PREEMPHASIS", V4L2_CID_TUNE_PREEMPHASIS },
#endif
#ifdef V4L2_CID_TUNE_POWER_LEVEL
    { "V4L2_CID_TUNE_POWER_LEVEL", V4L2_CID_TUNE_POWER_LEVEL },
#endif
#ifdef V4L2_CID_TUNE_ANTENNA_CAPACITOR
    { "V4L2_CID_TUNE_ANTENNA_CAPACITOR", V4L2_CID_TUNE_ANTENNA_CAPACITOR },
#endif
};


void
explain_buffer_v4l2_control_id(explain_string_buffer_t *sb, int value)
{
    if (value & V4L2_CTRL_FLAG_NEXT_CTRL)
    {
        explain_string_buffer_puts(sb, "V4L2_CTRL_FLAG_NEXT_CTRL | ");
        value &= ~V4L2_CTRL_FLAG_NEXT_CTRL;
    }
    explain_parse_bits_print_single(sb, value, table, SIZEOF(table));
}


enum explain_v4l2_control_id_check_t
explain_v4l2_control_id_check(int fildes, int data)
{
    struct v4l2_queryctrl dummy;

    memset(&dummy, 0, sizeof(dummy));
    dummy.id = data & ~V4L2_CTRL_FLAG_NEXT_CTRL;
    if (ioctl(fildes, VIDIOC_QUERYCTRL, &dummy) >= 0)
        return explain_v4l2_control_id_check_ok;
    switch (errno)
    {
    case EIO:
    case EINVAL:
        if (explain_parse_bits_find_by_value(data, table, SIZEOF(table)))
            return explain_v4l2_control_id_check_notsup;
        return explain_v4l2_control_id_check_nosuch;

    default:
        if (explain_parse_bits_find_by_value(data, table, SIZEOF(table)))
            return explain_v4l2_control_id_check_notsup;
        return explain_v4l2_control_id_check_no_idea;
    }
}

#endif


/* vim: set ts=8 sw=4 et : */
