Skip to content

Commit

Permalink
Added VideoWriterFile with API and API Params
Browse files Browse the repository at this point in the history
  • Loading branch information
diegohce authored and deadprogram committed Oct 21, 2024
1 parent ca73747 commit dc6fbbe
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 2 deletions.
4 changes: 2 additions & 2 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ Your pull requests will be greatly appreciated!
- [X] **Object Detection**

- [X] **imgcodecs. Image file reading and writing.**
- [ ] **videoio. Video I/O - WORK STARTED**
- [ ] VideoWriterWithGStreamer
- [X] **videoio. Video I/O - WORK STARTED**
- [X] VideoWriterWithGStreamer

- [X] **highgui. High-level GUI**
- [ ] **video. Video Analysis - WORK STARTED**
Expand Down
19 changes: 19 additions & 0 deletions videoio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,25 @@ void VideoWriter_Open(VideoWriter vw, const char* name, const char* codec, doubl
vw->open(name, codecCode, fps, cv::Size(width, height), isColor);
}

void VideoWriter_OpenWithAPI(VideoWriter vw, const char* name, int apiPreference, const char* codec, double fps, int width,
int height, bool isColor) {
int codecCode = cv::VideoWriter::fourcc(codec[0], codec[1], codec[2], codec[3]);
vw->open(name, apiPreference, codecCode, fps, cv::Size(width, height), isColor);
}

void VideoWriter_OpenWithAPIParams(VideoWriter vw, const char* name, int apiPreference, const char* codec, double fps, int width,
int height, IntVector params) {

std::vector<int> cpp_params;

for(int i = 0; i < params.length; i++) {
cpp_params.push_back(params.val[i]);
}

int codecCode = cv::VideoWriter::fourcc(codec[0], codec[1], codec[2], codec[3]);
vw->open(name, apiPreference, codecCode, fps, cv::Size(width, height), cpp_params);
}

int VideoWriter_IsOpened(VideoWriter vw) {
return vw->isOpened();
}
Expand Down
122 changes: 122 additions & 0 deletions videoio.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,63 @@ const (
VideoCaptureHWDevice VideoCaptureProperties = 51
)

// VideoWriterProperty
//
// For further details, please see:
// https://docs.opencv.org/4.x/d4/d15/group__videoio__flags__base.html#ga41c5cfa7859ae542b71b1d33bbd4d2b4
type VideoWriterProperty int

const (
// VideoWriterQuality Current quality (0..100%) of the encoded videostream.
// Can be adjusted dynamically in some codecs.
VideoWriterQuality VideoWriterProperty = 1

// VideoWriterFramebytes (Read-only): Size of just encoded video frame.
// Note that the encoding order may be different from representation order.
VideoWriterFramebytes VideoWriterProperty = 2

// VideoWriterNstripes Number of stripes for parallel encoding. -1 for auto detection.
VideoWriterNstripes VideoWriterProperty = 3

// VideoWriterIsColor If it is not zero, the encoder will expect and encode color frames,
// otherwise it will work with grayscale frames.
VideoWriterIsColor VideoWriterProperty = 4

// VideoWriterDepth Defaults to CV8U.
VideoWriterDepth VideoWriterProperty = 5

// VideoWriterHwAcceleration (open-only) Hardware acceleration type
// (see https://docs.opencv.org/4.x/dc/dfc/group__videoio__flags__others.html#gaf61f8388a47aad88cd82cbda6d52c391).
// Setting supported only via params parameter in VideoWriterFileWithAPIParams.
// Default value is backend-specific.
VideoWriterHwAcceleration VideoWriterProperty = 6

// VideoWriterHwDevice (open-only) Hardware device index (select GPU if multiple available).
// Device enumeration is acceleration type specific.
VideoWriterHwDevice VideoWriterProperty = 7

// VideoWriterHwAccelerationUseOpencl open-only) If non-zero, create new OpenCL context and bind it to current thread.
VideoWriterHwAccelerationUseOpencl VideoWriterProperty = 8

// VideoWriterRawVideo (open-only) Set to non-zero to enable encapsulation of an encoded raw video stream.
VideoWriterRawVideo VideoWriterProperty = 9

// VideoWriterKeyInterval (open-only) Set the key frame interval using raw video encapsulation
// (VideoWriterRawVideo != 0). Defaults to 1 when not set. FFmpeg back-end only.
VideoWriterKeyInterval VideoWriterProperty = 10

// VideoWriterKeyFlag Set to non-zero to signal that the following frames are key frames or zero if not,
// when encapsulating raw video (VideoWriterRawVideo != 0). FFmpeg back-end only.
VideoWriterKeyFlag VideoWriterProperty = 11

// VideoWriterPts Specifies the frame presentation timestamp for each frame using the FPS time base.
VideoWriterPts VideoWriterProperty = 12

// VideoWriterDtsDelay Specifies the maximum difference between presentation (pts)
// and decompression timestamps (dts) using the FPS time base.
VideoWriterDtsDelay VideoWriterProperty = 13
)

// VideoCapture is a wrapper around the OpenCV VideoCapture class.
//
// For further details, please see:
Expand Down Expand Up @@ -479,6 +536,71 @@ func VideoWriterFile(name string, codec string, fps float64, width int, height i
return
}

// VideoWriterFileWithAPI opens a VideoWriter with a specific output file.
// The "codec" param should be the four-letter code for the desired output
// codec, for example "MJPG".
//
// For further details, please see:
// http://docs.opencv.org/master/dd/d9e/classcv_1_1VideoWriter.html#a0901c353cd5ea05bba455317dab81130
func VideoWriterFileWithAPI(name string, apiPreference VideoCaptureAPI, codec string, fps float64, width int, height int, isColor bool) (vw *VideoWriter, err error) {

if fps == 0 || width == 0 || height == 0 {
return nil, fmt.Errorf("one of the numerical parameters "+
"is equal to zero: FPS: %f, width: %d, height: %d", fps, width, height)
}

vw = &VideoWriter{
p: C.VideoWriter_New(),
mu: &sync.RWMutex{},
}

cName := C.CString(name)
defer C.free(unsafe.Pointer(cName))

cCodec := C.CString(codec)
defer C.free(unsafe.Pointer(cCodec))

C.VideoWriter_OpenWithAPI(vw.p, cName, C.int(apiPreference), cCodec, C.double(fps), C.int(width), C.int(height), C.bool(isColor))
return
}

// VideoWriterFileWithAPIParams opens a VideoWriter with a specific output file.
// The "codec" param should be the four-letter code for the desired output
// codec, for example "MJPG".
//
// For further details, please see:
// http://docs.opencv.org/master/dd/d9e/classcv_1_1VideoWriter.html#a0901c353cd5ea05bba455317dab81130
func VideoWriterFileWithAPIParams(name string, apiPreference VideoCaptureAPI, codec string, fps float64, width int, height int, params []VideoWriterProperty) (vw *VideoWriter, err error) {

if fps == 0 || width == 0 || height == 0 {
return nil, fmt.Errorf("one of the numerical parameters "+
"is equal to zero: FPS: %f, width: %d, height: %d", fps, width, height)
}

vw = &VideoWriter{
p: C.VideoWriter_New(),
mu: &sync.RWMutex{},
}

c_name := C.CString(name)
defer C.free(unsafe.Pointer(c_name))

c_codec := C.CString(codec)
defer C.free(unsafe.Pointer(c_codec))

c_ints := make([]C.int, len(params))
for i := range params {
c_ints[i] = C.int(params[i])
}

c_params := C.IntVector{
val: unsafe.SliceData(c_ints),
length: C.int(len(params)),
}
C.VideoWriter_OpenWithAPIParams(vw.p, c_name, C.int(apiPreference), c_codec, C.double(fps), C.int(width), C.int(height), c_params)
return
}

// Close VideoWriter object.
func (vw *VideoWriter) Close() error {
C.VideoWriter_Close(vw.p)
Expand Down
5 changes: 5 additions & 0 deletions videoio.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ VideoWriter VideoWriter_New();
void VideoWriter_Close(VideoWriter vw);
void VideoWriter_Open(VideoWriter vw, const char* name, const char* codec, double fps, int width,
int height, bool isColor);
void VideoWriter_OpenWithAPI(VideoWriter vw, const char* name, int apiPreference, const char* codec, double fps,
int width, int height, bool isColor);
void VideoWriter_OpenWithAPIParams(VideoWriter vw, const char* name, int apiPreference, const char* codec, double fps,
int width, int height, IntVector params);

int VideoWriter_IsOpened(VideoWriter vw);
void VideoWriter_Write(VideoWriter vw, Mat img);

Expand Down
48 changes: 48 additions & 0 deletions videoio_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package gocv
import (
"io/ioutil"
"math"
"os"
"path/filepath"
"strconv"
"strings"
Expand Down Expand Up @@ -212,6 +213,53 @@ func TestVideoWriterFile(t *testing.T) {
}
}

func TestVideoWriterFileWithAPI(t *testing.T) {
dir := os.TempDir()
tmpfn := filepath.Join(dir, "test.avi")

img := IMRead("images/face-detect.jpg", IMReadColor)
if img.Empty() {
t.Error("Invalid read of Mat in VideoWriterFile test")
}
defer img.Close()

vw, _ := VideoWriterFileWithAPI(tmpfn, VideoCaptureFFmpeg, "MJPG", 25, img.Cols(), img.Rows(), true)
defer vw.Close()

if !vw.IsOpened() {
t.Error("Unable to open VideoWriterFile")
}

err := vw.Write(img)
if err != nil {
t.Error("Invalid Write() in VideoWriter")
}
}

func TestVideoWriterFileWithAPIParams(t *testing.T) {
dir := os.TempDir()
tmpfn := filepath.Join(dir, "test.avi")

img := IMRead("images/face-detect.jpg", IMReadColor)
if img.Empty() {
t.Error("Invalid read of Mat in VideoWriterFile test")
}
defer img.Close()

vw, _ := VideoWriterFileWithAPIParams(tmpfn, VideoCaptureFFmpeg, "MJPG", 25, img.Cols(), img.Rows(),
[]VideoWriterProperty{VideoWriterHwAcceleration, 0, VideoWriterIsColor, 1})
defer vw.Close()

if !vw.IsOpened() {
t.Error("Unable to open VideoWriterFile")
}

err := vw.Write(img)
if err != nil {
t.Error("Invalid Write() in VideoWriter")
}
}

func TestVideoCaptureFile_GrabRetrieve(t *testing.T) {
vc, err := VideoCaptureFile("images/small.mp4")
defer vc.Close()
Expand Down

0 comments on commit dc6fbbe

Please sign in to comment.