xref: /aosp_15_r20/external/libopus/src/repacketizer_demo.c (revision a58d3d2adb790c104798cd88c8a3aff4fa8b82cc)
1 /* Copyright (c) 2011 Xiph.Org Foundation
2    Written by Jean-Marc Valin */
3 /*
4    Redistribution and use in source and binary forms, with or without
5    modification, are permitted provided that the following conditions
6    are met:
7 
8    - Redistributions of source code must retain the above copyright
9    notice, this list of conditions and the following disclaimer.
10 
11    - Redistributions in binary form must reproduce the above copyright
12    notice, this list of conditions and the following disclaimer in the
13    documentation and/or other materials provided with the distribution.
14 
15    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31 
32 #include "opus.h"
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 
37 #define MAX_PACKETOUT 32000
38 
usage(char * argv0)39 void usage(char *argv0)
40 {
41    fprintf(stderr, "usage: %s [options] input_file output_file\n", argv0);
42 }
43 
int_to_char(opus_uint32 i,unsigned char ch[4])44 static void int_to_char(opus_uint32 i, unsigned char ch[4])
45 {
46     ch[0] = i>>24;
47     ch[1] = (i>>16)&0xFF;
48     ch[2] = (i>>8)&0xFF;
49     ch[3] = i&0xFF;
50 }
51 
char_to_int(unsigned char ch[4])52 static opus_uint32 char_to_int(unsigned char ch[4])
53 {
54     return ((opus_uint32)ch[0]<<24) | ((opus_uint32)ch[1]<<16)
55          | ((opus_uint32)ch[2]<< 8) |  (opus_uint32)ch[3];
56 }
57 
main(int argc,char * argv[])58 int main(int argc, char *argv[])
59 {
60    int i, eof=0;
61    FILE *fin, *fout;
62    unsigned char packets[48][1500];
63    int len[48];
64    int rng[48];
65    OpusRepacketizer *rp;
66    unsigned char output_packet[MAX_PACKETOUT];
67    int merge = 1, split=0;
68 
69    if (argc < 3)
70    {
71       usage(argv[0]);
72       return EXIT_FAILURE;
73    }
74    for (i=1;i<argc-2;i++)
75    {
76       if (strcmp(argv[i], "-merge")==0)
77       {
78          merge = atoi(argv[i+1]);
79          if(merge<1)
80          {
81             fprintf(stderr, "-merge parameter must be at least 1.\n");
82             return EXIT_FAILURE;
83          }
84          if(merge>48)
85          {
86             fprintf(stderr, "-merge parameter must be less than 48.\n");
87             return EXIT_FAILURE;
88          }
89          i++;
90       } else if (strcmp(argv[i], "-split")==0)
91          split = 1;
92       else
93       {
94          fprintf(stderr, "Unknown option: %s\n", argv[i]);
95          usage(argv[0]);
96          return EXIT_FAILURE;
97       }
98    }
99    fin = fopen(argv[argc-2], "r");
100    if(fin==NULL)
101    {
102      fprintf(stderr, "Error opening input file: %s\n", argv[argc-2]);
103      return EXIT_FAILURE;
104    }
105    fout = fopen(argv[argc-1], "w");
106    if(fout==NULL)
107    {
108      fprintf(stderr, "Error opening output file: %s\n", argv[argc-1]);
109      fclose(fin);
110      return EXIT_FAILURE;
111    }
112 
113    rp = opus_repacketizer_create();
114    while (!eof)
115    {
116       int err;
117       int nb_packets=merge;
118       opus_repacketizer_init(rp);
119       for (i=0;i<nb_packets;i++)
120       {
121          unsigned char ch[4];
122          if (fread(ch, 1, 4, fin)!=4)
123          {
124              if (feof(fin))
125              {
126                 eof = 1;
127              } else {
128                 fprintf(stderr, "Error reading payload length.\n");
129                 fclose(fin);
130                 fclose(fout);
131                 return EXIT_FAILURE;
132              }
133              break;
134          }
135          len[i] = char_to_int(ch);
136          /*fprintf(stderr, "in len = %d\n", len[i]);*/
137          if (len[i]>1500 || len[i]<0)
138          {
139              if (feof(fin))
140              {
141                 eof = 1;
142              } else {
143                 fprintf(stderr, "Invalid payload length\n");
144                 fclose(fin);
145                 fclose(fout);
146                 return EXIT_FAILURE;
147              }
148              break;
149          }
150          if (fread(ch, 1, 4, fin)!=4)
151          {
152              if (feof(fin))
153              {
154                 eof = 1;
155              } else {
156                 fprintf(stderr, "Error reading.\n");
157                 fclose(fin);
158                 fclose(fout);
159                 return EXIT_FAILURE;
160              }
161              break;
162          }
163          rng[i] = char_to_int(ch);
164          if (fread(packets[i], len[i], 1, fin)!=1) {
165              if (feof(fin))
166              {
167                 eof = 1;
168              } else {
169                 fprintf(stderr, "Error reading packet of %u bytes.\n", len[i]);
170                 fclose(fin);
171                 fclose(fout);
172                 return EXIT_FAILURE;
173              }
174              break;
175          }
176          err = opus_repacketizer_cat(rp, packets[i], len[i]);
177          if (err!=OPUS_OK)
178          {
179             fprintf(stderr, "opus_repacketizer_cat() failed: %s\n", opus_strerror(err));
180             break;
181          }
182       }
183       nb_packets = i;
184 
185       if (eof)
186          break;
187 
188       if (!split)
189       {
190          err = opus_repacketizer_out(rp, output_packet, MAX_PACKETOUT);
191          if (err>0) {
192             unsigned char int_field[4];
193             int_to_char(err, int_field);
194             if(fwrite(int_field, 1, 4, fout)!=4){
195                fprintf(stderr, "Error writing.\n");
196                return EXIT_FAILURE;
197             }
198             int_to_char(rng[nb_packets-1], int_field);
199             if (fwrite(int_field, 1, 4, fout)!=4) {
200                fprintf(stderr, "Error writing.\n");
201                return EXIT_FAILURE;
202             }
203             if (fwrite(output_packet, 1, err, fout)!=(unsigned)err) {
204                fprintf(stderr, "Error writing.\n");
205                return EXIT_FAILURE;
206             }
207             /*fprintf(stderr, "out len = %d\n", err);*/
208          } else {
209             fprintf(stderr, "opus_repacketizer_out() failed: %s\n", opus_strerror(err));
210          }
211       } else {
212          int nb_frames = opus_repacketizer_get_nb_frames(rp);
213          for (i=0;i<nb_frames;i++)
214          {
215             err = opus_repacketizer_out_range(rp, i, i+1, output_packet, MAX_PACKETOUT);
216             if (err>0) {
217                unsigned char int_field[4];
218                int_to_char(err, int_field);
219                if (fwrite(int_field, 1, 4, fout)!=4) {
220                   fprintf(stderr, "Error writing.\n");
221                   return EXIT_FAILURE;
222                }
223                if (i==nb_frames-1)
224                   int_to_char(rng[nb_packets-1], int_field);
225                else
226                   int_to_char(0, int_field);
227                if (fwrite(int_field, 1, 4, fout)!=4) {
228                   fprintf(stderr, "Error writing.\n");
229                   return EXIT_FAILURE;
230                }
231                if (fwrite(output_packet, 1, err, fout)!=(unsigned)err) {
232                   fprintf(stderr, "Error writing.\n");
233                   return EXIT_FAILURE;
234                }
235                /*fprintf(stderr, "out len = %d\n", err);*/
236             } else {
237                fprintf(stderr, "opus_repacketizer_out() failed: %s\n", opus_strerror(err));
238             }
239 
240          }
241       }
242    }
243 
244    fclose(fin);
245    fclose(fout);
246    return EXIT_SUCCESS;
247 }
248