Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <libavcodec/avcodec.h>
- #include <libavformat/avformat.h>
- #include <libavfilter/avfilter.h>
- #include <libavfilter/buffersink.h>
- #include <libavfilter/buffersrc.h>
- #include <libavutil/opt.h>
- #include <libavutil/pixdesc.h>
- #include <stdint.h>
- #include <stdbool.h>
- #include "resize.h"
- #include "chat.h"
- #include "shape.h"
- #include "write.h"
- typedef struct file
- {
- AVFormatContext* container;
- AVCodecContext** codec;
- bool* remux;
- } file;
- typedef struct transcodingParams {
- int width;
- int height;
- int tmpPix;
- int finalPix;
- int channel;
- int nb_streams;
- int64_t bitRate;
- int64_t sampleRate;
- int videoIndex;
- int audioIndex;
- char* videoEncoder;
- char* videoDecoder;
- char* audioEncoder;
- char* audioDecoder;
- AVRational sampleAspectRatio;
- AVRational frameRate;
- AVRational timebase;
- }transcodingParams;
- typedef struct filterCtx {
- AVFilterContext* buffersink_ctx;
- AVFilterContext* buffersrc_ctx;
- AVFilterGraph* filter_graph;
- }filterCtx;
- #define AUDIODECODER "copy"
- #define AUDIOENCODER "copy"
- #define VIDEODECODER "copy"
- #define VIDEOENCODER "copy"
- #define AUDIOINDEX -1
- #define BITRATE 0
- #define CHANNEL 0
- #define FINALPIX -1
- #define FRAMERATE 0
- #define SAMPLEASPECTRATIO 0
- #define HEIGHT 0
- #define NBSTREAMS 0
- #define WIDTH 0
- #define TIMEBASE 0
- #define TMPPIX -1
- #define VIDEOINDEX -1
- #define SAMPLERATE 0
- #define PROGRESSBARLENGTH 50
- #define END 0
- #define ERROR -1
- #define ENCODE 1
- #define REMUX 2
- #define CONTINUE 3
- #define EDIT 4
- #define EVER ;;
- filterCtx* initFilter(char* description, transcodingParams* params);
- void printProgress(unsigned int total, unsigned int left);
- int open_media(file* video, char* name, transcodingParams* params);
- int encode(file* decoder, file* encoder, AVFrame* input_frame, int index);
- int getFrame(file* decoder, AVFrame* frame, AVPacket* packet);
- int remux(file* decoder, file* encoder, AVPacket* packet);
- int createEncoders(file* encoder, transcodingParams* params);
- int getIndex(int type);
- void SaveFrame(AVFrame* pFrame, int width, int height, char* filename);
- static void save_gray_frame(unsigned char* buf, int wrap, int xsize, int ysize, char* filename);
- int applyFilter(filterCtx* filter, AVFrame* inFrame, AVFrame* outframe);
- unsigned int frameNumber = 0;
- unsigned int totalFrames = 0;
- transcodingParams* createParams()
- {
- transcodingParams* newParam = malloc(sizeof(transcodingParams));
- if (newParam == NULL)
- {
- return NULL;
- }
- newParam->audioDecoder = malloc(sizeof(AUDIODECODER));
- if (newParam->audioDecoder == NULL) { return NULL; }
- strcpy_s(newParam->audioDecoder, sizeof(AUDIODECODER), AUDIODECODER);
- newParam->audioEncoder = malloc(sizeof(AUDIOENCODER));
- if (newParam->audioEncoder == NULL) { return NULL; }
- strcpy_s(newParam->audioEncoder, sizeof(AUDIOENCODER), AUDIOENCODER);
- newParam->videoEncoder = malloc(sizeof(VIDEOENCODER));
- if (newParam->videoEncoder == NULL) { return NULL; }
- strcpy_s(newParam->videoEncoder, sizeof(VIDEOENCODER), VIDEOENCODER);
- newParam->videoDecoder = malloc(sizeof(VIDEODECODER));
- if (newParam->videoDecoder == NULL) { return NULL; }
- strcpy_s(newParam->videoDecoder, sizeof(VIDEODECODER), VIDEODECODER);
- newParam->sampleAspectRatio.den = SAMPLEASPECTRATIO;
- newParam->sampleAspectRatio.num = SAMPLEASPECTRATIO;
- newParam->frameRate.den = FRAMERATE;
- newParam->frameRate.num = FRAMERATE;
- newParam->timebase.num = TIMEBASE;
- newParam->timebase.den = TIMEBASE;
- newParam->bitRate = BITRATE;
- newParam->channel = BITRATE;
- newParam->sampleRate = SAMPLERATE;
- newParam->finalPix = FINALPIX;
- newParam->tmpPix = TMPPIX;
- newParam->height = HEIGHT;
- newParam->width = WIDTH;
- newParam->videoIndex = VIDEOINDEX;
- newParam->nb_streams = NBSTREAMS;
- newParam->audioIndex = AUDIOINDEX;
- }
- int main()
- {
- //char* VideoCodec[] = { "h264_cuvid","h264_nvenc" };
- char videoDecoder[] = "h264_cuvid";
- char videoEncoder[] = "h264_nvenc";
- int tmpPix = AV_PIX_FMT_RGB24;
- int finalPix = -1;
- int bitRate = 196000;
- int channel = 2;
- int h = 0;
- int w = 0;
- transcodingParams* params = malloc(sizeof(transcodingParams) * 2);
- if (params == NULL)
- {
- return -1;
- }
- params[0] = *createParams();
- params[1] = *createParams();
- params[1].tmpPix;
- params[1].videoDecoder = videoDecoder;
- params[1].videoEncoder = videoEncoder;
- params[1].bitRate = 196000;
- params[1].channel = 2;
- params[1].frameRate.den = 30000;
- params[1].frameRate.num = 1000;
- params[1].height = 1200;
- params[1].width = 1200;
- file* decoder = (file*)calloc(1, sizeof(file));
- file* encoder = (file*)calloc(1, sizeof(file));
- if (decoder == NULL || encoder == NULL)
- {
- return -1;
- }
- char input[] = "https://clips-media-assets2.twitch.tv/AT-cm%7C1257727679.mp4";
- char output[] = "out.avi";
- if (!open_media(decoder, input, params))
- {
- return -1;
- }
- int response = checkChanges(params);
- if (response > 0)
- {
- printf("error while comparing params");
- return -1;
- }
- avformat_alloc_output_context2(&encoder->container, NULL, NULL, output);
- if (!encoder->container)
- {
- return -1;
- }
- if (createEncoders(encoder, params))
- {
- return -1;
- }
- if (encoder->container->oformat->flags & AVFMT_GLOBALHEADER)
- encoder->container->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
- if (!(encoder->container->oformat->flags & AVFMT_NOFILE))
- {
- if (avio_open(&encoder->container->pb, output, AVIO_FLAG_WRITE) < 0)
- {
- printf("could not open the output file");
- return -1;
- }
- }
- AVDictionary* muxer_opts = NULL;
- if (avformat_write_header(encoder->container, &muxer_opts) < 0)
- {
- printf("an error occurred when opening output file");
- return -1;
- }
- /*
- shape* chat;
- int height = h * 50 / 100;
- int width = w * 50 / 100;
- struct SwsContext* first = NULL;
- struct SwsContext* second = NULL;
- chat = initChat(height, width, 500, h - height);
- */
- //filterDesc = "fps=fps=60000/1001";
- //char* filterDesc = "scale=250:250";
- AVFrame* frame = av_frame_alloc();
- AVPacket* packet = av_packet_alloc();
- AVFrame* filterFrame = av_frame_alloc();
- AVFrame* tmp = NULL;
- if (!frame || !packet || !filterFrame)
- {
- return -1;
- }
- #define FILTERSIZE 1024
- char filterDesc[FILTERSIZE];
- char currFilter[FILTERSIZE];
- filterDesc[0] = '\0';
- if (params[0].height != params[1].height || params[0].width != params[1].width)
- {
- if (filterDesc[0] != '\0') { strcat_s(filterDesc, FILTERSIZE, ","); }
- snprintf(currFilter, FILTERSIZE, "scale=%i:%i", params[1].width, params[1].height);
- strcat_s(filterDesc, FILTERSIZE, currFilter);
- currFilter[0] = '\0';
- }
- if (params[0].frameRate.den != params[1].frameRate.den || params[0].frameRate.num != params[1].frameRate.num)
- {
- if (filterDesc[0] != '\0') { strcat_s(filterDesc, FILTERSIZE, ","); }
- snprintf(currFilter, FILTERSIZE, "fps=%i/%i", params[1].frameRate.den, params[1].frameRate.num);
- strcat_s(filterDesc, FILTERSIZE, currFilter);
- currFilter[0] = '\0';
- }
- filterCtx* filter = NULL;
- if (filterDesc[0] != '\0')
- {
- filter = initFilter(filterDesc, params);
- }
- for (EVER)
- {
- response = getFrame(decoder, frame, packet);
- switch (response)
- {
- case EDIT:
- switch (decoder->container->streams[packet->stream_index]->codecpar->codec_type)
- {
- case AVMEDIA_TYPE_VIDEO:
- if (filter != NULL)
- {
- response = applyFilter(filter, frame, filterFrame);
- if (response < 0)
- {
- printf("Error while applying a filter");
- return -1;
- }
- tmp = frame;
- av_frame_unref(frame);
- frame = filterFrame;
- filterFrame = tmp;
- putchar('\n');
- printf("%p\n",frame);
- printf("%p\n",filterFrame);
- printf("%p\n",tmp);
- if (response == CONTINUE)
- {
- continue;
- }
- }
- break;
- case AVMEDIA_TYPE_AUDIO:
- break;
- }
- break;
- case REMUX:
- continue;
- case ERROR:
- return ERROR;
- case END:
- av_write_trailer(encoder->container);
- return 1;
- }
- if (response == ERROR)
- {
- return ERROR;
- }
- response = encode(decoder, encoder, frame, packet->stream_index);
- if (response == ERROR)
- {
- return ERROR;
- }
- }
- }
- /*
- *
- //tmp = resize(first, frame, w, h, tmpPix);
- frame = tmp;
- applyChat(chat, frame);
- char* filename = malloc(sizeof(char) * 512);
- snprintf(filename, 70, "C:/Users/gvian/source/repos/chat/chat/frames/After/frame%05d.ppm", frameNumber);
- frameNumber++;
- SaveFrame(frame, frame->width, frame->height, filename);
- tmp = resize(second, frame, w, h, decoder->codec[
- videoIndex]->pix_fmt);
- av_frame_free(&frame);
- av_frame_unref(frame);
- frame = tmp;
- tmp = NULL;
- */
- int checkChanges(transcodingParams* params)
- {
- if (strcmp(params[1].audioDecoder, AUDIODECODER) == 0) { params[1].audioDecoder = params[0].audioDecoder; }
- if (strcmp(params[1].audioEncoder, AUDIOENCODER) == 0) { params[1].audioEncoder = params[0].audioEncoder; }
- if (params[1].audioIndex == AUDIOINDEX) { params[1].audioIndex = params[0].audioIndex; }
- if (params[1].bitRate == BITRATE) { params[1].bitRate = params[0].bitRate; }
- if (params[1].channel == CHANNEL) { params[1].channel = params[0].channel; }
- if (params[1].finalPix == FINALPIX) { params[1].finalPix = params[0].finalPix; }
- if (params[1].frameRate.den == FRAMERATE && params[1].frameRate.num == FRAMERATE) { params[1].frameRate = params[0].frameRate; }
- if (params[1].sampleAspectRatio.den == SAMPLEASPECTRATIO && params[1].sampleAspectRatio.num == SAMPLEASPECTRATIO) { params[1].sampleAspectRatio = params[0].sampleAspectRatio; }
- if (params[1].height == HEIGHT) { params[1].height = params[0].height; }
- if (params[1].nb_streams == NBSTREAMS) { params[1].nb_streams = params[0].nb_streams; }
- if (params[1].width == WIDTH) { params[1].width = params[0].width; }
- if (params[1].timebase.den == TIMEBASE && params[1].timebase.num == TIMEBASE) { params[1].timebase = params[0].timebase; }
- if (params[1].tmpPix == TMPPIX) { params[1].tmpPix = params[0].tmpPix; }
- if (strcmp(params[1].videoDecoder, VIDEODECODER) == 0) { params[1].videoDecoder = params[0].videoDecoder; }
- if (strcmp(params[1].videoEncoder, VIDEOENCODER) == 0) { params[1].videoEncoder = params[0].videoEncoder; }
- if (params[1].videoIndex == VIDEOINDEX) { params[1].videoIndex = params[0].videoIndex; }
- if (params[1].sampleRate == SAMPLERATE) { params[1].sampleRate = params[0].sampleRate; }
- return 0;
- }
- filterCtx* initFilter(char* description, transcodingParams* params)
- {
- filterCtx* filter = malloc(sizeof(filterCtx));
- char args[512];
- int ret = 0;
- filter->buffersrc_ctx = NULL;
- filter->buffersink_ctx = NULL;
- AVFilterInOut* outputs = avfilter_inout_alloc();
- AVFilterInOut* inputs = avfilter_inout_alloc();
- filter->filter_graph = avfilter_graph_alloc();
- AVFilter* buffersrc = avfilter_get_by_name("buffer");
- AVFilter* buffersink = avfilter_get_by_name("buffersink");
- if (!outputs || !inputs || !filter->filter_graph) {
- return NULL;
- }
- buffersrc = avfilter_get_by_name("buffer");
- buffersink = avfilter_get_by_name("buffersink");
- if (!buffersrc || !buffersink)
- {
- return NULL;
- }
- snprintf(args, sizeof(args),
- "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
- params[0].width, params[0].height, params[0].finalPix,
- params[0].timebase.num, params[0].timebase.den,
- params[0].sampleAspectRatio.num,
- params[0].sampleAspectRatio.den);
- ret = avfilter_graph_create_filter(&filter->buffersrc_ctx, buffersrc, "in",
- args, NULL, filter->filter_graph);
- if (ret < 0)
- {
- return NULL;
- }
- ret = avfilter_graph_create_filter(&filter->buffersink_ctx, buffersink, "out",
- NULL, NULL, filter->filter_graph);
- if (ret < 0)
- {
- return NULL;
- }
- ret = av_opt_set_bin(filter->buffersink_ctx, "pix_fmts",
- (uint8_t*)¶ms[0].finalPix, sizeof(params[0].finalPix),
- AV_OPT_SEARCH_CHILDREN);
- if (ret < 0)
- {
- return NULL;
- }
- /* Endpoints for the filter graph. */
- outputs->name = av_strdup("in");
- outputs->filter_ctx = filter->buffersrc_ctx;
- outputs->pad_idx = 0;
- outputs->next = NULL;
- inputs->name = av_strdup("out");
- inputs->filter_ctx = filter->buffersink_ctx;
- inputs->pad_idx = 0;
- inputs->next = NULL;
- if (!outputs->name || !inputs->name)
- {
- return NULL;
- }
- if ((ret = avfilter_graph_parse_ptr(filter->filter_graph, description, &inputs, &outputs, NULL)) < 0)
- {
- return NULL;
- }
- if ((ret = avfilter_graph_config(filter->filter_graph, NULL)) < 0)
- {
- return NULL;
- }
- /* Fill FilteringContext */
- avfilter_inout_free(&inputs);
- avfilter_inout_free(&outputs);
- return filter;
- }
- int encode(file* decoder, file* encoder, AVFrame* input_frame, int index)
- {
- AVPacket* output_packet = av_packet_alloc();
- AVCodecContext* codec = encoder->codec[index];
- AVStream* stream = decoder->container->streams[index];
- if (!output_packet)
- {
- return ERROR;
- }
- int response = avcodec_send_frame(codec, input_frame);
- while (response >= 0)
- {
- response = avcodec_receive_packet(codec, output_packet);
- if (response == AVERROR(EAGAIN) || response == AVERROR_EOF)
- {
- break;
- }
- else if (response < 0)
- {
- return ERROR;
- }
- output_packet->stream_index = index;
- av_packet_rescale_ts(output_packet, stream->time_base, encoder->container->streams[index]->time_base);
- response = av_interleaved_write_frame(encoder->container, output_packet);
- if (response != 0)
- {
- return ERROR;
- }
- }
- av_packet_unref(output_packet);
- av_packet_free(&output_packet);
- return CONTINUE;
- }
- int applyFilter(filterCtx* filter, AVFrame* inFrame, AVFrame* outFrame)
- {
- int ret;
- /* push the decoded frame into the filtergraph */
- if (av_buffersrc_add_frame_flags(filter->buffersrc_ctx, inFrame, AV_BUFFERSRC_FLAG_KEEP_REF) < 0)
- {
- return 0;
- }
- /* pull filtered frames from the filtergraph */
- for (EVER)
- {
- ret = av_buffersink_get_frame(filter->buffersink_ctx, outFrame);
- if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
- {
- return CONTINUE;
- }
- if (ret < 0)
- {
- return -1;
- }
- return 0;
- }
- }
- static void save_gray_frame(unsigned char* buf, int wrap, int xsize, int ysize, char* filename)
- {
- FILE* f = NULL;
- int i;
- //char filename[32];
- fopen_s(&f, filename, "w");
- fprintf(f, "P5\n%d %d\n%d\n", xsize, ysize, 255);
- // writing line by line
- for (i = 0; i < ysize; i++)
- fwrite(buf + i * wrap, 1, xsize, f);
- fclose(f);
- }
- void SaveFrame(AVFrame* pFrame, int width, int height, char* filename)
- {
- FILE* pFile = NULL;
- int y;
- // Open file
- fopen_s(&pFile, filename, "wb");
- if (pFile == NULL)
- return;
- // Write header
- fprintf(pFile, "P6\n%d %d\n255\n", width, height);
- // Write pixel data
- for (y = 0; y < height; y++)
- fwrite(pFrame->data[0] + y * pFrame->linesize[0], 1, width * 3, pFile);
- // Close file
- fclose(pFile);
- }
- int remux(file* decoder, file* encoder, AVPacket* packet)
- {
- int index = packet->stream_index;
- av_packet_rescale_ts(packet, decoder->container->streams[index]->time_base, encoder->container->streams[index]->time_base);
- if (av_interleaved_write_frame(encoder->container, packet) < 0)
- {
- printf("error while copying stream packet");
- return ERROR;
- }
- return CONTINUE;
- }
- int getFrame(file* decoder, AVFrame* frame, AVPacket* packet)
- {
- av_frame_unref(frame);
- AVCodecContext* dec;
- while (av_read_frame(decoder->container, packet) >= 0)
- {
- int index = packet->stream_index;
- if (!decoder->remux[index])
- {
- dec = decoder->codec[index];
- int response = avcodec_send_packet(dec, packet);
- if (response < 0)
- {
- printf("Error while sending packet to decoder");
- return ERROR;
- }
- while (response >= 0)
- {
- response = avcodec_receive_frame(dec, frame);
- if (response == AVERROR(EAGAIN) || response == AVERROR_EOF)
- {
- break;
- }
- else if (response < 0)
- {
- printf("Error while receiving frame from decoder");
- return ERROR;
- }
- if (response >= 0)
- {
- return EDIT;
- }
- av_frame_unref(frame);
- }
- }
- else
- {
- return REMUX;
- }
- }
- return END;
- }
- int open_media(file* video, char* name, transcodingParams* params)
- {
- video->container = avformat_alloc_context();
- if (!video->container)
- {
- printf("Failed to alloc memory to the container of the input file");
- return 1;
- }
- if (avformat_open_input(&video->container, name, NULL, NULL) != 0)
- {
- printf("Failed to open input file");
- return 1;
- }
- if (avformat_find_stream_info(video->container, NULL) < 0)
- {
- printf("Failed to open read stream info");
- return 1;
- }
- video->codec = av_mallocz_array(video->container->nb_streams, sizeof(*video->codec));
- video->remux = av_mallocz_array(video->container->nb_streams, sizeof(bool));
- params[0].nb_streams = video->container->nb_streams;
- for (unsigned int i = 0; i < video->container->nb_streams; i++)
- {
- video->remux[i] = false;
- AVStream* stream = video->container->streams[i];
- AVCodec* dec;
- AVCodecContext* codec_ctx;
- switch (stream->codecpar->codec_type)
- {
- case AVMEDIA_TYPE_AUDIO:
- params[0].audioIndex = i;
- if (strcmp(params[0].audioDecoder, "copy") == 0 || strcmp(params[0].audioDecoder, "remux") == 0)
- {
- dec = avcodec_find_decoder(stream->codecpar->codec_id);
- }
- else
- {
- dec = avcodec_find_decoder_by_name(params[0].audioDecoder);
- }
- if (strcmp(params[0].audioEncoder, "copy") == 0)
- {
- params[0].audioEncoder = dec->name;
- }
- break;
- case AVMEDIA_TYPE_VIDEO:
- params[0].videoIndex = i;
- if (strcmp(params[0].videoDecoder, "copy") == 0 || strcmp(params[0].videoDecoder, "remux") == 0)
- {
- dec = avcodec_find_decoder(stream->codecpar->codec_id);
- }
- else
- {
- dec = avcodec_find_decoder_by_name(params[0].videoDecoder);
- }
- if (strcmp(params[0].videoEncoder, "copy") == 0)
- {
- params[0].videoEncoder = dec->name;
- }
- break;
- default:
- continue;
- }
- if (!dec)
- {
- printf("failed to find the codec");
- return -1;
- }
- codec_ctx = avcodec_alloc_context3(dec);
- if (!codec_ctx)
- {
- printf("failed to alloc memory for codec context");
- return -1;
- }
- if (avcodec_parameters_to_context(codec_ctx, stream->codecpar) < 0)
- {
- printf("failed to fill codec context");
- return -1;
- }
- if (avcodec_open2(codec_ctx, dec, NULL) < 0)
- {
- printf("failed to open codec");
- return -1;
- }
- video->codec[i] = codec_ctx;
- switch (stream->codecpar->codec_type)
- {
- case AVMEDIA_TYPE_AUDIO:
- params[0].bitRate = codec_ctx->bit_rate;
- params[0].channel = codec_ctx->channels;
- params[0].sampleRate = codec_ctx->sample_rate;
- break;
- case AVMEDIA_TYPE_VIDEO:
- params[0].height = codec_ctx->height;
- params[0].width = codec_ctx->width;
- params[0].finalPix = codec_ctx->pix_fmt;
- params[0].frameRate = av_guess_frame_rate(video->container, stream, NULL);
- params[0].sampleAspectRatio = codec_ctx->sample_aspect_ratio;
- params[0].timebase = av_inv_q(params[0].frameRate);
- break;
- }
- }
- return 1;
- }
- int createEncoders(file* encoder, transcodingParams* params)
- {
- int ret = 0;
- encoder->codec = av_mallocz_array(params[1].nb_streams, sizeof(*encoder->codec));
- for (int i = 0; i < params[1].nb_streams; i++)
- {
- AVStream* stream = avformat_new_stream(encoder->container, NULL);
- AVCodec* enc;
- AVCodecContext* cod_ctx = encoder->codec[i];
- if (strcmp(params[1].videoEncoder, "remux") == 0)
- {
- continue;
- }
- if (i == params[1].videoIndex)
- {
- enc = avcodec_find_encoder_by_name(params[1].videoEncoder);
- cod_ctx = avcodec_alloc_context3(enc);
- cod_ctx->height = params[1].height;
- cod_ctx->width = params[1].width;
- cod_ctx->pix_fmt = params[1].finalPix;
- cod_ctx->sample_aspect_ratio = params[1].sampleAspectRatio;
- cod_ctx->time_base = av_inv_q(params[1].frameRate);
- stream->time_base = cod_ctx->time_base;
- av_opt_set(cod_ctx->priv_data, "preset", "fast", 0);
- av_opt_set(cod_ctx->priv_data, "x264-params", "keyint=60:min-keyint=60:scenecut=0:force-cfr=1", 0);
- }
- else if (i == params[1].audioIndex)
- {
- enc = avcodec_find_encoder_by_name(params[1].audioEncoder);
- cod_ctx = avcodec_alloc_context3(enc);
- cod_ctx->channels = params[1].channel;
- cod_ctx->channel_layout = av_get_default_channel_layout(params[1].channel);
- cod_ctx->sample_rate = params[1].sampleRate;
- cod_ctx->sample_fmt = *enc->sample_fmts;
- cod_ctx->bit_rate = params[1].bitRate;
- cod_ctx->time_base = (AVRational){ 1, params[1].sampleRate };
- }
- else { continue; }
- ret = avcodec_open2(cod_ctx, enc, NULL);
- if (ret < 0)
- {
- printf("couldn't open codec");
- return -1;
- }
- avcodec_parameters_from_context(stream->codecpar, cod_ctx);
- encoder->codec[i] = cod_ctx;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement