
Recherche avancée
Médias (2)
-
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 (73)
-
Submit enhancements and plugins
13 avril 2011If you have developed a new extension to add one or more useful features to MediaSPIP, let us know and its integration into the core MedisSPIP functionality will be considered.
You can use the development discussion list to request for help with creating a plugin. As MediaSPIP is based on SPIP - or you can use the SPIP discussion list SPIP-Zone. -
Script d’installation automatique de MediaSPIP
25 avril 2011, parAfin de palier aux difficultés d’installation dues principalement aux dépendances logicielles coté serveur, un script d’installation "tout en un" en bash a été créé afin de faciliter cette étape sur un serveur doté d’une distribution Linux compatible.
Vous devez bénéficier d’un accès SSH à votre serveur et d’un compte "root" afin de l’utiliser, ce qui permettra d’installer les dépendances. Contactez votre hébergeur si vous ne disposez pas de cela.
La documentation de l’utilisation du script d’installation (...) -
Submit bugs and patches
13 avril 2011Unfortunately a software is never perfect.
If you think you have found a bug, report it using our ticket system. Please to help us to fix it by providing the following information : the browser you are using, including the exact version as precise an explanation as possible of the problem if possible, the steps taken resulting in the problem a link to the site / page in question
If you think you have solved the bug, fill in a ticket and attach to it a corrective patch.
You may also (...)
Sur d’autres sites (8267)
-
Revision 32592 : utiliser glob() pour choper la liste des sites (php 4.3.0 mini), et lister ...
1er novembre 2009, par fil@… — Logutiliser glob() pour choper la liste des sites (php 4.3.0 mini), et lister les plugins utilises
-
Revision 3052 : On commit pas grand chose des fois mais bon...
10 mars 2010, par kent1 — LogOn commit pas grand chose des fois mais bon…
-
Downscaling a video from 1080p to 480p using swscale and encoding to x265 gives a glitched output
5 mai 2023, par lokit khemkaI am basically first scaling a frame and then sending the frame to the encoder as below :


scaled_frame->pts = input_frame->pts;
scaled_frame->pkt_dts = input_frame->pkt_dts;
scaled_frame->pict_type = input_frame->pict_type;
sws_scale_frame(encoder->sws_ctx, scaled_frame, input_frame);
if (encode_video(decoder, encoder, scaled_frame))
 return -1;



The scaling context is configured as :


scaled_frame->width = 854;
scaled_frame->height=480; 
encoder->sws_ctx = sws_getContext(1920, 1080,
 decoder->video_avcc->pix_fmt, 
 scaled_frame->width, scaled_frame->height, decoder->video_avcc->pix_fmt, SWS_BICUBIC, NULL, NULL, NULL );
 if (!encoder->sws_ctx){logging("Cannot Create Scaling Context."); return -1;}



The encoder is configured as :


encoder_sc->video_avcc->height = decoder_ctx->height; //1080
 encoder_sc->video_avcc->width = decoder_ctx->width; //1920
 encoder_sc->video_avcc->bit_rate = 2 * 1000 * 1000;
 encoder_sc->video_avcc->rc_buffer_size = 4 * 1000 * 1000;
 encoder_sc->video_avcc->rc_max_rate = 2 * 1000 * 1000;
 encoder_sc->video_avcc->rc_min_rate = 2.5 * 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;



When I get the output, the output video is 1080p and I have glitches like :


I changed the encoder avcc resolution to 480p (854 x 480). However, that is causing the video to get sliced to the top quarter of the original frame.
I am new to FFMPEG and video processing in general.


EDIT : I am adding the minimal reproducible code sample. However, it is really long because I need to include code for decoding, scaling and then encoding because the possible error is either in scaling or encoding :


#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 

typedef struct StreamingContext{
 AVFormatContext* avfc;
 AVCodec *video_avc;
 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, AVCodec **avc, AVCodecContext **avcc)
{
 *avc = avcodec_find_decoder(avs->codecpar->codec_id);
 if (!*avc)
 {
 logging("Failed to find the codec.\n");
 return -1;
 }

 *avcc = avcodec_alloc_context3(*avc);
 if (!*avcc)
 {
 logging("Failed to alloc memory for codec context.");
 return -1;
 }

 if (avcodec_parameters_to_context(*avcc, avs->codecpar) < 0)
 {
 logging("Failed to fill Codec Context.");
 return -1;
 }

 if (avcodec_open2(*avcc, *avc, NULL) < 0)
 {
 logging("Failed to open Codec.");
 return -1;
 }

 return 0;
}

int open_media(const char *in_filename, AVFormatContext **avfc)
{
 *avfc = avformat_alloc_context();

 if (!*avfc)
 {
 logging("Failed to Allocate Memory for Format Context");
 return -1;
 }

 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 < 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
 {
 logging("Skipping Streams other than Video.");
 }
 }
 return 0;
}

int prepare_video_encoder(StreamingContext *encoder_sc, AVCodecContext *decoder_ctx, AVRational input_framerate,
 StreamingParams sp)
{
 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 = decoder_ctx->height;
 encoder_sc->video_avcc->width = decoder_ctx->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->rc_buffer_size = 4 * 1000 * 1000;
 encoder_sc->video_avcc->rc_max_rate = 2 * 1000 * 1000;
 encoder_sc->video_avcc->rc_min_rate = 2.5 * 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 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();
 if (!output_packet)
 {
 logging("Could not allocate memory for Output Packet.");
 return -1;
 }

 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;
 }
 else if (response < 0)
 {
 logging("Error while receiving packet from encoder: %s", av_err2str(response));
 return -1;
 }

 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);
 if (response != 0)
 {
 logging("Error %d while receiving packet from decoder: %s", response, av_err2str(response));
 return -1;
 }
 }

 av_packet_unref(output_packet);
 av_packet_free(&output_packet);

 return 0;
}

int transcode_video(StreamingContext *decoder, StreamingContext *encoder, AVPacket *input_packet, AVFrame *input_frame, AVFrame *scaled_frame)
{
 int response = avcodec_send_packet(decoder->video_avcc, input_packet);
 if (response < 0)
 {
 logging("Error while sending the Packet to Decoder: %s", av_err2str(response));
 return response;
 }

 while (response >= 0)
 {
 response = avcodec_receive_frame(decoder->video_avcc, input_frame);
 
 if (response == AVERROR(EAGAIN) || response == AVERROR_EOF)
 {
 break;
 }
 else if (response < 0)
 {
 logging("Error while receiving frame from Decoder: %s", av_err2str(response));
 return response;
 }
 if (response >= 0)
 {
 scaled_frame->pts = input_frame->pts;
 scaled_frame->pkt_dts = input_frame->pkt_dts;
 scaled_frame->pict_type = input_frame->pict_type;
 sws_scale_frame(encoder->sws_ctx, scaled_frame, input_frame);
 if (encode_video(decoder, encoder, scaled_frame))
 return -1;
 }

 av_frame_unref(input_frame);
 }
 return 0;
}

int main(int argc, char *argv[])
{
 StreamingParams sp = {0};
 sp.copy_audio = 1;
 sp.copy_video = 0;
 sp.video_codec = "libx265";


 StreamingContext *decoder = (StreamingContext *)calloc(1, sizeof(StreamingContext));
 decoder->filename = argv[1];

 StreamingContext *encoder = (StreamingContext *)calloc(1, sizeof(StreamingContext));
 encoder->filename = argv[2];

 if (sp.output_extension)
 {
 strcat(encoder->filename, sp.output_extension);
 }

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

 avformat_alloc_output_context2(&encoder->avfc, NULL, NULL, encoder->filename);
 if (!encoder->avfc)
 {
 logging("Could not allocate memory for output Format Context.");
 return -1;
 }

 AVRational input_framerate = av_guess_frame_rate(decoder->avfc, decoder->video_avs, NULL);
 prepare_video_encoder(encoder, decoder->video_avcc, input_framerate, sp);


 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;
 }
 }

 AVDictionary *muxer_opts = NULL;

 if (sp.muxer_opt_key && sp.muxer_opt_value)
 {
 av_dict_set(&muxer_opts, sp.muxer_opt_key, sp.muxer_opt_value, 0);
 }

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

 AVFrame *input_frame = av_frame_alloc();
 AVFrame *scaled_frame = av_frame_alloc();
 if (!input_frame || !scaled_frame)
 {
 logging("Failed to allocate memory for AVFrame");
 return -1;
 }

 // scaled_frame->format = AV_PIX_FMT_YUV420P;
 scaled_frame->width = 854;
 scaled_frame->height=480; 

 //Creating Scaling Context
 encoder->sws_ctx = sws_getContext(1920, 1080,
 decoder->video_avcc->pix_fmt, 
 scaled_frame->width, scaled_frame->height, decoder->video_avcc->pix_fmt, SWS_BICUBIC, NULL, NULL, NULL );
 if (!encoder->sws_ctx){logging("Cannot Create Scaling Context."); return -1;}


 AVPacket *input_packet = av_packet_alloc();
 if (!input_packet)
 {
 logging("Failed to allocate memory for AVPacket.");
 return -1;
 }

 while (av_read_frame(decoder->avfc, input_packet) >= 0)
 {
 if (decoder->avfc->streams[input_packet->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
 {
 if (transcode_video(decoder, encoder, input_packet, input_frame, scaled_frame))
 return -1;
 av_packet_unref(input_packet);
 }
 else
 {
 logging("Ignoring all nonvideo packets.");
 }
 }

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

 av_write_trailer(encoder->avfc);

 if (muxer_opts != NULL)
 {
 av_dict_free(&muxer_opts);
 muxer_opts = NULL;
 }

 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;
}



The video I am using for testing is available at the repo : https://github.com/leandromoreira/ffmpeg-libav-tutorial


The file name is small_bunny_1080p_60fps.mp4