
Recherche avancée
Médias (91)
-
Spoon - Revenge !
15 septembre 2011, par
Mis à jour : Septembre 2011
Langue : English
Type : Audio
-
My Morning Jacket - One Big Holiday
15 septembre 2011, par
Mis à jour : Septembre 2011
Langue : English
Type : Audio
-
Zap Mama - Wadidyusay ?
15 septembre 2011, par
Mis à jour : Septembre 2011
Langue : English
Type : Audio
-
David Byrne - My Fair Lady
15 septembre 2011, par
Mis à jour : Septembre 2011
Langue : English
Type : Audio
-
Beastie Boys - Now Get Busy
15 septembre 2011, par
Mis à jour : Septembre 2011
Langue : English
Type : Audio
-
Granite de l’Aber Ildut
9 septembre 2011, par
Mis à jour : Septembre 2011
Langue : français
Type : Texte
Autres articles (42)
-
MediaSPIP Core : La Configuration
9 novembre 2010, parMediaSPIP Core fournit par défaut trois pages différentes de configuration (ces pages utilisent le plugin de configuration CFG pour fonctionner) : une page spécifique à la configuration générale du squelettes ; une page spécifique à la configuration de la page d’accueil du site ; une page spécifique à la configuration des secteurs ;
Il fournit également une page supplémentaire qui n’apparait que lorsque certains plugins sont activés permettant de contrôler l’affichage et les fonctionnalités spécifiques (...) -
Configuration spécifique d’Apache
4 février 2011, parModules spécifiques
Pour la configuration d’Apache, il est conseillé d’activer certains modules non spécifiques à MediaSPIP, mais permettant d’améliorer les performances : mod_deflate et mod_headers pour compresser automatiquement via Apache les pages. Cf ce tutoriel ; mode_expires pour gérer correctement l’expiration des hits. Cf ce tutoriel ;
Il est également conseillé d’ajouter la prise en charge par apache du mime-type pour les fichiers WebM comme indiqué dans ce tutoriel.
Création d’un (...) -
Multilang : améliorer l’interface pour les blocs multilingues
18 février 2011, parMultilang est un plugin supplémentaire qui n’est pas activé par défaut lors de l’initialisation de MediaSPIP.
Après son activation, une préconfiguration est mise en place automatiquement par MediaSPIP init permettant à la nouvelle fonctionnalité d’être automatiquement opérationnelle. Il n’est donc pas obligatoire de passer par une étape de configuration pour cela.
Sur d’autres sites (3427)
-
Scale filter crashes with error when used from transcoding example
27 juin 2017, par ValiI’ve modified a bit (just to compile in c++) this code example :
https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/transcoding.c.What works : as is (null filter), a number of other filters like framerate, drawtext, ...
What doesn’t work : scale filter when scaling down.
I use the following syntax for scale ( I’ve tried many others also, same effect) :
"scale=w=iw/2 :-1"The error is : "Input picture width (240) is greater than stride (128)" where the values for width and stride depend on the input.
Misc environment info : windows, VS 2017, input example : rtsp ://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov
Any clue as to what I’m doing wrong ?
Thanks !
EDITED to add working code sample
#pragma comment(lib, "avcodec.lib")
#pragma comment(lib, "avutil.lib")
#pragma comment(lib, "avformat.lib")
#pragma comment(lib, "avfilter.lib")
/*
* Copyright (c) 2010 Nicolas George
* Copyright (c) 2011 Stefano Sabatini
* Copyright (c) 2014 Andrey Utkin
*
**** EDITED 2017 for testing (see original here: https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/transcoding.c)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* @file
* API example for demuxing, decoding, filtering, encoding and muxing
* @example transcoding.c
*/
extern "C"
{
#include <libavcodec></libavcodec>avcodec.h>
#include <libavformat></libavformat>avformat.h>
#include <libavfilter></libavfilter>avfiltergraph.h>
#include <libavfilter></libavfilter>buffersink.h>
#include <libavfilter></libavfilter>buffersrc.h>
#include <libavutil></libavutil>opt.h>
#include <libavutil></libavutil>pixdesc.h>
}
static AVFormatContext *ifmt_ctx;
static AVFormatContext *ofmt_ctx;
typedef struct FilteringContext {
AVFilterContext *buffersink_ctx;
AVFilterContext *buffersrc_ctx;
AVFilterGraph *filter_graph;
} FilteringContext;
static FilteringContext *filter_ctx;
typedef struct StreamContext {
AVCodecContext *dec_ctx;
AVCodecContext *enc_ctx;
} StreamContext;
static StreamContext *stream_ctx;
static int open_input_file(const char *filename, int& videoStreamIndex)
{
int ret;
unsigned int i;
ifmt_ctx = NULL;
if ((ret = avformat_open_input(&ifmt_ctx, filename, NULL, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
return ret;
}
if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n");
return ret;
}
// Just need video
videoStreamIndex = -1;
for (unsigned int i = 0; i < ifmt_ctx->nb_streams; i++)
{
if (ifmt_ctx->streams[i]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO)
continue;
videoStreamIndex = i;
break;
}
if (videoStreamIndex < 0)
{
av_log(NULL, AV_LOG_ERROR, "Cannot find video stream\n");
return videoStreamIndex;
}
stream_ctx = (StreamContext*)av_mallocz_array(ifmt_ctx->nb_streams, sizeof(*stream_ctx));
if (!stream_ctx)
return AVERROR(ENOMEM);
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
// Just need video
if (i != videoStreamIndex)
continue;
AVStream *stream = ifmt_ctx->streams[i];
AVCodec *dec = avcodec_find_decoder(stream->codecpar->codec_id);
AVCodecContext *codec_ctx;
if (!dec) {
av_log(NULL, AV_LOG_ERROR, "Failed to find decoder for stream #%u\n", i);
return AVERROR_DECODER_NOT_FOUND;
}
codec_ctx = avcodec_alloc_context3(dec);
if (!codec_ctx) {
av_log(NULL, AV_LOG_ERROR, "Failed to allocate the decoder context for stream #%u\n", i);
return AVERROR(ENOMEM);
}
ret = avcodec_parameters_to_context(codec_ctx, stream->codecpar);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Failed to copy decoder parameters to input decoder context "
"for stream #%u\n", i);
return ret;
}
/* Reencode video & audio and remux subtitles etc. */
if (codec_ctx->codec_type == AVMEDIA_TYPE_VIDEO
|| codec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
if (codec_ctx->codec_type == AVMEDIA_TYPE_VIDEO)
codec_ctx->framerate = av_guess_frame_rate(ifmt_ctx, stream, NULL);
/* Open decoder */
ret = avcodec_open2(codec_ctx, dec, NULL);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Failed to open decoder for stream #%u\n", i);
return ret;
}
}
stream_ctx[i].dec_ctx = codec_ctx;
}
av_dump_format(ifmt_ctx, 0, filename, 0);
return 0;
}
static int open_output_file(const char *filename, const int videoStreamIndex)
{
AVStream *out_stream;
AVStream *in_stream;
AVCodecContext *dec_ctx, *enc_ctx;
AVCodec *encoder;
int ret;
unsigned int i;
ofmt_ctx = NULL;
avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, filename);
if (!ofmt_ctx) {
av_log(NULL, AV_LOG_ERROR, "Could not create output context\n");
return AVERROR_UNKNOWN;
}
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
// Just need video
if (i != videoStreamIndex)
continue;
out_stream = avformat_new_stream(ofmt_ctx, NULL);
if (!out_stream) {
av_log(NULL, AV_LOG_ERROR, "Failed allocating output stream\n");
return AVERROR_UNKNOWN;
}
in_stream = ifmt_ctx->streams[i];
dec_ctx = stream_ctx[i].dec_ctx;
if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO) {
/* in this example, we choose transcoding to same codec */
encoder = avcodec_find_encoder(dec_ctx->codec_id);
if (!encoder) {
av_log(NULL, AV_LOG_FATAL, "Necessary encoder not found\n");
return AVERROR_INVALIDDATA;
}
enc_ctx = avcodec_alloc_context3(encoder);
if (!enc_ctx) {
av_log(NULL, AV_LOG_FATAL, "Failed to allocate the encoder context\n");
return AVERROR(ENOMEM);
}
/* In this example, we transcode to same properties (picture size,
* sample rate etc.). These properties can be changed for output
* streams easily using filters */
enc_ctx->height = dec_ctx->height;
enc_ctx->width = dec_ctx->width;
enc_ctx->sample_aspect_ratio = dec_ctx->sample_aspect_ratio;
/* take first format from list of supported formats */
if (encoder->pix_fmts)
enc_ctx->pix_fmt = encoder->pix_fmts[0];
else
enc_ctx->pix_fmt = dec_ctx->pix_fmt;
/* video time_base can be set to whatever is handy and supported by encoder */
//enc_ctx->time_base = av_inv_q(dec_ctx->framerate);
enc_ctx->time_base = dec_ctx->time_base;
/* Third parameter can be used to pass settings to encoder */
ret = avcodec_open2(enc_ctx, encoder, NULL);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot open video encoder for stream #%u\n", i);
return ret;
}
ret = avcodec_parameters_from_context(out_stream->codecpar, enc_ctx);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Failed to copy encoder parameters to output stream #%u\n", i);
return ret;
}
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
out_stream->time_base = enc_ctx->time_base;
stream_ctx[i].enc_ctx = enc_ctx;
}
else if (dec_ctx->codec_type == AVMEDIA_TYPE_UNKNOWN) {
av_log(NULL, AV_LOG_FATAL, "Elementary stream #%d is of unknown type, cannot proceed\n", i);
return AVERROR_INVALIDDATA;
}
else {
/* if this stream must be remuxed */
ret = avcodec_parameters_copy(out_stream->codecpar, in_stream->codecpar);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Copying parameters for stream #%u failed\n", i);
return ret;
}
out_stream->time_base = in_stream->time_base;
}
}
av_dump_format(ofmt_ctx, 0, filename, 1);
if (!(ofmt_ctx->oformat->flags & AVFMT_NOFILE)) {
ret = avio_open(&ofmt_ctx->pb, filename, AVIO_FLAG_WRITE);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Could not open output file '%s'", filename);
return ret;
}
}
/* init muxer, write output file header */
ret = avformat_write_header(ofmt_ctx, NULL);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error occurred when opening output file\n");
return ret;
}
return 0;
}
static int init_filter(FilteringContext* fctx, AVCodecContext *dec_ctx,
AVCodecContext *enc_ctx, const char *filter_spec)
{
char args[512];
int ret = 0;
AVFilter *buffersrc = NULL;
AVFilter *buffersink = NULL;
AVFilterContext *buffersrc_ctx = NULL;
AVFilterContext *buffersink_ctx = NULL;
AVFilterInOut *outputs = avfilter_inout_alloc();
AVFilterInOut *inputs = avfilter_inout_alloc();
AVFilterGraph *filter_graph = avfilter_graph_alloc();
if (!outputs || !inputs || !filter_graph) {
ret = AVERROR(ENOMEM);
goto end;
}
if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO) {
buffersrc = avfilter_get_by_name("buffer");
buffersink = avfilter_get_by_name("buffersink");
if (!buffersrc || !buffersink) {
av_log(NULL, AV_LOG_ERROR, "filtering source or sink element not found\n");
ret = AVERROR_UNKNOWN;
goto end;
}
snprintf(args, sizeof(args),
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt,
dec_ctx->time_base.num, dec_ctx->time_base.den,
dec_ctx->sample_aspect_ratio.num,
dec_ctx->sample_aspect_ratio.den);
ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
args, NULL, filter_graph);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n");
goto end;
}
ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",
NULL, NULL, filter_graph);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");
goto end;
}
ret = av_opt_set_bin(buffersink_ctx, "pix_fmts",
(uint8_t*)&enc_ctx->pix_fmt, sizeof(enc_ctx->pix_fmt),
AV_OPT_SEARCH_CHILDREN);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot set output pixel format\n");
goto end;
}
}
else {
ret = AVERROR_UNKNOWN;
goto end;
}
/* Endpoints for the filter graph. */
outputs->name = av_strdup("in");
outputs->filter_ctx = buffersrc_ctx;
outputs->pad_idx = 0;
outputs->next = NULL;
inputs->name = av_strdup("out");
inputs->filter_ctx = buffersink_ctx;
inputs->pad_idx = 0;
inputs->next = NULL;
if (!outputs->name || !inputs->name) {
ret = AVERROR(ENOMEM);
goto end;
}
if ((ret = avfilter_graph_parse_ptr(filter_graph, filter_spec,
&inputs, &outputs, NULL)) < 0)
goto end;
if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
goto end;
/* Fill FilteringContext */
fctx->buffersrc_ctx = buffersrc_ctx;
fctx->buffersink_ctx = buffersink_ctx;
fctx->filter_graph = filter_graph;
end:
avfilter_inout_free(&inputs);
avfilter_inout_free(&outputs);
return ret;
}
static int init_filters(const int videoStreamIndex)
{
const char *filter_spec;
unsigned int i;
int ret;
filter_ctx = (FilteringContext*)av_malloc_array(ifmt_ctx->nb_streams, sizeof(*filter_ctx));
if (!filter_ctx)
return AVERROR(ENOMEM);
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
// Just video
if (i != videoStreamIndex)
continue;
filter_ctx[i].buffersrc_ctx = NULL;
filter_ctx[i].buffersink_ctx = NULL;
filter_ctx[i].filter_graph = NULL;
if (!(ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO
|| ifmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO))
continue;
filter_spec = "null"; /* passthrough (dummy) filter for video */
//filter_spec = "scale=w=iw/2:-1";
// filter_spec = "drawtext=fontfile=FreeSerif.ttf: text='%{localtime}': x=w-text_w: y=0: fontsize=24: fontcolor=yellow@1.0: box=1: boxcolor=red@1.0";
// filter_spec = "drawtext=fontfile=FreeSerif.ttf :text='test': x=w-text_w: y=text_h: fontsize=24: fontcolor=yellow@1.0: box=1: boxcolor=red@1.0";
ret = init_filter(&filter_ctx[i], stream_ctx[i].dec_ctx,
stream_ctx[i].enc_ctx, filter_spec);
if (ret)
return ret;
}
return 0;
}
static int encode_write_frame(AVFrame *filt_frame, unsigned int stream_index, int *got_frame, const int videoStreamIndex) {
// Just video
if (stream_index != videoStreamIndex)
return 0;
int ret;
int got_frame_local;
AVPacket enc_pkt;
int(*enc_func)(AVCodecContext *, AVPacket *, const AVFrame *, int *) =
(ifmt_ctx->streams[stream_index]->codecpar->codec_type ==
AVMEDIA_TYPE_VIDEO) ? avcodec_encode_video2 : avcodec_encode_audio2;
if (!got_frame)
got_frame = &got_frame_local;
// av_log(NULL, AV_LOG_INFO, "Encoding frame\n");
/* encode filtered frame */
enc_pkt.data = NULL;
enc_pkt.size = 0;
av_init_packet(&enc_pkt);
ret = enc_func(stream_ctx[stream_index].enc_ctx, &enc_pkt,
filt_frame, got_frame);
av_frame_free(&filt_frame);
if (ret < 0)
return ret;
if (!(*got_frame))
return 0;
/* prepare packet for muxing */
/*enc_pkt.stream_index = stream_index;
av_packet_rescale_ts(&enc_pkt, stream_ctx[stream_index].enc_ctx->time_base, ofmt_ctx->streams[stream_index]->time_base);*/
enc_pkt.stream_index = 0;
av_packet_rescale_ts(&enc_pkt, stream_ctx[stream_index].enc_ctx->time_base, ofmt_ctx->streams[0]->time_base);
av_log(NULL, AV_LOG_DEBUG, "Muxing frame\n");
/* mux encoded frame */
ret = av_interleaved_write_frame(ofmt_ctx, &enc_pkt);
return ret;
}
static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index, const int videoStreamIndex)
{
// Just video, all else crashes
if (stream_index != videoStreamIndex)
return 0;
int ret;
AVFrame *filt_frame;
// av_log(NULL, AV_LOG_INFO, "Pushing decoded frame to filters\n");
/* push the decoded frame into the filtergraph */
ret = av_buffersrc_add_frame_flags(filter_ctx[stream_index].buffersrc_ctx,
frame, 0);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");
return ret;
}
/* pull filtered frames from the filtergraph */
while (1) {
filt_frame = av_frame_alloc();
if (!filt_frame) {
ret = AVERROR(ENOMEM);
break;
}
// av_log(NULL, AV_LOG_INFO, "Pulling filtered frame from filters\n");
ret = av_buffersink_get_frame(filter_ctx[stream_index].buffersink_ctx,
filt_frame);
if (ret < 0) {
/* if no more frames for output - returns AVERROR(EAGAIN)
* if flushed and no more frames for output - returns AVERROR_EOF
* rewrite retcode to 0 to show it as normal procedure completion
*/
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
ret = 0;
av_frame_free(&filt_frame);
break;
}
filt_frame->pict_type = AV_PICTURE_TYPE_NONE;
ret = encode_write_frame(filt_frame, stream_index, NULL, videoStreamIndex);
if (ret < 0)
break;
}
return ret;
}
static int flush_encoder(unsigned int stream_index, const int videoStreamIndex)
{
int ret;
int got_frame;
// Just video
if (stream_index != videoStreamIndex)
return 0;
if (!(stream_ctx[stream_index].enc_ctx->codec->capabilities &
AV_CODEC_CAP_DELAY))
return 0;
while (1) {
av_log(NULL, AV_LOG_INFO, "Flushing stream #%u encoder\n", stream_index);
ret = encode_write_frame(NULL, stream_index, &got_frame, videoStreamIndex);
if (ret < 0)
break;
if (!got_frame)
return 0;
}
return ret;
}
#include <vector>
int main(int argc, char **argv)
{
int ret;
AVPacket packet;
packet.data = NULL;
packet.size = 0;
AVFrame *frame = NULL;
enum AVMediaType type;
unsigned int stream_index;
unsigned int i;
int got_frame;
int(*dec_func)(AVCodecContext *, AVFrame *, int *, const AVPacket *);
#ifdef _DEBUG
// Hardcoded arguments
std::vector varguments;
{
varguments.push_back(argv[0]);
// Source
varguments.push_back("./big_buck_bunny_short.mp4 ");
// Destination
varguments.push_back("./big_buck_bunny_short-processed.mp4");
}
char** arguments = new char*[varguments.size()];
for (unsigned int i = 0; i < varguments.size(); i++)
{
arguments[i] = varguments[i];
}
argc = varguments.size();
argv = arguments;
#endif // _DEBUG
if (argc != 3) {
av_log(NULL, AV_LOG_ERROR, "Usage: %s <input file="file" /> <output file="file">\n", argv[0]);
return 1;
}
av_register_all();
avfilter_register_all();
int videoStreamIndex = -1;
if ((ret = open_input_file(argv[1], videoStreamIndex)) < 0)
goto end;
if ((ret = open_output_file(argv[2], videoStreamIndex)) < 0)
goto end;
if ((ret = init_filters(videoStreamIndex)) < 0)
goto end;
// Stop after a couple of frames
int framesToGet = 100;
/* read all packets */
//while (framesToGet--)
while(1)
{
if ((ret = av_read_frame(ifmt_ctx, &packet)) < 0)
break;
stream_index = packet.stream_index;
// I just need video
if (stream_index != videoStreamIndex) {
av_packet_unref(&packet);
continue;
}
type = ifmt_ctx->streams[packet.stream_index]->codecpar->codec_type;
av_log(NULL, AV_LOG_DEBUG, "Demuxer gave frame of stream_index %u\n",
stream_index);
if (filter_ctx[stream_index].filter_graph) {
av_log(NULL, AV_LOG_DEBUG, "Going to reencode&filter the frame\n");
frame = av_frame_alloc();
if (!frame) {
ret = AVERROR(ENOMEM);
break;
}
av_packet_rescale_ts(&packet,
ifmt_ctx->streams[stream_index]->time_base,
stream_ctx[stream_index].dec_ctx->time_base);
dec_func = (type == AVMEDIA_TYPE_VIDEO) ? avcodec_decode_video2 :
avcodec_decode_audio4;
ret = dec_func(stream_ctx[stream_index].dec_ctx, frame,
&got_frame, &packet);
if (ret < 0) {
av_frame_free(&frame);
av_log(NULL, AV_LOG_ERROR, "Decoding failed\n");
break;
}
if (got_frame) {
frame->pts = frame->best_effort_timestamp;
ret = filter_encode_write_frame(frame, stream_index, videoStreamIndex);
av_frame_free(&frame);
if (ret < 0)
goto end;
}
else {
av_frame_free(&frame);
}
}
else {
/* remux this frame without reencoding */
av_packet_rescale_ts(&packet,
ifmt_ctx->streams[stream_index]->time_base,
ofmt_ctx->streams[stream_index]->time_base);
ret = av_interleaved_write_frame(ofmt_ctx, &packet);
if (ret < 0)
goto end;
}
av_packet_unref(&packet);
}
/* flush filters and encoders */
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
/* flush filter */
if (!filter_ctx[i].filter_graph)
continue;
ret = filter_encode_write_frame(NULL, i, videoStreamIndex);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Flushing filter failed\n");
goto end;
}
/* flush encoder */
ret = flush_encoder(i, videoStreamIndex);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Flushing encoder failed\n");
goto end;
}
}
av_write_trailer(ofmt_ctx);
end:
av_packet_unref(&packet);
av_frame_free(&frame);
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
// Just video
if (i != videoStreamIndex)
continue;
avcodec_free_context(&stream_ctx[i].dec_ctx);
if (ofmt_ctx && ofmt_ctx->nb_streams > i && ofmt_ctx->streams[i] && stream_ctx[i].enc_ctx)
avcodec_free_context(&stream_ctx[i].enc_ctx);
if (filter_ctx && filter_ctx[i].filter_graph)
avfilter_graph_free(&filter_ctx[i].filter_graph);
}
av_free(filter_ctx);
av_free(stream_ctx);
avformat_close_input(&ifmt_ctx);
if (ofmt_ctx && !(ofmt_ctx->oformat->flags & AVFMT_NOFILE))
avio_closep(&ofmt_ctx->pb);
avformat_free_context(ofmt_ctx);
/*if (ret < 0)
av_log(NULL, AV_LOG_ERROR, "Error occurred: %s\n", av_err2str(ret));*/
return ret ? 1 : 0;
}
</output></vector> -
What ffmpeg settings to ensure 0 duplicate frames and 0 dropped frames when capturing to mpeg-2 program stream using ffmpeg/avfoundation on Mac ?
16 février 2017, par aerodavoI’m trying to capture to a DVD compliant mpeg-2 file (ffmpeg :
-target ntsc-dvd
) from the HDMI output of a camcorder into a Magewell HDMI to USB 3.0 box into my Late 2012 15" non-retina MacBook Pro (quad core 2.3, 16gb ram, ssd), using ffmpeg/avfoundation.I’ve tried everything I can think of, or find online. I’m still getting duplicate and dropped frames, which either leads to audio/video sync issues, or audio dropouts, especially for longer recordings. I need this to be stable for recordings of up to 2.5 hours. This is the Terminal output for a 1.5 hour recording :
Lapaki:~ Lapaki$ /Users/Lapaki/Desktop/ffmpeg -f avfoundation -video_size 960x540 -pixel_format uyvy422 -framerate ntsc -i "XI:XI" -vf crop=iw-240:ih:120:0 -target ntsc-dvd -aspect 4:3 -q:v 3 -ab 256k /Users/Lapaki/Desktop/FF\ Test/`date +%F`\ `date +%H_%M_%S`.mpg
ffmpeg version 3.2.3-tessus Copyright (c) 2000-2017 the FFmpeg developers
built with Apple LLVM version 8.0.0 (clang-800.0.42.1)
configuration: --cc=/usr/bin/clang --prefix=/opt/ffmpeg --extra-version=tessus --enable-avisynth --enable-fontconfig --enable-gpl --enable-libass --enable-libbluray --enable-libfreetype --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopus --enable-libschroedinger --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzmq --enable-version3 --disable-ffplay --disable-indev=qtkit --disable-indev=x11grab_xcb
libavutil 55. 34.101 / 55. 34.101
libavcodec 57. 64.101 / 57. 64.101
libavformat 57. 56.101 / 57. 56.101
libavdevice 57. 1.100 / 57. 1.100
libavfilter 6. 65.100 / 6. 65.100
libswscale 4. 2.100 / 4. 2.100
libswresample 2. 3.100 / 2. 3.100
libpostproc 54. 1.100 / 54. 1.100
Input #0, avfoundation, from 'XI:XI':
Duration: N/A, start: 610606.984208, bitrate: N/A
Stream #0:0: Video: rawvideo (UYVY / 0x59565955), uyvy422, 960x540, 29.97 fps, 29.97 tbr, 1000k tbn, 1000k tbc
Stream #0:1: Audio: pcm_f32le, 48000 Hz, stereo, flt, 3072 kb/s
Output #0, dvd, to '/Users/Lapaki/Desktop/FF Test/2017-02-15 17_46_28.mpg':
Metadata:
encoder : Lavf57.56.101
Stream #0:0: Video: mpeg2video (Main), yuv420p, 720x480 [SAR 8:9 DAR 4:3], q=2-31, 6000 kb/s, 29.97 fps, 90k tbn, 29.97 tbc
Metadata:
encoder : Lavc57.64.101 mpeg2video
Side data:
cpb: bitrate max/min/avg: 9000000/0/6000000 buffer size: 1835008 vbv_delay: -1
Stream #0:1: Audio: ac3, 48000 Hz, stereo, fltp, 256 kb/s
Metadata:
encoder : Lavc57.64.101 ac3
Stream mapping:
Stream #0:0 -> #0:0 (rawvideo (native) -> mpeg2video (native))
Stream #0:1 -> #0:1 (pcm_f32le (native) -> ac3 (native))
Press [q] to stop, [?] for help
[swscaler @ 0x7fd315892800] Warning: data is not aligned! This can lead to a speedloss
frame= 20 fps=0.0 q=3.0 size= 298kB time=00:00:00.65 bitrate=3721.4kbits/sframe= 35 fps= 35 q=3.0 size= 498kB time=00:00:01.13 bitrate=3591.2kbits/sframe= 50 fps= 33 q=3.0 size= 708kB time=00:00:01.64 bitrate=3519.4kbits/sframe= 65 fps= 32 q=3.0 size= 920kB time=00:00:02.16
...
bitrate=2721.7kbits/frame=162094 fps= 30 q=3.0 size= 1796936kB time=01:30:08.47 bitrate=2721.7kbits/frame=162109 fps= 30 q=3.0 size= 1797142kB time=01:30:08.98 bitrate=2721.8kbits/frame=162110 fps= 30 q=3.0 Lsize= 1797202kB time=01:30:09.01 bitrate=2721.9kbits/s dup=221 drop=0 speed= 1x
video:1579050kB audio:168069kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 2.866632%I deleted the middle part (denoted by the "..."), which is just a lot more of the same accumulating information. By the end there are 221 duplicate frames, and for this one I didn’t get any dropped frames, but that happens every other time as well it seems.
With this code, the audio seems to stay in pretty good sync, but I get little dropouts every 30 seconds to a minute or so. On this recording, there are dropouts at :
00:00:43, 00:01:19, 00:01:47, 00:02:17, 00:03:18, ...
I stopped listening there ; they happen at the end too, so I assume similarly spaced dropouts are happening throughout the file.
Is there some secret ffmpeg code to ensure there are no dropped or duplicate frames when capturing from a live source to dvd compliant mpeg-2 files ?
When I convert from pretty much any type of file to mpeg-2 files using
-target ntsc-dvd
, the speed is something like 10x on this machine, so it seems like it would have no problem keeping up with a live source, right ?I’ve also tried constant bit rate using
-b:v 5000k -minrate 5000k -maxrate 5000k -bufsize 2500k
, which also doesn’t prevent dropped/duplicate frames.I’ve tried separating out the audio and video inputs, which doesn’t solve it.
I’ve tried using
-vsync 0
on the video input, which does seem to solve the issue, because the output doesn’t report dups/drops, but the audio/video drift out of sync more and more, so that hasn’t worked either.Thanks so much for any help. I’ve been testing and testing and searching and searching for weeks...
-
Using ffmpeg and ffserver to create a 2x1 live stream fails with unconnected output error
31 janvier 2021, par weevilknievelI want to combine 2 RTSP streams (CCTV cameras) into a horizontal 2x1 strip and convert to webm for use in a HTML5 webpage.



I am able to convert the streams into an mpeg or avi file easily, but as soon as I try to post it to ffserver ffm feed, I hit a wall.



Here is my working ffmpeg command which writes out to a file :



ffmpeg -rtsp_transport tcp -thread_queue_size 12 -i "rtsp://192.168.1.132:554/user=admin&password=mypassword&channel=1&stream=1.sdp" -i "rtsp://192.168.1.132:554/user=admin&password=mypassword&channel=2&stream=1.sdp" -filter_complex "[0:v][1:v] hstack=inputs=2 [v]" -map "[v]" -r 30 output.mpg




It seems the ffmpeg process is outputting two streams and one of them is MPEG ? In the above command I had to put a frame rate "-r 30" into the command otherwise I got an error which said that MPEG 1/2 did not support a framerate of 5/1 ??



As soon as I try and stream to ffserver, I get an error :



ffmpeg -rtsp_transport tcp -thread_queue_size 12 -i "rtsp://192.168.1.132:554/user=admin&password=mypassword&channel=1&stream=1.sdp" -i "rtsp://192.168.1.132:554/user=admin&password=mypassword&channel=2&stream=1.sdp" -filter_complex "[0:v][1:v] hstack=inputs=2 [v]" -map "[v]" -r 30 http://localhost:8090/feed5.ffm




The error I get is "Filter hstack has an unconnected output" :



ffmpeg version N-86111-ga441aa90e8-static http://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2017 the FFmpeg developers
 built with gcc 5.4.1 (Debian 5.4.1-8) 20170304
 configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc-5 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gray --enable-libass --enable-libfreetype --enable-libfribidi --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libzimg
 libavutil 55. 63.100 / 55. 63.100
 libavcodec 57. 96.101 / 57. 96.101
 libavformat 57. 72.101 / 57. 72.101
 libavdevice 57. 7.100 / 57. 7.100
 libavfilter 6. 89.101 / 6. 89.101
 libswscale 4. 7.101 / 4. 7.101
 libswresample 2. 8.100 / 2. 8.100
 libpostproc 54. 6.100 / 54. 6.100
Input #0, rtsp, from 'rtsp://192.168.1.132:554/user=admin&password=mypassword&channel=1&stream=1.sdp':
 Duration: N/A, start: 0.166667, bitrate: N/A
 Stream #0:0: Video: h264 (High), yuv420p(progressive), 352x288, 6 fps, 6 tbr, 90k tbn, 180k tbc
Input #1, rtsp, from 'rtsp://192.168.1.132:554/user=admin&password=mypassword&channel=2&stream=1.sdp':
 Duration: N/A, start: 0.166667, bitrate: N/A
 Stream #1:0: Video: h264 (High), yuv420p(progressive), 352x288, 6 fps, 6 tbr, 90k tbn, 180k tbc
Filter hstack has an unconnected output




My ffserver conf is very basic :



HTTPPort 8090
HTTPBindAddress 0.0.0.0
MaxHTTPConnections 2000
MaxClients 1000
MaxBandwidth 100000
CustomLog -

<feed>
File /mnt/ramdisk/feed5.ffm
Truncate
FileMaxSize 5M
ACL allow 127.0.0.1
</feed>

<stream>
 Format webm
 Feed feed5.ffm
 VideoCodec libvpx
 VideoSize 640x360
 NoAudio
 AVOptionVideo quality realtime
 StartSendOnKey
 VideoBitRate 140
</stream>

<stream>
Format status
ACL allow localhost
ACL allow 192.168.0.0 192.168.255.255
</stream>
<redirect>
URL http://www.ffmpeg.org/
</redirect>




Edit :



Here is the debug output from the ffmpeg command above :



ffmpeg -v debug -rtsp_transport tcp -thread_queue_size 12 -i "rtsp://192.168.1.132:554/user=admin&password=mypassword&channel=1&stream=1.sdp" -i "rtsp://192.168.1.132:554/user=admin&password=mypassword&channel=2&stream=1.sdp" -filter_complex "[0:v][1:v] hstack=inputs=2 [v]" -map "[v]" -r 30 http://localhost:8090/feed5.ffm
ffmpeg version N-86111-ga441aa90e8-static http://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2017 the FFmpeg developers
 built with gcc 5.4.1 (Debian 5.4.1-8) 20170304
 configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc-5 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gray --enable-libass --enable-libfreetype --enable-libfribidi --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libzimg
 libavutil 55. 63.100 / 55. 63.100
 libavcodec 57. 96.101 / 57. 96.101
 libavformat 57. 72.101 / 57. 72.101
 libavdevice 57. 7.100 / 57. 7.100
 libavfilter 6. 89.101 / 6. 89.101
 libswscale 4. 7.101 / 4. 7.101
 libswresample 2. 8.100 / 2. 8.100
 libpostproc 54. 6.100 / 54. 6.100
Splitting the commandline.
Reading option '-v' ... matched as option 'v' (set logging level) with argument 'debug'.
Reading option '-rtsp_transport' ... matched as AVOption 'rtsp_transport' with argument 'tcp'.
Reading option '-thread_queue_size' ... matched as option 'thread_queue_size' (set the maximum number of queued packets from the demuxer) with argument '12'.
Reading option '-i' ... matched as input url with argument 'rtsp://192.168.1.132:554/user=admin&password=mypassword&channel=1&stream=1.sdp'.
Reading option '-i' ... matched as input url with argument 'rtsp://192.168.1.132:554/user=admin&password=mypassword&channel=2&stream=1.sdp'.
Reading option '-filter_complex' ... matched as option 'filter_complex' (create a complex filtergraph) with argument '[0:v][1:v] hstack=inputs=2 [v]'.
Reading option '-map' ... matched as option 'map' (set input stream mapping) with argument '[v]'.
Reading option '-r' ... matched as option 'r' (set frame rate (Hz value, fraction or abbreviation)) with argument '30'.
Reading option 'http://localhost:8090/feed5.ffm' ... matched as output url.
Finished splitting the commandline.
Parsing a group of options: global .
Applying option v (set logging level) with argument debug.
Applying option filter_complex (create a complex filtergraph) with argument [0:v][1:v] hstack=inputs=2 [v].
Successfully parsed a group of options.
Parsing a group of options: input url rtsp://192.168.1.132:554/user=admin&password=mypassword&channel=1&stream=1.sdp.
Applying option thread_queue_size (set the maximum number of queued packets from the demuxer) with argument 12.
Successfully parsed a group of options.
Opening an input file: rtsp://192.168.1.132:554/user=admin&password=mypassword&channel=1&stream=1.sdp.
[tcp @ 0x58fb5e0] No default whitelist set
[rtsp @ 0x58f9700] SDP:
v=0
o=- 38990265062388 38990265062388 IN IP4 192.168.1.132
a=range:npt=0-
m=video 0 RTP/AVP 96
c=IN IP4 0.0.0.0
a=rtpmap:96 H264/90000
a=framerate:0S
a=fmtp:96 profile-level-id=640014; packetization-mode=1; sprop-parameter-sets=Z2QAFK2EAQwgCGEAQwgCGEAQwgCEK1CwSyA=,aO48sA==
a=control:trackID=3

Failed to parse interval end specification ''
[rtsp @ 0x58f9700] video codec set to: h264
[rtsp @ 0x58f9700] RTP Profile IDC: 64 Profile IOP: 0 Level: 14
[rtsp @ 0x58f9700] RTP Packetization Mode: 1
[rtsp @ 0x58f9700] Extradata set to 0x58fb940 (size: 38)
[rtsp @ 0x58f9700] setting jitter buffer size to 0
[rtsp @ 0x58f9700] hello state=0
[h264 @ 0x58fca00] nal_unit_type: 7, nal_ref_idc: 3
[h264 @ 0x58fca00] nal_unit_type: 8, nal_ref_idc: 3
[h264 @ 0x58fca00] nal_unit_type: 7, nal_ref_idc: 3
[h264 @ 0x58fca00] nal_unit_type: 8, nal_ref_idc: 3
[h264 @ 0x58fca00] unknown SEI type 229
[h264 @ 0x58fca00] nal_unit_type: 7, nal_ref_idc: 3
[h264 @ 0x58fca00] nal_unit_type: 8, nal_ref_idc: 3
[h264 @ 0x58fca00] nal_unit_type: 6, nal_ref_idc: 0
[h264 @ 0x58fca00] nal_unit_type: 5, nal_ref_idc: 3
[h264 @ 0x58fca00] unknown SEI type 229
[h264 @ 0x58fca00] Reinit context to 352x288, pix_fmt: yuv420p
[h264 @ 0x58fca00] nal_unit_type: 1, nal_ref_idc: 3
 Last message repeated 5 times
[h264 @ 0x58fca00] unknown SEI type 229
 Last message repeated 1 times
[rtsp @ 0x58f9700] All info found
[rtsp @ 0x58f9700] Setting avg frame rate based on r frame rate
Input #0, rtsp, from 'rtsp://192.168.1.132:554/user=admin&password=mypassword&channel=1&stream=1.sdp':
 Duration: N/A, start: 0.166667, bitrate: N/A
 Stream #0:0, 28, 1/90000: Video: h264 (High), 1 reference frame, yuv420p(progressive, left), 352x288, 0/1, 6 fps, 6 tbr, 90k tbn, 180k tbc
Successfully opened the file.
Parsing a group of options: input url rtsp://192.168.1.132:554/user=admin&password=mypassword&channel=2&stream=1.sdp.
Successfully parsed a group of options.
Opening an input file: rtsp://192.168.1.132:554/user=admin&password=mypassword&channel=2&stream=1.sdp.
[tcp @ 0x59f4280] No default whitelist set
[rtsp @ 0x59f7620] SDP:
v=0
o=- 38990265062388 38990265062388 IN IP4 192.168.1.132
a=range:npt=0-
m=video 0 RTP/AVP 96
c=IN IP4 0.0.0.0
a=rtpmap:96 H264/90000
a=framerate:0S
a=fmtp:96 profile-level-id=640014; packetization-mode=1; sprop-parameter-sets=Z2QAFK2EAQwgCGEAQwgCGEAQwgCEK1CwSyA=,aO48sA==
a=control:trackID=3

Failed to parse interval end specification ''
[rtsp @ 0x59f7620] video codec set to: h264
[rtsp @ 0x59f7620] RTP Profile IDC: 64 Profile IOP: 0 Level: 14
[rtsp @ 0x59f7620] RTP Packetization Mode: 1
[rtsp @ 0x59f7620] Extradata set to 0x59f3670 (size: 38)
[rtp @ 0x59f62a0] No default whitelist set
[udp @ 0x58fb6a0] No default whitelist set
[udp @ 0x58fb6a0] end receive buffer size reported is 131072
[udp @ 0x591b940] No default whitelist set
[udp @ 0x591b940] end receive buffer size reported is 131072
[rtsp @ 0x59f7620] setting jitter buffer size to 500
[rtsp @ 0x59f7620] hello state=0
[h264 @ 0x59e4b20] nal_unit_type: 7, nal_ref_idc: 3
[h264 @ 0x59e4b20] nal_unit_type: 8, nal_ref_idc: 3
[h264 @ 0x59e4b20] nal_unit_type: 7, nal_ref_idc: 3
[h264 @ 0x59e4b20] nal_unit_type: 8, nal_ref_idc: 3
[h264 @ 0x59e4b20] unknown SEI type 229
[h264 @ 0x59e4b20] nal_unit_type: 7, nal_ref_idc: 3
[h264 @ 0x59e4b20] nal_unit_type: 8, nal_ref_idc: 3
[h264 @ 0x59e4b20] nal_unit_type: 6, nal_ref_idc: 0
[h264 @ 0x59e4b20] nal_unit_type: 5, nal_ref_idc: 3
[h264 @ 0x59e4b20] unknown SEI type 229
[h264 @ 0x59e4b20] Reinit context to 352x288, pix_fmt: yuv420p
[h264 @ 0x59e4b20] nal_unit_type: 1, nal_ref_idc: 3
 Last message repeated 5 times
[h264 @ 0x59e4b20] unknown SEI type 229
 Last message repeated 1 times
[rtsp @ 0x59f7620] All info found
[rtsp @ 0x59f7620] Setting avg frame rate based on r frame rate
Input #1, rtsp, from 'rtsp://192.168.1.132:554/user=admin&password=mypassword&channel=2&stream=1.sdp':
 Duration: N/A, start: 0.166667, bitrate: N/A
 Stream #1:0, 28, 1/90000: Video: h264 (High), 1 reference frame, yuv420p(progressive, left), 352x288, 0/1, 6 fps, 6 tbr, 90k tbn, 180k tbc
Successfully opened the file.
detected 2 logical cores
[Parsed_hstack_0 @ 0x59f7cc0] Setting 'inputs' to value '2'
Parsing a group of options: output url http://localhost:8090/feed5.ffm.
Applying option map (set input stream mapping) with argument [v].
Applying option r (set frame rate (Hz value, fraction or abbreviation)) with argument 30.
Successfully parsed a group of options.
Opening an output file: http://localhost:8090/feed5.ffm.
[http @ 0x59aa700] Setting default whitelist 'http,https,tls,rtp,tcp,udp,crypto,httpproxy'
[http @ 0x59aa700] request: GET /feed5.ffm HTTP/1.1
User-Agent: Lavf/57.72.101
Accept: */*
Range: bytes=0-
Connection: close
Host: localhost:8090
Icy-MetaData: 1


[ffm @ 0x5917d00] Format ffm probed with size=2048 and score=101
[NULL @ 0x5bce3e0] Setting entry with key 'video_size' to value '640x360'
[NULL @ 0x5bce3e0] Setting entry with key 'b' to value '140000'
[NULL @ 0x5bce3e0] Setting entry with key 'time_base' to value '1/5'
[NULL @ 0x5bce3e0] Setting entry with key 'bt' to value '35000'
[NULL @ 0x5bce3e0] Setting entry with key 'rc_eq' to value 'tex^qComp'
[NULL @ 0x5bce3e0] Setting entry with key 'maxrate' to value '280000'
[NULL @ 0x5bce3e0] Setting entry with key 'bufsize' to value '280000'
[AVIOContext @ 0x5915b80] Statistics: 4096 bytes read, 0 seeks
[http @ 0x5915f00] Setting default whitelist 'http,https,tls,rtp,tcp,udp,crypto,httpproxy'
[http @ 0x5915f00] request: POST /feed5.ffm HTTP/1.1
Transfer-Encoding: chunked
User-Agent: Lavf/57.72.101
Accept: */*
Connection: close
Host: localhost:8090
Icy-MetaData: 1


Successfully opened the file.
Filter hstack has an unconnected output
[AVIOContext @ 0x59ab080] Statistics: 0 seeks, 0 writeouts




I am stumped - any clues ?



Thanks in advance.