Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/writeffmpeg.c')
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c143
1 files changed, 53 insertions, 90 deletions
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 9b1c3b2ddb8..4db53999f10 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -39,19 +39,6 @@
#include <libswscale/swscale.h>
#include <libavcodec/opt.h>
-#if LIBAVFORMAT_VERSION_INT < (49 << 16)
-#define FFMPEG_OLD_FRAME_RATE 1
-#else
-#define FFMPEG_CODEC_IS_POINTER 1
-#define FFMPEG_CODEC_TIME_BASE 1
-#endif
-
-#if LIBAVFORMAT_VERSION_INT >= (52 << 16)
-#define OUTFILE_PB (outfile->pb)
-#else
-#define OUTFILE_PB (&outfile->pb)
-#endif
-
#if defined(WIN32) && (!(defined snprintf))
#define snprintf _snprintf
#endif
@@ -62,7 +49,9 @@
#include "BLI_blenlib.h"
-#include "AUD_C-API.h" /* must be before BKE_sound.h for define */
+#ifdef WITH_AUDASPACE
+# include "AUD_C-API.h"
+#endif
#include "BKE_global.h"
#include "BKE_idprop.h"
@@ -74,6 +63,8 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
+#include "ffmpeg_compat.h"
+
extern void do_init_ffmpeg(void);
static int ffmpeg_type = 0;
@@ -100,7 +91,9 @@ static uint8_t* audio_output_buffer = 0;
static int audio_outbuf_size = 0;
static double audio_time = 0.0f;
+#ifdef WITH_AUDASPACE
static AUD_Device* audio_mixdown_device = 0;
+#endif
#define FFMPEG_AUTOSPLIT_SIZE 2000000000
@@ -114,24 +107,13 @@ static void delete_picture(AVFrame* f)
}
}
-#ifdef FFMPEG_CODEC_IS_POINTER
-static AVCodecContext* get_codec_from_stream(AVStream* stream)
-{
- return stream->codec;
-}
-#else
-static AVCodecContext* get_codec_from_stream(AVStream* stream)
-{
- return &stream->codec;
-}
-#endif
-
+#ifdef WITH_AUDASPACE
static int write_audio_frame(void)
{
AVCodecContext* c = NULL;
AVPacket pkt;
- c = get_codec_from_stream(audio_stream);
+ c = audio_stream->codec;
av_init_packet(&pkt);
pkt.size = 0;
@@ -153,23 +135,22 @@ static int write_audio_frame(void)
if(c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE)
{
-#ifdef FFMPEG_CODEC_TIME_BASE
pkt.pts = av_rescale_q(c->coded_frame->pts,
- c->time_base, audio_stream->time_base);
-#else
- pkt.pts = c->coded_frame->pts;
-#endif
+ c->time_base, audio_stream->time_base);
fprintf(stderr, "Audio Frame PTS: %d\n", (int)pkt.pts);
}
pkt.stream_index = audio_stream->index;
- pkt.flags |= PKT_FLAG_KEY;
+
+ pkt.flags |= AV_PKT_FLAG_KEY;
+
if (av_interleaved_write_frame(outfile, &pkt) != 0) {
fprintf(stderr, "Error writing audio packet!\n");
return -1;
}
return 0;
}
+#endif // #ifdef WITH_AUDASPACE
/* Allocate a temporary frame */
static AVFrame* alloc_picture(int pix_fmt, int width, int height)
@@ -263,10 +244,10 @@ static int write_video_frame(RenderData *rd, AVFrame* frame, ReportList *reports
{
int outsize = 0;
int ret, success= 1;
- AVCodecContext* c = get_codec_from_stream(video_stream);
-#ifdef FFMPEG_CODEC_TIME_BASE
+ AVCodecContext* c = video_stream->codec;
+
frame->pts = rd->cfra - rd->sfra;
-#endif
+
if (rd->mode & R_FIELDS) {
frame->top_field_first = ((rd->mode & R_ODDFIELD) != 0);
}
@@ -278,19 +259,15 @@ static int write_video_frame(RenderData *rd, AVFrame* frame, ReportList *reports
av_init_packet(&packet);
if (c->coded_frame->pts != AV_NOPTS_VALUE) {
-#ifdef FFMPEG_CODEC_TIME_BASE
packet.pts = av_rescale_q(c->coded_frame->pts,
c->time_base,
video_stream->time_base);
-#else
- packet.pts = c->coded_frame->pts;
-#endif
fprintf(stderr, "Video Frame PTS: %d\n", (int)packet.pts);
} else {
fprintf(stderr, "Video Frame PTS: not set\n");
}
if (c->coded_frame->key_frame)
- packet.flags |= PKT_FLAG_KEY;
+ packet.flags |= AV_PKT_FLAG_KEY;
packet.stream_index = video_stream->index;
packet.data = video_buffer;
packet.size = outsize;
@@ -312,7 +289,7 @@ static AVFrame* generate_video_frame(uint8_t* pixels, ReportList *reports)
{
uint8_t* rendered_frame;
- AVCodecContext* c = get_codec_from_stream(video_stream);
+ AVCodecContext* c = video_stream->codec;
int width = c->width;
int height = c->height;
AVFrame* rgb_frame;
@@ -396,7 +373,7 @@ static void set_ffmpeg_property_option(AVCodecContext* c, IDProperty * prop)
switch(prop->type) {
case IDP_STRING:
fprintf(stderr, "%s.\n", IDP_String(prop));
- rv = av_set_string(c, prop->name, IDP_String(prop));
+ av_set_string3(c, prop->name, IDP_String(prop), 1, &rv);
break;
case IDP_FLOAT:
fprintf(stderr, "%g.\n", IDP_Float(prop));
@@ -407,7 +384,7 @@ static void set_ffmpeg_property_option(AVCodecContext* c, IDProperty * prop)
if (param) {
if (IDP_Int(prop)) {
- rv = av_set_string(c, name, param);
+ av_set_string3(c, name, param, 1, &rv);
} else {
return;
}
@@ -459,9 +436,9 @@ static AVStream* alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
/* Set up the codec context */
- c = get_codec_from_stream(st);
+ c = st->codec;
c->codec_id = codec_id;
- c->codec_type = CODEC_TYPE_VIDEO;
+ c->codec_type = AVMEDIA_TYPE_VIDEO;
/* Get some values from the current render settings */
@@ -469,7 +446,6 @@ static AVStream* alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
c->width = rectx;
c->height = recty;
-#ifdef FFMPEG_CODEC_TIME_BASE
/* FIXME: Really bad hack (tm) for NTSC support */
if (ffmpeg_type == FFMPEG_DV && rd->frs_sec != 25) {
c->time_base.den = 2997;
@@ -482,20 +458,6 @@ static AVStream* alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
c->time_base.den = rd->frs_sec * 100000;
c->time_base.num = ((double) rd->frs_sec_base) * 100000;
}
-#else
- /* FIXME: Really bad hack (tm) for NTSC support */
- if (ffmpeg_type == FFMPEG_DV && rd->frs_sec != 25) {
- c->frame_rate = 2997;
- c->frame_rate_base = 100;
- } else if ((double) ((int) rd->frs_sec_base) ==
- rd->frs_sec_base) {
- c->frame_rate = rd->frs_sec;
- c->frame_rate_base = rd->frs_sec_base;
- } else {
- c->frame_rate = rd->frs_sec * 100000;
- c->frame_rate_base = ((double) rd->frs_sec_base)*100000;
- }
-#endif
c->gop_size = ffmpeg_gop_size;
c->bit_rate = ffmpeg_video_bitrate*1000;
@@ -519,7 +481,7 @@ static AVStream* alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
c->pix_fmt = PIX_FMT_YUV422P;
}
- if (codec_id == CODEC_ID_XVID) {
+ if (ffmpeg_type == FFMPEG_XVID) {
/* arghhhh ... */
c->pix_fmt = PIX_FMT_YUV420P;
c->codec_tag = (('D'<<24) + ('I'<<16) + ('V'<<8) + 'X');
@@ -586,9 +548,9 @@ static AVStream* alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
st = av_new_stream(of, 1);
if (!st) return NULL;
- c = get_codec_from_stream(st);
+ c = st->codec;
c->codec_id = codec_id;
- c->codec_type = CODEC_TYPE_AUDIO;
+ c->codec_type = AVMEDIA_TYPE_AUDIO;
c->sample_rate = rd->ffcodecdata.audio_mixrate;
c->bit_rate = ffmpeg_audio_bitrate*1000;
@@ -666,13 +628,13 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
BKE_report(reports, RPT_ERROR, "No valid formats found.");
return 0;
}
- fmt = guess_format(NULL, exts[0], NULL);
+ fmt = av_guess_format(NULL, exts[0], NULL);
if (!fmt) {
BKE_report(reports, RPT_ERROR, "No valid formats found.");
return 0;
}
- of = av_alloc_format_context();
+ of = avformat_alloc_context();
if (!of) {
BKE_report(reports, RPT_ERROR, "Error opening output file");
return 0;
@@ -713,7 +675,7 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
fmt->video_codec = CODEC_ID_H264;
break;
case FFMPEG_XVID:
- fmt->video_codec = CODEC_ID_XVID;
+ fmt->video_codec = CODEC_ID_MPEG4;
break;
case FFMPEG_FLV:
fmt->video_codec = CODEC_ID_FLV1;
@@ -772,7 +734,7 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
return 0;
}
if (!(fmt->flags & AVFMT_NOFILE)) {
- if (url_fopen(&of->pb, name, URL_WRONLY) < 0) {
+ if (avio_open(&of->pb, name, AVIO_FLAG_WRITE) < 0) {
BKE_report(reports, RPT_ERROR, "Could not open file for writing.");
return 0;
}
@@ -780,7 +742,7 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
av_write_header(of);
outfile = of;
- dump_format(of, 0, name, 1);
+ av_dump_format(of, 0, name, 1);
return 1;
}
@@ -807,7 +769,7 @@ void flush_ffmpeg(void)
int outsize = 0;
int ret = 0;
- AVCodecContext* c = get_codec_from_stream(video_stream);
+ AVCodecContext* c = video_stream->codec;
/* get the delayed frames */
while (1) {
AVPacket packet;
@@ -822,19 +784,15 @@ void flush_ffmpeg(void)
break;
}
if (c->coded_frame->pts != AV_NOPTS_VALUE) {
-#ifdef FFMPEG_CODEC_TIME_BASE
packet.pts = av_rescale_q(c->coded_frame->pts,
c->time_base,
video_stream->time_base);
-#else
- packet.pts = c->coded_frame->pts;
-#endif
fprintf(stderr, "Video Frame PTS: %d\n", (int)packet.pts);
} else {
fprintf(stderr, "Video Frame PTS: not set\n");
}
if (c->coded_frame->key_frame) {
- packet.flags |= PKT_FLAG_KEY;
+ packet.flags |= AV_PKT_FLAG_KEY;
}
packet.stream_index = video_stream->index;
packet.data = video_buffer;
@@ -845,7 +803,7 @@ void flush_ffmpeg(void)
break;
}
}
- avcodec_flush_buffers(get_codec_from_stream(video_stream));
+ avcodec_flush_buffers(video_stream->codec);
}
/* **********************************************************************
@@ -899,22 +857,23 @@ int start_ffmpeg(struct Scene *scene, RenderData *rd, int rectx, int recty, Repo
ffmpeg_autosplit_count = 0;
success = start_ffmpeg_impl(rd, rectx, recty, reports);
-
+#ifdef WITH_AUDASPACE
if(audio_stream)
{
- AVCodecContext* c = get_codec_from_stream(audio_stream);
+ AVCodecContext* c = audio_stream->codec;
AUD_DeviceSpecs specs;
specs.channels = c->channels;
specs.format = AUD_FORMAT_S16;
specs.rate = rd->ffcodecdata.audio_mixrate;
audio_mixdown_device = sound_mixdown(scene, specs, rd->sfra, rd->ffcodecdata.audio_volume);
}
-
+#endif
return success;
}
void end_ffmpeg(void);
+#ifdef WITH_AUDASPACE
static void write_audio_frames(double to_pts)
{
int finished = 0;
@@ -926,6 +885,7 @@ static void write_audio_frames(double to_pts)
}
}
}
+#endif
int append_ffmpeg(RenderData *rd, int frame, int *pixels, int rectx, int recty, ReportList *reports)
{
@@ -945,7 +905,7 @@ int append_ffmpeg(RenderData *rd, int frame, int *pixels, int rectx, int recty,
success= (avframe && write_video_frame(rd, avframe, reports));
if (ffmpeg_autosplit) {
- if (url_ftell(OUTFILE_PB) > FFMPEG_AUTOSPLIT_SIZE) {
+ if (avio_tell(outfile->pb) > FFMPEG_AUTOSPLIT_SIZE) {
end_ffmpeg();
ffmpeg_autosplit_count++;
success &= start_ffmpeg_impl(rd, rectx, recty, reports);
@@ -953,8 +913,9 @@ int append_ffmpeg(RenderData *rd, int frame, int *pixels, int rectx, int recty,
}
}
+#ifdef WITH_AUDASPACE
write_audio_frames((frame - rd->sfra) / (((double)rd->frs_sec) / rd->frs_sec_base));
-
+#endif
return success;
}
@@ -968,13 +929,15 @@ void end_ffmpeg(void)
write_audio_frames();
}*/
+#ifdef WITH_AUDASPACE
if(audio_mixdown_device)
{
AUD_closeReadDevice(audio_mixdown_device);
audio_mixdown_device = 0;
}
-
- if (video_stream && get_codec_from_stream(video_stream)) {
+#endif
+
+ if (video_stream && video_stream->codec) {
fprintf(stderr, "Flushing delayed frames...\n");
flush_ffmpeg ();
}
@@ -985,8 +948,8 @@ void end_ffmpeg(void)
/* Close the video codec */
- if (video_stream && get_codec_from_stream(video_stream)) {
- avcodec_close(get_codec_from_stream(video_stream));
+ if (video_stream && video_stream->codec) {
+ avcodec_close(video_stream->codec);
printf("zero video stream %p\n", video_stream);
video_stream = 0;
}
@@ -1007,7 +970,7 @@ void end_ffmpeg(void)
}
if (outfile && outfile->oformat) {
if (!(outfile->oformat->flags & AVFMT_NOFILE)) {
- url_fclose(OUTFILE_PB);
+ avio_close(outfile->pb);
}
}
if (outfile) {
@@ -1101,12 +1064,12 @@ IDProperty *ffmpeg_property_add(RenderData *rd, char * type, int opt_index, int
switch (o->type) {
case FF_OPT_TYPE_INT:
case FF_OPT_TYPE_INT64:
- val.i = o->default_val;
+ val.i = FFMPEG_DEF_OPT_VAL_INT(o);
idp_type = IDP_INT;
break;
case FF_OPT_TYPE_DOUBLE:
case FF_OPT_TYPE_FLOAT:
- val.f = o->default_val;
+ val.f = FFMPEG_DEF_OPT_VAL_DOUBLE(o);
idp_type = IDP_FLOAT;
break;
case FF_OPT_TYPE_STRING:
@@ -1314,7 +1277,7 @@ void ffmpeg_set_preset(RenderData *rd, int preset)
case FFMPEG_PRESET_XVID:
if(preset == FFMPEG_PRESET_XVID) {
rd->ffcodecdata.type = FFMPEG_AVI;
- rd->ffcodecdata.codec = CODEC_ID_XVID;
+ rd->ffcodecdata.codec = CODEC_ID_MPEG4;
}
else if(preset == FFMPEG_PRESET_THEORA) {
rd->ffcodecdata.type = FFMPEG_OGG; // XXX broken
@@ -1357,7 +1320,7 @@ void ffmpeg_verify_image_type(RenderData *rd)
}
}
else if(rd->imtype == R_XVID) {
- if(rd->ffcodecdata.codec != CODEC_ID_XVID) {
+ if(rd->ffcodecdata.codec != CODEC_ID_MPEG4) {
ffmpeg_set_preset(rd, FFMPEG_PRESET_XVID);
audio= 1;
}