/* Get the output filename-- similar to the other output formats */ void BKE_ffmpeg_filepath_get(char *string, RenderData *rd) { char autosplit[20]; const char **exts = get_file_extensions(rd->ffcodecdata.type); const char **fe = exts; if (!string || !exts) return; strcpy(string, rd->pic); BLI_path_abs(string, G.main->name); BLI_make_existing_file(string); autosplit[0] = 0; if ((rd->ffcodecdata.flags & FFMPEG_AUTOSPLIT_OUTPUT) != 0) { sprintf(autosplit, "_%03d", ffmpeg_autosplit_count); } if (rd->scemode & R_EXTENSION) { while (*fe) { if (BLI_strcasecmp(string + strlen(string) - strlen(*fe), *fe) == 0) { break; } fe++; } if (*fe == NULL) { strcat(string, autosplit); BLI_path_frame_range(string, rd->sfra, rd->efra, 4); strcat(string, *exts); } else { *(string + strlen(string) - strlen(*fe)) = 0; strcat(string, autosplit); strcat(string, *fe); } } else { if (BLI_path_frame_check_chars(string)) { BLI_path_frame_range(string, rd->sfra, rd->efra, 4); } strcat(string, autosplit); } }
static int start_ffmpeg_impl(FFMpegContext *context, struct RenderData *rd, int rectx, int recty, const char *suffix, ReportList *reports) { /* Handle to the output file */ AVFormatContext *of; AVOutputFormat *fmt; AVDictionary *opts = NULL; char name[256], error[1024]; const char **exts; context->ffmpeg_type = rd->ffcodecdata.type; context->ffmpeg_codec = rd->ffcodecdata.codec; context->ffmpeg_audio_codec = rd->ffcodecdata.audio_codec; context->ffmpeg_video_bitrate = rd->ffcodecdata.video_bitrate; context->ffmpeg_audio_bitrate = rd->ffcodecdata.audio_bitrate; context->ffmpeg_gop_size = rd->ffcodecdata.gop_size; context->ffmpeg_autosplit = rd->ffcodecdata.flags & FFMPEG_AUTOSPLIT_OUTPUT; /* Determine the correct filename */ ffmpeg_filepath_get(context, name, rd, context->ffmpeg_preview, suffix); PRINT("Starting output to %s(ffmpeg)...\n" " Using type=%d, codec=%d, audio_codec=%d,\n" " video_bitrate=%d, audio_bitrate=%d,\n" " gop_size=%d, autosplit=%d\n" " render width=%d, render height=%d\n", name, context->ffmpeg_type, context->ffmpeg_codec, context->ffmpeg_audio_codec, context->ffmpeg_video_bitrate, context->ffmpeg_audio_bitrate, context->ffmpeg_gop_size, context->ffmpeg_autosplit, rectx, recty); exts = get_file_extensions(context->ffmpeg_type); if (!exts) { BKE_report(reports, RPT_ERROR, "No valid formats found"); return 0; } fmt = av_guess_format(NULL, exts[0], NULL); if (!fmt) { BKE_report(reports, RPT_ERROR, "No valid formats found"); return 0; } of = avformat_alloc_context(); if (!of) { BKE_report(reports, RPT_ERROR, "Error opening output file"); return 0; } of->oformat = fmt; of->packet_size = rd->ffcodecdata.mux_packet_size; if (context->ffmpeg_audio_codec != AV_CODEC_ID_NONE) { ffmpeg_dict_set_int(&opts, "muxrate", rd->ffcodecdata.mux_rate); } else { av_dict_set(&opts, "muxrate", "0", 0); } ffmpeg_dict_set_int(&opts, "preload", (int)(0.5 * AV_TIME_BASE)); of->max_delay = (int)(0.7 * AV_TIME_BASE); fmt->audio_codec = context->ffmpeg_audio_codec; BLI_strncpy(of->filename, name, sizeof(of->filename)); /* set the codec to the user's selection */ switch (context->ffmpeg_type) { case FFMPEG_AVI: case FFMPEG_MOV: case FFMPEG_MKV: fmt->video_codec = context->ffmpeg_codec; break; case FFMPEG_OGG: fmt->video_codec = AV_CODEC_ID_THEORA; break; case FFMPEG_DV: fmt->video_codec = AV_CODEC_ID_DVVIDEO; break; case FFMPEG_MPEG1: fmt->video_codec = AV_CODEC_ID_MPEG1VIDEO; break; case FFMPEG_MPEG2: fmt->video_codec = AV_CODEC_ID_MPEG2VIDEO; break; case FFMPEG_H264: fmt->video_codec = AV_CODEC_ID_H264; break; case FFMPEG_XVID: fmt->video_codec = AV_CODEC_ID_MPEG4; break; case FFMPEG_FLV: fmt->video_codec = AV_CODEC_ID_FLV1; break; case FFMPEG_MPEG4: default: fmt->video_codec = context->ffmpeg_codec; break; } if (fmt->video_codec == AV_CODEC_ID_DVVIDEO) { if (rectx != 720) { BKE_report(reports, RPT_ERROR, "Render width has to be 720 pixels for DV!"); return 0; } if (rd->frs_sec != 25 && recty != 480) { BKE_report(reports, RPT_ERROR, "Render height has to be 480 pixels for DV-NTSC!"); return 0; } if (rd->frs_sec == 25 && recty != 576) { BKE_report(reports, RPT_ERROR, "Render height has to be 576 pixels for DV-PAL!"); return 0; } } if (context->ffmpeg_type == FFMPEG_DV) { fmt->audio_codec = AV_CODEC_ID_PCM_S16LE; if (context->ffmpeg_audio_codec != AV_CODEC_ID_NONE && rd->ffcodecdata.audio_mixrate != 48000 && rd->ffcodecdata.audio_channels != 2) { BKE_report(reports, RPT_ERROR, "FFMPEG only supports 48khz / stereo audio for DV!"); av_dict_free(&opts); return 0; } } if (fmt->video_codec != AV_CODEC_ID_NONE) { context->video_stream = alloc_video_stream(context, rd, fmt->video_codec, of, rectx, recty, error, sizeof(error)); PRINT("alloc video stream %p\n", context->video_stream); if (!context->video_stream) { if (error[0]) BKE_report(reports, RPT_ERROR, error); else BKE_report(reports, RPT_ERROR, "Error initializing video stream"); av_dict_free(&opts); return 0; } } if (context->ffmpeg_audio_codec != AV_CODEC_ID_NONE) { context->audio_stream = alloc_audio_stream(context, rd, fmt->audio_codec, of, error, sizeof(error)); if (!context->audio_stream) { if (error[0]) BKE_report(reports, RPT_ERROR, error); else BKE_report(reports, RPT_ERROR, "Error initializing audio stream"); av_dict_free(&opts); return 0; } } if (!(fmt->flags & AVFMT_NOFILE)) { if (avio_open(&of->pb, name, AVIO_FLAG_WRITE) < 0) { BKE_report(reports, RPT_ERROR, "Could not open file for writing"); av_dict_free(&opts); return 0; } } if (avformat_write_header(of, NULL) < 0) { BKE_report(reports, RPT_ERROR, "Could not initialize streams, probably unsupported codec combination"); av_dict_free(&opts); avio_close(of->pb); return 0; } context->outfile = of; av_dump_format(of, 0, name, 1); av_dict_free(&opts); return 1; }
/* Get the output filename-- similar to the other output formats */ static void ffmpeg_filepath_get(FFMpegContext *context, char *string, RenderData *rd, bool preview, const char *suffix) { char autosplit[20]; const char **exts = get_file_extensions(rd->ffcodecdata.type); const char **fe = exts; int sfra, efra; if (!string || !exts) return; if (preview) { sfra = rd->psfra; efra = rd->pefra; } else { sfra = rd->sfra; efra = rd->efra; } strcpy(string, rd->pic); BLI_path_abs(string, G.main->name); BLI_make_existing_file(string); autosplit[0] = 0; if ((rd->ffcodecdata.flags & FFMPEG_AUTOSPLIT_OUTPUT) != 0) { if (context) { sprintf(autosplit, "_%03d", context->ffmpeg_autosplit_count); } } if (rd->scemode & R_EXTENSION) { while (*fe) { if (BLI_strcasecmp(string + strlen(string) - strlen(*fe), *fe) == 0) { break; } fe++; } if (*fe == NULL) { strcat(string, autosplit); BLI_path_frame_range(string, sfra, efra, 4); strcat(string, *exts); } else { *(string + strlen(string) - strlen(*fe)) = 0; strcat(string, autosplit); strcat(string, *fe); } } else { if (BLI_path_frame_check_chars(string)) { BLI_path_frame_range(string, sfra, efra, 4); } strcat(string, autosplit); } BLI_path_suffix(string, FILE_MAX, suffix, ""); }
static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, ReportList *reports) { /* Handle to the output file */ AVFormatContext* of; AVOutputFormat* fmt; char name[256]; const char ** exts; ffmpeg_type = rd->ffcodecdata.type; ffmpeg_codec = rd->ffcodecdata.codec; ffmpeg_audio_codec = rd->ffcodecdata.audio_codec; ffmpeg_video_bitrate = rd->ffcodecdata.video_bitrate; ffmpeg_audio_bitrate = rd->ffcodecdata.audio_bitrate; ffmpeg_gop_size = rd->ffcodecdata.gop_size; ffmpeg_autosplit = rd->ffcodecdata.flags & FFMPEG_AUTOSPLIT_OUTPUT; do_init_ffmpeg(); /* Determine the correct filename */ filepath_ffmpeg(name, rd); fprintf(stderr, "Starting output to %s(ffmpeg)...\n" " Using type=%d, codec=%d, audio_codec=%d,\n" " video_bitrate=%d, audio_bitrate=%d,\n" " gop_size=%d, autosplit=%d\n" " render width=%d, render height=%d\n", name, ffmpeg_type, ffmpeg_codec, ffmpeg_audio_codec, ffmpeg_video_bitrate, ffmpeg_audio_bitrate, ffmpeg_gop_size, ffmpeg_autosplit, rectx, recty); exts = get_file_extensions(ffmpeg_type); if (!exts) { BKE_report(reports, RPT_ERROR, "No valid formats found."); return 0; } fmt = av_guess_format(NULL, exts[0], NULL); if (!fmt) { BKE_report(reports, RPT_ERROR, "No valid formats found."); return 0; } of = avformat_alloc_context(); if (!of) { BKE_report(reports, RPT_ERROR, "Error opening output file"); return 0; } of->oformat = fmt; of->packet_size= rd->ffcodecdata.mux_packet_size; if (ffmpeg_audio_codec != CODEC_ID_NONE) { of->mux_rate = rd->ffcodecdata.mux_rate; } else { of->mux_rate = 0; } of->preload = (int)(0.5*AV_TIME_BASE); of->max_delay = (int)(0.7*AV_TIME_BASE); fmt->audio_codec = ffmpeg_audio_codec; BLI_snprintf(of->filename, sizeof(of->filename), "%s", name); /* set the codec to the user's selection */ switch(ffmpeg_type) { case FFMPEG_AVI: case FFMPEG_MOV: case FFMPEG_MKV: fmt->video_codec = ffmpeg_codec; break; case FFMPEG_OGG: fmt->video_codec = CODEC_ID_THEORA; break; case FFMPEG_DV: fmt->video_codec = CODEC_ID_DVVIDEO; break; case FFMPEG_MPEG1: fmt->video_codec = CODEC_ID_MPEG1VIDEO; break; case FFMPEG_MPEG2: fmt->video_codec = CODEC_ID_MPEG2VIDEO; break; case FFMPEG_H264: fmt->video_codec = CODEC_ID_H264; break; case FFMPEG_XVID: fmt->video_codec = CODEC_ID_MPEG4; break; case FFMPEG_FLV: fmt->video_codec = CODEC_ID_FLV1; break; case FFMPEG_MP3: fmt->audio_codec = CODEC_ID_MP3; case FFMPEG_WAV: fmt->video_codec = CODEC_ID_NONE; break; case FFMPEG_MPEG4: default: fmt->video_codec = CODEC_ID_MPEG4; break; } if (fmt->video_codec == CODEC_ID_DVVIDEO) { if (rectx != 720) { BKE_report(reports, RPT_ERROR, "Render width has to be 720 pixels for DV!"); return 0; } if (rd->frs_sec != 25 && recty != 480) { BKE_report(reports, RPT_ERROR, "Render height has to be 480 pixels for DV-NTSC!"); return 0; } if (rd->frs_sec == 25 && recty != 576) { BKE_report(reports, RPT_ERROR, "Render height has to be 576 pixels for DV-PAL!"); return 0; } } if (ffmpeg_type == FFMPEG_DV) { fmt->audio_codec = CODEC_ID_PCM_S16LE; if (ffmpeg_audio_codec != CODEC_ID_NONE && rd->ffcodecdata.audio_mixrate != 48000 && rd->ffcodecdata.audio_channels != 2) { BKE_report(reports, RPT_ERROR, "FFMPEG only supports 48khz / stereo audio for DV!"); return 0; } } if (fmt->video_codec != CODEC_ID_NONE) { video_stream = alloc_video_stream(rd, fmt->video_codec, of, rectx, recty); printf("alloc video stream %p\n", video_stream); if (!video_stream) { BKE_report(reports, RPT_ERROR, "Error initializing video stream."); return 0; } } if (ffmpeg_audio_codec != CODEC_ID_NONE) { audio_stream = alloc_audio_stream(rd, fmt->audio_codec, of); if (!audio_stream) { BKE_report(reports, RPT_ERROR, "Error initializing audio stream."); return 0; } } if (av_set_parameters(of, NULL) < 0) { BKE_report(reports, RPT_ERROR, "Error setting output parameters."); return 0; } if (!(fmt->flags & AVFMT_NOFILE)) { if (avio_open(&of->pb, name, AVIO_FLAG_WRITE) < 0) { BKE_report(reports, RPT_ERROR, "Could not open file for writing."); return 0; } } if (av_write_header(of) < 0) { BKE_report(reports, RPT_ERROR, "Could not initialize streams. Probably unsupported codec combination."); return 0; } outfile = of; av_dump_format(of, 0, name, 1); return 1; }