Advertisement
Guest User

Untitled

a guest
Aug 23rd, 2021
254
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 20.69 KB | None | 0 0
  1. #include <libavcodec/avcodec.h>
  2. #include <libavformat/avformat.h>
  3. #include <libavfilter/avfilter.h>
  4. #include <libavfilter/buffersink.h>
  5. #include <libavfilter/buffersrc.h>
  6. #include <libavutil/opt.h>
  7. #include <libavutil/pixdesc.h>
  8. #include <stdint.h>
  9. #include <stdbool.h>
  10. #include "resize.h"
  11. #include "chat.h"
  12. #include "shape.h"
  13. #include "write.h"
  14. typedef struct file
  15. {
  16.     AVFormatContext* container;
  17.     AVCodecContext** codec;
  18.     bool* remux;
  19. } file;
  20.  
  21. typedef struct transcodingParams {
  22.     int width;
  23.     int height;
  24.     int tmpPix;
  25.     int finalPix;
  26.     int channel;
  27.     int nb_streams;
  28.     int64_t bitRate;
  29.     int64_t sampleRate;
  30.     int videoIndex;
  31.     int audioIndex;
  32.     char* videoEncoder;
  33.     char* videoDecoder;
  34.     char* audioEncoder;
  35.     char* audioDecoder;
  36.     AVRational sampleAspectRatio;
  37.     AVRational frameRate;
  38.     AVRational timebase;
  39. }transcodingParams;
  40.  
  41. typedef struct filterCtx {
  42.     AVFilterContext* buffersink_ctx;
  43.     AVFilterContext* buffersrc_ctx;
  44.     AVFilterGraph* filter_graph;
  45. }filterCtx;
  46.  
  47. #define AUDIODECODER "copy"
  48. #define AUDIOENCODER "copy"
  49. #define VIDEODECODER "copy"
  50. #define VIDEOENCODER "copy"
  51. #define AUDIOINDEX -1
  52. #define BITRATE 0
  53. #define CHANNEL 0
  54. #define FINALPIX -1
  55. #define FRAMERATE 0
  56. #define SAMPLEASPECTRATIO 0
  57. #define HEIGHT 0
  58. #define NBSTREAMS 0
  59. #define WIDTH 0
  60. #define TIMEBASE 0
  61. #define TMPPIX -1
  62. #define VIDEOINDEX -1
  63. #define SAMPLERATE 0
  64. #define PROGRESSBARLENGTH 50
  65. #define END               0
  66. #define ERROR              -1
  67. #define ENCODE             1
  68. #define REMUX              2
  69. #define CONTINUE           3
  70. #define EDIT               4
  71. #define EVER               ;;
  72.  
  73. filterCtx* initFilter(char* description, transcodingParams* params);
  74. void printProgress(unsigned int total, unsigned int left);
  75. int open_media(file* video, char* name, transcodingParams* params);
  76. int encode(file* decoder, file* encoder, AVFrame* input_frame, int index);
  77. int getFrame(file* decoder, AVFrame* frame, AVPacket* packet);
  78. int remux(file* decoder, file* encoder, AVPacket* packet);
  79. int createEncoders(file* encoder, transcodingParams* params);
  80. int getIndex(int type);
  81. void SaveFrame(AVFrame* pFrame, int width, int height, char* filename);
  82. static void save_gray_frame(unsigned char* buf, int wrap, int xsize, int ysize, char* filename);
  83. int applyFilter(filterCtx* filter, AVFrame* inFrame, AVFrame* outframe);
  84.  
  85. unsigned int frameNumber = 0;
  86. unsigned int totalFrames = 0;
  87. transcodingParams* createParams()
  88. {
  89.     transcodingParams* newParam = malloc(sizeof(transcodingParams));
  90.     if (newParam == NULL)
  91.     {
  92.         return NULL;
  93.     }
  94.     newParam->audioDecoder = malloc(sizeof(AUDIODECODER));
  95.     if (newParam->audioDecoder == NULL) { return NULL; }
  96.     strcpy_s(newParam->audioDecoder, sizeof(AUDIODECODER), AUDIODECODER);
  97.  
  98.     newParam->audioEncoder = malloc(sizeof(AUDIOENCODER));
  99.     if (newParam->audioEncoder == NULL) { return NULL; }
  100.     strcpy_s(newParam->audioEncoder, sizeof(AUDIOENCODER), AUDIOENCODER);
  101.  
  102.     newParam->videoEncoder = malloc(sizeof(VIDEOENCODER));
  103.     if (newParam->videoEncoder == NULL) { return NULL; }
  104.     strcpy_s(newParam->videoEncoder, sizeof(VIDEOENCODER), VIDEOENCODER);
  105.  
  106.     newParam->videoDecoder = malloc(sizeof(VIDEODECODER));
  107.     if (newParam->videoDecoder == NULL) { return NULL; }
  108.     strcpy_s(newParam->videoDecoder, sizeof(VIDEODECODER), VIDEODECODER);
  109.  
  110.     newParam->sampleAspectRatio.den = SAMPLEASPECTRATIO;
  111.     newParam->sampleAspectRatio.num = SAMPLEASPECTRATIO;
  112.     newParam->frameRate.den = FRAMERATE;
  113.     newParam->frameRate.num = FRAMERATE;
  114.     newParam->timebase.num = TIMEBASE;
  115.     newParam->timebase.den = TIMEBASE;
  116.     newParam->bitRate = BITRATE;
  117.     newParam->channel = BITRATE;
  118.     newParam->sampleRate = SAMPLERATE;
  119.     newParam->finalPix = FINALPIX;
  120.     newParam->tmpPix = TMPPIX;
  121.     newParam->height = HEIGHT;
  122.     newParam->width = WIDTH;
  123.     newParam->videoIndex = VIDEOINDEX;
  124.     newParam->nb_streams = NBSTREAMS;
  125.     newParam->audioIndex = AUDIOINDEX;
  126. }
  127. int main()
  128. {
  129.  
  130.     //char* VideoCodec[] = { "h264_cuvid","h264_nvenc" };
  131.     char videoDecoder[] = "h264_cuvid";
  132.     char videoEncoder[] = "h264_nvenc";
  133.     int tmpPix = AV_PIX_FMT_RGB24;
  134.     int finalPix = -1;
  135.     int bitRate = 196000;
  136.     int channel = 2;
  137.     int h = 0;
  138.     int w = 0;
  139.  
  140.  
  141.     transcodingParams* params = malloc(sizeof(transcodingParams) * 2);
  142.  
  143.  
  144.     if (params == NULL)
  145.     {
  146.         return -1;
  147.     }
  148.     params[0] = *createParams();
  149.     params[1] = *createParams();
  150.     params[1].tmpPix;
  151.     params[1].videoDecoder = videoDecoder;
  152.     params[1].videoEncoder = videoEncoder;
  153.     params[1].bitRate = 196000;
  154.     params[1].channel = 2;
  155.     params[1].frameRate.den = 30000;
  156.     params[1].frameRate.num = 1000;
  157.     params[1].height = 1200;
  158.     params[1].width = 1200;
  159.  
  160.     file* decoder = (file*)calloc(1, sizeof(file));
  161.     file* encoder = (file*)calloc(1, sizeof(file));
  162.  
  163.     if (decoder == NULL || encoder == NULL)
  164.     {
  165.         return -1;
  166.     }
  167.  
  168.     char input[] = "https://clips-media-assets2.twitch.tv/AT-cm%7C1257727679.mp4";
  169.     char output[] = "out.avi";
  170.  
  171.     if (!open_media(decoder, input, params))
  172.     {
  173.         return -1;
  174.     }
  175.     int response = checkChanges(params);
  176.     if (response > 0)
  177.     {
  178.         printf("error while comparing params");
  179.         return -1;
  180.     }
  181.     avformat_alloc_output_context2(&encoder->container, NULL, NULL, output);
  182.     if (!encoder->container)
  183.     {
  184.         return -1;
  185.     }
  186.  
  187.     if (createEncoders(encoder, params))
  188.     {
  189.         return -1;
  190.     }
  191.  
  192.     if (encoder->container->oformat->flags & AVFMT_GLOBALHEADER)
  193.         encoder->container->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
  194.  
  195.     if (!(encoder->container->oformat->flags & AVFMT_NOFILE))
  196.     {
  197.         if (avio_open(&encoder->container->pb, output, AVIO_FLAG_WRITE) < 0)
  198.         {
  199.             printf("could not open the output file");
  200.             return -1;
  201.         }
  202.     }
  203.  
  204.     AVDictionary* muxer_opts = NULL;
  205.     if (avformat_write_header(encoder->container, &muxer_opts) < 0)
  206.     {
  207.         printf("an error occurred when opening output file");
  208.         return -1;
  209.     }
  210.     /*
  211.     shape* chat;
  212.  
  213.  
  214.     int height = h * 50 / 100;
  215.     int width = w * 50 / 100;
  216.  
  217.     struct SwsContext* first = NULL;
  218.     struct SwsContext* second = NULL;
  219.     chat = initChat(height, width, 500, h - height);
  220.     */
  221.     //filterDesc = "fps=fps=60000/1001";
  222.     //char* filterDesc = "scale=250:250";
  223.  
  224.  
  225.     AVFrame* frame = av_frame_alloc();
  226.     AVPacket* packet = av_packet_alloc();
  227.     AVFrame* filterFrame = av_frame_alloc();
  228.     AVFrame* tmp = NULL;
  229.     if (!frame || !packet || !filterFrame)
  230.     {
  231.         return -1;
  232.     }
  233.  
  234. #define FILTERSIZE 1024
  235.     char filterDesc[FILTERSIZE];
  236.     char currFilter[FILTERSIZE];
  237.     filterDesc[0] = '\0';
  238.     if (params[0].height != params[1].height || params[0].width != params[1].width)
  239.     {
  240.         if (filterDesc[0] != '\0') { strcat_s(filterDesc, FILTERSIZE, ","); }
  241.         snprintf(currFilter, FILTERSIZE, "scale=%i:%i", params[1].width, params[1].height);
  242.         strcat_s(filterDesc, FILTERSIZE, currFilter);
  243.         currFilter[0] = '\0';
  244.     }
  245.     if (params[0].frameRate.den != params[1].frameRate.den || params[0].frameRate.num != params[1].frameRate.num)
  246.     {
  247.         if (filterDesc[0] != '\0') { strcat_s(filterDesc, FILTERSIZE, ","); }
  248.         snprintf(currFilter, FILTERSIZE, "fps=%i/%i", params[1].frameRate.den, params[1].frameRate.num);
  249.         strcat_s(filterDesc, FILTERSIZE, currFilter);
  250.         currFilter[0] = '\0';
  251.     }
  252.     filterCtx* filter = NULL;
  253.     if (filterDesc[0] != '\0')
  254.     {
  255.         filter = initFilter(filterDesc, params);
  256.     }
  257.     for (EVER)
  258.     {
  259.         response = getFrame(decoder, frame, packet);
  260.  
  261.         switch (response)
  262.         {
  263.         case EDIT:
  264.             switch (decoder->container->streams[packet->stream_index]->codecpar->codec_type)
  265.             {
  266.             case AVMEDIA_TYPE_VIDEO:
  267.                 if (filter != NULL)
  268.                 {
  269.                     response = applyFilter(filter, frame, filterFrame);
  270.                     if (response < 0)
  271.                     {
  272.                         printf("Error while applying a filter");
  273.                         return -1;
  274.                     }
  275.                     tmp = frame;
  276.                     av_frame_unref(frame);
  277.                     frame = filterFrame;
  278.                     filterFrame = tmp;
  279.                     putchar('\n');
  280.                     printf("%p\n",frame);
  281.                     printf("%p\n",filterFrame);
  282.                     printf("%p\n",tmp);
  283.                     if (response == CONTINUE)
  284.                     {
  285.                         continue;
  286.                     }
  287.                 }
  288.  
  289.                 break;
  290.             case AVMEDIA_TYPE_AUDIO:
  291.                 break;
  292.             }
  293.             break;
  294.         case REMUX:
  295.             continue;
  296.         case ERROR:
  297.             return ERROR;
  298.         case END:
  299.             av_write_trailer(encoder->container);
  300.             return 1;
  301.         }
  302.         if (response == ERROR)
  303.         {
  304.             return ERROR;
  305.         }
  306.         response = encode(decoder, encoder, frame, packet->stream_index);
  307.         if (response == ERROR)
  308.         {
  309.             return ERROR;
  310.         }
  311.  
  312.     }
  313.  
  314. }
  315. /*
  316. *
  317. //tmp = resize(first, frame, w, h, tmpPix);
  318.  
  319. frame = tmp;
  320. applyChat(chat, frame);
  321. char* filename = malloc(sizeof(char) * 512);
  322. snprintf(filename, 70, "C:/Users/gvian/source/repos/chat/chat/frames/After/frame%05d.ppm", frameNumber);
  323.  
  324. frameNumber++;
  325. SaveFrame(frame, frame->width, frame->height, filename);
  326. tmp = resize(second, frame, w, h, decoder->codec[
  327. videoIndex]->pix_fmt);
  328. av_frame_free(&frame);
  329. av_frame_unref(frame);
  330. frame = tmp;
  331. tmp = NULL;
  332.  
  333.  
  334. */
  335. int checkChanges(transcodingParams* params)
  336. {
  337.     if (strcmp(params[1].audioDecoder, AUDIODECODER) == 0) { params[1].audioDecoder = params[0].audioDecoder; }
  338.     if (strcmp(params[1].audioEncoder, AUDIOENCODER) == 0) { params[1].audioEncoder = params[0].audioEncoder; }
  339.     if (params[1].audioIndex == AUDIOINDEX) { params[1].audioIndex = params[0].audioIndex; }
  340.     if (params[1].bitRate == BITRATE) { params[1].bitRate = params[0].bitRate; }
  341.     if (params[1].channel == CHANNEL) { params[1].channel = params[0].channel; }
  342.     if (params[1].finalPix == FINALPIX) { params[1].finalPix = params[0].finalPix; }
  343.     if (params[1].frameRate.den == FRAMERATE && params[1].frameRate.num == FRAMERATE) { params[1].frameRate = params[0].frameRate; }
  344.     if (params[1].sampleAspectRatio.den == SAMPLEASPECTRATIO && params[1].sampleAspectRatio.num == SAMPLEASPECTRATIO) { params[1].sampleAspectRatio = params[0].sampleAspectRatio; }
  345.     if (params[1].height == HEIGHT) { params[1].height = params[0].height; }
  346.     if (params[1].nb_streams == NBSTREAMS) { params[1].nb_streams = params[0].nb_streams; }
  347.     if (params[1].width == WIDTH) { params[1].width = params[0].width; }
  348.     if (params[1].timebase.den == TIMEBASE && params[1].timebase.num == TIMEBASE) { params[1].timebase = params[0].timebase; }
  349.     if (params[1].tmpPix == TMPPIX) { params[1].tmpPix = params[0].tmpPix; }
  350.     if (strcmp(params[1].videoDecoder, VIDEODECODER) == 0) { params[1].videoDecoder = params[0].videoDecoder; }
  351.     if (strcmp(params[1].videoEncoder, VIDEOENCODER) == 0) { params[1].videoEncoder = params[0].videoEncoder; }
  352.     if (params[1].videoIndex == VIDEOINDEX) { params[1].videoIndex = params[0].videoIndex; }
  353.     if (params[1].sampleRate == SAMPLERATE) { params[1].sampleRate = params[0].sampleRate; }
  354.     return 0;
  355. }
  356.  
  357. filterCtx* initFilter(char* description, transcodingParams* params)
  358. {
  359.  
  360.     filterCtx* filter = malloc(sizeof(filterCtx));
  361.  
  362.     char args[512];
  363.     int ret = 0;
  364.  
  365.  
  366.     filter->buffersrc_ctx = NULL;
  367.     filter->buffersink_ctx = NULL;
  368.     AVFilterInOut* outputs = avfilter_inout_alloc();
  369.     AVFilterInOut* inputs = avfilter_inout_alloc();
  370.     filter->filter_graph = avfilter_graph_alloc();
  371.  
  372.     AVFilter* buffersrc = avfilter_get_by_name("buffer");
  373.     AVFilter* buffersink = avfilter_get_by_name("buffersink");
  374.  
  375.  
  376.  
  377.     if (!outputs || !inputs || !filter->filter_graph) {
  378.         return NULL;
  379.     }
  380.  
  381.  
  382.     buffersrc = avfilter_get_by_name("buffer");
  383.     buffersink = avfilter_get_by_name("buffersink");
  384.     if (!buffersrc || !buffersink)
  385.     {
  386.         return NULL;
  387.     }
  388.  
  389.     snprintf(args, sizeof(args),
  390.         "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
  391.         params[0].width, params[0].height, params[0].finalPix,
  392.         params[0].timebase.num, params[0].timebase.den,
  393.         params[0].sampleAspectRatio.num,
  394.         params[0].sampleAspectRatio.den);
  395.  
  396.     ret = avfilter_graph_create_filter(&filter->buffersrc_ctx, buffersrc, "in",
  397.         args, NULL, filter->filter_graph);
  398.     if (ret < 0)
  399.     {
  400.         return NULL;
  401.     }
  402.  
  403.     ret = avfilter_graph_create_filter(&filter->buffersink_ctx, buffersink, "out",
  404.         NULL, NULL, filter->filter_graph);
  405.     if (ret < 0)
  406.     {
  407.         return NULL;
  408.     }
  409.  
  410.     ret = av_opt_set_bin(filter->buffersink_ctx, "pix_fmts",
  411.         (uint8_t*)&params[0].finalPix, sizeof(params[0].finalPix),
  412.         AV_OPT_SEARCH_CHILDREN);
  413.     if (ret < 0)
  414.     {
  415.         return NULL;
  416.     }
  417.  
  418.     /* Endpoints for the filter graph. */
  419.     outputs->name = av_strdup("in");
  420.     outputs->filter_ctx = filter->buffersrc_ctx;
  421.     outputs->pad_idx = 0;
  422.     outputs->next = NULL;
  423.  
  424.     inputs->name = av_strdup("out");
  425.     inputs->filter_ctx = filter->buffersink_ctx;
  426.     inputs->pad_idx = 0;
  427.     inputs->next = NULL;
  428.  
  429.     if (!outputs->name || !inputs->name)
  430.     {
  431.         return NULL;
  432.     }
  433.  
  434.     if ((ret = avfilter_graph_parse_ptr(filter->filter_graph, description, &inputs, &outputs, NULL)) < 0)
  435.     {
  436.         return NULL;
  437.  
  438.     }
  439.  
  440.     if ((ret = avfilter_graph_config(filter->filter_graph, NULL)) < 0)
  441.     {
  442.         return NULL;
  443.     }
  444.  
  445.  
  446.     /* Fill FilteringContext */
  447.  
  448.  
  449.     avfilter_inout_free(&inputs);
  450.     avfilter_inout_free(&outputs);
  451.  
  452.     return filter;
  453. }
  454. int encode(file* decoder, file* encoder, AVFrame* input_frame, int index)
  455. {
  456.     AVPacket* output_packet = av_packet_alloc();
  457.     AVCodecContext* codec = encoder->codec[index];
  458.     AVStream* stream = decoder->container->streams[index];
  459.     if (!output_packet)
  460.     {
  461.         return ERROR;
  462.     }
  463.  
  464.     int response = avcodec_send_frame(codec, input_frame);
  465.  
  466.     while (response >= 0)
  467.     {
  468.         response = avcodec_receive_packet(codec, output_packet);
  469.         if (response == AVERROR(EAGAIN) || response == AVERROR_EOF)
  470.         {
  471.             break;
  472.         }
  473.         else if (response < 0)
  474.         {
  475.             return ERROR;
  476.         }
  477.  
  478.         output_packet->stream_index = index;
  479.  
  480.         av_packet_rescale_ts(output_packet, stream->time_base, encoder->container->streams[index]->time_base);
  481.  
  482.         response = av_interleaved_write_frame(encoder->container, output_packet);
  483.         if (response != 0)
  484.         {
  485.             return ERROR;
  486.         }
  487.     }
  488.     av_packet_unref(output_packet);
  489.     av_packet_free(&output_packet);
  490.     return CONTINUE;
  491. }
  492.  
  493. int applyFilter(filterCtx* filter, AVFrame* inFrame, AVFrame* outFrame)
  494. {
  495.     int ret;
  496.     /* push the decoded frame into the filtergraph */
  497.     if (av_buffersrc_add_frame_flags(filter->buffersrc_ctx, inFrame, AV_BUFFERSRC_FLAG_KEEP_REF) < 0)
  498.     {
  499.         return 0;
  500.     }
  501.  
  502.     /* pull filtered frames from the filtergraph */
  503.     for (EVER)
  504.     {
  505.         ret = av_buffersink_get_frame(filter->buffersink_ctx, outFrame);
  506.         if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
  507.         {
  508.             return CONTINUE;
  509.         }
  510.         if (ret < 0)
  511.         {
  512.             return -1;
  513.         }
  514.         return 0;
  515.     }
  516.    
  517. }
  518. static void save_gray_frame(unsigned char* buf, int wrap, int xsize, int ysize, char* filename)
  519. {
  520.     FILE* f = NULL;
  521.     int i;
  522.     //char filename[32];
  523.     fopen_s(&f, filename, "w");
  524.  
  525.     fprintf(f, "P5\n%d %d\n%d\n", xsize, ysize, 255);
  526.  
  527.     // writing line by line
  528.     for (i = 0; i < ysize; i++)
  529.         fwrite(buf + i * wrap, 1, xsize, f);
  530.     fclose(f);
  531. }
  532.  
  533. void SaveFrame(AVFrame* pFrame, int width, int height, char* filename)
  534. {
  535.     FILE* pFile = NULL;
  536.     int  y;
  537.     // Open file
  538.     fopen_s(&pFile, filename, "wb");
  539.     if (pFile == NULL)
  540.         return;
  541.     // Write header
  542.     fprintf(pFile, "P6\n%d %d\n255\n", width, height);
  543.  
  544.     // Write pixel data
  545.  
  546.     for (y = 0; y < height; y++)
  547.         fwrite(pFrame->data[0] + y * pFrame->linesize[0], 1, width * 3, pFile);
  548.  
  549.  
  550.     // Close file
  551.     fclose(pFile);
  552. }
  553.  
  554. int remux(file* decoder, file* encoder, AVPacket* packet)
  555. {
  556.     int index = packet->stream_index;
  557.     av_packet_rescale_ts(packet, decoder->container->streams[index]->time_base, encoder->container->streams[index]->time_base);
  558.     if (av_interleaved_write_frame(encoder->container, packet) < 0)
  559.     {
  560.         printf("error while copying stream packet");
  561.         return ERROR;
  562.     }
  563.     return CONTINUE;
  564. }
  565.  
  566. int getFrame(file* decoder, AVFrame* frame, AVPacket* packet)
  567. {
  568.     av_frame_unref(frame);
  569.     AVCodecContext* dec;
  570.     while (av_read_frame(decoder->container, packet) >= 0)
  571.     {
  572.         int index = packet->stream_index;
  573.         if (!decoder->remux[index])
  574.         {
  575.             dec = decoder->codec[index];
  576.             int response = avcodec_send_packet(dec, packet);
  577.             if (response < 0)
  578.             {
  579.                 printf("Error while sending packet to decoder");
  580.                 return ERROR;
  581.             }
  582.             while (response >= 0)
  583.             {
  584.                 response = avcodec_receive_frame(dec, frame);
  585.                 if (response == AVERROR(EAGAIN) || response == AVERROR_EOF)
  586.                 {
  587.                     break;
  588.                 }
  589.                 else if (response < 0)
  590.                 {
  591.                     printf("Error while receiving frame from decoder");
  592.                     return ERROR;
  593.                 }
  594.                 if (response >= 0)
  595.                 {
  596.                     return EDIT;
  597.                 }
  598.                 av_frame_unref(frame);
  599.             }
  600.         }
  601.         else
  602.         {
  603.             return REMUX;
  604.         }
  605.     }
  606.     return END;
  607. }
  608.  
  609.  
  610. int open_media(file* video, char* name, transcodingParams* params)
  611. {
  612.     video->container = avformat_alloc_context();
  613.     if (!video->container)
  614.     {
  615.         printf("Failed to alloc memory to the container of the input file");
  616.         return 1;
  617.     }
  618.     if (avformat_open_input(&video->container, name, NULL, NULL) != 0)
  619.     {
  620.         printf("Failed to open input file");
  621.         return 1;
  622.     }
  623.     if (avformat_find_stream_info(video->container, NULL) < 0)
  624.     {
  625.         printf("Failed to open read stream info");
  626.         return 1;
  627.     }
  628.  
  629.     video->codec = av_mallocz_array(video->container->nb_streams, sizeof(*video->codec));
  630.     video->remux = av_mallocz_array(video->container->nb_streams, sizeof(bool));
  631.  
  632.     params[0].nb_streams = video->container->nb_streams;
  633.  
  634.     for (unsigned int i = 0; i < video->container->nb_streams; i++)
  635.     {
  636.         video->remux[i] = false;
  637.         AVStream* stream = video->container->streams[i];
  638.         AVCodec* dec;
  639.         AVCodecContext* codec_ctx;
  640.  
  641.         switch (stream->codecpar->codec_type)
  642.         {
  643.         case AVMEDIA_TYPE_AUDIO:
  644.             params[0].audioIndex = i;
  645.             if (strcmp(params[0].audioDecoder, "copy") == 0 || strcmp(params[0].audioDecoder, "remux") == 0)
  646.             {
  647.                 dec = avcodec_find_decoder(stream->codecpar->codec_id);
  648.  
  649.             }
  650.             else
  651.             {
  652.                 dec = avcodec_find_decoder_by_name(params[0].audioDecoder);
  653.             }
  654.             if (strcmp(params[0].audioEncoder, "copy") == 0)
  655.             {
  656.                 params[0].audioEncoder = dec->name;
  657.             }
  658.             break;
  659.  
  660.         case AVMEDIA_TYPE_VIDEO:
  661.             params[0].videoIndex = i;
  662.             if (strcmp(params[0].videoDecoder, "copy") == 0 || strcmp(params[0].videoDecoder, "remux") == 0)
  663.             {
  664.                 dec = avcodec_find_decoder(stream->codecpar->codec_id);
  665.             }
  666.             else
  667.             {
  668.                 dec = avcodec_find_decoder_by_name(params[0].videoDecoder);
  669.             }
  670.             if (strcmp(params[0].videoEncoder, "copy") == 0)
  671.             {
  672.                 params[0].videoEncoder = dec->name;
  673.             }
  674.             break;
  675.         default:
  676.             continue;
  677.         }
  678.  
  679.  
  680.         if (!dec)
  681.         {
  682.             printf("failed to find the codec");
  683.             return -1;
  684.         }
  685.  
  686.         codec_ctx = avcodec_alloc_context3(dec);
  687.         if (!codec_ctx)
  688.         {
  689.             printf("failed to alloc memory for codec context");
  690.             return -1;
  691.         }
  692.  
  693.         if (avcodec_parameters_to_context(codec_ctx, stream->codecpar) < 0)
  694.         {
  695.             printf("failed to fill codec context");
  696.             return -1;
  697.         }
  698.  
  699.         if (avcodec_open2(codec_ctx, dec, NULL) < 0)
  700.         {
  701.             printf("failed to open codec");
  702.             return -1;
  703.         }
  704.         video->codec[i] = codec_ctx;
  705.  
  706.         switch (stream->codecpar->codec_type)
  707.         {
  708.         case AVMEDIA_TYPE_AUDIO:
  709.  
  710.             params[0].bitRate = codec_ctx->bit_rate;
  711.  
  712.             params[0].channel = codec_ctx->channels;
  713.  
  714.             params[0].sampleRate = codec_ctx->sample_rate;
  715.  
  716.             break;
  717.  
  718.         case AVMEDIA_TYPE_VIDEO:
  719.  
  720.             params[0].height = codec_ctx->height;
  721.  
  722.             params[0].width = codec_ctx->width;
  723.  
  724.             params[0].finalPix = codec_ctx->pix_fmt;
  725.  
  726.             params[0].frameRate = av_guess_frame_rate(video->container, stream, NULL);
  727.  
  728.             params[0].sampleAspectRatio = codec_ctx->sample_aspect_ratio;
  729.  
  730.             params[0].timebase = av_inv_q(params[0].frameRate);
  731.  
  732.             break;
  733.         }
  734.     }
  735.     return 1;
  736. }
  737.  
  738.  
  739. int createEncoders(file* encoder, transcodingParams* params)
  740. {
  741.     int ret = 0;
  742.     encoder->codec = av_mallocz_array(params[1].nb_streams, sizeof(*encoder->codec));
  743.  
  744.     for (int i = 0; i < params[1].nb_streams; i++)
  745.     {
  746.  
  747.  
  748.         AVStream* stream = avformat_new_stream(encoder->container, NULL);
  749.         AVCodec* enc;
  750.         AVCodecContext* cod_ctx = encoder->codec[i];
  751.  
  752.         if (strcmp(params[1].videoEncoder, "remux") == 0)
  753.         {
  754.             continue;
  755.         }
  756.  
  757.  
  758.         if (i == params[1].videoIndex)
  759.         {
  760.             enc = avcodec_find_encoder_by_name(params[1].videoEncoder);
  761.             cod_ctx = avcodec_alloc_context3(enc);
  762.             cod_ctx->height = params[1].height;
  763.             cod_ctx->width = params[1].width;
  764.             cod_ctx->pix_fmt = params[1].finalPix;
  765.             cod_ctx->sample_aspect_ratio = params[1].sampleAspectRatio;
  766.             cod_ctx->time_base = av_inv_q(params[1].frameRate);
  767.             stream->time_base = cod_ctx->time_base;
  768.             av_opt_set(cod_ctx->priv_data, "preset", "fast", 0);
  769.             av_opt_set(cod_ctx->priv_data, "x264-params", "keyint=60:min-keyint=60:scenecut=0:force-cfr=1", 0);
  770.         }
  771.         else if (i == params[1].audioIndex)
  772.         {
  773.             enc = avcodec_find_encoder_by_name(params[1].audioEncoder);
  774.             cod_ctx = avcodec_alloc_context3(enc);
  775.             cod_ctx->channels = params[1].channel;
  776.             cod_ctx->channel_layout = av_get_default_channel_layout(params[1].channel);
  777.             cod_ctx->sample_rate = params[1].sampleRate;
  778.             cod_ctx->sample_fmt = *enc->sample_fmts;
  779.             cod_ctx->bit_rate = params[1].bitRate;
  780.             cod_ctx->time_base = (AVRational){ 1, params[1].sampleRate };
  781.         }
  782.         else { continue; }
  783.         ret = avcodec_open2(cod_ctx, enc, NULL);
  784.         if (ret < 0)
  785.         {
  786.             printf("couldn't open codec");
  787.             return -1;
  788.         }
  789.         avcodec_parameters_from_context(stream->codecpar, cod_ctx);
  790.         encoder->codec[i] = cod_ctx;
  791.  
  792.     }
  793.     return 0;
  794. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement