
Recherche avancée
Médias (3)
-
MediaSPIP Simple : futur thème graphique par défaut ?
26 septembre 2013, par
Mis à jour : Octobre 2013
Langue : français
Type : Video
-
GetID3 - Bloc informations de fichiers
9 avril 2013, par
Mis à jour : Mai 2013
Langue : français
Type : Image
-
GetID3 - Boutons supplémentaires
9 avril 2013, par
Mis à jour : Avril 2013
Langue : français
Type : Image
Autres articles (52)
-
Personnaliser en ajoutant son logo, sa bannière ou son image de fond
5 septembre 2013, parCertains thèmes prennent en compte trois éléments de personnalisation : l’ajout d’un logo ; l’ajout d’une bannière l’ajout d’une image de fond ;
-
Ecrire une actualité
21 juin 2013, parPrésentez les changements dans votre MédiaSPIP ou les actualités de vos projets sur votre MédiaSPIP grâce à la rubrique actualités.
Dans le thème par défaut spipeo de MédiaSPIP, les actualités sont affichées en bas de la page principale sous les éditoriaux.
Vous pouvez personnaliser le formulaire de création d’une actualité.
Formulaire de création d’une actualité Dans le cas d’un document de type actualité, les champs proposés par défaut sont : Date de publication ( personnaliser la date de publication ) (...) -
Qu’est ce qu’un éditorial
21 juin 2013, parEcrivez votre de point de vue dans un article. Celui-ci sera rangé dans une rubrique prévue à cet effet.
Un éditorial est un article de type texte uniquement. Il a pour objectif de ranger les points de vue dans une rubrique dédiée. Un seul éditorial est placé à la une en page d’accueil. Pour consulter les précédents, consultez la rubrique dédiée.
Vous pouvez personnaliser le formulaire de création d’un éditorial.
Formulaire de création d’un éditorial Dans le cas d’un document de type éditorial, les (...)
Sur d’autres sites (4028)
-
How to modify the bit_rate of AVFormatContext ?
27 mars 2023, par Zion LiuHello,I would like to know how to modify the bit_rate of AVFormatContext.


Here is the minimal reproducible example.This is a simple process for pushing rtmp video streams.Now I want to control the bitrate of the video it pushes.


I tried modifying the bitrate like this, but it didn't work.


AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
int64_t bit_rate = 400*1000;
....
ofmt_ctx->bit_rate = bit_rate;



Can be compiled by
g++ -Wall -o -g -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/local/include -L/usr/local/lib simplt_push_streaming.cpp -o test.out -lavformat -lavcodec -lavutil -lgobject-2.0 -lglib-2.0 -lpthread


And my ffmpeg version :
ffmpeg version 4.4.2-0ubuntu0.22.04.1


#include 
extern "C"
{
#include <libavformat></libavformat>avformat.h>
#include <libavutil></libavutil>mathematics.h>
#include <libavutil></libavutil>time.h>
};

int main(int argc, char* argv[])
{
 AVOutputFormat *ofmt = NULL;
 //Input AVFormatContext and Output AVFormatContext
 AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
 AVPacket pkt;
 const char *in_filename, *out_filename;
 int ret, i;
 int videoindex=-1;
 int frame_index=0;
 int64_t start_time=0;
 int64_t bit_rate = 400*1000;
 in_filename = "/home/zion/video/mecha.flv";// Input file URL
 out_filename = "rtmp://localhost:1935/live/test";//Output URL [RTMP]
 av_register_all();
 avformat_network_init();
 avformat_open_input(&ifmt_ctx, in_filename, 0, 0);
 avformat_find_stream_info(ifmt_ctx, 0);
 for(i=0; inb_streams; i++) 
 if(ifmt_ctx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){
 videoindex=i;
 break;
 }
 //Output
 avformat_alloc_output_context2(&ofmt_ctx, NULL, "flv", out_filename); //RTMP
 ofmt = ofmt_ctx->oformat;
 for (i = 0; i < ifmt_ctx->nb_streams; i++) {
 //Create output AVStream according to input AVStream
 AVStream *in_stream = ifmt_ctx->streams[i];
 AVStream *out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);
 //Copy the settings of AVCodecContext
 ret = avcodec_copy_context(out_stream->codec, in_stream->codec);
 out_stream->codec->codec_tag = 0;
 if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
 out_stream->codec->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
 }
 //Open output URL
 if (!(ofmt->flags & AVFMT_NOFILE)) {
 ret = avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE);
 }
 //Write file header
 avformat_write_header(ofmt_ctx, NULL);
 start_time=av_gettime();
 while (1) {
 AVStream *in_stream, *out_stream;
 //Get an AVPacket
 ret = av_read_frame(ifmt_ctx, &pkt);
 if (ret < 0)
 break;
 //Important:Delay
 if(pkt.stream_index==videoindex){
 AVRational time_base=ifmt_ctx->streams[videoindex]->time_base;
 AVRational time_base_q={1,AV_TIME_BASE};
 int64_t pts_time = av_rescale_q(pkt.dts, time_base, time_base_q);
 int64_t now_time = av_gettime() - start_time;
 if (pts_time > now_time)
 av_usleep(pts_time - now_time);
 }
 in_stream = ifmt_ctx->streams[pkt.stream_index];
 out_stream = ofmt_ctx->streams[pkt.stream_index];
 if(pkt.stream_index==videoindex){
 printf("Send %8d video frames to output URL\n",frame_index);
 frame_index++;
 }
/*I tried modifying the bitrate here and I'm not sure if this is the correct usage.*/
 ofmt_ctx->bit_rate = bit_rate;
 av_interleaved_write_frame(ofmt_ctx, &pkt);
 av_free_packet(&pkt);
 }
 //Write file trailer
 av_write_trailer(ofmt_ctx);
end:
 avformat_close_input(&ifmt_ctx);
 /* close output */
 if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
 avio_close(ofmt_ctx->pb);
 avformat_free_context(ofmt_ctx);
 return 0;
}



-
ERROR "Application provided invalid, non monotonically increasing dts to muxer in stream 1 : 6874 >= 6874" while writing encoded output to an mp4 file
11 mai 2023, par lokit khemkaI have a running RTSP stream, streaming video on a loop using the following FFMPEG command :


ffmpeg -re -stream_loop -1 -i ./ffmpeg_c_test/small_bunny_1080p_60fps.mp4 -ac 2 -f rtsp -rtsp_transport tcp rtsp://localhost:8554/mystream



The video file is obtained from the github link : https://github.com/leandromoreira/ffmpeg-libav-tutorial


I keep getting error response, when I calling the function
av_interleaved_write_frame
called from the functionremux
in the attached program. The output format ismp4
, output video codec isav1
and output audio codec is same as input audio codec. The error is from audio stream.

I tried to create a "minimal reproducible code", however, I think it is still not completely minimal, but it reproduces the exact error.


#include <libavcodec></libavcodec>avcodec.h>
#include <libavformat></libavformat>avformat.h>
#include <libavutil></libavutil>timestamp.h>
#include <libavutil></libavutil>opt.h>
#include <libswscale></libswscale>swscale.h>
#include 
#include 
#include 

#include 
#include 

typedef struct StreamingContext{
 AVFormatContext* avfc;
 const AVCodec *video_avc;
 const AVCodec *audio_avc;
 AVStream *video_avs;
 AVStream *audio_avs;
 AVCodecContext *video_avcc;
 AVCodecContext *audio_avcc;
 int video_index;
 int audio_index;
 char* filename;
 struct SwsContext *sws_ctx;
}StreamingContext;


typedef struct StreamingParams{
 char copy_video;
 char copy_audio;
 char *output_extension;
 char *muxer_opt_key;
 char *muxer_opt_value;
 char *video_codec;
 char *audio_codec;
 char *codec_priv_key;
 char *codec_priv_value;
}StreamingParams;

void logging(const char *fmt, ...)
{
 va_list args;
 fprintf(stderr, "LOG: ");
 va_start(args, fmt);
 vfprintf(stderr, fmt, args);
 va_end(args);
 fprintf(stderr, "\n");
}

int fill_stream_info(AVStream *avs, const AVCodec **avc, AVCodecContext **avcc)
{
 *avc = avcodec_find_decoder(avs->codecpar->codec_id);
 *avcc = avcodec_alloc_context3(*avc);
 if (avcodec_parameters_to_context(*avcc, avs->codecpar) < 0)
 {
 logging("Failed to fill Codec Context.");
 return -1;
 }
 avcodec_open2(*avcc, *avc, NULL);
 return 0;
}

int open_media(const char *in_filename, AVFormatContext **avfc)
{
 *avfc = avformat_alloc_context();
 if (avformat_open_input(avfc, in_filename, NULL, NULL) != 0)
 {
 logging("Failed to open input file %s", in_filename);
 return -1;
 }

 if (avformat_find_stream_info(*avfc, NULL) < 0)
 {
 logging("Failed to get Stream Info.");
 return -1;
 }
}

int prepare_decoder(StreamingContext *sc)
{
 for (int i = 0; i < (int)sc->avfc->nb_streams; i++)
 {
 if (sc->avfc->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
 {
 sc->video_avs = sc->avfc->streams[i];
 sc->video_index = i;

 if (fill_stream_info(sc->video_avs, &sc->video_avc, &sc->video_avcc))
 {
 return -1;
 }
 }
 else if (sc->avfc->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
 {
 sc->audio_avs = sc->avfc->streams[i];
 sc->audio_index = i;

 if (fill_stream_info(sc->audio_avs, &sc->audio_avc, &sc->audio_avcc))
 {
 return -1;
 }
 }
 else
 {
 logging("Skipping Streams other than Audio and Video.");
 }
 }
 return 0;
}

int prepare_video_encoder(StreamingContext *encoder_sc, AVCodecContext *decoder_ctx, AVRational input_framerate,
 StreamingParams sp, int scaled_frame_width, int scaled_frame_height)
{
 encoder_sc->video_avs = avformat_new_stream(encoder_sc->avfc, NULL);
 encoder_sc->video_avc = avcodec_find_encoder_by_name(sp.video_codec);
 if (!encoder_sc->video_avc)
 {
 logging("Cannot find the Codec.");
 return -1;
 }

 encoder_sc->video_avcc = avcodec_alloc_context3(encoder_sc->video_avc);
 if (!encoder_sc->video_avcc)
 {
 logging("Could not allocate memory for Codec Context.");
 return -1;
 }

 av_opt_set(encoder_sc->video_avcc->priv_data, "preset", "fast", 0);
 if (sp.codec_priv_key && sp.codec_priv_value)
 av_opt_set(encoder_sc->video_avcc->priv_data, sp.codec_priv_key, sp.codec_priv_value, 0);

 encoder_sc->video_avcc->height = scaled_frame_height;
 encoder_sc->video_avcc->width = scaled_frame_width;
 encoder_sc->video_avcc->sample_aspect_ratio = decoder_ctx->sample_aspect_ratio;

 if (encoder_sc->video_avc->pix_fmts)
 encoder_sc->video_avcc->pix_fmt = encoder_sc->video_avc->pix_fmts[0];
 else
 encoder_sc->video_avcc->pix_fmt = decoder_ctx->pix_fmt;

 encoder_sc->video_avcc->bit_rate = 2 * 1000 * 1000;

 encoder_sc->video_avcc->time_base = av_inv_q(input_framerate);
 encoder_sc->video_avs->time_base = encoder_sc->video_avcc->time_base;

 

 if (avcodec_open2(encoder_sc->video_avcc, encoder_sc->video_avc, NULL) < 0)
 {
 logging("Could not open the Codec.");
 return -1;
 }
 avcodec_parameters_from_context(encoder_sc->video_avs->codecpar, encoder_sc->video_avcc);
 return 0;
}


int prepare_copy(AVFormatContext *avfc, AVStream **avs, AVCodecParameters *decoder_par)
{
 *avs = avformat_new_stream(avfc, NULL);
 avcodec_parameters_copy((*avs)->codecpar, decoder_par);
 return 0;
}

int encode_video(StreamingContext *decoder, StreamingContext *encoder, AVFrame *input_frame)
{
 if (input_frame)
 input_frame->pict_type = AV_PICTURE_TYPE_NONE;

 AVPacket *output_packet = av_packet_alloc();


 int response = avcodec_send_frame(encoder->video_avcc, input_frame);

 while (response >= 0)
 {
 response = avcodec_receive_packet(encoder->video_avcc, output_packet);
 if (response == AVERROR(EAGAIN) || response == AVERROR_EOF)
 {
 break;
 }

 output_packet->stream_index = decoder->video_index;
 output_packet->duration = encoder->video_avs->time_base.den / encoder->video_avs->time_base.num;

 av_packet_rescale_ts(output_packet, decoder->video_avs->time_base, encoder->video_avs->time_base);
 response = av_interleaved_write_frame(encoder->avfc, output_packet);
 }

 av_packet_unref(output_packet);
 av_packet_free(&output_packet);

 return 0;
}

int remux(AVPacket **pkt, AVFormatContext **avfc, AVRational decoder_tb, AVRational encoder_tb)
{
 (*pkt)->duration = av_rescale_q((*pkt)->duration, decoder_tb, encoder_tb);
 (*pkt)->pos = -1;
 av_packet_rescale_ts(*pkt, decoder_tb, encoder_tb);
 if (av_interleaved_write_frame(*avfc, *pkt) < 0)
 {
 logging("Error while copying Stream Packet.");
 return -1;
 }
 return 0;
}

int transcode_video(StreamingContext *decoder, StreamingContext *encoder, AVPacket *input_packet, AVFrame *input_frame)
{
 int response = avcodec_send_packet(decoder->video_avcc, input_packet);
 while (response >= 0)
 {
 response = avcodec_receive_frame(decoder->video_avcc, input_frame);
 
 if (response == AVERROR(EAGAIN) || response == AVERROR_EOF)
 {
 break;
 }
 if (response >= 0)
 {
 if (encode_video(decoder, encoder, input_frame))
 return -1;
 }

 av_frame_unref(input_frame);
 }
 return 0;
}

int main(int argc, char *argv[])
{
 const int scaled_frame_width = 854;
 const int scaled_frame_height = 480;
 StreamingParams sp = {0};
 sp.copy_audio = 1;
 sp.copy_video = 0;
 sp.video_codec = "libsvtav1";
 
 StreamingContext *decoder = (StreamingContext *)calloc(1, sizeof(StreamingContext));
 decoder->filename = "rtsp://localhost:8554/mystream";

 StreamingContext *encoder = (StreamingContext *)calloc(1, sizeof(StreamingContext));
 encoder->filename = "small_bunny_9.mp4";
 
 if (sp.output_extension)
 {
 strcat(encoder->filename, sp.output_extension);
 }

 open_media(decoder->filename, &decoder->avfc);
 prepare_decoder(decoder);


 avformat_alloc_output_context2(&encoder->avfc, NULL, "mp4", encoder->filename);
 AVRational input_framerate = av_guess_frame_rate(decoder->avfc, decoder->video_avs, NULL);
 prepare_video_encoder(encoder, decoder->video_avcc, input_framerate, sp, scaled_frame_width, scaled_frame_height);

 prepare_copy(encoder->avfc, &encoder->audio_avs, decoder->audio_avs->codecpar);
 

 if (encoder->avfc->oformat->flags & AVFMT_GLOBALHEADER)
 encoder->avfc->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;

 if (!(encoder->avfc->oformat->flags & AVFMT_NOFILE))
 {
 if (avio_open(&encoder->avfc->pb, encoder->filename, AVIO_FLAG_WRITE) < 0)
 {
 logging("could not open the output file");
 return -1;
 }
 }

 
 if (avformat_write_header(encoder->avfc, NULL) < 0)
 {
 logging("an error occurred when opening output file");
 return -1;
 }

 AVFrame *input_frame = av_frame_alloc();
 AVPacket *input_packet = av_packet_alloc();

 while (1)
 {
 int ret = av_read_frame(decoder->avfc, input_packet);
 if(ret<0)
 break;
 if (decoder->avfc->streams[input_packet->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
 {
 if (transcode_video(decoder, encoder, input_packet, input_frame))
 return -1;
 av_packet_unref(input_packet);

 }
 else if (decoder->avfc->streams[input_packet->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
 {
 
 if (remux(&input_packet, &encoder->avfc, decoder->audio_avs->time_base, encoder->audio_avs->time_base))
 return -1;
 }
 else
 {
 logging("Ignoring all nonvideo or audio packets.");
 }
 }

 if (encode_video(decoder, encoder, NULL))
 return -1;
 

 av_write_trailer(encoder->avfc);


 if (input_frame != NULL)
 {
 av_frame_free(&input_frame);
 input_frame = NULL;
 }

 if (input_packet != NULL)
 {
 av_packet_free(&input_packet);
 input_packet = NULL;
 }

 avformat_close_input(&decoder->avfc);

 avformat_free_context(decoder->avfc);
 decoder->avfc = NULL;
 avformat_free_context(encoder->avfc);
 encoder->avfc = NULL;

 avcodec_free_context(&decoder->video_avcc);
 decoder->video_avcc = NULL;
 avcodec_free_context(&decoder->audio_avcc);
 decoder->audio_avcc = NULL;

 free(decoder);
 decoder = NULL;
 free(encoder);
 encoder = NULL;

 return 0;
}




-
ERROR "Tag [3][0][0][0] incompatible with output codec id '86016' (mp4a)" while writing headers for output mp4 file from a UDP stream
8 mai 2023, par lokit khemkaI have a running UDP stream, that I simulating using FFMPEG command :


ffmpeg -stream_loop -1 -re -i ./small_bunny_1080p_60fps.mp4 -v 0 -vcodec mpeg4 -f mpegts udp://127.0.0.1:23000



The video file is obtained from the github link : https://github.com/leandromoreira/ffmpeg-libav-tutorial


I keep getting error response, when I calling the function
avformat_write_header
. The output format ismp4
, output video codec isav1
and output audio codec is same as input audio codec.

I tried to create a "minimal reproducible code", however, I think it is still not completely minimal, but it reproduces the exact error.


#include <libavcodec></libavcodec>avcodec.h>
#include <libavformat></libavformat>avformat.h>
#include <libavutil></libavutil>timestamp.h>
#include <libavutil></libavutil>opt.h>
#include <libswscale></libswscale>swscale.h>
#include 
#include 
#include 

#include 
#include 

typedef struct StreamingContext{
 AVFormatContext* avfc;
 const AVCodec *video_avc;
 const AVCodec *audio_avc;
 AVStream *video_avs;
 AVStream *audio_avs;
 AVCodecContext *video_avcc;
 AVCodecContext *audio_avcc;
 int video_index;
 int audio_index;
 char* filename;
 struct SwsContext *sws_ctx;
}StreamingContext;


typedef struct StreamingParams{
 char copy_video;
 char copy_audio;
 char *output_extension;
 char *muxer_opt_key;
 char *muxer_opt_value;
 char *video_codec;
 char *audio_codec;
 char *codec_priv_key;
 char *codec_priv_value;
}StreamingParams;

void logging(const char *fmt, ...)
{
 va_list args;
 fprintf(stderr, "LOG: ");
 va_start(args, fmt);
 vfprintf(stderr, fmt, args);
 va_end(args);
 fprintf(stderr, "\n");
}

int fill_stream_info(AVStream *avs, const AVCodec **avc, AVCodecContext **avcc)
{
 *avc = avcodec_find_decoder(avs->codecpar->codec_id);
 *avcc = avcodec_alloc_context3(*avc);
 if (avcodec_parameters_to_context(*avcc, avs->codecpar) < 0)
 {
 logging("Failed to fill Codec Context.");
 return -1;
 }
 avcodec_open2(*avcc, *avc, NULL);
 return 0;
}

int open_media(const char *in_filename, AVFormatContext **avfc)
{
 *avfc = avformat_alloc_context();
 if (avformat_open_input(avfc, in_filename, NULL, NULL) != 0)
 {
 logging("Failed to open input file %s", in_filename);
 return -1;
 }

 if (avformat_find_stream_info(*avfc, NULL) < 0)
 {
 logging("Failed to get Stream Info.");
 return -1;
 }
}

int prepare_decoder(StreamingContext *sc)
{
 for (int i = 0; i < (int)sc->avfc->nb_streams; i++)
 {
 if (sc->avfc->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
 {
 sc->video_avs = sc->avfc->streams[i];
 sc->video_index = i;

 if (fill_stream_info(sc->video_avs, &sc->video_avc, &sc->video_avcc))
 {
 return -1;
 }
 }
 else if (sc->avfc->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
 {
 sc->audio_avs = sc->avfc->streams[i];
 sc->audio_index = i;

 if (fill_stream_info(sc->audio_avs, &sc->audio_avc, &sc->audio_avcc))
 {
 return -1;
 }
 }
 else
 {
 logging("Skipping Streams other than Audio and Video.");
 }
 }
 return 0;
}

int prepare_video_encoder(StreamingContext *encoder_sc, AVCodecContext *decoder_ctx, AVRational input_framerate,
 StreamingParams sp, int scaled_frame_width, int scaled_frame_height)
{
 encoder_sc->video_avs = avformat_new_stream(encoder_sc->avfc, NULL);
 encoder_sc->video_avc = avcodec_find_encoder_by_name(sp.video_codec);
 if (!encoder_sc->video_avc)
 {
 logging("Cannot find the Codec.");
 return -1;
 }

 encoder_sc->video_avcc = avcodec_alloc_context3(encoder_sc->video_avc);
 if (!encoder_sc->video_avcc)
 {
 logging("Could not allocate memory for Codec Context.");
 return -1;
 }

 av_opt_set(encoder_sc->video_avcc->priv_data, "preset", "fast", 0);
 if (sp.codec_priv_key && sp.codec_priv_value)
 av_opt_set(encoder_sc->video_avcc->priv_data, sp.codec_priv_key, sp.codec_priv_value, 0);

 encoder_sc->video_avcc->height = scaled_frame_height;
 encoder_sc->video_avcc->width = scaled_frame_width;
 encoder_sc->video_avcc->sample_aspect_ratio = decoder_ctx->sample_aspect_ratio;

 if (encoder_sc->video_avc->pix_fmts)
 encoder_sc->video_avcc->pix_fmt = encoder_sc->video_avc->pix_fmts[0];
 else
 encoder_sc->video_avcc->pix_fmt = decoder_ctx->pix_fmt;

 encoder_sc->video_avcc->bit_rate = 2 * 1000 * 1000;

 encoder_sc->video_avcc->time_base = av_inv_q(input_framerate);
 encoder_sc->video_avs->time_base = encoder_sc->video_avcc->time_base;

 

 if (avcodec_open2(encoder_sc->video_avcc, encoder_sc->video_avc, NULL) < 0)
 {
 logging("Could not open the Codec.");
 return -1;
 }
 avcodec_parameters_from_context(encoder_sc->video_avs->codecpar, encoder_sc->video_avcc);
 return 0;
}


int prepare_copy(AVFormatContext *avfc, AVStream **avs, AVCodecParameters *decoder_par)
{
 *avs = avformat_new_stream(avfc, NULL);
 avcodec_parameters_copy((*avs)->codecpar, decoder_par);
 return 0;
}

int encode_video(StreamingContext *decoder, StreamingContext *encoder, AVFrame *input_frame)
{
 if (input_frame)
 input_frame->pict_type = AV_PICTURE_TYPE_NONE;

 AVPacket *output_packet = av_packet_alloc();


 int response = avcodec_send_frame(encoder->video_avcc, input_frame);

 while (response >= 0)
 {
 response = avcodec_receive_packet(encoder->video_avcc, output_packet);
 if (response == AVERROR(EAGAIN) || response == AVERROR_EOF)
 {
 break;
 }

 output_packet->stream_index = decoder->video_index;
 output_packet->duration = encoder->video_avs->time_base.den / encoder->video_avs->time_base.num / decoder->video_avs->avg_frame_rate.num * decoder->video_avs->avg_frame_rate.den;

 av_packet_rescale_ts(output_packet, decoder->video_avs->time_base, encoder->video_avs->time_base);
 response = av_interleaved_write_frame(encoder->avfc, output_packet);
 }

 av_packet_unref(output_packet);
 av_packet_free(&output_packet);

 return 0;
}

int remux(AVPacket **pkt, AVFormatContext **avfc, AVRational decoder_tb, AVRational encoder_tb)
{
 av_packet_rescale_ts(*pkt, decoder_tb, encoder_tb);
 if (av_interleaved_write_frame(*avfc, *pkt) < 0)
 {
 logging("Error while copying Stream Packet.");
 return -1;
 }
 return 0;
}

int transcode_video(StreamingContext *decoder, StreamingContext *encoder, AVPacket *input_packet, AVFrame *input_frame)
{
 int response = avcodec_send_packet(decoder->video_avcc, input_packet);
 while (response >= 0)
 {
 response = avcodec_receive_frame(decoder->video_avcc, input_frame);
 
 if (response == AVERROR(EAGAIN) || response == AVERROR_EOF)
 {
 break;
 }
 if (response >= 0)
 {
 if (encode_video(decoder, encoder, input_frame))
 return -1;
 }

 av_frame_unref(input_frame);
 }
 return 0;
}

int main(int argc, char *argv[])
{
 const int scaled_frame_width = 854;
 const int scaled_frame_height = 480;
 StreamingParams sp = {0};
 sp.copy_audio = 1;
 sp.copy_video = 0;
 sp.video_codec = "libsvtav1";
 
 StreamingContext *decoder = (StreamingContext *)calloc(1, sizeof(StreamingContext));
 decoder->filename = "udp://127.0.0.1:23000";

 StreamingContext *encoder = (StreamingContext *)calloc(1, sizeof(StreamingContext));
 encoder->filename = "small_bunny_9.mp4";
 
 if (sp.output_extension)
 {
 strcat(encoder->filename, sp.output_extension);
 }

 open_media(decoder->filename, &decoder->avfc);
 prepare_decoder(decoder);


 avformat_alloc_output_context2(&encoder->avfc, NULL, "mp4", encoder->filename);
 AVRational input_framerate = av_guess_frame_rate(decoder->avfc, decoder->video_avs, NULL);
 prepare_video_encoder(encoder, decoder->video_avcc, input_framerate, sp, scaled_frame_width, scaled_frame_height);

 prepare_copy(encoder->avfc, &encoder->audio_avs, decoder->audio_avs->codecpar);
 

 if (encoder->avfc->oformat->flags & AVFMT_GLOBALHEADER)
 encoder->avfc->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;

 if (!(encoder->avfc->oformat->flags & AVFMT_NOFILE))
 {
 if (avio_open(&encoder->avfc->pb, encoder->filename, AVIO_FLAG_WRITE) < 0)
 {
 logging("could not open the output file");
 return -1;
 }
 }

 
 if (avformat_write_header(encoder->avfc, NULL) < 0)
 {
 logging("an error occurred when opening output file");
 return -1;
 }

 AVFrame *input_frame = av_frame_alloc();
 AVPacket *input_packet = av_packet_alloc();

 while (1)
 {
 int ret = av_read_frame(decoder->avfc, input_packet);
 if(ret<0)
 break;
 if (decoder->avfc->streams[input_packet->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
 {
 if (transcode_video(decoder, encoder, input_packet, input_frame))
 return -1;
 av_packet_unref(input_packet);

 }
 else if (decoder->avfc->streams[input_packet->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
 {
 
 if (remux(&input_packet, &encoder->avfc, decoder->audio_avs->time_base, encoder->audio_avs->time_base))
 return -1;
 }
 else
 {
 logging("Ignoring all nonvideo or audio packets.");
 }
 }

 if (encode_video(decoder, encoder, NULL))
 return -1;
 

 av_write_trailer(encoder->avfc);


 if (input_frame != NULL)
 {
 av_frame_free(&input_frame);
 input_frame = NULL;
 }

 if (input_packet != NULL)
 {
 av_packet_free(&input_packet);
 input_packet = NULL;
 }

 avformat_close_input(&decoder->avfc);

 avformat_free_context(decoder->avfc);
 decoder->avfc = NULL;
 avformat_free_context(encoder->avfc);
 encoder->avfc = NULL;

 avcodec_free_context(&decoder->video_avcc);
 decoder->video_avcc = NULL;
 avcodec_free_context(&decoder->audio_avcc);
 decoder->audio_avcc = NULL;

 free(decoder);
 decoder = NULL;
 free(encoder);
 encoder = NULL;

 return 0;
}