sunlubo / SwiftFFmpeg

A Swift wrapper for the FFmpeg API
Apache License 2.0
521 stars 83 forks source link

sendPacket ends in -22 Invalid argument #65

Closed wibed closed 1 year ago

wibed commented 1 year ago

i try to read a frame into a packet and then send the packet to a decoder like this:

    try picture.data.withUnsafeMutableReadableBytes { bytes in
      try bytes.withMemoryRebound(to: UInt8.self) { ptr in
        var bufferData = BufferData(ptr: ptr.baseAddress!, size: ptr.count)

        let ioContext = AVIOContext(
          buffer: pictureBuffer,
          size: pictureSize,
          writable: false,
          opaque: &bufferData,
          readHandler: read_packet,
          writeHandler: nil,
          seekHandler: nil
        )
        let fmtContext = AVFormatContext()
        fmtContext.pb = ioContext

        try fmtContext.openInput()
        try fmtContext.findStreamInfo()
        fmtContext.dumpFormat()

        guard let codec = AVCodec.findEncoderById(.JPEG2000)
          else { fatalError("png codec doesn't exist") }

        let codecContext = AVCodecContext(codec: codec)
        codecContext.width = 320
        codecContext.height = 208
        codecContext.pixelFormat = .RGB24
        codecContext.timebase = AVRational(num: 1, den: 1)
        codecContext.framerate = AVRational(num: 0, den: 1)
        try codecContext.openCodec()

        //guard let stream: AVStream = fmtContext.addStream(codec: codec) else {
        //  fatalError("Failed allocating output stream") }
        //stream.codecParameters.copy(from: codecContext)

        let packet = AVPacket()
        try fmtContext.readFrame(into: packet)
        try codecContext.sendPacket(packet)

      }

but fail to do so, even though it is unlike the frontpage example. i have read many other examples but could not manage to get more information on the matter, besides the one i already have.

wibed commented 1 year ago

including a missing portion, which is existant in your example, stream

aswell as excluding CodecContext options.

        ...
        guard let codec = AVCodec.findEncoderById(.JPEG2000)
          else { fatalError("png codec doesn't exist") }

        let codecContext = AVCodecContext(codec: codec)
        codecContext.width = 320
        codecContext.height = 208
        codecContext.pixelFormat = .RGB24
        codecContext.timebase = AVRational(num: 1, den: 1)
        codecContext.framerate = AVRational(num: 0, den: 1)
        try codecContext.openCodec()

        guard let stream = fmtContext.streams.first(where: {$0.mediaType == .video }) else {
          fatalError("failed allocating output stream") }
        print(stream.mediaType)
        stream.codecParameters.copy(from: codecContext)

        let packet = AVPacket()

        while let _ = try? fmtContext.readFrame(into: packet) {
          defer { packet.unref() }

          if( packet.streamIndex != stream.index ) { continue }
          try codecContext.sendPacket(packet)
        }
      }
    }

still the same output

wibed commented 1 year ago

assuming i dont want to encode i want to decode i'd use (the change of format is arbitrary)

...
guard let codec = AVCodec.findDecoderById(.PNG)
...

instead of

...
guard let codec = AVCodec.findEncoderById(.JPEG2000)
...