Newest 'x264' Questions - Stack Overflow

http://stackoverflow.com/questions/tagged/x264

Les articles publiés sur le site

  • Why ffmpeg can play h264 even when flag —disable-libx264 is set ? [closed]

    2 décembre 2020, par Jams

    To be complient with x264 licensing (for a commercial software I'm making) I plan to use a compiled version of ffmpeg without x264 support. Here is the ouput of the command line ffmpeg -L:

    ffmpeg version n4.3.1-20-g8a2acdc6da Copyright (c) 2000-2020 the FFmpeg developers built with gcc 9.3-win32 (GCC) 20200320 configuration: --prefix=/ffbuild/prefix --pkg-config-flags=--static --pkg-config=pkg-config --cross-prefix=x86_64-w64-mingw32- --arch=x86_64 --target-os=mingw32 --enable-version3 --disable-debug --enable-shared --disable-static --disable-debug --enable-iconv --enable-zlib --enable-libxml2 --enable-libfreetype --enable-libfribidi --enable-gmp --enable-lzma --enable-fontconfig --enable-opencl --enable-libvmaf --disable-vulkan --enable-libvorbis --enable-amf --enable-libaom --disable-avisynth --enable-libdav1d --disable-libdavs2 --enable-ffnvcodec --enable-cuda-llvm --disable-libglslang --enable-libass --enable-libbluray --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvpx --enable-libwebp --enable-libmfx --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librav1e --enable-schannel --enable-sdl2 --enable-libsoxr --enable-libsrt --enable-libtwolame --disable-libvidstab --disable-libx264 --disable-libx265 --disable-libxavs2 --disable-libxvid --enable-libzimg --extra-cflags=-DLIBTWOLAME_STATIC --extra-cxxflags= --extra-ldflags=-pthread --extra-libs=-lgomp libavutil 56. 51.100 / 56. 51.100 libavcodec 58. 91.100 / 58. 91.100 libavformat 58. 45.100 / 58. 45.100 libavdevice 58. 10.100 / 58. 10.100 libavfilter 7. 85.100 / 7. 85.100 libswscale 5. 7.100 / 5. 7.100 libswresample 3. 7.100 / 3. 7.100 ffmpeg is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.

    But when I play a video encoded with h264 it plays perfectly. Is expected? How to be sure I'm not infringing the license?

    Here is where I downloaded the binaries: https://github.com/BtbN/FFmpeg-Builds/releases
    And I picked a release with the following name: win64-gpl-shared-4.3.zip

    Thanks.

  • Frame sliced into 2 under some degree. How fix it ?

    26 novembre 2020, par Алекс Аникей

    I trying use h264 codec in videochat application. And in some reason frame sliced into 2 triangle (picture below). I try send my desktop image to another person and get this image on another client.

    What settings i set wrong? My code:

    Init:

    VCSession *vc_new_x264(Logger *log, ToxAV *av, uint32_t friend_number, toxav_video_receive_frame_cb *cb, void *cb_data,
                           VCSession *vc)
    {
    
        if (x264_param_default_preset(&param, "slow", "zerolatency") < 0) {
            // goto fail;
        }
    
        param.i_csp = X264_CSP_I420;
        param.i_width  = 1920;
        param.i_height = 1080;
        vc->h264_enc_width = param.i_width;
        vc->h264_enc_height = param.i_height;
    
        param.i_keyint_max = 30;
    
        param.b_vfr_input = 1; /* VFR input.  If 1, use timebase and timestamps for ratecontrol purposes.
                                * If 0, use fps only. */
        param.i_timebase_num = 1;       // 1 ms = timebase units = (1/1000)s
        param.i_timebase_den = 1000;   // 1 ms = timebase units = (1/1000)s
        param.b_repeat_headers = 1;
        param.b_annexb = 1;
    
        param.rc.f_rate_tolerance = VIDEO_F_RATE_TOLERANCE_H264;
        param.rc.i_vbv_buffer_size = 1500;
        param.rc.i_vbv_max_bitrate = VIDEO_BITRATE_INITIAL_VALUE_H264 * 1;
    
        vc->h264_enc_bitrate = VIDEO_BITRATE_INITIAL_VALUE_H264;
    
        param.rc.i_qp_min = 13;
        param.rc.i_qp_max = 35; // max quantizer for x264
    
        vc->h264_enc_bitrate = VIDEO_BITRATE_INITIAL_VALUE_H264;
    
        param.rc.b_stat_read = 0;
        param.rc.b_stat_write = 0;
    
    
        if (x264_param_apply_profile(&param,
                                     "high") < 0) { // "baseline", "main", "high", "high10", "high422", "high444"
            // goto fail;
        }
    
    
        if (x264_picture_alloc(&(vc->h264_in_pic), param.i_csp, param.i_width, param.i_height) < 0) {
            // goto fail;
        }
    
        vc->h264_encoder = x264_encoder_open(&param);
    
        AVCodec *codec = NULL;
        vc->h264_decoder = NULL;
        avcodec_register_all();
        codec = NULL;
    
        codec = avcodec_find_decoder(AV_CODEC_ID_H264);
    
        if (!codec) {
            LOGGER_WARNING(log, "codec not found H264 on decoder");
        }
    
        vc->h264_decoder = avcodec_alloc_context3(codec);
    
        if (codec->capabilities & AV_CODEC_CAP_TRUNCATED) {
            vc->h264_decoder->flags |= AV_CODEC_FLAG_TRUNCATED; /* we do not send complete frames */
        }
    
    
        vc->h264_decoder->delay = 5;
    
        if (avcodec_open2(vc->h264_decoder, codec, NULL) < 0) {
            LOGGER_WARNING(log, "could not open codec H264 on decoder");
        }
    
    
        return vc;
    }
    

    Get frame and decoding him:

    void vc_iterate_x264(VCSession *vc)
    {
    
        if (!vc) {
            return;
        }
    
        pthread_mutex_lock(vc->queue_mutex);
    
        struct RTPMessage *p;
    
        if (!rb_read(vc->vbuf_raw, (void **)&p)) {
            LOGGER_TRACE(vc->log, "no Video frame data available");
            pthread_mutex_unlock(vc->queue_mutex);
            return;
        }
    
        pthread_mutex_unlock(vc->queue_mutex);
        const struct RTPHeader *const header = &p->header;
    
        uint32_t full_data_len;
    
        if (header->flags & RTP_LARGE_FRAME) {
            full_data_len = header->data_length_full;
            LOGGER_WARNING(vc->log, "vc_iterate:001:full_data_len=%d", (int)full_data_len);
        } else {
            full_data_len = p->len;
            if (header->data_length_lower != full_data_len)
            {
                LOGGER_ERROR("Data header and packet don't equal: %d - header %d - packet", header->data_length_lower, full_data_len);
            }
            LOGGER_DEBUG(vc->log, "vc_iterate:002");
        }
    
        decode_frame_h264(vc, p, full_data_len);
    }
    
    void decode_frame_h264(VCSession *vc,
                           struct RTPMessage *p,
                           uint32_t full_data_len)
    {
    
        AVPacket *compr_data;
        compr_data = av_packet_alloc();
    
    
        uint8_t *tmp_buf = calloc(1, full_data_len + FF_INPUT_BUFFER_PADDING_SIZE);
        memcpy(tmp_buf, p->data, full_data_len);
    
        compr_data->data = tmp_buf; // p->data;
        compr_data->size = (int)full_data_len; // hmm, "int" again
    
        avcodec_send_packet(vc->h264_decoder, compr_data);
    
        int ret_ = 0;
        while (ret_ >= 0) {
            AVFrame *frame = av_frame_alloc();
            ret_ = avcodec_receive_frame(vc->h264_decoder, frame);
            if (ret_ == AVERROR(EAGAIN) || ret_ == AVERROR_EOF) {
                // error
                break;
            } else if (ret_ < 0) {
                // Error during decoding
                break;
            } else if (ret_ == 0) {
                vc->vcb(vc->av, vc->friend_number, frame->width, frame->height,
                              (const uint8_t *)frame->data[0],
                              (const uint8_t *)frame->data[1],
                              (const uint8_t *)frame->data[2],
                              frame->linesize[0], frame->linesize[1],
                              frame->linesize[2], vc->vcb_user_data);
            } else {
                // some other error
            }
            av_frame_free(&frame);
        }
        av_packet_free(&compr_data);
        free(tmp_buf);
        free(p);
    }
    

    Send frame and encoding:

    bool toxav_video_send_frame(ToxAV *av, uint32_t friend_number, uint16_t width, uint16_t height, const uint8_t *y,
                                const uint8_t *u, const uint8_t *v, Toxav_Err_Send_Frame *error, int16_t kf_max_dist, vpx_codec_er_flags_t error_resilient,
                                unsigned int my_lag_in_frames, uint16_t kf_mode, uint16_t quality_mode)
    {
        Toxav_Err_Send_Frame rc = TOXAV_ERR_SEND_FRAME_OK;
        ToxAVCall *call;
        uint64_t video_frame_record_timestamp = current_time_monotonic(av->m->mono_time);
    
        int vpx_encode_flags = 0;
    
        pthread_mutex_lock(call->mutex_video);
        pthread_mutex_unlock(av->mutex);
    
        if (y == nullptr || u == nullptr || v == nullptr) {
            pthread_mutex_unlock(call->mutex_video);
            rc = TOXAV_ERR_SEND_FRAME_NULL;
            goto RETURN;
        }
    
    
        if (call->video_rtp->ssrc < VIDEO_SEND_X_KEYFRAMES_FIRST) {
            // Key frame flag for first frames
            vpx_encode_flags = VPX_EFLAG_FORCE_KF;
            LOGGER_INFO(av->m->log, "I_FRAME_FLAG:%d only-i-frame mode", call->video_rtp->ssrc);
    
            ++call->video_rtp->ssrc;
        } else if (call->video_rtp->ssrc == VIDEO_SEND_X_KEYFRAMES_FIRST) {
            // normal keyframe placement
            vpx_encode_flags = 0;
            LOGGER_INFO(av->m->log, "I_FRAME_FLAG:%d normal mode", call->video_rtp->ssrc);
    
            ++call->video_rtp->ssrc;
        }
    
    
        x264_nal_t *nal = NULL;
        int i_frame_size = 0;
    
        uint32_t result = encode_frame_h264(av, friend_number, width, height,
                                            y, u, v,
                                            &video_frame_record_timestamp,
                                            vpx_encode_flags,
                                            &nal,
                                            &i_frame_size);
        if (result != 0) {
            pthread_mutex_unlock(call->mutex_video);
            rc = TOXAV_ERR_SEND_FRAME_INVALID;
            goto RETURN;
        }
    
        ++call->video->frame_counter;
    
        rc = send_frames_h264(av, friend_number, width, height,
                              y, u, v, call,
                              &video_frame_record_timestamp,
                              vpx_encode_flags,
                              &nal,
                              &i_frame_size,
                              &rc);
    
        pthread_mutex_unlock(call->mutex_video);
    
    RETURN:
    
        if (error) {
            *error = rc;
        }
    
        return rc == TOXAV_ERR_SEND_FRAME_OK;
    }
    
    uint32_t send_frames_h264(ToxAV *av, uint32_t friend_number, uint16_t width, uint16_t height,
                              const uint8_t *y,
                              const uint8_t *u, const uint8_t *v, ToxAVCall *call,
                              uint64_t *video_frame_record_timestamp,
                              int vpx_encode_flags,
                              x264_nal_t **nal,
                              int *i_frame_size,
                              TOXAV_ERR_SEND_FRAME *rc)
    {
    
        if (*i_frame_size > 0) {
    
            // use the record timestamp that was actually used for this frame
            *video_frame_record_timestamp = (uint64_t)call->video->h264_in_pic.i_pts;
            const uint32_t frame_length_in_bytes = *i_frame_size;
            const int keyframe = (int)call->video->h264_out_pic.b_keyframe;
    
            LOGGER_DEBUG(av->m->log, "video packet record time: %lu", (*video_frame_record_timestamp));
    
            int res = rtp_send_data
                      (
                          call->video_rtp,
                          (const uint8_t *)((*nal)->p_payload),
                          frame_length_in_bytes,
                          keyframe,
                          *video_frame_record_timestamp,
                          av->m->log
                      );
    
            (*video_frame_record_timestamp)++;
    
            if (res < 0) {
                LOGGER_WARNING(av->m->log, "Could not send video frame: %s", strerror(errno));
                *rc = TOXAV_ERR_SEND_FRAME_RTP_FAILED;
                return 1;
            }
    
            return 0;
        } else {
            *rc = TOXAV_ERR_SEND_FRAME_RTP_FAILED;
            return 1;
        }
    
    }
    

    I get image like this:

    enter image description here

  • Use MinGW to compile x264 in windows, Error Code 5

    7 novembre 2020, par ArthurRen
    rm -f libx264.a    
    gcc-ar rc libx264.a  common/osdep.o common/base.o common/cpu.o common/tables.o encoder/api.o common/win32thread.o common/mc-8.o common/predict-8.o common/pixel-8.o common/macroblock-8.o common/frame-8.o common/dct-8.o common/cabac-8.o common/common-8.o common/rectangle-8.o common/set-8.o common/quant-8.o common/deblock-8.o common/vlc-8.o common/mvpred-8.o common/bitstream-8.o encoder/analyse-8.o encoder/me-8.o encoder/ratecontrol-8.o encoder/set-8.o encoder/macroblock-8.o encoder/cabac-8.o encoder/cavlc-8.o encoder/encoder-8.o encoder/lookahead-8.o common/threadpool-8.o common/x86/mc-c-8.o common/x86/predict-c-8.o common/opencl-8.o encoder/slicetype-cl-8.o common/mc-10.o common/predict-10.o common/pixel-10.o common/macroblock-10.o common/frame-10.o common/dct-10.o common/cabac-10.o common/common-10.o common/rectangle-10.o common/set-10.o common/quant-10.o common/deblock-10.o common/vlc-10.o common/mvpred-10.o common/bitstream-10.o encoder/analyse-10.o encoder/me-10.o encoder/ratecontrol-10.o encoder/set-10.o encoder/macroblock-10.o encoder/cabac-10.o encoder/cavlc-10.o encoder/encoder-10.o encoder/lookahead-10.o common/threadpool-10.o common/x86/mc-c-10.o common/x86/predict-c-10.o  common/x86/cpu-a.o common/x86/dct-32-8.o common/x86/pixel-32-8.o common/x86/bitstream-a-8.o common/x86/const-a-8.o common/x86/cabac-a-8.o common/x86/dct-a-8.o common/x86/deblock-a-8.o common/x86/mc-a-8.o common/x86/mc-a2-8.o common/x86/pixel-a-8.o common/x86/predict-a-8.o common/x86/quant-a-8.o common/x86/sad-a-8.o common/x86/dct-32-10.o common/x86/pixel-32-10.o common/x86/bitstream-a-10.o common/x86/const-a-10.o common/x86/cabac-a-10.o common/x86/dct-a-10.o common/x86/deblock-a-10.o common/x86/mc-a-10.o common/x86/mc-a2-10.o common/x86/pixel-a-10.o common/x86/predict-a-10.o common/x86/quant-a-10.o common/x86/sad16-a-10.o
    make: *** [libx264.a] Error 5
    

    The text above is the output infomation in the shell, and I don't know how to get more detailed information. What does "Error 5" means?

  • PSNR calculation in H.264 packet loss

    7 novembre 2020, par K07

    I'm streaming H.264(libx264) videos using RTP. I would like to compare the different error resiliency methods in h.264. In some research papers, psnr was used to compare them. So I would like to know how to calculate the psnr of the h.264 video during streaming.

  • How do I force an IDR-frame using the x264 C API ?

    28 octobre 2020, par Keith

    I am attempting to use an external bool signal to force the next encoded frame to be an IDR-frame using the x264 C API. I am using the "baseline" profile with the "ultrafast" and "zerolatency" presets. I tried to use the input pic settings prior to encoding, as in this code snippet, but this has not worked. My class Open() and Encode() methods are shown here. Any help will be appreciated.

    int X264Encoder::Open(void)
    {
      if (_x264VideoEncoder != NULL)
        Close();
    
      // Set up default parameters.
      if (x264_param_default_preset(&_param, _encoderSpeedPreset.c_str(), "zerolatency") < 0)  // 0=success, -1=failed
        { _errStr = "X264Encoder::Open: Default parameter preset failed with " + _encoderSpeedPreset; return(0); }
    
      // Set non-default params.
      _param.i_bitdepth       = 8;
      _param.i_csp            = _colourSpaceMapping[_colourSpace]; // Input colour space
      if(!_param.i_csp)
        { _errStr = "X264Encoder::Open: Incompatible colour space " + to_string(_colourSpace); return(0); }
      _param.i_width          = _width;
      _param.i_height         = _height;
      _param.i_fps_num        = _videoRateNumerator;
      _param.i_fps_den        = _videoRateDenominator;
    
      _param.rc.i_bitrate     = _avgBitsPerSecond / 1000; // bitrate units are in kbits/s
    
      _param.i_threads        = 1;
      _param.b_vfr_input      = 0;  // VFR input.  If 1, use timebase and timestamps for ratecontrol purposes. If 0, use fps only.
      _param.b_repeat_headers = 1;  // Put SPS/PPS before each keyframe
      _param.b_annexb         = 1;  // If set, place start codes (4 bytes) before NAL units, otherwise place size (4 bytes) before NAL units.
    
      // Apply profile restrictions.
      if (x264_param_apply_profile(&_param, _profile.c_str()) < 0)  // 0=success, -1=failed
        { _errStr = "X264Encoder::Open: Unable to set profile " + _profile; return(0); }
    
      // Initialise the encoder input pic buffer.
      if (x264_picture_alloc(&_picIn, _param.i_csp, _param.i_width, _param.i_height) < 0)
        { _errStr = "X264Encoder::Open: Unable to alloc input picture buffer"; return(0); }
      _inPicIsAllocated = true;
    
      // Instantiate the encoder.
      _x264VideoEncoder = x264_encoder_open(&_param);
      if (_x264VideoEncoder == NULL)
      {
        _errStr = "X264Encoder::Open: Unable to instantiate the encoder"; 
        // Clean up before exit.
        x264_picture_clean(&_picIn);
        _inPicIsAllocated = false;
        return(0);
      }//end if !_x264VideoEncoder...
    
      // Frame counting for pts timestamps.
      _frameNum     = 0;
      _lastPicType  = 0; // IDR-frame
    
      d.clear();
    
      return(1);
    }//end Open.
    
    int X264Encoder::Encode(void* pSrc, void* pCmp, void* codeParameter)
    {
      _encodedFrameSize = 0;
    
      // Validation house work.
      if(!Ready())
        { _errStr = "X264Encoder::Encode: Not ready"; return(0); }
    
      if(!pSrc || !pCmp)
        { _errStr = "X264Encoder::Encode: Invalid function parameter list"; return(0); }
    
      // Load input image. 
      if(_param.i_csp != X264_CSP_I420) // Can only process I420 input colour space.
        { _errStr = "X264Encoder::Encode: I420 colour space required"; return(0); }
      uint32_t lumSize = _width * _height;
      uint32_t chrSize = lumSize / 4;
      // Transfer the input source image into the x264 picture img structure.
      uint8_t* pImg = static_cast(pSrc);
      memcpy_s(_picIn.img.plane[0], lumSize, pImg, lumSize);
      pImg += lumSize;
      memcpy_s(_picIn.img.plane[1], chrSize, pImg, chrSize);
      pImg += chrSize;
      memcpy_s(_picIn.img.plane[2], chrSize, pImg, chrSize);
    
      // Encode single frame
      _picIn.i_pts = _frameNum;
      if (_idrFrameRequired) 
      {  
        _picIn.i_type = X264_TYPE_IDR; 
        //... and clear the signal.
        _idrFrameRequired = false; 
      }//end if _idrFrameRequired...
      else 
        _picIn.i_type = X264_TYPE_AUTO;
    
      _encodedFrameSize = x264_encoder_encode(_x264VideoEncoder, &_nal, &_nalCnt, &_picIn, &_picOut);
      if (_encodedFrameSize > 0)
      {
        // Write the encoded stream to the output.
        uint8_t* pOut = static_cast(pCmp);
        memcpy_s(pOut, _encodedFrameSize, _nal->p_payload, _encodedFrameSize);
      }//end else if _encodedFrameSize...
      else
        { _errStr = "X264Encoder::Encode: Encode process failed"; return(0); }
    
      _lastPicType = 1; // Non-IDR
      if (_picOut.i_type == X264_TYPE_IDR)
        _lastPicType = 0; // IDR
    
      d.push_back({ _encodedFrameSize, _lastPicType });
    
      _frameNum++;
      return(1);
    }//end Encode...