Advertisement
gviandres

transcoder

Dec 23rd, 2021
397
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 22.29 KB | None | 0 0
  1. ```c
  2. #include <libavcodec/avcodec.h>
  3. #include <libavformat/avformat.h>
  4. #include <libavutil/opt.h>
  5. #include <libavutil/pixdesc.h>
  6. #include <libavutil/avutil.h>
  7.  
  8. typedef struct file
  9. {
  10.     AVFormatContext *container;
  11.     AVCodecContext **codec;
  12.     int *frames;
  13.     int *last_pts;
  14.     int *pre_pts;
  15.  
  16.     //Counting packets (same principle as counting frames).
  17.     ////////////////////////////////////////////////////////////////////
  18.     int *packets;
  19.     ////////////////////////////////////////////////////////////////////
  20. } file;
  21.  
  22. typedef struct EncoderContext
  23. {
  24.     file *encoder;
  25.  
  26. } EncoderContext;
  27.  
  28. file *create_output(int streams, const char *filename);
  29. file *start_output_from_file(const char *path, file *input, const char *video_encoder, const char *audio_encoder);
  30. int create_video_encoder(AVCodecContext **cod_ctx, AVFormatContext *container, const char *encoder, int width, int height,
  31.                          int pix_fmt, AVRational sample_aspect_ratio, AVRational frame_rate, int bit_rate, int buffer_size);
  32. int create_audio_encoder(AVCodecContext **cod_ctx, AVFormatContext *container, const char *encoder,
  33.                          int channels, int sample_rate, int bit_rate);
  34. int decode_frame(file *decoder, AVFrame *frame, AVPacket *packet);
  35. int open_media(file *video, const char input_path[], const char *video_codec, const char *audio_codec);
  36. void save_gray_frame(unsigned char *buf, int width, int height);
  37. int free_file(file *f);
  38. int encode_frame(file *encoder, AVFrame *input_frame, int index);
  39. int stream_clip(file *input, file *output);
  40. int fill_with_empty_frames_until_all_streams_match_pts(file *input, file *output);
  41.  
  42. int main()
  43. {
  44.     int res;
  45.     int inputs_len = 1;
  46.  
  47.     //file* input1 = malloc(sizeof(file));
  48.     file *input1 = calloc(sizeof(file), 1);
  49.  
  50.     res = open_media(input1, "in_short.mp4", "h264_cuvid", NULL);
  51.     if (res == 1)
  52.     {
  53.         printf("Failed opening input 1");
  54.         return 1;
  55.     }
  56.     file *output = start_output_from_file("output2.mp4", input1, "h264_nvenc", NULL);
  57.  
  58.     if (!input1)
  59.     {
  60.         printf("Failed opening output");
  61.         return 1;
  62.     }
  63.  
  64.     stream_clip(input1, output);
  65.     free_file(input1);
  66.  
  67.     for (int i = 0; i < inputs_len; i++)
  68.     {
  69.         //file* input = malloc(sizeof(file));
  70.         file *input = calloc(sizeof(file), 1);
  71.         res = open_media(input, "in_short.mp4", "h264_cuvid", NULL);
  72.         stream_clip(input, output);
  73.         free_file(input);
  74.     }
  75.  
  76.     encode_frame(output, NULL, 0);
  77.     encode_frame(output, NULL, 1);
  78.  
  79.     av_write_trailer(output->container);
  80.  
  81.     free_file(output);
  82. }
  83.  
  84. int stream_clip(file *input, file *output)
  85. {
  86.     AVPacket *packet = av_packet_alloc();
  87.     AVFrame *frame = av_frame_alloc();
  88.     int res;
  89.  
  90.     while (1)
  91.     {
  92.         res = decode_frame(input, frame, packet);
  93.  
  94.         if (res == 1)
  95.         {
  96.             printf("Error decoding a frame\n");
  97.             av_frame_free(&frame);
  98.             av_packet_free(&packet);
  99.  
  100.             return 1;
  101.         }
  102.         else if (res == 0)
  103.         {
  104.  
  105.             AVCodecContext *codec = output->codec[packet->stream_index];
  106.             AVRational fps = output->codec[packet->stream_index]->framerate;
  107.             int frames_per_packet = 1;
  108.             AVRational time_base = output->container->streams[packet->stream_index]->time_base;
  109.  
  110.             if (input->container->streams[packet->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
  111.             {
  112.                 fps.den = 1;
  113.                 fps.num = input->container->streams[packet->stream_index]->codecpar->sample_rate;
  114.  
  115.                 ////////////////////////////////////////////////////////////////////
  116.                 frames_per_packet = input->container->streams[packet->stream_index]->codecpar->frame_size; //For the audio there are 1024 (or 960) frames per packet https://stackoverflow.com/questions/23216103/about-definition-for-terms-of-audio-codec
  117.                 ////////////////////////////////////////////////////////////////////
  118.             }
  119.  
  120.             //Why pkt_duration = pts???
  121.             ////////////////////////////////////////////////////////////////////
  122.             //frame->pkt_duration = frame->pts;
  123.             frame->pkt_duration = (int64_t)(av_q2d(av_div_q((AVRational){time_base.den, 1}, fps))) * (int64_t)frames_per_packet;
  124.             ////////////////////////////////////////////////////////////////////
  125.  
  126.             frame->pts = (int64_t)(output->frames[packet->stream_index] * frame->pkt_duration);
  127.  
  128.             output->last_pts[packet->stream_index] = frame->pts;
  129.  
  130.             frame->pkt_dts = frame->pts;
  131.  
  132.             printf("%i FRAME %i PTS %i\n", (int)packet->stream_index, (int)output->frames[packet->stream_index], (int)frame->pts);
  133.  
  134.             output->frames[packet->stream_index]++;
  135.  
  136.             res = encode_frame(output, frame, packet->stream_index);
  137.             if (res == 1)
  138.             {
  139.                 av_frame_free(&frame);
  140.                 printf("Failde encoding frame\n");
  141.                 return 1;
  142.             }
  143.             av_frame_unref(frame);
  144.         }
  145.  
  146.         else if (res == -1)
  147.         {
  148.             printf("\nfile \"%s\" ended\n", input->container->url);
  149.             break;
  150.         }
  151.     }
  152.     for (int i = 0; i < input->container->nb_streams; i++)
  153.     {
  154.         output->pre_pts[i] = output->last_pts[i];
  155.         output->last_pts[i] = 0;
  156.     }
  157.  
  158.     fill_with_empty_frames_until_all_streams_match_pts(input, output);
  159.  
  160.     av_frame_free(&frame);
  161.  
  162.     decode_frame(input, NULL, packet);
  163.  
  164.     av_packet_free(&packet);
  165.  
  166.     return 0;
  167. }
  168.  
  169. int encode_frame(file *encoder, AVFrame *input_frame, int index)
  170. {
  171.  
  172.     AVPacket *output_packet = av_packet_alloc();
  173.     if (!output_packet)
  174.     {
  175.         printf("ENCODER: Failed mallocing output_package");
  176.         return 1;
  177.     }
  178.  
  179.     AVCodecContext *codec = encoder->codec[index];
  180.  
  181.     if (!codec)
  182.         return 0;
  183.  
  184.     int response = avcodec_send_frame(codec, input_frame);
  185.  
  186.     while (response >= 0)
  187.     {
  188.         //The packet unref is supposed to be here
  189.         ////////////////////////////////////////////////////////////////////////
  190.         av_packet_unref(output_packet);
  191.         ////////////////////////////////////////////////////////////////////////
  192.  
  193.         response = avcodec_receive_packet(codec, output_packet);
  194.  
  195.         if (response == AVERROR(EAGAIN) || response == AVERROR_EOF)
  196.         {
  197.             break;
  198.         }
  199.         else if (response < 0)
  200.         {
  201.             printf("ENCODER: Error receiving packet");
  202.  
  203.             return 1;
  204.         }
  205.  
  206.         output_packet->stream_index = index;
  207.  
  208.         //I think we have to set PTS, DTS and duration for each packet.
  209.         ////////////////////////////////////////////////////////////////////////
  210.         //output_packet->pts = input_frame->pts;
  211.         //output_packet->dts = input_frame->pkt_dts;
  212.         //output_packet->duration = input_frame->pkt_duration;
  213.         AVRational fps = codec->framerate;
  214.         int frames_per_packet = 1;
  215.  
  216.         if (encoder->container->streams[index]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
  217.         {
  218.             fps.den = 1;
  219.             fps.num = encoder->container->streams[index]->codecpar->sample_rate;
  220.  
  221.             ////////////////////////////////////////////////////////////////////
  222.             frames_per_packet = encoder->container->streams[index]->codecpar->frame_size; //For the audio there are 1024 (or 960) frames per packet https://stackoverflow.com/questions/23216103/about-definition-for-terms-of-audio-codec
  223.             ////////////////////////////////////////////////////////////////////
  224.         }
  225.  
  226.         AVRational time_base = encoder->container->streams[index]->time_base;
  227.  
  228.         output_packet->duration = (int64_t)(av_q2d(av_div_q((AVRational){time_base.den, 1}, fps))) * (int64_t)frames_per_packet;
  229.         output_packet->pts = (int64_t)(output_packet->duration * encoder->packets[index]);
  230.         output_packet->dts = output_packet->pts;
  231.  
  232.         encoder->packets[index]++; //Count packets
  233.         ////////////////////////////////////////////////////////////////////////
  234.  
  235.         response = av_interleaved_write_frame(encoder->container, output_packet);
  236.  
  237.         if (response != 0)
  238.         {
  239.             printf("ENCODER:failed writing frame");
  240.  
  241.             return 1;
  242.         }
  243.     }
  244.  
  245.     av_packet_free(&output_packet);
  246.  
  247.     return 0;
  248. }
  249.  
  250. int free_file(file *f)
  251. {
  252.     int i;
  253.     for (i = 0; i < (int)f->container->nb_streams; i++)
  254.     {
  255.         if (f->codec[i] == NULL)
  256.         {
  257.             continue;
  258.         }
  259.         avcodec_free_context(&f->codec[i]);
  260.     }
  261.  
  262.     //av_free - Free a memory block which has been allocated with a function of av_malloc(), but f->codec is not allocated with av_malloc()???
  263.     //av_free(f->codec);
  264.  
  265.     avformat_close_input(&f->container);
  266.  
  267.     ////////////////////////////////////////////////////////////////////////
  268.     if (f->frames != NULL)
  269.     {
  270.         free(f->frames);
  271.     }
  272.  
  273.     if (f->packets != NULL)
  274.     {
  275.         free(f->packets);
  276.     }
  277.     ////////////////////////////////////////////////////////////////////////
  278.  
  279.     free(f);
  280.  
  281.     return 0;
  282. }
  283.  
  284. int fill_with_empty_frames_until_all_streams_match_pts(file *input, file *output)
  285. {
  286.     int res;
  287.  
  288.     int biggest_pts = 0;
  289.     int biggest_pts_index = -1;
  290.  
  291.     for (int i = 0; i < output->container->nb_streams; i++)
  292.     {
  293.         int curr_pts_in_new_time_base = av_rescale_q(output->pre_pts[i], output->container->streams[i]->time_base, (AVRational){.den = 60000, .num = 1});
  294.    
  295.         if (curr_pts_in_new_time_base > biggest_pts)
  296.         {
  297.             biggest_pts = curr_pts_in_new_time_base;
  298.             biggest_pts_index = i;
  299.         }
  300.     }
  301.  
  302.     for (int i = 0; i < output->container->nb_streams; i++)
  303.     {
  304.  
  305.         AVCodecContext *codec = output->codec[i];
  306.         AVRational fps = output->codec[i]->framerate;
  307.         AVRational time_base = output->container->streams[i]->time_base;
  308.  
  309.         int frames_per_packet = 1;
  310.  
  311.         if (output->container->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
  312.         {
  313.             fps.den = 1;
  314.             fps.num = input->container->streams[i]->codecpar->sample_rate;
  315.  
  316.             ////////////////////////////////////////////////////////////////////
  317.             frames_per_packet = input->container->streams[i]->codecpar->frame_size; //For the audio there are 1024 (or 960) frames per packet https://stackoverflow.com/questions/23216103/about-definition-for-terms-of-audio-codec
  318.             ////////////////////////////////////////////////////////////////////
  319.         }
  320.  
  321.         AVFrame *dummy_frame = av_frame_alloc();
  322.  
  323.         switch (output->container->streams[i]->codecpar->codec_type)
  324.         {
  325.         case AVMEDIA_TYPE_AUDIO:
  326.             dummy_frame->nb_samples = frames_per_packet;
  327.             dummy_frame->format = output->container->streams[i]->codecpar->format;
  328.             dummy_frame->channel_layout = output->container->streams[i]->codecpar->channel_layout;
  329.             break;
  330.         case AVMEDIA_TYPE_VIDEO:
  331.             dummy_frame->width = output->container->streams[i]->codecpar->width;
  332.             dummy_frame->height = output->container->streams[i]->codecpar->height;
  333.             dummy_frame->format = output->container->streams[i]->codecpar->format;
  334.             break;
  335.         default:
  336.             continue;
  337.         }
  338.  
  339.         av_frame_get_buffer(dummy_frame, 0);
  340.  
  341.         while (1)
  342.         {
  343.             int64_t pkt_duration = (int64_t)(av_q2d(av_div_q((AVRational){time_base.den, 1}, fps))) * (int64_t)frames_per_packet;
  344.             int curr_pts_in_new_time_base = av_rescale_q(pkt_duration * output->frames[i], output->container->streams[i]->time_base, (AVRational){.den = 60000, .num = 1});
  345.             printf("biggest_pts %i\n", biggest_pts);
  346.             printf("curr_pts_in_new_time_base %i\n", curr_pts_in_new_time_base);
  347.  
  348.             printf("Adding frame\n");
  349.             if (biggest_pts <= curr_pts_in_new_time_base)
  350.                 break;
  351.             dummy_frame->pkt_duration = pkt_duration;
  352.             dummy_frame->pts = (int64_t)(dummy_frame->pkt_duration * output->frames[i]);
  353.  
  354.             dummy_frame->pkt_dts = dummy_frame->pts;
  355.  
  356.             printf("%i FRAME %i PTS %i\n", (int)i, (int)output->frames[i], (int)dummy_frame->pts);
  357.  
  358.             output->frames[i]++;
  359.  
  360.             res = encode_frame(output, dummy_frame, i);
  361.         }
  362.         av_frame_free(&dummy_frame);
  363.     }
  364. }
  365.  
  366. int open_media(file *video, const char input_path[], const char *video_codec, const char *audio_codec)
  367. {
  368.     video->container = avformat_alloc_context();
  369.  
  370.     if (!video->container)
  371.     {
  372.         printf("Failed to alloc memory to the container of the input file");
  373.         return 1;
  374.     }
  375.     if (avformat_open_input(&video->container, input_path, NULL, NULL) != 0)
  376.     {
  377.         printf("Failed to open input file");
  378.         return 1;
  379.     }
  380.     if (avformat_find_stream_info(video->container, NULL) < 0)
  381.     {
  382.         printf("Failed to open read stream info");
  383.         return 1;
  384.     }
  385.  
  386.     video->codec = calloc(video->container->nb_streams, sizeof(AVCodecContext *));
  387.  
  388.     for (unsigned int i = 0; i < video->container->nb_streams; i++)
  389.     {
  390.         const char *curr_codec = NULL;
  391.  
  392.         AVStream *stream = video->container->streams[i];
  393.         const AVCodec *dec;
  394.         AVCodecContext *codec_ctx;
  395.  
  396.         if (AVMEDIA_TYPE_VIDEO == stream->codecpar->codec_type)
  397.         {
  398.             curr_codec = video_codec;
  399.         }
  400.         else if (AVMEDIA_TYPE_AUDIO == stream->codecpar->codec_type)
  401.         {
  402.             curr_codec = audio_codec;
  403.         }
  404.  
  405.         if (curr_codec == NULL)
  406.             dec = avcodec_find_decoder(stream->codecpar->codec_id);
  407.         else
  408.             dec = avcodec_find_decoder_by_name(video_codec);
  409.  
  410.         if (!dec)
  411.         {
  412.             printf("failed to find the codec");
  413.             return 1;
  414.         }
  415.  
  416.         codec_ctx = avcodec_alloc_context3(dec);
  417.         if (!codec_ctx)
  418.         {
  419.             printf("failed to alloc memory for codec context");
  420.             return 1;
  421.         }
  422.  
  423.         if (avcodec_parameters_to_context(codec_ctx, stream->codecpar) < 0)
  424.         {
  425.             printf("failed to fill codec context");
  426.             return 1;
  427.         }
  428.  
  429.         if (avcodec_open2(codec_ctx, dec, NULL) < 0)
  430.         {
  431.             printf("failed to open codec");
  432.             return 1;
  433.         }
  434.  
  435.         video->codec[i] = codec_ctx;
  436.     }
  437.     return 0;
  438. }
  439.  
  440. /*
  441.     returns:
  442.     1 if error
  443.     0 if success
  444.     -1 if file ended
  445. */
  446. int decode_frame(file *decoder, AVFrame *frame, AVPacket *packet)
  447. {
  448.     AVCodecContext *dec;
  449.  
  450.     while (1)
  451.     {
  452.         av_packet_unref(packet);
  453.         if (av_read_frame(decoder->container, packet) < 0)
  454.             break;
  455.  
  456.         int index = packet->stream_index;
  457.  
  458.         dec = decoder->codec[index];
  459.  
  460.         int response = avcodec_send_packet(dec, packet);
  461.  
  462.         if (response < 0)
  463.         {
  464.             printf("Error while sending packet to decoder");
  465.             return 1;
  466.         }
  467.  
  468.         while (response >= 0)
  469.         {
  470.             response = avcodec_receive_frame(dec, frame);
  471.             if (response == AVERROR(EAGAIN) || response == AVERROR_EOF)
  472.             {
  473.                 break;
  474.             }
  475.             else if (response < 0)
  476.             {
  477.                 printf("Error while receiving frame from decoder");
  478.                 return 1;
  479.             }
  480.             if (response >= 0)
  481.             {
  482.                 return 0;
  483.             }
  484.             av_frame_unref(frame);
  485.         }
  486.     }
  487.     return -1;
  488. }
  489. int create_audio_encoder(AVCodecContext **cod_ctx, AVFormatContext *container, const char *encoder,
  490.                          int channels, int sample_rate, int bit_rate)
  491. {
  492.     AVStream *stream = avformat_new_stream(container, NULL);
  493.     if (!stream)
  494.     {
  495.         printf("CREATE AUDIO ENCODER: Failed allocating memory for stream");
  496.         return 1;
  497.     }
  498.     const AVCodec *enc = avcodec_find_encoder_by_name(encoder);
  499.     if (!enc)
  500.     {
  501.         printf("CREATE AUDIO ENCODER: Failed searching encoder");
  502.  
  503.         return 1;
  504.     }
  505.  
  506.     cod_ctx[0] = avcodec_alloc_context3(enc);
  507.  
  508.     if (!cod_ctx[0])
  509.     {
  510.         printf("CREATE AUDIO ENCODER: Failed allocation codec context");
  511.         return 1;
  512.     }
  513.  
  514.     cod_ctx[0]->channels = channels;
  515.     cod_ctx[0]->channel_layout = av_get_default_channel_layout(channels);
  516.     cod_ctx[0]->sample_rate = sample_rate;
  517.     cod_ctx[0]->sample_fmt = *enc->sample_fmts;
  518.     cod_ctx[0]->bit_rate = bit_rate;
  519.     cod_ctx[0]->time_base = (AVRational){1, sample_rate}; // 1/48000
  520.  
  521.     int res = 0;
  522.  
  523.     res = avcodec_open2(cod_ctx[0], enc, NULL);
  524.     if (res < 0)
  525.     {
  526.         printf("CREATE AUDIO ENCODER: couldn't open codec");
  527.         return 1;
  528.     }
  529.  
  530.     res = avcodec_parameters_from_context(stream->codecpar, cod_ctx[0]);
  531.  
  532.     if (res < 0)
  533.     {
  534.         printf("CREATE AUDIO ENCODER: failed setting codec parameters from context");
  535.         return 1;
  536.     }
  537.  
  538.     return 0;
  539. }
  540.  
  541. int create_video_encoder(AVCodecContext **cod_ctx, AVFormatContext *container, const char *encoder, int width, int height,
  542.                          int pix_fmt, AVRational sample_aspect_ratio, AVRational frame_rate, int bit_rate, int buffer_size)
  543. {
  544.     AVStream *stream = avformat_new_stream(container, NULL);
  545.     if (!stream)
  546.     {
  547.         printf("CREATE VIDEO ENCODER: Failed allocating memory for stream");
  548.         return 1;
  549.     }
  550.     const AVCodec *enc = avcodec_find_encoder_by_name(encoder);
  551.     if (!enc)
  552.     {
  553.         printf("CREATE VIDEO ENCODER: Failed searching encoder");
  554.  
  555.         return 1;
  556.     }
  557.  
  558.     cod_ctx[0] = avcodec_alloc_context3(enc);
  559.  
  560.     if (!cod_ctx[0])
  561.     {
  562.         printf("CREATE VIDEO ENCODER: Failed allocation codec context");
  563.         return 1;
  564.     }
  565.  
  566.     cod_ctx[0]->height = height;
  567.     cod_ctx[0]->width = width;
  568.     cod_ctx[0]->pix_fmt = pix_fmt;
  569.  
  570.     cod_ctx[0]->sample_aspect_ratio = sample_aspect_ratio;
  571.  
  572.     //It's not a good idea to set the video time base to 1/60 - we need higher resolution for allowing audio synchronization
  573.     ////////////////////////////////////////////////////////////////////////////
  574.     cod_ctx[0]->time_base = av_make_q(1, 60000); //av_inv_q(frame_rate);
  575.     ////////////////////////////////////////////////////////////////////////////
  576.  
  577.     cod_ctx[0]->framerate = frame_rate;
  578.     cod_ctx[0]->bit_rate = bit_rate;
  579.     cod_ctx[0]->rc_buffer_size = buffer_size;
  580.     cod_ctx[0]->rc_max_rate = buffer_size;
  581.     cod_ctx[0]->rc_min_rate = buffer_size;
  582.  
  583.     stream->time_base = cod_ctx[0]->time_base; //cod_ctx->time_base;
  584.  
  585.     int res = 0;
  586.  
  587.     res = av_opt_set(cod_ctx[0]->priv_data, "preset", "fast", 0);
  588.  
  589.     if (res != 0)
  590.     {
  591.         printf("CREATE VIDEO ENCODER: Failed opt set");
  592.         return 1;
  593.     }
  594.  
  595.     res = avcodec_open2(cod_ctx[0], enc, NULL);
  596.     if (res < 0)
  597.     {
  598.         printf("CREATE VIDEO ENCODER: couldn't open codec");
  599.         return 1;
  600.     }
  601.  
  602.     res = avcodec_parameters_from_context(stream->codecpar, cod_ctx[0]);
  603.  
  604.     if (res < 0)
  605.     {
  606.         printf("CREATE VIDEO ENCODER: failed setting codec parameters from context");
  607.         return 1;
  608.     }
  609.  
  610.     return 0;
  611. }
  612.  
  613. file *start_output_from_file(const char *path, file *input, const char *video_encoder, const char *audio_encoder)
  614. {
  615.     int res;
  616.  
  617.     file *output = create_output(input->container->nb_streams, path);
  618.     if (!output)
  619.     {
  620.         return NULL;
  621.     }
  622.     AVCodecContext *codec_ctx;
  623.     output->frames = calloc(input->container->nb_streams, sizeof(int));
  624.     output->packets = calloc(input->container->nb_streams, sizeof(int));
  625.     output->last_pts = calloc(input->container->nb_streams, sizeof(int));
  626.     output->pre_pts = calloc(input->container->nb_streams, sizeof(int));
  627.  
  628.     for (int stream = 0; stream < (int)input->container->nb_streams; stream++)
  629.     {
  630.         codec_ctx = input->codec[stream];
  631.  
  632.         switch (codec_ctx->codec_type)
  633.         {
  634.         case AVMEDIA_TYPE_AUDIO:
  635.             if (audio_encoder == NULL)
  636.             {
  637.                 audio_encoder = codec_ctx->codec_descriptor->name;
  638.             }
  639.             res = create_audio_encoder(&output->codec[stream], output->container, audio_encoder, codec_ctx->channels, codec_ctx->sample_rate, (int)codec_ctx->bit_rate);
  640.  
  641.             break;
  642.  
  643.         case AVMEDIA_TYPE_VIDEO:
  644.  
  645.             if (video_encoder == NULL)
  646.             {
  647.                 video_encoder = codec_ctx->codec_descriptor->name;
  648.             }
  649.             AVRational framerate = av_guess_frame_rate(input->container, input->container->streams[stream], NULL);
  650.             res = create_video_encoder(&output->codec[stream], output->container, video_encoder, codec_ctx->width, codec_ctx->height,
  651.                                        23, (AVRational){1, 1}, framerate, (int)codec_ctx->bit_rate, codec_ctx->rc_buffer_size);
  652.             break;
  653.         }
  654.         if (res != 0)
  655.         {
  656.             printf("Failed opening encoder stream number %i \n", stream);
  657.             return NULL;
  658.         }
  659.     }
  660.  
  661.     if (output->container->oformat->flags & AVFMT_GLOBALHEADER)
  662.         output->container->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
  663.  
  664.     if (!(output->container->oformat->flags & AVFMT_NOFILE))
  665.     {
  666.         if (avio_open(&output->container->pb, path, AVIO_FLAG_WRITE) < 0)
  667.         {
  668.             printf("could not open the output file");
  669.             return NULL;
  670.         }
  671.     }
  672.  
  673.     AVDictionary *muxer_opts = NULL;
  674.  
  675.     if (avformat_write_header(output->container, &muxer_opts) < 0)
  676.     {
  677.         printf("an error occurred when opening output file");
  678.         return NULL;
  679.     }
  680.  
  681.     return output;
  682. }
  683.  
  684. file *create_output(int streams, const char *filename)
  685. {
  686.     int res;
  687.  
  688.     //file* output = malloc(sizeof(file));
  689.     file *output = calloc(sizeof(file), 1);
  690.     if (!output)
  691.     {
  692.         return NULL;
  693.     }
  694.     res = avformat_alloc_output_context2(&output->container, NULL, NULL, filename);
  695.     if (res < 0)
  696.     {
  697.         printf("Failed opening output\n");
  698.         return NULL;
  699.     }
  700.  
  701.     output->codec = av_calloc(streams, sizeof(AVCodecContext *));
  702.  
  703.     if (!output->codec)
  704.     {
  705.         printf("Failed allocating ram for codec\n");
  706.         return NULL;
  707.     }
  708.  
  709.     for (int stream = 0; stream < streams; stream++)
  710.     {
  711.         output->codec[stream] = NULL;
  712.     }
  713.  
  714.     return output;
  715. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement