
Recherche avancée
Médias (1)
-
Collections - Formulaire de création rapide
19 février 2013, par
Mis à jour : Février 2013
Langue : français
Type : Image
Autres articles (63)
-
Supporting all media types
13 avril 2011, parUnlike most software and media-sharing platforms, MediaSPIP aims to manage as many different media types as possible. The following are just a few examples from an ever-expanding list of supported formats : images : png, gif, jpg, bmp and more audio : MP3, Ogg, Wav and more video : AVI, MP4, OGV, mpg, mov, wmv and more text, code and other data : OpenOffice, Microsoft Office (Word, PowerPoint, Excel), web (html, CSS), LaTeX, Google Earth and (...)
-
Modifier la date de publication
21 juin 2013, parComment changer la date de publication d’un média ?
Il faut au préalable rajouter un champ "Date de publication" dans le masque de formulaire adéquat :
Administrer > Configuration des masques de formulaires > Sélectionner "Un média"
Dans la rubrique "Champs à ajouter, cocher "Date de publication "
Cliquer en bas de la page sur Enregistrer -
MediaSPIP Init et Diogène : types de publications de MediaSPIP
11 novembre 2010, parÀ l’installation d’un site MediaSPIP, le plugin MediaSPIP Init réalise certaines opérations dont la principale consiste à créer quatre rubriques principales dans le site et de créer cinq templates de formulaire pour Diogène.
Ces quatre rubriques principales (aussi appelées secteurs) sont : Medias ; Sites ; Editos ; Actualités ;
Pour chacune de ces rubriques est créé un template de formulaire spécifique éponyme. Pour la rubrique "Medias" un second template "catégorie" est créé permettant d’ajouter (...)
Sur d’autres sites (2714)
-
Google Analytics 4 (GA4) vs Universal Analytics (UA)
24 janvier 2022, par Erin — Analytics Tips -
C++ ffmpeg Specified pixel format is invalid or not supported
4 septembre 2022, par TurgutSo I have a program that reads an opengl window and encodes the read data as a video. Now through a series of experimentation I have learned that the bit format of my glfw window is
8:8:8
as returned byglfwGetVideoMode(monitor)
. So I use this function to read the window :

glReadPixels(0, 0,gl_width, gl_height,GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*) Buffer);


and I simply encode it in the
AV_PIX_FMT_YUV420P
format.

Under normal circumstances this method works just fine. However, when I actually run the program, the output I get, as opposed to what I can see in the glfw window, is really low resolution and a bit pixelated.


Here is what my GLFW window looks like :



Now this is what I want it to look like. It looks just fine on the opengl window, and I encode it directly without altering
Buffer
.

And here is what the encoded result, test.mp4 looks like when I run it using mplayer or similar software :




It's a lot more blurry and pixelated compare to the GLFW window. With some experimentation and following an answer to another question I asked, I us
avcodec_find_best_pix_fmt_of_list((*codec)->pix_fmts, AV_PIX_FMT_RGBA, 1, &ret)
and it returned 13. Which led me to believe usingAV_PIX_FMT_YUVJ422P
is the best option for this convertion to not have a blurry/pixelated result. However, no matter which function I pass, every single format gives off an error exceptAV_PIX_FMT_YUV420P
. The error is :

[mpeg4 @ 0x558e74f47900] Specified pixel format yuvj422p is invalid or not supported



I have no idea why this is happening, as the format is bound to a define and it is changed throughout the entire program when I change the define.


Here is my encoder so far (I have trimmed some parts) :


video_encoder.cpp :


int video_encoder::write_frame(AVFormatContext *fmt_ctx, AVCodecContext *c,
 AVStream *st, AVFrame *frame, AVPacket *pkt)
 {
 int ret;
 // Conditional jump or move depends on uninitialised value
 // Use of uninitialised value of size 8
 // send the frame to the encoder

 // Error is about c.
 ret = avcodec_send_frame(c, frame);

 if (ret < 0) {
 std::cout << "Error sending a frame to the encoder: " << ret << std::endl;
 exit(1);
 }

 while (ret >= 0) {
 ret = avcodec_receive_packet(c, pkt);

 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
 break;
 else if (ret < 0) {
 std::cout << "Error encoding a frame: " << ret << std::endl;
 exit(1);
 }

 /* rescale output packet timestamp values from codec to stream timebase */
 av_packet_rescale_ts(pkt, c->time_base, st->time_base);
 pkt->stream_index = st->index;

 /* Write the compressed frame to the media file. */
 //log_packet(fmt_ctx, pkt);

 //std::cout << "Packet: " << pkt << std::endl;

 ret = av_interleaved_write_frame(fmt_ctx, pkt);

 /* pkt is now blank (av_interleaved_write_frame() takes ownership of
 * its contents and resets pkt), so that no unreferencing is necessary.
 * This would be different if one used av_write_frame(). */
 if (ret < 0) {
 std::cout << "Error while writing output packet: " << ret << std::endl;
 exit(1);
 }
 }

 return ret == AVERROR_EOF ? 1 : 0;
}


/* Add an output stream. */
void video_encoder::add_stream(OutputStream *ost, AVFormatContext *oc,
 const AVCodec **codec,
 enum AVCodecID codec_id)
{
 AVCodecContext *c;
 int i;

 /* find the encoder */
 *codec = avcodec_find_encoder(codec_id);
 
 if (!(*codec)) {
 fprintf(stderr, "Could not find encoder for '%s'\n",
 avcodec_get_name(codec_id));
 exit(1);
 }

 ost->tmp_pkt = av_packet_alloc();

 if (!ost->tmp_pkt) {
 fprintf(stderr, "Could not allocate AVPacket\n");
 exit(1);
 }

 ost->st = avformat_new_stream(oc, NULL);
 if (!ost->st) {
 fprintf(stderr, "Could not allocate stream\n");
 exit(1);
 }
 ost->st->id = oc->nb_streams-1;
 c = avcodec_alloc_context3(*codec);
 if (!c) {
 fprintf(stderr, "Could not alloc an encoding context\n");
 exit(1);
 }
 ost->enc = c;


 switch ((*codec)->type) {
 case AVMEDIA_TYPE_AUDIO:
 ...
 case AVMEDIA_TYPE_VIDEO:
 c->codec_id = codec_id;

 c->bit_rate = 10000;
 /* Resolution must be a multiple of two. */
 c->width = width;
 c->height = height;
 /* timebase: This is the fundamental unit of time (in seconds) in terms
 * of which frame timestamps are represented. For fixed-fps content,
 * timebase should be 1/framerate and timestamp increments should be
 * identical to 1. */
 ost->st->time_base = (AVRational){ 1, STREAM_FRAME_RATE }; // *frame_rate
 c->time_base = ost->st->time_base;

 c->gop_size = 7; /* emit one intra frame every twelve frames at most */
 c->pix_fmt = STREAM_PIX_FMT;
 //if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) 
 // c->max_b_frames = 2;
 if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
 /* Needed to avoid using macroblocks in which some coeffs overflow.
 * This does not happen with normal video, it just happens here as
 * the motion of the chroma plane does not match the luma plane. */
 c->mb_decision = 2;
 }

 if ((*codec)->pix_fmts){
 //c->pix_fmt = (*codec)->pix_fmts[0];
 std::cout << "NEW FORMAT : " << c->pix_fmt << std::endl;
 }

 int ret;
 avcodec_find_best_pix_fmt_of_list((*codec)->pix_fmts, AV_PIX_FMT_RGBA, 1, &ret);
 std::cout << "Desired format is: " << ret << std::endl;
 break;
 }
 

 /* Some formats want stream headers to be separate. */
 if (oc->oformat->flags & AVFMT_GLOBALHEADER)
 c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
}

/**************************************************************/
/* video output */

AVFrame* video_encoder::alloc_picture(enum AVPixelFormat pix_fmt, int width, int height)
{
 AVFrame *picture;
 int ret;

 picture = av_frame_alloc();
 if (!picture)
 return NULL;

 picture->format = pix_fmt;
 picture->width = width;
 picture->height = height;

 /* allocate the buffers for the frame data */
 ret = av_frame_get_buffer(picture, 0);
 if (ret < 0) {
 fprintf(stderr, "Could not allocate frame data.\n");
 exit(1);
 }

 return picture;
}

void video_encoder::open_video(AVFormatContext *oc, const AVCodec *codec,
 OutputStream *ost, AVDictionary *opt_arg)
{
 int ret;
 AVCodecContext *c = ost->enc;
 AVDictionary *opt = NULL;
 av_dict_copy(&opt, opt_arg, 0);
 /* open the codec */
 ret = avcodec_open2(c, codec, &opt);
 av_dict_free(&opt);
 if (ret < 0) {
 fprintf(stderr, "Could not open video codec: %s\n", ret);
 exit(1);
 }

 /* allocate and init a re-usable frame */
 ost->frame = alloc_picture(c->pix_fmt, c->width, c->height);
 if (!ost->frame) {
 fprintf(stderr, "Could not allocate video frame\n");
 exit(1);
 }

 /* If the output format is not YUV420P, then a temporary YUV420P
 * picture is needed too. It is then converted to the required
 * output format. */
 ost->tmp_frame = NULL;


 /* copy the stream parameters to the muxer */
 ret = avcodec_parameters_from_context(ost->st->codecpar, c);
 if (ret < 0) {
 fprintf(stderr, "Could not copy the stream parameters\n");
 exit(1);
 }
}


void video_encoder::set_frame_yuv_from_rgb(AVFrame *frame, struct SwsContext *sws_context) {
 const int in_linesize[1] = { 4 * width };
 //uint8_t* dest[4] = { rgb_data, NULL, NULL, NULL };

 
 sws_context = sws_getContext(
 width, height, AV_PIX_FMT_RGBA,
 width, height, STREAM_PIX_FMT,
 SCALE_FLAGS, 0, 0, 0);

 sws_scale(sws_context, (const uint8_t * const *)&rgb_data, in_linesize, 0,
 height, frame->data, frame->linesize);
}

AVFrame* video_encoder::get_video_frame(OutputStream *ost)
{
 AVCodecContext *c = ost->enc;
 /* check if we want to generate more frames */
 if (av_compare_ts(ost->next_pts, c->time_base,
 (float) STREAM_DURATION / 1000, (AVRational){ 1, 1 }) > 0)
 return NULL;

 /* when we pass a frame to the encoder, it may keep a reference to it
 * internally; make sure we do not overwrite it here */
 if (av_frame_make_writable(ost->frame) < 0)
 exit(1);

 
 set_frame_yuv_from_rgb(ost->frame, ost->sws_ctx);
 
 
 ost->frame->pts = ost->next_pts++;

 return ost->frame;
}

/*
 * encode one video frame and send it to the muxer
 * return 1 when encoding is finished, 0 otherwise
 */
int video_encoder::write_video_frame(AVFormatContext *oc, OutputStream *ost)
{
 return write_frame(oc, ost->enc, ost->st, get_video_frame(ost), ost->tmp_pkt);
}

void video_encoder::close_stream(AVFormatContext *oc, OutputStream *ost)
{
 avcodec_free_context(&ost->enc);
 av_frame_free(&ost->frame);
 av_frame_free(&ost->tmp_frame);
 av_packet_free(&ost->tmp_pkt);
 //sws_freeContext(ost->sws_ctx);
 //swr_free(&ost->swr_ctx);
}

/**************************************************************/
/* media file output */

void video_encoder::set_encode_framebuffer(uint8_t* data, bool audio_only)
{
 rgb_data = data;
}

video_encoder::~video_encoder()
{
 av_write_trailer(enc_inf.oc);

 /* Close each codec. */
 if (enc_inf.have_video)
 close_stream(enc_inf.oc, &enc_inf.video_st);

 if (!(enc_inf.fmt->flags & AVFMT_NOFILE))
 /* Close the output file. */
 avio_closep(&enc_inf.oc->pb);

 /* free the stream */
 avformat_free_context(enc_inf.oc);
 std::cout << "Done, closing." << std::endl; 
}

bool video_encoder::encode_one_frame()
{
 if (enc_inf.encode_video || enc_inf.encode_audio) {
 /* select the stream to encode */
 if (enc_inf.encode_video &&
 (!enc_inf.encode_audio || av_compare_ts(enc_inf.video_st.next_pts, enc_inf.video_st.enc->time_base,
 enc_inf.audio_st.next_pts, enc_inf.audio_st.enc->time_base) <= 0)) {
 enc_inf.encode_video = !write_video_frame(enc_inf.oc, &enc_inf.video_st);
 return true;
 } 
 }
 return false;
}


video_encoder::video_encoder(int w, int h, float fps, unsigned int duration) 
 :width(w), height(h), STREAM_FRAME_RATE(fps), STREAM_DURATION(duration)
{
 //std::filesystem::create_directory("media"); 

 //std::string as_str = "./output/" + std::string(getenv ("OUTPUT_UUID")) + ".mp4";
 std::string as_str = "./output/video.mp4";

 char* filename = const_cast(as_str.c_str());
 enc_inf.video_st, enc_inf.audio_st = (struct OutputStream) { 0 };
 enc_inf.video_st.next_pts = 1; 
 enc_inf.audio_st.next_pts = 1;
 enc_inf.encode_audio, enc_inf.encode_video = 0;
 int ret;
 int i;
 //rgb_data = (uint8_t*)malloc( 48 * sizeof(uint8_t) );

 /* allocate the output media context */
 avformat_alloc_output_context2(&enc_inf.oc, NULL, NULL, filename);

 if (!enc_inf.oc) {
 //VI_ERROR("Could not deduce output format from file extension: using MPEG.\n");
 avformat_alloc_output_context2(&enc_inf.oc, NULL, "mpeg", filename);
 }
 if (!enc_inf.oc)
 std::cout << "FAILED" << std::endl;
 //return 1;

 enc_inf.fmt = enc_inf.oc->oformat;

 /* Add the audio and video streams using the default format codecs
 * and initialize the codecs. */
 if (enc_inf.fmt->video_codec != AV_CODEC_ID_NONE) {
 add_stream(&enc_inf.video_st, enc_inf.oc, &video_codec, enc_inf.fmt->video_codec);
 enc_inf.have_video = 1;
 enc_inf.encode_video = 1;
 }

 /* Now that all the parameters are set, we can open the audio and
 * video codecs and allocate the necessary encode buffers. */
 if (enc_inf.have_video)
 open_video(enc_inf.oc, video_codec, &enc_inf.video_st, opt);

 /* open the output file, if needed */
 if (!(enc_inf.fmt->flags & AVFMT_NOFILE)) {
 ret = avio_open(&enc_inf.oc->pb, filename, AVIO_FLAG_WRITE);
 if (ret < 0) {
 //VI_ERROR("Could not open '%s': %s\n", filename, ret);
 //return 1;
 }
 }

 /* Write the stream header, if any. */
 ret = avformat_write_header(enc_inf.oc, &opt);
 if (ret < 0) {
 VI_ERROR("Error occurred when opening output file:");
 //return 1;
 }
 
 //return 0;
}



video_encoder.h :


#define STREAM_PIX_FMT AV_PIX_FMT_YUV420P /* default pix_fmt */

#define SCALE_FLAGS SWS_SPLINE

/* The output bit rate in bit/s */
#define OUTPUT_BIT_RATE 96000
/* The number of output channels */
#define OUTPUT_CHANNELS 2

typedef struct OutputStream {
 AVStream *st;
 AVCodecContext *enc;

 /* pts of the next frame that will be generated */
 int64_t next_pts;
 int samples_count;

 AVFrame *frame;
 AVFrame *tmp_frame;

 AVPacket *tmp_pkt;

 float t, tincr, tincr2;

 struct SwsContext *sws_ctx;
 struct SwrContext *swr_ctx;
} OutputStream;
 typedef struct {
 OutputStream video_st, audio_st;
 const AVOutputFormat *fmt;
 AVFormatContext *oc;
 int have_video, have_audio, encode_video, encode_audio;
 std::string name;
 } encode_info;



Again, changing
STREAM_PIX_FMT
anything other thanAV_PIX_FMT_YUV420P
causes the program to give the error.

What is the cause of this and how can I fix this ? Also am I on the right track for fixing the pixelation problem ? I'm using ubuntu.


-
Google Optimize vs Matomo A/B Testing : Everything You Need to Know
17 mars 2023, par Erin — Analytics Tips