1 /*
2 * aud_scan_avi.c
3 *
4 * Scans the audio track - AVI specific functions
5 *
6 * Copyright (C) Tilmann Bitterberg - June 2003
7 *
8 * This file is part of transcode, a video stream processing tool
9 *
10 * transcode is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2, or (at your option)
13 * any later version.
14 *
15 * transcode is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with GNU Make; see the file COPYING. If not, write to
22 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <stdint.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <unistd.h>
34
35 #include "aud_scan_avi.h"
36 #include "aud_scan.h"
37
38 // ------------------------
39 // You must set the requested audio before entering this function
40 // the AVI file out must be filled with correct values.
41 // ------------------------
42
sync_audio_video_avi2avi(double vid_ms,double * aud_ms,avi_t * in,avi_t * out)43 int sync_audio_video_avi2avi (double vid_ms, double *aud_ms, avi_t *in, avi_t *out)
44 {
45 static char *data = NULL;
46 int vbr = AVI_get_audio_vbr(out);
47 int mp3rate = AVI_audio_mp3rate(out);
48 int format = AVI_audio_format(out);
49 int chan = AVI_audio_channels(out);
50 long rate = AVI_audio_rate(out);
51 int bits = AVI_audio_bits(out);
52 long bytes = 0;
53
54 bits = (bits == 0)?16:bits;
55
56 if (!data) data = malloc(48000*16*4);
57 if (!data) fprintf (stderr, "Malloc failed at %s:%d\n", __FILE__, __LINE__);
58
59 if (format == 0x1) {
60 mp3rate = rate*chan*bits;
61 } else {
62 mp3rate *= 1000;
63 }
64
65 if (tc_format_ms_supported(format)) {
66
67 while (*aud_ms < vid_ms) {
68
69 if( (bytes = AVI_read_audio_chunk(in, data)) < 0) {
70 AVI_print_error("AVI audio read frame");
71 //*aud_ms = vid_ms;
72 return(-2);
73 }
74 //fprintf(stderr, "len (%ld)\n", bytes);
75
76 if(AVI_write_audio(out, data, bytes)<0) {
77 AVI_print_error("AVI write audio frame");
78 return(-1);
79 }
80
81 // pass-through null frames
82 if (bytes == 0) {
83 *aud_ms = vid_ms;
84 break;
85 }
86
87 if ( vbr && tc_get_audio_header(data, bytes, format, NULL, NULL, &mp3rate)<0) {
88 // if this is the last frame of the file, slurp in audio chunks
89 //if (n == frames-1) continue;
90 *aud_ms = vid_ms;
91 } else {
92 if (vbr) mp3rate *= 1000;
93 *aud_ms += (bytes*8.0*1000.0)/(double)mp3rate;
94 }
95 /*
96 fprintf(stderr, "%s track (%d) %8.0lf->%8.0lf len (%ld) rate (%ld)\n",
97 format==0x55?"MP3":format==0x1?"PCM":"AC3",
98 j, vid_ms, aud_ms[j], bytes, mp3rate);
99 */
100 }
101
102 } else { // fallback for not supported audio format
103
104 do {
105 if ( (bytes = AVI_read_audio_chunk(in, data) ) < 0) {
106 AVI_print_error("AVI audio read frame");
107 return -2;
108 }
109
110 if(AVI_write_audio(out, data, bytes)<0) {
111 AVI_print_error("AVI write audio frame");
112 return(-1);
113 }
114 } while (AVI_can_read_audio(in));
115 }
116
117
118 return 0;
119 }
120
sync_audio_video_avi2avi_ro(double vid_ms,double * aud_ms,avi_t * in)121 int sync_audio_video_avi2avi_ro (double vid_ms, double *aud_ms, avi_t *in)
122 {
123 static char *data = NULL;
124 int vbr = AVI_get_audio_vbr(in);
125 int mp3rate = AVI_audio_mp3rate(in);
126 int format = AVI_audio_format(in);
127 int chan = AVI_audio_channels(in);
128 long rate = AVI_audio_rate(in);
129 int bits = AVI_audio_bits(in);
130 long bytes = 0;
131
132 bits = (bits == 0)?16:bits;
133
134 if (!data) data = malloc(48000*16*4);
135 if (!data) fprintf (stderr, "Malloc failed at %s:%d\n", __FILE__, __LINE__);
136
137 if (format == 0x1) {
138 mp3rate = rate*chan*bits;
139 } else {
140 mp3rate *= 1000;
141 }
142
143 if (tc_format_ms_supported(format)) {
144
145 while (*aud_ms < vid_ms) {
146
147 if( (bytes = AVI_read_audio_chunk(in, data)) < 0) {
148 AVI_print_error("AVI audio read frame");
149 //*aud_ms = vid_ms;
150 return(-2);
151 }
152 //fprintf(stderr, "len (%ld)\n", bytes);
153
154 // pass-through null frames
155 if (bytes == 0) {
156 *aud_ms = vid_ms;
157 break;
158 }
159
160 if ( vbr && tc_get_audio_header(data, bytes, format, NULL, NULL, &mp3rate)<0) {
161 // if this is the last frame of the file, slurp in audio chunks
162 //if (n == frames-1) continue;
163 *aud_ms = vid_ms;
164 } else {
165 if (vbr) mp3rate *= 1000;
166 *aud_ms += (bytes*8.0*1000.0)/(double)mp3rate;
167 }
168 /*
169 fprintf(stderr, "%s track (%d) %8.0lf->%8.0lf len (%ld) rate (%ld)\n",
170 format==0x55?"MP3":format==0x1?"PCM":"AC3",
171 j, vid_ms, aud_ms[j], bytes, mp3rate);
172 */
173 }
174
175 } else { // fallback for not supported audio format
176
177 do {
178 if ( (bytes = AVI_read_audio_chunk(in, data) ) < 0) {
179 AVI_print_error("AVI audio read frame");
180 return -2;
181 }
182 } while (AVI_can_read_audio(in));
183 }
184
185
186 return 0;
187 }
188
189 /*************************************************************************/
190
191 /*
192 * Local variables:
193 * c-file-style: "stroustrup"
194 * c-file-offsets: ((case-label . *) (statement-case-intro . *))
195 * indent-tabs-mode: nil
196 * End:
197 *
198 * vim: expandtab shiftwidth=4:
199 */
200