
Recherche avancée
Médias (1)
-
Richard Stallman et le logiciel libre
19 octobre 2011, par
Mis à jour : Mai 2013
Langue : français
Type : Texte
Autres articles (63)
-
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 (...) -
Des sites réalisés avec MediaSPIP
2 mai 2011, parCette page présente quelques-uns des sites fonctionnant sous MediaSPIP.
Vous pouvez bien entendu ajouter le votre grâce au formulaire en bas de page. -
HTML5 audio and video support
13 avril 2011, parMediaSPIP uses HTML5 video and audio tags to play multimedia files, taking advantage of the latest W3C innovations supported by modern browsers.
The MediaSPIP player used has been created specifically for MediaSPIP and can be easily adapted to fit in with a specific theme.
For older browsers the Flowplayer flash fallback is used.
MediaSPIP allows for media playback on major mobile platforms with the above (...)
Sur d’autres sites (4893)
-
swscale : fix gbrap to gbrap alpha scaling
15 janvier 2015, par Vittorio Giovara -
How can I use ffmpeg to create video with alpha from png in C code ?
29 juin 2023, par rebornI'm trying to encode a video (mov) from png images with alpha channel in FFMPEG. Using cmd :


ffmpeg -i %d.png -r 25 -vcodec png -b:v 2500K out.mov -y



It works well.


Now I want to use in c++ code, but it got error like this :


[mov @ 0x29bf0c0] muxer does not support non seekable output



I use it in code like this :


oformat = av_guess_format("mov", nullptr, nullptr)
oformat->video_codec = AV_CODEC_ID_PNG;



The ffmpeg shows :


ffmpeg -h muxer=mov
Muxer mov [QuickTime / MOV]:
Common extensions: mov.
Default video codec: h264.
Default audio codec: aac.



The default video codec is h264, but it can create mov with png encoder using ffmpeg Command Line like above


ffmpeg -i out.mov

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'resa.mov':
 Metadata:
 major_brand : qt
 minor_version : 512
 compatible_brands: qt
 encoder : Lavf59.24.100
 Duration: 00:00:03.00, start: 0.000000, bitrate: 13430 kb/s
 Stream #0:0: Video: png (png / 0x20676E70), rgba(pc), 1280x720, 13427 kb/s, 25 fps, 25 tbr, 12800 tbn, 12800 tbc (default)
 Metadata:
 handler_name : VideoHandler
 vendor_id : FFMP



How can I change this cmd to c code ?


ffmpeg -i %d.png -r 25 -vcodec png -b:v 2500K out.mov -y



The code I use :
Header file :


#ifndef _RENDER_H_
#define _RENDER_H_
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <cstring>
#include 
#include 
#include <algorithm>
#include <string> 

extern "C"
{
#include <libavcodec></libavcodec>avcodec.h>
#include <libavcodec></libavcodec>avfft.h>

#include <libavdevice></libavdevice>avdevice.h>

#include <libavfilter></libavfilter>avfilter.h>
//#include <libavfilter></libavfilter>avfiltergraph.h>
#include <libavfilter></libavfilter>buffersink.h>
#include <libavfilter></libavfilter>buffersrc.h>

#include <libavformat></libavformat>avformat.h>
#include <libavformat></libavformat>avio.h>

 

#include <libavutil></libavutil>opt.h>
#include <libavutil></libavutil>common.h>
#include <libavutil></libavutil>channel_layout.h>
#include <libavutil></libavutil>imgutils.h>
#include <libavutil></libavutil>mathematics.h>
#include <libavutil></libavutil>samplefmt.h>
#include <libavutil></libavutil>time.h>
#include <libavutil></libavutil>opt.h>
#include <libavutil></libavutil>pixdesc.h>
#include <libavutil></libavutil>file.h>


 
//#include "libavcodec/vdpau.h"
#include "libavutil/hwcontext.h"
//#include "libavutil/hwcontext_vdpau.h"

 

#include <libswscale></libswscale>swscale.h>

 class VideoCapture {
 public:

 VideoCapture() {
 oformat = nullptr;
 ofctx = nullptr;
 videoStream = nullptr;
 videoFrame = nullptr;
 swsCtx = nullptr;
 frameCounter = 0;

 
 av_register_all();
 //av_log_set_callback(avlog_cb);
 }

 ~VideoCapture() {
 //Free();
 }

 void Init(std::string name, int width, int height, int fpsrate, int bitrate);

 void AddFrame(uint8_t *data);

 void Finish();

 private:

 AVOutputFormat *oformat;
 AVFormatContext *ofctx;
 AVIOContext *avio_out;
 AVStream *videoStream;
 AVFrame *videoFrame;

 AVCodec *codec;
 AVCodecContext *cctx;
 struct buffer_data *bd;
 struct buffer_data* res_video;
 SwsContext *swsCtx;
 //FILE *fp_write;
 char* filename;
 //int buf_len;
 int frameCounter;

 int fps;

 void Free();

 void Remux();
 };

 struct buffer_data {
 uint8_t *ptr;
 size_t size; ///< size left in the buffer
 };

}
#endif
</string></algorithm></cstring></fstream></cstdlib></cstdio></iostream>


and the code :


#include "VideoCapture.h"
#define FINAL_FILE_NAME "record.mov"
#define VIDEO_TMP_FILE "tmp.avi"


using namespace std;

FILE *fp_write;
static int write_packet(void *opaque, uint8_t *buf, size_t buf_size)
{
 struct buffer_data *bd = (struct buffer_data *)opaque;
 printf("ptr :%p size:%zu\n", bd->ptr, bd->size);
 memcpy(bd->ptr + bd->size, buf, buf_size);
 bd->size = buf_size + bd->size;
 return 1;
}

void VideoCapture::Init(string filename, int width, int height, int fpsrate, int bitrate) {

 fps = fpsrate;

 int err;
 uint8_t *outbuffer=nullptr;
 outbuffer=(uint8_t*)av_malloc(32768);
 bd = (struct buffer_data*)malloc(sizeof(struct buffer_data));
 bd->ptr = (uint8_t*)av_malloc(1000000000);
 bd->size = 0;
 avio_out =avio_alloc_context(outbuffer, 32768,1,bd,nullptr,write_packet,nullptr);
 if (!(oformat = av_guess_format("mov", nullptr, nullptr))) {
 cout << "Failed to define output format"<< endl;
 return;
 }
 oformat->video_codec = AV_CODEC_ID_PNG;
 cout << "oformat->video_codec " << oformat->video_codec << endl;
 if ((err = avformat_alloc_output_context2(&ofctx, oformat, nullptr, nullptr) < 0)) {
 cout <<"Failed to allocate output context"<< endl;
 //Free();
 return;
 }
 cout << "oformat->video_codec " << oformat->video_codec << endl;
 if (!(codec = avcodec_find_encoder(oformat->video_codec))) {
 cout <<"Failed to find encoder"<< endl;
 //Free();
 return;
 }

 if (!(videoStream = avformat_new_stream(ofctx, codec))) {
 cout <<"Failed to create new stream"<< endl;
 //Free();
 return;
 }

 if (!(cctx = avcodec_alloc_context3(codec))) {
 cout <<"Failed to allocate codec context"<< endl;
 //Free();
 return;
 }

 videoStream->codecpar->codec_id = oformat->video_codec;
 videoStream->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
 videoStream->codecpar->width = width;
 videoStream->codecpar->height = height;
 videoStream->codecpar->format = AV_PIX_FMT_RGBA;
 videoStream->codecpar->bit_rate = bitrate * 1000;
 videoStream->time_base = { 1, fps };

 avcodec_parameters_to_context(cctx, videoStream->codecpar);
 cctx->time_base = { 1, fps };
 cctx->max_b_frames = 2;
 cctx->gop_size = 12;
 if (videoStream->codecpar->codec_id == AV_CODEC_ID_PNG) {
 //av_opt_set(cctx, "preset", "ultrafast", 0);
 }
 if (ofctx->oformat->flags & AVFMT_GLOBALHEADER) {
 cctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
 }
 avcodec_parameters_from_context(videoStream->codecpar, cctx);

 if ((err = avcodec_open2(cctx, codec, nullptr)) < 0) {
 cout <<"Failed to open codec"<< endl;
 Free();
 return;
 }
 
 ofctx->pb = avio_out;
 
 ofctx->flags=AVFMT_FLAG_CUSTOM_IO;
 if ((err = avformat_write_header(ofctx, nullptr)) < 0) {
 cout <<"Failed to write header"<< endl;
 Free();
 return;
 }

 //av_dump_format(ofctx, 0, VIDEO_TMP_FILE, 1);
 cout << "init com" << endl;
}

void VideoCapture::AddFrame(uint8_t *data) {
 int err;
 if (!videoFrame) {

 videoFrame = av_frame_alloc();
 videoFrame->format = AV_PIX_FMT_RGBA;
 videoFrame->width = cctx->width;
 videoFrame->height = cctx->height;

 if ((err = av_frame_get_buffer(videoFrame, 32)) < 0) {
 cout <<"Failed to allocate picture"<< endl;
 return;
 }
 }
 cout << "finish" << endl;
 if (!swsCtx) {
 swsCtx = sws_getContext(cctx->width, cctx->height, AV_PIX_FMT_RGBA, cctx->width, cctx->height, AV_PIX_FMT_RGBA, SWS_BICUBIC, 0, 0, 0);
 }

 int inLinesize[1] = { 4 * cctx->width};

 
 sws_scale(swsCtx, (const uint8_t * const *)&data, inLinesize, 0, cctx->height, videoFrame->data, videoFrame->linesize);

 videoFrame->pts = (1.0 / 30.0) * 90000 * (frameCounter++);;

 if ((err = avcodec_send_frame(cctx, videoFrame)) < 0) {
 cout <<"Failed to send frame"<< endl;
 return;
 }

 AVPacket pkt;
 av_init_packet(&pkt);
 pkt.data = nullptr;
 pkt.size = 0;

 if (avcodec_receive_packet(cctx, &pkt) == 0) {
 pkt.flags |= AV_PKT_FLAG_KEY;
 av_interleaved_write_frame(ofctx, &pkt);
 av_packet_unref(&pkt);
 }
}

void VideoCapture::Finish() {
 
 AVPacket pkt;
 av_init_packet(&pkt);
 pkt.data = nullptr;
 pkt.size = 0;

 for (;;) {
 avcodec_send_frame(cctx, nullptr);
 if (avcodec_receive_packet(cctx, &pkt) == 0) {
 av_interleaved_write_frame(ofctx, &pkt);
 av_packet_unref(&pkt);
 }
 else {
 break;
 }
 }
 
 
 av_write_trailer(ofctx);
 /*
 if (!(oformat->flags & AVFMT_NOFILE)) {
 int err = avio_close(ofctx->pb);
 if (err < 0) {
 cout <<"Failed to close file"<< endl;
 }
 }
 */
 fp_write = fopen(VIDEO_TMP_FILE, "wb");
 if (!feof(fp_write)) {
 int true_size = fwrite(bd->ptr, 1, bd->size, fp_write);
 std::cout << true_size << std::endl;
 }
 fcloseall();

 //Remux();
 //Free();
}

void VideoCapture::Free() {
 if (videoFrame) {
 //std::cout << "videoFrame " << std::endl;
 av_frame_free(&videoFrame);
 }
 if (cctx) {
 //std::cout << "cctx" << std::endl;
 avcodec_free_context(&cctx);
 }
 if (ofctx) {
 //std::cout << "ofctx" << ofctx << std::endl;
 avformat_free_context(ofctx);
 }
 if (swsCtx) {
 //std::cout << "swsCtx" << std::endl;
 sws_freeContext(swsCtx);
 }
 /*
 if (bd->ptr != (void*)0)
 {
 free(bd->ptr);
 }
 free(bd);*/
}

static int read_packet(void *opaque, uint8_t *buf, int buf_size)
{
 struct buffer_data *bd = (struct buffer_data *)opaque;
 buf_size = FFMIN(buf_size, bd->size);
 if(buf_size == 0) return -1;
 //printf("read ptr:%p size:%zu\n", bd->ptr, bd->size);
 /* copy internal buffer data to buf */
 memcpy(buf, bd->ptr, buf_size);
 bd->ptr += buf_size;
 bd->size -= buf_size;
 return buf_size;
}

void VideoCapture::Remux() {
 AVFormatContext *ifmt_ctx = nullptr, *ofmt_ctx = nullptr;
 int err;

 unsigned char* inbuffer=nullptr;
 inbuffer=(unsigned char*)av_malloc(32768);
 ifmt_ctx = avformat_alloc_context();
 AVIOContext *avio_in =avio_alloc_context(inbuffer, 32768 ,0,bd,read_packet,nullptr,nullptr);
 ifmt_ctx->pb=avio_in;
 
 if (!(oformat = av_guess_format(nullptr, nullptr, "h264"))) {
 cout << "Failed to define output format";
 return;
 }

 if ((err = avformat_open_input(&ifmt_ctx, "nullptr", 0, 0)) < 0) {
 cout <<"Failed to open input file for remuxing"<< endl;
 }
 if ((err = avformat_find_stream_info(ifmt_ctx, 0)) < 0) {
 cout <<"Failed to retrieve input stream information"<< endl;
 }
 if ((err = avformat_alloc_output_context2(&ofmt_ctx, oformat, nullptr, nullptr))) {
 cout <<"Failed to allocate output context"<< endl;
 }

 AVStream *inVideoStream = ifmt_ctx->streams[0];
 AVStream *outVideoStream = avformat_new_stream(ofmt_ctx, nullptr);
 if (!outVideoStream) {
 cout <<"Failed to allocate output video stream" << endl;
 }
 outVideoStream->time_base = { 1, fps };
 avcodec_parameters_copy(outVideoStream->codecpar, inVideoStream->codecpar);
 outVideoStream->codecpar->codec_tag = 0;
 
 uint8_t *outbuffer=nullptr;
 outbuffer=(uint8_t*)av_malloc(32768);
 res_video = (struct buffer_data*)malloc(sizeof(struct buffer_data));
 res_video->ptr = (uint8_t*)av_malloc(100000000);
 res_video->size = 0;

 if (!(ofmt_ctx->oformat->flags & AVFMT_NOFILE)) {
 avio_out =avio_alloc_context(outbuffer, 32768,1, res_video, nullptr, write_packet, nullptr);
 ofmt_ctx->pb = avio_out;
 }
 AVDictionary* opts = nullptr;
 av_dict_set(&opts, "movflags", "frag_keyframe+empty_moov", 0);
 if ((err = avformat_write_header(ofmt_ctx, &opts)) < 0) {
 cout <<"Failed to write header to output file"<< endl;
 }

 AVPacket videoPkt;
 int ts = 0;
 while (true) {
 if ((err = av_read_frame(ifmt_ctx, &videoPkt)) < 0) {
 break;
 }
 videoPkt.stream_index = outVideoStream->index;
 videoPkt.pts = ts;
 videoPkt.dts = ts;
 videoPkt.duration = av_rescale_q(videoPkt.duration, inVideoStream->time_base, outVideoStream->time_base);
 ts += videoPkt.duration;
 videoPkt.pos = -1;
 if ((err = av_interleaved_write_frame(ofmt_ctx, &videoPkt)) < 0) {
 cout <<"Failed to mux packet"<< endl;
 av_packet_unref(&videoPkt);
 break;
 }
 av_packet_unref(&videoPkt);
 }

 av_write_trailer(ofmt_ctx);
 cout << "res_video->size " << res_video->size << endl;
 fp_write=fopen(FINAL_FILE_NAME,"wb");
 if(!feof(fp_write)){
 int true_size=fwrite(res_video->ptr,1, res_video->size,fp_write);
 std::cout << true_size << std::endl;
 }
 fcloseall();
}



-
How to use callback function in ffmpeg
9 septembre 2014, par chesschistatic int interrupt_cb(void *ctx)
I understand that many of the functions provided by the ffmpeg libraries are blocking. In order to control the blocking function to timeout, we can assign a callback function to interrupt_callback.
For example, the
avformat_open_input
may take 1 second to complete. If I set a timer for 500 milliseconds, will it never be able to connect to the RTSP server and return non-zero value ?What is the optimal value for setting this timeout ? What will these blocking functions behave when the timeout value is too small ?
What is the best approach to use this callback function ?