Ejemplo n.º 1
0
/* 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);
	}
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
/* 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, "");
}
Ejemplo n.º 4
0
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;
}