rework keyframe hide popup, keyframe auto render, textbox set_selection wide text
[goodguy/history.git] / cinelerra-5.1 / libzmpeg3 / a52dec-0.7.3 / src / a52dec.c
1 /*
2  * a52dec.c
3  * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
4  * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
5  *
6  * This file is part of a52dec, a free ATSC A-52 stream decoder.
7  * See http://liba52.sourceforge.net/ for updates.
8  *
9  * a52dec is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * a52dec is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22  */
23
24 #include "config.h"
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <getopt.h>
31 #ifdef HAVE_IO_H
32 #include <fcntl.h>
33 #include <io.h>
34 #endif
35 #ifdef HAVE_SYS_TIME_H
36 #include <sys/time.h>
37 #include <signal.h>
38 #endif
39 #include <inttypes.h>
40
41 #include "a52.h"
42 #include "audio_out.h"
43 #include "mm_accel.h"
44
45 #define BUFFER_SIZE 4096
46 static uint8_t buffer[BUFFER_SIZE];
47 static FILE * in_file;
48 static int demux_track = 0;
49 static int demux_pid = 0;
50 static int disable_accel = 0;
51 static int disable_dynrng = 0;
52 static ao_open_t * output_open = NULL;
53 static ao_instance_t * output;
54 static a52_state_t * state;
55
56 #ifdef HAVE_SYS_TIME_H
57
58 static void print_fps (int final);
59
60 static RETSIGTYPE signal_handler (int sig)
61 {
62     print_fps (1);
63     signal (sig, SIG_DFL);
64     raise (sig);
65 }
66
67 static void print_fps (int final) 
68 {
69     static uint32_t frame_counter = 0;
70     static struct timeval tv_beg, tv_start;
71     static int total_elapsed;
72     static int last_count = 0;
73     struct timeval tv_end;
74     int fps, tfps, frames, elapsed;
75
76     gettimeofday (&tv_end, NULL);
77
78     if (!frame_counter) {
79         tv_start = tv_beg = tv_end;
80         signal (SIGINT, signal_handler);
81     }
82
83     elapsed = (tv_end.tv_sec - tv_beg.tv_sec) * 100 +
84         (tv_end.tv_usec - tv_beg.tv_usec) / 10000;
85     total_elapsed = (tv_end.tv_sec - tv_start.tv_sec) * 100 +
86         (tv_end.tv_usec - tv_start.tv_usec) / 10000;
87
88     if (final) {
89         if (total_elapsed) 
90             tfps = frame_counter * 10000 / total_elapsed;
91         else
92             tfps = 0;
93
94         fprintf (stderr,"\n%d frames decoded in %d.%02d "
95                  "seconds (%d.%02d fps)\n", frame_counter,
96                  total_elapsed / 100, total_elapsed % 100,
97                  tfps / 100, tfps % 100);
98
99         return;
100     }
101
102     frame_counter++;
103
104     if (elapsed < 50)   /* only display every 0.50 seconds */
105         return;
106
107     tv_beg = tv_end;
108     frames = frame_counter - last_count;
109
110     fps = frames * 10000 / elapsed;                     /* 100x */
111     tfps = frame_counter * 10000 / total_elapsed;       /* 100x */
112
113     fprintf (stderr, "%d frames in %d.%02d sec (%d.%02d fps), "
114              "%d last %d.%02d sec (%d.%02d fps)\033[K\r", frame_counter,
115              total_elapsed / 100, total_elapsed % 100,
116              tfps / 100, tfps % 100, frames, elapsed / 100, elapsed % 100,
117              fps / 100, fps % 100);
118
119     last_count = frame_counter;
120 }
121
122 #else /* !HAVE_SYS_TIME_H */
123
124 static void print_fps (int final)
125 {
126 }
127
128 #endif
129
130 static void print_usage (char ** argv)
131 {
132     int i;
133     ao_driver_t * drivers;
134
135     fprintf (stderr, "usage: "
136              "%s [-o <mode>] [-s [<track>]] [-t <pid>] [-c] [-r] <file>\n"
137              "\t-s\tuse program stream demultiplexer, track 0-7 or 0x80-0x87\n"
138              "\t-t\tuse transport stream demultiplexer, pid 0x10-0x1ffe\n"
139              "\t-c\tuse c implementation, disables all accelerations\n"
140              "\t-r\tdisable dynamic range compression\n"
141              "\t-o\taudio output mode\n", argv[0]);
142
143     drivers = ao_drivers ();
144     for (i = 0; drivers[i].name; i++)
145         fprintf (stderr, "\t\t\t%s\n", drivers[i].name);
146
147     exit (1);
148 }
149
150 static void handle_args (int argc, char ** argv)
151 {
152     int c;
153     ao_driver_t * drivers;
154     int i;
155     char * s;
156
157     drivers = ao_drivers ();
158     while ((c = getopt (argc, argv, "s::t:cro:")) != -1)
159         switch (c) {
160         case 'o':
161             for (i = 0; drivers[i].name != NULL; i++)
162                 if (strcmp (drivers[i].name, optarg) == 0)
163                     output_open = drivers[i].open;
164             if (output_open == NULL) {
165                 fprintf (stderr, "Invalid video driver: %s\n", optarg);
166                 print_usage (argv);
167             }
168             break;
169
170         case 's':
171             demux_track = 0x80;
172             if (optarg != NULL) {
173                 demux_track = strtol (optarg, &s, 16);
174                 if (demux_track < 0x80)
175                     demux_track += 0x80;
176                 if ((demux_track < 0x80) || (demux_track > 0x87) || (*s)) {
177                     fprintf (stderr, "Invalid track number: %s\n", optarg);
178                     print_usage (argv);
179                 }
180             }
181             break;
182
183         case 't':
184             demux_pid = strtol (optarg, &s, 16);
185             if ((demux_pid < 0x10) || (demux_pid > 0x1ffe) || (*s)) {
186                 fprintf (stderr, "Invalid pid: %s\n", optarg);
187                 print_usage (argv);
188             }
189             break;
190
191         case 'c':
192             disable_accel = 1;
193             break;
194
195         case 'r':
196             disable_dynrng = 1;
197             break;
198
199         default:
200             print_usage (argv);
201         }
202
203     /* -o not specified, use a default driver */
204     if (output_open == NULL)
205         output_open = drivers[0].open;
206
207     if (optind < argc) {
208         in_file = fopen (argv[optind], "rb");
209         if (!in_file) {
210             fprintf (stderr, "%s - couldnt open file %s\n", strerror (errno),
211                      argv[optind]);
212             exit (1);
213         }
214     } else
215         in_file = stdin;
216 }
217
218 void a52_decode_data (uint8_t * start, uint8_t * end)
219 {
220     static uint8_t buf[3840];
221     static uint8_t * bufptr = buf;
222     static uint8_t * bufpos = buf + 7;
223
224     /*
225      * sample_rate and flags are static because this routine could
226      * exit between the a52_syncinfo() and the ao_setup(), and we want
227      * to have the same values when we get back !
228      */
229
230     static int sample_rate;
231     static int flags;
232     int bit_rate;
233     int len;
234
235     while (1) {
236         len = end - start;
237         if (!len)
238             break;
239         if (len > bufpos - bufptr)
240             len = bufpos - bufptr;
241         memcpy (bufptr, start, len);
242         bufptr += len;
243         start += len;
244         if (bufptr == bufpos) {
245             if (bufpos == buf + 7) {
246                 int length;
247
248                 length = a52_syncinfo (buf, &flags, &sample_rate, &bit_rate);
249                 if (!length) {
250                     fprintf (stderr, "skip\n");
251                     for (bufptr = buf; bufptr < buf + 6; bufptr++)
252                         bufptr[0] = bufptr[1];
253                     continue;
254                 }
255                 bufpos = buf + length;
256             } else {
257                 sample_t level, bias;
258                 int i;
259
260                 if (ao_setup (output, sample_rate, &flags, &level, &bias))
261                     goto error;
262                 flags |= A52_ADJUST_LEVEL;
263                 if (a52_frame (state, buf, &flags, &level, bias))
264                     goto error;
265                 if (disable_dynrng)
266                     a52_dynrng (state, NULL, NULL);
267                 for (i = 0; i < 6; i++) {
268                     if (a52_block (state))
269                         goto error;
270                     if (ao_play (output, flags, a52_samples (state)))
271                         goto error;
272                 }
273                 bufptr = buf;
274                 bufpos = buf + 7;
275                 print_fps (0);
276                 continue;
277             error:
278                 fprintf (stderr, "error\n");
279                 bufptr = buf;
280                 bufpos = buf + 7;
281             }
282         }
283     }
284 }
285
286 #define DEMUX_PAYLOAD_START 1
287 static int demux (uint8_t * buf, uint8_t * end, int flags)
288 {
289     static int mpeg1_skip_table[16] = {
290         0, 0, 4, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
291     };
292
293     /*
294      * the demuxer keeps some state between calls:
295      * if "state" = DEMUX_HEADER, then "head_buf" contains the first
296      *     "bytes" bytes from some header.
297      * if "state" == DEMUX_DATA, then we need to copy "bytes" bytes
298      *     of ES data before the next header.
299      * if "state" == DEMUX_SKIP, then we need to skip "bytes" bytes
300      *     of data before the next header.
301      *
302      * NEEDBYTES makes sure we have the requested number of bytes for a
303      * header. If we dont, it copies what we have into head_buf and returns,
304      * so that when we come back with more data we finish decoding this header.
305      *
306      * DONEBYTES updates "buf" to point after the header we just parsed.
307      */
308
309 #define DEMUX_HEADER 0
310 #define DEMUX_DATA 1
311 #define DEMUX_SKIP 2
312     static int state = DEMUX_SKIP;
313     static int state_bytes = 0;
314     static uint8_t head_buf[268];
315
316     uint8_t * header;
317     int bytes;
318     int len;
319
320 #define NEEDBYTES(x)                                            \
321     do {                                                        \
322         int missing;                                            \
323                                                                 \
324         missing = (x) - bytes;                                  \
325         if (missing > 0) {                                      \
326             if (header == head_buf) {                           \
327                 if (missing <= end - buf) {                     \
328                     memcpy (header + bytes, buf, missing);      \
329                     buf += missing;                             \
330                     bytes = (x);                                \
331                 } else {                                        \
332                     memcpy (header + bytes, buf, end - buf);    \
333                     state_bytes = bytes + end - buf;            \
334                     return 0;                                   \
335                 }                                               \
336             } else {                                            \
337                 memcpy (head_buf, header, bytes);               \
338                 state = DEMUX_HEADER;                           \
339                 state_bytes = bytes;                            \
340                 return 0;                                       \
341             }                                                   \
342         }                                                       \
343     } while (0)
344
345 #define DONEBYTES(x)            \
346     do {                        \
347         if (header != head_buf) \
348             buf = header + (x); \
349     } while (0)
350
351     if (flags & DEMUX_PAYLOAD_START)
352         goto payload_start;
353     switch (state) {
354     case DEMUX_HEADER:
355         if (state_bytes > 0) {
356             header = head_buf;
357             bytes = state_bytes;
358             goto continue_header;
359         }
360         break;
361     case DEMUX_DATA:
362         if (demux_pid || (state_bytes > end - buf)) {
363             a52_decode_data (buf, end);
364             state_bytes -= end - buf;
365             return 0;
366         }
367         a52_decode_data (buf, buf + state_bytes);
368         buf += state_bytes;
369         break;
370     case DEMUX_SKIP:
371         if (demux_pid || (state_bytes > end - buf)) {
372             state_bytes -= end - buf;
373             return 0;
374         }
375         buf += state_bytes;
376         break;
377     }
378
379     while (1) {
380         if (demux_pid) {
381             state = DEMUX_SKIP;
382             return 0;
383         }
384     payload_start:
385         header = buf;
386         bytes = end - buf;
387     continue_header:
388         NEEDBYTES (4);
389         if (header[0] || header[1] || (header[2] != 1)) {
390             if (demux_pid) {
391                 state = DEMUX_SKIP;
392                 return 0;
393             } else if (header != head_buf) {
394                 buf++;
395                 goto payload_start;
396             } else {
397                 header[0] = header[1];
398                 header[1] = header[2];
399                 header[2] = header[3];
400                 bytes = 3;
401                 goto continue_header;
402             }
403         }
404         if (demux_pid && (header[3] != 0xbd)) {
405             fprintf (stderr, "bad stream id %x\n", header[3]);
406             exit (1);
407         }
408         switch (header[3]) {
409         case 0xb9:      /* program end code */
410             /* DONEBYTES (4); */
411             /* break;         */
412             return 1;
413         case 0xba:      /* pack header */
414             NEEDBYTES (12);
415             if ((header[4] & 0xc0) == 0x40) {   /* mpeg2 */
416                 NEEDBYTES (14);
417                 len = 14 + (header[13] & 7);
418                 NEEDBYTES (len);
419                 DONEBYTES (len);
420                 /* header points to the mpeg2 pack header */
421             } else if ((header[4] & 0xf0) == 0x20) {    /* mpeg1 */
422                 DONEBYTES (12);
423                 /* header points to the mpeg1 pack header */
424             } else {
425                 fprintf (stderr, "weird pack header\n");
426                 exit (1);
427             }
428             break;
429         case 0xbd:      /* private stream 1 */
430             NEEDBYTES (7);
431             if ((header[6] & 0xc0) == 0x80) {   /* mpeg2 */
432                 NEEDBYTES (9);
433                 len = 10 + header[8];
434                 NEEDBYTES (len);
435                 /* header points to the mpeg2 pes header */
436             } else {    /* mpeg1 */
437                 len = 7;
438                 while ((header-1)[len] == 0xff) {
439                     len++;
440                     NEEDBYTES (len);
441                     if (len == 23) {
442                         fprintf (stderr, "too much stuffing\n");
443                         break;
444                     }
445                 }
446                 if (((header-1)[len] & 0xc0) == 0x40) {
447                     len += 2;
448                     NEEDBYTES (len);
449                 }
450                 len += mpeg1_skip_table[(header - 1)[len] >> 4] + 1;
451                 NEEDBYTES (len);
452                 /* header points to the mpeg1 pes header */
453             }
454             if ((!demux_pid) && ((header-1)[len] != demux_track)) {
455                 DONEBYTES (len);
456                 bytes = 6 + (header[4] << 8) + header[5] - len;
457                 if (bytes <= 0)
458                     continue;
459                 goto skip;
460             }
461             len += 3;
462             NEEDBYTES (len);
463             DONEBYTES (len);
464             bytes = 6 + (header[4] << 8) + header[5] - len;
465             if (demux_pid || (bytes > end - buf)) {
466                 a52_decode_data (buf, end);
467                 state = DEMUX_DATA;
468                 state_bytes = bytes - (end - buf);
469                 return 0;
470             } else if (bytes <= 0)
471                 continue;
472             a52_decode_data (buf, buf + bytes);
473             buf += bytes;
474             break;
475         default:
476             if (header[3] < 0xb9) {
477                 fprintf (stderr,
478                          "looks like a video stream, not system stream\n");
479                 exit (1);
480             } else {
481                 NEEDBYTES (6);
482                 DONEBYTES (6);
483                 bytes = (header[4] << 8) + header[5];
484             skip:
485                 if (bytes > end - buf) {
486                     state = DEMUX_SKIP;
487                     state_bytes = bytes - (end - buf);
488                     return 0;
489                 }
490                 buf += bytes;
491             }
492         }
493     }
494 }
495
496 static void ps_loop (void)
497 {
498     uint8_t * end;
499
500     do {
501         end = buffer + fread (buffer, 1, BUFFER_SIZE, in_file);
502         if (demux (buffer, end, 0))
503             break;      /* hit program_end_code */
504     } while (end == buffer + BUFFER_SIZE);
505 }
506
507 static void ts_loop (void)
508 {
509 #define PACKETS (BUFFER_SIZE / 188)
510     uint8_t * buf;
511     uint8_t * data;
512     uint8_t * end;
513     int packets;
514     int i;
515     int pid;
516
517     do {
518         packets = fread (buffer, 188, PACKETS, in_file);
519         for (i = 0; i < packets; i++) {
520             buf = buffer + i * 188;
521             end = buf + 188;
522             if (buf[0] != 0x47) {
523                 fprintf (stderr, "bad sync byte\n");
524                 exit (1);
525             }
526             pid = ((buf[1] << 8) + buf[2]) & 0x1fff;
527             if (pid != demux_pid)
528                 continue;
529             data = buf + 4;
530             if (buf[3] & 0x20) {        /* buf contains an adaptation field */
531                 data = buf + 5 + buf[4];
532                 if (data > end)
533                     continue;
534             }
535             if (buf[3] & 0x10)
536                 demux (data, end, (buf[1] & 0x40) ? DEMUX_PAYLOAD_START : 0);
537         }
538     } while (packets == PACKETS);
539 }
540
541 static void es_loop (void)
542 {
543     int size;
544                 
545     do {
546         size = fread (buffer, 1, BUFFER_SIZE, in_file);
547         a52_decode_data (buffer, buffer + size);
548     } while (size == BUFFER_SIZE);
549 }
550
551 int main (int argc, char ** argv)
552 {
553     uint32_t accel;
554
555 #ifdef HAVE_IO_H
556     setmode (fileno (stdout), O_BINARY);
557 #endif
558
559     fprintf (stderr, PACKAGE"-"VERSION
560              " - by Michel Lespinasse <walken@zoy.org> and Aaron Holtzman\n");
561
562     handle_args (argc, argv);
563
564     accel = disable_accel ? 0 : MM_ACCEL_DJBFFT;
565
566     output = ao_open (output_open);
567     if (output == NULL) {
568         fprintf (stderr, "Can not open output\n");
569         return 1;
570     }
571
572     state = a52_init (accel);
573     if (state == NULL) {
574         fprintf (stderr, "A52 init failed\n");
575         return 1;
576     }
577
578     if (demux_pid)
579         ts_loop ();
580     else if (demux_track)
581         ps_loop ();
582     else
583         es_loop ();
584
585     a52_free (state);
586     ao_close (output);
587     print_fps (1);
588     return 0;
589 }