1 /*
2 * tcdecode.c
3 *
4 * Copyright (C) Thomas Oestreich - June 2001
5 *
6 * This file is part of transcode, a video stream processing tool
7 *
8 * transcode is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * transcode is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with GNU Make; see the file COPYING. If not, write to
20 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
24 #include "transcode.h"
25 #include "tcinfo.h"
26
27 #include <limits.h>
28
29 #include "ioaux.h"
30 #include "tc.h"
31 #include "libtc/xio.h"
32
33 #define EXE "tcdecode"
34
35 extern long fileinfo(int fd, int skip);
36
37 int verbose = TC_QUIET;
38
import_exit(int code)39 void import_exit(int code)
40 {
41 if (verbose & TC_DEBUG)
42 tc_log_msg(EXE, "(pid=%d) exit (code %d)", (int) getpid(), code);
43 exit(code);
44 }
45
46
47 /* ------------------------------------------------------------
48 *
49 * print a usage/version message
50 *
51 * ------------------------------------------------------------*/
52
53
version(void)54 void version(void)
55 {
56 /* print id string to stderr */
57 fprintf(stderr, "%s (%s v%s) (C) 2001-2003 Thomas Oestreich,"
58 " 2003-2010 Transcode Team\n",
59 EXE, PACKAGE, VERSION);
60 }
61
62
usage(int status)63 static void usage(int status)
64 {
65 version();
66
67 fprintf(stderr,"\nUsage: %s [options]\n", EXE);
68
69 fprintf(stderr," -i file input file [stdin]\n");
70 fprintf(stderr," -x codec source codec (required)\n");
71 fprintf(stderr," -t package codec package\n");
72 fprintf(stderr," -g wxh stream frame size [autodetect]\n");
73 fprintf(stderr," -y format output raw stream format [rgb]\n");
74 fprintf(stderr," -Q mode decoding quality (0=fastest-5=best) [%d]\n", VQUALITY);
75 fprintf(stderr," -d mode verbosity mode\n");
76 fprintf(stderr," -s c,f,r audio gain for ac3 downmixing [1,1,1]\n");
77 fprintf(stderr," -A n A52 decoder flag [0]\n");
78 fprintf(stderr," -C s,e decode only from start to end ((V) frames/(A) bytes) [all]\n");
79 fprintf(stderr," -Y use libdv YUY2 decoder mode\n");
80 fprintf(stderr," -z r convert zero padding to silence\n");
81 fprintf(stderr," -v print version\n");
82
83 exit(status);
84 }
85
86 /* ------------------------------------------------------------
87 *
88 * universal decode thread frontend
89 *
90 * ------------------------------------------------------------*/
91
main(int argc,char * argv[])92 int main(int argc, char *argv[])
93 {
94 decode_t decode;
95 int ch, done=0;
96 char *codec=NULL, *format="rgb", *magic="none";
97
98 memset(&decode, 0, sizeof(decode));
99 decode.magic = TC_MAGIC_UNKNOWN;
100 decode.stype = TC_STYPE_UNKNOWN;
101 decode.quality = VQUALITY;
102 decode.ac3_gain[0] = decode.ac3_gain[1] = decode.ac3_gain[2] = 1.0;
103 decode.frame_limit[0]=0;
104 decode.frame_limit[1]=LONG_MAX;
105
106 libtc_init(&argc, &argv);
107
108 while ((ch = getopt(argc, argv, "Q:t:d:x:i:a:g:vy:s:YC:A:z:?h")) != -1) {
109 switch (ch) {
110
111 case 'i':
112 if (optarg[0]=='-') usage(EXIT_FAILURE);
113 decode.name = optarg;
114 break;
115
116 case 'd':
117 if (optarg[0]=='-') usage(EXIT_FAILURE);
118 verbose = atoi(optarg);
119 break;
120
121 case 'Q':
122 if (optarg[0]=='-') usage(EXIT_FAILURE);
123 decode.quality = atoi(optarg);
124 break;
125
126 case 'A':
127 if (optarg[0]=='-') usage(EXIT_FAILURE);
128 decode.a52_mode = atoi(optarg);
129 break;
130
131 case 'x':
132 if (optarg[0]=='-') usage(EXIT_FAILURE);
133 codec = optarg;
134 break;
135
136 case 't':
137 if (optarg[0]=='-') usage(EXIT_FAILURE);
138 magic = optarg;
139 break;
140
141 case 'y':
142 if (optarg[0]=='-') usage(EXIT_FAILURE);
143 format = optarg;
144 break;
145
146 case 'g':
147 if (optarg[0]=='-') usage(EXIT_FAILURE);
148 if (2 != sscanf(optarg,"%dx%d", &decode.width, &decode.height)) usage(EXIT_FAILURE);
149 break;
150
151 case 'v':
152 version();
153 exit(0);
154 break;
155
156 case 'Y':
157 decode.dv_yuy2_mode=1;
158 break;
159
160 case 's':
161 if(optarg[0]=='-') usage(EXIT_FAILURE);
162 if (3 != sscanf(optarg,"%lf,%lf,%lf", &decode.ac3_gain[0], &decode.ac3_gain[1], &decode.ac3_gain[2])) usage(EXIT_FAILURE);
163 break;
164
165 case 'C':
166 if(optarg[0]=='-') usage(EXIT_FAILURE);
167 if (2 != sscanf(optarg,"%ld,%ld", &decode.frame_limit[0], &decode.frame_limit[1])) usage(EXIT_FAILURE);
168 if (decode.frame_limit[0] >= decode.frame_limit[1])
169 {
170 tc_log_error(EXE, "Invalid -C options");
171 usage(EXIT_FAILURE);
172 }
173 break;
174
175 case 'z':
176 if(optarg[0]=='-') usage(EXIT_FAILURE);
177 decode.padrate = atoi(optarg);
178 break;
179
180 case 'h':
181 usage(EXIT_SUCCESS);
182 default:
183 usage(EXIT_FAILURE);
184 }
185 }
186
187 ac_init(AC_ALL);
188
189 /* ------------------------------------------------------------
190 *
191 * fill out defaults for info structure
192 *
193 * ------------------------------------------------------------*/
194
195 // assume defaults
196 if(decode.name==NULL) decode.stype=TC_STYPE_STDIN;
197
198 // no autodetection yet
199 if(codec==NULL) {
200 tc_log_error(EXE, "codec must be specified");
201 usage(EXIT_FAILURE);
202 }
203
204 // do not try to mess with the stream
205 if (decode.stype != TC_STYPE_STDIN) {
206 if (tc_file_check(decode.name)) exit(1);
207 if ((decode.fd_in = xio_open(decode.name, O_RDONLY)) < 0) {
208 tc_log_perror(EXE, "open file");
209 exit(1);
210 }
211
212 // try to find out the filetype
213 decode.magic = fileinfo(decode.fd_in, 0);
214 if (verbose)
215 tc_log_msg(EXE, "(pid=%d) %s", getpid(), filetype(decode.magic));
216
217 } else decode.fd_in = STDIN_FILENO;
218
219 decode.fd_out = STDOUT_FILENO;
220 decode.codec = TC_CODEC_UNKNOWN;
221 decode.verbose = verbose;
222 if (decode.width < 0) decode.width = 0;
223 if (decode.height < 0) decode.height = 0;
224
225 /* ------------------------------------------------------------
226 *
227 * output raw stream format
228 *
229 * ------------------------------------------------------------*/
230
231 if (!strcmp(format, "rgb")) decode.format = TC_CODEC_RGB;
232 else if (!strcmp(format, "yuv420p")) decode.format = TC_CODEC_YUV420P;
233 else if (!strcmp(format, "yuv2")) decode.format = TC_CODEC_YUV2;
234 else if (!strcmp(format, "yuy2")) decode.format = TC_CODEC_YUY2;
235 else if (!strcmp(format, "pcm")) decode.format = TC_CODEC_PCM;
236 else if (!strcmp(format, "raw")) decode.format = TC_CODEC_RAW;
237
238 /* ------------------------------------------------------------
239 *
240 * codec specific section
241 *
242 * note: user provided values overwrite autodetection!
243 *
244 * ------------------------------------------------------------*/
245
246 // FFMPEG can decode a lot
247 if(!strcmp(magic, "ffmpeg") || !strcmp(magic, "lavc")) {
248 if (!strcmp(codec, "mpeg2")) decode.codec = TC_CODEC_MPEG2;
249 else if (!strcmp(codec, "mpeg2video")) decode.codec = TC_CODEC_MPEG2;
250 else if (!strcmp(codec, "mpeg1video")) decode.codec = TC_CODEC_MPEG1;
251 else if (!strcmp(codec, "divx3")) decode.codec = TC_CODEC_DIVX3;
252 else if (!strcmp(codec, "divx")) decode.codec = TC_CODEC_DIVX4;
253 else if (!strcmp(codec, "divx4")) decode.codec = TC_CODEC_DIVX4;
254 else if (!strcmp(codec, "mp42")) decode.codec = TC_CODEC_MP42;
255 else if (!strcmp(codec, "mjpg")) decode.codec = TC_CODEC_MJPEG;
256 else if (!strcmp(codec, "mjpeg")) decode.codec = TC_CODEC_MJPEG;
257 else if (!strcmp(codec, "rv10")) decode.codec = TC_CODEC_RV10;
258 else if (!strcmp(codec, "svq1")) decode.codec = TC_CODEC_SVQ1;
259 else if (!strcmp(codec, "svq3")) decode.codec = TC_CODEC_SVQ3;
260 else if (!strcmp(codec, "vp3")) decode.codec = TC_CODEC_VP3;
261 else if (!strcmp(codec, "4xm")) decode.codec = TC_CODEC_4XM;
262 else if (!strcmp(codec, "wmv1")) decode.codec = TC_CODEC_WMV1;
263 else if (!strcmp(codec, "wmv2")) decode.codec = TC_CODEC_WMV2;
264 else if (!strcmp(codec, "hfyu")) decode.codec = TC_CODEC_HUFFYUV;
265 else if (!strcmp(codec, "indeo3")) decode.codec = TC_CODEC_INDEO3;
266 else if (!strcmp(codec, "h263p")) decode.codec = TC_CODEC_H263P;
267 else if (!strcmp(codec, "h263i")) decode.codec = TC_CODEC_H263I;
268 else if (!strcmp(codec, "dvvideo")) decode.codec = TC_CODEC_DV;
269 else if (!strcmp(codec, "dv")) decode.codec = TC_CODEC_DV;
270 else if (!strcmp(codec, "vag")) decode.codec = TC_CODEC_VAG;
271
272 decode_lavc(&decode);
273 }
274
275 // MPEG2
276 if (!strcmp(codec, "mpeg2")) {
277 decode.codec = TC_CODEC_MPEG2;
278 decode_mpeg2(&decode);
279 done = 1;
280 }
281
282 // OGG
283 if (!strcmp(codec, "ogg")) {
284 decode.codec = TC_CODEC_VORBIS;
285 decode_ogg(&decode);
286 done = 1;
287 }
288
289 // AC3
290 if (!strcmp(codec, "ac3")) {
291 decode.codec = TC_CODEC_AC3;
292 decode_a52(&decode);
293 done = 1;
294 }
295
296 // MP3
297 if (!strcmp(codec, "mp3")) {
298 decode.codec = TC_CODEC_MP3;
299 decode_mp3(&decode);
300 done = 1;
301 }
302
303 // MP2
304 if (!strcmp(codec, "mp2")) {
305 decode.codec = TC_CODEC_MP3;
306 decode_mp2(&decode);
307 done = 1;
308 }
309
310 // DV
311 if (!strcmp(codec, "dv")) {
312 decode.codec = TC_CODEC_DV;
313 decode_dv(&decode);
314 done = 1;
315 }
316
317 // YUV420P
318 if (!strcmp(codec, "yuv420p")) {
319 decode.codec = TC_CODEC_YUV420P;
320 decode_yuv(&decode);
321 done = 1;
322 }
323
324 #if 0
325 // DivX Video
326 if (!strcmp(codec, "divx")) {
327 decode.select = TC_VIDEO;
328 decode_divx(&decode);
329 done = 1;
330 }
331 #endif
332
333 // MOV
334 if (!strcmp(codec, "mov")) {
335 decode_mov(&decode);
336 done = 1;
337 }
338
339 // LZO
340 if (!strcmp(codec, "lzo")) {
341 decode_lzo(&decode);
342 done = 1;
343 }
344
345 if(!done) {
346 tc_log_error(EXE, "(pid=%d) unable to handle codec %s", getpid(), codec);
347 exit(1);
348 }
349
350 if (decode.fd_in != STDIN_FILENO) xio_close(decode.fd_in);
351
352 return 0;
353 }
354
355 #include "libtc/static_xio.h"
356