Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- void AviWriter::openFile(QString name, unsigned int width, unsigned int height, float fps)
- {
- LOG_INFO("Opening file %s, properties: [width: %d, height: %d, fps: %d]",
- name.toAscii().data(), width, height, fps);
- av_log_set_level(AV_LOG_DEBUG);
- // presentation timestamp
- m_avpkt.pts = 0;
- // decompresion timestamp
- m_avpkt.dts = 0;
- // position in stream, -1 -> unknown
- m_avpkt.pos = -1;
- // duration of this packet in AVStream->time_base units
- // 0 -> unknown
- m_avpkt.duration = 0;
- // Time diff in av stream units between pts of this packet and point at which
- // output from the decoder has converged independent from availability of previous frame.
- m_avpkt.convergence_duration = 0;
- // AV_PKT_FLAG
- m_avpkt.flags = 0;
- m_avpkt.stream_index = 0;
- m_avpkt.destruct = NULL;
- av_register_all();
- avcodec_register_all();
- m_avOutputFormat = av_guess_format("avi", NULL, NULL);
- if( !m_avOutputFormat )
- {
- std::string msg("Cannot find suitable output format");
- LOG_ERROR(msg.c_str());
- throw AviException(msg);
- }
- m_codecp = avcodec_find_decoder(CODEC_ID_MPEG4);
- if(m_codecp == NULL)
- {
- std::string msg("avcodec_find_decoder failed");
- LOG_ERROR(msg.c_str());
- throw AviException(msg);
- }
- m_avFormatCtx = avformat_alloc_context();
- if(m_avFormatCtx == NULL)
- {
- std::string msg("Couldn't allocate memory for output format");
- LOG_ERROR(msg.c_str());
- throw AviException(msg);
- }
- m_avFormatCtx->oformat = m_avOutputFormat;
- LOG_INFO("Setting filename to av output format");
- //qsnprintf(m_avFormatCtx->filename, sizeof(m_avFormatCtx->filename), "%s",name.toAscii().data());
- m_avFormatCtx->max_delay = (int)(0.7 * AV_TIME_BASE);
- m_avCodecCtx = avcodec_alloc_context3(m_codecp);
- if( !m_avCodecCtx )
- LOG_INFO( "Can not create codec context" );
- m_picture = avcodec_alloc_frame();
- m_avCodecCtx->width = width;
- m_avCodecCtx->height = height;
- m_avCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
- m_avCodecCtx->pix_fmt = PIX_FMT_YUV420P;
- /*
- * Convert FPS float value to AVRational (time_base value)
- * A bit of explanation:
- * time_base field is something opposite to framerate. The FPS value tell how much frames are rendered in one second.
- * Time_base (timebase ? time-base ? time base ? How to spell that crap ?) is a measure that tells you how much time it takes
- * to render one frame, hence time_base = 1/FPS.
- *
- * AVCodec doc says we should use 1/FPS for fixed framerate, or just time base as it is.
- *
- * Here i convert float fps value to AVRational struct (fractions made of integers, clever) then i reverse denominator and nominator.
- */
- AVRational one = av_d2q(fps, std::numeric_limits<int>::max() );
- m_avCodecCtx->time_base.num = one.den;
- m_avCodecCtx->time_base.den = one.num;
- m_avCodecCtx->has_b_frames = 1;
- m_avCodecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
- if (avcodec_open2(m_avCodecCtx, m_codecp, NULL) < 0)
- {
- std::string msg("avcodec_open failed !");
- LOG_ERROR(msg.c_str());
- throw AviException(msg);
- }
- m_avVideo = avformat_new_stream(m_avFormatCtx, m_codecp);
- if(!m_avVideo)
- {
- std::string msg("av_new_stream failed: Could not alloc video stream");
- LOG_ERROR(msg.c_str());
- throw AviException(msg);
- }
- m_avVideo->codec = m_avCodecCtx;
- if(nRitaConfig.debug())
- {
- LOG_DEBUG("Dump format");
- av_dump_format(m_avFormatCtx, 0, name.toAscii().data(), 1);
- }
- if (!(m_avOutputFormat->flags & AVFMT_NOFILE))
- {
- LOG_INFO("url_fopen");
- if (avio_open(&m_avFormatCtx->pb, name.toAscii().data(), AVIO_FLAG_WRITE) < 0)
- {
- std::string msg("Could not open file, avio_open failed");
- LOG_ERROR(msg.c_str());
- throw AviException(msg);
- }
- }
- writeHeader();
- }
- void AviWriter::writeHeader()
- {
- LOG_INFO("Writing header");
- avformat_write_header(m_avFormatCtx, NULL);
- }
- void AviWriter::close()
- {
- LOG_INFO("Closing %s file", m_aviFile.fileName().toAscii().data());
- av_write_trailer(m_avFormatCtx);
- av_freep(&m_avFormatCtx->streams[0]->codec);
- av_freep(&m_avFormatCtx->streams[0]);
- if (!(m_avOutputFormat->flags & AVFMT_NOFILE))
- {
- // close the output file
- avio_close(m_avFormatCtx->pb);
- }
- av_free(m_avFormatCtx);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement