54 #define M_PI 3.1415926535897931
57 #define STREAM_FRAME_RATE 25
58 #define STREAM_PIX_FMT AV_PIX_FMT_YUV420P
59 #define STREAM_PIX_WORK AV_PIX_FMT_RGB24
93 st = avformat_new_stream(oc, NULL);
95 yCFatal(FFMPEGWRITER,
"Could not alloc stream");
99 c->codec_id = codec_id;
100 c->codec_type = AVMEDIA_TYPE_AUDIO;
104 c->sample_rate = 44100;
111 yCInfo(FFMPEGWRITER,
"Opening audio stream");
118 codec = avcodec_find_encoder(c->codec_id);
120 yCFatal(FFMPEGWRITER,
"Audio codec not found");
124 if (avcodec_open2(c, codec,
nullptr) < 0) {
125 yCFatal(FFMPEGWRITER,
"Could not open codec");
130 tincr = 2 *
M_PI * 110.0 / c->sample_rate;
132 tincr2 = 2 *
M_PI * 110.0 / c->sample_rate / c->sample_rate;
139 if (c->frame_size <= 1) {
141 switch(st->codec->codec_id) {
142 case AV_CODEC_ID_PCM_S16LE:
143 case AV_CODEC_ID_PCM_S16BE:
144 case AV_CODEC_ID_PCM_U16LE:
145 case AV_CODEC_ID_PCM_U16BE:
161 "FRAME SIZE is %d / samples size is %d\n",
174 for(j=0;j<frame_size;j++) {
175 v = (int)(sin(
t) * 10000);
176 for(i = 0; i < nb_channels; i++)
185 frame = av_frame_alloc();
187 yCFatal(FFMPEGWRITER,
"Could not allocate audio frame");
189 frame->nb_samples = c->frame_size;
190 frame->format = c->sample_fmt;
191 frame->channel_layout = c->channel_layout;
192 int buffer_size = av_samples_get_buffer_size(
nullptr, c->channels,
195 if (buffer_size < 0) {
196 yCError(FFMPEGWRITER,
"Could not get sample buffer size");
198 samples = av_malloc(buffer_size);
201 "Could not allocate %d bytes for samples buffer",
205 int ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
206 (
const uint8_t*)
samples, buffer_size, 0);
208 yCFatal(FFMPEGWRITER,
"Could not setup audio frame");
216 av_init_packet(&pkt);
227 av_init_packet(&tmp);
230 pkt.size = avcodec_encode_audio2(c, &tmp, frame, &got_packet);
231 if (tmp.side_data_elems > 0) {
232 for (
int i = 0; i < tmp.side_data_elems; i++) {
233 av_free(tmp.side_data[i].data);
235 av_freep(&tmp.side_data);
236 tmp.side_data_elems = 0;
239 av_frame_free(&frame);
241 pkt.pts= av_rescale_q(c->coded_frame->pts, c->time_base, st->time_base);
242 pkt.flags |= AV_PKT_FLAG_KEY;
243 pkt.stream_index= st->index;
247 if (av_write_frame(oc, &pkt) != 0) {
248 yCFatal(FFMPEGWRITER,
"Error while writing audio frame");
250 yCInfo(FFMPEGWRITER,
"Wrote some audio");
256 yCInfo(FFMPEGWRITER,
"Preparing to write audio (%d left over)",
samples_at);
268 if (remain<avail) { avail = remain; }
269 for (
int i=0; i<avail; i++) {
281 av_init_packet(&pkt);
289 av_init_packet(&tmp);
292 pkt.size = avcodec_encode_audio2(c, &tmp, frame, &got_packet);
293 if (tmp.side_data_elems > 0) {
294 for (
int i = 0; i < tmp.side_data_elems; i++) {
295 av_free(tmp.side_data[i].data);
297 av_freep(&tmp.side_data);
298 tmp.side_data_elems = 0;
301 av_frame_free(&frame);
303 pkt.pts= av_rescale_q(c->coded_frame->pts, c->time_base,
306 yCTrace(FFMPEGWRITER,
"(%d)", pkt.size);
308 pkt.flags |= AV_PKT_FLAG_KEY;
311 pkt.stream_index= st->index;
317 if (av_write_frame(oc, &pkt) != 0) {
318 yCFatal(FFMPEGWRITER,
"Error while writing audio frame");
323 yCInfo(FFMPEGWRITER,
" wrote audio\n");
328 avcodec_close(st->codec);
340 int w,
int h,
int framerate)
345 st = avformat_new_stream(oc, NULL);
347 yCFatal(FFMPEGWRITER,
"Could not alloc stream");
351 c->codec_id = codec_id;
352 c->codec_type = AVMEDIA_TYPE_VIDEO;
355 c->bit_rate = 400000;
363 c->time_base.den = framerate;
364 c->time_base.num = 1;
367 if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
371 if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO){
378 if(!strcmp(oc->oformat->name,
"mp4") || !strcmp(oc->oformat->name,
"mov") || !strcmp(oc->oformat->name,
"3gp"))
379 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
388 uint8_t *picture_buf;
391 picture = av_frame_alloc();
394 size = avpicture_get_size((AVPixelFormat)pix_fmt, width, height);
395 picture_buf = (uint8_t*)av_malloc(size);
400 avpicture_fill((AVPicture *)picture, picture_buf,
401 (AVPixelFormat)pix_fmt, width, height);
405 void FfmpegWriter::open_video(AVFormatContext *oc, AVStream *st)
407 yCInfo(FFMPEGWRITER,
"Opening video stream");
414 codec = avcodec_find_encoder(c->codec_id);
416 yCFatal(FFMPEGWRITER,
"Video codec not found");
420 if (avcodec_open2(c, codec,
nullptr) < 0) {
421 yCFatal(FFMPEGWRITER,
"Could not open codec");
424 video_outbuf =
nullptr;
431 video_outbuf_size = 200000;
432 video_outbuf = (uint8_t*)av_malloc(video_outbuf_size);
437 yCFatal(FFMPEGWRITER,
"Could not allocate picture");
443 tmp_picture =
nullptr;
444 if (c->pix_fmt != AV_PIX_FMT_RGB24) {
445 tmp_picture =
alloc_picture(AV_PIX_FMT_RGB24, c->width, c->height);
447 yCFatal(FFMPEGWRITER,
"Could not allocate temporary picture");
457 for(y=0;y<height;y++) {
458 for(x=0;x<width;x++) {
459 int base = y*(width*3);
460 pict->data[0][base + x*3] = img.
safePixel(x,y).
r;
461 pict->data[0][base +x*3+1] = img.
safePixel(x,y).
g;
462 pict->data[0][base +x*3+2] = img.
safePixel(x,y).
b;
468 void FfmpegWriter::write_video_frame(AVFormatContext *oc, AVStream *st,
476 if (c->pix_fmt != AV_PIX_FMT_RGB24) {
477 fill_rgb_image(tmp_picture, frame_count, c->width, c->height, img);
479 (AVPicture *)tmp_picture, AV_PIX_FMT_RGB24,
480 c->width, c->height);
488 av_init_packet(&tmp);
489 tmp.data = video_outbuf;
490 tmp.size = video_outbuf_size;
491 out_size = avcodec_encode_video2(c, &tmp, picture, &got_packet);
492 if (tmp.side_data_elems > 0) {
493 for (
int i = 0; i < tmp.side_data_elems; i++) {
494 av_free(tmp.side_data[i].data);
496 av_freep(&tmp.side_data);
497 tmp.side_data_elems = 0;
502 av_init_packet(&pkt);
504 pkt.pts= av_rescale_q(c->coded_frame->pts, c->time_base, st->time_base);
505 if(c->coded_frame->key_frame)
506 pkt.flags |= AV_PKT_FLAG_KEY;
507 pkt.stream_index= st->index;
508 pkt.data= video_outbuf;
525 ret = av_write_frame(oc, &pkt);
531 yCFatal(FFMPEGWRITER,
"Error while writing video frame");
536 void FfmpegWriter::close_video(AVFormatContext *oc, AVStream *st)
538 avcodec_close(st->codec);
539 av_free(picture->data[0]);
542 av_free(tmp_picture->data[0]);
543 av_free(tmp_picture);
545 av_free(video_outbuf);
556 "ffmpeg libavcodec version number %d.%d.%d",
557 LIBAVCODEC_VERSION_MAJOR,
558 LIBAVCODEC_VERSION_MINOR,
559 LIBAVCODEC_VERSION_MICRO);
562 savedConfig.fromString(config.
toString());
565 return delayedOpen(config);
573 "width of image (must be even)").asInt32();
575 "height of image (must be even)").asInt32();
576 int framerate = config.
check(
"framerate",
Value(30),
577 "baseline images per second").asInt32();
581 bool audio = config.
check(
"audio",
"should audio be included");
583 sample_rate = config.
check(
"sample_rate",
Value(44100),
584 "audio samples per second").asInt32();
586 "audio samples per second").asInt32();
589 filename = config.
check(
"out",
Value(
"movie.avi"),
590 "name of movie to write").asString();
604 fmt = av_guess_format(
nullptr, filename.c_str(),
nullptr);
606 yCInfo(FFMPEGWRITER,
"Could not deduce output format from file extension: using MPEG.");
607 fmt = av_guess_format(
"mpeg",
nullptr,
nullptr);
610 yCFatal(FFMPEGWRITER,
"Could not find suitable output format");
614 oc = avformat_alloc_context();
616 yCFatal(FFMPEGWRITER,
"Memory error");
619 snprintf(oc->filename,
sizeof(oc->filename),
"%s", filename.c_str());
625 if (fmt->video_codec != AV_CODEC_ID_NONE) {
630 yCInfo(FFMPEGWRITER,
"Adding audio %dx%d", sample_rate, channels);
631 if (fmt->audio_codec != AV_CODEC_ID_NONE) {
633 if (audio_st!=
nullptr) {
634 AVCodecContext *c = audio_st->codec;
635 c->sample_rate = sample_rate;
636 c->channels = channels;
638 yCError(FFMPEGWRITER,
"Failed to add audio");
641 yCWarning(FFMPEGWRITER,
"No audio codec available");
644 yCInfo(FFMPEGWRITER,
"Skipping audio");
647 av_dump_format(oc, 0, filename.c_str(), 1);
652 open_video(oc, video_st);
659 if (!(fmt->flags & AVFMT_NOFILE)) {
660 if (avio_open(&oc->pb, filename.c_str(), AVIO_FLAG_WRITE) < 0) {
661 yCFatal(FFMPEGWRITER,
"Could not open '%s'", filename.c_str());
666 avformat_write_header(oc, NULL);
672 if (!isOk()) {
return false; }
676 close_video(oc, video_st);
681 av_write_trailer(oc);
684 for(
unsigned int i = 0; i < oc->nb_streams; i++) {
685 av_freep(&oc->streams[i]->codec);
686 av_freep(&oc->streams[i]);
689 if (!(fmt->flags & AVFMT_NOFILE)) {
697 yCInfo(FFMPEGWRITER,
"Closed media file %s", filename.c_str());
704 savedConfig.put(
"width",
Value((
int)image.width()));
705 savedConfig.put(
"height",
Value((
int)image.height()));
707 if (!isOk()) {
return false; }
711 audio_pts = (double)av_stream_get_end_pts(audio_st) * audio_st->time_base.num / audio_st->time_base.den;
716 video_pts = (double)av_stream_get_end_pts(video_st) * video_st->time_base.num / video_st->time_base.den;
720 if (!(audio_st||video_st))
724 if (!video_st || (video_st && audio_st && audio_pts < video_pts)) {
727 write_video_frame(oc, video_st, image);
738 savedConfig.put(
"width",
Value((
int)image.width()));
739 savedConfig.put(
"height",
Value((
int)image.height()));
742 savedConfig.put(
"audio",
Value(1));
744 if (!isOk()) {
return false; }
747 write_video_frame(oc, video_st, image);