Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- extern "C" {
- #include <libavformat/avformat.h>
- #include <libswscale/swscale.h>
- #include <libavutil/imgutils.h>
- }
- int error;
- AVFormatContext* inputFormatContext = NULL;
- AVFormatContext* outputFormatContext = NULL;
- AVCodecContext* encoderContext;
- AVCodecContext* decoderContext;
- SwsContext *swsCtx = nullptr;
- AVCodec* decoderCodec;
- AVPacket* decodePacket;
- AVPacket* encodePacket;
- AVFrame* inputFrame;
- AVFrame* outputFrame;
- int main(int argc, char **argv){
- if(argc < 3){
- puts("2 arguments are required, input file and output file.");
- return 0;
- }
- char* inputFile = argv[1];
- char* outputFile = argv[2];
- error = avformat_open_input(&inputFormatContext, inputFile, NULL, NULL);
- if (error) {
- return 1;
- }
- error = avformat_find_stream_info(inputFormatContext, NULL);
- if (error) {
- return 1;
- }
- int streamIndex = av_find_best_stream(inputFormatContext, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0);
- if (streamIndex < 0) {
- error = AVERROR_UNKNOWN;
- return 1;
- }
- AVStream* stream = inputFormatContext->streams[streamIndex];
- AVCodecParameters* codecParameters = stream->codecpar;
- if (!codecParameters->codec_id) {
- error = AVERROR_UNKNOWN;
- return 1;
- }
- //Opening input
- decoderCodec = avcodec_find_decoder(codecParameters->codec_id);
- decoderContext = avcodec_alloc_context3(decoderCodec);
- if (!decoderContext) {
- error = AVERROR_UNKNOWN;
- return 1;
- }
- error = avcodec_parameters_to_context(decoderContext, codecParameters);
- if(error){
- return 1;
- }
- decoderContext->thread_count = 0;
- error = avcodec_open2(decoderContext, decoderCodec, nullptr);
- if(error){
- return 1;
- }
- //Opened input
- //init frames
- inputFrame = av_frame_alloc();
- if(!inputFrame){
- error = AVERROR_UNKNOWN;
- return 1;
- }
- outputFrame = av_frame_alloc();
- if(!outputFrame){
- error = AVERROR_UNKNOWN;
- return 1;
- }
- decodePacket = av_packet_alloc();
- if(!decodePacket){
- error = AVERROR_UNKNOWN;
- return 1;
- }
- encodePacket = av_packet_alloc();
- if(!encodePacket){
- error = AVERROR_UNKNOWN;
- return 1;
- }
- avformat_alloc_output_context2(&outputFormatContext, NULL, NULL, outputFile);
- outputFormatContext->video_codec_id = av_guess_codec(outputFormatContext->oformat, NULL, outputFile, NULL, AVMEDIA_TYPE_VIDEO);
- outputFormatContext->video_codec = avcodec_find_encoder(outputFormatContext->video_codec_id);
- if(!outputFormatContext->video_codec){
- error = AVERROR_UNKNOWN;
- return 1;
- }
- encoderContext = avcodec_alloc_context3(outputFormatContext->video_codec);
- if(!encoderContext){
- error = AVERROR_UNKNOWN;
- return 1;
- }
- encoderContext->width = 100;
- encoderContext->height = 100;
- encoderContext->pix_fmt = avcodec_find_best_pix_fmt_of_list(outputFormatContext->video_codec->pix_fmts, decoderContext->pix_fmt, true, NULL);
- encoderContext->time_base = av_make_q(1, (stream->avg_frame_rate.num + (stream->avg_frame_rate.den / 2)) / stream->avg_frame_rate.den);
- error = avcodec_open2(encoderContext, outputFormatContext->video_codec, nullptr);
- if(error){
- return 1;
- }
- //init encoder
- swsCtx = sws_getContext(decoderContext->width, decoderContext->height, decoderContext->pix_fmt,
- encoderContext->width, encoderContext->height, encoderContext->pix_fmt,
- 0, nullptr, nullptr, nullptr);
- if(!swsCtx){
- error = AVERROR_UNKNOWN;
- return 1;
- }
- outputFrame->format = encoderContext->pix_fmt;
- outputFrame->width = encoderContext->width;
- outputFrame->height = encoderContext->height;
- error = av_frame_get_buffer(outputFrame, 0);
- //error = av_image_alloc(outputFrame->data, outputFrame->linesize, encoderContext->width, encoderContext->height, encoderContext->pix_fmt, 4);
- if(error < 0) {
- return 1;
- }
- AVStream* out_stream = avformat_new_stream(outputFormatContext, NULL);
- error = avcodec_parameters_from_context(out_stream->codecpar, decoderContext);
- if(error){
- return 1;
- }
- if (!(outputFormatContext->oformat->flags & AVFMT_NOFILE)) {
- error = avio_open(&outputFormatContext->pb, outputFile, AVIO_FLAG_WRITE);
- if (error < 0) {
- return 1;
- }
- }
- AVDictionary *opts;
- av_dict_set(&opts, "loop", "0", 0);
- error = avformat_write_header(outputFormatContext, &opts);
- if(error){
- return 1;
- }
- while (true) {
- av_frame_unref(inputFrame);
- av_packet_unref(decodePacket);
- //probably ended frames
- if(av_read_frame(inputFormatContext, decodePacket) < 0){
- error = 0;
- break;
- }
- //different stream. ignore.
- if (decodePacket->stream_index != streamIndex) {
- continue;
- }
- //send packet
- error = avcodec_send_packet(decoderContext, decodePacket);
- if (error < 0 ) {
- //get next one
- if (error == AVERROR(EAGAIN)){
- continue;
- } else {
- return 1;
- }
- }
- //send frame
- error = avcodec_receive_frame(decoderContext, inputFrame);
- if (error < 0) {
- //get next one
- if (error == AVERROR(EAGAIN)){
- continue;
- } else {
- return 1;
- }
- }
- if(!sws_scale(swsCtx, inputFrame->data,
- inputFrame->linesize, 0, inputFrame->height, outputFrame->data, outputFrame->linesize)){
- return 1;
- }
- error = avcodec_send_frame(encoderContext, outputFrame);
- if(error){
- return 1;
- }
- error = avcodec_receive_packet(encoderContext, encodePacket);
- if(error){
- return 1;
- }
- encodePacket->pts = av_rescale_q_rnd(decodePacket->pts, stream->time_base, out_stream->time_base, static_cast<AVRounding>(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
- encodePacket->dts = av_rescale_q_rnd(decodePacket->dts, stream->time_base, out_stream->time_base, static_cast<AVRounding>(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
- encodePacket->duration = av_rescale_q(decodePacket->duration, stream->time_base, out_stream->time_base);
- encodePacket->pos = -1;
- error = av_interleaved_write_frame(outputFormatContext, encodePacket);
- if (error < 0) {
- return 1;
- }
- }
- error = av_write_trailer(outputFormatContext);
- if(error){
- return 1;
- }
- puts("Finished conversion.");
- if (!(outputFormatContext->oformat->flags & AVFMT_NOFILE)){
- avio_closep(&outputFormatContext->pb);
- }
- av_packet_unref(encodePacket);
- av_packet_unref(decodePacket);
- avcodec_send_packet(decoderContext, nullptr);
- avcodec_send_packet(encoderContext, nullptr);
- //av_freep(&outputFrame->data);
- av_frame_free(&inputFrame);
- av_frame_free(&outputFrame);
- sws_freeContext(swsCtx);
- av_packet_free(&encodePacket);
- av_packet_free(&decodePacket);
- avcodec_free_context(&encoderContext);
- avcodec_free_context(&decoderContext);
- avformat_close_input(&inputFormatContext);
- avformat_free_context(outputFormatContext);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement