FAQ
I'm having trouble calling sws_scale because I'm passing a reference to a
Go pointer on line 143:

https://github.com/stephenwithav/ffmpeg/blob/develop/ffmpeg.go#L143

---

  var input_data [3]*C.uint8_t
  var input_linesize [3]C.int

  switch im := m.(type) {
  case *image.RGBA:
   bpp := 4
   input_data = [3]*C.uint8_t{ptr(im.Pix)}
   input_linesize = [3]C.int{C.int(im.Bounds().Dx() * bpp)}
  case *image.NRGBA:
   bpp := 4
   input_data = [3]*C.uint8_t{ptr(im.Pix)}
   input_linesize = [3]C.int{C.int(im.Bounds().Dx() * bpp)}
  default:
   panic("Unknown input image type")
  }

  // Perform scaling from input type to output type
  C.sws_scale(e._swscontext, &input_data[0], &input_linesize[0],
   0, e._context.height,
   &e._frame.data[0], &e._frame.linesize[0])

---

In the switch statement, I have tried several options to change input_data
to avoid having the Go pointer to Go pointer. The closest I have come, I
think, is this:

---
        var input_data [3]*uint8


         var input_linesize [3]C.int





         switch im := m.(type) {


         case *image.RGBA:


                 bpp := 4


                 for i, _ := range im.Pix[:3] {


                         input_data[i] = &im.Pix[i]


                 }


                 input_linesize = [3]C.int{C.int(im.Bounds().Dx() * bpp)}


         case *image.NRGBA:


                 bpp := 4


                 for i, _ := range im.Pix[:3] {


                         input_data[i] = &im.Pix[i]


                 }


                 input_linesize = [3]C.int{C.int(im.Bounds().Dx() * bpp)}


         default:


                 panic("Unknown input image type")


         }





         // Perform scaling from input type to output type


         C.sws_scale(e._swscontext, (**C.uint8_t)(&input_data[0]),
&input_linesize[0],


                 0, e._context.height,


                 &e._frame.data[0], &e._frame.linesize[0])


  ---

...but then go build gives the following error:

ffmpeg/ffmpeg.go:147: cannot convert &input_data[0] (type **uint8) to type
**C.uint8_t

Am I approaching this the right way?

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Ian Lance Taylor at Feb 22, 2016 at 6:47 pm

    On Mon, Feb 22, 2016 at 3:50 AM, Steven Edwards wrote:
    I'm having trouble calling sws_scale because I'm passing a reference to a Go
    pointer on line 143:

    https://github.com/stephenwithav/ffmpeg/blob/develop/ffmpeg.go#L143

    ---

    var input_data [3]*C.uint8_t
    var input_linesize [3]C.int

    switch im := m.(type) {
    case *image.RGBA:
    bpp := 4
    input_data = [3]*C.uint8_t{ptr(im.Pix)}
    input_linesize = [3]C.int{C.int(im.Bounds().Dx() * bpp)}
    case *image.NRGBA:
    bpp := 4
    input_data = [3]*C.uint8_t{ptr(im.Pix)}
    input_linesize = [3]C.int{C.int(im.Bounds().Dx() * bpp)}
    default:
    panic("Unknown input image type")
    }

    // Perform scaling from input type to output type
    C.sws_scale(e._swscontext, &input_data[0], &input_linesize[0],
    0, e._context.height,
    &e._frame.data[0], &e._frame.linesize[0])

    ---

    In the switch statement, I have tried several options to change input_data
    to avoid having the Go pointer to Go pointer. The closest I have come, I
    think, is this:

    ---
    var input_data [3]*uint8
    var input_linesize [3]C.int

    switch im := m.(type) {
    case *image.RGBA:
    bpp := 4
    for i, _ := range im.Pix[:3] {
    input_data[i] = &im.Pix[i]
    }
    input_linesize = [3]C.int{C.int(im.Bounds().Dx() * bpp)}
    case *image.NRGBA:
    bpp := 4
    for i, _ := range im.Pix[:3] {
    input_data[i] = &im.Pix[i]
    }
    input_linesize = [3]C.int{C.int(im.Bounds().Dx() * bpp)}
    default:
    panic("Unknown input image type")
    }

    // Perform scaling from input type to output type
    C.sws_scale(e._swscontext, (**C.uint8_t)(&input_data[0]),
    &input_linesize[0],
    0, e._context.height,
    &e._frame.data[0], &e._frame.linesize[0])
    ---

    ...but then go build gives the following error:

    ffmpeg/ffmpeg.go:147: cannot convert &input_data[0] (type **uint8) to type
    **C.uint8_t

    Am I approaching this the right way?
    You can avoid that specific error easily enough by writing
    (**C.uint8_t)(unsafe.Pointer(&input_data[0])).

    But I don't understand what you are trying to do here. What Go 1.6
    enforces is that you can not pass a Go pointer that contains a Go
    pointer. In this case input_data is a Go array, so &input_data[0] is
    a Go pointer. Passing &input_data[0] to C is only permitted if
    input_data does not itself contain any Go pointers. If im.Pix is also
    Go memory, then &im.Pix[i] is a Go pointer, and then you are passing a
    Go pointer to memory that contains Go pointers, which is not
    permitted. This is only OK if im.Pix is a C pointer.

    I think the most likely way to make this pointer- and data-structure
    heavy C code work with the Go garbage collector is to allocate more of
    the memory in C.

    Ian

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Steven Edwards at Feb 22, 2016 at 8:08 pm
    My goal is to pass an image's data, im.Pix, to sws_scale, which has the
    following function signature:

    int sws_scale (struct SwsContext *c, const uint8_t *const srcSlice[], const
    int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const
    int dstStride[])

    I can't figure out how to pass a go array (or slice) as the correct type.

    Similarly, I could rewrite most of the code in C, but how would I reference
    the im.Pix data?

    Best,

    Steven
    On Monday, February 22, 2016 at 1:48:04 PM UTC-5, Ian Lance Taylor wrote:

    On Mon, Feb 22, 2016 at 3:50 AM, Steven Edwards <curead...@gmail.com
    <javascript:>> wrote:
    I'm having trouble calling sws_scale because I'm passing a reference to a Go
    pointer on line 143:

    https://github.com/stephenwithav/ffmpeg/blob/develop/ffmpeg.go#L143

    ---

    var input_data [3]*C.uint8_t
    var input_linesize [3]C.int

    switch im := m.(type) {
    case *image.RGBA:
    bpp := 4
    input_data = [3]*C.uint8_t{ptr(im.Pix)}
    input_linesize = [3]C.int{C.int(im.Bounds().Dx() * bpp)}
    case *image.NRGBA:
    bpp := 4
    input_data = [3]*C.uint8_t{ptr(im.Pix)}
    input_linesize = [3]C.int{C.int(im.Bounds().Dx() * bpp)}
    default:
    panic("Unknown input image type")
    }

    // Perform scaling from input type to output type
    C.sws_scale(e._swscontext, &input_data[0], &input_linesize[0],
    0, e._context.height,
    &e._frame.data[0], &e._frame.linesize[0])

    ---

    In the switch statement, I have tried several options to change
    input_data
    to avoid having the Go pointer to Go pointer. The closest I have come, I
    think, is this:

    ---
    var input_data [3]*uint8
    var input_linesize [3]C.int

    switch im := m.(type) {
    case *image.RGBA:
    bpp := 4
    for i, _ := range im.Pix[:3] {
    input_data[i] = &im.Pix[i]
    }
    input_linesize = [3]C.int{C.int(im.Bounds().Dx() * bpp)}
    case *image.NRGBA:
    bpp := 4
    for i, _ := range im.Pix[:3] {
    input_data[i] = &im.Pix[i]
    }
    input_linesize = [3]C.int{C.int(im.Bounds().Dx() * bpp)}
    default:
    panic("Unknown input image type")
    }

    // Perform scaling from input type to output type
    C.sws_scale(e._swscontext, (**C.uint8_t)(&input_data[0]),
    &input_linesize[0],
    0, e._context.height,
    &e._frame.data[0], &e._frame.linesize[0])
    ---

    ...but then go build gives the following error:

    ffmpeg/ffmpeg.go:147: cannot convert &input_data[0] (type **uint8) to type
    **C.uint8_t

    Am I approaching this the right way?
    You can avoid that specific error easily enough by writing
    (**C.uint8_t)(unsafe.Pointer(&input_data[0])).

    But I don't understand what you are trying to do here. What Go 1.6
    enforces is that you can not pass a Go pointer that contains a Go
    pointer. In this case input_data is a Go array, so &input_data[0] is
    a Go pointer. Passing &input_data[0] to C is only permitted if
    input_data does not itself contain any Go pointers. If im.Pix is also
    Go memory, then &im.Pix[i] is a Go pointer, and then you are passing a
    Go pointer to memory that contains Go pointers, which is not
    permitted. This is only OK if im.Pix is a C pointer.

    I think the most likely way to make this pointer- and data-structure
    heavy C code work with the Go garbage collector is to allocate more of
    the memory in C.

    Ian
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Ian Lance Taylor at Feb 22, 2016 at 9:12 pm

    On Mon, Feb 22, 2016 at 12:07 PM, Steven Edwards wrote:
    My goal is to pass an image's data, im.Pix, to sws_scale, which has the
    following function signature:

    int sws_scale (struct SwsContext *c, const uint8_t *const srcSlice[], const
    int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const
    int dstStride[])

    I can't figure out how to pass a go array (or slice) as the correct type.
    The C function expects a pointer to pointers for the srcSlice
    argument. The inner pointers must be C pointers. There is no valid
    way for them to be Go pointers.

    Therefore, you must either copy im.Pix into C memory for this specific
    call, or you must allocate it in C memory in the first place. I would
    guess that the latter will give better performance.

    Ian

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedFeb 22, '16 at 5:40p
activeFeb 22, '16 at 9:12p
posts4
users2
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase