JuliaIO / VideoIO.jl

Reading and writing of video files in Julia via ffmpeg
https://juliaio.github.io/VideoIO.jl/stable
Other
125 stars 53 forks source link

opencamera() not working and simultaneous encode/mux test reports as broken (Julia 1.6.3, VideoIO 0.9.6) #341

Closed airspaced-nk5 closed 2 years ago

airspaced-nk5 commented 2 years ago

Just freshly added Video IO v0.9.6 and tried running the default webcam script implementing opencamera() as in the documentation (made sure to include GLMakie, etc.). I tried running with no argument to opencamera(), as well as with using the DEFAULT_CAMERA_DEVICE and CAMERA_DEVICES entries. I ran the tests for the package and all but one test set pass. The failure is that for "Simultaneous encoding and muxing" 400/824 tests report broken.

I imagine the test failures somewhat reveal the problem, but in looking around and reading the stacktrace I could not find how to address this. The stacktrace referenced an error in unsafe_convert and the first entry was [1] avformat_open_input(ps::VideoIO.NestedCStruct{VideoIO.libffmpeg.AVFormatContext}, url::String, fmt::String, options::VideoIO.AVDict) @ VideoIO.libffmpeg... . Running in Windows.

Any help addressing this would be much appreciated, thanks!

4thjuly commented 2 years ago

I'm not sure what the real problem is but I worked around this by changing:

Base.convert(::Type{Ref{Ptr{AVDictionary}}}, d::AVDict) = d.ref_ptr_dict to Base.cconvert(::Type{Ptr{Ptr{AVDictionary}}}, d::AVDict) = d.ref_ptr_dict

in avdictionary.jl

airspaced-nk5 commented 2 years ago

I just tried this modification and it does not work for me. I made the modification and saved as admin, then attempted using GLMakie, VideoIO; VideoIO.viewcam() But when I did this, the precompile step gave the following error, which I had not seen before (either because I did not notice, or it did not exist). But the error persists when I precompile now: WARNING: using libffmpeg.##meta#51 in module VideoIO conflicts with an existing identifier. Not sure if this has anything to do with the issue, but it crudely makes sense because the primary issue is with encoding/muxing.

Thanks for the helpful idea though @4thjuly.

Still looking for help or more ideally an official fix. Thanks all!

nlw0 commented 2 years ago

I believe had the same problem, both in julia 1.6.3 and 1.7.0-rc3. The cconvert change worked for me. I got the warning as well, but could load images from the camera. Thanks, @4thjuly!

yakir12 commented 2 years ago

Same problem:

julia> cam = VideoIO.opencamera()
ERROR: MethodError: no method matching unsafe_convert(::Type{Ptr{Ptr{VideoIO.libffmpeg.AVDictionary}}}, ::VideoIO.AVDict)
Closest candidates are:
  unsafe_convert(::Type{Ptr{T}}, ::Base.ReshapedArray{T}) where T at ~/julia/usr/share/julia/base/reshapedarray.jl:281
  unsafe_convert(::Type{Ptr{T}}, ::StaticArrays.MArray{S, T}) where {S, T} at ~/.julia/packages/StaticArrays/OWJK7/src/MArray.jl:109
  unsafe_convert(::Type{Ptr{T}}, ::PermutedDimsArray{T}) where T at ~/julia/usr/share/julia/base/permuteddimsarray.jl:54
  ...
Stacktrace:
 [1] avformat_open_input(ps::VideoIO.NestedCStruct{VideoIO.libffmpeg.AVFormatContext}, url::String, fmt::Ptr{VideoIO.libffmpeg.AVInputFormat}, options::VideoIO.AVDict)
   @ VideoIO.libffmpeg ~/.julia/packages/VideoIO/EsW3Z/lib/libffmpeg.jl:8571
 [2] open_avinput(avin::VideoIO.AVInput{String}, source::String, input_format::Ptr{VideoIO.libffmpeg.AVInputFormat}, options::VideoIO.AVDict)
   @ VideoIO ~/.julia/packages/VideoIO/EsW3Z/src/avio.jl:195
 [3] VideoIO.AVInput(source::String, input_format::Ptr{VideoIO.libffmpeg.AVInputFormat}, options::VideoIO.AVDict; avio_ctx_buffer_size::Int64)
   @ VideoIO ~/.julia/packages/VideoIO/EsW3Z/src/avio.jl:218
 [4] VideoIO.AVInput(source::String, input_format::Ptr{VideoIO.libffmpeg.AVInputFormat}, options::VideoIO.AVDict)
   @ VideoIO ~/.julia/packages/VideoIO/EsW3Z/src/avio.jl:207
 [5] opencamera(::String, ::Ptr{VideoIO.libffmpeg.AVInputFormat}, ::VideoIO.AVDict; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
   @ VideoIO ~/.julia/packages/VideoIO/EsW3Z/src/avio.jl:1016
 [6] opencamera(::String, ::Ptr{VideoIO.libffmpeg.AVInputFormat}, ::VideoIO.AVDict) (repeats 2 times)
   @ VideoIO ~/.julia/packages/VideoIO/EsW3Z/src/avio.jl:1016
 [7] top-level scope
   @ REPL[7]:1

julia> versioninfo()
Julia Version 1.7.0
Commit 3bf9d17731 (2021-11-30 12:12 UTC)
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: AMD Ryzen Threadripper 2950X 16-Core Processor
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-12.0.1 (ORCJIT, znver1)
Environment:
  JULIA_REVISE = auto

...and the cconvert change worked for me as well.

classner commented 2 years ago

@airspaced-nk5 this also doesn't solve the issue for me. :(

hhaensel commented 2 years ago

for me it helped to

import Base.unsafe_convert
unsafe_convert(::Type{Ptr{Ptr{T}}}, ad::VideoIO.AVDict) where T = unsafe_convert(Ptr{Ptr{T}}, getfield(ad, :ref_ptr_dict))
hhaensel commented 2 years ago

Well, it's probably the fallback that I modified, so rather do

import Base.cconvert
Base.cconvert(::Type{Ptr{Ptr{VideoIO.AVDictionary}}}, d::VideoIO.AVDict) = d.ref_ptr_dict

if you don't want to modify the sources.

Anyhow, I guess that avdictionary.jl should be patched.

airspaced-nk5 commented 2 years ago

@hhaensel this last recommendation to use Base.cconvert did the trick for me. Thank you.

I'm curious why this worked for me but the recommendation from @4thjuly I had tried previously did not, as they appear to be almost identical. Perhaps it might have just been something subtle in my attempt to implement the suggestion, or that I did not properly reference the locally rebuilt package.

Either way thanks all for helping out and providing ideas!

hhaensel commented 2 years ago

@hhaensel this last recommendation to use Base.cconvert did the trick for me. Thank you.

I'm curious why this worked for me but the recommendation from @4thjuly I had tried previously did not, as they appear to be almost identical. Perhaps it might have just been something subtle in my attempt to implement the suggestion, or that I did not properly reference the locally rebuilt package.

Either way thanks all for helping out and providing ideas!

I think you didn't update the package correctly. There are two possibility to do it

IanButterworth commented 2 years ago

Fixed by #345

hhaensel commented 2 years ago

Hi @IanButterworth , if I understood @melonedo correctly, we should rather use

Base.unsafe_convert(::Type{Ptr{Ptr{T}}}, ad::VideoIO.AVDict) where T = Base.unsafe_convert(Ptr{Ptr{T}}, getfield(ad, :ref_ptr_dict))

Should I file another PR or did I misunderstand something?

IanButterworth commented 2 years ago

See @gnimuc's approval in https://github.com/JuliaIO/VideoIO.jl/pull/345

hhaensel commented 2 years ago

Ah, thank you! So we got it right then!