Advertisement
Guest User

Untitled

a guest
Oct 7th, 2024
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.60 KB | None | 0 0
  1. extern "C" {
  2. #include <libavformat/avformat.h>
  3. #include <libswscale/swscale.h>
  4. #include <libavutil/imgutils.h>
  5. }
  6.  
  7. int error;
  8.  
  9. AVFormatContext* inputFormatContext = NULL;
  10. AVFormatContext* outputFormatContext = NULL;
  11.  
  12. AVCodecContext* encoderContext;
  13. AVCodecContext* decoderContext;
  14.  
  15. SwsContext *swsCtx = nullptr;
  16.  
  17. AVCodec* decoderCodec;
  18.  
  19. AVPacket* decodePacket;
  20. AVPacket* encodePacket;
  21.  
  22. AVFrame* inputFrame;
  23. AVFrame* outputFrame;
  24.  
  25. int main(int argc, char **argv){
  26.  
  27.   if(argc < 3){
  28.     puts("2 arguments are required, input file and output file.");
  29.     return 0;
  30.   }
  31.  
  32.   char* inputFile = argv[1];
  33.   char* outputFile = argv[2];
  34.  
  35.   error = avformat_open_input(&inputFormatContext, inputFile, NULL, NULL);
  36.  
  37.   if (error) {
  38.     return 1;
  39.   }
  40.  
  41.   error = avformat_find_stream_info(inputFormatContext, NULL);
  42.  
  43.   if (error) {
  44.     return 1;
  45.   }
  46.  
  47.    
  48.   int streamIndex = av_find_best_stream(inputFormatContext, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0);
  49.  
  50.   if (streamIndex < 0) {
  51.     error = AVERROR_UNKNOWN;
  52.     return 1;
  53.   }
  54.  
  55.   AVStream* stream = inputFormatContext->streams[streamIndex];
  56.  
  57.   AVCodecParameters* codecParameters = stream->codecpar;
  58.  
  59.   if (!codecParameters->codec_id) {
  60.     error = AVERROR_UNKNOWN;
  61.     return 1;
  62.   }
  63.  
  64.   //Opening input
  65.   decoderCodec = avcodec_find_decoder(codecParameters->codec_id);
  66.  
  67.   decoderContext = avcodec_alloc_context3(decoderCodec);
  68.   if (!decoderContext) {
  69.     error = AVERROR_UNKNOWN;
  70.     return 1;
  71.   }
  72.  
  73.   error = avcodec_parameters_to_context(decoderContext, codecParameters);
  74.  
  75.   if(error){
  76.     return 1;
  77.   }
  78.  
  79.   decoderContext->thread_count = 0;
  80.   error = avcodec_open2(decoderContext, decoderCodec, nullptr);
  81.  
  82.   if(error){
  83.     return 1;
  84.   }
  85. //Opened input
  86.  
  87.  
  88.   //init frames
  89.  
  90.   inputFrame = av_frame_alloc();
  91.  
  92.   if(!inputFrame){
  93.     error = AVERROR_UNKNOWN;
  94.     return 1;
  95.   }
  96.  
  97.    outputFrame = av_frame_alloc();
  98.  
  99.   if(!outputFrame){
  100.     error = AVERROR_UNKNOWN;
  101.     return 1;
  102.   }
  103.  
  104.   decodePacket = av_packet_alloc();
  105.  
  106.   if(!decodePacket){
  107.     error = AVERROR_UNKNOWN;
  108.     return 1;
  109.   }
  110.  
  111.  encodePacket = av_packet_alloc();
  112.  
  113.   if(!encodePacket){
  114.     error = AVERROR_UNKNOWN;
  115.     return 1;
  116.   }
  117.  
  118.   avformat_alloc_output_context2(&outputFormatContext, NULL, NULL, outputFile);
  119.  
  120.   outputFormatContext->video_codec_id = av_guess_codec(outputFormatContext->oformat, NULL, outputFile, NULL, AVMEDIA_TYPE_VIDEO);
  121.  
  122.   outputFormatContext->video_codec = avcodec_find_encoder(outputFormatContext->video_codec_id);
  123.  
  124.   if(!outputFormatContext->video_codec){
  125.     error = AVERROR_UNKNOWN;
  126.     return 1;
  127.   }
  128.  
  129.   encoderContext = avcodec_alloc_context3(outputFormatContext->video_codec);
  130.  
  131.  if(!encoderContext){
  132.     error = AVERROR_UNKNOWN;
  133.     return 1;
  134.   }
  135.  
  136.   encoderContext->width = 100;
  137.   encoderContext->height = 100;
  138.  
  139.  
  140.   encoderContext->pix_fmt = avcodec_find_best_pix_fmt_of_list(outputFormatContext->video_codec->pix_fmts, decoderContext->pix_fmt, true, NULL);                                        
  141.  
  142.   encoderContext->time_base = av_make_q(1, (stream->avg_frame_rate.num + (stream->avg_frame_rate.den / 2)) / stream->avg_frame_rate.den);
  143.  
  144.   error = avcodec_open2(encoderContext, outputFormatContext->video_codec, nullptr);
  145.  
  146.   if(error){
  147.     return 1;
  148.   }
  149.   //init encoder
  150.  
  151.   swsCtx = sws_getContext(decoderContext->width, decoderContext->height, decoderContext->pix_fmt,
  152.                              encoderContext->width, encoderContext->height, encoderContext->pix_fmt,
  153.                              0, nullptr, nullptr, nullptr);
  154.                              
  155.                          
  156.   if(!swsCtx){
  157.     error = AVERROR_UNKNOWN;
  158.     return 1;
  159.   }
  160.  
  161.   outputFrame->format = encoderContext->pix_fmt;
  162.   outputFrame->width = encoderContext->width;
  163.   outputFrame->height = encoderContext->height;
  164.  
  165.   error = av_frame_get_buffer(outputFrame, 0);
  166.  //error = av_image_alloc(outputFrame->data, outputFrame->linesize, encoderContext->width, encoderContext->height, encoderContext->pix_fmt, 4);
  167.        
  168.    if(error < 0) {
  169.      return 1;
  170.    }
  171.    
  172.  AVStream* out_stream = avformat_new_stream(outputFormatContext, NULL);
  173.    
  174.  error = avcodec_parameters_from_context(out_stream->codecpar, decoderContext);
  175.  
  176.  if(error){
  177.   return 1;
  178.  }
  179.    
  180.   if (!(outputFormatContext->oformat->flags & AVFMT_NOFILE)) {
  181.         error = avio_open(&outputFormatContext->pb, outputFile, AVIO_FLAG_WRITE);
  182.         if (error < 0) {
  183.             return 1;
  184.         }
  185.     }
  186.  
  187.   AVDictionary *opts;
  188.  
  189.   av_dict_set(&opts, "loop", "0", 0);
  190.  
  191.   error = avformat_write_header(outputFormatContext, &opts);
  192.  
  193.   if(error){
  194.       return 1;
  195.     }
  196.  
  197.   while (true) {
  198.        
  199.         av_frame_unref(inputFrame);
  200.         av_packet_unref(decodePacket);
  201.        
  202.         //probably ended frames
  203.         if(av_read_frame(inputFormatContext, decodePacket) < 0){
  204.           error = 0;
  205.           break;
  206.         }
  207.        
  208.         //different stream. ignore.
  209.         if (decodePacket->stream_index != streamIndex) {
  210.           continue;
  211.         }
  212.        
  213.         //send packet
  214.         error = avcodec_send_packet(decoderContext, decodePacket);
  215.        
  216.         if (error < 0 ) {
  217.          
  218.         //get next one
  219.           if (error == AVERROR(EAGAIN)){
  220.              continue;
  221.             } else {
  222.               return 1;
  223.             }
  224.         }
  225.        
  226.         //send frame
  227.         error = avcodec_receive_frame(decoderContext, inputFrame);
  228.        
  229.         if (error < 0) {
  230.          
  231.           //get next one
  232.           if (error == AVERROR(EAGAIN)){
  233.               continue;
  234.             } else {
  235.               return 1;
  236.             }
  237.         }
  238.        
  239.      
  240.      if(!sws_scale(swsCtx, inputFrame->data,
  241.                   inputFrame->linesize, 0, inputFrame->height, outputFrame->data, outputFrame->linesize)){
  242.         return 1;
  243.         }
  244.  
  245.         error = avcodec_send_frame(encoderContext, outputFrame);
  246.            
  247.         if(error){
  248.           return 1;
  249.         }
  250.  
  251.         error = avcodec_receive_packet(encoderContext, encodePacket);
  252.  
  253.         if(error){
  254.           return 1;
  255.         }
  256.        
  257.         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));
  258.         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));
  259.         encodePacket->duration = av_rescale_q(decodePacket->duration, stream->time_base, out_stream->time_base);
  260.         encodePacket->pos = -1;
  261.  
  262.         error = av_interleaved_write_frame(outputFormatContext, encodePacket);
  263.        
  264.         if (error < 0) {
  265.             return 1;
  266.         }
  267.  
  268.     }
  269.    
  270.   error = av_write_trailer(outputFormatContext);
  271.  
  272.     if(error){
  273.       return 1;
  274.     }
  275.    
  276.     puts("Finished conversion.");
  277.    
  278.      if (!(outputFormatContext->oformat->flags & AVFMT_NOFILE)){
  279.         avio_closep(&outputFormatContext->pb);
  280.      }
  281.    
  282.     av_packet_unref(encodePacket);
  283.     av_packet_unref(decodePacket);
  284.  
  285.     avcodec_send_packet(decoderContext, nullptr);
  286.     avcodec_send_packet(encoderContext, nullptr);
  287.    
  288.     //av_freep(&outputFrame->data);
  289.    
  290.     av_frame_free(&inputFrame);
  291.     av_frame_free(&outputFrame);
  292.  
  293.     sws_freeContext(swsCtx);
  294.    
  295.     av_packet_free(&encodePacket);
  296.     av_packet_free(&decodePacket);
  297.    
  298.     avcodec_free_context(&encoderContext);
  299.     avcodec_free_context(&decoderContext);
  300.    
  301.     avformat_close_input(&inputFormatContext);
  302.     avformat_free_context(outputFormatContext);
  303.  
  304.   return 0;
  305. }
  306.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement