4 * Partial Copyright (c) 2006 Peter Schlaile
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
23 #if defined(_WIN32) && defined(_DEBUG) && !defined(__MINGW32__) && !defined(__CYGWIN__)
24 /* This does not seem necessary or present on MSVC 8, but may be needed in earlier versions? */
32 #include <ffmpeg/avformat.h>
33 #include <ffmpeg/avcodec.h>
34 #include <ffmpeg/rational.h>
36 #if LIBAVFORMAT_VERSION_INT < (49 << 16)
37 #define FFMPEG_OLD_FRAME_RATE 1
39 #define FFMPEG_CODEC_IS_POINTER 1
40 #define FFMPEG_CODEC_TIME_BASE 1
43 #if defined(WIN32) && (!(defined snprintf))
44 #define snprintf _snprintf
47 #include "BKE_writeffmpeg.h"
49 #include "MEM_guardedalloc.h"
50 #include "BLI_blenlib.h"
52 #include "BKE_bad_level_calls.h"
53 #include "BKE_global.h"
55 #include "IMB_imbuf_types.h"
56 #include "IMB_imbuf.h"
58 #include "BSE_seqaudio.h"
60 #include "DNA_scene_types.h"
67 extern void do_init_ffmpeg();
68 void makeffmpegstring(char* string
);
70 static int ffmpeg_type
= 0;
71 static int ffmpeg_codec
= CODEC_ID_MPEG4
;
72 static int ffmpeg_audio_codec
= CODEC_ID_MP2
;
73 static int ffmpeg_video_bitrate
= 1150;
74 static int ffmpeg_audio_bitrate
= 128;
75 static int ffmpeg_gop_size
= 12;
76 static int ffmpeg_multiplex_audio
= 1;
77 static int ffmpeg_autosplit
= 0;
78 static int ffmpeg_autosplit_count
= 0;
80 static AVFormatContext
* outfile
= 0;
81 static AVStream
* video_stream
= 0;
82 static AVStream
* audio_stream
= 0;
83 static AVFrame
* current_frame
= 0;
85 static uint8_t* video_buffer
= 0;
86 static int video_buffersize
= 0;
88 static uint8_t* audio_input_buffer
= 0;
89 static int audio_input_frame_size
= 0;
90 static uint8_t* audio_output_buffer
= 0;
91 static int audio_outbuf_size
= 0;
93 static RenderData
*ffmpeg_renderdata
= 0;
95 #define FFMPEG_AUTOSPLIT_SIZE 2000000000
97 /* Delete a picture buffer */
99 static void delete_picture(AVFrame
* f
)
102 if (f
->data
[0]) MEM_freeN(f
->data
[0]);
107 #ifdef FFMPEG_CODEC_IS_POINTER
108 static AVCodecContext
* get_codec_from_stream(AVStream
* stream
)
110 return stream
->codec
;
113 static AVCodecContext
* get_codec_from_stream(AVStream
* stream
)
115 return &stream
->codec
;
119 static int write_audio_frame(void)
121 AVCodecContext
* c
= NULL
;
124 c
= get_codec_from_stream(audio_stream
);
126 audiostream_fill(audio_input_buffer
,
127 audio_input_frame_size
128 * sizeof(short) * c
->channels
);
130 av_init_packet(&pkt
);
132 pkt
.size
= avcodec_encode_audio(c
, audio_output_buffer
,
134 (short*) audio_input_buffer
);
135 pkt
.data
= audio_output_buffer
;
136 #ifdef FFMPEG_CODEC_TIME_BASE
137 pkt
.pts
= av_rescale_q(c
->coded_frame
->pts
,
138 c
->time_base
, audio_stream
->time_base
);
140 pkt
.pts
= c
->coded_frame
->pts
;
142 fprintf(stderr
, "Audio Frame PTS: %lld\n", pkt
.pts
);
144 pkt
.stream_index
= audio_stream
->index
;
145 pkt
.flags
|= PKT_FLAG_KEY
;
146 if (av_interleaved_write_frame(outfile
, &pkt
) != 0) {
147 error("Error writing audio packet");
153 /* Allocate a temporary frame */
154 static AVFrame
* alloc_picture(int pix_fmt
, int width
, int height
)
160 /* allocate space for the struct */
161 f
= avcodec_alloc_frame();
163 size
= avpicture_get_size(pix_fmt
, width
, height
);
164 /* allocate the actual picture buffer */
165 buf
= MEM_mallocN(size
, "AVFrame buffer");
170 avpicture_fill((AVPicture
*)f
, buf
, pix_fmt
, width
, height
);
174 /* Get the correct file extensions for the requested format,
175 first is always desired guess_format parameter */
176 static const char** get_file_extensions(int format
)
180 static const char * rv
[] = { ".dv", NULL
};
184 static const char * rv
[] = { ".mpg", ".mpeg", NULL
};
188 static const char * rv
[] = { ".dvd", ".vob", ".mpg", ".mpeg",
193 static const char * rv
[] = { ".mp4", ".mpg", ".mpeg", NULL
};
197 static const char * rv
[] = { ".avi", NULL
};
201 static const char * rv
[] = { ".mov", NULL
};
205 /* FIXME: avi for now... */
206 static const char * rv
[] = { ".avi", NULL
};
211 /* FIXME: avi for now... */
212 static const char * rv
[] = { ".avi", NULL
};
220 /* Write a frame to the output file */
221 static void write_video_frame(AVFrame
* frame
)
225 AVCodecContext
* c
= get_codec_from_stream(video_stream
);
226 #ifdef FFMPEG_CODEC_TIME_BASE
227 frame
->pts
= G
.scene
->r
.cfra
- G
.scene
->r
.sfra
;
230 outsize
= avcodec_encode_video(c
, video_buffer
, video_buffersize
,
234 av_init_packet(&packet
);
236 #ifdef FFMPEG_CODEC_TIME_BASE
237 packet
.pts
= av_rescale_q(c
->coded_frame
->pts
,
239 video_stream
->time_base
);
241 packet
.pts
= c
->coded_frame
->pts
;
243 fprintf(stderr
, "Video Frame PTS: %lld\n", packet
.pts
);
244 if (c
->coded_frame
->key_frame
)
245 packet
.flags
|= PKT_FLAG_KEY
;
246 packet
.stream_index
= video_stream
->index
;
247 packet
.data
= video_buffer
;
248 packet
.size
= outsize
;
249 ret
= av_interleaved_write_frame(outfile
, &packet
);
253 error("Error writing frame");
257 /* read and encode a frame of audio from the buffer */
258 static AVFrame
* generate_video_frame(uint8_t* pixels
)
260 uint8_t* rendered_frame
;
262 AVCodecContext
* c
= get_codec_from_stream(video_stream
);
263 int width
= c
->width
;
264 int height
= c
->height
;
267 if (c
->pix_fmt
!= PIX_FMT_RGBA32
) {
268 rgb_frame
= alloc_picture(PIX_FMT_RGBA32
, width
, height
);
271 error("Couldn't allocate temporary frame");
275 rgb_frame
= current_frame
;
278 rendered_frame
= pixels
;
280 /* Do RGBA-conversion and flipping in one step depending
283 if (G
.order
== L_ENDIAN
) {
285 for (y
= 0; y
< height
; y
++) {
286 uint8_t* target
= rgb_frame
->data
[0]
287 + width
* 4 * (height
- y
- 1);
288 uint8_t* src
= rendered_frame
+ width
* 4 * y
;
289 uint8_t* end
= src
+ width
* 4;
302 for (y
= 0; y
< height
; y
++) {
303 uint8_t* target
= rgb_frame
->data
[0]
304 + width
* 4 * (height
- y
- 1);
305 uint8_t* src
= rendered_frame
+ width
* 4 * y
;
306 uint8_t* end
= src
+ width
* 4;
319 if (c
->pix_fmt
!= PIX_FMT_RGBA32
) {
320 img_convert((AVPicture
*)current_frame
, c
->pix_fmt
,
321 (AVPicture
*)rgb_frame
, PIX_FMT_RGBA32
, width
, height
);
322 delete_picture(rgb_frame
);
324 return current_frame
;
327 /* prepare a video stream for the output file */
329 static AVStream
* alloc_video_stream(int codec_id
, AVFormatContext
* of
,
330 int rectx
, int recty
)
335 st
= av_new_stream(of
, 0);
336 if (!st
) return NULL
;
338 /* Set up the codec context */
340 c
= get_codec_from_stream(st
);
341 c
->codec_id
= codec_id
;
342 c
->codec_type
= CODEC_TYPE_VIDEO
;
345 /* Get some values from the current render settings */
350 #ifdef FFMPEG_CODEC_TIME_BASE
351 /* FIXME: Really bad hack (tm) for NTSC support */
352 if (ffmpeg_type
== FFMPEG_DV
&& G
.scene
->r
.frs_sec
!= 25) {
353 c
->time_base
.den
= 2997;
354 c
->time_base
.num
= 100;
355 } else if ((double) ((int) G
.scene
->r
.frs_sec_base
) ==
356 G
.scene
->r
.frs_sec_base
) {
357 c
->time_base
.den
= G
.scene
->r
.frs_sec
;
358 c
->time_base
.num
= (int) G
.scene
->r
.frs_sec_base
;
360 c
->time_base
.den
= G
.scene
->r
.frs_sec
* 100000;
361 c
->time_base
.num
= ((double) G
.scene
->r
.frs_sec_base
) * 100000;
364 /* FIXME: Really bad hack (tm) for NTSC support */
365 if (ffmpeg_type
== FFMPEG_DV
&& G
.scene
->r
.frs_sec
!= 25) {
366 c
->frame_rate
= 2997;
367 c
->frame_rate_base
= 100;
368 } else if ((double) ((int) G
.scene
->r
.frs_sec_base
) ==
369 G
.scene
->r
.frs_sec_base
) {
370 c
->frame_rate
= G
.scene
->r
.frs_sec
;
371 c
->frame_rate_base
= G
.scene
->r
.frs_sec_base
;
373 c
->frame_rate
= G
.scene
->r
.frs_sec
* 100000;
374 c
->frame_rate_base
= ((double) G
.scene
->r
.frs_sec_base
)*100000;
378 c
->gop_size
= ffmpeg_gop_size
;
379 c
->bit_rate
= ffmpeg_video_bitrate
*1000;
380 c
->rc_max_rate
= G
.scene
->r
.ffcodecdata
.rc_max_rate
*1000;
381 c
->rc_min_rate
= G
.scene
->r
.ffcodecdata
.rc_min_rate
*1000;
382 c
->rc_buffer_size
= G
.scene
->r
.ffcodecdata
.rc_buffer_size
* 1024;
383 c
->rc_initial_buffer_occupancy
384 = G
.scene
->r
.ffcodecdata
.rc_buffer_size
*3/4;
385 c
->rc_buffer_aggressivity
= 1.0;
386 c
->me_method
= ME_EPZS
;
388 codec
= avcodec_find_encoder(c
->codec_id
);
389 if (!codec
) return NULL
;
391 /* Be sure to use the correct pixel format(e.g. RGB, YUV) */
393 if (codec
->pix_fmts
) {
394 c
->pix_fmt
= codec
->pix_fmts
[0];
396 /* makes HuffYUV happy ... */
397 c
->pix_fmt
= PIX_FMT_YUV422P
;
400 if (codec_id
== CODEC_ID_XVID
) {
402 c
->pix_fmt
= PIX_FMT_YUV420P
;
405 if (!strcmp(of
->oformat
->name
, "mp4") ||
406 !strcmp(of
->oformat
->name
, "mov") ||
407 !strcmp(of
->oformat
->name
, "3gp")) {
408 fprintf(stderr
, "Using global header\n");
409 c
->flags
|= CODEC_FLAG_GLOBAL_HEADER
;
412 /* Determine whether we are encoding interlaced material or not */
413 if (G
.scene
->r
.mode
& (1 << 6)) {
414 fprintf(stderr
, "Encoding interlaced video\n");
415 c
->flags
|= CODEC_FLAG_INTERLACED_DCT
;
416 c
->flags
|= CODEC_FLAG_INTERLACED_ME
;
418 c
->sample_aspect_ratio
.num
= G
.scene
->r
.xasp
;
419 c
->sample_aspect_ratio
.den
= G
.scene
->r
.yasp
;
421 if (avcodec_open(c
, codec
) < 0) {
422 error("Couldn't initialize codec");
426 video_buffersize
= 2000000;
427 video_buffer
= (uint8_t*)MEM_mallocN(video_buffersize
,
428 "FFMPEG video buffer");
430 current_frame
= alloc_picture(c
->pix_fmt
, c
->width
, c
->height
);
434 /* Prepare an audio stream for the output file */
436 static AVStream
* alloc_audio_stream(int codec_id
, AVFormatContext
* of
)
442 st
= av_new_stream(of
, 1);
443 if (!st
) return NULL
;
445 c
= get_codec_from_stream(st
);
446 c
->codec_id
= codec_id
;
447 c
->codec_type
= CODEC_TYPE_AUDIO
;
449 c
->sample_rate
= G
.scene
->audio
.mixrate
;
450 c
->bit_rate
= ffmpeg_audio_bitrate
*1000;
452 codec
= avcodec_find_encoder(c
->codec_id
);
454 error("Couldn't find a valid audio codec");
457 if (avcodec_open(c
, codec
) < 0) {
458 error("Couldn't initialize audio codec");
462 /* FIXME: Should be user configurable */
463 if (ffmpeg_type
== FFMPEG_DV
) {
464 /* this is a hack around the poor ffmpeg dv multiplexer. */
465 /* only fixes PAL for now
466 (NTSC is a lot more complicated here...)! */
467 audio_outbuf_size
= 7680;
469 audio_outbuf_size
= 10000;
471 audio_output_buffer
= (uint8_t*)MEM_mallocN(
472 audio_outbuf_size
, "FFMPEG audio encoder input buffer");
474 /* ugly hack for PCM codecs */
476 if (c
->frame_size
<= 1) {
477 audio_input_frame_size
= audio_outbuf_size
/ c
->channels
;
478 switch(c
->codec_id
) {
479 case CODEC_ID_PCM_S16LE
:
480 case CODEC_ID_PCM_S16BE
:
481 case CODEC_ID_PCM_U16LE
:
482 case CODEC_ID_PCM_U16BE
:
483 audio_input_frame_size
>>= 1;
489 audio_input_frame_size
= c
->frame_size
;
492 audio_input_buffer
= (uint8_t*)MEM_mallocN(
493 audio_input_frame_size
* sizeof(short) * c
->channels
,
494 "FFMPEG audio encoder output buffer");
498 /* essential functions -- start, append, end */
500 void start_ffmpeg_impl(struct RenderData
*rd
, int rectx
, int recty
)
502 /* Handle to the output file */
508 ffmpeg_type
= rd
->ffcodecdata
.type
;
509 ffmpeg_codec
= rd
->ffcodecdata
.codec
;
510 ffmpeg_audio_codec
= rd
->ffcodecdata
.audio_codec
;
511 ffmpeg_video_bitrate
= rd
->ffcodecdata
.video_bitrate
;
512 ffmpeg_audio_bitrate
= rd
->ffcodecdata
.audio_bitrate
;
513 ffmpeg_gop_size
= rd
->ffcodecdata
.gop_size
;
514 ffmpeg_multiplex_audio
= rd
->ffcodecdata
.flags
515 & FFMPEG_MULTIPLEX_AUDIO
;
516 ffmpeg_autosplit
= rd
->ffcodecdata
.flags
517 & FFMPEG_AUTOSPLIT_OUTPUT
;
521 /* Determine the correct filename */
522 makeffmpegstring(name
);
523 fprintf(stderr
, "Starting output to %s(ffmpeg)...\n"
524 " Using type=%d, codec=%d, audio_codec=%d,\n"
525 " video_bitrate=%d, audio_bitrate=%d,\n"
526 " gop_size=%d, multiplex=%d, autosplit=%d\n"
527 " render width=%d, render height=%d\n",
528 name
, ffmpeg_type
, ffmpeg_codec
, ffmpeg_audio_codec
,
529 ffmpeg_video_bitrate
, ffmpeg_audio_bitrate
,
530 ffmpeg_gop_size
, ffmpeg_multiplex_audio
,
531 ffmpeg_autosplit
, rectx
, recty
);
533 exts
= get_file_extensions(ffmpeg_type
);
535 G
.afbreek
= 1; /* Abort render */
536 error("No valid formats found");
539 fmt
= guess_format(NULL
, exts
[0], NULL
);
541 G
.afbreek
= 1; /* Abort render */
542 error("No valid formats found");
546 of
= av_alloc_format_context();
549 error("Error opening output file");
554 of
->packet_size
= G
.scene
->r
.ffcodecdata
.mux_packet_size
;
555 if (ffmpeg_multiplex_audio
) {
556 of
->mux_rate
= G
.scene
->r
.ffcodecdata
.mux_rate
;
561 of
->preload
= (int)(0.5*AV_TIME_BASE
);
562 of
->max_delay
= (int)(0.7*AV_TIME_BASE
);
564 snprintf(of
->filename
, sizeof(of
->filename
), "%s", name
);
565 /* set the codec to the user's selection */
566 switch(ffmpeg_type
) {
569 fmt
->video_codec
= ffmpeg_codec
;
572 fmt
->video_codec
= CODEC_ID_DVVIDEO
;
575 fmt
->video_codec
= CODEC_ID_MPEG1VIDEO
;
578 fmt
->video_codec
= CODEC_ID_MPEG2VIDEO
;
581 fmt
->video_codec
= CODEC_ID_H264
;
584 fmt
->video_codec
= CODEC_ID_XVID
;
588 fmt
->video_codec
= CODEC_ID_MPEG4
;
591 if (fmt
->video_codec
== CODEC_ID_DVVIDEO
) {
594 error("Render width has to be 720 pixels for DV!");
597 if (G
.scene
->r
.frs_sec
!= 25 && recty
!= 480) {
599 error("Render height has to be 480 pixels "
604 if (G
.scene
->r
.frs_sec
== 25 && recty
!= 576) {
606 error("Render height has to be 576 pixels "
612 fmt
->audio_codec
= ffmpeg_audio_codec
;
614 if (ffmpeg_type
== FFMPEG_DV
) {
615 fmt
->audio_codec
= CODEC_ID_PCM_S16LE
;
616 if (ffmpeg_multiplex_audio
617 && G
.scene
->audio
.mixrate
!= 48000) {
619 error("FFMPEG only supports 48khz / stereo "
625 video_stream
= alloc_video_stream(fmt
->video_codec
, of
, rectx
, recty
);
628 error("Error initializing video stream");
632 if (ffmpeg_multiplex_audio
) {
633 audio_stream
= alloc_audio_stream(fmt
->audio_codec
, of
);
636 error("Error initializing audio stream");
639 audiostream_play(SFRA
, 0, 1);
641 if (av_set_parameters(of
, NULL
) < 0) {
643 error("Error setting output parameters");
646 if (!(fmt
->flags
& AVFMT_NOFILE
)) {
647 if (url_fopen(&of
->pb
, name
, URL_WRONLY
) < 0) {
649 error("Could not open file for writing");
656 dump_format(of
, 0, name
, 1);
659 /* **********************************************************************
661 ********************************************************************** */
663 /* Get the output filename-- similar to the other output formats */
664 void makeffmpegstring(char* string
) {
666 char txt
[FILE_MAXDIR
+FILE_MAXFILE
];
669 const char ** exts
= get_file_extensions(G
.scene
->r
.ffcodecdata
.type
);
670 const char ** fe
= exts
;
672 if (!string
|| !exts
) return;
674 strcpy(string
, G
.scene
->r
.pic
);
675 BLI_convertstringcode(string
, G
.sce
, G
.scene
->r
.cfra
);
677 BLI_make_existing_file(string
);
681 if ((G
.scene
->r
.ffcodecdata
.flags
& FFMPEG_AUTOSPLIT_OUTPUT
) != 0) {
682 sprintf(autosplit
, "_%03d", ffmpeg_autosplit_count
);
686 if (BLI_strcasecmp(string
+ strlen(string
) - strlen(*fe
),
694 strcat(string
, autosplit
);
695 sprintf(txt
, "%04d_%04d%s", (G
.scene
->r
.sfra
),
696 (G
.scene
->r
.efra
), *exts
);
699 *(string
+ strlen(string
) - strlen(*fe
)) = 0;
700 strcat(string
, autosplit
);
706 void start_ffmpeg(RenderData
*rd
, int rectx
, int recty
)
708 ffmpeg_autosplit_count
= 0;
710 ffmpeg_renderdata
= rd
;
712 start_ffmpeg_impl(rd
, rectx
, recty
);
715 void end_ffmpeg(void);
717 static void write_audio_frames()
721 while (ffmpeg_multiplex_audio
&& !finished
) {
722 double a_pts
= ((double)audio_stream
->pts
.val
723 * audio_stream
->time_base
.num
724 / audio_stream
->time_base
.den
);
725 double v_pts
= ((double)video_stream
->pts
.val
726 * video_stream
->time_base
.num
727 / video_stream
->time_base
.den
);
737 void append_ffmpeg(int frame
, int *pixels
, int rectx
, int recty
)
739 fprintf(stderr
, "Writing frame %i, "
740 "render width=%d, render height=%d\n", frame
,
743 write_audio_frames();
744 write_video_frame(generate_video_frame((unsigned char*) pixels
));
746 if (ffmpeg_autosplit
) {
747 if (url_ftell(&outfile
->pb
) > FFMPEG_AUTOSPLIT_SIZE
) {
749 ffmpeg_autosplit_count
++;
750 start_ffmpeg_impl(ffmpeg_renderdata
,
757 void end_ffmpeg(void)
761 fprintf(stderr
, "Closing ffmpeg...\n");
763 write_audio_frames();
766 av_write_trailer(outfile
);
769 /* Close the video codec */
771 if (video_stream
&& get_codec_from_stream(video_stream
)) {
772 avcodec_close(get_codec_from_stream(video_stream
));
777 /* Close the output file */
779 for (i
= 0; i
< outfile
->nb_streams
; i
++) {
780 if (&outfile
->streams
[i
]) {
781 av_freep(&outfile
->streams
[i
]);
785 /* free the temp buffer */
787 delete_picture(current_frame
);
790 if (outfile
&& outfile
->oformat
) {
791 if (!(outfile
->oformat
->flags
& AVFMT_NOFILE
)) {
792 url_fclose(&outfile
->pb
);
800 MEM_freeN(video_buffer
);
803 if (audio_output_buffer
) {
804 MEM_freeN(audio_output_buffer
);
805 audio_output_buffer
= 0;
807 if (audio_input_buffer
) {
808 MEM_freeN(audio_input_buffer
);
809 audio_input_buffer
= 0;