Newest 'x264' Questions - Stack Overflow
Les articles publiés sur le site
-
X264 : How to compile x264 with swscale support ?
23 avril 2014, par user1884325Objective
I am trying to build:
an x264 static library (.lib) with swscale support. I would like to use this library in a Visual Studio project where 24-bit RGB bitmap images are:
- Converted from RGB to YUV2
- The converted image is sent to the x264 encoder
- and the output of the encoder is streamed to a remote IP-endpoint via UDP.
an x264 executable (.exe) with swscale support. I would like to use the executable for the same purpose as described above. In another Visual Studio project, I will start the x264.exe up as a separate process and pipe bitmap data to the x264 process via its stdin and read out the encoded data from the process's stdout.
Problem
I am having some trouble figuring out how to compile with swscale support. I need swscale support for both the executable and the library.
Status
So far I have downloaded the latest x264 source from the x264 website.
I have installed MINGW on my machine and when I run 'configure' and 'make' I get the x264 static library - but without swscale support.
I haven't been able to find a detailed step-by-step guide on how to include swscale in the x264 library. The closest I've come to a description is this discussion:
http://forum.doom9.org/showthread.php?t=165350
So I downloaded libpack from:
http://komisar.gin.by/mingw/index.html
and extracted it to my harddrive:
Then I executed 'make' and 'configure' (again) in my x264 directory:
./configure --extra-cflags="-I/m/somePath/libpack/libpack/libpack/include" --extra-ldflags="-L/m/somePath/libpack/libpack/libpack/lib"
I have the following in the lib and include directory:
When I execute the above 'configure' I get:
platform: X86 system: WINDOWS cli: yes libx264: internal shared: no static: no asm: yes interlaced: yes avs: avisynth lavf: no ffms: no mp4: lsmash gpl: yes thread: win32 opencl: yes filters: crop select_every debug: no gprof: no strip: no PIC: no bit depth: 8 chroma format: all You can run 'make' or 'make fprofiled' now. bash.exe"-3.1$
When I execute 'make' I end up with this error:
gcc.exe: error: unrecognized command line option '-fomit-frame-poin' gcc.exe: fatal error: no input files compilation terminated. make: *** [.depend] Error 1 bash.exe"-3.1$
Question What am I doing wrong??
-
libx264 encoder video plays too fast
23 avril 2014, par NickI'm trying to write a program that uses libx264 to encode the video frames. I've wrapped this code into a small class (see below). I have frames that are in YUV420 format. libx264 encodes the frames and I save them to a file. I can play the file back in VLC, all of the frames are there, but it plays back at several hundred times the actual frame rate. Currently I am capturing frames at 2.5 FPS, but they play back as if it was recorded at 250 or more FPS. I've tried to change the frame rate with no luck.
I've also tried to set
_param.b_vfr_input = 1
and then set the time bases appropriately, but that causes my program to crash. Any ideas? My encode code is shown below. I've also included the output of ffprobe -show_frames
Wrapper Class:
x264wrapper::x264wrapper(int width, int height, int fps, int timeBaseNum, int timeBaseDen, int vfr) { x264_param_default_preset(&_param, "veryfast", "zerolatency"); _param.i_threads = 1; _param.i_width = width; _param.i_height = height; _param.i_fps_num = fps; _param.i_fps_den = 1; // Intra refres: _param.i_keyint_max = fps; _param.b_intra_refresh = 1; //Rate control: _param.rc.i_rc_method = X264_RC_CRF; //_param.rc.i_rc_method = X264_RC_CQP; _param.rc.f_rf_constant = 25; _param.rc.f_rf_constant_max = 35; //For streaming: _param.b_repeat_headers = 1; _param.b_annexb = 1; // misc _param.b_vfr_input = vfr; _param.i_timebase_num = timeBaseNum; _param.i_timebase_den = timeBaseDen; _param.i_log_level = X264_LOG_DEBUG; _encoder = x264_encoder_open(&_param); cout << "Timebase " << _param.i_timebase_num << "/" << _param.i_timebase_den << endl; cout << "fps " << _param.i_fps_num << "/" << _param.i_fps_den << endl; _ticks_per_frame = (int64_t)_param.i_timebase_den * _param.i_fps_den / _param.i_timebase_num / _param.i_fps_num; cout << "ticks_per_frame " << _ticks_per_frame << endl; int result = x264_picture_alloc(&_pic_in, X264_CSP_I420, width, height); if (result != 0) { cout << "Failed to allocate picture" << endl; throw(1); } _ofs = new ofstream("output.h264", ofstream::out | ofstream::binary); _pts = 0; } x264wrapper::~x264wrapper(void) { _ofs->close(); } void x264wrapper::encode(uint8_t * buf) { x264_nal_t* nals; int i_nals; convertFromBalserToX264(buf); _pts += _ticks_per_frame; _pic_in.i_pts = _pts; x264_picture_t pic_out; int frame_size = x264_encoder_encode(_encoder, &nals, &i_nals, &_pic_in, &pic_out); if (frame_size >= 0) { _ofs->write((char*)nals[0].p_payload, frame_size); } else { cout << "error: x264_encoder_encode failed" << endl; } }
Output of ffprobe -show_frames:
[FRAME] media_type=video key_frame=1 pkt_pts=N/A pkt_pts_time=N/A pkt_dts=N/A pkt_dts_time=N/A pkt_duration=48000 pkt_duration_time=0.040000 pkt_pos=0 width=1920 height=1080 pix_fmt=yuv420p sample_aspect_ratio=N/A pict_type=I coded_picture_number=0 display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 reference=0 [/FRAME] [FRAME] media_type=video key_frame=0 pkt_pts=N/A pkt_pts_time=N/A pkt_dts=N/A pkt_dts_time=N/A pkt_duration=N/A pkt_duration_time=N/A pkt_pos=54947 width=1920 height=1080 pix_fmt=yuv420p sample_aspect_ratio=N/A pict_type=P coded_picture_number=1 display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 reference=0 [/FRAME] [FRAME] media_type=video key_frame=0 pkt_pts=N/A pkt_pts_time=N/A pkt_dts=N/A pkt_dts_time=N/A pkt_duration=N/A pkt_duration_time=N/A pkt_pos=57899 width=1920 height=1080 pix_fmt=yuv420p sample_aspect_ratio=N/A pict_type=P coded_picture_number=2 display_picture_number=0 interlaced_frame=0 top_field_first=0 repeat_pict=0 reference=0 [/FRAME]
-
X264 : How to access NAL units from encoder ?
18 avril 2014, par user1884325When I call
frame_size = x264_encoder_encode(encoder, &nals, &i_nals, &pic_in, &pic_out);
and subsequently write each NAL to a file like this:
if (frame_size >= 0) { int i; int j; for (i = 0; i < i_nals; i++) { printf("******************* NAL %d (%d bytes) *******************\n", i, nals[i].i_payload); fwrite(&(nals[i].p_payload[0]), 1, nals[i].i_payload, fid); } }
then I get this
My questions are:
1) Is it normal that there's readable parameters in the beginning of the file?
2) How do I configure the X264 encoder so that the encoder returns frames that I can send via UDP without the packet getting fragmented (size must be below 1390 or somewhere around that).
3) With the x264.exe I pass in these options:
"--threads 1 --profile baseline --level 3.2 --preset ultrafast --bframes 0 --force-cfr --no-mbtree --sync-lookahead 0 --rc-lookahead 0 --keyint 1000 --intra-refresh"
How do I map those to the settings in the X264 parameters structure ? (x264_param_t)
4) I have been told that the x264 static library doesn't support bitmap input to the encoder and that I have to use libswscale for conversion of the 24bit RGB input bitmap to YUV2. The encoder, supposedly, only takes YUV2 as input? Is this true? If so, how do I build libswscale for the x264 static library?
-
X264 Encoder API
16 avril 2014, par user1884325I'm studying the X264 API for encoding images.
So far I've built the X264 library and the following code snippet shows how far I am:
int frame_size; x264_t* encoder; x264_picture_t pic_in, pic_out; x264_param_t x264Param; int fps = 20; int width = 1280; int height = 720; x264_nal_t* nals; int i_nals; x264_param_default_preset(&x264Param, "veryfast", "zerolatency"); x264Param.i_threads = 1; x264Param.i_width = 1280; x264Param.i_height = 720; x264Param.i_fps_num = fps; x264Param.i_fps_den = 1; x264Param.i_keyint_max = fps; x264Param.b_intra_refresh = 1; x264Param.rc.i_rc_method = X264_RC_CRF; x264Param.rc.f_rf_constant = 25; x264Param.rc.f_rf_constant_max = 35; x264Param.b_repeat_headers = 1; x264Param.b_annexb = 1; x264_param_apply_profile(&x264Param, "baseline"); encoder = x264_encoder_open(&x264Param); x264_picture_alloc(&pic_in, X264_CSP_BGR, width, height); /* How to fill in bitmap data? */ frame_size = x264_encoder_encode(encoder, &nals, &i_nals, &pic_in, &pic_out); if (frame_size >= 0) { printf("OK\n"); }
So I'm trying to encode a 24bit BGR bitmap image. However, the x264 header file doesn't show any API function for writing the bitmap image to the encoder. How is this done?
EDIT
This code snippet seems to work. I would appreciate a review and some comments. Thanks.
int frame_size; int accum_frame_size; x264_t* encoder; x264_picture_t pic_in, pic_out; x264_param_t x264Param; int fps = 20; int width = 1280; int height = 720; x264_nal_t* nals; int i_nals; int64_t frameCount = 0; int k; for (k = 0; k < (1280*3*720); k++) { bgr[k] = rand(); } x264_param_default_preset(&x264Param, "veryfast", "zerolatency"); x264Param.i_threads = 1; x264Param.i_width = 1280; x264Param.i_height = 720; x264Param.i_fps_num = fps; x264Param.i_fps_den = 1; x264Param.i_keyint_max = fps; x264Param.b_intra_refresh = 1; x264Param.rc.i_rc_method = X264_RC_CRF; x264Param.i_csp = X264_CSP_BGR; x264Param.rc.f_rf_constant = 25; x264Param.rc.f_rf_constant_max = 35; x264Param.b_repeat_headers = 1; x264Param.b_annexb = 1; x264_param_apply_profile(&x264Param, "baseline"); encoder = x264_encoder_open(&x264Param); x264_picture_alloc(&pic_in, X264_CSP_BGR, width, height); /* Load 24-bit BGR bitmap */ pic_in.img.i_csp = X264_CSP_BGR; pic_in.img.i_plane = 1; pic_in.img.i_stride[0] = 3 * 1280; pic_in.img.plane[0] = bgr; pic_in.i_pts = frameCount; pic_in.i_type = X264_TYPE_AUTO; pic_out.i_pts = frameCount; /* Returns a frame size of 912 for first frame in this case */ frame_size = x264_encoder_encode(encoder, &nals, &i_nals, &pic_in, &pic_out); printf("Decoder returned frame size = %d \n", frame_size); printf("Decoder returned %d NAL units \n", i_nals); if (frame_size >= 0) { int i; int j; accum_frame_size = 0; for (i = 0; i < i_nals; i++) { printf("******************* NAL %d (%d bytes) *******************\n", i, nals[i].i_payload); for (j = 0; j < nals[i].i_payload; j++) { if (j == 0) printf("First 10 bytes: "); if (j < 10) printf("%02X |", nals[i].p_payload[j]); accum_frame_size++; } printf("\n"); } } printf("Verified frame size = %d \n", accum_frame_size);
EDIT #2 The encoder outputs this:
x264 [error]: baseline profile doesn't support 4:4:4 x264 [info]: using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX x264 [info]: profile High 4:4:4 Predictive, level 3.1, 4:4:4 8-bit Decoder returned frame size = 1467194 Decoder returned 4 NAL units ******************* NAL 0 (31 bytes) ******************* First 10 bytes: 00 |00 |00 |01 |67 |F4 |00 |1F |91 |89 | ******************* NAL 1 (8 bytes) ******************* First 10 bytes: 00 |00 |00 |01 |68 |EF |1F |2C | ******************* NAL 2 (595 bytes) ******************* First 10 bytes: 00 |00 |01 |06 |05 |FF |FF |4C |DC |45 | ******************* NAL 3 (1466560 bytes) ******************* First 10 bytes: 00 |00 |01 |65 |88 |82 |0A |FF |F5 |B0 | Verified frame size = 1467194
Isn't each NAL unit supposed to start with 0x00 0x00 0x00 0x01 ?
szatmary : I appreciate your valuable feedback. So you're saying that each NAL unit does not necessarily start with 0,0,0,1. However, I'm a bit unclear on your answer. Are you implying that with a certain configuration the NAL units will start with 0,0,0,1 ? If so, which configuration is that? I need to make sure that each NAL unit I transmit out on the network to a remote receiver starts with 0,0,0,1. Prior to exploring the x264 library I was using the x264 exe and piped BMP data in and encoded data out from the x264 process. I then parsed the encoder output and looked for NAL units by looking for 0,0,0,1. How do I accomplish the same with the x264 library?
Regarding libswscale:
I downloaded the ffmpeg source and ran configure and make in MINGW. After the process had completed I couldn't find anything but a number of .exe files. How do I build actual static libraries (.lib) which I can use in a Visual Studio project?
-
x264/avcodec : Deduce frame sequence number from NAL unit
4 avril 2014, par Dan TumaykinI'm using avcodec H264 decoder in my project. I receive NAL units from network, stick together NALs from same frame (additional header is added on network layer) and than pass to the decoder. I was wondering if frame sequence number is encoded into NAL unit - it would be logical, as we need the reference to IDR frames.
If this information is present - how can I extract it?
Right now I looking into ITU-T H.264 specification, which is quite complex I can admit. So far I have not found the answer to my question.