diff --git a/Project.toml b/Project.toml index e02dee0e..d4ddee32 100644 --- a/Project.toml +++ b/Project.toml @@ -2,7 +2,7 @@ name = "TranscodingStreams" uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" license = "MIT" authors = ["Kenta Sato "] -version = "0.10.8" +version = "0.10.9" [deps] Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" diff --git a/docs/src/reference.md b/docs/src/reference.md index 610e23fa..6a748d80 100644 --- a/docs/src/reference.md +++ b/docs/src/reference.md @@ -45,7 +45,9 @@ TranscodingStreams.expectedsize TranscodingStreams.minoutsize TranscodingStreams.initialize TranscodingStreams.finalize +TranscodingStreams.startproc2 TranscodingStreams.startproc +TranscodingStreams.process2 TranscodingStreams.process ``` diff --git a/src/codec.jl b/src/codec.jl index d6cff34e..dfb6d289 100644 --- a/src/codec.jl +++ b/src/codec.jl @@ -18,12 +18,16 @@ There are six functions for a codec to implement: - `initialize`: initialize the codec - `finalize`: finalize the codec - `startproc`: start processing with the codec +- `startproc2`: start processing with the codec - `process`: process data with the codec. +- `process2`: process data with the codec. These are defined in the `TranscodingStreams` and a new codec type must extend these methods if necessary. Implementing a `process` method is mandatory but others are optional. `expectedsize`, `minoutsize`, `initialize`, `finalize`, -and `startproc` have a default implementation. +`startproc`, `startproc2`, and `process2` have a default implementation. + +Methods ending with a 2 allow extra keyword arguments, for future hints. Your codec type is denoted by `C` and its object by `codec`. @@ -156,6 +160,17 @@ function startproc(codec::Codec, mode::Symbol, error::Error)::Symbol return :ok end +""" + startproc2(codec::Codec, mode::Symbol, error::Error; kwargs...)::Symbol + +Start data processing with `codec` of `mode`. + +The default method does nothing and returns `:ok`. +""" +function startproc2(codec::Codec, mode::Symbol, error::Error; kwargs...)::Symbol + startproc(codec, mode, error) +end + """ process(codec::Codec, input::Memory, output::Memory, error::Error)::Tuple{Int,Int,Symbol} @@ -167,3 +182,14 @@ function process(codec::Codec, input::Memory, output::Memory, error::Error)::Tup # no default method throw(MethodError(process, (codec, input, output, error))) end + +""" + process2(codec::Codec, input::Memory, output::Memory, error::Error; kwargs...)::Tuple{Int,Int,Symbol} + +Do data processing with `codec`. + +There is no default method. +""" +function process2(codec::Codec, input::Memory, output::Memory, error::Error; kwargs...)::Tuple{Int,Int,Symbol} + process(codec, input, output, error) +end \ No newline at end of file diff --git a/src/stream.jl b/src/stream.jl index 22ef593f..3da0794f 100644 --- a/src/stream.jl +++ b/src/stream.jl @@ -675,7 +675,7 @@ end # Call `startproc` with epilogne. function callstartproc(stream::TranscodingStream, mode::Symbol) state = stream.state - state.code = startproc(stream.codec, mode, state.error) + state.code = startproc2(stream.codec, mode, state.error) if state.code == :error changemode!(stream, :panic) end @@ -687,7 +687,7 @@ function callprocess(stream::TranscodingStream, inbuf::Buffer, outbuf::Buffer) state = stream.state input = buffermem(inbuf) GC.@preserve inbuf makemargin!(outbuf, minoutsize(stream.codec, input)) - Δin, Δout, state.code = GC.@preserve inbuf outbuf process(stream.codec, input, marginmem(outbuf), state.error) + Δin, Δout, state.code = GC.@preserve inbuf outbuf process2(stream.codec, input, marginmem(outbuf), state.error) @debug( "called process()", code = state.code, @@ -781,7 +781,7 @@ function changemode!(stream::TranscodingStream, newmode::Symbol) throw(state.error[]) elseif mode == :idle if newmode == :read || newmode == :write - state.code = startproc(stream.codec, newmode, state.error) + state.code = startproc2(stream.codec, newmode, state.error) if state.code == :error changemode!(stream, :panic) end diff --git a/src/transcode.jl b/src/transcode.jl index e5a3bfb1..823edfb8 100644 --- a/src/transcode.jl +++ b/src/transcode.jl @@ -143,14 +143,16 @@ function unsafe_transcode!( input::Buffer, ) error = Error() - code = startproc(codec, :write, error) + # Note: pledged_input_size is currently experimental + code = startproc2(codec, :write, error; pledged_input_size=buffersize(input)) if code === :error @goto error end n = minoutsize(codec, buffermem(input)) @label process makemargin!(output, n) - Δin, Δout, code = process(codec, buffermem(input), marginmem(output), error) + # Note: all_input is an experimental hint that all input is available for the current frame. + Δin, Δout, code = process2(codec, buffermem(input), marginmem(output), error; all_input=true) @debug( "called process()", code = code, @@ -165,7 +167,7 @@ function unsafe_transcode!( @goto error elseif code === :end if buffersize(input) > 0 - if startproc(codec, :write, error) === :error + if startproc2(codec, :write, error) === :error @goto error end n = minoutsize(codec, buffermem(input)) diff --git a/test/codecdoubleframe.jl b/test/codecdoubleframe.jl index 1ebeee02..b5d7540a 100644 --- a/test/codecdoubleframe.jl +++ b/test/codecdoubleframe.jl @@ -22,11 +22,13 @@ end DoubleFrameEncoder() = DoubleFrameEncoder(Ref(false), Ref(false), Ref(false)) -function TranscodingStreams.process( +TranscodingStreams.process(c::DoubleFrameEncoder, i, o, e) = TranscodingStreams.process2(c, i, o, e) +function TranscodingStreams.process2( codec :: DoubleFrameEncoder, input :: TranscodingStreams.Memory, output :: TranscodingStreams.Memory, - error_ref :: TranscodingStreams.Error, + error_ref :: TranscodingStreams.Error; + kwargs..., ) if input.size == 0 codec.got_stop_msg[] = true @@ -75,7 +77,8 @@ function TranscodingStreams.minoutsize( return 2 end -function TranscodingStreams.startproc(codec::DoubleFrameEncoder, ::Symbol, error::Error) +TranscodingStreams.startproc(c::DoubleFrameEncoder, s, e) = TranscodingStreams.startproc2(c, s, e) +function TranscodingStreams.startproc2(codec::DoubleFrameEncoder, ::Symbol, error::Error; kwargs...) codec.opened[] = false codec.got_stop_msg[] = false codec.stopped[] = false @@ -91,11 +94,13 @@ end DoubleFrameDecoder() = DoubleFrameDecoder(Ref(1), Ref(0x00), Ref(0x00)) -function TranscodingStreams.process( +TranscodingStreams.process(c::DoubleFrameDecoder, i, o, e) = TranscodingStreams.process2(c, i, o, e) +function TranscodingStreams.process2( codec :: DoubleFrameDecoder, input :: TranscodingStreams.Memory, output :: TranscodingStreams.Memory, - error_ref :: TranscodingStreams.Error, + error_ref :: TranscodingStreams.Error; + kwargs... ) Δin::Int = 0 Δout::Int = 0 @@ -172,7 +177,8 @@ function TranscodingStreams.process( end end -function TranscodingStreams.startproc(codec::DoubleFrameDecoder, ::Symbol, error::Error) +TranscodingStreams.startproc(c::DoubleFrameDecoder, x::Symbol, e::Error) = TranscodingStreams.startproc2(c, x, e) +function TranscodingStreams.startproc2(codec::DoubleFrameDecoder, ::Symbol, error::Error; kwargs...) codec.state[] = 1 codec.a[] = 0x00 codec.b[] = 0x00