Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add motion vector extraction from side data #33

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

cvley
Copy link

@cvley cvley commented Mar 24, 2017

Hi, I need motion vector extraction from video, so I implement related functions.

Pls. review them, thanks 😄

@codecov-io
Copy link

codecov-io commented Mar 24, 2017

Codecov Report

Merging #33 into master will decrease coverage by 0.32%.
The diff coverage is 0%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master      #33      +/-   ##
==========================================
- Coverage   32.11%   31.79%   -0.33%     
==========================================
  Files           4        4              
  Lines        2525     2551      +26     
==========================================
  Hits          811      811              
- Misses       1667     1693      +26     
  Partials       47       47
Impacted Files Coverage Δ
avutil/avutil.go 31.75% <0%> (-1.17%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a36251d...496bfea. Read the comment docs.

avutil/avutil.go Outdated
@@ -980,6 +989,64 @@ func (f *Frame) PacketDuration() int64 {
return int64(C.av_frame_get_pkt_duration(f.CAVFrame))
}

func (f *Frame) GetSideData() *FrameSideData {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In go I like to avoid Get... as much as possible.
Please rename to SideData.
Also, please make it accept the type of side data:

func (f *Frame) SideData(dataType FrameSideDataType) *FrameSideData

Please define them on the top of the file as something like this:

https://github.com/cvley/go-libav/blob/e12c9dd34b37af9a083f8423fb25b6d04d277ce4/avutil/avutil.go#L104-L115

Please use these values:

https://www.ffmpeg.org/doxygen/3.0/frame_8h_source.html#l00048

type FrameSideDataType C.enum_AVFrameSideDataType 

const (
	FrameSideDataTypePanScan FrameSideDataType = C.AV_FRAME_DATA_PANSCAN
...
	FrameSideDataTypeMotionVectors FrameSideDataType = C.AV_FRAME_DATA_MOTION_VECTORS
...
)

avutil/avutil.go Outdated
@@ -41,6 +42,14 @@ package avutil
// }
// return 0;
//}
//static const AVMotionVector *go_motion_vector(const AVFrameSideData *sd, int num) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An extra line here between functions please.

avutil/avutil.go Outdated
// const AVMotionVector *mvs = (const AVMotionVector *)sd->data;
// return &mvs[num];
//}
//static int go_motion_vector_size(const AVFrameSideData *sd) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

type FrameSideData struct {
CFrameSideData *C.AVFrameSideData
}

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since I am following this pattern, can you follow it too?

func NewFrameSideDataFromC(cFrameSideData unsafe.Pointer) * FrameSideData {
    return &FrameSideData{CFrameSideData: (*C.AVFrameSideData)(cFrameSideData)}
}

and then call it inside Frame.SideData() ?

type MotionVector struct {
CMotionVector *C.AVMotionVector
}

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you do the same here for NewMotionVectorFromC ?

avutil/avutil.go Outdated
return int64(mv.CMotionVector.source)
}

func (mv *MotionVector) Width() int64 {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason why you use int64?
libav returns int8 for this: https://www.ffmpeg.org/doxygen/3.0/structAVMotionVector.html#ae208462700b6b52d22ed38e9d62cf2cf
I think we should use int8 too. Same for Height

avutil/avutil.go Outdated
return int64(mv.CMotionVector.dst_x), int64(mv.CMotionVector.dst_y)
}

func (mv *MotionVector) MotionVector() (int64, int64) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is a MotionVector we should just call this Vector
libav defines this as int32.

avutil/avutil.go Outdated
return int64(mv.CMotionVector.motion_x), int64(mv.CMotionVector.motion_y)
}

func (mv *MotionVector) MotionScale() int64 {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is a MotionVector we should just call this Scale
libav defines this as uint16.

avutil/avutil.go Outdated
CMotionVector *C.AVMotionVector
}

func (mv *MotionVector) Source() int64 {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

int32

avutil/avutil.go Outdated
func (mv *MotionVector) MotionScale() int64 {
return int64(mv.CMotionVector.motion_scale)
}

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add support for Flags too:

https://www.ffmpeg.org/doxygen/3.0/structAVMotionVector.html#a75d00ba82df36ec5e697527ddb9addcc

func (mv *MotionVector) Flags() uint64 {
  return mv.CMotionVector.flags
}

@imkira
Copy link
Owner

imkira commented Mar 26, 2017

@cvley Thank you for your PR.
Please take a look at the review.
Can you also add some simple tests where you call all new functions?
Thanks

@cvley
Copy link
Author

cvley commented Mar 26, 2017

@imkira Thanks for your reviews. I will work on it 😄

@cvley
Copy link
Author

cvley commented Mar 27, 2017

@imkira I have fixed the code and add a simple test, please review them.

By the way, I'd like to generate a random video in the test to perform motion vectors extraction, is it OK?

Thanks.

@imkira
Copy link
Owner

imkira commented Mar 28, 2017

@cvley No problem about the random video.

During tests I'm currently downloading to a directory called fixtures

https://bintray.com/imkira/go-libav/download_file?file_path=sample_iPod.m4v
https://bintray.com/imkira/go-libav/download_file?file_path=sample_iTunes.mov
https://bintray.com/imkira/go-libav/download_file?file_path=sample_mpeg4.mp4

And referencing them like this:

fixture := fixturePath("sample_mpeg4.mp4")

Do any of these work for your tests?

If not, please send me the file to [email protected] and I will upload it for the tests.
Thanks

FrameDataPanScan FrameSideDataType = C.AV_FRAME_DATA_PANSCAN
FrameDataA53CC FrameSideDataType = C.AV_FRAME_DATA_A53_CC
FrameDataStereo3D FrameSideDataType = C.AV_FRAME_DATA_STEREO3D
FrameDataMatrixEncoding FrameSideDataType = C.AV_FRAME_DATA_MATRIXENCODING
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should use _ too in MATRIX_ENCODING

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean we use FrameDataMATRIX_ENCODING instead of FrameDataMatrixEncoding?

Should I change all these types using _?

Thanks.

FrameDataMatrixEncoding FrameSideDataType = C.AV_FRAME_DATA_MATRIXENCODING
FrameDataDownMixInfo FrameSideDataType = C.AV_FRAME_DATA_DOWNMIX_INFO
FrameDataReplayGain FrameSideDataType = C.AV_FRAME_DATA_REPLAYGAIN
FrameDataDisplayMatrix FrameSideDataType = C.AV_FRAME_DATA_DISPLAYMATRIX
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DISPLAY_MATRIX

return
}

C.av_buffer_unref(unsafe.Pointer(&sd.CFrameSideData.buf))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't these managed pointers. Do we to provide this?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't use buf directly here, but we need to free it.

I will dig more about the buf and av_buffer_unref usage.

Thanks.

return FrameSideDataType(sd.CFrameSideData._type)
}

func (sd *FrameSideData) MotionVector(n int) *MotionVector {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see you didn't follow my advice for MotionVectors() []*MotionVector.
Also, you're not using go_motion_vector_size anymore.
How will you discover the number of motion vectors in go?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry about this

@@ -845,3 +845,13 @@ func TestPixelFormatDescriptor_ComponentCount(t *testing.T) {
t.Fatalf("[TestPixelFormatDescriptor_ComponentCount] count=%d, NG expected=%d", count, 3)
}
}

func TestMotionVectorFromFrameSideData(t *testing.T) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you make a separate function TestFrameSideData where you call all its funcs?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No problems. I will try your test videos and random generated videos. 😄

sideData := frame.SideData(FrameDataMotionVectors)
if sideData != nil {
t.Fatalf("[TestMotionVectorFromFrameSideData] sidedata=%v, NG expected=nil", sideData)
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you call all MotionVector's funcs?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No problems.

@imkira
Copy link
Owner

imkira commented Jun 30, 2017

Any update on this @cvley ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants