OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright © 2010 Mozilla Foundation | |
3 * | |
4 * This program is made available under an ISC-style license. See the | |
5 * accompanying file LICENSE for details. | |
6 */ | |
7 #include <assert.h> | |
8 #include <stdarg.h> | |
9 #include <stdio.h> | |
10 #include <stdlib.h> | |
11 #include <stdint.h> | |
12 #include "nestegg/nestegg.h" | |
13 | |
14 #undef DEBUG | |
15 #define SEEK_TEST | |
16 | |
17 static int | |
18 stdio_read(void * p, size_t length, void * file) | |
19 { | |
20 size_t r; | |
21 FILE * fp = file; | |
22 | |
23 r = fread(p, length, 1, fp); | |
24 if (r == 0 && feof(fp)) | |
25 return 0; | |
26 return r == 0 ? -1 : 1; | |
27 } | |
28 | |
29 static int | |
30 stdio_seek(int64_t offset, int whence, void * file) | |
31 { | |
32 FILE * fp = file; | |
33 return fseek(fp, offset, whence); | |
34 } | |
35 | |
36 static int64_t | |
37 stdio_tell(void * fp) | |
38 { | |
39 return ftell(fp); | |
40 } | |
41 | |
42 static void | |
43 log_callback(nestegg * ctx, unsigned int severity, char const * fmt, ...) | |
44 { | |
45 va_list ap; | |
46 char const * sev = NULL; | |
47 | |
48 #if !defined(DEBUG) | |
49 if (severity < NESTEGG_LOG_WARNING) | |
50 return; | |
51 #endif | |
52 | |
53 switch (severity) { | |
54 case NESTEGG_LOG_DEBUG: | |
55 sev = "debug: "; | |
56 break; | |
57 case NESTEGG_LOG_WARNING: | |
58 sev = "warning: "; | |
59 break; | |
60 case NESTEGG_LOG_CRITICAL: | |
61 sev = "critical:"; | |
62 break; | |
63 default: | |
64 sev = "unknown: "; | |
65 } | |
66 | |
67 fprintf(stderr, "%p %s ", (void *) ctx, sev); | |
68 | |
69 va_start(ap, fmt); | |
70 vfprintf(stderr, fmt, ap); | |
71 va_end(ap); | |
72 | |
73 fprintf(stderr, "\n"); | |
74 } | |
75 | |
76 int | |
77 main(int argc, char * argv[]) | |
78 { | |
79 FILE * fp; | |
80 int r, type; | |
81 nestegg * ctx; | |
82 nestegg_audio_params aparams; | |
83 nestegg_packet * pkt; | |
84 nestegg_video_params vparams; | |
85 size_t length, size; | |
86 uint64_t duration, tstamp, pkt_tstamp; | |
87 unsigned char * codec_data, * ptr; | |
88 unsigned int cnt, i, j, track, tracks, pkt_cnt, pkt_track; | |
89 unsigned int data_items = 0; | |
90 nestegg_io io = { | |
91 stdio_read, | |
92 stdio_seek, | |
93 stdio_tell, | |
94 NULL | |
95 }; | |
96 | |
97 if (argc != 2) | |
98 return EXIT_FAILURE; | |
99 | |
100 fp = fopen(argv[1], "rb"); | |
101 if (!fp) | |
102 return EXIT_FAILURE; | |
103 | |
104 io.userdata = fp; | |
105 | |
106 ctx = NULL; | |
107 r = nestegg_init(&ctx, io, log_callback, -1); | |
108 if (r != 0) | |
109 return EXIT_FAILURE; | |
110 | |
111 nestegg_track_count(ctx, &tracks); | |
112 nestegg_duration(ctx, &duration); | |
113 #if defined(DEBUG) | |
114 fprintf(stderr, "media has %u tracks and duration %fs\n", tracks, duration / 1
e9); | |
115 #endif | |
116 | |
117 for (i = 0; i < tracks; ++i) { | |
118 type = nestegg_track_type(ctx, i); | |
119 #if defined(DEBUG) | |
120 fprintf(stderr, "track %u: type: %d codec: %d", i, | |
121 type, nestegg_track_codec_id(ctx, i)); | |
122 #endif | |
123 nestegg_track_codec_data_count(ctx, i, &data_items); | |
124 for (j = 0; j < data_items; ++j) { | |
125 nestegg_track_codec_data(ctx, i, j, &codec_data, &length); | |
126 #if defined(DEBUG) | |
127 fprintf(stderr, " (%p, %u)", codec_data, (unsigned int) length); | |
128 #endif | |
129 } | |
130 if (type == NESTEGG_TRACK_VIDEO) { | |
131 nestegg_track_video_params(ctx, i, &vparams); | |
132 #if defined(DEBUG) | |
133 fprintf(stderr, " video: %ux%u (d: %ux%u %ux%ux%ux%u)", | |
134 vparams.width, vparams.height, | |
135 vparams.display_width, vparams.display_height, | |
136 vparams.crop_top, vparams.crop_left, vparams.crop_bottom, vparams.
crop_right); | |
137 #endif | |
138 } else if (type == NESTEGG_TRACK_AUDIO) { | |
139 nestegg_track_audio_params(ctx, i, &aparams); | |
140 #if defined(DEBUG) | |
141 fprintf(stderr, " audio: %.2fhz %u bit %u channels", | |
142 aparams.rate, aparams.depth, aparams.channels); | |
143 #endif | |
144 } | |
145 #if defined(DEBUG) | |
146 fprintf(stderr, "\n"); | |
147 #endif | |
148 } | |
149 | |
150 #if defined(SEEK_TEST) | |
151 #if defined(DEBUG) | |
152 fprintf(stderr, "seek to middle\n"); | |
153 #endif | |
154 r = nestegg_track_seek(ctx, 0, duration / 2); | |
155 if (r == 0) { | |
156 #if defined(DEBUG) | |
157 fprintf(stderr, "middle "); | |
158 #endif | |
159 r = nestegg_read_packet(ctx, &pkt); | |
160 if (r == 1) { | |
161 nestegg_packet_track(pkt, &track); | |
162 nestegg_packet_count(pkt, &cnt); | |
163 nestegg_packet_tstamp(pkt, &tstamp); | |
164 #if defined(DEBUG) | |
165 fprintf(stderr, "* t %u pts %f frames %u\n", track, tstamp / 1e9, cnt); | |
166 #endif | |
167 nestegg_free_packet(pkt); | |
168 } else { | |
169 #if defined(DEBUG) | |
170 fprintf(stderr, "middle seek failed\n"); | |
171 #endif | |
172 } | |
173 } | |
174 | |
175 #if defined(DEBUG) | |
176 fprintf(stderr, "seek to ~end\n"); | |
177 #endif | |
178 r = nestegg_track_seek(ctx, 0, duration - (duration / 10)); | |
179 if (r == 0) { | |
180 #if defined(DEBUG) | |
181 fprintf(stderr, "end "); | |
182 #endif | |
183 r = nestegg_read_packet(ctx, &pkt); | |
184 if (r == 1) { | |
185 nestegg_packet_track(pkt, &track); | |
186 nestegg_packet_count(pkt, &cnt); | |
187 nestegg_packet_tstamp(pkt, &tstamp); | |
188 #if defined(DEBUG) | |
189 fprintf(stderr, "* t %u pts %f frames %u\n", track, tstamp / 1e9, cnt); | |
190 #endif | |
191 nestegg_free_packet(pkt); | |
192 } else { | |
193 #if defined(DEBUG) | |
194 fprintf(stderr, "end seek failed\n"); | |
195 #endif | |
196 } | |
197 } | |
198 | |
199 #if defined(DEBUG) | |
200 fprintf(stderr, "seek to ~start\n"); | |
201 #endif | |
202 r = nestegg_track_seek(ctx, 0, duration / 10); | |
203 if (r == 0) { | |
204 #if defined(DEBUG) | |
205 fprintf(stderr, "start "); | |
206 #endif | |
207 r = nestegg_read_packet(ctx, &pkt); | |
208 if (r == 1) { | |
209 nestegg_packet_track(pkt, &track); | |
210 nestegg_packet_count(pkt, &cnt); | |
211 nestegg_packet_tstamp(pkt, &tstamp); | |
212 #if defined(DEBUG) | |
213 fprintf(stderr, "* t %u pts %f frames %u\n", track, tstamp / 1e9, cnt); | |
214 #endif | |
215 nestegg_free_packet(pkt); | |
216 } else { | |
217 #if defined(DEBUG) | |
218 fprintf(stderr, "start seek failed\n"); | |
219 #endif | |
220 } | |
221 } | |
222 #endif | |
223 | |
224 while (nestegg_read_packet(ctx, &pkt) > 0) { | |
225 nestegg_packet_track(pkt, &pkt_track); | |
226 nestegg_packet_count(pkt, &pkt_cnt); | |
227 nestegg_packet_tstamp(pkt, &pkt_tstamp); | |
228 | |
229 #if defined(DEBUG) | |
230 fprintf(stderr, "t %u pts %f frames %u: ", pkt_track, pkt_tstamp / 1e9, pkt_
cnt); | |
231 #endif | |
232 | |
233 for (i = 0; i < pkt_cnt; ++i) { | |
234 nestegg_packet_data(pkt, i, &ptr, &size); | |
235 #if defined(DEBUG) | |
236 fprintf(stderr, "%u ", (unsigned int) size); | |
237 #endif | |
238 } | |
239 #if defined(DEBUG) | |
240 fprintf(stderr, "\n"); | |
241 #endif | |
242 | |
243 nestegg_free_packet(pkt); | |
244 } | |
245 | |
246 nestegg_destroy(ctx); | |
247 fclose(fp); | |
248 | |
249 return EXIT_SUCCESS; | |
250 } | |
OLD | NEW |