Recherche avancée

Médias (1)

Mot : - Tags -/Rennes

Autres articles (61)

  • Le profil des utilisateurs

    12 avril 2011, par

    Chaque utilisateur dispose d’une page de profil lui permettant de modifier ses informations personnelle. Dans le menu de haut de page par défaut, un élément de menu est automatiquement créé à l’initialisation de MediaSPIP, visible uniquement si le visiteur est identifié sur le site.
    L’utilisateur a accès à la modification de profil depuis sa page auteur, un lien dans la navigation "Modifier votre profil" est (...)

  • Configurer la prise en compte des langues

    15 novembre 2010, par

    Accéder à la configuration et ajouter des langues prises en compte
    Afin de configurer la prise en compte de nouvelles langues, il est nécessaire de se rendre dans la partie "Administrer" du site.
    De là, dans le menu de navigation, vous pouvez accéder à une partie "Gestion des langues" permettant d’activer la prise en compte de nouvelles langues.
    Chaque nouvelle langue ajoutée reste désactivable tant qu’aucun objet n’est créé dans cette langue. Dans ce cas, elle devient grisée dans la configuration et (...)

  • XMP PHP

    13 mai 2011, par

    Dixit Wikipedia, XMP signifie :
    Extensible Metadata Platform ou XMP est un format de métadonnées basé sur XML utilisé dans les applications PDF, de photographie et de graphisme. Il a été lancé par Adobe Systems en avril 2001 en étant intégré à la version 5.0 d’Adobe Acrobat.
    Étant basé sur XML, il gère un ensemble de tags dynamiques pour l’utilisation dans le cadre du Web sémantique.
    XMP permet d’enregistrer sous forme d’un document XML des informations relatives à un fichier : titre, auteur, historique (...)

Sur d’autres sites (4316)

  • Getting shifted timestamps when encoding a fragmented h264 mp4 with ffmpeg

    14 septembre 2022, par Martin Castin

    I am trying to encode a fragmented h264 mp4 with ffmpeg. I tried the following command :

    


    ffmpeg -i input.mp4 -movflags +frag_keyframe+separate_moof+omit_tfhd_offset+empty_moov output.mp4


    


    It does give me a fragmented mp4 but the timestamps of the frames seem to be shifted by 0.04s when I read the video with mpv. The first frame has a timestamp of 0.04s instead of 0s, as in the input video (1920x1080, 50 fps). I encountered the problem both with ffmpeg 5.1 and ffmpeg 3.4.11.

    


    I tried to add several flags, as -avoid_negative_ts make_zero or -copyts -output_ts_offset -0.04, but it did not help.

    


    I am also trying to achieve this using the ffmpeg libav libraries in C++ but did not get to better result. Here are the code fragments I used.

    


     avformat_alloc_output_context2(&oc, NULL, NULL, filename);

 if (oc_->oformat->flags & AVFMT_GLOBALHEADER) {
    codecCtx_->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
 }
...
 AVDictionary* opts = NULL;

 av_dict_set(&opts, "movflags", "frag_keyframe+separate_moof+omit_tfhd_offset+empty_moov", 0);

 ret = avformat_write_header(oc_, &opts);


    


    Do you know how to avoid this behaviour of shifted timestamps for fragmented mp4, either with ffmpeg or libav ?

    


    Edit : example videos and complete code example

    


    I also tried with the following ffmpeg build

    


    ffmpeg version 5.0.1-static https://johnvansickle.com/ffmpeg/  Copyright (c) 2000-2022 the FFmpeg developers
built with gcc 8 (Debian 8.3.0-6)
configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gmp --enable-libgme --enable-gray --enable-libaom --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libdav1d --enable-libxvid --enable-libzvbi --enable-libzimg
libavutil      57. 17.100 / 57. 17.100
libavcodec     59. 18.100 / 59. 18.100
libavformat    59. 16.100 / 59. 16.100
libavdevice    59.  4.100 / 59.  4.100
libavfilter     8. 24.100 /  8. 24.100
libswscale      6.  4.100 /  6.  4.100
libswresample   4.  3.100 /  4.  3.100
libpostproc    56.  3.100 / 56.  3.100


    


    and with the sintel trailer as input video, which is 24fps, and I thus get a timeshift of 83ms. Here is the output I get.

    


    Here is a complete code example, slightly adapted from the muxing.c ffmpeg example (audio removed and adapted for c++). This code shows exactly the same problem.

    


    You can just comment the line 383 (that is calling av_dict_set) to switch back to a not fragmented mp4 that will not have the timestamp shift.

    


    /*&#xA; * Copyright (c) 2003 Fabrice Bellard&#xA; *&#xA; * Permission is hereby granted, free of charge, to any person obtaining a copy&#xA; * of this software and associated documentation files (the "Software"), to deal&#xA; * in the Software without restriction, including without limitation the rights&#xA; * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell&#xA; * copies of the Software, and to permit persons to whom the Software is&#xA; * furnished to do so, subject to the following conditions:&#xA; *&#xA; * The above copyright notice and this permission notice shall be included in&#xA; * all copies or substantial portions of the Software.&#xA; *&#xA; * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR&#xA; * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,&#xA; * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL&#xA; * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER&#xA; * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,&#xA; * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN&#xA; * THE SOFTWARE.&#xA; */&#xA;&#xA;/**&#xA; * @file&#xA; * libavformat API example.&#xA; *&#xA; * Output a media file in any supported libavformat format. The default&#xA; * codecs are used.&#xA; * @example muxing.c&#xA; */&#xA;&#xA;#include <cstdlib>&#xA;#include <cstdio>&#xA;#include <cstring>&#xA;#include <cmath>&#xA;&#xA;extern "C"&#xA;{&#xA;#define __STDC_CONSTANT_MACROS&#xA;#include <libavutil></libavutil>avassert.h>&#xA;#include <libavutil></libavutil>channel_layout.h>&#xA;#include <libavutil></libavutil>opt.h>&#xA;#include <libavutil></libavutil>mathematics.h>&#xA;#include <libavutil></libavutil>timestamp.h>&#xA;#include <libavcodec></libavcodec>avcodec.h>&#xA;#include <libavformat></libavformat>avformat.h>&#xA;#include <libswscale></libswscale>swscale.h>&#xA;#include <libswresample></libswresample>swresample.h>&#xA;}&#xA;&#xA;#define STREAM_DURATION   10.0&#xA;#define STREAM_FRAME_RATE 25 /* 25 images/s */&#xA;#define STREAM_PIX_FMT    AV_PIX_FMT_YUV420P /* default pix_fmt */&#xA;&#xA;#define SCALE_FLAGS SWS_BICUBIC&#xA;&#xA;// a wrapper around a single output AVStream&#xA;typedef struct OutputStream {&#xA;  AVStream *st;&#xA;  AVCodecContext *enc;&#xA;&#xA;  /* pts of the next frame that will be generated */&#xA;  int64_t next_pts;&#xA;  int samples_count;&#xA;&#xA;  AVFrame *frame;&#xA;  AVFrame *tmp_frame;&#xA;&#xA;  AVPacket *tmp_pkt;&#xA;&#xA;  float t, tincr, tincr2;&#xA;&#xA;  struct SwsContext *sws_ctx;&#xA;  struct SwrContext *swr_ctx;&#xA;} OutputStream;&#xA;&#xA;static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt)&#xA;{&#xA;  AVRational *time_base = &amp;fmt_ctx->streams[pkt->stream_index]->time_base;&#xA;&#xA;//  printf("pts:%s pts_time:%s dts:%s dts_time:%s duration:%s duration_time:%s stream_index:%d\n",&#xA;//         av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, time_base),&#xA;//         av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, time_base),&#xA;//         av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, time_base),&#xA;//         pkt->stream_index);&#xA;}&#xA;&#xA;static int write_frame(AVFormatContext *fmt_ctx, AVCodecContext *c,&#xA;                       AVStream *st, AVFrame *frame, AVPacket *pkt)&#xA;{&#xA;  int ret;&#xA;&#xA;  // send the frame to the encoder&#xA;  ret = avcodec_send_frame(c, frame);&#xA;  if (ret &lt; 0) {&#xA;    fprintf(stderr, "Error sending a frame to the encoder");&#xA;    exit(1);&#xA;  }&#xA;&#xA;  while (ret >= 0) {&#xA;    ret = avcodec_receive_packet(c, pkt);&#xA;    if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)&#xA;      break;&#xA;    else if (ret &lt; 0) {&#xA;      fprintf(stderr, "Error encoding a frame\n");&#xA;      exit(1);&#xA;    }&#xA;&#xA;    /* rescale output packet timestamp values from codec to stream timebase */&#xA;    av_packet_rescale_ts(pkt, c->time_base, st->time_base);&#xA;    pkt->stream_index = st->index;&#xA;&#xA;    /* Write the compressed frame to the media file. */&#xA;    log_packet(fmt_ctx, pkt);&#xA;    ret = av_interleaved_write_frame(fmt_ctx, pkt);&#xA;    /* pkt is now blank (av_interleaved_write_frame() takes ownership of&#xA;     * its contents and resets pkt), so that no unreferencing is necessary.&#xA;     * This would be different if one used av_write_frame(). */&#xA;    if (ret &lt; 0) {&#xA;      fprintf(stderr, "Error while writing output packet\n");&#xA;      exit(1);&#xA;    }&#xA;  }&#xA;&#xA;  return ret == AVERROR_EOF ? 1 : 0;&#xA;}&#xA;&#xA;/* Add an output stream. */&#xA;static void add_stream(OutputStream *ost, AVFormatContext *oc,&#xA;                       const AVCodec **codec,&#xA;                       enum AVCodecID codec_id)&#xA;{&#xA;  AVCodecContext *c;&#xA;  int i;&#xA;&#xA;  /* find the encoder */&#xA;  *codec = avcodec_find_encoder(codec_id);&#xA;  if (!(*codec)) {&#xA;    fprintf(stderr, "Could not find encoder for &#x27;%s&#x27;\n",&#xA;            avcodec_get_name(codec_id));&#xA;    exit(1);&#xA;  }&#xA;&#xA;  ost->tmp_pkt = av_packet_alloc();&#xA;  if (!ost->tmp_pkt) {&#xA;    fprintf(stderr, "Could not allocate AVPacket\n");&#xA;    exit(1);&#xA;  }&#xA;&#xA;  ost->st = avformat_new_stream(oc, NULL);&#xA;  if (!ost->st) {&#xA;    fprintf(stderr, "Could not allocate stream\n");&#xA;    exit(1);&#xA;  }&#xA;  ost->st->id = oc->nb_streams-1;&#xA;  c = avcodec_alloc_context3(*codec);&#xA;  if (!c) {&#xA;    fprintf(stderr, "Could not alloc an encoding context\n");&#xA;    exit(1);&#xA;  }&#xA;  ost->enc = c;&#xA;&#xA;  switch ((*codec)->type) {&#xA;    case AVMEDIA_TYPE_VIDEO:&#xA;      c->codec_id = codec_id;&#xA;&#xA;      c->bit_rate = 400000;&#xA;      /* Resolution must be a multiple of two. */&#xA;      c->width    = 352;&#xA;      c->height   = 288;&#xA;      /* timebase: This is the fundamental unit of time (in seconds) in terms&#xA;       * of which frame timestamps are represented. For fixed-fps content,&#xA;       * timebase should be 1/framerate and timestamp increments should be&#xA;       * identical to 1. */&#xA;      ost->st->time_base = (AVRational){ 1, STREAM_FRAME_RATE };&#xA;      c->time_base       = ost->st->time_base;&#xA;&#xA;      c->gop_size      = 12; /* emit one intra frame every twelve frames at most */&#xA;      c->pix_fmt       = STREAM_PIX_FMT;&#xA;      if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {&#xA;        /* just for testing, we also add B-frames */&#xA;        c->max_b_frames = 2;&#xA;      }&#xA;      if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO) {&#xA;        /* Needed to avoid using macroblocks in which some coeffs overflow.&#xA;         * This does not happen with normal video, it just happens here as&#xA;         * the motion of the chroma plane does not match the luma plane. */&#xA;        c->mb_decision = 2;&#xA;      }&#xA;      break;&#xA;&#xA;    default:&#xA;      break;&#xA;  }&#xA;&#xA;  /* Some formats want stream headers to be separate. */&#xA;  if (oc->oformat->flags &amp; AVFMT_GLOBALHEADER)&#xA;    c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;&#xA;}&#xA;&#xA;/**************************************************************/&#xA;/* video output */&#xA;&#xA;static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height)&#xA;{&#xA;  AVFrame *picture;&#xA;  int ret;&#xA;&#xA;  picture = av_frame_alloc();&#xA;  if (!picture)&#xA;    return NULL;&#xA;&#xA;  picture->format = pix_fmt;&#xA;  picture->width  = width;&#xA;  picture->height = height;&#xA;&#xA;  /* allocate the buffers for the frame data */&#xA;  ret = av_frame_get_buffer(picture, 0);&#xA;  if (ret &lt; 0) {&#xA;    fprintf(stderr, "Could not allocate frame data.\n");&#xA;    exit(1);&#xA;  }&#xA;&#xA;  return picture;&#xA;}&#xA;&#xA;static void open_video(AVFormatContext *oc, const AVCodec *codec,&#xA;                       OutputStream *ost, AVDictionary *opt_arg)&#xA;{&#xA;  int ret;&#xA;  AVCodecContext *c = ost->enc;&#xA;  AVDictionary *opt = NULL;&#xA;&#xA;  av_dict_copy(&amp;opt, opt_arg, 0);&#xA;&#xA;  /* open the codec */&#xA;  ret = avcodec_open2(c, codec, &amp;opt);&#xA;  av_dict_free(&amp;opt);&#xA;  if (ret &lt; 0) {&#xA;    fprintf(stderr, "Could not open video codec\n");&#xA;    exit(1);&#xA;  }&#xA;&#xA;  /* allocate and init a re-usable frame */&#xA;  ost->frame = alloc_picture(c->pix_fmt, c->width, c->height);&#xA;  if (!ost->frame) {&#xA;    fprintf(stderr, "Could not allocate video frame\n");&#xA;    exit(1);&#xA;  }&#xA;&#xA;  /* If the output format is not YUV420P, then a temporary YUV420P&#xA;   * picture is needed too. It is then converted to the required&#xA;   * output format. */&#xA;  ost->tmp_frame = NULL;&#xA;  if (c->pix_fmt != AV_PIX_FMT_YUV420P) {&#xA;    ost->tmp_frame = alloc_picture(AV_PIX_FMT_YUV420P, c->width, c->height);&#xA;    if (!ost->tmp_frame) {&#xA;      fprintf(stderr, "Could not allocate temporary picture\n");&#xA;      exit(1);&#xA;    }&#xA;  }&#xA;&#xA;  /* copy the stream parameters to the muxer */&#xA;  ret = avcodec_parameters_from_context(ost->st->codecpar, c);&#xA;  if (ret &lt; 0) {&#xA;    fprintf(stderr, "Could not copy the stream parameters\n");&#xA;    exit(1);&#xA;  }&#xA;}&#xA;&#xA;/* Prepare a dummy image. */&#xA;static void fill_yuv_image(AVFrame *pict, int frame_index,&#xA;                           int width, int height)&#xA;{&#xA;  int x, y, i;&#xA;&#xA;  i = frame_index;&#xA;&#xA;  /* Y */&#xA;  for (y = 0; y &lt; height; y&#x2B;&#x2B;)&#xA;    for (x = 0; x &lt; width; x&#x2B;&#x2B;)&#xA;      pict->data[0][y * pict->linesize[0] &#x2B; x] = x &#x2B; y &#x2B; i * 3;&#xA;&#xA;  /* Cb and Cr */&#xA;  for (y = 0; y &lt; height / 2; y&#x2B;&#x2B;) {&#xA;    for (x = 0; x &lt; width / 2; x&#x2B;&#x2B;) {&#xA;      pict->data[1][y * pict->linesize[1] &#x2B; x] = 128 &#x2B; y &#x2B; i * 2;&#xA;      pict->data[2][y * pict->linesize[2] &#x2B; x] = 64 &#x2B; x &#x2B; i * 5;&#xA;    }&#xA;  }&#xA;}&#xA;&#xA;static AVFrame *get_video_frame(OutputStream *ost)&#xA;{&#xA;  AVCodecContext *c = ost->enc;&#xA;&#xA;  /* check if we want to generate more frames */&#xA;  if (av_compare_ts(ost->next_pts, c->time_base,&#xA;                    STREAM_DURATION, (AVRational){ 1, 1 }) > 0)&#xA;    return NULL;&#xA;&#xA;  /* when we pass a frame to the encoder, it may keep a reference to it&#xA;   * internally; make sure we do not overwrite it here */&#xA;  if (av_frame_make_writable(ost->frame) &lt; 0)&#xA;    exit(1);&#xA;&#xA;  if (c->pix_fmt != AV_PIX_FMT_YUV420P) {&#xA;    /* as we only generate a YUV420P picture, we must convert it&#xA;     * to the codec pixel format if needed */&#xA;    if (!ost->sws_ctx) {&#xA;      ost->sws_ctx = sws_getContext(c->width, c->height,&#xA;                                    AV_PIX_FMT_YUV420P,&#xA;                                    c->width, c->height,&#xA;                                    c->pix_fmt,&#xA;                                    SCALE_FLAGS, NULL, NULL, NULL);&#xA;      if (!ost->sws_ctx) {&#xA;        fprintf(stderr,&#xA;                "Could not initialize the conversion context\n");&#xA;        exit(1);&#xA;      }&#xA;    }&#xA;    fill_yuv_image(ost->tmp_frame, ost->next_pts, c->width, c->height);&#xA;    sws_scale(ost->sws_ctx, (const uint8_t * const *) ost->tmp_frame->data,&#xA;              ost->tmp_frame->linesize, 0, c->height, ost->frame->data,&#xA;              ost->frame->linesize);&#xA;  } else {&#xA;    fill_yuv_image(ost->frame, ost->next_pts, c->width, c->height);&#xA;  }&#xA;&#xA;  ost->frame->pts = ost->next_pts&#x2B;&#x2B;;&#xA;&#xA;  return ost->frame;&#xA;}&#xA;&#xA;/*&#xA; * encode one video frame and send it to the muxer&#xA; * return 1 when encoding is finished, 0 otherwise&#xA; */&#xA;static int write_video_frame(AVFormatContext *oc, OutputStream *ost)&#xA;{&#xA;  return write_frame(oc, ost->enc, ost->st, get_video_frame(ost), ost->tmp_pkt);&#xA;}&#xA;&#xA;static void close_stream(AVFormatContext *oc, OutputStream *ost)&#xA;{&#xA;  avcodec_free_context(&amp;ost->enc);&#xA;  av_frame_free(&amp;ost->frame);&#xA;  av_frame_free(&amp;ost->tmp_frame);&#xA;  av_packet_free(&amp;ost->tmp_pkt);&#xA;  sws_freeContext(ost->sws_ctx);&#xA;  swr_free(&amp;ost->swr_ctx);&#xA;}&#xA;&#xA;/**************************************************************/&#xA;/* media file output */&#xA;&#xA;int main(int argc, char **argv)&#xA;{&#xA;  OutputStream video_st = { 0 }, audio_st = { 0 };&#xA;  const AVOutputFormat *fmt;&#xA;  const char *filename;&#xA;  AVFormatContext *oc;&#xA;  const AVCodec *audio_codec, *video_codec;&#xA;  int ret;&#xA;  int have_video = 0, have_audio = 0;&#xA;  int encode_video = 0, encode_audio = 0;&#xA;  AVDictionary *opt = NULL;&#xA;  int i;&#xA;&#xA;  if (argc &lt; 2) {&#xA;    printf("usage: %s output_file\n"&#xA;           "API example program to output a media file with libavformat.\n"&#xA;           "This program generates a synthetic audio and video stream, encodes and\n"&#xA;           "muxes them into a file named output_file.\n"&#xA;           "The output format is automatically guessed according to the file extension.\n"&#xA;           "Raw images can also be output by using &#x27;%%d&#x27; in the filename.\n"&#xA;           "\n", argv[0]);&#xA;    return 1;&#xA;  }&#xA;&#xA;  filename = argv[1];&#xA;&#xA;  av_dict_set(&amp;opt, "movflags", "frag_keyframe&#x2B;separate_moof&#x2B;omit_tfhd_offset&#x2B;empty_moov", 0);&#xA;&#xA;  /* allocate the output media context */&#xA;  avformat_alloc_output_context2(&amp;oc, NULL, NULL, filename);&#xA;  if (!oc) {&#xA;    printf("Could not deduce output format from file extension: using MPEG.\n");&#xA;    avformat_alloc_output_context2(&amp;oc, NULL, "mpeg", filename);&#xA;  }&#xA;  if (!oc)&#xA;    return 1;&#xA;&#xA;  fmt = oc->oformat;&#xA;&#xA;  /* Add the audio and video streams using the default format codecs&#xA;   * and initialize the codecs. */&#xA;  if (fmt->video_codec != AV_CODEC_ID_NONE) {&#xA;    add_stream(&amp;video_st, oc, &amp;video_codec, fmt->video_codec);&#xA;    have_video = 1;&#xA;    encode_video = 1;&#xA;  }&#xA;&#xA;  /* Now that all the parameters are set, we can open the audio and&#xA;   * video codecs and allocate the necessary encode buffers. */&#xA;  if (have_video)&#xA;    open_video(oc, video_codec, &amp;video_st, opt);&#xA;&#xA;&#xA;  av_dump_format(oc, 0, filename, 1);&#xA;&#xA;  /* open the output file, if needed */&#xA;  if (!(fmt->flags &amp; AVFMT_NOFILE)) {&#xA;    ret = avio_open(&amp;oc->pb, filename, AVIO_FLAG_WRITE);&#xA;    if (ret &lt; 0) {&#xA;      fprintf(stderr, "Could not open &#x27;%s&#x27;\n", filename);&#xA;      return 1;&#xA;    }&#xA;  }&#xA;&#xA;  /* Write the stream header, if any. */&#xA;  ret = avformat_write_header(oc, &amp;opt);&#xA;  if (ret &lt; 0) {&#xA;    fprintf(stderr, "Error occurred when opening output file\n");&#xA;    return 1;&#xA;  }&#xA;&#xA;  while (encode_video || encode_audio) {&#xA;    /* select the stream to encode */&#xA;    if (encode_video &amp;&amp;&#xA;        (!encode_audio || av_compare_ts(video_st.next_pts, video_st.enc->time_base,&#xA;                                        audio_st.next_pts, audio_st.enc->time_base) &lt;= 0)) {&#xA;      encode_video = !write_video_frame(oc, &amp;video_st);&#xA;    }&#xA;  }&#xA;&#xA;  av_write_trailer(oc);&#xA;&#xA;  /* Close each codec. */&#xA;  if (have_video)&#xA;    close_stream(oc, &amp;video_st);&#xA;  if (have_audio)&#xA;    close_stream(oc, &amp;audio_st);&#xA;&#xA;  if (!(fmt->flags &amp; AVFMT_NOFILE))&#xA;    /* Close the output file. */&#xA;    avio_closep(&amp;oc->pb);&#xA;&#xA;  /* free the stream */&#xA;  avformat_free_context(oc);&#xA;&#xA;  return 0;&#xA;}&#xA;</cmath></cstring></cstdio></cstdlib>

    &#xA;

  • Forcing ffmpeg to capture unreliable ALSA audio stream

    6 février 2015, par Peter Becich

    I am attempting to transfer some old Video 8 tapes to my computer, though an EasyCap USB stick and the motherboard’s sound line-in, on Ubuntu. I believe the arguments are correctly laid out below to capture from two independent streams, and encode them both into the output MP4 file.

    ffmpeg’s detection of the ALSA stream is seemingly goofed up by the inconsistencies of the tape. In the failure case, only short blips of the tapes audio exist in the output MP4. The audio bitrate of the output file is less than 10 kbps, averaged out across the whole file. The output video seems to be fine, even though the low frames-per-second in the failure case log below.

    The audio and video streams can be captured fine for short amounts of time before a source error occurs ; this provides the success case log. The failure case log was created by intentionally making an error in the source streams — turning on the camera makes a brief noisy signal.

    Is there a setting that needs to be forced to keep ffmpeg recording the audio stream, even when the tape is blank or noisy ?

    Could it be that the libfdk_aac audio encoder is tripped up by the low quality source ?

    The relevant line ; rawvideo stream is piped to this in script at bottom :

    ffmpeg -pixel_format uyvy422 -s:v 720x480 -framerate 29.97 -f rawvideo \
    -i $PIPE  -f alsa -i hw:0,0 -vf scale=w=720:h=540 -vcodec libx264 \
    -preset ultrafast -shortest -c:a libfdk_aac -b:a 128k -af pan=1:c0=c0  \
    -ar 96000 $OUTFILE

    The ar argument was one attempt to force recording.

    ffmpeg log file for (short-lived) success ; high frames-per-second captured :

    ffmpeg version 2.5.3 Copyright (c) 2000-2015 the FFmpeg developers
     built on Jan 11 2015 17:53:45 with gcc 4.8 (Ubuntu 4.8.2-19ubuntu1)
     configuration: --extra-libs=-ldl --prefix=/opt/ffmpeg --enable-avresample --disable-debug --enable-nonfree --enable-gpl --enable-version3 --enable-libpulse --enable-libopencore-amrnb --enable-libopencore-amrwb --disable-decoder=amrnb --disable-decoder=amrwb --enable-libx264 --enable-libx265 --enable-libfdk-aac --enable-libvorbis --enable-libmp3lame --enable-libopus --enable-libvpx --enable-libspeex --enable-libass --enable-avisynth --enable-libsoxr --enable-libxvid --enable-libvo-aacenc --enable-libvidstab
     libavutil      54. 15.100 / 54. 15.100
     libavcodec     56. 13.100 / 56. 13.100
     libavformat    56. 15.102 / 56. 15.102
     libavdevice    56.  3.100 / 56.  3.100
     libavfilter     5.  2.103 /  5.  2.103
     libavresample   2.  1.  0 /  2.  1.  0
     libswscale      3.  1.101 /  3.  1.101
     libswresample   1.  1.100 /  1.  1.100
     libpostproc    53.  3.100 / 53.  3.100
    Input #0, rawvideo, from '/tmp/somagic-pipe':
     Duration: N/A, start: 0.000000, bitrate: 165722 kb/s
       Stream #0:0: Video: rawvideo (UYVY / 0x59565955), uyvy422, 720x480, 165722 kb/s, 29.97 tbr, 29.97 tbn, 29.97 tbc
    Home directory not accessible: Permission denied
    Guessed Channel Layout for  Input Stream #1.0 : stereo
    Input #1, alsa, from 'hw:0,0':
     Duration: N/A, start: 1423202268.577088, bitrate: 1536 kb/s
       Stream #1:0: Audio: pcm_s16le, 48000 Hz, 2 channels, s16, 1536 kb/s
    No pixel format specified, yuv422p for H.264 encoding chosen.
    Use -pix_fmt yuv420p for compatibility with outdated media players.
    [Parsed_pan_0 @ 0x3335d60] This syntax is deprecated. Use '|' to separate the list items.
    Single channel layout '1' is interpreted as a number of channels, switch to the syntax '1c' otherwise it will be interpreted as a channel layout number in a later version
    [Parsed_pan_0 @ 0x3335d60] Pure channel mapping detected: 0
    [libx264 @ 0x3364bc0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.1 Cache64
    [libx264 @ 0x3364bc0] profile High 4:2:2, level 3.1, 4:2:2 8-bit
    [libx264 @ 0x3364bc0] 264 - core 142 r2389 956c8d8 - H.264/MPEG-4 AVC codec - Copyleft 2003-2014 - http://www.videolan.org/x264.html - options: cabac=0 ref=1 deblock=0:0:0 analyse=0:0 me=dia subme=0 psy=1 psy_rd=1.00:0.00 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=0 threads=3 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=250 keyint_min=25 scenecut=0 intra_refresh=0 rc=crf mbtree=0 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=0
    Output #0, mp4, to '/home/peterbecich/easycap/Videos/fpv_video_02_05_2015_21_57_48.mp4':
     Metadata:
       encoder         : Lavf56.15.102
       Stream #0:0: Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv422p, 720x540, q=-1--1, 29.97 fps, 11988 tbn, 29.97 tbc
       Metadata:
         encoder         : Lavc56.13.100 libx264
       Stream #0:1: Audio: aac (libfdk_aac) ([64][0][0][0] / 0x0040), 96000 Hz, mono, s16, 128 kb/s
       Metadata:
         encoder         : Lavc56.13.100 libfdk_aac
    Stream mapping:
     Stream #0:0 -> #0:0 (rawvideo (native) -> h264 (libx264))
     Stream #1:0 -> #0:1 (pcm_s16le (native) -> aac (libfdk_aac))
    Press [q] to stop, [?] for help
    frame=   13 fps=0.0 q=26.0 size=     187kB time=00:00:00.30 bitrate=5102.7kbits/s    
    frame=   29 fps= 29 q=26.0 size=     469kB time=00:00:00.83 bitrate=4607.6kbits/s    
    frame=   44 fps= 29 q=26.0 size=     755kB time=00:00:01.33 bitrate=4635.2kbits/s    
    frame=   59 fps= 29 q=26.0 size=    1024kB time=00:00:01.83 bitrate=4572.1kbits/s    
    frame=   74 fps= 29 q=26.0 size=    1279kB time=00:00:02.33 bitrate=4486.5kbits/s    
    frame=   89 fps= 29 q=26.0 size=    1516kB time=00:00:02.83 bitrate=4378.0kbits/s    
    frame=  104 fps= 29 q=26.0 size=    1752kB time=00:00:03.33 bitrate=4301.0kbits/s    
    frame=  119 fps= 29 q=26.0 size=    1991kB time=00:00:03.83 bitrate=4251.1kbits/s    
    frame=  135 fps= 30 q=26.0 size=    2245kB time=00:00:04.37 bitrate=4207.5kbits/s    
    frame=  150 fps= 30 q=26.0 size=    2524kB time=00:00:04.87 bitrate=4245.0kbits/s    
    frame=  165 fps= 30 q=26.0 size=    2808kB time=00:00:05.37 bitrate=4282.0kbits/s    
    frame=  180 fps= 30 q=26.0 size=    3091kB time=00:00:05.87 bitrate=4311.5kbits/s    
    [rawvideo @ 0x3350640] Invalid buffer size, packet size 65536 &lt; expected frame_size 691200
    Error while decoding stream #0:0: Invalid argument
    frame=  183 fps= 29 q=-1.0 Lsize=    3247kB time=00:00:06.11 bitrate=4351.5kbits/s    
    video:3142kB audio:96kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.254788%
    [libx264 @ 0x3364bc0] frame I:1     Avg QP:20.00  size:  2289
    [libx264 @ 0x3364bc0] frame P:182   Avg QP:25.99  size: 17664
    [libx264 @ 0x3364bc0] mb I  I16..4: 100.0%  0.0%  0.0%
    [libx264 @ 0x3364bc0] mb P  I16..4: 78.5%  0.0%  0.0%  P16..4: 20.2%  0.0%  0.0%  0.0%  0.0%    skip: 1.4%
    [libx264 @ 0x3364bc0] coded y,uvDC,uvAC intra: 84.1% 71.5% 18.9% inter: 51.9% 63.5% 0.4%
    [libx264 @ 0x3364bc0] i16 v,h,dc,p: 15%  8% 69%  8%
    [libx264 @ 0x3364bc0] i8c dc,h,v,p: 50% 19% 24%  7%
    [libx264 @ 0x3364bc0] kb/s:4215.02

    ffmpeg log for failure ; low FPS captured :

    ffmpeg version 2.5.3 Copyright (c) 2000-2015 the FFmpeg developers
     built on Jan 11 2015 17:53:45 with gcc 4.8 (Ubuntu 4.8.2-19ubuntu1)
     configuration: --extra-libs=-ldl --prefix=/opt/ffmpeg --enable-avresample --disable-debug --enable-nonfree --enable-gpl --enable-version3 --enable-libpulse --enable-libopencore-amrnb --enable-libopencore-amrwb --disable-decoder=amrnb --disable-decoder=amrwb --enable-libx264 --enable-libx265 --enable-libfdk-aac --enable-libvorbis --enable-libmp3lame --enable-libopus --enable-libvpx --enable-libspeex --enable-libass --enable-avisynth --enable-libsoxr --enable-libxvid --enable-libvo-aacenc --enable-libvidstab
     libavutil      54. 15.100 / 54. 15.100
     libavcodec     56. 13.100 / 56. 13.100
     libavformat    56. 15.102 / 56. 15.102
     libavdevice    56.  3.100 / 56.  3.100
     libavfilter     5.  2.103 /  5.  2.103
     libavresample   2.  1.  0 /  2.  1.  0
     libswscale      3.  1.101 /  3.  1.101
     libswresample   1.  1.100 /  1.  1.100
     libpostproc    53.  3.100 / 53.  3.100
    Input #0, rawvideo, from '/tmp/somagic-pipe':
     Duration: N/A, start: 0.000000, bitrate: 165722 kb/s
       Stream #0:0: Video: rawvideo (UYVY / 0x59565955), uyvy422, 720x480, 165722 kb/s, 29.97 tbr, 29.97 tbn, 29.97 tbc
    Home directory not accessible: Permission denied
    Guessed Channel Layout for  Input Stream #1.0 : stereo
    Input #1, alsa, from 'hw:0,0':
     Duration: N/A, start: 1423201999.226455, bitrate: 1536 kb/s
       Stream #1:0: Audio: pcm_s16le, 48000 Hz, 2 channels, s16, 1536 kb/s
    No pixel format specified, yuv422p for H.264 encoding chosen.
    Use -pix_fmt yuv420p for compatibility with outdated media players.
    [Parsed_pan_0 @ 0x21cad60] This syntax is deprecated. Use '|' to separate the list items.
    Single channel layout '1' is interpreted as a number of channels, switch to the syntax '1c' otherwise it will be interpreted as a channel layout number in a later version
    [Parsed_pan_0 @ 0x21cad60] Pure channel mapping detected: 0
    [libx264 @ 0x21f9bc0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.1 Cache64
    [libx264 @ 0x21f9bc0] profile High 4:2:2, level 3.1, 4:2:2 8-bit
    [libx264 @ 0x21f9bc0] 264 - core 142 r2389 956c8d8 - H.264/MPEG-4 AVC codec - Copyleft 2003-2014 - http://www.videolan.org/x264.html - options: cabac=0 ref=1 deblock=0:0:0 analyse=0:0 me=dia subme=0 psy=1 psy_rd=1.00:0.00 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=0 threads=3 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=250 keyint_min=25 scenecut=0 intra_refresh=0 rc=crf mbtree=0 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=0
    Output #0, mp4, to '/home/peterbecich/easycap/Videos/fpv_video_02_05_2015_21_53_18.mp4':
     Metadata:
       encoder         : Lavf56.15.102
       Stream #0:0: Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv422p, 720x540, q=-1--1, 29.97 fps, 11988 tbn, 29.97 tbc
       Metadata:
         encoder         : Lavc56.13.100 libx264
       Stream #0:1: Audio: aac (libfdk_aac) ([64][0][0][0] / 0x0040), 96000 Hz, mono, s16, 128 kb/s
       Metadata:
         encoder         : Lavc56.13.100 libfdk_aac
    Stream mapping:
     Stream #0:0 -> #0:0 (rawvideo (native) -> h264 (libx264))
     Stream #1:0 -> #0:1 (pcm_s16le (native) -> aac (libfdk_aac))
    Press [q] to stop, [?] for help
    frame=    1 fps=0.0 q=0.0 size=       0kB time=00:00:00.00 bitrate=N/A    
    frame=    1 fps=1.0 q=0.0 size=       0kB time=00:00:00.00 bitrate=N/A    
    frame=    1 fps=0.7 q=0.0 size=       0kB time=00:00:00.00 bitrate=N/A    
    frame=    1 fps=0.5 q=0.0 size=       0kB time=00:00:00.00 bitrate=N/A    
    frame=    1 fps=0.4 q=0.0 size=       0kB time=00:00:00.00 bitrate=N/A    
    frame=    1 fps=0.3 q=0.0 size=       0kB time=00:00:00.00 bitrate=N/A    
    frame=    1 fps=0.3 q=0.0 size=       0kB time=00:00:00.00 bitrate=N/A    
    frame=    1 fps=0.2 q=0.0 size=       0kB time=00:00:00.00 bitrate=N/A    
    frame=    1 fps=0.2 q=0.0 size=       0kB time=00:00:00.00 bitrate=N/A    
    frame=    1 fps=0.2 q=0.0 size=       0kB time=00:00:00.00 bitrate=N/A    
    frame=    1 fps=0.2 q=0.0 size=       0kB time=00:00:00.00 bitrate=N/A    
    [alsa @ 0x21e5ac0] ALSA buffer xrun.
    frame=    8 fps=1.3 q=19.0 size=      12kB time=00:00:06.03 bitrate=  15.9kbits/s    
    frame=   23 fps=3.5 q=18.0 size=      12kB time=00:00:06.03 bitrate=  16.4kbits/s    
    frame=   38 fps=5.4 q=18.0 size=      12kB time=00:00:06.03 bitrate=  16.7kbits/s    
    frame=   53 fps=7.0 q=18.0 size=      12kB time=00:00:06.03 bitrate=  16.9kbits/s    
    frame=   68 fps=8.4 q=26.0 size=     146kB time=00:00:06.03 bitrate= 198.8kbits/s    
    frame=   83 fps=9.7 q=26.0 size=     375kB time=00:00:06.03 bitrate= 510.0kbits/s    
    frame=   98 fps= 11 q=26.0 size=     608kB time=00:00:06.03 bitrate= 826.5kbits/s    
    frame=  114 fps= 12 q=26.0 size=     875kB time=00:00:06.03 bitrate=1189.1kbits/s    
    frame=  128 fps= 13 q=26.0 size=    1091kB time=00:00:06.03 bitrate=1481.6kbits/s    
    frame=  144 fps= 14 q=26.0 size=    1339kB time=00:00:06.03 bitrate=1819.2kbits/s    
    frame=  159 fps= 14 q=26.0 size=    1571kB time=00:00:06.03 bitrate=2134.6kbits/s    
    frame=  174 fps= 15 q=26.0 size=    1796kB time=00:00:06.03 bitrate=2440.1kbits/s    
    [alsa @ 0x21e5ac0] ALSA buffer xrun.
    frame=  189 fps= 16 q=26.0 size=    2015kB time=00:00:12.04 bitrate=1370.4kbits/s    
    frame=  204 fps= 16 q=26.0 size=    2238kB time=00:00:12.04 bitrate=1522.3kbits/s    
    frame=  219 fps= 17 q=26.0 size=    2490kB time=00:00:12.04 bitrate=1694.2kbits/s    
    frame=  235 fps= 17 q=26.0 size=    2728kB time=00:00:12.04 bitrate=1855.8kbits/s    
    frame=  250 fps= 18 q=26.0 size=    2973kB time=00:00:12.04 bitrate=2022.4kbits/s    
    [rawvideo @ 0x21e5640] Invalid buffer size, packet size 65536 &lt; expected frame_size 691200
    Error while decoding stream #0:0: Invalid argument
    frame=  261 fps= 18 q=-1.0 Lsize=    3269kB time=00:00:12.06 bitrate=2220.1kbits/s    
    video:3263kB audio:4kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.081101%
    [libx264 @ 0x21f9bc0] frame I:2     Avg QP:21.50  size: 21342
    [libx264 @ 0x21f9bc0] frame P:259   Avg QP:24.22  size: 12734
    [libx264 @ 0x21f9bc0] mb I  I16..4: 100.0%  0.0%  0.0%
    [libx264 @ 0x21f9bc0] mb P  I16..4: 62.8%  0.0%  0.0%  P16..4: 14.2%  0.0%  0.0%  0.0%  0.0%    skip:22.9%
    [libx264 @ 0x21f9bc0] coded y,uvDC,uvAC intra: 77.7% 61.2% 14.1% inter: 19.7% 24.8% 1.6%
    [libx264 @ 0x21f9bc0] i16 v,h,dc,p: 17% 10% 65%  8%
    [libx264 @ 0x21f9bc0] i8c dc,h,v,p: 52% 18% 24%  6%
    [libx264 @ 0x21f9bc0] kb/s:3068.90

    The whole script :

    #!/bin/sh

    PIPE=/tmp/somagic-pipe
    OUTFILEDIR=~/easycap/Videos/
    LOGDIR=~/.somagic-log/
    NOW=`date +"%m_%d_%Y_%H_%M_%S"`

    OUTFILE=${OUTFILEDIR}fpv_video_${NOW}.mp4

    mkdir $LOGDIR

    FFMPEG_LOG=${LOGDIR}ffmpeg.log
    SOMAGIC_LOG=${LOGDIR}somagic.log
    MPLAYER_LOG=${LOGDIR}mplayer.log

    rm $PIPE >/dev/null 2>&amp;1
    rm $OUTFILE >/dev/null 2>&amp;1

    rm $FFMPEG_LOG
    rm $SOMAGIC_LOG
    rm $MPLAYER_LOG

    mkfifo $PIPE >/dev/null 2>&amp;1

    ffmpeg -pixel_format uyvy422 -s:v 720x480 -framerate 29.97 -f rawvideo \
    -i $PIPE  -f alsa -i hw:0,0 -vf scale=w=720:h=540 -vcodec libx264 \
    -preset ultrafast -shortest -c:a libfdk_aac -b:a 128k -af pan=1:c0=c0  \
    -ar 96000 $OUTFILE > $FFMPEG_LOG 2>&amp;1 &amp;

    somagic-capture --ntsc -c --luminance=2 --lum-aperture=3 2> $SOMAGIC_LOG \
    | tee $PIPE | \
    mplayer -vf yadif,screenshot -demuxer rawvideo -rawvideo \
    "ntsc:format=uyvy:fps=30000/1001" -aspect 4:3 - 2> $MPLAYER_LOG


    rm $PIPE >/dev/null 2>&amp;1

    Modified from here : https://gist.github.com/Brick85/0b327ac2d3d45e23ed33