Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS Client #1

Closed
hungrxyz opened this issue Sep 9, 2015 · 12 comments
Closed

iOS Client #1

hungrxyz opened this issue Sep 9, 2015 · 12 comments

Comments

@hungrxyz
Copy link

hungrxyz commented Sep 9, 2015

I'm trying to use the opus codec with ogg encapsulation in an iOS app. I came so far that I have data encoded into opus but I'm stuck at packaging it with Ogg.

@rillian
Copy link
Contributor

rillian commented Sep 9, 2015

Sorry, what issue are you having?

@hungrxyz
Copy link
Author

hungrxyz commented Sep 9, 2015

Sorry, I pressed enter to fast by mistake.

I'm having issues packaging the encoded opus data into Ogg packets, especially how to create ID and Comment headers in Objective-C/Swift. And I'm having a hard time finding examples of how to do it.

@hungrxyz hungrxyz changed the title iOS iOS Client Sep 9, 2015
@rillian
Copy link
Contributor

rillian commented Sep 9, 2015

@hungrxyz
Copy link
Author

Yes, well I went through all of that. I guess I will have to learn C to get this to work.

@rillian
Copy link
Contributor

rillian commented Sep 10, 2015

The spec for the format is https://tools.ietf.org/html/draft-ietf-codec-oggopus if you haven't looked at that. If there's anything unclear, please let me know. Or I can answer specific questions. I don't know any swift, so I can't help with direct examples.

@hungrxyz
Copy link
Author

Yes so I'm having trouble creating ID and Comment Headers in Objective C from this part:

/*Write header*/
===============================================================================
  {
    unsigned char header_data[100];
    int packet_size=opus_header_to_packet(&header, header_data, 100);
    op.packet=header_data;
    op.bytes=packet_size;
    op.b_o_s=1;
    op.e_o_s=0;
    op.granulepos=0;
    op.packetno=0;
    ogg_stream_packetin(&os, &op);                        ####  ID Header?   ####

    while((ret=ogg_stream_flush(&os, &og))){
      if(!ret)break;
      ret=oe_write_page(&og, fout);
      if(ret!=og.header_len+og.body_len){
        fprintf(stderr,"Error: failed writing header to output stream\n");
        exit(1);
      }
      bytes_written+=ret;
      pages_out++;
    }
===============================================================================
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    comment_pad(&inopt.comments, &inopt.comments_length, comment_padding);
    op.packet=(unsigned char *)inopt.comments;
    op.bytes=inopt.comments_length;
    op.b_o_s=0;
    op.e_o_s=0;
    op.granulepos=0;
    op.packetno=1;
    ogg_stream_packetin(&os, &op);                ####   Comment Header?   ####
  }                                     

  /* writing the rest of the opus header packets */
  while((ret=ogg_stream_flush(&os, &og))){
    if(!ret)break;
    ret=oe_write_page(&og, fout);
    if(ret!=og.header_len + og.body_len){
      fprintf(stderr,"Error: failed writing header to output stream\n");
      exit(1);
    }
    bytes_written+=ret;
    pages_out++;
  }
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Are my marks correct that the upper part is for creating the ID Header and the lower for Comment Header?

If so, what is the oe_enc_opt inopt;? In which file can I find it?

@rillian
Copy link
Contributor

rillian commented Sep 11, 2015

Are my marks correct that the upper part is for creating the ID Header and the lower for Comment Header?

The first section converts an OpusHeader struct to an ogg packet and writes it out to the stream. The second does the same for an array of strings containing the message data key-value pairs. So they create the headers and write them to the stream, but the code you've quoted doesn't actually constuct the OpusHeader or comment structures or fill in any data. You'll need to do that to get valid output.

If so, what is the oe_enc_opt inopt;?

This is a parameter structure filled in during opusenc's long argument parsing section, which isn't very easy to read. It's declared in https://github.com/xiph/opus-tools/blob/master/src/opusenc.h#L23

@hungrxyz
Copy link
Author

Aha, so the comment is constructed with this function:

static void comment_pad(char **comments, int* length, int amount)
{
  if(amount>0){
    int i;
    int newlen;
    char* p=*comments;
    /*Make sure there is at least amount worth of padding free, and
       round up to the maximum that fits in the current ogg segments.*/
    newlen=(*length+amount+255)/255*255-1;
    p=realloc(p,newlen);
    if(p==NULL){
      fprintf(stderr,"realloc failed in comment_pad()\n");
      exit(1);
    }
    for(i=*length;i<newlen;i++)p[i]=0;
    *comments=p;
    *length=newlen;
  }
}

I don't seem to find oe_enc_opt in libopus.a/libogg.a. Do I need to add some header files?

Thanks for your help.

@rillian
Copy link
Contributor

rillian commented Sep 11, 2015

static void comment_pad(char **comments, int* length, int amount)

Sort of. This adds padding to the end of the comment data. See comment_init() and comment_add() for the rest of the implementation.

I don't seem to find oe_enc_opt in libopus.a/libogg.a. Do I need to add some header files?

Perhaps confusingly, neither libopus nor libogg provide code for the id and comment header generation. This code is from the opus-tools project. You'd need to borrow or re-implement what's there. https://github.com/xiph/opus-tools/

@hungrxyz
Copy link
Author

Okay, I'm sorry but can you be more specific on what is needed to create the id and comment header and perhaps just point out the elements that are used in opus-tools?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants