Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- void Controler::exportVideo( QList<QPair<quint64, quint64> >clips, QString fileName )
- {
- OutputStream video_st = { 0 }, audio_st = { 0 };
- AVOutputFormat *fmt;
- AVFormatContext *oc;
- AVFrame* frame;
- AVCodec *audio_codec, *video_codec;
- int ret;
- int have_video = 0, have_audio = 0;
- int encode_video = 0, encode_audio = 0;
- AVDictionary *opt = NULL;
- /* Initialize libavcodec, and register all codecs and formats. */
- av_register_all();
- avcodec_register_all();
- /* allocate the output media context */
- avformat_alloc_output_context2(&oc, NULL, NULL, fileName.toLatin1() );
- if ( !oc )
- {
- qDebug() << "Could not deduce output format from file extension: using MPEG.";
- avformat_alloc_output_context2( &oc, NULL, "mpeg", fileName.toLatin1() );
- return;
- }
- fmt = oc->oformat;
- /* Add the audio and video streams using the default format codecs
- * and initialize the codecs. */
- if ( fmt->video_codec != AV_CODEC_ID_NONE )
- {
- VE::add_stream( &video_st, oc, &video_codec, fmt->video_codec );
- have_video = 1;
- encode_video = 1;
- }
- if ( fmt->audio_codec != AV_CODEC_ID_NONE )
- {
- VE::add_stream( &audio_st, oc, &audio_codec, fmt->audio_codec );
- have_audio = 1;
- encode_audio = 1;
- }
- video_st.st->codec->width = 1920;
- video_st.st->codec->height = 1080;
- /* Now that all the parameters are set, we can open the audio and
- * video codecs and allocate the necessary encode buffers. */
- if ( have_video )
- VE::open_video( oc, video_codec, &video_st, opt );
- if ( have_audio )
- VE::open_audio( oc, audio_codec, &audio_st, opt );
- av_dump_format( oc, 0, fileName.toLatin1(), 1 );
- /* open the output file, if needed */
- if ( !( fmt->flags & AVFMT_NOFILE ) )
- {
- ret = avio_open( &oc->pb, fileName.toLatin1(), AVIO_FLAG_WRITE );
- if (ret < 0)
- {
- qDebug() << "Could not open " << fileName.toLatin1(); //, av_err2str(ret));
- return;
- }
- }
- frame = av_frame_alloc();
- if ( !frame )
- {
- qDebug() << "Could not allocate video frame";
- return;
- }
- frame->format = AV_PIX_FMT_YUV420P;
- frame->width = 1920;
- frame->height = 1080;
- /* the image can be allocated by any means and av_image_alloc() is
- * just the most convenient way if av_malloc() is to be used */
- //ret = av_image_alloc( frame->data, frame->linesize, 1920, 1080, AV_PIX_FMT_YUV420P, 32 );
- ret = av_image_alloc( video_st.frame->data, frame->linesize, 1920, 1080, AV_PIX_FMT_YUV420P, 32 );
- if ( ret < 0 )
- {
- qDebug() << "Could not allocate raw picture buffer";
- return;
- }
- /* Write the stream header, if any. */
- ret = avformat_write_header( oc, &opt );
- if (ret < 0)
- {
- qDebug() << "Error occurred when opening output file: "; //, av_err2str(ret));
- return ;
- }
- quint64 totalSize = 0;
- for (int clip = 0; clip < clips.size(); ++clip)
- {
- quint64 in = clips[clip].first;
- quint64 out = clips[clip].second;
- totalSize += ( out - in );
- }
- QProgressDialog progress("Encoding video file", "Cancel", 0, totalSize, 0);
- progress.setWindowModality(Qt::WindowModal);
- progress.show();
- quint64 progressValue = 0;
- for ( int clip = 0; clip < clips.size(); ++clip )
- {
- quint64 in = clips[clip].first;
- quint64 out = clips[clip].second;
- qDebug() << "-----";
- qDebug() << clips[clip].first << " " << clips[clip].second;
- for ( quint64 frameId = in; frameId <= out; ++frameId )
- {
- progress.setValue( progressValue++ );
- encode_video = !write_video_frame( oc, &video_st, frameId );
- //encode_video = !write_video_frame( oc, &video_st, frame );
- /*
- if ( encode_video && ( !encode_audio || av_compare_ts( video_st.next_pts, video_st.st->codec->time_base, audio_st.next_pts, audio_st.st->codec->time_base ) <= 0) )
- {
- encode_video = !write_video_frame(oc, &video_st, frameId );
- }
- else
- {
- encode_audio = !write_audio_frame(oc, &audio_st, frameId );
- }
- */
- }
- }
- av_write_trailer(oc);
- /* Close each codec. */
- if (have_video)
- VE::close_stream(oc, &video_st);
- if (have_audio)
- VE::close_stream(oc, &audio_st);
- if (!(fmt->flags & AVFMT_NOFILE))
- /* Close the output file. */
- avio_closep(&oc->pb);
- /* free the stream */
- avformat_free_context(oc);
- return ;
- }
- /*
- * encode one video frame and send it to the muxer
- * return 1 when encoding is finished, 0 otherwise
- */
- int Controler::write_video_frame( AVFormatContext *oc, OutputStream *ost, quint64 frameId )
- {
- int ret;
- AVCodecContext *c;
- int got_packet = 0;
- AVPacket pkt = { 0 };
- c = ost->st->codec;
- AVFrame* frame = getVideoFrame( frameId, ost );
- av_init_packet( &pkt );
- /* encode the image */
- ret = avcodec_encode_video2( c, &pkt, frame, &got_packet );
- if ( ret < 0 )
- {
- qDebug() << "Error encoding video frame: "; //, av_err2str(ret));
- exit(1);
- }
- if (got_packet)
- {
- ret = VE::write_frame( oc, &c->time_base, ost->st, &pkt );
- }
- else
- {
- ret = 0;
- }
- if ( ret < 0 )
- {
- qDebug() << "Error while writing video frame: "; //, av_err2str(ret));
- exit(1);
- }
- return (frame || got_packet) ? 0 : 1;
- }
- int Controler::write_audio_frame(AVFormatContext *oc, OutputStream *ost, quint64 frameId )
- {
- AVCodecContext *c;
- AVPacket pkt = { 0 }; // data and size must be 0;
- AVFrame *frame;
- int ret;
- int got_packet;
- int dst_nb_samples;
- av_init_packet(&pkt);
- c = ost->st->codec;
- frame = getAudioFrame( frameId, ost );
- if (frame)
- {
- /* convert samples from native format to destination codec format, using the resampler */
- /* compute destination number of samples */
- dst_nb_samples = av_rescale_rnd(swr_get_delay(ost->swr_ctx, c->sample_rate) + frame->nb_samples,
- c->sample_rate, c->sample_rate, AV_ROUND_UP);
- av_assert0(dst_nb_samples == frame->nb_samples);
- /* when we pass a frame to the encoder, it may keep a reference to it
- * internally;
- * make sure we do not overwrite it here
- */
- ret = av_frame_make_writable(ost->frame);
- if (ret < 0)
- exit(1);
- /* convert to destination format */
- ret = swr_convert(ost->swr_ctx,
- ost->frame->data, dst_nb_samples,
- (const uint8_t **)frame->data, frame->nb_samples);
- if (ret < 0) {
- fprintf(stderr, "Error while converting\n");
- exit(1);
- }
- frame = ost->frame;
- AVRational ar;
- ar.num = 1;
- ar.den = c->sample_rate;
- frame->pts = av_rescale_q(ost->samples_count, ar, c->time_base);
- ost->samples_count += dst_nb_samples;
- }
- ret = avcodec_encode_audio2(c, &pkt, frame, &got_packet);
- if (ret < 0) {
- qDebug() << "Error encoding audio frame: "; //, av_err2str(ret));
- exit(1);
- }
- if (got_packet) {
- ret = VE::write_frame(oc, &c->time_base, ost->st, &pkt);
- if (ret < 0) {
- qDebug() << "Error while writing audio frame:"; //, av_err2str(ret));
- exit(1);
- }
- }
- return ( frame || got_packet ) ? 0 : 1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement