1 /*
2 * decode_lavc.c
3 *
4 * Copyright (C) Tilmann Bitterberg - March 2003
5 * Copyright (C) Thomas Oestreich - June 2001
6 * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
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 "transcode.h"
31 #include "tcinfo.h"
32
33 #include "aclib/imgconvert.h"
34 #include "ioaux.h"
35 #include "tc.h"
36
37 #include "libtc/libtc.h"
38
39
40 #define READ_BUFFER_SIZE (10*1024*1024)
41 #define MOD_NAME "decode_ffmpeg"
42
43 #define MAX_BUF 1024
44
45 #ifdef HAVE_FFMPEG
46
47 #include "libtc/tcavcodec.h"
48
49
50 static int verbose_flag=TC_QUIET;
51
52 struct ffmpeg_codec {
53 int id;
54 unsigned int tc_id;
55 char *name;
56 char fourCCs[10][5];
57 };
58
59 // fourCC to ID mapping taken from MPlayer's codecs.conf
60 static struct ffmpeg_codec ffmpeg_codecs[] = {
61 {AV_CODEC_ID_MSMPEG4V1, TC_CODEC_ERROR, "mp41",
62 {"MP41", "DIV1", ""}},
63 {AV_CODEC_ID_MSMPEG4V2, TC_CODEC_MP42, "mp42",
64 {"MP42", "DIV2", ""}},
65 {AV_CODEC_ID_MSMPEG4V3, TC_CODEC_DIVX3, "msmpeg4",
66 {"DIV3", "DIV5", "AP41", "MPG3", "MP43", ""}},
67 {AV_CODEC_ID_MPEG4, TC_CODEC_DIVX4, "mpeg4",
68 {"DIVX", "XVID", "MP4S", "M4S2", "MP4V", "UMP4", "DX50", ""}},
69 {AV_CODEC_ID_MJPEG, TC_CODEC_MJPEG, "mjpeg",
70 {"MJPG", "AVRN", "AVDJ", "JPEG", "MJPA", "JFIF", ""}},
71 {AV_CODEC_ID_MPEG1VIDEO, TC_CODEC_MPEG1VIDEO, "mpeg1video",
72 {"MPG1", ""}},
73 {AV_CODEC_ID_DVVIDEO, TC_CODEC_DV, "dvvideo",
74 {"DVSD", ""}},
75 {AV_CODEC_ID_WMV1, TC_CODEC_WMV1, "wmv1",
76 {"WMV1", ""}},
77 {AV_CODEC_ID_WMV2, TC_CODEC_WMV2, "wmv2",
78 {"WMV2", ""}},
79 {AV_CODEC_ID_HUFFYUV, TC_CODEC_HUFFYUV, "hfyu",
80 {"HFYU", ""}},
81 {AV_CODEC_ID_H263I, TC_CODEC_H263I, "h263i",
82 {"I263", ""}},
83 {AV_CODEC_ID_H263P, TC_CODEC_H263P, "h263p",
84 {"H263", "U263", "VIV1", ""}},
85 {AV_CODEC_ID_RV10, TC_CODEC_RV10, "rv10",
86 {"RV10", "RV13", ""}},
87 {AV_CODEC_ID_SVQ1, TC_CODEC_SVQ1, "svq1",
88 {"SVQ1", ""}},
89 {AV_CODEC_ID_SVQ3, TC_CODEC_SVQ3, "svq3",
90 {"SVQ3", ""}},
91 {AV_CODEC_ID_MPEG2VIDEO, TC_CODEC_MPEG2, "mpeg2video",
92 {"MPG2", ""}},
93 {0, TC_CODEC_UNKNOWN, NULL, {""}}};
94
95
find_ffmpeg_codec_id(unsigned int transcode_id)96 static struct ffmpeg_codec *find_ffmpeg_codec_id(unsigned int transcode_id)
97 {
98 struct ffmpeg_codec *cdc = &ffmpeg_codecs[0];
99 while (cdc->name != NULL) {
100 if (cdc->tc_id == transcode_id)
101 return cdc;
102 cdc++;
103 }
104
105 return NULL;
106 }
107
108
109 /* ------------------------------------------------------------
110 *
111 * decoder thread
112 *
113 * ------------------------------------------------------------*/
114
decode_lavc(decode_t * decode)115 void decode_lavc(decode_t *decode)
116 {
117 uint8_t *out_buffer = NULL;
118 int pass_through = 0;
119 char *buffer = NULL;
120 char *yuv2rgb_buffer = NULL;
121 AVCodec *lavc_dec_codec = NULL;
122 AVCodecContext *lavc_dec_context;
123 int x_dim = 0, y_dim = 0;
124 int pix_fmt, frame_size = 0, bpp = 8;
125 struct ffmpeg_codec *codec;
126
127 char *fourCC = NULL;
128 char *mp4_ptr=NULL;
129 int flush = 0;
130 int mp4_size=0;
131 int buf_len=0;
132 int run=0;
133
134 // decoder
135 int len = 0;
136 long bytes_read = 0;
137 uint8_t *planes[3];
138
139 verbose_flag = decode->verbose;
140
141 x_dim = decode->width;
142 y_dim = decode->height;
143
144 fourCC="DIVX";
145
146 //----------------------------------------
147 //
148 // setup decoder
149 //
150 //----------------------------------------
151
152 TC_INIT_LIBAVCODEC;
153
154 codec = find_ffmpeg_codec_id(decode->codec);
155 if (codec == NULL) {
156 tc_log_error(__FILE__, "No codec is known for the TAG '%lx'.",
157 decode->codec);
158 goto decoder_error;
159 }
160 if (decode->verbose & TC_DEBUG) {
161 tc_log_msg(__FILE__, "Using Codec %s id 0x%x",
162 codec->name, codec->tc_id);
163 }
164
165 lavc_dec_codec = avcodec_find_decoder(codec->id);
166 if (!lavc_dec_codec) {
167 tc_log_error(__FILE__, "No codec found for the FOURCC '%s'.", fourCC);
168 goto decoder_error;
169 }
170
171 // Set these to the expected values so that ffmpeg's decoder can
172 // properly detect interlaced input.
173 lavc_dec_context = avcodec_alloc_context3(NULL);
174 if (lavc_dec_context == NULL) {
175 tc_log_error(__FILE__, "Could not allocate enough memory.");
176 goto decoder_error;
177 }
178 lavc_dec_context->width = x_dim;
179 lavc_dec_context->height = y_dim;
180
181 #if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0)
182 lavc_dec_context->error_resilience = 2;
183 #else
184 lavc_dec_context->err_recognition = 2;
185 #endif
186 lavc_dec_context->error_concealment = 3;
187 lavc_dec_context->workaround_bugs = FF_BUG_AUTODETECT;
188
189 if (avcodec_open2(lavc_dec_context, lavc_dec_codec, NULL) < 0) {
190 tc_log_error(__FILE__, "Could not initialize the '%s' codec.",
191 codec->name);
192 goto decoder_error;
193 }
194
195 pix_fmt = decode->format;
196
197 frame_size = (x_dim * y_dim * 3)/2;
198 switch (pix_fmt)
199 {
200 case TC_CODEC_YUV420P:
201 frame_size = (x_dim * y_dim * 3)/2;
202 break;
203
204 case TC_CODEC_RGB:
205 frame_size = x_dim * y_dim * 3;
206 bpp = 24;
207
208 if (yuv2rgb_buffer == NULL)
209 yuv2rgb_buffer = tc_bufalloc(frame_size);
210
211 if (yuv2rgb_buffer == NULL)
212 {
213 tc_log_perror(__FILE__, "out of memory");
214 goto decoder_error;
215 }
216 else
217 memset(yuv2rgb_buffer, 0, frame_size);
218 break;
219
220 case TC_CODEC_RAW:
221 pass_through = 1;
222 break;
223 }
224
225 if(buffer == NULL) buffer=tc_bufalloc(READ_BUFFER_SIZE);
226 if(buffer == NULL) {
227 tc_log_perror(__FILE__, "out of memory");
228 goto decoder_error;
229 }
230
231 if(out_buffer == NULL) out_buffer=tc_bufalloc(frame_size);
232 if(out_buffer == NULL) {
233 tc_log_perror(__FILE__, "out of memory");
234 goto decoder_error;
235 }
236
237 memset(buffer, 0, READ_BUFFER_SIZE);
238 memset(out_buffer, 0, frame_size);
239
240 // DECODE MAIN LOOP
241
242 bytes_read = tc_pread(decode->fd_in, (uint8_t*) buffer, READ_BUFFER_SIZE);
243
244 if (bytes_read < 0) {
245 tc_log_warn(__FILE__, "EOF?");
246 goto decoder_error;
247 }
248 mp4_ptr = buffer;
249 mp4_size = bytes_read;
250 buf_len = 0;
251
252 do {
253 AVFrame picture;
254 int got_picture = 0;
255
256 if (buf_len >= mp4_size) {
257 if (verbose_flag & TC_DEBUG)
258 tc_log_warn(__FILE__, "EOF?");
259 break;
260 }
261
262 //tc_log_msg(__FILE__, "SIZE: (%d) MP4(%d) blen(%d) BUF(%d) read(%ld)", len, mp4_size, buf_len, READ_BUFFER_SIZE, bytes_read);
263 do {
264 AVPacket avpkt;
265 av_init_packet(&avpkt);
266 avpkt.data = NULL;
267 avpkt.size = 0;
268 len = avcodec_decode_video2(lavc_dec_context, &picture,
269 &got_picture, &avpkt);
270
271 if (len < 0) {
272 tc_log_error(__FILE__, "frame decoding failed");
273 goto decoder_error;
274 }
275 if (verbose_flag & TC_DEBUG) {
276 tc_log_msg(__FILE__, "here frame pic %d run %d len %d",
277 got_picture, run, len);
278 }
279 if (run++ > 10000) {
280 tc_log_error(__FILE__, "Fatal decoder error");
281 goto decoder_error;
282 }
283 } while (!got_picture);
284 run = 0;
285
286 buf_len += len;
287
288 YUV_INIT_PLANES(planes, out_buffer, IMG_YUV420P,
289 lavc_dec_context->width, lavc_dec_context->height);
290
291 // Convert avcodec image to the requested YUV or RGB format
292 switch (lavc_dec_context->pix_fmt) {
293 case AV_PIX_FMT_YUVJ420P:
294 case AV_PIX_FMT_YUV420P:
295 // Remove "dead space" at right edge of planes, if any
296 if (picture.linesize[0] != lavc_dec_context->width) {
297 int y;
298 for (y = 0; y < lavc_dec_context->height; y++) {
299 ac_memcpy(picture.data[0] + y*lavc_dec_context->width,
300 picture.data[0] + y*picture.linesize[0],
301 lavc_dec_context->width);
302 if (y%2 == 0) {
303 ac_memcpy(picture.data[1] + y*(lavc_dec_context->width/2),
304 picture.data[1] + y*picture.linesize[1],
305 lavc_dec_context->width/2);
306 ac_memcpy(picture.data[2] + y*(lavc_dec_context->width/2),
307 picture.data[2] + y*picture.linesize[2],
308 lavc_dec_context->width/2);
309 }
310 }
311 }
312 /* FIXME: we can't use tcv_convert here because it assumes
313 * contiguous planes, which libavcodec might not give us --AC */
314 ac_imgconvert(picture.data, IMG_YUV420P, planes,
315 pix_fmt==TC_CODEC_YUV420P ? IMG_YUV420P : IMG_RGB_DEFAULT,
316 lavc_dec_context->width, lavc_dec_context->height);
317 break;
318 case AV_PIX_FMT_YUV411P:
319 if (picture.linesize[0] != lavc_dec_context->width) {
320 int y;
321 for (y = 0; y < lavc_dec_context->height; y++) {
322 ac_memcpy(picture.data[0] + y*lavc_dec_context->width,
323 picture.data[0] + y*picture.linesize[0],
324 lavc_dec_context->width);
325 ac_memcpy(picture.data[1] + y*(lavc_dec_context->width/4),
326 picture.data[1] + y*picture.linesize[1],
327 lavc_dec_context->width/4);
328 ac_memcpy(picture.data[2] + y*(lavc_dec_context->width/4),
329 picture.data[2] + y*picture.linesize[2],
330 lavc_dec_context->width/4);
331 }
332 }
333 ac_imgconvert(picture.data, IMG_YUV411P, planes,
334 pix_fmt==TC_CODEC_YUV420P ? IMG_YUV420P : IMG_RGB_DEFAULT,
335 lavc_dec_context->width, lavc_dec_context->height);
336 break;
337 case AV_PIX_FMT_YUVJ422P:
338 case AV_PIX_FMT_YUV422P:
339 if (picture.linesize[0] != lavc_dec_context->width) {
340 int y;
341 for (y = 0; y < lavc_dec_context->height; y++) {
342 ac_memcpy(picture.data[0] + y*lavc_dec_context->width,
343 picture.data[0] + y*picture.linesize[0],
344 lavc_dec_context->width);
345 ac_memcpy(picture.data[1] + y*(lavc_dec_context->width/2),
346 picture.data[1] + y*picture.linesize[1],
347 lavc_dec_context->width/2);
348 ac_memcpy(picture.data[2] + y*(lavc_dec_context->width/2),
349 picture.data[2] + y*picture.linesize[2],
350 lavc_dec_context->width/2);
351 }
352 }
353 ac_imgconvert(picture.data, IMG_YUV422P, planes,
354 pix_fmt==TC_CODEC_YUV420P ? IMG_YUV420P : IMG_RGB_DEFAULT,
355 lavc_dec_context->width, lavc_dec_context->height);
356 break;
357 case AV_PIX_FMT_YUVJ444P:
358 case AV_PIX_FMT_YUV444P:
359 if (picture.linesize[0] != lavc_dec_context->width) {
360 int y;
361 for (y = 0; y < lavc_dec_context->height; y++) {
362 ac_memcpy(picture.data[0] + y*lavc_dec_context->width,
363 picture.data[0] + y*picture.linesize[0],
364 lavc_dec_context->width);
365 ac_memcpy(picture.data[1] + y*lavc_dec_context->width,
366 picture.data[1] + y*picture.linesize[1],
367 lavc_dec_context->width);
368 ac_memcpy(picture.data[2] + y*lavc_dec_context->width,
369 picture.data[2] + y*picture.linesize[2],
370 lavc_dec_context->width);
371 }
372 }
373 ac_imgconvert(picture.data, IMG_YUV444P, planes,
374 pix_fmt==TC_CODEC_YUV420P ? IMG_YUV420P : IMG_RGB_DEFAULT,
375 lavc_dec_context->width, lavc_dec_context->height);
376 break;
377 default:
378 tc_log_error(__FILE__, "Unsupported decoded frame format");
379 goto decoder_error;
380 }
381
382 /* buffer more than half empty -> Fill it */
383 if (!flush && buf_len > mp4_size/2+1) {
384 int rest = mp4_size - buf_len;
385 if (verbose_flag & TC_DEBUG)
386 tc_log_msg(__FILE__, "FILL rest %d", rest);
387
388 /* Move data if needed */
389 if (rest)
390 memmove(buffer, buffer+buf_len, READ_BUFFER_SIZE-buf_len);
391
392 /* read new data */
393 if ( (bytes_read = tc_pread(decode->fd_in, (uint8_t*) (buffer+(READ_BUFFER_SIZE-buf_len)), buf_len) ) != buf_len) {
394 if (verbose_flag & TC_DEBUG)
395 tc_log_msg(__FILE__, "read failed read (%ld) should (%d)", bytes_read, buf_len);
396 flush = 1;
397 mp4_size -= buf_len;
398 mp4_size += bytes_read;
399 }
400 buf_len = 0;
401 }
402 //tc_log_msg(__FILE__, "SIZE: (%d) MP4(%d) blen(%d) BUF(%d) read(%ld)", len, mp4_size, buf_len, READ_BUFFER_SIZE, bytes_read);
403 if (mp4_size<=0) {
404
405 if (verbose_flag & TC_DEBUG)
406 tc_log_msg(__FILE__, "no more bytes");
407 break;
408 }
409
410 if (tc_pwrite(decode->fd_out, out_buffer, frame_size) != frame_size) {
411 goto decoder_error;
412 }
413
414 } while (1);
415
416 import_exit(0);
417 return;
418
419 decoder_error:
420 import_exit(1);
421 }
422
423
424 #else /* HAVE_FFMPEG */
425
decode_lavc(decode_t * decode)426 void decode_lavc(decode_t *decode)
427 {
428 tc_log_error(__FILE__, "No support for FFmpeg configured -- exiting");
429 import_exit(1);
430 }
431
432
433 #endif /* HAVE_FFMPEG */
434
435 /*************************************************************************/
436
437 /*
438 * Local variables:
439 * c-file-style: "stroustrup"
440 * c-file-offsets: ((case-label . *) (statement-case-intro . *))
441 * indent-tabs-mode: nil
442 * End:
443 *
444 * vim: expandtab shiftwidth=4:
445 */
446
447