Newest 'x264' Questions - Stack Overflow
Les articles publiés sur le site
-
Encoding images to h264 and rtp output : SDP file without sprop-parameter-sets does not play
14 septembre 2021, par oarfishtl;dr: I try to encode acquired camera frames to h264, send via RTP and play this back on another device. SDP file generated by ffmpeg for a sample video has info which my own SDP file misses. My SDP file plays in ffplay, but not VLC, while both play ffmpeg's SDP file. I am suspecting missing sprop-parameter-sets in my SDP file.
Ultimately I want to play this back in VLC.
I am writing code that encodes images to h264 and outputs to an RTP server (or client? anyway the part that is listening). I generate an SDP file for this.
- ffplay plays the stream without problem
- mplayer shows a green box embedded in a larger black box, but I read somewhere it only supports mpegts over RTP, so not sure
- VLC does not play the SDP file.
Now when instead I use some random video and have ffmpeg output an SDP file like so
ffmpeg -re -i some.mp4 -an -c:v copy -f rtp -sdp_file video.sdp "rtp://127.0.0.1:5004"
I can see that the generated SDP file – which plays in both ffplay and VLC – includes the base64 encoded
sprop-parameter-sets
field, and removing this causes the stream to not play.> cat video.sdp v=0 o=- 0 0 IN IP4 127.0.0.1 s=No Name c=IN IP4 127.0.0.1 t=0 0 a=tool:libavformat 58.76.100 m=video 5004 RTP/AVP 96 b=AS:1034 a=rtpmap:96 H264/90000 a=fmtp:96 packetization-mode=1; sprop-parameter-sets=Z2QANKzZQDAA7fiMBagICAoAAAMAAgAAAwDwHjBjLA==,aOvjyyLA; profile-level-id=640034
My own SDP file on the other hand, does not contain this information, and VLC hangs for 10s and then stops trying with "no data received".
> cat test.sdp v=0 o=- 0 0 IN IP4 127.0.0.1 s=No Name c=IN IP4 127.0.0.1 t=0 0 a=tool:libavformat 58.76.100 m=video 44499 RTP/AVP 96 b=AS:2000 a=rtpmap:96 H264/90000 a=fmtp:96 packetization-mode=1
So my theory is that my custom code must somehow add this SPS information to the SDP file. But despite hours of searching, I could not find a structured way to set the extradata field on the
AVStream
'sAVCodecParams
. The code I'm using is roughly this (I'm sure there's unrelated errors in there):// variables std::vector imgbuf; AVFormatContext *ofmt_ctx = nullptr; AVCodec *out_codec = nullptr; AVStream *out_stream = nullptr; AVCodecContext *out_codec_ctx = nullptr; SwsContext *swsctx = nullptr; cv::Mat canvas_; unsigned int height_; unsigned int width_; unsigned int fps_; AVFrame *frame_ = nullptr; AVOutputFormat *format = av_guess_format("rtp", nullptr, nullptr); const auto url = std::string("rtp://127.0.0.1:5001"); avformat_alloc_output_context2(ofmt_ctx, format, format->name, url.c_str()); out_codec = avcodec_find_encoder(AV_CODEC_ID_H264); stream = avformat_new_stream(ofmt_ctx, out_codec); out_codec_ctx = avcodec_alloc_context3(out_codec); // then, for each incoming image: while (receive_image) { static bool first_time = true; if (first_time) { // discover necessary params such as image dimensions from the first // received image first_time = false; height_ = image.rows; width_ = image.cols; codec_ctx->codec_tag = 0; codec_ctx->bit_rate = 2e6; // does nothing, unfortunately codec_ctx->thread_count = 1; codec_ctx->codec_id = AV_CODEC_ID_H264; codec_ctx->codec_type = AVMEDIA_TYPE_VIDEO; codec_ctx->width = width_; codec_ctx->height = height_; codec_ctx->gop_size = 6; codec_ctx->pix_fmt = AV_PIX_FMT_YUV420P; codec_ctx->framerate = fps_; codec_ctx->time_base = av_inv_q(fps_); avcodec_parameters_from_context(stream, out_codec_ctx); // this stuff is empty: is that the problem? stream->codecpar->extradata = codec_ctx->extradata; stream->codecpar->extradata_size = codec_ctx->extradata_size; AVDictionary *codec_options = nullptr; av_dict_set(&codec_options, "profile", "high", 0); av_dict_set(&codec_options, "preset", "ultrafast", 0); av_dict_set(&codec_options, "tune", "zerolatency", 0); // open video encoder avcodec_open2(codec_ctx, codec, &codec_options); stream->time_base.num = 1; stream->time_base.den = fps_; avio_open(&(ofmt_ctx->pb), ofmt_ctx->filename, AVIO_FLAG_WRITE); /* Write a file for VLC */ char buf[200000]; AVFormatContext *ac[] = {ofmt_ctx}; av_sdp_create(ac, 1, buf, 20000); printf("sdp:\n%s\n", buf); FILE *fsdp = fopen("test.sdp", "w"); fprintf(fsdp, "%s", buf); fclose(fsdp); swsctx = sws_getContext(width_, height_, AV_PIX_FMT_BGR24, width_, height_, out_codec_ctx->pix_fmt, SWS_BICUBIC, nullptr, nullptr, nullptr); } if (!frame_) { frame_ = av_frame_alloc(); std::uint8_t *framebuf = new uint8_t[av_image_get_buffer_size( codec_ctx->pix_fmt, width_, height_, 1)]; av_image_fill_arrays(frame_->data, frame_->linesize, framebuf, codec_ctx->pix_fmt, width, height, 1); frame_->width = width_; frame_->height = height_; frame_->format = static_cast
(codec_ctx->pix_fmt); success = avformat_write_header(ofmt_ctx, nullptr); } if (imgbuf.empty()) { imgbuf.resize(height_ * width_ * 3 + 16); canvas_ = cv::Mat(height_, width_, CV_8UC3, imgbuf.data(), width_ * 3); } else { image.copyTo(canvas_); } const int stride[] = {static_cast (image.step[0])}; sws_scale(swsctx, &canvas_.data, stride, 0, canvas_.rows, frame_->data, frame_->linesize); frame_->pts += av_rescale_q(1, out_codec_ctx->time_base, stream->time_base); AVPacket pkt = {0}; avcodec_send_frame(out_codec_ctx, frame_); avcodec_receive_packet(out_codec_ctx, &pkt); av_interleaved_write_frame(ofmt_ctx, &pkt); } Can anyone offer some advice here?
--
Update
When setting
this->out_codec_ctx->flags |=AV_CODEC_FLAG_GLOBAL_HEADER;
extradata is actually present in the codec context, but I had to move
avcodec_parameters_from_context()
afteravcodec_open2()
, as the extradata is empty before opening the codec. I now getsprop-parameter-sets
in the SDP file, but VLC still does not play it. -
Error in compiling x264 on ARM 64-bit platform
2 septembre 2021, par yanzhang.guoThe same x264 source code I compiled on Debian 10 (Buster) system has no problem, but I can't compile it on an ARM 64-bit platform. Why?
Maybe there is something wrong with the Makefile, but I don't know where it is.
Configure
./configure --disable-asm --enable-shared --host=aarch64-linux platform: AARCH64 byte order: little-endian system: LINUX cli: yes libx264: internal shared: yes static: no asm: no interlaced: yes avs: avxsynth lavf: no ffms: no mp4: no gpl: yes thread: posix opencl: yes filters: crop select_every lto: no debug: no gprof: no strip: no PIC: yes bit depth: all chroma format: all
Edit file config.mak,
SRCPATH=. prefix=/usr/local exec_prefix=${prefix} bindir=${exec_prefix}/bin libdir=${exec_prefix}/lib includedir=${prefix}/include SYS_ARCH=AARCH64 SYS=LINUX CC=aarch64-linux-gnu-gcc CFLAGS=-Wno-maybe-uninitialized -Wshadow -O3 -ffast-math -Wall -I. -I$(SRCPATH) -std=gnu99 - D_GNU_SOURCE -fPIC -fomit-frame-pointer -fno-tree-vectorize COMPILER=GNU COMPILER_STYLE=GNU DEPMM=-MM -g0 DEPMT=-MT LD=aarch64-linux-gnu-gcc -o LDFLAGS= -lm -lpthread -ldl LIBX264=libx264.a AR=aarch64-linux-gnu-gcc-ar rc RANLIB=aarch64-linux-gnu-gcc-ranlib STRIP=aarch64-linux-gnu-strip INSTALL=install AS= ASFLAGS= -I. -I$(SRCPATH) -DSTACK_ALIGNMENT=16 -DPIC RC= RCFLAGS= EXE= HAVE_GETOPT_LONG=1 DEVNULL=/dev/null PROF_GEN_CC=-fprofile-generate PROF_GEN_LD=-fprofile-generate PROF_USE_CC=-fprofile-use PROF_USE_LD=-fprofile-use HAVE_OPENCL=yes CC_O=-o $@ default: cli install: install-cli SOSUFFIX=so SONAME=libx264.so.157 SOFLAGS=-shared -Wl,-soname,$(SONAME) -Wl,-Bsymbolic default: lib-shared install: install-lib-shared LDFLAGSCLI = -ldl CLI_LIBX264 = $(LIBX264)
Make, an error occurred, details in error.
Add file config.h after configure,
#define HAVE_MALLOC_H 1 #define ARCH_X86_64 1 #define SYS_LINUX 1 #define STACK_ALIGNMENT 64 #define HAVE_POSIXTHREAD 1 #define HAVE_CPU_COUNT 1 #define HAVE_THREAD 1 #define HAVE_LOG2F 1 #define HAVE_STRTOK_R 1 #define HAVE_CLOCK_GETTIME 1 #define HAVE_MMAP 1 #define HAVE_THP 1 #define HAVE_AVS 1 #define USE_AVXSYNTH 1 #define HAVE_VECTOREXT 1 #define fseek fseeko #define ftell ftello #define HAVE_BITDEPTH8 1 #define HAVE_BITDEPTH10 1 #define HAVE_GPL 1 #define HAVE_INTERLACED 1 #define HAVE_OPENCL (BIT_DEPTH==8) #define HAVE_ALTIVEC 0 #define HAVE_ALTIVEC_H 0 #define HAVE_MMX 0 #define HAVE_ARMV6 0 #define HAVE_ARMV6T2 0 #define HAVE_NEON 0 #define HAVE_BEOSTHREAD 0 #define HAVE_WIN32THREAD 0 #define HAVE_SWSCALE 0 #define HAVE_LAVF 0 #define HAVE_FFMS 0 #define HAVE_GPAC 0 #define HAVE_LSMASH 0 #define HAVE_X86_INLINE_ASM 0 #define HAVE_AS_FUNC 0 #define HAVE_INTEL_DISPATCHER 0 #define HAVE_MSA 0 #define HAVE_WINRT 0 #define HAVE_VSX 0 #define HAVE_ARM_INLINE_ASM 0
-
High Quality Screen Capture with FFmpeg
27 août 2021, par plumzlI'm trying to figure out a command for high quality screen capture on REHL.
I have tried various options, but none really worked. The quality is not good enough. I'm quite new to ffmpeg and doesn't quite understand all the different flags. So any help would be appreciated!
The commands I have tried:
ffmpeg -y -f x11grab -r 30 -s 1920x1080 -i :0.0+0,0 -vcodec libx264 -strict -2 -b:v 16M output.mov
The first command I tried. The weird thing is it doesn't seem to preserve the bitrate specified
-b:v 16M
. The output video's bitrate is only 2mb/s. Is that not the correct way to specify bitrate when doing screen capture?ffmpeg -f x11grab -s 1920x1080 -r 30 -i :0.0 -qscale 0 -vcodec huffyuv output.mov
The huffyuv codec is supposed to be lossless, but the quality doesn't seem to be any better than the libx264 output.
ffmpeg -f x11grab -r 30 -s 1920x1080 -i :0.0+0,0 -vcodec copy -pix_fmt yuv420p -qscale 0 -an output.mkv ffmpeg -f rawvideo -pix_fmt yuv420p -s:v 1920x1080 -r 30 -i output.mkv -an -c:v libx264 -qscale 0 result.mov
I'm even trying to capture rawvideo and then convert it to libx264 codec viedeo. But the output is corrupted.
I'm using the version of ffmpeg that's built on April 23rd this year. It doesn't have the preset like
-vpre lossless_ultrafast
which I see mentioned in a lot posts.Edit:
After more research, this is the command I end up using. I have to use h264 codec and yuv420p as pixel_fmt since I need to be able to play the quicktimes using quicktime.
ffmpeg -y -f x11grab -framerate 30 -video_size 1920x1080 -i :0.0+0,0 -c:v libx264 -pix_fmt yuv420p -qp 0 -preset ultrafast output.mov
The quality doesn't seem to be much improved even though -qp is set to 0. But it could also because of the rgb conversion to yuv color space according to this post.
-
Gstreamer, x264enc "Redistribute latency..." error
20 août 2021, par JasonI'm trying to setup a video pipeline with very limited bandwidth. I was able to do it with two raspberry pis using the below lines. The first is for the camera pi and the second is to watch stream:
gst-launch-1.0 rpicamsrc preview=false ! 'video/x-h264, width=800, height=600, framerate=30/1' ! h264parse ! rtph264pay config-interval=1 pt=96 ! gdppay ! udpsink host=YOUR_PC_IP port=5000 gst-launch-1.0 udpsrc port=5000 ! gdpdepay ! rtph264depay ! h264parse ! avdec_h264 ! autovideosink sync=false
It works but I go over my bandwidth limit if there is movement. I'm not sure if there is a way to limit bandwidth by setting a parameter here:
'video/x-h264, width=800, height=600, framerate=30/1'
From what I can find online, I have to use something like x264enc. I've followed tutorials but I can't get x264enc to work. it always outputs "Redistribute latency..." on both machines when run and it stays there.
I've tried using x264enc like follows:
gst-launch-1.0 rpicamsrc preview=false ! 'video/x-raw, width=800, height=600, framerate=30/1' ! x264enc ! h264parse ! rtph264pay config-interval=1 pt=96 ! gdppay ! udpsink host=YOUR_PC_IP port=5000 gst-launch-1.0 rpicamsrc preview=false ! 'video/x-raw, width=800, height=600, framerate=30/1' ! x264enc tune=zerolatency ! h264parse ! rtph264pay config-interval=1 pt=96 ! gdppay ! udpsink host=YOUR_PC_IP port=5000 gst-launch-1.0 rpicamsrc preview=false ! x264enc ! h264parse ! rtph264pay config-interval=1 pt=96 ! gdppay ! udpsink host=YOUR_PC_IP port=5000 gst-launch-1.0 rpicamsrc preview=false ! x264enc tune=zerolatency ! h264parse ! rtph264pay config-interval=1 pt=96 ! gdppay ! udpsink host=YOUR_PC_IP port=5000
Based on tutorials, I would think some of those should work. Other threads say that tune=zerolatency fixes my problem. At least the ones with same output of "Redistribute latency..." I don't know what I'm doing wrong.
Any help would be appreciated. Thanks!
-
How to encode multiple files with a batch file
11 juillet 2021, par Black ButterflyI am Encoding my own anime videos to save some space on my HDD using this script
https://gist.github.com/ScarletDevil25/9d71e4a7f5c215e558ecad158aa52600
However I can only encode one video at a time by dragging said video to the batch file and allowing it to run.
What I would like to be able to do is have the batch file encode multiple videos at once.
also as another question if someone could tell me how I would run this as admin