github.com/aamcrae/webcam@v0.0.0-20210915060337-934acc13bdc3/frame/frame.go (about)

     1  // Copyright 2019 Google LLC
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     https://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // package frame wraps raw webcam frames as an image.
    16  package frame
    17  
    18  import (
    19  	"fmt"
    20  	"image"
    21  
    22  	"github.com/aamcrae/webcam"
    23  )
    24  
    25  type FourCC string
    26  
    27  // Release is called when the frame is no longer in use.
    28  // The implementation may set a finalizer on the frame as a precaution
    29  // in case Release is not called (which would cause a kernel resource leak).
    30  type Frame interface {
    31  	image.Image
    32  	Release()
    33  }
    34  
    35  var framerFactoryMap = map[FourCC]func(int, int, int, int) func([]byte, func()) (Frame, error){}
    36  
    37  // RegisterFramer registers a framer factory for a format.
    38  // Note that only one handler can be registered for any single format.
    39  func RegisterFramer(format FourCC, factory func(int, int, int, int) func([]byte, func()) (Frame, error)) {
    40  	framerFactoryMap[format] = factory
    41  }
    42  
    43  // GetFramer returns a function that wraps the frame for this format.
    44  func GetFramer(format FourCC, w, h, stride, size int) (func([]byte, func()) (Frame, error), error) {
    45  	if factory, ok := framerFactoryMap[format]; ok {
    46  		return factory(w, h, stride, size), nil
    47  	}
    48  	return nil, fmt.Errorf("No handler for format '%s'", format)
    49  }
    50  
    51  // PixelFormatToFourCC converts the v4l2 PixelFormat to a FourCC.
    52  func PixelFormatToFourCC(pf webcam.PixelFormat) FourCC {
    53  	b := make([]byte, 4)
    54  	b[0] = byte(pf)
    55  	b[1] = byte(pf >> 8)
    56  	b[2] = byte(pf >> 16)
    57  	b[3] = byte(pf >> 24)
    58  	return FourCC(b)
    59  }
    60  
    61  // FourCCToPixelFormat converts the four character string to a v4l2 PixelFormat.
    62  func FourCCToPixelFormat(f FourCC) (webcam.PixelFormat, error) {
    63  	if len(f) != 4 {
    64  		return 0, fmt.Errorf("%s: Illegal FourCC", f)
    65  	}
    66  	return webcam.PixelFormat(uint32(f[0]) | uint32(f[1])<<8 | uint32(f[2])<<16 | uint32(f[3])<<24), nil
    67  }