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 ======================================================= */
40 ffmpeg library headers have historically had multiple locations.
41 We should check all of the locations to be more portable.
44 #ifdef HAVE_LIBAVFORMAT_AVFORMAT_H
45 # include <libavformat/avformat.h>
46 #elif defined(HAVE_AVFORMAT_H)
47 # include <avformat.h>
48 #elif defined(HAVE_FFMPEG_AVFORMAT_H)
49 # include <ffmpeg/avformat.h>
52 #ifdef WITH_LIBSWSCALE
53 #ifdef HAVE_LIBSWSCALE_SWSCALE_H
54 # include <libswscale/swscale.h>
55 #elif defined(HAVE_SWSCALE_H)
57 #elif defined(HAVE_FFMPEG_SWSCALE_H)
58 # include <ffmpeg/swscale.h>
64 #include <synfig/general.h>
72 #define snprintf _snprintf
75 /* === U S I N G =========================================================== */
77 using namespace synfig;
81 /* === I N F O ============================================================= */
83 SYNFIG_TARGET_INIT(Target_LibAVCodec);
84 SYNFIG_TARGET_SET_NAME(Target_LibAVCodec,"libav");
85 SYNFIG_TARGET_SET_EXT(Target_LibAVCodec,"avi");
86 SYNFIG_TARGET_SET_VERSION(Target_LibAVCodec,"0.1");
87 SYNFIG_TARGET_SET_CVS_ID(Target_LibAVCodec,"$Id$");
89 /* === C L A S S E S & S T R U C T S ======================================= */
91 bool Target_LibAVCodec::registered = false;
94 //float STREAM_DURATION = 5.0f;
106 int samplerate; //in HZ
107 int samplesize; //in bytes
110 AVFrame *alloc_picture(int pix_fmt, int width, int height)
113 uint8_t *picture_buf;
116 picture = avcodec_alloc_frame();
119 size = avpicture_get_size(pix_fmt, width, height);
120 picture_buf = (uint8_t *)malloc(size);
125 avpicture_fill((AVPicture *)picture, picture_buf,
126 pix_fmt, width, height);
130 void free_picture(AVFrame *pic)
132 av_free(pic->data[0]);
136 //the frame must be RGB24
137 static void convert_surface_frame(AVFrame *pic, const Surface &s, const Gamma &gamma)
140 Surface::const_pen p = s.begin();
151 stride = pic->linesize[0];
153 for(j = 0; j < h; j++, p.inc_y(), ptr += stride)
157 //use convert_color_format instead...
159 const int channels = 3;
161 for(int i = 0; i < w; i++, p.inc_x(), tptr += channels)
165 Color::value_type r = c.get_r();
166 Color::value_type g = c.get_g();
167 Color::value_type b = c.get_b();
168 Color::value_type a = c.get_a();
175 //essentially treats it as if it has a background color of black
177 //we must also clamp the rgb values [0,1]
186 //now scale to range of char [0,255]
187 tptr[0] = (int)(r*255);
188 tptr[1] = (int)(g*255);
189 tptr[2] = (int)(b*255);
195 convert_color_format((unsigned char *)tptr,&p.get_value(),w,PF_RGB,gamma);
201 //Audio Streamer (abstracts the open, write and close operations for audio streams)
209 vector<unsigned char>audiobuffer;
211 int audio_input_frame_size;
213 bool open(AVFormatContext *formatc, AVStream *stream)
215 AVCodecContext *context;
218 context = &stream->codec;
221 codec = avcodec_find_encoder(context->codec_id);
224 synfig::warning("audio-open: could not find codec");
229 if(avcodec_open(context, codec) < 0)
231 synfig::warning("audio-open: could not open codec");
235 /* hardcoded example for generating samples array*/
238 tincr = 2 * M_PI * 110.0 / c->sample_rate;
239 tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;*/
241 audiobuffer.resize(10000);
243 /* ugly hack for PCM codecs (will be removed ASAP with new PCM
244 support to compute the input frame size in samples */
245 if (context->frame_size <= 1) {
246 audio_input_frame_size = audiobuffer.size() / context->channels;
247 switch(stream->codec.codec_id) {
248 case CODEC_ID_PCM_S16LE:
249 case CODEC_ID_PCM_S16BE:
250 case CODEC_ID_PCM_U16LE:
251 case CODEC_ID_PCM_U16BE:
252 audio_input_frame_size >>= 1;
258 audio_input_frame_size = context->frame_size;
262 //samples = (int16_t *)malloc(audio_input_frame_size * 2 * c->channels);
267 bool write_frame(AVFormatContext *formatc, AVStream *stream, void *samples)
270 AVCodecContext *context;
272 context = &stream->codec;
274 //hardcoded in example
275 //must read in from somewhere...
276 //get_audio_frame(samples, audio_input_frame_size, c->channels);
279 const short int*samps=(const short int *)samples; //assuming it's set from somewhere right now
281 size = avcodec_encode_audio(context, &audiobuffer[0], audiobuffer.size(), samps);
283 //write the compressed audio to a file
284 if(av_write_frame(formatc, stream->index, &audiobuffer[0], size) != 0)
286 synfig::warning("audio-write_frame: unable to write the entire audio frame");
293 void close(AVFormatContext *formatc, AVStream *stream)
295 //we may also want to catch delayed frames from here (don't for now)
299 avcodec_close(&stream->codec);
302 //if(samples)av_free(samples);
303 audiobuffer.resize(0);
312 AVFrame *encodable; //for compression and output to a file (in compatible pixel format)
314 vector<unsigned char> videobuffer;
316 bool startedencoding;
318 //int stream_nb_frames;
320 bool open(AVFormatContext *formatc, AVStream *stream)
322 if(!formatc || !stream)
324 synfig::warning("Attempt to open a video codec with a bad format or stream");
330 AVCodecContext *context;
332 //get from inside stream
333 context = stream->codec;
335 //search for desired codec (contained in the stream)
336 codec = avcodec_find_encoder(context->codec_id);
339 synfig::warning("Open_video: could not find desired codec");
343 //try to open the codec
344 if(avcodec_open(context, codec) < 0)
346 synfig::warning("open_video: could not open desired codec");
350 videobuffer.resize(0);
351 if(!(formatc->oformat->flags & AVFMT_RAWPICTURE))
353 //resize buffer to desired buffersize
354 videobuffer.resize(200000); //TODO: need to figure out a good size
357 //allocate the base picture which will be used to encode
358 /*picture = alloc_picture(PIX_FMT_RGBA32, context->width, context->height);
361 synfig::warning("open_video: could not allocate the picture to be encoded");
365 //if our output (rgb) needs to be translated to a different coordinate system, need a temporary picture in that color space
367 /* Should use defaults of RGB
371 PIX_FMT_RGBA32 //stored in cpu endianness (!!!!)
373 (possibly translate directly to required coordinate systems later on... less error)
376 if(context->pix_fmt != PIX_FMT_RGB24)
378 encodable = alloc_picture(context->pix_fmt, context->width, context->height);
381 synfig::warning("open_video: could not allocate encodable picture");
389 //write a frame with the frame passed in
390 bool write_frame(AVFormatContext *formatc, AVStream *stream, AVFrame *pict)
392 if(!formatc || !stream)
394 synfig::warning("Attempt to open a video codec with a bad format or stream");
400 AVCodecContext *context = stream->codec;
403 If pict is invalid (NULL), then we are done compressing frames and we are trying to get
404 the buffer cleared out (or if it's already in the right format) so no transform necessary
408 startedencoding = true;
412 if ( pict && context->pix_fmt != PIX_FMT_RGB24 )
414 //We're using RGBA at the moment, write custom conversion code later (get less accuracy errors)
415 #ifdef WITH_LIBSWSCALE
416 struct SwsContext* img_convert_ctx =
417 sws_getContext(context->width, context->height, PIX_FMT_RGB24,
418 context->width, context->height, context->pix_fmt,
419 SWS_BICUBIC, NULL, NULL, NULL);
421 sws_scale(img_convert_ctx, pict->data, pict->linesize,
423 0, context->height, encodable->data,
424 encodable->linesize);
426 sws_freeContext (img_convert_ctx);
428 img_convert((AVPicture *)encodable, context->pix_fmt,
429 (AVPicture *)pict, PIX_FMT_RGB24,
430 context->width, context->height);
437 av_init_packet(&pkt);
438 pkt.stream_index = stream->index;
439 pkt.data = (uint8_t *)pict;
440 pkt.size = sizeof(AVPicture);
441 if( context->coded_frame )
442 pkt.pts = context->coded_frame->pts;
443 if( context->coded_frame && context->coded_frame->key_frame)
444 pkt.flags |= PKT_FLAG_KEY;
446 //kluge for raw picture format (they said they'd fix)
447 if (formatc->oformat->flags & AVFMT_RAWPICTURE)
449 ret = av_write_frame(formatc, &pkt);
453 //encode our given image
454 size = avcodec_encode_video(context, &videobuffer[0], videobuffer.size(), pict);
456 //if greater than zero we've got stuff to write
459 av_init_packet(&pkt);
460 pkt.stream_index = stream->index;
461 pkt.data = &videobuffer[0];
463 if( context->coded_frame )
464 pkt.pts = context->coded_frame->pts;
465 if( context->coded_frame && context->coded_frame->key_frame)
466 pkt.flags |= PKT_FLAG_KEY;
468 ret = av_write_frame(formatc, &pkt);
470 //error detect - possibly throw later...
473 synfig::warning("write_frame: error while writing video frame");
477 //if 0, it was buffered (if invalid picture we don't have ANY data left)
480 //if we're clearing the buffers and there was no stuff to be written, we're done (like in codec example)
484 startedencoding = false;
494 void close(AVFormatContext */*formatc*/, AVStream *stream)
497 avcodec_close(stream->codec);
501 free_picture(encodable);
505 videobuffer.resize(0);
509 class Target_LibAVCodec::LibAVEncoder
515 AVOutputFormat *format; //reference to global, do not delete
517 AVFormatContext *formatc;
520 //AVStream *audio_st;
531 AVFrame *picture; //for encoding to RGB24 (perhaps RGBA later)
546 //vid.stream_nb_frames = 2; //reasonable default
564 bool Initialize(const char *filename, const char *typestring)
566 //guess if we have a type string, otherwise use filename
569 //formatptr guess_format(type, filename, MIME type)
570 format = guess_format(typestring,NULL,NULL);
574 format = guess_format(NULL, filename, NULL);
579 synfig::warning("Unable to Guess the output, defaulting to mpeg");
580 format = guess_format("mpeg", NULL, NULL);
585 synfig::warning("Unable to find output format");
589 //allocate the output context
590 formatc = (AVFormatContext *)av_mallocz(sizeof(AVFormatContext));
593 synfig::warning("Memory error\n");
596 //set the output format to the one we found
597 formatc->oformat = format;
599 //print the output filename
600 snprintf(formatc->filename, sizeof(formatc->filename), "%s", filename);
607 if(format->video_codec != CODEC_ID_NONE)
609 video_st = add_video_stream(format->video_codec,vInfo);
617 /*if(format->audio_codec != CODEC_ID_NONE)
619 audio_st = add_audio_stream(format->audio_codec,aInfo);
622 //set output parameters: required in ALL cases
624 video_st->codec->time_base= (AVRational){1,vInfo.fps};
625 video_st->codec->width = vInfo.w;
626 video_st->codec->height = vInfo.h;
627 video_st->codec->pix_fmt = PIX_FMT_YUV420P;
629 //dump the formatting information as the file header
630 dump_format(formatc, 0, filename, 1);
632 //open codecs and allocate buffers
635 if(!vid.open(formatc, video_st))
637 synfig::warning("Could not open video encoder");
643 if(!aud.open(formatc, audio_st))
645 synfig::warning("Could not open audio encoder");
651 if(!(format->flags & AVFMT_NOFILE))
653 //use libav's file open function (what does it do differently????)
654 if(url_fopen(&formatc->pb, filename, URL_WRONLY) < 0)
656 synfig::warning("Unable to open file: %s", filename);
661 //allocate the picture to render to
662 //may have to retrieve the width, height from the codec... for resizing...
663 picture = alloc_picture(PIX_FMT_RGB24,vInfo.w,vInfo.h);//video_st->codec.width, video_st->codec.height);
666 synfig::warning("Unable to allocate the temporary AVFrame surface");
671 //vInfo.w = video_st->codec.width;
672 //vInfo.h = video_st->codec.height;
674 //write the stream header
675 av_write_header(formatc);
684 if(picture) free_picture(picture);
686 //do all the clean up file rendering
687 if(formatc && video_st)
689 //want to scan in delayed frames until no longer needed (TODO)
690 if(vid.startedencoding) while( vid.write_frame(formatc, video_st, 0) );
692 //may want to move this... probably to the end of the last frame...
693 av_write_trailer(formatc);
698 vid.close(formatc,video_st);
700 aud.close(formatc,audio_st);*/
702 /* write the trailer, if any */
705 /* free the streams */
706 for(i = 0; i < formatc->nb_streams; i++)
708 av_freep(&formatc->streams[i]);
711 if(!(format->flags & AVFMT_NOFILE))
713 /* close the output file */
714 #if LIBAVFORMAT_VERSION_INT >= (52<<16)
715 url_fclose(formatc->pb);
717 url_fclose(&formatc->pb);
721 /* free the stream */
735 //vid.stream_nb_frames = 2; //reasonable default
741 //create a video output stream
742 AVStream *add_video_stream(int codec_id, const VideoInfo &info)
744 AVCodecContext *context;
747 st = av_new_stream(formatc, 0);
750 synfig::warning("video-add_stream: Unable to allocate stream");
755 context->codec_id = (CodecID)codec_id;
756 context->codec_type = CODEC_TYPE_VIDEO;
758 //PARAMETERS MUST BE PASSED IN SOMEHOW (ANOTHER FUNCTION PARAMETER???)
760 /* resolution must be a multiple of two */
761 context->width = info.w;
762 context->height = info.h;
764 //have another way to input these
765 context->bit_rate = info.bitrate; //TODO: Make dependant on the quality
767 /* frames per second */
768 // FIXME: Port next two lines to recent libavcodec versions
769 //context->frame_rate = info.fps;
770 //context->frame_rate_base = 1;
773 context->mb_decision=FF_MB_DECISION_BITS;
775 context->gop_size = info.fps/4; /* emit one intra frame every twelve frames at most */
777 //HACK: MPEG requires b frames be set... any better way to do this?
778 if (context->codec_id == CODEC_ID_MPEG1VIDEO ||
779 context->codec_id == CODEC_ID_MPEG2VIDEO)
781 /* just for testing, we also add B frames */
782 context->max_b_frames = 2;
788 // add an audio output stream
789 AVStream *add_audio_stream(int codec_id,const AudioInfo &/*aInfo*/)
791 AVCodecContext *context;
794 stream = av_new_stream(formatc, 1);
797 synfig::warning("could not alloc stream");
801 context = stream->codec;
802 context->codec_id = (CodecID)codec_id;
803 context->codec_type = CODEC_TYPE_AUDIO;
805 /* put sample parameters */
806 context->bit_rate = 64000;
807 context->sample_rate = 44100;
808 context->channels = 2;
814 /* === M E T H O D S ======================================================= */
816 Target_LibAVCodec::Target_LibAVCodec(const char *Filename,
817 const synfig::TargetParam& /* params */):
827 data = new LibAVEncoder;
830 Target_LibAVCodec::~Target_LibAVCodec()
836 Target_LibAVCodec::set_rend_desc(RendDesc *given_desc)
838 // This is where you can determine how you want stuff
839 // to be rendered! given_desc is the suggestion, and
840 // you need to modify it to suit the needs of the codec.
841 // ie: Making the pixel dimensions divisible by 8, etc...
845 //resize surface (round even)
846 int w = desc.get_w();
847 int h = desc.get_h();
848 Point tl = desc.get_tl();
849 Point br = desc.get_br();
850 Real pw = desc.get_pw();
851 Real ph = desc.get_ph();
853 //resize to the size it should be...
854 //desc.set_subwindow(-offx/2,-offy/2, desc.get_w() - offx?(offx + 8):0, desc.get_h() - offy?(offy + 8):0);
856 //if resolution is broken, change the size... or something
857 //budge to nearest pixel values
880 //may want to round frame rate
881 data->vInfo.fps = (int)floor(desc.get_frame_rate()+0.5);
882 #define MEGABYTES_PER_HOUR(x) (((x)*1024/3600*1024*8)/*/640*w/480*h*/)
883 data->vInfo.bitrate = MEGABYTES_PER_HOUR(400);
884 //data->vInfo.bitrate = 800000; //make customizable somehow
886 desc.set_frame_rate(data->vInfo.fps);
888 data->frame_count = desc.get_frame_start();
889 data->num_frames = desc.get_frame_end()+1; //number of frames should be 1 greater than the last one
891 surface.set_wh(data->vInfo.w,data->vInfo.h);
897 Target_LibAVCodec::end_frame()
899 //AVStream *audio_st = data->audio_st;
900 AVStream *video_st = data->video_st;
902 AVFormatContext *formatc = data->formatc;
904 //double &audio_pts = data->audio_pts;
905 //double &video_pts = data->video_pts;
907 //ignore audio for now
909 audio_pts = (double)audio_st->pts.val * formatc->pts_num / formatc->pts_den;
914 video_pts = (double)video_st->pts.val * formatc->pts_num / formatc->pts_den;
918 //hardcoded crappiness
919 /*if ((!audio_st || audio_pts >= STREAM_DURATION) &&
920 (!video_st || video_pts >= STREAM_DURATION))
923 if(data->frame_count >= data->num_frames) return;
925 //copy the current surface to the buffer
926 if(data->picture)convert_surface_frame(data->picture,surface,gamma());
928 //encode the frame and write it to the file
929 if(!data->vid.write_frame(formatc,video_st,data->picture))
931 synfig::warning("Unable to write a frame");
936 if(data->frame_count >= data->num_frames)
941 /* write interleaved audio and video frames */
942 /*if (!video_st || (video_st && audio_st && audio_pts < video_pts)) {
943 data->aud.write_frame(formatc,audio_st);
945 data->vid.write_frame(formatc,video_st);
950 Target_LibAVCodec::start_frame(synfig::ProgressCallback */*callback*/)
952 //prepare all the color buffer stuff, etc.
958 Target_LibAVCodec::start_scanline(int scanline)
960 return surface[scanline];
962 return 0; // This should kill the render process
966 Target_LibAVCodec::end_scanline()
968 //don't need to do anything until the whole frame is done
972 bool Target_LibAVCodec::init()
974 //hardcoded test for mpeg
975 if(!data->Initialize(filename.c_str(),NULL))
977 synfig::warning("Unable to Initialize the audio video encoders");