// Copyright 2019 Google LLC.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Code generated file. DO NOT EDIT.

// Package videointelligence provides access to the Cloud Video Intelligence API.
//
// This package is DEPRECATED. Use package cloud.google.com/go/videointelligence/apiv1 instead.
//
// For product documentation, see: https://cloud.google.com/video-intelligence/docs/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/videointelligence/v1p1beta1"
//   ...
//   ctx := context.Background()
//   videointelligenceService, err := videointelligence.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for authentication.
//
// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// Other authentication options
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   videointelligenceService, err := videointelligence.NewService(ctx, option.WithAPIKey("AIza..."))
//
// To use an OAuth token (e.g., a user token obtained via a three-legged OAuth flow), use option.WithTokenSource:
//
//   config := &oauth2.Config{...}
//   // ...
//   token, err := config.Exchange(ctx, ...)
//   videointelligenceService, err := videointelligence.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package videointelligence // import "google.golang.org/api/videointelligence/v1p1beta1"

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"

	googleapi "google.golang.org/api/googleapi"
	gensupport "google.golang.org/api/internal/gensupport"
	option "google.golang.org/api/option"
	htransport "google.golang.org/api/transport/http"
)

// Always reference these packages, just in case the auto-generated code
// below doesn't.
var _ = bytes.NewBuffer
var _ = strconv.Itoa
var _ = fmt.Sprintf
var _ = json.NewDecoder
var _ = io.Copy
var _ = url.Parse
var _ = gensupport.MarshalJSON
var _ = googleapi.Version
var _ = errors.New
var _ = strings.Replace
var _ = context.Canceled

const apiId = "videointelligence:v1p1beta1"
const apiName = "videointelligence"
const apiVersion = "v1p1beta1"
const basePath = "https://videointelligence.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// View and manage your data across Google Cloud Platform services
	CloudPlatformScope = "https://www.googleapis.com/auth/cloud-platform"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/cloud-platform",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s, err := New(client)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

// New creates a new Service. It uses the provided http.Client for requests.
//
// Deprecated: please use NewService instead.
// To provide a custom HTTP client, use option.WithHTTPClient.
// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.Videos = NewVideosService(s)
	return s, nil
}

type Service struct {
	client    *http.Client
	BasePath  string // API endpoint base URL
	UserAgent string // optional additional User-Agent fragment

	Videos *VideosService
}

func (s *Service) userAgent() string {
	if s.UserAgent == "" {
		return googleapi.UserAgent
	}
	return googleapi.UserAgent + " " + s.UserAgent
}

func NewVideosService(s *Service) *VideosService {
	rs := &VideosService{s: s}
	return rs
}

type VideosService struct {
	s *Service
}

// GoogleCloudVideointelligenceV1AnnotateVideoProgress: Video annotation
// progress. Included in the `metadata`
// field of the `Operation` returned by the `GetOperation`
// call of the `google::longrunning::Operations` service.
type GoogleCloudVideointelligenceV1AnnotateVideoProgress struct {
	// AnnotationProgress: Progress metadata for all videos specified in
	// `AnnotateVideoRequest`.
	AnnotationProgress []*GoogleCloudVideointelligenceV1VideoAnnotationProgress `json:"annotationProgress,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AnnotationProgress")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AnnotationProgress") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1AnnotateVideoProgress) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1AnnotateVideoProgress
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1AnnotateVideoResponse: Video annotation
// response. Included in the `response`
// field of the `Operation` returned by the `GetOperation`
// call of the `google::longrunning::Operations` service.
type GoogleCloudVideointelligenceV1AnnotateVideoResponse struct {
	// AnnotationResults: Annotation results for all videos specified in
	// `AnnotateVideoRequest`.
	AnnotationResults []*GoogleCloudVideointelligenceV1VideoAnnotationResults `json:"annotationResults,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AnnotationResults")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AnnotationResults") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1AnnotateVideoResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1AnnotateVideoResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1Entity: Detected entity from video
// analysis.
type GoogleCloudVideointelligenceV1Entity struct {
	// Description: Textual description, e.g. `Fixed-gear bicycle`.
	Description string `json:"description,omitempty"`

	// EntityId: Opaque entity ID. Some IDs may be available in
	// [Google Knowledge Graph
	// Search
	// API](https://developers.google.com/knowledge-graph/).
	EntityId string `json:"entityId,omitempty"`

	// LanguageCode: Language code for `description` in BCP-47 format.
	LanguageCode string `json:"languageCode,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Description") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1Entity) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1Entity
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1ExplicitContentAnnotation: Explicit
// content annotation (based on per-frame visual signals only).
// If no explicit content has been detected in a frame, no annotations
// are
// present for that frame.
type GoogleCloudVideointelligenceV1ExplicitContentAnnotation struct {
	// Frames: All video frames where explicit content was detected.
	Frames []*GoogleCloudVideointelligenceV1ExplicitContentFrame `json:"frames,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Frames") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Frames") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1ExplicitContentAnnotation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1ExplicitContentAnnotation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1ExplicitContentFrame: Video frame level
// annotation results for explicit content.
type GoogleCloudVideointelligenceV1ExplicitContentFrame struct {
	// PornographyLikelihood: Likelihood of the pornography content..
	//
	// Possible values:
	//   "LIKELIHOOD_UNSPECIFIED" - Unspecified likelihood.
	//   "VERY_UNLIKELY" - Very unlikely.
	//   "UNLIKELY" - Unlikely.
	//   "POSSIBLE" - Possible.
	//   "LIKELY" - Likely.
	//   "VERY_LIKELY" - Very likely.
	PornographyLikelihood string `json:"pornographyLikelihood,omitempty"`

	// TimeOffset: Time-offset, relative to the beginning of the video,
	// corresponding to the
	// video frame for this location.
	TimeOffset string `json:"timeOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "PornographyLikelihood") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "PornographyLikelihood") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1ExplicitContentFrame) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1ExplicitContentFrame
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1LabelAnnotation: Label annotation.
type GoogleCloudVideointelligenceV1LabelAnnotation struct {
	// CategoryEntities: Common categories for the detected entity.
	// E.g. when the label is `Terrier` the category is likely `dog`. And in
	// some
	// cases there might be more than one categories e.g. `Terrier` could
	// also be
	// a `pet`.
	CategoryEntities []*GoogleCloudVideointelligenceV1Entity `json:"categoryEntities,omitempty"`

	// Entity: Detected entity.
	Entity *GoogleCloudVideointelligenceV1Entity `json:"entity,omitempty"`

	// Frames: All video frames where a label was detected.
	Frames []*GoogleCloudVideointelligenceV1LabelFrame `json:"frames,omitempty"`

	// Segments: All video segments where a label was detected.
	Segments []*GoogleCloudVideointelligenceV1LabelSegment `json:"segments,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CategoryEntities") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CategoryEntities") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1LabelAnnotation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1LabelAnnotation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1LabelFrame: Video frame level
// annotation results for label detection.
type GoogleCloudVideointelligenceV1LabelFrame struct {
	// Confidence: Confidence that the label is accurate. Range: [0, 1].
	Confidence float64 `json:"confidence,omitempty"`

	// TimeOffset: Time-offset, relative to the beginning of the video,
	// corresponding to the
	// video frame for this location.
	TimeOffset string `json:"timeOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1LabelFrame) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1LabelFrame
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1LabelFrame) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1LabelFrame
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1LabelSegment: Video segment level
// annotation results for label detection.
type GoogleCloudVideointelligenceV1LabelSegment struct {
	// Confidence: Confidence that the label is accurate. Range: [0, 1].
	Confidence float64 `json:"confidence,omitempty"`

	// Segment: Video segment where a label was detected.
	Segment *GoogleCloudVideointelligenceV1VideoSegment `json:"segment,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1LabelSegment) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1LabelSegment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1LabelSegment) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1LabelSegment
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1NormalizedBoundingBox: Normalized
// bounding box.
// The normalized vertex coordinates are relative to the original
// image.
// Range: [0, 1].
type GoogleCloudVideointelligenceV1NormalizedBoundingBox struct {
	// Bottom: Bottom Y coordinate.
	Bottom float64 `json:"bottom,omitempty"`

	// Left: Left X coordinate.
	Left float64 `json:"left,omitempty"`

	// Right: Right X coordinate.
	Right float64 `json:"right,omitempty"`

	// Top: Top Y coordinate.
	Top float64 `json:"top,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Bottom") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Bottom") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1NormalizedBoundingBox) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1NormalizedBoundingBox
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1NormalizedBoundingBox) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1NormalizedBoundingBox
	var s1 struct {
		Bottom gensupport.JSONFloat64 `json:"bottom"`
		Left   gensupport.JSONFloat64 `json:"left"`
		Right  gensupport.JSONFloat64 `json:"right"`
		Top    gensupport.JSONFloat64 `json:"top"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Bottom = float64(s1.Bottom)
	s.Left = float64(s1.Left)
	s.Right = float64(s1.Right)
	s.Top = float64(s1.Top)
	return nil
}

// GoogleCloudVideointelligenceV1NormalizedBoundingPoly: Normalized
// bounding polygon for text (that might not be aligned with
// axis).
// Contains list of the corner points in clockwise order starting
// from
// top-left corner. For example, for a rectangular bounding box:
// When the text is horizontal it might look like:
//         0----1
//         |    |
//         3----2
//
// When it's clockwise rotated 180 degrees around the top-left corner
// it
// becomes:
//         2----3
//         |    |
//         1----0
//
// and the vertex order will still be (0, 1, 2, 3). Note that values can
// be less
// than 0, or greater than 1 due to trignometric calculations for
// location of
// the box.
type GoogleCloudVideointelligenceV1NormalizedBoundingPoly struct {
	// Vertices: Normalized vertices of the bounding polygon.
	Vertices []*GoogleCloudVideointelligenceV1NormalizedVertex `json:"vertices,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Vertices") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Vertices") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1NormalizedBoundingPoly) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1NormalizedBoundingPoly
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1NormalizedVertex: A vertex represents a
// 2D point in the image.
// NOTE: the normalized vertex coordinates are relative to the original
// image
// and range from 0 to 1.
type GoogleCloudVideointelligenceV1NormalizedVertex struct {
	// X: X coordinate.
	X float64 `json:"x,omitempty"`

	// Y: Y coordinate.
	Y float64 `json:"y,omitempty"`

	// ForceSendFields is a list of field names (e.g. "X") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "X") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1NormalizedVertex) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1NormalizedVertex
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1NormalizedVertex) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1NormalizedVertex
	var s1 struct {
		X gensupport.JSONFloat64 `json:"x"`
		Y gensupport.JSONFloat64 `json:"y"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.X = float64(s1.X)
	s.Y = float64(s1.Y)
	return nil
}

// GoogleCloudVideointelligenceV1ObjectTrackingAnnotation: Annotations
// corresponding to one tracked object.
type GoogleCloudVideointelligenceV1ObjectTrackingAnnotation struct {
	// Confidence: Object category's labeling confidence of this track.
	Confidence float64 `json:"confidence,omitempty"`

	// Entity: Entity to specify the object category that this track is
	// labeled as.
	Entity *GoogleCloudVideointelligenceV1Entity `json:"entity,omitempty"`

	// Frames: Information corresponding to all frames where this object
	// track appears.
	// Non-streaming batch mode: it may be one or multiple
	// ObjectTrackingFrame
	// messages in frames.
	// Streaming mode: it can only be one ObjectTrackingFrame message in
	// frames.
	Frames []*GoogleCloudVideointelligenceV1ObjectTrackingFrame `json:"frames,omitempty"`

	// Segment: Non-streaming batch mode ONLY.
	// Each object track corresponds to one video segment where it appears.
	Segment *GoogleCloudVideointelligenceV1VideoSegment `json:"segment,omitempty"`

	// TrackId: Streaming mode ONLY.
	// In streaming mode, we do not know the end time of a tracked
	// object
	// before it is completed. Hence, there is no VideoSegment info
	// returned.
	// Instead, we provide a unique identifiable integer track_id so
	// that
	// the customers can correlate the results of the
	// ongoing
	// ObjectTrackAnnotation of the same track_id over time.
	TrackId int64 `json:"trackId,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1ObjectTrackingAnnotation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1ObjectTrackingAnnotation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1ObjectTrackingAnnotation) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1ObjectTrackingAnnotation
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1ObjectTrackingFrame: Video frame level
// annotations for object detection and tracking. This field
// stores per frame location, time offset, and confidence.
type GoogleCloudVideointelligenceV1ObjectTrackingFrame struct {
	// NormalizedBoundingBox: The normalized bounding box location of this
	// object track for the frame.
	NormalizedBoundingBox *GoogleCloudVideointelligenceV1NormalizedBoundingBox `json:"normalizedBoundingBox,omitempty"`

	// TimeOffset: The timestamp of the frame in microseconds.
	TimeOffset string `json:"timeOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "NormalizedBoundingBox") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NormalizedBoundingBox") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1ObjectTrackingFrame) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1ObjectTrackingFrame
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1SpeechRecognitionAlternative:
// Alternative hypotheses (a.k.a. n-best list).
type GoogleCloudVideointelligenceV1SpeechRecognitionAlternative struct {
	// Confidence: Output only. The confidence estimate between 0.0 and 1.0.
	// A higher number
	// indicates an estimated greater likelihood that the recognized words
	// are
	// correct. This field is set only for the top alternative.
	// This field is not guaranteed to be accurate and users should not rely
	// on it
	// to be always provided.
	// The default of 0.0 is a sentinel value indicating `confidence` was
	// not set.
	Confidence float64 `json:"confidence,omitempty"`

	// Transcript: Transcript text representing the words that the user
	// spoke.
	Transcript string `json:"transcript,omitempty"`

	// Words: Output only. A list of word-specific information for each
	// recognized word.
	// Note: When `enable_speaker_diarization` is true, you will see all the
	// words
	// from the beginning of the audio.
	Words []*GoogleCloudVideointelligenceV1WordInfo `json:"words,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1SpeechRecognitionAlternative) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1SpeechRecognitionAlternative
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1SpeechRecognitionAlternative) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1SpeechRecognitionAlternative
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1SpeechTranscription: A speech
// recognition result corresponding to a portion of the audio.
type GoogleCloudVideointelligenceV1SpeechTranscription struct {
	// Alternatives: May contain one or more recognition hypotheses (up to
	// the maximum specified
	// in `max_alternatives`).  These alternatives are ordered in terms
	// of
	// accuracy, with the top (first) alternative being the most probable,
	// as
	// ranked by the recognizer.
	Alternatives []*GoogleCloudVideointelligenceV1SpeechRecognitionAlternative `json:"alternatives,omitempty"`

	// LanguageCode: Output only. The
	// [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tag
	// of
	// the language in this result. This language code was detected to have
	// the
	// most likelihood of being spoken in the audio.
	LanguageCode string `json:"languageCode,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Alternatives") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Alternatives") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1SpeechTranscription) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1SpeechTranscription
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1TextAnnotation: Annotations related to
// one detected OCR text snippet. This will contain the
// corresponding text, confidence value, and frame level information for
// each
// detection.
type GoogleCloudVideointelligenceV1TextAnnotation struct {
	// Segments: All video segments where OCR detected text appears.
	Segments []*GoogleCloudVideointelligenceV1TextSegment `json:"segments,omitempty"`

	// Text: The detected text.
	Text string `json:"text,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Segments") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Segments") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1TextAnnotation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1TextAnnotation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1TextFrame: Video frame level annotation
// results for text annotation (OCR).
// Contains information regarding timestamp and bounding box locations
// for the
// frames containing detected OCR text snippets.
type GoogleCloudVideointelligenceV1TextFrame struct {
	// RotatedBoundingBox: Bounding polygon of the detected text for this
	// frame.
	RotatedBoundingBox *GoogleCloudVideointelligenceV1NormalizedBoundingPoly `json:"rotatedBoundingBox,omitempty"`

	// TimeOffset: Timestamp of this frame.
	TimeOffset string `json:"timeOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g. "RotatedBoundingBox")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "RotatedBoundingBox") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1TextFrame) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1TextFrame
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1TextSegment: Video segment level
// annotation results for text detection.
type GoogleCloudVideointelligenceV1TextSegment struct {
	// Confidence: Confidence for the track of detected text. It is
	// calculated as the highest
	// over all frames where OCR detected text appears.
	Confidence float64 `json:"confidence,omitempty"`

	// Frames: Information related to the frames where OCR detected text
	// appears.
	Frames []*GoogleCloudVideointelligenceV1TextFrame `json:"frames,omitempty"`

	// Segment: Video segment where a text snippet was detected.
	Segment *GoogleCloudVideointelligenceV1VideoSegment `json:"segment,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1TextSegment) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1TextSegment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1TextSegment) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1TextSegment
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1VideoAnnotationProgress: Annotation
// progress for a single video.
type GoogleCloudVideointelligenceV1VideoAnnotationProgress struct {
	// Feature: Specifies which feature is being tracked if the request
	// contains more than
	// one features.
	//
	// Possible values:
	//   "FEATURE_UNSPECIFIED" - Unspecified.
	//   "LABEL_DETECTION" - Label detection. Detect objects, such as dog or
	// flower.
	//   "SHOT_CHANGE_DETECTION" - Shot change detection.
	//   "EXPLICIT_CONTENT_DETECTION" - Explicit content detection.
	//   "SPEECH_TRANSCRIPTION" - Speech transcription.
	//   "TEXT_DETECTION" - OCR text detection and tracking.
	//   "OBJECT_TRACKING" - Object detection and tracking.
	Feature string `json:"feature,omitempty"`

	// InputUri: Video file location in
	// [Google Cloud Storage](https://cloud.google.com/storage/).
	InputUri string `json:"inputUri,omitempty"`

	// ProgressPercent: Approximate percentage processed thus far.
	// Guaranteed to be
	// 100 when fully processed.
	ProgressPercent int64 `json:"progressPercent,omitempty"`

	// Segment: Specifies which segment is being tracked if the request
	// contains more than
	// one segments.
	Segment *GoogleCloudVideointelligenceV1VideoSegment `json:"segment,omitempty"`

	// StartTime: Time when the request was received.
	StartTime string `json:"startTime,omitempty"`

	// UpdateTime: Time of the most recent update.
	UpdateTime string `json:"updateTime,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Feature") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Feature") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1VideoAnnotationProgress) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1VideoAnnotationProgress
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1VideoAnnotationResults: Annotation
// results for a single video.
type GoogleCloudVideointelligenceV1VideoAnnotationResults struct {
	// Error: If set, indicates an error. Note that for a single
	// `AnnotateVideoRequest`
	// some videos may succeed and some may fail.
	Error *GoogleRpcStatus `json:"error,omitempty"`

	// ExplicitAnnotation: Explicit content annotation.
	ExplicitAnnotation *GoogleCloudVideointelligenceV1ExplicitContentAnnotation `json:"explicitAnnotation,omitempty"`

	// FrameLabelAnnotations: Label annotations on frame level.
	// There is exactly one element for each unique label.
	FrameLabelAnnotations []*GoogleCloudVideointelligenceV1LabelAnnotation `json:"frameLabelAnnotations,omitempty"`

	// InputUri: Video file location in
	// [Google Cloud Storage](https://cloud.google.com/storage/).
	InputUri string `json:"inputUri,omitempty"`

	// ObjectAnnotations: Annotations for list of objects detected and
	// tracked in video.
	ObjectAnnotations []*GoogleCloudVideointelligenceV1ObjectTrackingAnnotation `json:"objectAnnotations,omitempty"`

	// Segment: Video segment on which the annotation is run.
	Segment *GoogleCloudVideointelligenceV1VideoSegment `json:"segment,omitempty"`

	// SegmentLabelAnnotations: Topical label annotations on video level or
	// user specified segment level.
	// There is exactly one element for each unique label.
	SegmentLabelAnnotations []*GoogleCloudVideointelligenceV1LabelAnnotation `json:"segmentLabelAnnotations,omitempty"`

	// SegmentPresenceLabelAnnotations: Presence label annotations on video
	// level or user specified segment level.
	// There is exactly one element for each unique label. Compared to
	// the
	// existing topical `segment_label_annotations`, this field presents
	// more
	// fine-grained, segment-level labels detected in video content and is
	// made
	// available only when the client sets `LabelDetectionConfig.model`
	// to
	// "builtin/latest" in the request.
	SegmentPresenceLabelAnnotations []*GoogleCloudVideointelligenceV1LabelAnnotation `json:"segmentPresenceLabelAnnotations,omitempty"`

	// ShotAnnotations: Shot annotations. Each shot is represented as a
	// video segment.
	ShotAnnotations []*GoogleCloudVideointelligenceV1VideoSegment `json:"shotAnnotations,omitempty"`

	// ShotLabelAnnotations: Topical label annotations on shot level.
	// There is exactly one element for each unique label.
	ShotLabelAnnotations []*GoogleCloudVideointelligenceV1LabelAnnotation `json:"shotLabelAnnotations,omitempty"`

	// ShotPresenceLabelAnnotations: Presence label annotations on shot
	// level. There is exactly one element for
	// each unique label. Compared to the existing
	// topical
	// `shot_label_annotations`, this field presents more fine-grained,
	// shot-level
	// labels detected in video content and is made available only when the
	// client
	// sets `LabelDetectionConfig.model` to "builtin/latest" in the request.
	ShotPresenceLabelAnnotations []*GoogleCloudVideointelligenceV1LabelAnnotation `json:"shotPresenceLabelAnnotations,omitempty"`

	// SpeechTranscriptions: Speech transcription.
	SpeechTranscriptions []*GoogleCloudVideointelligenceV1SpeechTranscription `json:"speechTranscriptions,omitempty"`

	// TextAnnotations: OCR text detection and tracking.
	// Annotations for list of detected text snippets. Each will have list
	// of
	// frame information associated with it.
	TextAnnotations []*GoogleCloudVideointelligenceV1TextAnnotation `json:"textAnnotations,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Error") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Error") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1VideoAnnotationResults) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1VideoAnnotationResults
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1VideoSegment: Video segment.
type GoogleCloudVideointelligenceV1VideoSegment struct {
	// EndTimeOffset: Time-offset, relative to the beginning of the
	// video,
	// corresponding to the end of the segment (inclusive).
	EndTimeOffset string `json:"endTimeOffset,omitempty"`

	// StartTimeOffset: Time-offset, relative to the beginning of the
	// video,
	// corresponding to the start of the segment (inclusive).
	StartTimeOffset string `json:"startTimeOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g. "EndTimeOffset") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "EndTimeOffset") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1VideoSegment) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1VideoSegment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1WordInfo: Word-specific information for
// recognized words. Word information is only
// included in the response when certain request parameters are set,
// such
// as `enable_word_time_offsets`.
type GoogleCloudVideointelligenceV1WordInfo struct {
	// Confidence: Output only. The confidence estimate between 0.0 and 1.0.
	// A higher number
	// indicates an estimated greater likelihood that the recognized words
	// are
	// correct. This field is set only for the top alternative.
	// This field is not guaranteed to be accurate and users should not rely
	// on it
	// to be always provided.
	// The default of 0.0 is a sentinel value indicating `confidence` was
	// not set.
	Confidence float64 `json:"confidence,omitempty"`

	// EndTime: Time offset relative to the beginning of the audio,
	// and
	// corresponding to the end of the spoken word. This field is only set
	// if
	// `enable_word_time_offsets=true` and only in the top hypothesis. This
	// is an
	// experimental feature and the accuracy of the time offset can vary.
	EndTime string `json:"endTime,omitempty"`

	// SpeakerTag: Output only. A distinct integer value is assigned for
	// every speaker within
	// the audio. This field specifies which one of those speakers was
	// detected to
	// have spoken this word. Value ranges from 1 up to
	// diarization_speaker_count,
	// and is only set if speaker diarization is enabled.
	SpeakerTag int64 `json:"speakerTag,omitempty"`

	// StartTime: Time offset relative to the beginning of the audio,
	// and
	// corresponding to the start of the spoken word. This field is only set
	// if
	// `enable_word_time_offsets=true` and only in the top hypothesis. This
	// is an
	// experimental feature and the accuracy of the time offset can vary.
	StartTime string `json:"startTime,omitempty"`

	// Word: The word corresponding to this set of information.
	Word string `json:"word,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1WordInfo) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1WordInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1WordInfo) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1WordInfo
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1beta2AnnotateVideoProgress: Video
// annotation progress. Included in the `metadata`
// field of the `Operation` returned by the `GetOperation`
// call of the `google::longrunning::Operations` service.
type GoogleCloudVideointelligenceV1beta2AnnotateVideoProgress struct {
	// AnnotationProgress: Progress metadata for all videos specified in
	// `AnnotateVideoRequest`.
	AnnotationProgress []*GoogleCloudVideointelligenceV1beta2VideoAnnotationProgress `json:"annotationProgress,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AnnotationProgress")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AnnotationProgress") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1beta2AnnotateVideoProgress) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1beta2AnnotateVideoProgress
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1beta2AnnotateVideoResponse: Video
// annotation response. Included in the `response`
// field of the `Operation` returned by the `GetOperation`
// call of the `google::longrunning::Operations` service.
type GoogleCloudVideointelligenceV1beta2AnnotateVideoResponse struct {
	// AnnotationResults: Annotation results for all videos specified in
	// `AnnotateVideoRequest`.
	AnnotationResults []*GoogleCloudVideointelligenceV1beta2VideoAnnotationResults `json:"annotationResults,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AnnotationResults")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AnnotationResults") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1beta2AnnotateVideoResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1beta2AnnotateVideoResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1beta2Entity: Detected entity from video
// analysis.
type GoogleCloudVideointelligenceV1beta2Entity struct {
	// Description: Textual description, e.g. `Fixed-gear bicycle`.
	Description string `json:"description,omitempty"`

	// EntityId: Opaque entity ID. Some IDs may be available in
	// [Google Knowledge Graph
	// Search
	// API](https://developers.google.com/knowledge-graph/).
	EntityId string `json:"entityId,omitempty"`

	// LanguageCode: Language code for `description` in BCP-47 format.
	LanguageCode string `json:"languageCode,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Description") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1beta2Entity) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1beta2Entity
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1beta2ExplicitContentAnnotation:
// Explicit content annotation (based on per-frame visual signals
// only).
// If no explicit content has been detected in a frame, no annotations
// are
// present for that frame.
type GoogleCloudVideointelligenceV1beta2ExplicitContentAnnotation struct {
	// Frames: All video frames where explicit content was detected.
	Frames []*GoogleCloudVideointelligenceV1beta2ExplicitContentFrame `json:"frames,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Frames") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Frames") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1beta2ExplicitContentAnnotation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1beta2ExplicitContentAnnotation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1beta2ExplicitContentFrame: Video frame
// level annotation results for explicit content.
type GoogleCloudVideointelligenceV1beta2ExplicitContentFrame struct {
	// PornographyLikelihood: Likelihood of the pornography content..
	//
	// Possible values:
	//   "LIKELIHOOD_UNSPECIFIED" - Unspecified likelihood.
	//   "VERY_UNLIKELY" - Very unlikely.
	//   "UNLIKELY" - Unlikely.
	//   "POSSIBLE" - Possible.
	//   "LIKELY" - Likely.
	//   "VERY_LIKELY" - Very likely.
	PornographyLikelihood string `json:"pornographyLikelihood,omitempty"`

	// TimeOffset: Time-offset, relative to the beginning of the video,
	// corresponding to the
	// video frame for this location.
	TimeOffset string `json:"timeOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "PornographyLikelihood") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "PornographyLikelihood") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1beta2ExplicitContentFrame) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1beta2ExplicitContentFrame
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1beta2LabelAnnotation: Label annotation.
type GoogleCloudVideointelligenceV1beta2LabelAnnotation struct {
	// CategoryEntities: Common categories for the detected entity.
	// E.g. when the label is `Terrier` the category is likely `dog`. And in
	// some
	// cases there might be more than one categories e.g. `Terrier` could
	// also be
	// a `pet`.
	CategoryEntities []*GoogleCloudVideointelligenceV1beta2Entity `json:"categoryEntities,omitempty"`

	// Entity: Detected entity.
	Entity *GoogleCloudVideointelligenceV1beta2Entity `json:"entity,omitempty"`

	// Frames: All video frames where a label was detected.
	Frames []*GoogleCloudVideointelligenceV1beta2LabelFrame `json:"frames,omitempty"`

	// Segments: All video segments where a label was detected.
	Segments []*GoogleCloudVideointelligenceV1beta2LabelSegment `json:"segments,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CategoryEntities") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CategoryEntities") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1beta2LabelAnnotation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1beta2LabelAnnotation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1beta2LabelFrame: Video frame level
// annotation results for label detection.
type GoogleCloudVideointelligenceV1beta2LabelFrame struct {
	// Confidence: Confidence that the label is accurate. Range: [0, 1].
	Confidence float64 `json:"confidence,omitempty"`

	// TimeOffset: Time-offset, relative to the beginning of the video,
	// corresponding to the
	// video frame for this location.
	TimeOffset string `json:"timeOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1beta2LabelFrame) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1beta2LabelFrame
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1beta2LabelFrame) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1beta2LabelFrame
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1beta2LabelSegment: Video segment level
// annotation results for label detection.
type GoogleCloudVideointelligenceV1beta2LabelSegment struct {
	// Confidence: Confidence that the label is accurate. Range: [0, 1].
	Confidence float64 `json:"confidence,omitempty"`

	// Segment: Video segment where a label was detected.
	Segment *GoogleCloudVideointelligenceV1beta2VideoSegment `json:"segment,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1beta2LabelSegment) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1beta2LabelSegment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1beta2LabelSegment) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1beta2LabelSegment
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1beta2NormalizedBoundingBox: Normalized
// bounding box.
// The normalized vertex coordinates are relative to the original
// image.
// Range: [0, 1].
type GoogleCloudVideointelligenceV1beta2NormalizedBoundingBox struct {
	// Bottom: Bottom Y coordinate.
	Bottom float64 `json:"bottom,omitempty"`

	// Left: Left X coordinate.
	Left float64 `json:"left,omitempty"`

	// Right: Right X coordinate.
	Right float64 `json:"right,omitempty"`

	// Top: Top Y coordinate.
	Top float64 `json:"top,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Bottom") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Bottom") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1beta2NormalizedBoundingBox) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1beta2NormalizedBoundingBox
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1beta2NormalizedBoundingBox) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1beta2NormalizedBoundingBox
	var s1 struct {
		Bottom gensupport.JSONFloat64 `json:"bottom"`
		Left   gensupport.JSONFloat64 `json:"left"`
		Right  gensupport.JSONFloat64 `json:"right"`
		Top    gensupport.JSONFloat64 `json:"top"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Bottom = float64(s1.Bottom)
	s.Left = float64(s1.Left)
	s.Right = float64(s1.Right)
	s.Top = float64(s1.Top)
	return nil
}

// GoogleCloudVideointelligenceV1beta2NormalizedBoundingPoly: Normalized
// bounding polygon for text (that might not be aligned with
// axis).
// Contains list of the corner points in clockwise order starting
// from
// top-left corner. For example, for a rectangular bounding box:
// When the text is horizontal it might look like:
//         0----1
//         |    |
//         3----2
//
// When it's clockwise rotated 180 degrees around the top-left corner
// it
// becomes:
//         2----3
//         |    |
//         1----0
//
// and the vertex order will still be (0, 1, 2, 3). Note that values can
// be less
// than 0, or greater than 1 due to trignometric calculations for
// location of
// the box.
type GoogleCloudVideointelligenceV1beta2NormalizedBoundingPoly struct {
	// Vertices: Normalized vertices of the bounding polygon.
	Vertices []*GoogleCloudVideointelligenceV1beta2NormalizedVertex `json:"vertices,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Vertices") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Vertices") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1beta2NormalizedBoundingPoly) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1beta2NormalizedBoundingPoly
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1beta2NormalizedVertex: A vertex
// represents a 2D point in the image.
// NOTE: the normalized vertex coordinates are relative to the original
// image
// and range from 0 to 1.
type GoogleCloudVideointelligenceV1beta2NormalizedVertex struct {
	// X: X coordinate.
	X float64 `json:"x,omitempty"`

	// Y: Y coordinate.
	Y float64 `json:"y,omitempty"`

	// ForceSendFields is a list of field names (e.g. "X") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "X") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1beta2NormalizedVertex) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1beta2NormalizedVertex
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1beta2NormalizedVertex) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1beta2NormalizedVertex
	var s1 struct {
		X gensupport.JSONFloat64 `json:"x"`
		Y gensupport.JSONFloat64 `json:"y"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.X = float64(s1.X)
	s.Y = float64(s1.Y)
	return nil
}

// GoogleCloudVideointelligenceV1beta2ObjectTrackingAnnotation:
// Annotations corresponding to one tracked object.
type GoogleCloudVideointelligenceV1beta2ObjectTrackingAnnotation struct {
	// Confidence: Object category's labeling confidence of this track.
	Confidence float64 `json:"confidence,omitempty"`

	// Entity: Entity to specify the object category that this track is
	// labeled as.
	Entity *GoogleCloudVideointelligenceV1beta2Entity `json:"entity,omitempty"`

	// Frames: Information corresponding to all frames where this object
	// track appears.
	// Non-streaming batch mode: it may be one or multiple
	// ObjectTrackingFrame
	// messages in frames.
	// Streaming mode: it can only be one ObjectTrackingFrame message in
	// frames.
	Frames []*GoogleCloudVideointelligenceV1beta2ObjectTrackingFrame `json:"frames,omitempty"`

	// Segment: Non-streaming batch mode ONLY.
	// Each object track corresponds to one video segment where it appears.
	Segment *GoogleCloudVideointelligenceV1beta2VideoSegment `json:"segment,omitempty"`

	// TrackId: Streaming mode ONLY.
	// In streaming mode, we do not know the end time of a tracked
	// object
	// before it is completed. Hence, there is no VideoSegment info
	// returned.
	// Instead, we provide a unique identifiable integer track_id so
	// that
	// the customers can correlate the results of the
	// ongoing
	// ObjectTrackAnnotation of the same track_id over time.
	TrackId int64 `json:"trackId,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1beta2ObjectTrackingAnnotation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1beta2ObjectTrackingAnnotation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1beta2ObjectTrackingAnnotation) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1beta2ObjectTrackingAnnotation
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1beta2ObjectTrackingFrame: Video frame
// level annotations for object detection and tracking. This
// field
// stores per frame location, time offset, and confidence.
type GoogleCloudVideointelligenceV1beta2ObjectTrackingFrame struct {
	// NormalizedBoundingBox: The normalized bounding box location of this
	// object track for the frame.
	NormalizedBoundingBox *GoogleCloudVideointelligenceV1beta2NormalizedBoundingBox `json:"normalizedBoundingBox,omitempty"`

	// TimeOffset: The timestamp of the frame in microseconds.
	TimeOffset string `json:"timeOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "NormalizedBoundingBox") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NormalizedBoundingBox") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1beta2ObjectTrackingFrame) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1beta2ObjectTrackingFrame
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1beta2SpeechRecognitionAlternative:
// Alternative hypotheses (a.k.a. n-best list).
type GoogleCloudVideointelligenceV1beta2SpeechRecognitionAlternative struct {
	// Confidence: Output only. The confidence estimate between 0.0 and 1.0.
	// A higher number
	// indicates an estimated greater likelihood that the recognized words
	// are
	// correct. This field is set only for the top alternative.
	// This field is not guaranteed to be accurate and users should not rely
	// on it
	// to be always provided.
	// The default of 0.0 is a sentinel value indicating `confidence` was
	// not set.
	Confidence float64 `json:"confidence,omitempty"`

	// Transcript: Transcript text representing the words that the user
	// spoke.
	Transcript string `json:"transcript,omitempty"`

	// Words: Output only. A list of word-specific information for each
	// recognized word.
	// Note: When `enable_speaker_diarization` is true, you will see all the
	// words
	// from the beginning of the audio.
	Words []*GoogleCloudVideointelligenceV1beta2WordInfo `json:"words,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1beta2SpeechRecognitionAlternative) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1beta2SpeechRecognitionAlternative
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1beta2SpeechRecognitionAlternative) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1beta2SpeechRecognitionAlternative
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1beta2SpeechTranscription: A speech
// recognition result corresponding to a portion of the audio.
type GoogleCloudVideointelligenceV1beta2SpeechTranscription struct {
	// Alternatives: May contain one or more recognition hypotheses (up to
	// the maximum specified
	// in `max_alternatives`).  These alternatives are ordered in terms
	// of
	// accuracy, with the top (first) alternative being the most probable,
	// as
	// ranked by the recognizer.
	Alternatives []*GoogleCloudVideointelligenceV1beta2SpeechRecognitionAlternative `json:"alternatives,omitempty"`

	// LanguageCode: Output only. The
	// [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tag
	// of
	// the language in this result. This language code was detected to have
	// the
	// most likelihood of being spoken in the audio.
	LanguageCode string `json:"languageCode,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Alternatives") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Alternatives") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1beta2SpeechTranscription) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1beta2SpeechTranscription
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1beta2TextAnnotation: Annotations
// related to one detected OCR text snippet. This will contain
// the
// corresponding text, confidence value, and frame level information for
// each
// detection.
type GoogleCloudVideointelligenceV1beta2TextAnnotation struct {
	// Segments: All video segments where OCR detected text appears.
	Segments []*GoogleCloudVideointelligenceV1beta2TextSegment `json:"segments,omitempty"`

	// Text: The detected text.
	Text string `json:"text,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Segments") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Segments") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1beta2TextAnnotation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1beta2TextAnnotation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1beta2TextFrame: Video frame level
// annotation results for text annotation (OCR).
// Contains information regarding timestamp and bounding box locations
// for the
// frames containing detected OCR text snippets.
type GoogleCloudVideointelligenceV1beta2TextFrame struct {
	// RotatedBoundingBox: Bounding polygon of the detected text for this
	// frame.
	RotatedBoundingBox *GoogleCloudVideointelligenceV1beta2NormalizedBoundingPoly `json:"rotatedBoundingBox,omitempty"`

	// TimeOffset: Timestamp of this frame.
	TimeOffset string `json:"timeOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g. "RotatedBoundingBox")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "RotatedBoundingBox") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1beta2TextFrame) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1beta2TextFrame
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1beta2TextSegment: Video segment level
// annotation results for text detection.
type GoogleCloudVideointelligenceV1beta2TextSegment struct {
	// Confidence: Confidence for the track of detected text. It is
	// calculated as the highest
	// over all frames where OCR detected text appears.
	Confidence float64 `json:"confidence,omitempty"`

	// Frames: Information related to the frames where OCR detected text
	// appears.
	Frames []*GoogleCloudVideointelligenceV1beta2TextFrame `json:"frames,omitempty"`

	// Segment: Video segment where a text snippet was detected.
	Segment *GoogleCloudVideointelligenceV1beta2VideoSegment `json:"segment,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1beta2TextSegment) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1beta2TextSegment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1beta2TextSegment) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1beta2TextSegment
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1beta2VideoAnnotationProgress:
// Annotation progress for a single video.
type GoogleCloudVideointelligenceV1beta2VideoAnnotationProgress struct {
	// Feature: Specifies which feature is being tracked if the request
	// contains more than
	// one features.
	//
	// Possible values:
	//   "FEATURE_UNSPECIFIED" - Unspecified.
	//   "LABEL_DETECTION" - Label detection. Detect objects, such as dog or
	// flower.
	//   "SHOT_CHANGE_DETECTION" - Shot change detection.
	//   "EXPLICIT_CONTENT_DETECTION" - Explicit content detection.
	//   "SPEECH_TRANSCRIPTION" - Speech transcription.
	//   "TEXT_DETECTION" - OCR text detection and tracking.
	//   "OBJECT_TRACKING" - Object detection and tracking.
	Feature string `json:"feature,omitempty"`

	// InputUri: Video file location in
	// [Google Cloud Storage](https://cloud.google.com/storage/).
	InputUri string `json:"inputUri,omitempty"`

	// ProgressPercent: Approximate percentage processed thus far.
	// Guaranteed to be
	// 100 when fully processed.
	ProgressPercent int64 `json:"progressPercent,omitempty"`

	// Segment: Specifies which segment is being tracked if the request
	// contains more than
	// one segments.
	Segment *GoogleCloudVideointelligenceV1beta2VideoSegment `json:"segment,omitempty"`

	// StartTime: Time when the request was received.
	StartTime string `json:"startTime,omitempty"`

	// UpdateTime: Time of the most recent update.
	UpdateTime string `json:"updateTime,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Feature") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Feature") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1beta2VideoAnnotationProgress) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1beta2VideoAnnotationProgress
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1beta2VideoAnnotationResults: Annotation
// results for a single video.
type GoogleCloudVideointelligenceV1beta2VideoAnnotationResults struct {
	// Error: If set, indicates an error. Note that for a single
	// `AnnotateVideoRequest`
	// some videos may succeed and some may fail.
	Error *GoogleRpcStatus `json:"error,omitempty"`

	// ExplicitAnnotation: Explicit content annotation.
	ExplicitAnnotation *GoogleCloudVideointelligenceV1beta2ExplicitContentAnnotation `json:"explicitAnnotation,omitempty"`

	// FrameLabelAnnotations: Label annotations on frame level.
	// There is exactly one element for each unique label.
	FrameLabelAnnotations []*GoogleCloudVideointelligenceV1beta2LabelAnnotation `json:"frameLabelAnnotations,omitempty"`

	// InputUri: Video file location in
	// [Google Cloud Storage](https://cloud.google.com/storage/).
	InputUri string `json:"inputUri,omitempty"`

	// ObjectAnnotations: Annotations for list of objects detected and
	// tracked in video.
	ObjectAnnotations []*GoogleCloudVideointelligenceV1beta2ObjectTrackingAnnotation `json:"objectAnnotations,omitempty"`

	// Segment: Video segment on which the annotation is run.
	Segment *GoogleCloudVideointelligenceV1beta2VideoSegment `json:"segment,omitempty"`

	// SegmentLabelAnnotations: Topical label annotations on video level or
	// user specified segment level.
	// There is exactly one element for each unique label.
	SegmentLabelAnnotations []*GoogleCloudVideointelligenceV1beta2LabelAnnotation `json:"segmentLabelAnnotations,omitempty"`

	// SegmentPresenceLabelAnnotations: Presence label annotations on video
	// level or user specified segment level.
	// There is exactly one element for each unique label. Compared to
	// the
	// existing topical `segment_label_annotations`, this field presents
	// more
	// fine-grained, segment-level labels detected in video content and is
	// made
	// available only when the client sets `LabelDetectionConfig.model`
	// to
	// "builtin/latest" in the request.
	SegmentPresenceLabelAnnotations []*GoogleCloudVideointelligenceV1beta2LabelAnnotation `json:"segmentPresenceLabelAnnotations,omitempty"`

	// ShotAnnotations: Shot annotations. Each shot is represented as a
	// video segment.
	ShotAnnotations []*GoogleCloudVideointelligenceV1beta2VideoSegment `json:"shotAnnotations,omitempty"`

	// ShotLabelAnnotations: Topical label annotations on shot level.
	// There is exactly one element for each unique label.
	ShotLabelAnnotations []*GoogleCloudVideointelligenceV1beta2LabelAnnotation `json:"shotLabelAnnotations,omitempty"`

	// ShotPresenceLabelAnnotations: Presence label annotations on shot
	// level. There is exactly one element for
	// each unique label. Compared to the existing
	// topical
	// `shot_label_annotations`, this field presents more fine-grained,
	// shot-level
	// labels detected in video content and is made available only when the
	// client
	// sets `LabelDetectionConfig.model` to "builtin/latest" in the request.
	ShotPresenceLabelAnnotations []*GoogleCloudVideointelligenceV1beta2LabelAnnotation `json:"shotPresenceLabelAnnotations,omitempty"`

	// SpeechTranscriptions: Speech transcription.
	SpeechTranscriptions []*GoogleCloudVideointelligenceV1beta2SpeechTranscription `json:"speechTranscriptions,omitempty"`

	// TextAnnotations: OCR text detection and tracking.
	// Annotations for list of detected text snippets. Each will have list
	// of
	// frame information associated with it.
	TextAnnotations []*GoogleCloudVideointelligenceV1beta2TextAnnotation `json:"textAnnotations,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Error") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Error") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1beta2VideoAnnotationResults) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1beta2VideoAnnotationResults
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1beta2VideoSegment: Video segment.
type GoogleCloudVideointelligenceV1beta2VideoSegment struct {
	// EndTimeOffset: Time-offset, relative to the beginning of the
	// video,
	// corresponding to the end of the segment (inclusive).
	EndTimeOffset string `json:"endTimeOffset,omitempty"`

	// StartTimeOffset: Time-offset, relative to the beginning of the
	// video,
	// corresponding to the start of the segment (inclusive).
	StartTimeOffset string `json:"startTimeOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g. "EndTimeOffset") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "EndTimeOffset") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1beta2VideoSegment) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1beta2VideoSegment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1beta2WordInfo: Word-specific
// information for recognized words. Word information is only
// included in the response when certain request parameters are set,
// such
// as `enable_word_time_offsets`.
type GoogleCloudVideointelligenceV1beta2WordInfo struct {
	// Confidence: Output only. The confidence estimate between 0.0 and 1.0.
	// A higher number
	// indicates an estimated greater likelihood that the recognized words
	// are
	// correct. This field is set only for the top alternative.
	// This field is not guaranteed to be accurate and users should not rely
	// on it
	// to be always provided.
	// The default of 0.0 is a sentinel value indicating `confidence` was
	// not set.
	Confidence float64 `json:"confidence,omitempty"`

	// EndTime: Time offset relative to the beginning of the audio,
	// and
	// corresponding to the end of the spoken word. This field is only set
	// if
	// `enable_word_time_offsets=true` and only in the top hypothesis. This
	// is an
	// experimental feature and the accuracy of the time offset can vary.
	EndTime string `json:"endTime,omitempty"`

	// SpeakerTag: Output only. A distinct integer value is assigned for
	// every speaker within
	// the audio. This field specifies which one of those speakers was
	// detected to
	// have spoken this word. Value ranges from 1 up to
	// diarization_speaker_count,
	// and is only set if speaker diarization is enabled.
	SpeakerTag int64 `json:"speakerTag,omitempty"`

	// StartTime: Time offset relative to the beginning of the audio,
	// and
	// corresponding to the start of the spoken word. This field is only set
	// if
	// `enable_word_time_offsets=true` and only in the top hypothesis. This
	// is an
	// experimental feature and the accuracy of the time offset can vary.
	StartTime string `json:"startTime,omitempty"`

	// Word: The word corresponding to this set of information.
	Word string `json:"word,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1beta2WordInfo) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1beta2WordInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1beta2WordInfo) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1beta2WordInfo
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1p1beta1AnnotateVideoProgress: Video
// annotation progress. Included in the `metadata`
// field of the `Operation` returned by the `GetOperation`
// call of the `google::longrunning::Operations` service.
type GoogleCloudVideointelligenceV1p1beta1AnnotateVideoProgress struct {
	// AnnotationProgress: Progress metadata for all videos specified in
	// `AnnotateVideoRequest`.
	AnnotationProgress []*GoogleCloudVideointelligenceV1p1beta1VideoAnnotationProgress `json:"annotationProgress,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AnnotationProgress")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AnnotationProgress") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1AnnotateVideoProgress) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1AnnotateVideoProgress
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p1beta1AnnotateVideoRequest: Video
// annotation request.
type GoogleCloudVideointelligenceV1p1beta1AnnotateVideoRequest struct {
	// Features: Required. Requested video annotation features.
	//
	// Possible values:
	//   "FEATURE_UNSPECIFIED" - Unspecified.
	//   "LABEL_DETECTION" - Label detection. Detect objects, such as dog or
	// flower.
	//   "SHOT_CHANGE_DETECTION" - Shot change detection.
	//   "EXPLICIT_CONTENT_DETECTION" - Explicit content detection.
	//   "SPEECH_TRANSCRIPTION" - Speech transcription.
	//   "TEXT_DETECTION" - OCR text detection and tracking.
	//   "OBJECT_TRACKING" - Object detection and tracking.
	Features []string `json:"features,omitempty"`

	// InputContent: The video data bytes.
	// If unset, the input video(s) should be specified via `input_uri`.
	// If set, `input_uri` should be unset.
	InputContent string `json:"inputContent,omitempty"`

	// InputUri: Input video location. Currently, only
	// [Google Cloud Storage](https://cloud.google.com/storage/) URIs
	// are
	// supported, which must be specified in the following
	// format:
	// `gs://bucket-id/object-id` (other URI formats
	// return
	// google.rpc.Code.INVALID_ARGUMENT). For more information, see
	// [Request URIs](/storage/docs/reference-uris).
	// A video URI may include wildcards in `object-id`, and thus
	// identify
	// multiple videos. Supported wildcards: '*' to match 0 or more
	// characters;
	// '?' to match 1 character. If unset, the input video should be
	// embedded
	// in the request as `input_content`. If set, `input_content` should be
	// unset.
	InputUri string `json:"inputUri,omitempty"`

	// LocationId: Optional. Cloud region where annotation should take
	// place. Supported cloud
	// regions: `us-east1`, `us-west1`, `europe-west1`, `asia-east1`. If no
	// region
	// is specified, a region will be determined based on video file
	// location.
	LocationId string `json:"locationId,omitempty"`

	// OutputUri: Optional. Location where the output (in JSON format)
	// should be stored.
	// Currently, only [Google Cloud
	// Storage](https://cloud.google.com/storage/)
	// URIs are supported, which must be specified in the following
	// format:
	// `gs://bucket-id/object-id` (other URI formats
	// return
	// google.rpc.Code.INVALID_ARGUMENT). For more information, see
	// [Request URIs](/storage/docs/reference-uris).
	OutputUri string `json:"outputUri,omitempty"`

	// VideoContext: Additional video context and/or feature-specific
	// parameters.
	VideoContext *GoogleCloudVideointelligenceV1p1beta1VideoContext `json:"videoContext,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Features") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Features") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1AnnotateVideoRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1AnnotateVideoRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p1beta1AnnotateVideoResponse: Video
// annotation response. Included in the `response`
// field of the `Operation` returned by the `GetOperation`
// call of the `google::longrunning::Operations` service.
type GoogleCloudVideointelligenceV1p1beta1AnnotateVideoResponse struct {
	// AnnotationResults: Annotation results for all videos specified in
	// `AnnotateVideoRequest`.
	AnnotationResults []*GoogleCloudVideointelligenceV1p1beta1VideoAnnotationResults `json:"annotationResults,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AnnotationResults")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AnnotationResults") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1AnnotateVideoResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1AnnotateVideoResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p1beta1Entity: Detected entity from
// video analysis.
type GoogleCloudVideointelligenceV1p1beta1Entity struct {
	// Description: Textual description, e.g. `Fixed-gear bicycle`.
	Description string `json:"description,omitempty"`

	// EntityId: Opaque entity ID. Some IDs may be available in
	// [Google Knowledge Graph
	// Search
	// API](https://developers.google.com/knowledge-graph/).
	EntityId string `json:"entityId,omitempty"`

	// LanguageCode: Language code for `description` in BCP-47 format.
	LanguageCode string `json:"languageCode,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Description") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1Entity) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1Entity
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p1beta1ExplicitContentAnnotation:
// Explicit content annotation (based on per-frame visual signals
// only).
// If no explicit content has been detected in a frame, no annotations
// are
// present for that frame.
type GoogleCloudVideointelligenceV1p1beta1ExplicitContentAnnotation struct {
	// Frames: All video frames where explicit content was detected.
	Frames []*GoogleCloudVideointelligenceV1p1beta1ExplicitContentFrame `json:"frames,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Frames") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Frames") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1ExplicitContentAnnotation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1ExplicitContentAnnotation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p1beta1ExplicitContentDetectionConfig:
// Config for EXPLICIT_CONTENT_DETECTION.
type GoogleCloudVideointelligenceV1p1beta1ExplicitContentDetectionConfig struct {
	// Model: Model to use for explicit content detection.
	// Supported values: "builtin/stable" (the default if unset)
	// and
	// "builtin/latest".
	Model string `json:"model,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Model") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Model") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1ExplicitContentDetectionConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1ExplicitContentDetectionConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p1beta1ExplicitContentFrame: Video
// frame level annotation results for explicit content.
type GoogleCloudVideointelligenceV1p1beta1ExplicitContentFrame struct {
	// PornographyLikelihood: Likelihood of the pornography content..
	//
	// Possible values:
	//   "LIKELIHOOD_UNSPECIFIED" - Unspecified likelihood.
	//   "VERY_UNLIKELY" - Very unlikely.
	//   "UNLIKELY" - Unlikely.
	//   "POSSIBLE" - Possible.
	//   "LIKELY" - Likely.
	//   "VERY_LIKELY" - Very likely.
	PornographyLikelihood string `json:"pornographyLikelihood,omitempty"`

	// TimeOffset: Time-offset, relative to the beginning of the video,
	// corresponding to the
	// video frame for this location.
	TimeOffset string `json:"timeOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "PornographyLikelihood") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "PornographyLikelihood") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1ExplicitContentFrame) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1ExplicitContentFrame
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p1beta1LabelAnnotation: Label
// annotation.
type GoogleCloudVideointelligenceV1p1beta1LabelAnnotation struct {
	// CategoryEntities: Common categories for the detected entity.
	// E.g. when the label is `Terrier` the category is likely `dog`. And in
	// some
	// cases there might be more than one categories e.g. `Terrier` could
	// also be
	// a `pet`.
	CategoryEntities []*GoogleCloudVideointelligenceV1p1beta1Entity `json:"categoryEntities,omitempty"`

	// Entity: Detected entity.
	Entity *GoogleCloudVideointelligenceV1p1beta1Entity `json:"entity,omitempty"`

	// Frames: All video frames where a label was detected.
	Frames []*GoogleCloudVideointelligenceV1p1beta1LabelFrame `json:"frames,omitempty"`

	// Segments: All video segments where a label was detected.
	Segments []*GoogleCloudVideointelligenceV1p1beta1LabelSegment `json:"segments,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CategoryEntities") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CategoryEntities") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1LabelAnnotation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1LabelAnnotation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p1beta1LabelDetectionConfig: Config for
// LABEL_DETECTION.
type GoogleCloudVideointelligenceV1p1beta1LabelDetectionConfig struct {
	// FrameConfidenceThreshold: The confidence threshold we perform
	// filtering on the labels from
	// frame-level detection. If not set, it is set to 0.4 by default. The
	// valid
	// range for this threshold is [0.1, 0.9]. Any value set outside of
	// this
	// range will be clipped.
	// Note: for best results please follow the default threshold. We will
	// update
	// the default threshold everytime when we release a new model.
	FrameConfidenceThreshold float64 `json:"frameConfidenceThreshold,omitempty"`

	// LabelDetectionMode: What labels should be detected with
	// LABEL_DETECTION, in addition to
	// video-level labels or segment-level labels.
	// If unspecified, defaults to `SHOT_MODE`.
	//
	// Possible values:
	//   "LABEL_DETECTION_MODE_UNSPECIFIED" - Unspecified.
	//   "SHOT_MODE" - Detect shot-level labels.
	//   "FRAME_MODE" - Detect frame-level labels.
	//   "SHOT_AND_FRAME_MODE" - Detect both shot-level and frame-level
	// labels.
	LabelDetectionMode string `json:"labelDetectionMode,omitempty"`

	// Model: Model to use for label detection.
	// Supported values: "builtin/stable" (the default if unset)
	// and
	// "builtin/latest".
	Model string `json:"model,omitempty"`

	// StationaryCamera: Whether the video has been shot from a stationary
	// (i.e. non-moving) camera.
	// When set to true, might improve detection accuracy for moving
	// objects.
	// Should be used with `SHOT_AND_FRAME_MODE` enabled.
	StationaryCamera bool `json:"stationaryCamera,omitempty"`

	// VideoConfidenceThreshold: The confidence threshold we perform
	// filtering on the labels from
	// video-level and shot-level detections. If not set, it is set to 0.3
	// by
	// default. The valid range for this threshold is [0.1, 0.9]. Any value
	// set
	// outside of this range will be clipped.
	// Note: for best results please follow the default threshold. We will
	// update
	// the default threshold everytime when we release a new model.
	VideoConfidenceThreshold float64 `json:"videoConfidenceThreshold,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "FrameConfidenceThreshold") to unconditionally include in API
	// requests. By default, fields with empty values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "FrameConfidenceThreshold")
	// to include in API requests with the JSON null value. By default,
	// fields with empty values are omitted from API requests. However, any
	// field with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1LabelDetectionConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1LabelDetectionConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p1beta1LabelDetectionConfig) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1LabelDetectionConfig
	var s1 struct {
		FrameConfidenceThreshold gensupport.JSONFloat64 `json:"frameConfidenceThreshold"`
		VideoConfidenceThreshold gensupport.JSONFloat64 `json:"videoConfidenceThreshold"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.FrameConfidenceThreshold = float64(s1.FrameConfidenceThreshold)
	s.VideoConfidenceThreshold = float64(s1.VideoConfidenceThreshold)
	return nil
}

// GoogleCloudVideointelligenceV1p1beta1LabelFrame: Video frame level
// annotation results for label detection.
type GoogleCloudVideointelligenceV1p1beta1LabelFrame struct {
	// Confidence: Confidence that the label is accurate. Range: [0, 1].
	Confidence float64 `json:"confidence,omitempty"`

	// TimeOffset: Time-offset, relative to the beginning of the video,
	// corresponding to the
	// video frame for this location.
	TimeOffset string `json:"timeOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1LabelFrame) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1LabelFrame
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p1beta1LabelFrame) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1LabelFrame
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1p1beta1LabelSegment: Video segment
// level annotation results for label detection.
type GoogleCloudVideointelligenceV1p1beta1LabelSegment struct {
	// Confidence: Confidence that the label is accurate. Range: [0, 1].
	Confidence float64 `json:"confidence,omitempty"`

	// Segment: Video segment where a label was detected.
	Segment *GoogleCloudVideointelligenceV1p1beta1VideoSegment `json:"segment,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1LabelSegment) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1LabelSegment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p1beta1LabelSegment) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1LabelSegment
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1p1beta1NormalizedBoundingBox:
// Normalized bounding box.
// The normalized vertex coordinates are relative to the original
// image.
// Range: [0, 1].
type GoogleCloudVideointelligenceV1p1beta1NormalizedBoundingBox struct {
	// Bottom: Bottom Y coordinate.
	Bottom float64 `json:"bottom,omitempty"`

	// Left: Left X coordinate.
	Left float64 `json:"left,omitempty"`

	// Right: Right X coordinate.
	Right float64 `json:"right,omitempty"`

	// Top: Top Y coordinate.
	Top float64 `json:"top,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Bottom") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Bottom") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1NormalizedBoundingBox) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1NormalizedBoundingBox
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p1beta1NormalizedBoundingBox) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1NormalizedBoundingBox
	var s1 struct {
		Bottom gensupport.JSONFloat64 `json:"bottom"`
		Left   gensupport.JSONFloat64 `json:"left"`
		Right  gensupport.JSONFloat64 `json:"right"`
		Top    gensupport.JSONFloat64 `json:"top"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Bottom = float64(s1.Bottom)
	s.Left = float64(s1.Left)
	s.Right = float64(s1.Right)
	s.Top = float64(s1.Top)
	return nil
}

// GoogleCloudVideointelligenceV1p1beta1NormalizedBoundingPoly:
// Normalized bounding polygon for text (that might not be aligned with
// axis).
// Contains list of the corner points in clockwise order starting
// from
// top-left corner. For example, for a rectangular bounding box:
// When the text is horizontal it might look like:
//         0----1
//         |    |
//         3----2
//
// When it's clockwise rotated 180 degrees around the top-left corner
// it
// becomes:
//         2----3
//         |    |
//         1----0
//
// and the vertex order will still be (0, 1, 2, 3). Note that values can
// be less
// than 0, or greater than 1 due to trignometric calculations for
// location of
// the box.
type GoogleCloudVideointelligenceV1p1beta1NormalizedBoundingPoly struct {
	// Vertices: Normalized vertices of the bounding polygon.
	Vertices []*GoogleCloudVideointelligenceV1p1beta1NormalizedVertex `json:"vertices,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Vertices") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Vertices") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1NormalizedBoundingPoly) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1NormalizedBoundingPoly
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p1beta1NormalizedVertex: A vertex
// represents a 2D point in the image.
// NOTE: the normalized vertex coordinates are relative to the original
// image
// and range from 0 to 1.
type GoogleCloudVideointelligenceV1p1beta1NormalizedVertex struct {
	// X: X coordinate.
	X float64 `json:"x,omitempty"`

	// Y: Y coordinate.
	Y float64 `json:"y,omitempty"`

	// ForceSendFields is a list of field names (e.g. "X") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "X") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1NormalizedVertex) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1NormalizedVertex
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p1beta1NormalizedVertex) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1NormalizedVertex
	var s1 struct {
		X gensupport.JSONFloat64 `json:"x"`
		Y gensupport.JSONFloat64 `json:"y"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.X = float64(s1.X)
	s.Y = float64(s1.Y)
	return nil
}

// GoogleCloudVideointelligenceV1p1beta1ObjectTrackingAnnotation:
// Annotations corresponding to one tracked object.
type GoogleCloudVideointelligenceV1p1beta1ObjectTrackingAnnotation struct {
	// Confidence: Object category's labeling confidence of this track.
	Confidence float64 `json:"confidence,omitempty"`

	// Entity: Entity to specify the object category that this track is
	// labeled as.
	Entity *GoogleCloudVideointelligenceV1p1beta1Entity `json:"entity,omitempty"`

	// Frames: Information corresponding to all frames where this object
	// track appears.
	// Non-streaming batch mode: it may be one or multiple
	// ObjectTrackingFrame
	// messages in frames.
	// Streaming mode: it can only be one ObjectTrackingFrame message in
	// frames.
	Frames []*GoogleCloudVideointelligenceV1p1beta1ObjectTrackingFrame `json:"frames,omitempty"`

	// Segment: Non-streaming batch mode ONLY.
	// Each object track corresponds to one video segment where it appears.
	Segment *GoogleCloudVideointelligenceV1p1beta1VideoSegment `json:"segment,omitempty"`

	// TrackId: Streaming mode ONLY.
	// In streaming mode, we do not know the end time of a tracked
	// object
	// before it is completed. Hence, there is no VideoSegment info
	// returned.
	// Instead, we provide a unique identifiable integer track_id so
	// that
	// the customers can correlate the results of the
	// ongoing
	// ObjectTrackAnnotation of the same track_id over time.
	TrackId int64 `json:"trackId,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1ObjectTrackingAnnotation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1ObjectTrackingAnnotation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p1beta1ObjectTrackingAnnotation) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1ObjectTrackingAnnotation
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1p1beta1ObjectTrackingConfig: Config for
// OBJECT_TRACKING.
type GoogleCloudVideointelligenceV1p1beta1ObjectTrackingConfig struct {
	// Model: Model to use for object tracking.
	// Supported values: "builtin/stable" (the default if unset)
	// and
	// "builtin/latest".
	Model string `json:"model,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Model") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Model") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1ObjectTrackingConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1ObjectTrackingConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p1beta1ObjectTrackingFrame: Video frame
// level annotations for object detection and tracking. This
// field
// stores per frame location, time offset, and confidence.
type GoogleCloudVideointelligenceV1p1beta1ObjectTrackingFrame struct {
	// NormalizedBoundingBox: The normalized bounding box location of this
	// object track for the frame.
	NormalizedBoundingBox *GoogleCloudVideointelligenceV1p1beta1NormalizedBoundingBox `json:"normalizedBoundingBox,omitempty"`

	// TimeOffset: The timestamp of the frame in microseconds.
	TimeOffset string `json:"timeOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "NormalizedBoundingBox") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NormalizedBoundingBox") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1ObjectTrackingFrame) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1ObjectTrackingFrame
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p1beta1ShotChangeDetectionConfig:
// Config for SHOT_CHANGE_DETECTION.
type GoogleCloudVideointelligenceV1p1beta1ShotChangeDetectionConfig struct {
	// Model: Model to use for shot change detection.
	// Supported values: "builtin/stable" (the default if unset)
	// and
	// "builtin/latest".
	Model string `json:"model,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Model") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Model") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1ShotChangeDetectionConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1ShotChangeDetectionConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p1beta1SpeechContext: Provides "hints"
// to the speech recognizer to favor specific words and phrases
// in the results.
type GoogleCloudVideointelligenceV1p1beta1SpeechContext struct {
	// Phrases: Optional. A list of strings containing words and phrases
	// "hints" so that
	// the speech recognition is more likely to recognize them. This can be
	// used
	// to improve the accuracy for specific words and phrases, for example,
	// if
	// specific commands are typically spoken by the user. This can also be
	// used
	// to add additional words to the vocabulary of the recognizer.
	// See
	// [usage limits](https://cloud.google.com/speech/limits#content).
	Phrases []string `json:"phrases,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Phrases") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Phrases") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1SpeechContext) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1SpeechContext
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p1beta1SpeechRecognitionAlternative:
// Alternative hypotheses (a.k.a. n-best list).
type GoogleCloudVideointelligenceV1p1beta1SpeechRecognitionAlternative struct {
	// Confidence: Output only. The confidence estimate between 0.0 and 1.0.
	// A higher number
	// indicates an estimated greater likelihood that the recognized words
	// are
	// correct. This field is set only for the top alternative.
	// This field is not guaranteed to be accurate and users should not rely
	// on it
	// to be always provided.
	// The default of 0.0 is a sentinel value indicating `confidence` was
	// not set.
	Confidence float64 `json:"confidence,omitempty"`

	// Transcript: Transcript text representing the words that the user
	// spoke.
	Transcript string `json:"transcript,omitempty"`

	// Words: Output only. A list of word-specific information for each
	// recognized word.
	// Note: When `enable_speaker_diarization` is true, you will see all the
	// words
	// from the beginning of the audio.
	Words []*GoogleCloudVideointelligenceV1p1beta1WordInfo `json:"words,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1SpeechRecognitionAlternative) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1SpeechRecognitionAlternative
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p1beta1SpeechRecognitionAlternative) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1SpeechRecognitionAlternative
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1p1beta1SpeechTranscription: A speech
// recognition result corresponding to a portion of the audio.
type GoogleCloudVideointelligenceV1p1beta1SpeechTranscription struct {
	// Alternatives: May contain one or more recognition hypotheses (up to
	// the maximum specified
	// in `max_alternatives`).  These alternatives are ordered in terms
	// of
	// accuracy, with the top (first) alternative being the most probable,
	// as
	// ranked by the recognizer.
	Alternatives []*GoogleCloudVideointelligenceV1p1beta1SpeechRecognitionAlternative `json:"alternatives,omitempty"`

	// LanguageCode: Output only. The
	// [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tag
	// of
	// the language in this result. This language code was detected to have
	// the
	// most likelihood of being spoken in the audio.
	LanguageCode string `json:"languageCode,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Alternatives") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Alternatives") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1SpeechTranscription) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1SpeechTranscription
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p1beta1SpeechTranscriptionConfig:
// Config for SPEECH_TRANSCRIPTION.
type GoogleCloudVideointelligenceV1p1beta1SpeechTranscriptionConfig struct {
	// AudioTracks: Optional. For file formats, such as MXF or MKV,
	// supporting multiple audio
	// tracks, specify up to two tracks. Default: track 0.
	AudioTracks []int64 `json:"audioTracks,omitempty"`

	// DiarizationSpeakerCount: Optional. If set, specifies the estimated
	// number of speakers in the conversation.
	// If not set, defaults to '2'.
	// Ignored unless enable_speaker_diarization is set to true.
	DiarizationSpeakerCount int64 `json:"diarizationSpeakerCount,omitempty"`

	// EnableAutomaticPunctuation: Optional. If 'true', adds punctuation to
	// recognition result hypotheses.
	// This feature is only available in select languages. Setting this
	// for
	// requests in other languages has no effect at all. The default 'false'
	// value
	// does not add punctuation to result hypotheses. NOTE: "This is
	// currently
	// offered as an experimental service, complimentary to all users. In
	// the
	// future this may be exclusively available as a premium feature."
	EnableAutomaticPunctuation bool `json:"enableAutomaticPunctuation,omitempty"`

	// EnableSpeakerDiarization: Optional. If 'true', enables speaker
	// detection for each recognized word in
	// the top alternative of the recognition result using a speaker_tag
	// provided
	// in the WordInfo.
	// Note: When this is true, we send all the words from the beginning of
	// the
	// audio for the top alternative in every consecutive responses.
	// This is done in order to improve our speaker tags as our models learn
	// to
	// identify the speakers in the conversation over time.
	EnableSpeakerDiarization bool `json:"enableSpeakerDiarization,omitempty"`

	// EnableWordConfidence: Optional. If `true`, the top result includes a
	// list of words and the
	// confidence for those words. If `false`, no word-level
	// confidence
	// information is returned. The default is `false`.
	EnableWordConfidence bool `json:"enableWordConfidence,omitempty"`

	// FilterProfanity: Optional. If set to `true`, the server will attempt
	// to filter out
	// profanities, replacing all but the initial character in each filtered
	// word
	// with asterisks, e.g. "f***". If set to `false` or omitted,
	// profanities
	// won't be filtered out.
	FilterProfanity bool `json:"filterProfanity,omitempty"`

	// LanguageCode: Required. *Required* The language of the supplied audio
	// as a
	// [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language
	// tag.
	// Example: "en-US".
	// See [Language
	// Support](https://cloud.google.com/speech/docs/languages)
	// for a list of the currently supported language codes.
	LanguageCode string `json:"languageCode,omitempty"`

	// MaxAlternatives: Optional. Maximum number of recognition hypotheses
	// to be returned.
	// Specifically, the maximum number of `SpeechRecognitionAlternative`
	// messages
	// within each `SpeechTranscription`. The server may return fewer
	// than
	// `max_alternatives`. Valid values are `0`-`30`. A value of `0` or `1`
	// will
	// return a maximum of one. If omitted, will return a maximum of one.
	MaxAlternatives int64 `json:"maxAlternatives,omitempty"`

	// SpeechContexts: Optional. A means to provide context to assist the
	// speech recognition.
	SpeechContexts []*GoogleCloudVideointelligenceV1p1beta1SpeechContext `json:"speechContexts,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AudioTracks") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AudioTracks") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1SpeechTranscriptionConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1SpeechTranscriptionConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p1beta1TextAnnotation: Annotations
// related to one detected OCR text snippet. This will contain
// the
// corresponding text, confidence value, and frame level information for
// each
// detection.
type GoogleCloudVideointelligenceV1p1beta1TextAnnotation struct {
	// Segments: All video segments where OCR detected text appears.
	Segments []*GoogleCloudVideointelligenceV1p1beta1TextSegment `json:"segments,omitempty"`

	// Text: The detected text.
	Text string `json:"text,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Segments") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Segments") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1TextAnnotation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1TextAnnotation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p1beta1TextDetectionConfig: Config for
// TEXT_DETECTION.
type GoogleCloudVideointelligenceV1p1beta1TextDetectionConfig struct {
	// LanguageHints: Language hint can be specified if the language to be
	// detected is known a
	// priori. It can increase the accuracy of the detection. Language hint
	// must
	// be language code in BCP-47 format.
	//
	// Automatic language detection is performed if no hint is provided.
	LanguageHints []string `json:"languageHints,omitempty"`

	// Model: Model to use for text detection.
	// Supported values: "builtin/stable" (the default if unset)
	// and
	// "builtin/latest".
	Model string `json:"model,omitempty"`

	// ForceSendFields is a list of field names (e.g. "LanguageHints") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "LanguageHints") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1TextDetectionConfig) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1TextDetectionConfig
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p1beta1TextFrame: Video frame level
// annotation results for text annotation (OCR).
// Contains information regarding timestamp and bounding box locations
// for the
// frames containing detected OCR text snippets.
type GoogleCloudVideointelligenceV1p1beta1TextFrame struct {
	// RotatedBoundingBox: Bounding polygon of the detected text for this
	// frame.
	RotatedBoundingBox *GoogleCloudVideointelligenceV1p1beta1NormalizedBoundingPoly `json:"rotatedBoundingBox,omitempty"`

	// TimeOffset: Timestamp of this frame.
	TimeOffset string `json:"timeOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g. "RotatedBoundingBox")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "RotatedBoundingBox") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1TextFrame) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1TextFrame
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p1beta1TextSegment: Video segment level
// annotation results for text detection.
type GoogleCloudVideointelligenceV1p1beta1TextSegment struct {
	// Confidence: Confidence for the track of detected text. It is
	// calculated as the highest
	// over all frames where OCR detected text appears.
	Confidence float64 `json:"confidence,omitempty"`

	// Frames: Information related to the frames where OCR detected text
	// appears.
	Frames []*GoogleCloudVideointelligenceV1p1beta1TextFrame `json:"frames,omitempty"`

	// Segment: Video segment where a text snippet was detected.
	Segment *GoogleCloudVideointelligenceV1p1beta1VideoSegment `json:"segment,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1TextSegment) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1TextSegment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p1beta1TextSegment) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1TextSegment
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1p1beta1VideoAnnotationProgress:
// Annotation progress for a single video.
type GoogleCloudVideointelligenceV1p1beta1VideoAnnotationProgress struct {
	// Feature: Specifies which feature is being tracked if the request
	// contains more than
	// one features.
	//
	// Possible values:
	//   "FEATURE_UNSPECIFIED" - Unspecified.
	//   "LABEL_DETECTION" - Label detection. Detect objects, such as dog or
	// flower.
	//   "SHOT_CHANGE_DETECTION" - Shot change detection.
	//   "EXPLICIT_CONTENT_DETECTION" - Explicit content detection.
	//   "SPEECH_TRANSCRIPTION" - Speech transcription.
	//   "TEXT_DETECTION" - OCR text detection and tracking.
	//   "OBJECT_TRACKING" - Object detection and tracking.
	Feature string `json:"feature,omitempty"`

	// InputUri: Video file location in
	// [Google Cloud Storage](https://cloud.google.com/storage/).
	InputUri string `json:"inputUri,omitempty"`

	// ProgressPercent: Approximate percentage processed thus far.
	// Guaranteed to be
	// 100 when fully processed.
	ProgressPercent int64 `json:"progressPercent,omitempty"`

	// Segment: Specifies which segment is being tracked if the request
	// contains more than
	// one segments.
	Segment *GoogleCloudVideointelligenceV1p1beta1VideoSegment `json:"segment,omitempty"`

	// StartTime: Time when the request was received.
	StartTime string `json:"startTime,omitempty"`

	// UpdateTime: Time of the most recent update.
	UpdateTime string `json:"updateTime,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Feature") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Feature") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1VideoAnnotationProgress) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1VideoAnnotationProgress
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p1beta1VideoAnnotationResults:
// Annotation results for a single video.
type GoogleCloudVideointelligenceV1p1beta1VideoAnnotationResults struct {
	// Error: If set, indicates an error. Note that for a single
	// `AnnotateVideoRequest`
	// some videos may succeed and some may fail.
	Error *GoogleRpcStatus `json:"error,omitempty"`

	// ExplicitAnnotation: Explicit content annotation.
	ExplicitAnnotation *GoogleCloudVideointelligenceV1p1beta1ExplicitContentAnnotation `json:"explicitAnnotation,omitempty"`

	// FrameLabelAnnotations: Label annotations on frame level.
	// There is exactly one element for each unique label.
	FrameLabelAnnotations []*GoogleCloudVideointelligenceV1p1beta1LabelAnnotation `json:"frameLabelAnnotations,omitempty"`

	// InputUri: Video file location in
	// [Google Cloud Storage](https://cloud.google.com/storage/).
	InputUri string `json:"inputUri,omitempty"`

	// ObjectAnnotations: Annotations for list of objects detected and
	// tracked in video.
	ObjectAnnotations []*GoogleCloudVideointelligenceV1p1beta1ObjectTrackingAnnotation `json:"objectAnnotations,omitempty"`

	// Segment: Video segment on which the annotation is run.
	Segment *GoogleCloudVideointelligenceV1p1beta1VideoSegment `json:"segment,omitempty"`

	// SegmentLabelAnnotations: Topical label annotations on video level or
	// user specified segment level.
	// There is exactly one element for each unique label.
	SegmentLabelAnnotations []*GoogleCloudVideointelligenceV1p1beta1LabelAnnotation `json:"segmentLabelAnnotations,omitempty"`

	// SegmentPresenceLabelAnnotations: Presence label annotations on video
	// level or user specified segment level.
	// There is exactly one element for each unique label. Compared to
	// the
	// existing topical `segment_label_annotations`, this field presents
	// more
	// fine-grained, segment-level labels detected in video content and is
	// made
	// available only when the client sets `LabelDetectionConfig.model`
	// to
	// "builtin/latest" in the request.
	SegmentPresenceLabelAnnotations []*GoogleCloudVideointelligenceV1p1beta1LabelAnnotation `json:"segmentPresenceLabelAnnotations,omitempty"`

	// ShotAnnotations: Shot annotations. Each shot is represented as a
	// video segment.
	ShotAnnotations []*GoogleCloudVideointelligenceV1p1beta1VideoSegment `json:"shotAnnotations,omitempty"`

	// ShotLabelAnnotations: Topical label annotations on shot level.
	// There is exactly one element for each unique label.
	ShotLabelAnnotations []*GoogleCloudVideointelligenceV1p1beta1LabelAnnotation `json:"shotLabelAnnotations,omitempty"`

	// ShotPresenceLabelAnnotations: Presence label annotations on shot
	// level. There is exactly one element for
	// each unique label. Compared to the existing
	// topical
	// `shot_label_annotations`, this field presents more fine-grained,
	// shot-level
	// labels detected in video content and is made available only when the
	// client
	// sets `LabelDetectionConfig.model` to "builtin/latest" in the request.
	ShotPresenceLabelAnnotations []*GoogleCloudVideointelligenceV1p1beta1LabelAnnotation `json:"shotPresenceLabelAnnotations,omitempty"`

	// SpeechTranscriptions: Speech transcription.
	SpeechTranscriptions []*GoogleCloudVideointelligenceV1p1beta1SpeechTranscription `json:"speechTranscriptions,omitempty"`

	// TextAnnotations: OCR text detection and tracking.
	// Annotations for list of detected text snippets. Each will have list
	// of
	// frame information associated with it.
	TextAnnotations []*GoogleCloudVideointelligenceV1p1beta1TextAnnotation `json:"textAnnotations,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Error") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Error") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1VideoAnnotationResults) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1VideoAnnotationResults
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p1beta1VideoContext: Video context
// and/or feature-specific parameters.
type GoogleCloudVideointelligenceV1p1beta1VideoContext struct {
	// ExplicitContentDetectionConfig: Config for
	// EXPLICIT_CONTENT_DETECTION.
	ExplicitContentDetectionConfig *GoogleCloudVideointelligenceV1p1beta1ExplicitContentDetectionConfig `json:"explicitContentDetectionConfig,omitempty"`

	// LabelDetectionConfig: Config for LABEL_DETECTION.
	LabelDetectionConfig *GoogleCloudVideointelligenceV1p1beta1LabelDetectionConfig `json:"labelDetectionConfig,omitempty"`

	// ObjectTrackingConfig: Config for OBJECT_TRACKING.
	ObjectTrackingConfig *GoogleCloudVideointelligenceV1p1beta1ObjectTrackingConfig `json:"objectTrackingConfig,omitempty"`

	// Segments: Video segments to annotate. The segments may overlap and
	// are not required
	// to be contiguous or span the whole video. If unspecified, each video
	// is
	// treated as a single segment.
	Segments []*GoogleCloudVideointelligenceV1p1beta1VideoSegment `json:"segments,omitempty"`

	// ShotChangeDetectionConfig: Config for SHOT_CHANGE_DETECTION.
	ShotChangeDetectionConfig *GoogleCloudVideointelligenceV1p1beta1ShotChangeDetectionConfig `json:"shotChangeDetectionConfig,omitempty"`

	// SpeechTranscriptionConfig: Config for SPEECH_TRANSCRIPTION.
	SpeechTranscriptionConfig *GoogleCloudVideointelligenceV1p1beta1SpeechTranscriptionConfig `json:"speechTranscriptionConfig,omitempty"`

	// TextDetectionConfig: Config for TEXT_DETECTION.
	TextDetectionConfig *GoogleCloudVideointelligenceV1p1beta1TextDetectionConfig `json:"textDetectionConfig,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "ExplicitContentDetectionConfig") to unconditionally include in API
	// requests. By default, fields with empty values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g.
	// "ExplicitContentDetectionConfig") to include in API requests with the
	// JSON null value. By default, fields with empty values are omitted
	// from API requests. However, any field with an empty value appearing
	// in NullFields will be sent to the server as null. It is an error if a
	// field in this list has a non-empty value. This may be used to include
	// null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1VideoContext) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1VideoContext
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p1beta1VideoSegment: Video segment.
type GoogleCloudVideointelligenceV1p1beta1VideoSegment struct {
	// EndTimeOffset: Time-offset, relative to the beginning of the
	// video,
	// corresponding to the end of the segment (inclusive).
	EndTimeOffset string `json:"endTimeOffset,omitempty"`

	// StartTimeOffset: Time-offset, relative to the beginning of the
	// video,
	// corresponding to the start of the segment (inclusive).
	StartTimeOffset string `json:"startTimeOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g. "EndTimeOffset") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "EndTimeOffset") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1VideoSegment) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1VideoSegment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p1beta1WordInfo: Word-specific
// information for recognized words. Word information is only
// included in the response when certain request parameters are set,
// such
// as `enable_word_time_offsets`.
type GoogleCloudVideointelligenceV1p1beta1WordInfo struct {
	// Confidence: Output only. The confidence estimate between 0.0 and 1.0.
	// A higher number
	// indicates an estimated greater likelihood that the recognized words
	// are
	// correct. This field is set only for the top alternative.
	// This field is not guaranteed to be accurate and users should not rely
	// on it
	// to be always provided.
	// The default of 0.0 is a sentinel value indicating `confidence` was
	// not set.
	Confidence float64 `json:"confidence,omitempty"`

	// EndTime: Time offset relative to the beginning of the audio,
	// and
	// corresponding to the end of the spoken word. This field is only set
	// if
	// `enable_word_time_offsets=true` and only in the top hypothesis. This
	// is an
	// experimental feature and the accuracy of the time offset can vary.
	EndTime string `json:"endTime,omitempty"`

	// SpeakerTag: Output only. A distinct integer value is assigned for
	// every speaker within
	// the audio. This field specifies which one of those speakers was
	// detected to
	// have spoken this word. Value ranges from 1 up to
	// diarization_speaker_count,
	// and is only set if speaker diarization is enabled.
	SpeakerTag int64 `json:"speakerTag,omitempty"`

	// StartTime: Time offset relative to the beginning of the audio,
	// and
	// corresponding to the start of the spoken word. This field is only set
	// if
	// `enable_word_time_offsets=true` and only in the top hypothesis. This
	// is an
	// experimental feature and the accuracy of the time offset can vary.
	StartTime string `json:"startTime,omitempty"`

	// Word: The word corresponding to this set of information.
	Word string `json:"word,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p1beta1WordInfo) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1WordInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p1beta1WordInfo) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p1beta1WordInfo
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1p2beta1AnnotateVideoProgress: Video
// annotation progress. Included in the `metadata`
// field of the `Operation` returned by the `GetOperation`
// call of the `google::longrunning::Operations` service.
type GoogleCloudVideointelligenceV1p2beta1AnnotateVideoProgress struct {
	// AnnotationProgress: Progress metadata for all videos specified in
	// `AnnotateVideoRequest`.
	AnnotationProgress []*GoogleCloudVideointelligenceV1p2beta1VideoAnnotationProgress `json:"annotationProgress,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AnnotationProgress")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AnnotationProgress") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p2beta1AnnotateVideoProgress) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1AnnotateVideoProgress
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p2beta1AnnotateVideoResponse: Video
// annotation response. Included in the `response`
// field of the `Operation` returned by the `GetOperation`
// call of the `google::longrunning::Operations` service.
type GoogleCloudVideointelligenceV1p2beta1AnnotateVideoResponse struct {
	// AnnotationResults: Annotation results for all videos specified in
	// `AnnotateVideoRequest`.
	AnnotationResults []*GoogleCloudVideointelligenceV1p2beta1VideoAnnotationResults `json:"annotationResults,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AnnotationResults")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AnnotationResults") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p2beta1AnnotateVideoResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1AnnotateVideoResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p2beta1Entity: Detected entity from
// video analysis.
type GoogleCloudVideointelligenceV1p2beta1Entity struct {
	// Description: Textual description, e.g. `Fixed-gear bicycle`.
	Description string `json:"description,omitempty"`

	// EntityId: Opaque entity ID. Some IDs may be available in
	// [Google Knowledge Graph
	// Search
	// API](https://developers.google.com/knowledge-graph/).
	EntityId string `json:"entityId,omitempty"`

	// LanguageCode: Language code for `description` in BCP-47 format.
	LanguageCode string `json:"languageCode,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Description") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p2beta1Entity) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1Entity
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p2beta1ExplicitContentAnnotation:
// Explicit content annotation (based on per-frame visual signals
// only).
// If no explicit content has been detected in a frame, no annotations
// are
// present for that frame.
type GoogleCloudVideointelligenceV1p2beta1ExplicitContentAnnotation struct {
	// Frames: All video frames where explicit content was detected.
	Frames []*GoogleCloudVideointelligenceV1p2beta1ExplicitContentFrame `json:"frames,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Frames") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Frames") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p2beta1ExplicitContentAnnotation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1ExplicitContentAnnotation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p2beta1ExplicitContentFrame: Video
// frame level annotation results for explicit content.
type GoogleCloudVideointelligenceV1p2beta1ExplicitContentFrame struct {
	// PornographyLikelihood: Likelihood of the pornography content..
	//
	// Possible values:
	//   "LIKELIHOOD_UNSPECIFIED" - Unspecified likelihood.
	//   "VERY_UNLIKELY" - Very unlikely.
	//   "UNLIKELY" - Unlikely.
	//   "POSSIBLE" - Possible.
	//   "LIKELY" - Likely.
	//   "VERY_LIKELY" - Very likely.
	PornographyLikelihood string `json:"pornographyLikelihood,omitempty"`

	// TimeOffset: Time-offset, relative to the beginning of the video,
	// corresponding to the
	// video frame for this location.
	TimeOffset string `json:"timeOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "PornographyLikelihood") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "PornographyLikelihood") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p2beta1ExplicitContentFrame) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1ExplicitContentFrame
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p2beta1LabelAnnotation: Label
// annotation.
type GoogleCloudVideointelligenceV1p2beta1LabelAnnotation struct {
	// CategoryEntities: Common categories for the detected entity.
	// E.g. when the label is `Terrier` the category is likely `dog`. And in
	// some
	// cases there might be more than one categories e.g. `Terrier` could
	// also be
	// a `pet`.
	CategoryEntities []*GoogleCloudVideointelligenceV1p2beta1Entity `json:"categoryEntities,omitempty"`

	// Entity: Detected entity.
	Entity *GoogleCloudVideointelligenceV1p2beta1Entity `json:"entity,omitempty"`

	// Frames: All video frames where a label was detected.
	Frames []*GoogleCloudVideointelligenceV1p2beta1LabelFrame `json:"frames,omitempty"`

	// Segments: All video segments where a label was detected.
	Segments []*GoogleCloudVideointelligenceV1p2beta1LabelSegment `json:"segments,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CategoryEntities") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CategoryEntities") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p2beta1LabelAnnotation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1LabelAnnotation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p2beta1LabelFrame: Video frame level
// annotation results for label detection.
type GoogleCloudVideointelligenceV1p2beta1LabelFrame struct {
	// Confidence: Confidence that the label is accurate. Range: [0, 1].
	Confidence float64 `json:"confidence,omitempty"`

	// TimeOffset: Time-offset, relative to the beginning of the video,
	// corresponding to the
	// video frame for this location.
	TimeOffset string `json:"timeOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p2beta1LabelFrame) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1LabelFrame
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p2beta1LabelFrame) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1LabelFrame
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1p2beta1LabelSegment: Video segment
// level annotation results for label detection.
type GoogleCloudVideointelligenceV1p2beta1LabelSegment struct {
	// Confidence: Confidence that the label is accurate. Range: [0, 1].
	Confidence float64 `json:"confidence,omitempty"`

	// Segment: Video segment where a label was detected.
	Segment *GoogleCloudVideointelligenceV1p2beta1VideoSegment `json:"segment,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p2beta1LabelSegment) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1LabelSegment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p2beta1LabelSegment) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1LabelSegment
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1p2beta1NormalizedBoundingBox:
// Normalized bounding box.
// The normalized vertex coordinates are relative to the original
// image.
// Range: [0, 1].
type GoogleCloudVideointelligenceV1p2beta1NormalizedBoundingBox struct {
	// Bottom: Bottom Y coordinate.
	Bottom float64 `json:"bottom,omitempty"`

	// Left: Left X coordinate.
	Left float64 `json:"left,omitempty"`

	// Right: Right X coordinate.
	Right float64 `json:"right,omitempty"`

	// Top: Top Y coordinate.
	Top float64 `json:"top,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Bottom") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Bottom") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p2beta1NormalizedBoundingBox) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1NormalizedBoundingBox
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p2beta1NormalizedBoundingBox) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1NormalizedBoundingBox
	var s1 struct {
		Bottom gensupport.JSONFloat64 `json:"bottom"`
		Left   gensupport.JSONFloat64 `json:"left"`
		Right  gensupport.JSONFloat64 `json:"right"`
		Top    gensupport.JSONFloat64 `json:"top"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Bottom = float64(s1.Bottom)
	s.Left = float64(s1.Left)
	s.Right = float64(s1.Right)
	s.Top = float64(s1.Top)
	return nil
}

// GoogleCloudVideointelligenceV1p2beta1NormalizedBoundingPoly:
// Normalized bounding polygon for text (that might not be aligned with
// axis).
// Contains list of the corner points in clockwise order starting
// from
// top-left corner. For example, for a rectangular bounding box:
// When the text is horizontal it might look like:
//         0----1
//         |    |
//         3----2
//
// When it's clockwise rotated 180 degrees around the top-left corner
// it
// becomes:
//         2----3
//         |    |
//         1----0
//
// and the vertex order will still be (0, 1, 2, 3). Note that values can
// be less
// than 0, or greater than 1 due to trignometric calculations for
// location of
// the box.
type GoogleCloudVideointelligenceV1p2beta1NormalizedBoundingPoly struct {
	// Vertices: Normalized vertices of the bounding polygon.
	Vertices []*GoogleCloudVideointelligenceV1p2beta1NormalizedVertex `json:"vertices,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Vertices") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Vertices") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p2beta1NormalizedBoundingPoly) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1NormalizedBoundingPoly
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p2beta1NormalizedVertex: A vertex
// represents a 2D point in the image.
// NOTE: the normalized vertex coordinates are relative to the original
// image
// and range from 0 to 1.
type GoogleCloudVideointelligenceV1p2beta1NormalizedVertex struct {
	// X: X coordinate.
	X float64 `json:"x,omitempty"`

	// Y: Y coordinate.
	Y float64 `json:"y,omitempty"`

	// ForceSendFields is a list of field names (e.g. "X") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "X") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p2beta1NormalizedVertex) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1NormalizedVertex
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p2beta1NormalizedVertex) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1NormalizedVertex
	var s1 struct {
		X gensupport.JSONFloat64 `json:"x"`
		Y gensupport.JSONFloat64 `json:"y"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.X = float64(s1.X)
	s.Y = float64(s1.Y)
	return nil
}

// GoogleCloudVideointelligenceV1p2beta1ObjectTrackingAnnotation:
// Annotations corresponding to one tracked object.
type GoogleCloudVideointelligenceV1p2beta1ObjectTrackingAnnotation struct {
	// Confidence: Object category's labeling confidence of this track.
	Confidence float64 `json:"confidence,omitempty"`

	// Entity: Entity to specify the object category that this track is
	// labeled as.
	Entity *GoogleCloudVideointelligenceV1p2beta1Entity `json:"entity,omitempty"`

	// Frames: Information corresponding to all frames where this object
	// track appears.
	// Non-streaming batch mode: it may be one or multiple
	// ObjectTrackingFrame
	// messages in frames.
	// Streaming mode: it can only be one ObjectTrackingFrame message in
	// frames.
	Frames []*GoogleCloudVideointelligenceV1p2beta1ObjectTrackingFrame `json:"frames,omitempty"`

	// Segment: Non-streaming batch mode ONLY.
	// Each object track corresponds to one video segment where it appears.
	Segment *GoogleCloudVideointelligenceV1p2beta1VideoSegment `json:"segment,omitempty"`

	// TrackId: Streaming mode ONLY.
	// In streaming mode, we do not know the end time of a tracked
	// object
	// before it is completed. Hence, there is no VideoSegment info
	// returned.
	// Instead, we provide a unique identifiable integer track_id so
	// that
	// the customers can correlate the results of the
	// ongoing
	// ObjectTrackAnnotation of the same track_id over time.
	TrackId int64 `json:"trackId,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p2beta1ObjectTrackingAnnotation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1ObjectTrackingAnnotation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p2beta1ObjectTrackingAnnotation) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1ObjectTrackingAnnotation
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1p2beta1ObjectTrackingFrame: Video frame
// level annotations for object detection and tracking. This
// field
// stores per frame location, time offset, and confidence.
type GoogleCloudVideointelligenceV1p2beta1ObjectTrackingFrame struct {
	// NormalizedBoundingBox: The normalized bounding box location of this
	// object track for the frame.
	NormalizedBoundingBox *GoogleCloudVideointelligenceV1p2beta1NormalizedBoundingBox `json:"normalizedBoundingBox,omitempty"`

	// TimeOffset: The timestamp of the frame in microseconds.
	TimeOffset string `json:"timeOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "NormalizedBoundingBox") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NormalizedBoundingBox") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p2beta1ObjectTrackingFrame) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1ObjectTrackingFrame
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p2beta1SpeechRecognitionAlternative:
// Alternative hypotheses (a.k.a. n-best list).
type GoogleCloudVideointelligenceV1p2beta1SpeechRecognitionAlternative struct {
	// Confidence: Output only. The confidence estimate between 0.0 and 1.0.
	// A higher number
	// indicates an estimated greater likelihood that the recognized words
	// are
	// correct. This field is set only for the top alternative.
	// This field is not guaranteed to be accurate and users should not rely
	// on it
	// to be always provided.
	// The default of 0.0 is a sentinel value indicating `confidence` was
	// not set.
	Confidence float64 `json:"confidence,omitempty"`

	// Transcript: Transcript text representing the words that the user
	// spoke.
	Transcript string `json:"transcript,omitempty"`

	// Words: Output only. A list of word-specific information for each
	// recognized word.
	// Note: When `enable_speaker_diarization` is true, you will see all the
	// words
	// from the beginning of the audio.
	Words []*GoogleCloudVideointelligenceV1p2beta1WordInfo `json:"words,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p2beta1SpeechRecognitionAlternative) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1SpeechRecognitionAlternative
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p2beta1SpeechRecognitionAlternative) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1SpeechRecognitionAlternative
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1p2beta1SpeechTranscription: A speech
// recognition result corresponding to a portion of the audio.
type GoogleCloudVideointelligenceV1p2beta1SpeechTranscription struct {
	// Alternatives: May contain one or more recognition hypotheses (up to
	// the maximum specified
	// in `max_alternatives`).  These alternatives are ordered in terms
	// of
	// accuracy, with the top (first) alternative being the most probable,
	// as
	// ranked by the recognizer.
	Alternatives []*GoogleCloudVideointelligenceV1p2beta1SpeechRecognitionAlternative `json:"alternatives,omitempty"`

	// LanguageCode: Output only. The
	// [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tag
	// of
	// the language in this result. This language code was detected to have
	// the
	// most likelihood of being spoken in the audio.
	LanguageCode string `json:"languageCode,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Alternatives") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Alternatives") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p2beta1SpeechTranscription) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1SpeechTranscription
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p2beta1TextAnnotation: Annotations
// related to one detected OCR text snippet. This will contain
// the
// corresponding text, confidence value, and frame level information for
// each
// detection.
type GoogleCloudVideointelligenceV1p2beta1TextAnnotation struct {
	// Segments: All video segments where OCR detected text appears.
	Segments []*GoogleCloudVideointelligenceV1p2beta1TextSegment `json:"segments,omitempty"`

	// Text: The detected text.
	Text string `json:"text,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Segments") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Segments") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p2beta1TextAnnotation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1TextAnnotation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p2beta1TextFrame: Video frame level
// annotation results for text annotation (OCR).
// Contains information regarding timestamp and bounding box locations
// for the
// frames containing detected OCR text snippets.
type GoogleCloudVideointelligenceV1p2beta1TextFrame struct {
	// RotatedBoundingBox: Bounding polygon of the detected text for this
	// frame.
	RotatedBoundingBox *GoogleCloudVideointelligenceV1p2beta1NormalizedBoundingPoly `json:"rotatedBoundingBox,omitempty"`

	// TimeOffset: Timestamp of this frame.
	TimeOffset string `json:"timeOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g. "RotatedBoundingBox")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "RotatedBoundingBox") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p2beta1TextFrame) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1TextFrame
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p2beta1TextSegment: Video segment level
// annotation results for text detection.
type GoogleCloudVideointelligenceV1p2beta1TextSegment struct {
	// Confidence: Confidence for the track of detected text. It is
	// calculated as the highest
	// over all frames where OCR detected text appears.
	Confidence float64 `json:"confidence,omitempty"`

	// Frames: Information related to the frames where OCR detected text
	// appears.
	Frames []*GoogleCloudVideointelligenceV1p2beta1TextFrame `json:"frames,omitempty"`

	// Segment: Video segment where a text snippet was detected.
	Segment *GoogleCloudVideointelligenceV1p2beta1VideoSegment `json:"segment,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p2beta1TextSegment) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1TextSegment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p2beta1TextSegment) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1TextSegment
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1p2beta1VideoAnnotationProgress:
// Annotation progress for a single video.
type GoogleCloudVideointelligenceV1p2beta1VideoAnnotationProgress struct {
	// Feature: Specifies which feature is being tracked if the request
	// contains more than
	// one features.
	//
	// Possible values:
	//   "FEATURE_UNSPECIFIED" - Unspecified.
	//   "LABEL_DETECTION" - Label detection. Detect objects, such as dog or
	// flower.
	//   "SHOT_CHANGE_DETECTION" - Shot change detection.
	//   "EXPLICIT_CONTENT_DETECTION" - Explicit content detection.
	//   "SPEECH_TRANSCRIPTION" - Speech transcription.
	//   "TEXT_DETECTION" - OCR text detection and tracking.
	//   "OBJECT_TRACKING" - Object detection and tracking.
	Feature string `json:"feature,omitempty"`

	// InputUri: Video file location in
	// [Google Cloud Storage](https://cloud.google.com/storage/).
	InputUri string `json:"inputUri,omitempty"`

	// ProgressPercent: Approximate percentage processed thus far.
	// Guaranteed to be
	// 100 when fully processed.
	ProgressPercent int64 `json:"progressPercent,omitempty"`

	// Segment: Specifies which segment is being tracked if the request
	// contains more than
	// one segments.
	Segment *GoogleCloudVideointelligenceV1p2beta1VideoSegment `json:"segment,omitempty"`

	// StartTime: Time when the request was received.
	StartTime string `json:"startTime,omitempty"`

	// UpdateTime: Time of the most recent update.
	UpdateTime string `json:"updateTime,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Feature") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Feature") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p2beta1VideoAnnotationProgress) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1VideoAnnotationProgress
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p2beta1VideoAnnotationResults:
// Annotation results for a single video.
type GoogleCloudVideointelligenceV1p2beta1VideoAnnotationResults struct {
	// Error: If set, indicates an error. Note that for a single
	// `AnnotateVideoRequest`
	// some videos may succeed and some may fail.
	Error *GoogleRpcStatus `json:"error,omitempty"`

	// ExplicitAnnotation: Explicit content annotation.
	ExplicitAnnotation *GoogleCloudVideointelligenceV1p2beta1ExplicitContentAnnotation `json:"explicitAnnotation,omitempty"`

	// FrameLabelAnnotations: Label annotations on frame level.
	// There is exactly one element for each unique label.
	FrameLabelAnnotations []*GoogleCloudVideointelligenceV1p2beta1LabelAnnotation `json:"frameLabelAnnotations,omitempty"`

	// InputUri: Video file location in
	// [Google Cloud Storage](https://cloud.google.com/storage/).
	InputUri string `json:"inputUri,omitempty"`

	// ObjectAnnotations: Annotations for list of objects detected and
	// tracked in video.
	ObjectAnnotations []*GoogleCloudVideointelligenceV1p2beta1ObjectTrackingAnnotation `json:"objectAnnotations,omitempty"`

	// Segment: Video segment on which the annotation is run.
	Segment *GoogleCloudVideointelligenceV1p2beta1VideoSegment `json:"segment,omitempty"`

	// SegmentLabelAnnotations: Topical label annotations on video level or
	// user specified segment level.
	// There is exactly one element for each unique label.
	SegmentLabelAnnotations []*GoogleCloudVideointelligenceV1p2beta1LabelAnnotation `json:"segmentLabelAnnotations,omitempty"`

	// SegmentPresenceLabelAnnotations: Presence label annotations on video
	// level or user specified segment level.
	// There is exactly one element for each unique label. Compared to
	// the
	// existing topical `segment_label_annotations`, this field presents
	// more
	// fine-grained, segment-level labels detected in video content and is
	// made
	// available only when the client sets `LabelDetectionConfig.model`
	// to
	// "builtin/latest" in the request.
	SegmentPresenceLabelAnnotations []*GoogleCloudVideointelligenceV1p2beta1LabelAnnotation `json:"segmentPresenceLabelAnnotations,omitempty"`

	// ShotAnnotations: Shot annotations. Each shot is represented as a
	// video segment.
	ShotAnnotations []*GoogleCloudVideointelligenceV1p2beta1VideoSegment `json:"shotAnnotations,omitempty"`

	// ShotLabelAnnotations: Topical label annotations on shot level.
	// There is exactly one element for each unique label.
	ShotLabelAnnotations []*GoogleCloudVideointelligenceV1p2beta1LabelAnnotation `json:"shotLabelAnnotations,omitempty"`

	// ShotPresenceLabelAnnotations: Presence label annotations on shot
	// level. There is exactly one element for
	// each unique label. Compared to the existing
	// topical
	// `shot_label_annotations`, this field presents more fine-grained,
	// shot-level
	// labels detected in video content and is made available only when the
	// client
	// sets `LabelDetectionConfig.model` to "builtin/latest" in the request.
	ShotPresenceLabelAnnotations []*GoogleCloudVideointelligenceV1p2beta1LabelAnnotation `json:"shotPresenceLabelAnnotations,omitempty"`

	// SpeechTranscriptions: Speech transcription.
	SpeechTranscriptions []*GoogleCloudVideointelligenceV1p2beta1SpeechTranscription `json:"speechTranscriptions,omitempty"`

	// TextAnnotations: OCR text detection and tracking.
	// Annotations for list of detected text snippets. Each will have list
	// of
	// frame information associated with it.
	TextAnnotations []*GoogleCloudVideointelligenceV1p2beta1TextAnnotation `json:"textAnnotations,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Error") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Error") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p2beta1VideoAnnotationResults) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1VideoAnnotationResults
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p2beta1VideoSegment: Video segment.
type GoogleCloudVideointelligenceV1p2beta1VideoSegment struct {
	// EndTimeOffset: Time-offset, relative to the beginning of the
	// video,
	// corresponding to the end of the segment (inclusive).
	EndTimeOffset string `json:"endTimeOffset,omitempty"`

	// StartTimeOffset: Time-offset, relative to the beginning of the
	// video,
	// corresponding to the start of the segment (inclusive).
	StartTimeOffset string `json:"startTimeOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g. "EndTimeOffset") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "EndTimeOffset") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p2beta1VideoSegment) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1VideoSegment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p2beta1WordInfo: Word-specific
// information for recognized words. Word information is only
// included in the response when certain request parameters are set,
// such
// as `enable_word_time_offsets`.
type GoogleCloudVideointelligenceV1p2beta1WordInfo struct {
	// Confidence: Output only. The confidence estimate between 0.0 and 1.0.
	// A higher number
	// indicates an estimated greater likelihood that the recognized words
	// are
	// correct. This field is set only for the top alternative.
	// This field is not guaranteed to be accurate and users should not rely
	// on it
	// to be always provided.
	// The default of 0.0 is a sentinel value indicating `confidence` was
	// not set.
	Confidence float64 `json:"confidence,omitempty"`

	// EndTime: Time offset relative to the beginning of the audio,
	// and
	// corresponding to the end of the spoken word. This field is only set
	// if
	// `enable_word_time_offsets=true` and only in the top hypothesis. This
	// is an
	// experimental feature and the accuracy of the time offset can vary.
	EndTime string `json:"endTime,omitempty"`

	// SpeakerTag: Output only. A distinct integer value is assigned for
	// every speaker within
	// the audio. This field specifies which one of those speakers was
	// detected to
	// have spoken this word. Value ranges from 1 up to
	// diarization_speaker_count,
	// and is only set if speaker diarization is enabled.
	SpeakerTag int64 `json:"speakerTag,omitempty"`

	// StartTime: Time offset relative to the beginning of the audio,
	// and
	// corresponding to the start of the spoken word. This field is only set
	// if
	// `enable_word_time_offsets=true` and only in the top hypothesis. This
	// is an
	// experimental feature and the accuracy of the time offset can vary.
	StartTime string `json:"startTime,omitempty"`

	// Word: The word corresponding to this set of information.
	Word string `json:"word,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p2beta1WordInfo) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1WordInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p2beta1WordInfo) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p2beta1WordInfo
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1p3beta1AnnotateVideoProgress: Video
// annotation progress. Included in the `metadata`
// field of the `Operation` returned by the `GetOperation`
// call of the `google::longrunning::Operations` service.
type GoogleCloudVideointelligenceV1p3beta1AnnotateVideoProgress struct {
	// AnnotationProgress: Progress metadata for all videos specified in
	// `AnnotateVideoRequest`.
	AnnotationProgress []*GoogleCloudVideointelligenceV1p3beta1VideoAnnotationProgress `json:"annotationProgress,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AnnotationProgress")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AnnotationProgress") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1AnnotateVideoProgress) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1AnnotateVideoProgress
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p3beta1AnnotateVideoResponse: Video
// annotation response. Included in the `response`
// field of the `Operation` returned by the `GetOperation`
// call of the `google::longrunning::Operations` service.
type GoogleCloudVideointelligenceV1p3beta1AnnotateVideoResponse struct {
	// AnnotationResults: Annotation results for all videos specified in
	// `AnnotateVideoRequest`.
	AnnotationResults []*GoogleCloudVideointelligenceV1p3beta1VideoAnnotationResults `json:"annotationResults,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AnnotationResults")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AnnotationResults") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1AnnotateVideoResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1AnnotateVideoResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p3beta1Celebrity: Celebrity definition.
type GoogleCloudVideointelligenceV1p3beta1Celebrity struct {
	// Description: Textual description of additional information about the
	// celebrity, if
	// applicable.
	Description string `json:"description,omitempty"`

	// DisplayName: The celebrity name.
	DisplayName string `json:"displayName,omitempty"`

	// Name: The resource name of the celebrity. Have the
	// format
	// `video-intelligence/kg-mid` indicates a celebrity from preloaded
	// gallery.
	// kg-mid is the id in Google knowledge graph, which is unique for
	// the
	// celebrity.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Description") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1Celebrity) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1Celebrity
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p3beta1CelebrityRecognitionAnnotation:
// Celebrity recognition annotation per video.
type GoogleCloudVideointelligenceV1p3beta1CelebrityRecognitionAnnotation struct {
	// CelebrityTracks: The tracks detected from the input video, including
	// recognized celebrities
	// and other detected faces in the video.
	CelebrityTracks []*GoogleCloudVideointelligenceV1p3beta1CelebrityTrack `json:"celebrityTracks,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CelebrityTracks") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CelebrityTracks") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1CelebrityRecognitionAnnotation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1CelebrityRecognitionAnnotation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p3beta1CelebrityTrack: The annotation
// result of a celebrity face track. RecognizedCelebrity field
// could be empty if the face track does not have any matched
// celebrities.
type GoogleCloudVideointelligenceV1p3beta1CelebrityTrack struct {
	// Celebrities: Top N match of the celebrities for the face in this
	// track.
	Celebrities []*GoogleCloudVideointelligenceV1p3beta1RecognizedCelebrity `json:"celebrities,omitempty"`

	// FaceTrack: A track of a person's face.
	FaceTrack *GoogleCloudVideointelligenceV1p3beta1Track `json:"faceTrack,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Celebrities") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Celebrities") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1CelebrityTrack) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1CelebrityTrack
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p3beta1DetectedAttribute: A generic
// detected attribute represented by name in string format.
type GoogleCloudVideointelligenceV1p3beta1DetectedAttribute struct {
	// Confidence: Detected attribute confidence. Range [0, 1].
	Confidence float64 `json:"confidence,omitempty"`

	// Name: The name of the attribute, i.e. glasses, dark_glasses,
	// mouth_open etc.
	// A full list of supported type names will be provided in the document.
	Name string `json:"name,omitempty"`

	// Value: Text value of the detection result. For example, the value for
	// "HairColor"
	// can be "black", "blonde", etc.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1DetectedAttribute) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1DetectedAttribute
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p3beta1DetectedAttribute) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1DetectedAttribute
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1p3beta1Entity: Detected entity from
// video analysis.
type GoogleCloudVideointelligenceV1p3beta1Entity struct {
	// Description: Textual description, e.g. `Fixed-gear bicycle`.
	Description string `json:"description,omitempty"`

	// EntityId: Opaque entity ID. Some IDs may be available in
	// [Google Knowledge Graph
	// Search
	// API](https://developers.google.com/knowledge-graph/).
	EntityId string `json:"entityId,omitempty"`

	// LanguageCode: Language code for `description` in BCP-47 format.
	LanguageCode string `json:"languageCode,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Description") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Description") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1Entity) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1Entity
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p3beta1ExplicitContentAnnotation:
// Explicit content annotation (based on per-frame visual signals
// only).
// If no explicit content has been detected in a frame, no annotations
// are
// present for that frame.
type GoogleCloudVideointelligenceV1p3beta1ExplicitContentAnnotation struct {
	// Frames: All video frames where explicit content was detected.
	Frames []*GoogleCloudVideointelligenceV1p3beta1ExplicitContentFrame `json:"frames,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Frames") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Frames") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1ExplicitContentAnnotation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1ExplicitContentAnnotation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p3beta1ExplicitContentFrame: Video
// frame level annotation results for explicit content.
type GoogleCloudVideointelligenceV1p3beta1ExplicitContentFrame struct {
	// PornographyLikelihood: Likelihood of the pornography content..
	//
	// Possible values:
	//   "LIKELIHOOD_UNSPECIFIED" - Unspecified likelihood.
	//   "VERY_UNLIKELY" - Very unlikely.
	//   "UNLIKELY" - Unlikely.
	//   "POSSIBLE" - Possible.
	//   "LIKELY" - Likely.
	//   "VERY_LIKELY" - Very likely.
	PornographyLikelihood string `json:"pornographyLikelihood,omitempty"`

	// TimeOffset: Time-offset, relative to the beginning of the video,
	// corresponding to the
	// video frame for this location.
	TimeOffset string `json:"timeOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "PornographyLikelihood") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "PornographyLikelihood") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1ExplicitContentFrame) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1ExplicitContentFrame
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p3beta1LabelAnnotation: Label
// annotation.
type GoogleCloudVideointelligenceV1p3beta1LabelAnnotation struct {
	// CategoryEntities: Common categories for the detected entity.
	// E.g. when the label is `Terrier` the category is likely `dog`. And in
	// some
	// cases there might be more than one categories e.g. `Terrier` could
	// also be
	// a `pet`.
	CategoryEntities []*GoogleCloudVideointelligenceV1p3beta1Entity `json:"categoryEntities,omitempty"`

	// Entity: Detected entity.
	Entity *GoogleCloudVideointelligenceV1p3beta1Entity `json:"entity,omitempty"`

	// Frames: All video frames where a label was detected.
	Frames []*GoogleCloudVideointelligenceV1p3beta1LabelFrame `json:"frames,omitempty"`

	// Segments: All video segments where a label was detected.
	Segments []*GoogleCloudVideointelligenceV1p3beta1LabelSegment `json:"segments,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CategoryEntities") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "CategoryEntities") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1LabelAnnotation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1LabelAnnotation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p3beta1LabelFrame: Video frame level
// annotation results for label detection.
type GoogleCloudVideointelligenceV1p3beta1LabelFrame struct {
	// Confidence: Confidence that the label is accurate. Range: [0, 1].
	Confidence float64 `json:"confidence,omitempty"`

	// TimeOffset: Time-offset, relative to the beginning of the video,
	// corresponding to the
	// video frame for this location.
	TimeOffset string `json:"timeOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1LabelFrame) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1LabelFrame
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p3beta1LabelFrame) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1LabelFrame
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1p3beta1LabelSegment: Video segment
// level annotation results for label detection.
type GoogleCloudVideointelligenceV1p3beta1LabelSegment struct {
	// Confidence: Confidence that the label is accurate. Range: [0, 1].
	Confidence float64 `json:"confidence,omitempty"`

	// Segment: Video segment where a label was detected.
	Segment *GoogleCloudVideointelligenceV1p3beta1VideoSegment `json:"segment,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1LabelSegment) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1LabelSegment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p3beta1LabelSegment) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1LabelSegment
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1p3beta1LogoRecognitionAnnotation:
// Annotation corresponding to one detected, tracked and recognized logo
// class.
type GoogleCloudVideointelligenceV1p3beta1LogoRecognitionAnnotation struct {
	// Entity: Entity category information to specify the logo class that
	// all the logo
	// tracks within this LogoRecognitionAnnotation are recognized as.
	Entity *GoogleCloudVideointelligenceV1p3beta1Entity `json:"entity,omitempty"`

	// Segments: All video segments where the recognized logo appears. There
	// might be
	// multiple instances of the same logo class appearing in one
	// VideoSegment.
	Segments []*GoogleCloudVideointelligenceV1p3beta1VideoSegment `json:"segments,omitempty"`

	// Tracks: All logo tracks where the recognized logo appears. Each track
	// corresponds
	// to one logo instance appearing in consecutive frames.
	Tracks []*GoogleCloudVideointelligenceV1p3beta1Track `json:"tracks,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Entity") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Entity") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1LogoRecognitionAnnotation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1LogoRecognitionAnnotation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p3beta1NormalizedBoundingBox:
// Normalized bounding box.
// The normalized vertex coordinates are relative to the original
// image.
// Range: [0, 1].
type GoogleCloudVideointelligenceV1p3beta1NormalizedBoundingBox struct {
	// Bottom: Bottom Y coordinate.
	Bottom float64 `json:"bottom,omitempty"`

	// Left: Left X coordinate.
	Left float64 `json:"left,omitempty"`

	// Right: Right X coordinate.
	Right float64 `json:"right,omitempty"`

	// Top: Top Y coordinate.
	Top float64 `json:"top,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Bottom") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Bottom") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1NormalizedBoundingBox) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1NormalizedBoundingBox
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p3beta1NormalizedBoundingBox) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1NormalizedBoundingBox
	var s1 struct {
		Bottom gensupport.JSONFloat64 `json:"bottom"`
		Left   gensupport.JSONFloat64 `json:"left"`
		Right  gensupport.JSONFloat64 `json:"right"`
		Top    gensupport.JSONFloat64 `json:"top"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Bottom = float64(s1.Bottom)
	s.Left = float64(s1.Left)
	s.Right = float64(s1.Right)
	s.Top = float64(s1.Top)
	return nil
}

// GoogleCloudVideointelligenceV1p3beta1NormalizedBoundingPoly:
// Normalized bounding polygon for text (that might not be aligned with
// axis).
// Contains list of the corner points in clockwise order starting
// from
// top-left corner. For example, for a rectangular bounding box:
// When the text is horizontal it might look like:
//         0----1
//         |    |
//         3----2
//
// When it's clockwise rotated 180 degrees around the top-left corner
// it
// becomes:
//         2----3
//         |    |
//         1----0
//
// and the vertex order will still be (0, 1, 2, 3). Note that values can
// be less
// than 0, or greater than 1 due to trignometric calculations for
// location of
// the box.
type GoogleCloudVideointelligenceV1p3beta1NormalizedBoundingPoly struct {
	// Vertices: Normalized vertices of the bounding polygon.
	Vertices []*GoogleCloudVideointelligenceV1p3beta1NormalizedVertex `json:"vertices,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Vertices") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Vertices") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1NormalizedBoundingPoly) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1NormalizedBoundingPoly
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p3beta1NormalizedVertex: A vertex
// represents a 2D point in the image.
// NOTE: the normalized vertex coordinates are relative to the original
// image
// and range from 0 to 1.
type GoogleCloudVideointelligenceV1p3beta1NormalizedVertex struct {
	// X: X coordinate.
	X float64 `json:"x,omitempty"`

	// Y: Y coordinate.
	Y float64 `json:"y,omitempty"`

	// ForceSendFields is a list of field names (e.g. "X") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "X") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1NormalizedVertex) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1NormalizedVertex
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p3beta1NormalizedVertex) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1NormalizedVertex
	var s1 struct {
		X gensupport.JSONFloat64 `json:"x"`
		Y gensupport.JSONFloat64 `json:"y"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.X = float64(s1.X)
	s.Y = float64(s1.Y)
	return nil
}

// GoogleCloudVideointelligenceV1p3beta1ObjectTrackingAnnotation:
// Annotations corresponding to one tracked object.
type GoogleCloudVideointelligenceV1p3beta1ObjectTrackingAnnotation struct {
	// Confidence: Object category's labeling confidence of this track.
	Confidence float64 `json:"confidence,omitempty"`

	// Entity: Entity to specify the object category that this track is
	// labeled as.
	Entity *GoogleCloudVideointelligenceV1p3beta1Entity `json:"entity,omitempty"`

	// Frames: Information corresponding to all frames where this object
	// track appears.
	// Non-streaming batch mode: it may be one or multiple
	// ObjectTrackingFrame
	// messages in frames.
	// Streaming mode: it can only be one ObjectTrackingFrame message in
	// frames.
	Frames []*GoogleCloudVideointelligenceV1p3beta1ObjectTrackingFrame `json:"frames,omitempty"`

	// Segment: Non-streaming batch mode ONLY.
	// Each object track corresponds to one video segment where it appears.
	Segment *GoogleCloudVideointelligenceV1p3beta1VideoSegment `json:"segment,omitempty"`

	// TrackId: Streaming mode ONLY.
	// In streaming mode, we do not know the end time of a tracked
	// object
	// before it is completed. Hence, there is no VideoSegment info
	// returned.
	// Instead, we provide a unique identifiable integer track_id so
	// that
	// the customers can correlate the results of the
	// ongoing
	// ObjectTrackAnnotation of the same track_id over time.
	TrackId int64 `json:"trackId,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1ObjectTrackingAnnotation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1ObjectTrackingAnnotation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p3beta1ObjectTrackingAnnotation) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1ObjectTrackingAnnotation
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1p3beta1ObjectTrackingFrame: Video frame
// level annotations for object detection and tracking. This
// field
// stores per frame location, time offset, and confidence.
type GoogleCloudVideointelligenceV1p3beta1ObjectTrackingFrame struct {
	// NormalizedBoundingBox: The normalized bounding box location of this
	// object track for the frame.
	NormalizedBoundingBox *GoogleCloudVideointelligenceV1p3beta1NormalizedBoundingBox `json:"normalizedBoundingBox,omitempty"`

	// TimeOffset: The timestamp of the frame in microseconds.
	TimeOffset string `json:"timeOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "NormalizedBoundingBox") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NormalizedBoundingBox") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1ObjectTrackingFrame) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1ObjectTrackingFrame
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p3beta1RecognizedCelebrity: The
// recognized celebrity with confidence score.
type GoogleCloudVideointelligenceV1p3beta1RecognizedCelebrity struct {
	// Celebrity: The recognized celebrity.
	Celebrity *GoogleCloudVideointelligenceV1p3beta1Celebrity `json:"celebrity,omitempty"`

	// Confidence: Recognition confidence. Range [0, 1].
	Confidence float64 `json:"confidence,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Celebrity") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Celebrity") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1RecognizedCelebrity) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1RecognizedCelebrity
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p3beta1RecognizedCelebrity) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1RecognizedCelebrity
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1p3beta1SpeechRecognitionAlternative:
// Alternative hypotheses (a.k.a. n-best list).
type GoogleCloudVideointelligenceV1p3beta1SpeechRecognitionAlternative struct {
	// Confidence: Output only. The confidence estimate between 0.0 and 1.0.
	// A higher number
	// indicates an estimated greater likelihood that the recognized words
	// are
	// correct. This field is set only for the top alternative.
	// This field is not guaranteed to be accurate and users should not rely
	// on it
	// to be always provided.
	// The default of 0.0 is a sentinel value indicating `confidence` was
	// not set.
	Confidence float64 `json:"confidence,omitempty"`

	// Transcript: Transcript text representing the words that the user
	// spoke.
	Transcript string `json:"transcript,omitempty"`

	// Words: Output only. A list of word-specific information for each
	// recognized word.
	// Note: When `enable_speaker_diarization` is true, you will see all the
	// words
	// from the beginning of the audio.
	Words []*GoogleCloudVideointelligenceV1p3beta1WordInfo `json:"words,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1SpeechRecognitionAlternative) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1SpeechRecognitionAlternative
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p3beta1SpeechRecognitionAlternative) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1SpeechRecognitionAlternative
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1p3beta1SpeechTranscription: A speech
// recognition result corresponding to a portion of the audio.
type GoogleCloudVideointelligenceV1p3beta1SpeechTranscription struct {
	// Alternatives: May contain one or more recognition hypotheses (up to
	// the maximum specified
	// in `max_alternatives`).  These alternatives are ordered in terms
	// of
	// accuracy, with the top (first) alternative being the most probable,
	// as
	// ranked by the recognizer.
	Alternatives []*GoogleCloudVideointelligenceV1p3beta1SpeechRecognitionAlternative `json:"alternatives,omitempty"`

	// LanguageCode: Output only. The
	// [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tag
	// of
	// the language in this result. This language code was detected to have
	// the
	// most likelihood of being spoken in the audio.
	LanguageCode string `json:"languageCode,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Alternatives") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Alternatives") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1SpeechTranscription) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1SpeechTranscription
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p3beta1StreamingAnnotateVideoResponse:
// `StreamingAnnotateVideoResponse` is the only message returned to the
// client
// by `StreamingAnnotateVideo`. A series of zero or
// more
// `StreamingAnnotateVideoResponse` messages are streamed back to the
// client.
type GoogleCloudVideointelligenceV1p3beta1StreamingAnnotateVideoResponse struct {
	// AnnotationResults: Streaming annotation results.
	AnnotationResults *GoogleCloudVideointelligenceV1p3beta1StreamingVideoAnnotationResults `json:"annotationResults,omitempty"`

	// AnnotationResultsUri: GCS URI that stores annotation results of one
	// streaming session.
	// It is a directory that can hold multiple files in JSON
	// format.
	// Example uri
	// format:
	// gs://bucket_id/object_id/cloud_project_name-session_id
	AnnotationResultsUri string `json:"annotationResultsUri,omitempty"`

	// Error: If set, returns a google.rpc.Status message that
	// specifies the error for the operation.
	Error *GoogleRpcStatus `json:"error,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AnnotationResults")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AnnotationResults") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1StreamingAnnotateVideoResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1StreamingAnnotateVideoResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p3beta1StreamingVideoAnnotationResults:
// Streaming annotation results corresponding to a portion of the
// video
// that is currently being processed.
type GoogleCloudVideointelligenceV1p3beta1StreamingVideoAnnotationResults struct {
	// ExplicitAnnotation: Explicit content annotation results.
	ExplicitAnnotation *GoogleCloudVideointelligenceV1p3beta1ExplicitContentAnnotation `json:"explicitAnnotation,omitempty"`

	// LabelAnnotations: Label annotation results.
	LabelAnnotations []*GoogleCloudVideointelligenceV1p3beta1LabelAnnotation `json:"labelAnnotations,omitempty"`

	// ObjectAnnotations: Object tracking results.
	ObjectAnnotations []*GoogleCloudVideointelligenceV1p3beta1ObjectTrackingAnnotation `json:"objectAnnotations,omitempty"`

	// ShotAnnotations: Shot annotation results. Each shot is represented as
	// a video segment.
	ShotAnnotations []*GoogleCloudVideointelligenceV1p3beta1VideoSegment `json:"shotAnnotations,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ExplicitAnnotation")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ExplicitAnnotation") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1StreamingVideoAnnotationResults) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1StreamingVideoAnnotationResults
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p3beta1TextAnnotation: Annotations
// related to one detected OCR text snippet. This will contain
// the
// corresponding text, confidence value, and frame level information for
// each
// detection.
type GoogleCloudVideointelligenceV1p3beta1TextAnnotation struct {
	// Segments: All video segments where OCR detected text appears.
	Segments []*GoogleCloudVideointelligenceV1p3beta1TextSegment `json:"segments,omitempty"`

	// Text: The detected text.
	Text string `json:"text,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Segments") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Segments") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1TextAnnotation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1TextAnnotation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p3beta1TextFrame: Video frame level
// annotation results for text annotation (OCR).
// Contains information regarding timestamp and bounding box locations
// for the
// frames containing detected OCR text snippets.
type GoogleCloudVideointelligenceV1p3beta1TextFrame struct {
	// RotatedBoundingBox: Bounding polygon of the detected text for this
	// frame.
	RotatedBoundingBox *GoogleCloudVideointelligenceV1p3beta1NormalizedBoundingPoly `json:"rotatedBoundingBox,omitempty"`

	// TimeOffset: Timestamp of this frame.
	TimeOffset string `json:"timeOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g. "RotatedBoundingBox")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "RotatedBoundingBox") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1TextFrame) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1TextFrame
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p3beta1TextSegment: Video segment level
// annotation results for text detection.
type GoogleCloudVideointelligenceV1p3beta1TextSegment struct {
	// Confidence: Confidence for the track of detected text. It is
	// calculated as the highest
	// over all frames where OCR detected text appears.
	Confidence float64 `json:"confidence,omitempty"`

	// Frames: Information related to the frames where OCR detected text
	// appears.
	Frames []*GoogleCloudVideointelligenceV1p3beta1TextFrame `json:"frames,omitempty"`

	// Segment: Video segment where a text snippet was detected.
	Segment *GoogleCloudVideointelligenceV1p3beta1VideoSegment `json:"segment,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1TextSegment) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1TextSegment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p3beta1TextSegment) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1TextSegment
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1p3beta1TimestampedObject: For tracking
// related features.
// An object at time_offset with attributes, and located
// with
// normalized_bounding_box.
type GoogleCloudVideointelligenceV1p3beta1TimestampedObject struct {
	// Attributes: Optional. The attributes of the object in the bounding
	// box.
	Attributes []*GoogleCloudVideointelligenceV1p3beta1DetectedAttribute `json:"attributes,omitempty"`

	// NormalizedBoundingBox: Normalized Bounding box in a frame, where the
	// object is located.
	NormalizedBoundingBox *GoogleCloudVideointelligenceV1p3beta1NormalizedBoundingBox `json:"normalizedBoundingBox,omitempty"`

	// TimeOffset: Time-offset, relative to the beginning of the
	// video,
	// corresponding to the video frame for this object.
	TimeOffset string `json:"timeOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Attributes") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Attributes") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1TimestampedObject) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1TimestampedObject
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p3beta1Track: A track of an object
// instance.
type GoogleCloudVideointelligenceV1p3beta1Track struct {
	// Attributes: Optional. Attributes in the track level.
	Attributes []*GoogleCloudVideointelligenceV1p3beta1DetectedAttribute `json:"attributes,omitempty"`

	// Confidence: Optional. The confidence score of the tracked object.
	Confidence float64 `json:"confidence,omitempty"`

	// Segment: Video segment of a track.
	Segment *GoogleCloudVideointelligenceV1p3beta1VideoSegment `json:"segment,omitempty"`

	// TimestampedObjects: The object with timestamp and attributes per
	// frame in the track.
	TimestampedObjects []*GoogleCloudVideointelligenceV1p3beta1TimestampedObject `json:"timestampedObjects,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Attributes") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Attributes") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1Track) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1Track
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p3beta1Track) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1Track
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleCloudVideointelligenceV1p3beta1VideoAnnotationProgress:
// Annotation progress for a single video.
type GoogleCloudVideointelligenceV1p3beta1VideoAnnotationProgress struct {
	// Feature: Specifies which feature is being tracked if the request
	// contains more than
	// one features.
	//
	// Possible values:
	//   "FEATURE_UNSPECIFIED" - Unspecified.
	//   "LABEL_DETECTION" - Label detection. Detect objects, such as dog or
	// flower.
	//   "SHOT_CHANGE_DETECTION" - Shot change detection.
	//   "EXPLICIT_CONTENT_DETECTION" - Explicit content detection.
	//   "SPEECH_TRANSCRIPTION" - Speech transcription.
	//   "TEXT_DETECTION" - OCR text detection and tracking.
	//   "OBJECT_TRACKING" - Object detection and tracking.
	//   "LOGO_RECOGNITION" - Logo detection, tracking, and recognition.
	//   "CELEBRITY_RECOGNITION" - Celebrity recognition.
	Feature string `json:"feature,omitempty"`

	// InputUri: Video file location in
	// [Google Cloud Storage](https://cloud.google.com/storage/).
	InputUri string `json:"inputUri,omitempty"`

	// ProgressPercent: Approximate percentage processed thus far.
	// Guaranteed to be
	// 100 when fully processed.
	ProgressPercent int64 `json:"progressPercent,omitempty"`

	// Segment: Specifies which segment is being tracked if the request
	// contains more than
	// one segments.
	Segment *GoogleCloudVideointelligenceV1p3beta1VideoSegment `json:"segment,omitempty"`

	// StartTime: Time when the request was received.
	StartTime string `json:"startTime,omitempty"`

	// UpdateTime: Time of the most recent update.
	UpdateTime string `json:"updateTime,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Feature") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Feature") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1VideoAnnotationProgress) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1VideoAnnotationProgress
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p3beta1VideoAnnotationResults:
// Annotation results for a single video.
type GoogleCloudVideointelligenceV1p3beta1VideoAnnotationResults struct {
	// CelebrityRecognitionAnnotations: Celebrity recognition annotations.
	CelebrityRecognitionAnnotations *GoogleCloudVideointelligenceV1p3beta1CelebrityRecognitionAnnotation `json:"celebrityRecognitionAnnotations,omitempty"`

	// Error: If set, indicates an error. Note that for a single
	// `AnnotateVideoRequest`
	// some videos may succeed and some may fail.
	Error *GoogleRpcStatus `json:"error,omitempty"`

	// ExplicitAnnotation: Explicit content annotation.
	ExplicitAnnotation *GoogleCloudVideointelligenceV1p3beta1ExplicitContentAnnotation `json:"explicitAnnotation,omitempty"`

	// FrameLabelAnnotations: Label annotations on frame level.
	// There is exactly one element for each unique label.
	FrameLabelAnnotations []*GoogleCloudVideointelligenceV1p3beta1LabelAnnotation `json:"frameLabelAnnotations,omitempty"`

	// InputUri: Video file location in
	// [Google Cloud Storage](https://cloud.google.com/storage/).
	InputUri string `json:"inputUri,omitempty"`

	// LogoRecognitionAnnotations: Annotations for list of logos detected,
	// tracked and recognized in video.
	LogoRecognitionAnnotations []*GoogleCloudVideointelligenceV1p3beta1LogoRecognitionAnnotation `json:"logoRecognitionAnnotations,omitempty"`

	// ObjectAnnotations: Annotations for list of objects detected and
	// tracked in video.
	ObjectAnnotations []*GoogleCloudVideointelligenceV1p3beta1ObjectTrackingAnnotation `json:"objectAnnotations,omitempty"`

	// Segment: Video segment on which the annotation is run.
	Segment *GoogleCloudVideointelligenceV1p3beta1VideoSegment `json:"segment,omitempty"`

	// SegmentLabelAnnotations: Topical label annotations on video level or
	// user specified segment level.
	// There is exactly one element for each unique label.
	SegmentLabelAnnotations []*GoogleCloudVideointelligenceV1p3beta1LabelAnnotation `json:"segmentLabelAnnotations,omitempty"`

	// SegmentPresenceLabelAnnotations: Presence label annotations on video
	// level or user specified segment level.
	// There is exactly one element for each unique label. Compared to
	// the
	// existing topical `segment_label_annotations`, this field presents
	// more
	// fine-grained, segment-level labels detected in video content and is
	// made
	// available only when the client sets `LabelDetectionConfig.model`
	// to
	// "builtin/latest" in the request.
	SegmentPresenceLabelAnnotations []*GoogleCloudVideointelligenceV1p3beta1LabelAnnotation `json:"segmentPresenceLabelAnnotations,omitempty"`

	// ShotAnnotations: Shot annotations. Each shot is represented as a
	// video segment.
	ShotAnnotations []*GoogleCloudVideointelligenceV1p3beta1VideoSegment `json:"shotAnnotations,omitempty"`

	// ShotLabelAnnotations: Topical label annotations on shot level.
	// There is exactly one element for each unique label.
	ShotLabelAnnotations []*GoogleCloudVideointelligenceV1p3beta1LabelAnnotation `json:"shotLabelAnnotations,omitempty"`

	// ShotPresenceLabelAnnotations: Presence label annotations on shot
	// level. There is exactly one element for
	// each unique label. Compared to the existing
	// topical
	// `shot_label_annotations`, this field presents more fine-grained,
	// shot-level
	// labels detected in video content and is made available only when the
	// client
	// sets `LabelDetectionConfig.model` to "builtin/latest" in the request.
	ShotPresenceLabelAnnotations []*GoogleCloudVideointelligenceV1p3beta1LabelAnnotation `json:"shotPresenceLabelAnnotations,omitempty"`

	// SpeechTranscriptions: Speech transcription.
	SpeechTranscriptions []*GoogleCloudVideointelligenceV1p3beta1SpeechTranscription `json:"speechTranscriptions,omitempty"`

	// TextAnnotations: OCR text detection and tracking.
	// Annotations for list of detected text snippets. Each will have list
	// of
	// frame information associated with it.
	TextAnnotations []*GoogleCloudVideointelligenceV1p3beta1TextAnnotation `json:"textAnnotations,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "CelebrityRecognitionAnnotations") to unconditionally include in API
	// requests. By default, fields with empty values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g.
	// "CelebrityRecognitionAnnotations") to include in API requests with
	// the JSON null value. By default, fields with empty values are omitted
	// from API requests. However, any field with an empty value appearing
	// in NullFields will be sent to the server as null. It is an error if a
	// field in this list has a non-empty value. This may be used to include
	// null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1VideoAnnotationResults) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1VideoAnnotationResults
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p3beta1VideoSegment: Video segment.
type GoogleCloudVideointelligenceV1p3beta1VideoSegment struct {
	// EndTimeOffset: Time-offset, relative to the beginning of the
	// video,
	// corresponding to the end of the segment (inclusive).
	EndTimeOffset string `json:"endTimeOffset,omitempty"`

	// StartTimeOffset: Time-offset, relative to the beginning of the
	// video,
	// corresponding to the start of the segment (inclusive).
	StartTimeOffset string `json:"startTimeOffset,omitempty"`

	// ForceSendFields is a list of field names (e.g. "EndTimeOffset") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "EndTimeOffset") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1VideoSegment) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1VideoSegment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudVideointelligenceV1p3beta1WordInfo: Word-specific
// information for recognized words. Word information is only
// included in the response when certain request parameters are set,
// such
// as `enable_word_time_offsets`.
type GoogleCloudVideointelligenceV1p3beta1WordInfo struct {
	// Confidence: Output only. The confidence estimate between 0.0 and 1.0.
	// A higher number
	// indicates an estimated greater likelihood that the recognized words
	// are
	// correct. This field is set only for the top alternative.
	// This field is not guaranteed to be accurate and users should not rely
	// on it
	// to be always provided.
	// The default of 0.0 is a sentinel value indicating `confidence` was
	// not set.
	Confidence float64 `json:"confidence,omitempty"`

	// EndTime: Time offset relative to the beginning of the audio,
	// and
	// corresponding to the end of the spoken word. This field is only set
	// if
	// `enable_word_time_offsets=true` and only in the top hypothesis. This
	// is an
	// experimental feature and the accuracy of the time offset can vary.
	EndTime string `json:"endTime,omitempty"`

	// SpeakerTag: Output only. A distinct integer value is assigned for
	// every speaker within
	// the audio. This field specifies which one of those speakers was
	// detected to
	// have spoken this word. Value ranges from 1 up to
	// diarization_speaker_count,
	// and is only set if speaker diarization is enabled.
	SpeakerTag int64 `json:"speakerTag,omitempty"`

	// StartTime: Time offset relative to the beginning of the audio,
	// and
	// corresponding to the start of the spoken word. This field is only set
	// if
	// `enable_word_time_offsets=true` and only in the top hypothesis. This
	// is an
	// experimental feature and the accuracy of the time offset can vary.
	StartTime string `json:"startTime,omitempty"`

	// Word: The word corresponding to this set of information.
	Word string `json:"word,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Confidence") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Confidence") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudVideointelligenceV1p3beta1WordInfo) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1WordInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleCloudVideointelligenceV1p3beta1WordInfo) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleCloudVideointelligenceV1p3beta1WordInfo
	var s1 struct {
		Confidence gensupport.JSONFloat64 `json:"confidence"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Confidence = float64(s1.Confidence)
	return nil
}

// GoogleLongrunningOperation: This resource represents a long-running
// operation that is the result of a
// network API call.
type GoogleLongrunningOperation struct {
	// Done: If the value is `false`, it means the operation is still in
	// progress.
	// If `true`, the operation is completed, and either `error` or
	// `response` is
	// available.
	Done bool `json:"done,omitempty"`

	// Error: The error result of the operation in case of failure or
	// cancellation.
	Error *GoogleRpcStatus `json:"error,omitempty"`

	// Metadata: Service-specific metadata associated with the operation.
	// It typically
	// contains progress information and common metadata such as create
	// time.
	// Some services might not provide such metadata.  Any method that
	// returns a
	// long-running operation should document the metadata type, if any.
	Metadata googleapi.RawMessage `json:"metadata,omitempty"`

	// Name: The server-assigned name, which is only unique within the same
	// service that
	// originally returns it. If you use the default HTTP mapping,
	// the
	// `name` should be a resource name ending with
	// `operations/{unique_id}`.
	Name string `json:"name,omitempty"`

	// Response: The normal response of the operation in case of success.
	// If the original
	// method returns no data on success, such as `Delete`, the response
	// is
	// `google.protobuf.Empty`.  If the original method is
	// standard
	// `Get`/`Create`/`Update`, the response should be the resource.  For
	// other
	// methods, the response should have the type `XxxResponse`, where
	// `Xxx`
	// is the original method name.  For example, if the original method
	// name
	// is `TakeSnapshot()`, the inferred response type
	// is
	// `TakeSnapshotResponse`.
	Response googleapi.RawMessage `json:"response,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Done") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Done") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleLongrunningOperation) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleLongrunningOperation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleRpcStatus: The `Status` type defines a logical error model that
// is suitable for
// different programming environments, including REST APIs and RPC APIs.
// It is
// used by [gRPC](https://github.com/grpc). Each `Status` message
// contains
// three pieces of data: error code, error message, and error
// details.
//
// You can find out more about this error model and how to work with it
// in the
// [API Design Guide](https://cloud.google.com/apis/design/errors).
type GoogleRpcStatus struct {
	// Code: The status code, which should be an enum value of
	// google.rpc.Code.
	Code int64 `json:"code,omitempty"`

	// Details: A list of messages that carry the error details.  There is a
	// common set of
	// message types for APIs to use.
	Details []googleapi.RawMessage `json:"details,omitempty"`

	// Message: A developer-facing error message, which should be in
	// English. Any
	// user-facing error message should be localized and sent in
	// the
	// google.rpc.Status.details field, or localized by the client.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleRpcStatus) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleRpcStatus
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "videointelligence.videos.annotate":

type VideosAnnotateCall struct {
	s                                                         *Service
	googlecloudvideointelligencev1p1beta1Annotatevideorequest *GoogleCloudVideointelligenceV1p1beta1AnnotateVideoRequest
	urlParams_                                                gensupport.URLParams
	ctx_                                                      context.Context
	header_                                                   http.Header
}

// Annotate: Performs asynchronous video annotation. Progress and
// results can be
// retrieved through the `google.longrunning.Operations`
// interface.
// `Operation.metadata` contains `AnnotateVideoProgress`
// (progress).
// `Operation.response` contains `AnnotateVideoResponse` (results).
func (r *VideosService) Annotate(googlecloudvideointelligencev1p1beta1Annotatevideorequest *GoogleCloudVideointelligenceV1p1beta1AnnotateVideoRequest) *VideosAnnotateCall {
	c := &VideosAnnotateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.googlecloudvideointelligencev1p1beta1Annotatevideorequest = googlecloudvideointelligencev1p1beta1Annotatevideorequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *VideosAnnotateCall) Fields(s ...googleapi.Field) *VideosAnnotateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *VideosAnnotateCall) Context(ctx context.Context) *VideosAnnotateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *VideosAnnotateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *VideosAnnotateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20191216")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudvideointelligencev1p1beta1Annotatevideorequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1p1beta1/videos:annotate")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "videointelligence.videos.annotate" call.
// Exactly one of *GoogleLongrunningOperation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *GoogleLongrunningOperation.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *VideosAnnotateCall) Do(opts ...googleapi.CallOption) (*GoogleLongrunningOperation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GoogleLongrunningOperation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Performs asynchronous video annotation. Progress and results can be\nretrieved through the `google.longrunning.Operations` interface.\n`Operation.metadata` contains `AnnotateVideoProgress` (progress).\n`Operation.response` contains `AnnotateVideoResponse` (results).",
	//   "flatPath": "v1p1beta1/videos:annotate",
	//   "httpMethod": "POST",
	//   "id": "videointelligence.videos.annotate",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1p1beta1/videos:annotate",
	//   "request": {
	//     "$ref": "GoogleCloudVideointelligenceV1p1beta1_AnnotateVideoRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleLongrunning_Operation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}
