-
Notifications
You must be signed in to change notification settings - Fork 135
Add codec ffmpeg #621
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
base: master
Are you sure you want to change the base?
Add codec ffmpeg #621
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #621 +/- ##
=======================================
Coverage 44.49% 44.49%
=======================================
Files 80 80
Lines 5558 5558
=======================================
Hits 2473 2473
Misses 2915 2915
Partials 170 170 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
35848ce
to
d1c609a
Compare
f4a451c
to
39bc14a
Compare
fc86229
to
71168b7
Compare
cd37985
to
ac5650d
Compare
f741aed
to
1bccd6b
Compare
be4ca15
to
16f049b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems very nice!
.github/workflows/ci.yaml
Outdated
working-directory: pkg/codec/ffmpeg | ||
run: | | ||
ls -la tmp/n7.0/ | ||
ls -la tmp/n7.0/lib/ || echo "lib directory not found" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
false || echo
will always success.
It should be like
ls -la tmp/n7.0/lib/ || echo "lib directory not found" | |
ls -la tmp/n7.0/lib/ || (echo "lib directory not found"; exit 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can just delete this "Verify FFmpeg installation" task? I only added it for the sake of debugging CI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just removing this part would be fine
pkg/codec/ffmpeg/ffmpeg.go
Outdated
|
||
for { | ||
if err = e.codecCtx.ReceivePacket(e.packet); err != nil { | ||
if errors.Is(err, astiav.ErrEof) || errors.Is(err, astiav.ErrEagain) { | ||
continue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will it be a busy loop or is there a sleep in ReceivePacket
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a busy loop, avcodec_receive_packet
which is the underlying C function ReceivePacket
calls returns ErrEagain
immediatly if no data available.
I'm not very familiar with FFmpeg, but as far as I know this is common pattern when using libavcodec, and it shouldn't have too much negative impact on performance?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm also not familiar with ffmpeg library, but a tutorial for C (with many stars) seems breaking the loop if avcodec_receive_packet
returned EAGAIN or EOF.
// TODO: check if this is a key frame | ||
// if !r.(*encoder).isKeyFrame { | ||
// t.Fatal("Not a key frame") | ||
// } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't it work for now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The commented out code is from tests of other encoders in this project, the problem here is that isKeyFrame
is not a property in the newly implemented softwareEncoder
and hardwareEncoder
, we only have nextIsKeyFrame
here so we can't just test it like this😅. This ffmpeg encoder do supports forcing key frame though. Perhaps we can parse the nalu header of the output data to verify if it's a key frame?
@3DRX Sorry for taking time, I don't want to just review the code, I want to play with it and test it, I'll test it this weekend! Thank you so much for making this happen. |
@at-wat Thanks for reviewing! I will address them in seperate commits, for the easiness of review. |
@JoeTurki No worries! I really hope this PR can be thoroughly tested and reviewed so people can have a smoother experience using it. |
@at-wat I've resolved the conversations that I think may be resolved by follow up changes for less buzz. Feel free to reopen them if needed😊 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the delay!
Left some comments and replies.
Also it might be cleaner to make
run: |
make
to
run: make
.github/workflows/ci.yaml
Outdated
working-directory: pkg/codec/ffmpeg | ||
run: | | ||
ls -la tmp/n7.0/ | ||
ls -la tmp/n7.0/lib/ || echo "lib directory not found" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just removing this part would be fine
pkg/codec/ffmpeg/ffmpeg.go
Outdated
|
||
for { | ||
if err = e.codecCtx.ReceivePacket(e.packet); err != nil { | ||
if errors.Is(err, astiav.ErrEof) || errors.Is(err, astiav.ErrEagain) { | ||
continue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm also not familiar with ffmpeg library, but a tutorial for C (with many stars) seems breaking the loop if avcodec_receive_packet
returned EAGAIN or EOF.
@at-wat Thanks for your review! This is ffmpeg's documentation https://ffmpeg.org/doxygen/3.3/group__lavc__encdec.html I think we need to keep trying when received EAGAIN, but I'm not sure about EOF, I will test it later, hopefully this weekend. |
It seems saying that we should end the loop and send a new input data if |
@at-wat Sorry for the delay, I've tested and tweaked the codec config options and found that as long as the encoder is configured with constrained VBR and no B frames (suitable for realtime video), every Thank you so much for the review :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the delay!
hardwareEncoder
is fixed but softwareEncoder
seems not.
Also, please click Re-request review
to make the updated PR listed at https://github.com/pulls/review-requested
for { | ||
if err = e.codecCtx.ReceivePacket(e.packet); err != nil { | ||
if errors.Is(err, astiav.ErrEof) || errors.Is(err, astiav.ErrEagain) { | ||
continue | ||
} | ||
return nil, func() {}, err | ||
} | ||
break | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This error handling should be fixed as well as the hardwareEncoder
This is a PR for adding ffmpeg based video encoders.
Update CI pipeline, or it will failed for not founding ffmpeg library.We add go-astiav as a dependency inpkg/codec/ffmpeg/go.mod
to avoid breaking CI and other user's build. When using github.com/pion/mediadevices/pkg/codec/ffmpeg, it's a requirement for users to provide their own ffmpeg library as described here.TestImageSizeChange
is skipped. Also, since CI environment can't have access to hardware encoders such as NVENC, only software encoder is tested.pkg/codec/ffmpeg
in CI.