diff options
Diffstat (limited to 'source/blender/blenkernel/intern/writeffmpeg.c')
-rw-r--r-- | source/blender/blenkernel/intern/writeffmpeg.c | 143 |
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; } |