1 /* === S Y N F I G ========================================================= */
8 ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 ** Copyright (c) 2008 Paul Wise
10 ** Copyright (c) 2008 Gerco Ballintijn
12 ** This package is free software; you can redistribute it and/or
13 ** modify it under the terms of the GNU General Public License as
14 ** published by the Free Software Foundation; either version 2 of
15 ** the License, or (at your option) any later version.
17 ** This package is distributed in the hope that it will be useful,
18 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 ** General Public License for more details.
23 /* ========================================================================= */
25 /* === H E A D E R S ======================================================= */
27 #define SYNFIG_NO_ANGLE
42 ffmpeg library headers have historically had multiple locations.
43 We should check all of the locations to be more portable.
46 #ifdef HAVE_LIBAVFORMAT_AVFORMAT_H
47 # include <libavformat/avformat.h>
48 #elif defined(HAVE_AVFORMAT_H)
49 # include <avformat.h>
50 #elif defined(HAVE_FFMPEG_AVFORMAT_H)
51 # include <ffmpeg/avformat.h>
54 #ifdef WITH_LIBSWSCALE
55 #ifdef HAVE_LIBSWSCALE_SWSCALE_H
56 # include <libswscale/swscale.h>
57 #elif defined(HAVE_SWSCALE_H)
59 #elif defined(HAVE_FFMPEG_SWSCALE_H)
60 # include <ffmpeg/swscale.h>
66 #include <synfig/general.h>
74 #define snprintf _snprintf
77 /* === U S I N G =========================================================== */
79 using namespace synfig;
83 /* === I N F O ============================================================= */
85 SYNFIG_TARGET_INIT(Target_LibAVCodec);
86 SYNFIG_TARGET_SET_NAME(Target_LibAVCodec,"libav");
87 SYNFIG_TARGET_SET_EXT(Target_LibAVCodec,"avi");
88 SYNFIG_TARGET_SET_VERSION(Target_LibAVCodec,"0.1");
89 SYNFIG_TARGET_SET_CVS_ID(Target_LibAVCodec,"$Id$");
91 /* === C L A S S E S & S T R U C T S ======================================= */
93 bool Target_LibAVCodec::registered = false;
96 //float STREAM_DURATION = 5.0f;
108 int samplerate; //in HZ
109 int samplesize; //in bytes
112 AVFrame *alloc_picture(int pix_fmt, int width, int height)
115 uint8_t *picture_buf;
118 picture = avcodec_alloc_frame();
121 size = avpicture_get_size(pix_fmt, width, height);
122 picture_buf = (uint8_t *)malloc(size);
127 avpicture_fill((AVPicture *)picture, picture_buf,
128 pix_fmt, width, height);
132 void free_picture(AVFrame *pic)
134 av_free(pic->data[0]);
138 //the frame must be RGB24
139 static void convert_surface_frame(AVFrame *pic, const Surface &s, const Gamma &gamma)
142 Surface::const_pen p = s.begin();
153 stride = pic->linesize[0];
155 for(j = 0; j < h; j++, p.inc_y(), ptr += stride)
159 //use convert_color_format instead...
161 const int channels = 3;
163 for(int i = 0; i < w; i++, p.inc_x(), tptr += channels)
167 Color::value_type r = c.get_r();
168 Color::value_type g = c.get_g();
169 Color::value_type b = c.get_b();
170 Color::value_type a = c.get_a();
177 //essentially treats it as if it has a background color of black
179 //we must also clamp the rgb values [0,1]
188 //now scale to range of char [0,255]
189 tptr[0] = (int)(r*255);
190 tptr[1] = (int)(g*255);
191 tptr[2] = (int)(b*255);
197 convert_color_format((unsigned char *)tptr,&p.get_value(),w,PF_RGB,gamma);
203 //Audio Streamer (abstracts the open, write and close operations for audio streams)
211 vector<unsigned char>audiobuffer;
213 int audio_input_frame_size;
215 bool open(AVFormatContext *formatc, AVStream *stream)
217 AVCodecContext *context;
220 context = &stream->codec;
223 codec = avcodec_find_encoder(context->codec_id);
226 synfig::warning("audio-open: could not find codec");
231 if(avcodec_open(context, codec) < 0)
233 synfig::warning("audio-open: could not open codec");
237 /* hardcoded example for generating samples array*/
240 tincr = 2 * M_PI * 110.0 / c->sample_rate;
241 tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;*/
243 audiobuffer.resize(10000);
245 /* ugly hack for PCM codecs (will be removed ASAP with new PCM
246 support to compute the input frame size in samples */
247 if (context->frame_size <= 1) {
248 audio_input_frame_size = audiobuffer.size() / context->channels;
249 switch(stream->codec.codec_id) {
250 case CODEC_ID_PCM_S16LE:
251 case CODEC_ID_PCM_S16BE:
252 case CODEC_ID_PCM_U16LE:
253 case CODEC_ID_PCM_U16BE:
254 audio_input_frame_size >>= 1;
260 audio_input_frame_size = context->frame_size;
264 //samples = (int16_t *)malloc(audio_input_frame_size * 2 * c->channels);
269 bool write_frame(AVFormatContext *formatc, AVStream *stream, void *samples)
272 AVCodecContext *context;
274 context = &stream->codec;
276 //hardcoded in example
277 //must read in from somewhere...
278 //get_audio_frame(samples, audio_input_frame_size, c->channels);
281 const short int*samps=(const short int *)samples; //assuming it's set from somewhere right now
283 size = avcodec_encode_audio(context, &audiobuffer[0], audiobuffer.size(), samps);
285 //write the compressed audio to a file
286 if(av_write_frame(formatc, stream->index, &audiobuffer[0], size) != 0)
288 synfig::warning("audio-write_frame: unable to write the entire audio frame");
295 void close(AVFormatContext *formatc, AVStream *stream)
297 //we may also want to catch delayed frames from here (don't for now)
301 avcodec_close(&stream->codec);
304 //if(samples)av_free(samples);
305 audiobuffer.resize(0);
314 AVFrame *encodable; //for compression and output to a file (in compatible pixel format)
316 vector<unsigned char> videobuffer;
318 bool startedencoding;
320 //int stream_nb_frames;
322 bool open(AVFormatContext *formatc, AVStream *stream)
324 if(!formatc || !stream)
326 synfig::warning("Attempt to open a video codec with a bad format or stream");
332 AVCodecContext *context;
334 //get from inside stream
335 context = stream->codec;
337 //search for desired codec (contained in the stream)
338 codec = avcodec_find_encoder(context->codec_id);
341 synfig::warning("Open_video: could not find desired codec");
345 //try to open the codec
346 if(avcodec_open(context, codec) < 0)
348 synfig::warning("open_video: could not open desired codec");
352 videobuffer.resize(0);
353 if(!(formatc->oformat->flags & AVFMT_RAWPICTURE))
355 //resize buffer to desired buffersize
356 videobuffer.resize(200000); //TODO: need to figure out a good size
359 //allocate the base picture which will be used to encode
360 /*picture = alloc_picture(PIX_FMT_RGBA32, context->width, context->height);
363 synfig::warning("open_video: could not allocate the picture to be encoded");
367 //if our output (rgb) needs to be translated to a different coordinate system, need a temporary picture in that color space
369 /* Should use defaults of RGB
373 PIX_FMT_RGBA32 //stored in cpu endianness (!!!!)
375 (possibly translate directly to required coordinate systems later on... less error)
378 if(context->pix_fmt != PIX_FMT_RGB24)
380 encodable = alloc_picture(context->pix_fmt, context->width, context->height);
383 synfig::warning("open_video: could not allocate encodable picture");
391 //write a frame with the frame passed in
392 bool write_frame(AVFormatContext *formatc, AVStream *stream, AVFrame *pict)
394 if(!formatc || !stream)
396 synfig::warning("Attempt to open a video codec with a bad format or stream");
402 AVCodecContext *context = stream->codec;
405 If pict is invalid (NULL), then we are done compressing frames and we are trying to get
406 the buffer cleared out (or if it's already in the right format) so no transform necessary
410 startedencoding = true;
414 if ( pict && context->pix_fmt != PIX_FMT_RGB24 )
416 //We're using RGBA at the moment, write custom conversion code later (get less accuracy errors)
417 #ifdef WITH_LIBSWSCALE
418 struct SwsContext* img_convert_ctx =
419 sws_getContext(context->width, context->height, PIX_FMT_RGB24,
420 context->width, context->height, context->pix_fmt,
421 SWS_BICUBIC, NULL, NULL, NULL);
423 sws_scale(img_convert_ctx, pict->data, pict->linesize,
425 0, context->height, encodable->data,
426 encodable->linesize);
428 sws_freeContext (img_convert_ctx);
430 img_convert((AVPicture *)encodable, context->pix_fmt,
431 (AVPicture *)pict, PIX_FMT_RGB24,
432 context->width, context->height);
439 av_init_packet(&pkt);
440 pkt.stream_index = stream->index;
441 pkt.data = (uint8_t *)pict;
442 pkt.size = sizeof(AVPicture);
443 if( context->coded_frame )
444 pkt.pts = context->coded_frame->pts;
445 if( context->coded_frame && context->coded_frame->key_frame)
446 pkt.flags |= PKT_FLAG_KEY;
448 //kluge for raw picture format (they said they'd fix)
449 if (formatc->oformat->flags & AVFMT_RAWPICTURE)
451 ret = av_write_frame(formatc, &pkt);
455 //encode our given image
456 size = avcodec_encode_video(context, &videobuffer[0], videobuffer.size(), pict);
458 //if greater than zero we've got stuff to write
461 av_init_packet(&pkt);
462 pkt.stream_index = stream->index;
463 pkt.data = &videobuffer[0];
465 if( context->coded_frame )
466 pkt.pts = context->coded_frame->pts;
467 if( context->coded_frame && context->coded_frame->key_frame)
468 pkt.flags |= PKT_FLAG_KEY;
470 ret = av_write_frame(formatc, &pkt);
472 //error detect - possibly throw later...
475 synfig::warning("write_frame: error while writing video frame");
479 //if 0, it was buffered (if invalid picture we don't have ANY data left)
482 //if we're clearing the buffers and there was no stuff to be written, we're done (like in codec example)
486 startedencoding = false;
496 void close(AVFormatContext */*formatc*/, AVStream *stream)
499 avcodec_close(stream->codec);
503 free_picture(encodable);
507 videobuffer.resize(0);
511 class Target_LibAVCodec::LibAVEncoder
517 AVOutputFormat *format; //reference to global, do not delete
519 AVFormatContext *formatc;
522 //AVStream *audio_st;
533 AVFrame *picture; //for encoding to RGB24 (perhaps RGBA later)
548 //vid.stream_nb_frames = 2; //reasonable default
566 bool Initialize(const char *filename, const char *typestring)
568 //guess if we have a type string, otherwise use filename
571 //formatptr guess_format(type, filename, MIME type)
572 format = guess_format(typestring,NULL,NULL);
576 format = guess_format(NULL, filename, NULL);
581 synfig::warning("Unable to Guess the output, defaulting to mpeg");
582 format = guess_format("mpeg", NULL, NULL);
587 synfig::warning("Unable to find output format");
591 //allocate the output context
592 formatc = (AVFormatContext *)av_mallocz(sizeof(AVFormatContext));
595 synfig::warning("Memory error\n");
598 //set the output format to the one we found
599 formatc->oformat = format;
601 //print the output filename
602 snprintf(formatc->filename, sizeof(formatc->filename), "%s", filename);
609 if(format->video_codec != CODEC_ID_NONE)
611 video_st = add_video_stream(format->video_codec,vInfo);
619 /*if(format->audio_codec != CODEC_ID_NONE)
621 audio_st = add_audio_stream(format->audio_codec,aInfo);
624 //set output parameters: required in ALL cases
626 video_st->codec->time_base= (AVRational){1,vInfo.fps};
627 video_st->codec->width = vInfo.w;
628 video_st->codec->height = vInfo.h;
629 video_st->codec->pix_fmt = PIX_FMT_YUV420P;
631 //dump the formatting information as the file header
632 dump_format(formatc, 0, filename, 1);
634 //open codecs and allocate buffers
637 if(!vid.open(formatc, video_st))
639 synfig::warning("Could not open video encoder");
645 if(!aud.open(formatc, audio_st))
647 synfig::warning("Could not open audio encoder");
653 if(!(format->flags & AVFMT_NOFILE))
655 //use libav's file open function (what does it do differently????)
656 if(url_fopen(&formatc->pb, filename, URL_WRONLY) < 0)
658 synfig::warning("Unable to open file: %s", filename);
663 //allocate the picture to render to
664 //may have to retrieve the width, height from the codec... for resizing...
665 picture = alloc_picture(PIX_FMT_RGB24,vInfo.w,vInfo.h);//video_st->codec.width, video_st->codec.height);
668 synfig::warning("Unable to allocate the temporary AVFrame surface");
673 //vInfo.w = video_st->codec.width;
674 //vInfo.h = video_st->codec.height;
676 //write the stream header
677 av_write_header(formatc);
686 if(picture) free_picture(picture);
688 //do all the clean up file rendering
689 if(formatc && video_st)
691 //want to scan in delayed frames until no longer needed (TODO)
692 if(vid.startedencoding) while( vid.write_frame(formatc, video_st, 0) );
694 //may want to move this... probably to the end of the last frame...
695 av_write_trailer(formatc);
700 vid.close(formatc,video_st);
702 aud.close(formatc,audio_st);*/
704 /* write the trailer, if any */
707 /* free the streams */
708 for(i = 0; i < formatc->nb_streams; i++)
710 av_freep(&formatc->streams[i]);
713 if(!(format->flags & AVFMT_NOFILE))
715 /* close the output file */
716 #if LIBAVFORMAT_VERSION_INT >= (52<<16)
717 url_fclose(formatc->pb);
719 url_fclose(&formatc->pb);
723 /* free the stream */
737 //vid.stream_nb_frames = 2; //reasonable default
743 //create a video output stream
744 AVStream *add_video_stream(int codec_id, const VideoInfo &info)
746 AVCodecContext *context;
749 st = av_new_stream(formatc, 0);
752 synfig::warning("video-add_stream: Unable to allocate stream");
757 context->codec_id = (CodecID)codec_id;
758 context->codec_type = CODEC_TYPE_VIDEO;
760 //PARAMETERS MUST BE PASSED IN SOMEHOW (ANOTHER FUNCTION PARAMETER???)
762 /* resolution must be a multiple of two */
763 context->width = info.w;
764 context->height = info.h;
766 //have another way to input these
767 context->bit_rate = info.bitrate; //TODO: Make dependant on the quality
769 /* frames per second */
770 // FIXME: Port next two lines to recent libavcodec versions
771 //context->frame_rate = info.fps;
772 //context->frame_rate_base = 1;
775 context->mb_decision=FF_MB_DECISION_BITS;
777 context->gop_size = info.fps/4; /* emit one intra frame every twelve frames at most */
779 //HACK: MPEG requires b frames be set... any better way to do this?
780 if (context->codec_id == CODEC_ID_MPEG1VIDEO ||
781 context->codec_id == CODEC_ID_MPEG2VIDEO)
783 /* just for testing, we also add B frames */
784 context->max_b_frames = 2;
790 // add an audio output stream
791 AVStream *add_audio_stream(int codec_id,const AudioInfo &/*aInfo*/)
793 AVCodecContext *context;
796 stream = av_new_stream(formatc, 1);
799 synfig::warning("could not alloc stream");
803 context = stream->codec;
804 context->codec_id = (CodecID)codec_id;
805 context->codec_type = CODEC_TYPE_AUDIO;
807 /* put sample parameters */
808 context->bit_rate = 64000;
809 context->sample_rate = 44100;
810 context->channels = 2;
816 /* === M E T H O D S ======================================================= */
818 Target_LibAVCodec::Target_LibAVCodec(const char *Filename):
828 data = new LibAVEncoder;
831 Target_LibAVCodec::~Target_LibAVCodec()
837 Target_LibAVCodec::set_rend_desc(RendDesc *given_desc)
839 // This is where you can determine how you want stuff
840 // to be rendered! given_desc is the suggestion, and
841 // you need to modify it to suit the needs of the codec.
842 // ie: Making the pixel dimensions divisible by 8, etc...
846 //resize surface (round even)
847 int w = desc.get_w();
848 int h = desc.get_h();
849 Point tl = desc.get_tl();
850 Point br = desc.get_br();
851 Real pw = desc.get_pw();
852 Real ph = desc.get_ph();
854 //resize to the size it should be...
855 //desc.set_subwindow(-offx/2,-offy/2, desc.get_w() - offx?(offx + 8):0, desc.get_h() - offy?(offy + 8):0);
857 //if resolution is broken, change the size... or something
858 //budge to nearest pixel values
881 //may want to round frame rate
882 data->vInfo.fps = (int)floor(desc.get_frame_rate()+0.5);
883 #define MEGABYTES_PER_HOUR(x) (((x)*1024/3600*1024*8)/*/640*w/480*h*/)
884 data->vInfo.bitrate = MEGABYTES_PER_HOUR(400);
885 //data->vInfo.bitrate = 800000; //make customizable somehow
887 desc.set_frame_rate(data->vInfo.fps);
889 data->frame_count = desc.get_frame_start();
890 data->num_frames = desc.get_frame_end()+1; //number of frames should be 1 greater than the last one
892 surface.set_wh(data->vInfo.w,data->vInfo.h);
898 Target_LibAVCodec::end_frame()
900 //AVStream *audio_st = data->audio_st;
901 AVStream *video_st = data->video_st;
903 AVFormatContext *formatc = data->formatc;
905 //double &audio_pts = data->audio_pts;
906 //double &video_pts = data->video_pts;
908 //ignore audio for now
910 audio_pts = (double)audio_st->pts.val * formatc->pts_num / formatc->pts_den;
915 video_pts = (double)video_st->pts.val * formatc->pts_num / formatc->pts_den;
919 //hardcoded crappiness
920 /*if ((!audio_st || audio_pts >= STREAM_DURATION) &&
921 (!video_st || video_pts >= STREAM_DURATION))
924 if(data->frame_count >= data->num_frames) return;
926 //copy the current surface to the buffer
927 if(data->picture)convert_surface_frame(data->picture,surface,gamma());
929 //encode the frame and write it to the file
930 if(!data->vid.write_frame(formatc,video_st,data->picture))
932 synfig::warning("Unable to write a frame");
937 if(data->frame_count >= data->num_frames)
942 /* write interleaved audio and video frames */
943 /*if (!video_st || (video_st && audio_st && audio_pts < video_pts)) {
944 data->aud.write_frame(formatc,audio_st);
946 data->vid.write_frame(formatc,video_st);
951 Target_LibAVCodec::start_frame(synfig::ProgressCallback */*callback*/)
953 //prepare all the color buffer stuff, etc.
959 Target_LibAVCodec::start_scanline(int scanline)
961 return surface[scanline];
963 return 0; // This should kill the render process
967 Target_LibAVCodec::end_scanline()
969 //don't need to do anything until the whole frame is done
973 bool Target_LibAVCodec::init()
975 //hardcoded test for mpeg
976 if(!data->Initialize(filename.c_str(),NULL))
978 synfig::warning("Unable to Initialize the audio video encoders");