Newest 'libx264' Questions - Stack Overflow

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

Les articles publiés sur le site

  • iOS Build PJSIP with FFmpeg+libx264

    22 février 2021, par Meonardo

    I have built the FFmpeg with libx264 into static libs, here is my directory tree.

    ./ffmpeg
    ├── include
    │   ├── libavcodec
    │   │   ├── ac3_parser.h
    │   │   ├── adts_parser.h
    │   │   ├── avcodec.h
    │   │   ├── avdct.h
    │   │   ├── avfft.h
    │   │   ├── bsf.h
    │   │   ├── codec.h
    │   │   ├── codec_desc.h
    │   │   ├── codec_id.h
    │   │   ├── codec_par.h
    │   │   ├── d3d11va.h
    │   │   ├── dirac.h
    │   │   ├── dv_profile.h
    │   │   ├── dxva2.h
    │   │   ├── jni.h
    │   │   ├── mediacodec.h
    │   │   ├── packet.h
    │   │   ├── qsv.h
    │   │   ├── vaapi.h
    │   │   ├── vdpau.h
    │   │   ├── version.h
    │   │   ├── videotoolbox.h
    │   │   ├── vorbis_parser.h
    │   │   └── xvmc.h
    │   ├── libavdevice
    │   │   ├── avdevice.h
    │   │   └── version.h
    │   ├── libavfilter
    │   │   ├── avfilter.h
    │   │   ├── buffersink.h
    │   │   ├── buffersrc.h
    │   │   └── version.h
    │   ├── libavformat
    │   │   ├── avformat.h
    │   │   ├── avio.h
    │   │   └── version.h
    │   ├── libavutil
    │   │   ├── adler32.h
    │   │   ├── aes.h
    │   │   ├── aes_ctr.h
    │   │   ├── attributes.h
    │   │   ├── audio_fifo.h
    │   │   ├── avassert.h
    │   │   ├── avconfig.h
    │   │   ├── avstring.h
    │   │   ├── avutil.h
    │   │   ├── base64.h
    │   │   ├── blowfish.h
    │   │   ├── bprint.h
    │   │   ├── bswap.h
    │   │   ├── buffer.h
    │   │   ├── camellia.h
    │   │   ├── cast5.h
    │   │   ├── channel_layout.h
    │   │   ├── common.h
    │   │   ├── cpu.h
    │   │   ├── crc.h
    │   │   ├── des.h
    │   │   ├── dict.h
    │   │   ├── display.h
    │   │   ├── dovi_meta.h
    │   │   ├── downmix_info.h
    │   │   ├── encryption_info.h
    │   │   ├── error.h
    │   │   ├── eval.h
    │   │   ├── ffversion.h
    │   │   ├── fifo.h
    │   │   ├── file.h
    │   │   ├── frame.h
    │   │   ├── hash.h
    │   │   ├── hdr_dynamic_metadata.h
    │   │   ├── hmac.h
    │   │   ├── hwcontext.h
    │   │   ├── hwcontext_cuda.h
    │   │   ├── hwcontext_d3d11va.h
    │   │   ├── hwcontext_drm.h
    │   │   ├── hwcontext_dxva2.h
    │   │   ├── hwcontext_mediacodec.h
    │   │   ├── hwcontext_opencl.h
    │   │   ├── hwcontext_qsv.h
    │   │   ├── hwcontext_vaapi.h
    │   │   ├── hwcontext_vdpau.h
    │   │   ├── hwcontext_videotoolbox.h
    │   │   ├── hwcontext_vulkan.h
    │   │   ├── imgutils.h
    │   │   ├── intfloat.h
    │   │   ├── intreadwrite.h
    │   │   ├── lfg.h
    │   │   ├── log.h
    │   │   ├── lzo.h
    │   │   ├── macros.h
    │   │   ├── mastering_display_metadata.h
    │   │   ├── mathematics.h
    │   │   ├── md5.h
    │   │   ├── mem.h
    │   │   ├── motion_vector.h
    │   │   ├── murmur3.h
    │   │   ├── opt.h
    │   │   ├── parseutils.h
    │   │   ├── pixdesc.h
    │   │   ├── pixelutils.h
    │   │   ├── pixfmt.h
    │   │   ├── random_seed.h
    │   │   ├── rational.h
    │   │   ├── rc4.h
    │   │   ├── replaygain.h
    │   │   ├── ripemd.h
    │   │   ├── samplefmt.h
    │   │   ├── sha.h
    │   │   ├── sha512.h
    │   │   ├── spherical.h
    │   │   ├── stereo3d.h
    │   │   ├── tea.h
    │   │   ├── threadmessage.h
    │   │   ├── time.h
    │   │   ├── timecode.h
    │   │   ├── timestamp.h
    │   │   ├── tree.h
    │   │   ├── twofish.h
    │   │   ├── tx.h
    │   │   ├── version.h
    │   │   ├── video_enc_params.h
    │   │   └── xtea.h
    │   ├── libpostproc
    │   │   ├── postprocess.h
    │   │   └── version.h
    │   ├── libswresample
    │   │   ├── swresample.h
    │   │   └── version.h
    │   ├── libswscale
    │   │   ├── swscale.h
    │   │   └── version.h
    │   └── libx264
    │       ├── x264.h
    │       └── x264_config.h
    └── lib
        ├── libavcodec.a
        ├── libavdevice.a
        ├── libavfilter.a
        ├── libavformat.a
        ├── libavutil.a
        ├── libpostproc.a
        ├── libswresample.a
        ├── libswscale.a
        └── libx264.a
    

    The final lib was created successfully, no error message in log file, but when I import the lib to my Xcode Project, the linker give me tons of errors(missing symbols like: Undefined symbol: _pjsua_vid_codec_set_priority). I found the pjsua_vid.o is very small(200Bytes) compare to my pjsip+openh264 build file(was 47KB), perhaps this is the reason cause the link error.

    Here is my build log: log_file

    the build script I am using:

    #!/bin/sh
    
    # see http://stackoverflow.com/a/3915420/318790
    function realpath { echo $(cd $(dirname "$1"); pwd)/$(basename "$1"); }
    __FILE__=`realpath "$0"`
    __DIR__=`dirname "${__FILE__}"`
    
    # download
    function download() {
        "${__DIR__}/download.sh" "$1" "$2" #--no-cache
    }
    
    BASE_DIR="$1"
    PJSIP_URL="https://github.com/pjsip/pjproject/archive/2.10.zip"
    #http://www.pjsip.org/release/2.8.0/pjproject-2.8.0.tar.bz2
    PJSIP_DIR="$1/src"
    LIB_PATHS=("pjlib/lib" \
               "pjlib-util/lib" \
               "pjmedia/lib" \
               "pjnath/lib" \
               "pjsip/lib" \
               "third_party/lib")
    
    OPENSSL_PREFIX=
    FFMPEG_PREFIX=
    OPENH264_PREFIX=
    OPUS_PREFIX=
    while [ "$#" -gt 0 ]; do
        case $1 in
            --with-openssl)
                if [ "$#" -gt 1 ]; then
                    OPENSSL_PREFIX=$(python -c "import os,sys; print os.path.realpath(sys.argv[1])" "$2")
                    shift 2
                    continue
                else
                    echo 'ERROR: Must specify a non-empty "--with-openssl PREFIX" argument.' >&2
                    exit 1
                fi
                ;;
            --with-openh264)
                if [ "$#" -gt 1 ]; then
                    OPENH264_PREFIX=$(python -c "import os,sys; print os.path.realpath(sys.argv[1])" "$2")
                    shift 2
                    continue
                else
                    echo 'ERROR: Must specify a non-empty "--with-openh264 PREFIX" argument.' >&2
                    exit 1
                fi
                ;;
            --with-ffmpeg)
                if [ "$#" -gt 1 ]; then
                    FFMPEG_PREFIX=$(python -c "import os,sys; print os.path.realpath(sys.argv[1])" "$2")
                    shift 2
                    continue
                else
                    echo 'ERROR: Must specify a non-empty "--with-ffmpeg PREFIX" argument.' >&2
                    exit 1
                fi
                ;;
            --with-opus)
                if [ "$#" -gt 1 ]; then
                    OPUS_PREFIX=$(python -c "import os,sys; print os.path.realpath(sys.argv[1])" "$2")
                    shift 2
                    continue
                else
                    echo 'ERROR: Must specify a non-empty "--with-opus PREFIX" argument.' >&2
                    exit 1
                fi
                ;;
        esac
    
        shift
    done
    
    function config_site() {
        SOURCE_DIR=$1
        PJSIP_CONFIG_PATH="${SOURCE_DIR}/pjlib/include/pj/config_site.h"
        HAS_VIDEO=
    
        echo "Creating config_site.h ..."
    
        if [ -f "${PJSIP_CONFIG_PATH}" ]; then
            rm "${PJSIP_CONFIG_PATH}"
        fi
    
        echo "#define PJ_CONFIG_IPHONE 1" >> "${PJSIP_CONFIG_PATH}"
        echo "#define PJ_HAS_IPV6 1" >> "${PJSIP_CONFIG_PATH}" # Enable IPV6
        if [[ ${OPENH264_PREFIX} ]]; then
            # echo "#define PJMEDIA_HAS_VID_TOOLBOX_CODEC 1" >> "${PJSIP_CONFIG_PATH}"
            # echo "#define PJMEDIA_HAS_OPENH264_CODEC 1" >> "${PJSIP_CONFIG_PATH}"
            echo "#define PJMEDIA_HAS_FFMPEG_VID_CODEC 1" >> "${PJSIP_CONFIG_PATH}"
            HAS_VIDEO=1
        fi
        if [[ ${HAS_VIDEO} ]]; then
            echo "#define PJMEDIA_HAS_VIDEO 1" >> "${PJSIP_CONFIG_PATH}"
            echo "#define PJMEDIA_VIDEO_DEV_HAS_OPENGL 1" >> "${PJSIP_CONFIG_PATH}"
            echo "#define PJMEDIA_VIDEO_DEV_HAS_OPENGL_ES 1" >> "${PJSIP_CONFIG_PATH}"
            echo "#define PJMEDIA_VIDEO_DEV_HAS_IOS_OPENGL 1" >> "${PJSIP_CONFIG_PATH}"
            echo "#include ES3/glext.h>" >> "${PJSIP_CONFIG_PATH}"
        fi
        echo "#include config_site_sample.h>" >> "${PJSIP_CONFIG_PATH}"
    }
    
    function clean_libs () {
        ARCH=${1}
        for SRC_DIR in ${LIB_PATHS[*]}; do
            DIR="${PJSIP_DIR}/${SRC_DIR}"
            if [ -d "${DIR}" ]; then
                rm -rf "${DIR}"/*
            fi
    
            DIR="${PJSIP_DIR}/${SRC_DIR}-${ARCH}"
            if [ -d "${DIR}" ]; then
                rm -rf "${DIR}"
            fi
        done
    }
    
    function copy_libs () {
        ARCH=${1}
    
        for SRC_DIR in ${LIB_PATHS[*]}; do
            SRC_DIR="${PJSIP_DIR}/${SRC_DIR}"
            DST_DIR="${SRC_DIR}-${ARCH}"
            if [ -d "${DST_DIR}" ]; then
                rm -rf "${DST_DIR}"
            fi
            cp -R "${SRC_DIR}" "${DST_DIR}"
            rm -rf "${SRC_DIR}"/* # delete files because this directory will be used for the final lipo output
        done
    }
    
    function _build() {
        pushd . > /dev/null
        cd ${PJSIP_DIR}
    
        ARCH=$1
        LOG=${BASE_DIR}/${ARCH}.log
    
        # configure
        CONFIGURE="./configure-iphone"
        if [[ ${OPENSSL_PREFIX} ]]; then
            CONFIGURE="${CONFIGURE} --with-ssl=${OPENSSL_PREFIX}"
        fi
        # if [[ ${OPENH264_PREFIX} ]]; then
        #     CONFIGURE="${CONFIGURE} --with-openh264=${OPENH264_PREFIX}"
        # fi
        if [[ ${FFMPEG_PREFIX} ]]; then
            CONFIGURE="${CONFIGURE} --with-ffmpeg=${FFMPEG_PREFIX}"
        fi
        if [[ ${OPUS_PREFIX} ]]; then
            CONFIGURE="${CONFIGURE} --with-opus=${OPUS_PREFIX}"
        fi
    
        # flags
        if [[ ! ${CFLAGS} ]]; then
            export CFLAGS=
        fi
        if [[ ! ${LDFLAGS} ]]; then
            export LDFLAGS=
        fi
        if [[ ${OPENSSL_PREFIX} ]]; then
            export CFLAGS="${CFLAGS} -I${OPENSSL_PREFIX}/include"
            export LDFLAGS="${LDFLAGS} -L${OPENSSL_PREFIX}/lib"
        fi
        # if [[ ${OPENH264_PREFIX} ]]; then
        #     export CFLAGS="${CFLAGS} -I${OPENH264_PREFIX}/include"
        #     export LDFLAGS="${LDFLAGS} -L${OPENH264_PREFIX}/lib"
        # fi
        if [[ ${FFMPEG_PREFIX} ]]; then
            export CFLAGS="${CFLAGS} -I${FFMPEG_PREFIX}/include"
            export LDFLAGS="${LDFLAGS} -L${FFMPEG_PREFIX}/lib"
        fi
        export LDFLAGS="${LDFLAGS} -lstdc++"
    
        echo "Building for ${ARCH}..."
    
        clean_libs ${ARCH}
    
        make distclean > ${LOG} 2>&1
        ARCH="-arch ${ARCH}" ${CONFIGURE} >> ${LOG} 2>&1
        make dep >> ${LOG} 2>&1
        make clean >> ${LOG}
        make lib >> ${LOG} 2>&1
    
        copy_libs ${ARCH}
    }
    
    # function armv7() {
    #     export DEVPATH="`xcrun -sdk iphoneos --show-sdk-platform-path`/Developer"
    #     export CFLAGS="-miphoneos-version-min=8.0"
    #     export LDFLAGS=
    #     _build "armv7"
    # }
    # function armv7s() {
    #     export DEVPATH="`xcrun -sdk iphoneos --show-sdk-platform-path`/Developer"
    #     export CFLAGS="-miphoneos-version-min=8.0"
    #     export LDFLAGS=
    #     _build "armv7s"
    # }
    function arm64() {
        export DEVPATH="`xcrun -sdk iphoneos --show-sdk-platform-path`/Developer"
        export CFLAGS="-miphoneos-version-min=8.0"
        export LDFLAGS=
        _build "arm64"
    }
    function i386() {
        export DEVPATH="`xcrun -sdk iphonesimulator --show-sdk-platform-path`/Developer"
        export CFLAGS="-O2 -m32 -mios-simulator-version-min=8.0"
        export LDFLAGS="-O2 -m32 -mios-simulator-version-min=8.0"
        _build "i386"
    }
    function x86_64() {
        export DEVPATH="`xcrun -sdk iphonesimulator --show-sdk-platform-path`/Developer"
        export CFLAGS="-O2 -m32 -mios-simulator-version-min=8.0"
        export LDFLAGS="-O2 -m32 -mios-simulator-version-min=8.0"
        _build "x86_64"
    }
    
    function lipo() {
        TMP=`mktemp -t lipo`
        echo "Lipo libs... (${TMP})"
    
        for LIB_DIR in ${LIB_PATHS[*]}; do # loop over libs
            DST_DIR="${PJSIP_DIR}/${LIB_DIR}"
    
            # use the first architecture to find all libraries
            PATTERN_DIR="${DST_DIR}-$1"
            for PATTERN_FILE in `ls -l1 "${PATTERN_DIR}"`; do
                OPTIONS=""
    
                # loop over all architectures and collect the current library
                for ARCH in "$@"; do
                    FILE="${DST_DIR}-${ARCH}/${PATTERN_FILE/-$1-/-${ARCH}-}"
                    if [ -e "${FILE}" ]; then
                        OPTIONS="$OPTIONS -arch ${ARCH} ${FILE}"
                    fi
                done
    
                if [ "$OPTIONS" != "" ]; then
                    OUTPUT_PREFIX=$(dirname "${DST_DIR}")
                    OUTPUT="${OUTPUT_PREFIX}/lib/${PATTERN_FILE/-$1-/-}"
    
                    OPTIONS="${OPTIONS} -create -output ${OUTPUT}"
                    echo "$OPTIONS" >> "${TMP}"
                fi
            done
        done
    
        while read LINE; do
            xcrun -sdk iphoneos lipo ${LINE}
        done < "${TMP}"
    }
    
    # download "${PJSIP_URL}" "${PJSIP_DIR}"
    config_site "${PJSIP_DIR}"
    arm64 && i386 && x86_64
    lipo arm64 i386 x86_64
    

    Thanks for any advice.

  • Generating all P frame intra refresh H264 with x264

    3 février 2021, par Andrew

    I am trying to generate a periodic intra refresh h264 stream with only P frames using ffmpeg and x264 but I always get an I frame at the start.

    Is there a way with x264 to create a P frame only stream?

    Commands I am using:

    ffmpeg -f lavfi -re -i testsrc=duration=5:size=1920x1080:rate=30000/1001 -s 1920x1080 -pix_fmt yuv420p -f rawvideo out.yuv
    x264 --input-res 1920x1080 --intra-refresh out.yuv --b-pyramid none -b 0 --ref 0  -o out.264
    

    Verification:

        ffprobe -show_frames out.264 |grep pict_type=I
    

    Or just looking at the x264 output e.g.

    yuv [info]: 1920x1080p 0:0 @ 25/1 fps (cfr)
    x264 [info]: using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
    x264 [info]: profile High, level 4.0, 4:2:0, 8-bit
    x264 [info]: frame I:1     Avg QP:13.63  size: 12189
    x264 [info]: frame P:149   Avg QP:13.59  size:   874
    x264 [info]: mb I  I16..4: 78.7% 18.6%  2.7%
    x264 [info]: mb P  I16..4:  2.3%  0.1%  0.0%  P16..4:  3.2%  0.3%  0.0%  0.0%  0.0%    skip:94.1%
    x264 [info]: 8x8 transform intra:7.6% inter:91.5%
    x264 [info]: coded y,uvDC,uvAC intra: 1.3% 18.9% 3.6% inter: 0.1% 1.1% 0.1%
    x264 [info]: i16 v,h,dc,p: 86%  6%  1%  7%
    x264 [info]: i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 42% 22% 36%  0%  0%  0%  0%  0%  0%
    x264 [info]: i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 29% 30% 32%  3%  1%  3%  0%  3%  0%
    x264 [info]: i8c dc,h,v,p: 28%  7% 55%  9%
    x264 [info]: Weighted P-Frames: Y:0.0% UV:0.0%
    x264 [info]: kb/s:189.96
    
    encoded 150 frames, 66.76 fps, 189.96 kb/s
    
  • Proper use of `nalu_process` callback in x264

    26 janvier 2021, par gspr

    I wish to make use of libx264's low-latency encoding mechanism, whereby a user-provided callback is called as soon as a single NAL unit is available instead of having to wait for a whole frame to be encoded before starting processing.

    The x264 documentation states the following about that facility:

    /* Optional low-level callback for low-latency encoding.  Called for each output NAL unit
     * immediately after the NAL unit is finished encoding.  This allows the calling application
     * to begin processing video data (e.g. by sending packets over a network) before the frame
     * is done encoding.
     *
     * This callback MUST do the following in order to work correctly:
     * 1) Have available an output buffer of at least size nal->i_payload*3/2 + 5 + 64.
     * 2) Call x264_nal_encode( h, dst, nal ), where dst is the output buffer.
     * After these steps, the content of nal is valid and can be used in the same way as if
     * the NAL unit were output by x264_encoder_encode.
     *
     * This does not need to be synchronous with the encoding process: the data pointed to
     * by nal (both before and after x264_nal_encode) will remain valid until the next
     * x264_encoder_encode call.  The callback must be re-entrant.
     *
     * This callback does not work with frame-based threads; threads must be disabled
     * or sliced-threads enabled.  This callback also does not work as one would expect
     * with HRD -- since the buffering period SEI cannot be calculated until the frame
     * is finished encoding, it will not be sent via this callback.
     *
     * Note also that the NALs are not necessarily returned in order when sliced threads is
     * enabled.  Accordingly, the variable i_first_mb and i_last_mb are available in
     * x264_nal_t to help the calling application reorder the slices if necessary.
     *
     * When this callback is enabled, x264_encoder_encode does not return valid NALs;
     * the calling application is expected to acquire all output NALs through the callback.
     *
     * It is generally sensible to combine this callback with a use of slice-max-mbs or
     * slice-max-size.
     *
     * The opaque pointer is the opaque pointer from the input frame associated with this
     * NAL unit. This helps distinguish between nalu_process calls from different sources,
     * e.g. if doing multiple encodes in one process.
     */
    void (*nalu_process)( x264_t *h, x264_nal_t *nal, void *opaque );
    

    This seems straight forward enough. However, when I run the following dummy code, I get a segfault on the marked line. I've tried to add some debugging to x264_nal_encode itself to understand where it goes wrong, but it seems to be the function call itself that results in a segfault. Am I missing something here? (Let's ignore the fact that the use of assert probably makes cb non-reentrant – it's only there to indicate to the reader that my workspace buffer is more than large enough.)

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #define WS_SIZE 10000000
    uint8_t * workspace;
    
    void cb(x264_t * h, x264_nal_t * nal, void * opaque)
    {
      assert((nal->i_payload*3)/2 + 5 + 64 < WS_SIZE);
      x264_nal_encode(h, workspace, nal); // Segfault here.
      // Removed: Process nal.
    }
    
    int main(int argc, char ** argv)
    {
      uint8_t * fake_frame = malloc(1280*720*3);
      memset(fake_frame, 0, 1280*720*3);
    
      workspace = malloc(WS_SIZE);
    
      x264_param_t param;
      int status = x264_param_default_preset(&param, "ultrafast", "zerolatency");
      assert(status == 0);
    
      param.i_csp = X264_CSP_RGB;
      param.i_width = 1280;
      param.i_height = 720;
      param.i_threads = 1;
      param.i_lookahead_threads = 1;
      param.i_frame_total = 0;
      param.i_fps_num = 30;
      param.i_fps_den = 1;
      param.i_slice_max_size = 1024;
      param.b_annexb = 1;
      param.nalu_process = cb;
    
      status = x264_param_apply_profile(&param, "high444");
      assert(status == 0);
    
      x264_t * h = x264_encoder_open(&param);
      assert(h);
    
      x264_picture_t pic;
      status = x264_picture_alloc(&pic, param.i_csp, param.i_width, param.i_height);
      assert(pic.img.i_plane == 1);
    
      x264_picture_t pic_out;
      x264_nal_t * nal; // Not used. We process NALs in cb.
      int i_nal;
    
      for (int i = 0; i < 100; ++i)
      {
        pic.i_pts = i;
        pic.img.plane[0] = fake_frame;
        status = x264_encoder_encode(h, &nal, &i_nal, &pic, &pic_out);
      }
    
      x264_encoder_close(h);
      x264_picture_clean(&pic);
      free(workspace);
      free(fake_frame);
      return 0;
    }
    

    Edit: The segfault happens the first time cb calls x264_nal_encode. If I switch to a different preset, where more frames are encoded before the first callback happens, then several successful calls to x264_encoder_encode are made before the first callback, and hence segfault, occurs.

  • how to trim video in h264 format using ffmpeg while preserving quality ?

    16 décembre 2020, par prisonmike11

    I'm new to ffmpeg,

    I'm trimming a small clip from a bluray H264 video by providing start and end duration.

    I tried:

    ffmpeg -ss 00:01:00 -i input.mp4 -to 00:02:00 -c copy output.mp4
    

    but this results in stuttering issues in start of the video. The audio and video also don't match.

    I tried using -c libx264 but this is taking too long and the output video has much lower bit rate.

    My goal is to trim as fast as possible while preserving quality. I don't care about the frame accuracy of the trim. I plan on uploading the output to youtube.

    what flags should I use?

  • Unknown decoder 'libx264'

    29 octobre 2020, par Reboot_My_Computer

    I have ffmpeg with libx264 enabled from BtbN for Windows 10. This is the command:

    ffmpeg -f gdigrab -c:v libx264 -framerate 30 -i title="FiveM" -f flv rtmp://MYSITE.COM/stream/MYSECRETKEY
    

    Unfortunately I get this output:

    Unknown decoder 'libx264'