diff --git a/src/avio.jl b/src/avio.jl index e8d0ad9b..2f332d19 100644 --- a/src/avio.jl +++ b/src/avio.jl @@ -295,7 +295,14 @@ function VideoReader(avin::AVInput, video_stream=1; width, height, target_format, transcode_interpolation, C_NULL, C_NULL, C_NULL) - avpicture_fill(pointer(aTargetVideoFrame), target_buf, target_format, width, height) + align = 16 + offset = 64 # length of data + ccall((:av_image_alloc, libavutil), + Cint, + (Ref{Ptr{UInt8}}, Ref{Cint}, Cint, Cint, AVPixelFormat, Cint), + Ptr{Ptr{UInt8}}(pointer(aTargetVideoFrame)), Ptr{Int32}(pointer(aTargetVideoFrame) + offset), width, height, target_format, align + ) + apTargetDataBuffers = reinterpret(Ptr{UInt8}, [aTargetVideoFrame[1].data]) apTargetLineSizes = reinterpret(Cint, [aTargetVideoFrame[1].linesize]) @@ -407,17 +414,6 @@ function retrieve!(r::VideoReader{TRANSCODE}, buf::VidArray{T}) where T <: Eight t = r.transcodeContext - # Set up target buffer - if pointer(buf) != t.apTargetDataBuffers[1] - avpicture_fill(pointer(t.aTargetVideoFrame), - buf, - t.target_pix_fmt, - r.width, r.height) - t.apTargetDataBuffers = reinterpret(Ptr{UInt8}, [t.aTargetVideoFrame[1].data]) - t.apTargetLineSizes = reinterpret(Cint, [t.aTargetVideoFrame[1].linesize]) - - end - apSourceDataBuffers = isempty(r.frame_queue) ? reinterpret(Ptr{UInt8}, [r.aVideoFrame[1].data]) : reinterpret(Ptr{UInt8}, [popfirst!(r.frame_queue)]) apSourceLineSizes = reinterpret(Cint, [r.aVideoFrame[1].linesize]) @@ -432,6 +428,30 @@ function retrieve!(r::VideoReader{TRANSCODE}, buf::VidArray{T}) where T <: Eight t.apTargetLineSizes) Base.sigatomic_end() + bytes_per_pixel = t.target_bits_per_pixel >> 3 + + i_buf = Ptr{UInt8}(pointer(r.transcodeContext.aTargetVideoFrame)) + i_stride = unsafe_load(pointer(r.transcodeContext.aTargetVideoFrame)).linesize[1] + o_stride = unsafe_load(pointer(r.transcodeContext.aTargetVideoFrame)).width * bytes_per_pixel + o_size = unsafe_load(pointer(r.transcodeContext.aTargetVideoFrame)).height * o_stride + o_buf = buf.parent + + _p = r.transcodeContext.aTargetVideoFrame[1].data[1] + if t.target_bits_per_pixel == 8 + p = Ptr{Gray{N0f8}}(Int(_p)) + else + p = Ptr{RGB{N0f8}}(Int(_p)) + end + + height, width = size(buf) + + for h in 1:height + bp = p + (h-1) * i_stride + for w in 1:width + o_buf[(h-1)*width+w] = unsafe_load(bp, w) + end + end + reset_frame_flag!(r) return buf