Ubuntu 16.04.5下FFmpeg编译与开发环境搭建
PC环境: Ubuntu 18.04 上面只要安装下面的提示安装即可,基本上不必再下载依赖库的源代码进行编译和安装
编译步骤:
1, 安装相关工具:
- sudo apt install -y autoconf automake build-essential git libass-dev libfreetype6-dev libsdl2-dev libtheora-dev libtool libva-dev libvdpau-dev libvorbis-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev pkg-config texinfo wget zlib1g-dev
- sudo apt install -y nasm yasm cmake mercurial
2,git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg,得到文件夹ffmpeg,进入ffmpeg文件夹:
- ./configure --enable-shared --prefix=/usr/local/ffmpeg
安装到/usr/local/ffmpeg下,可通过“--prefix=安装目录”进行修改。--enable-shared:指定生成动态库,默认是静态库。静态库不方便后续开发。
2.sudo make
3.sudo make install
3,添加ffmpeg库的链接:
在/etc/ld.so.conf中 末尾添加 /usr/local/ffmpeg/lib 即可,执行
- sudo ldconfig
4.安装VS Code
参考https://blog.csdn.net/u011258217/article/details/78693564
--------------------------------------------------- ubuntu 16.04.5 下还需要按照一下提示进行安装依赖 -------------------------------------
sudo apt-get update
sudo apt-get -y --force-yes install autoconf automake build-essential libass-dev libfreetype6-dev \
libsdl1.2-dev libtheora-dev libtool libva-dev libvdpau-dev libvorbis-dev libxcb1-dev libxcb-shm0-dev \
libxcb-xfixes0-dev pkg-config texi2html zlib1g-dev
2、建立安装包的源文件夹
mkdir ~/ffmpeg_sources
sudo apt install yasm libx264-dev libx265-dev libfdk-aac-dev libmp3lame-dev libopus-dev libvpx-dev -y
cd ~/ffmpeg_sources
wget http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz
tar xzvf yasm-1.3.0.tar.gz
cd yasm-1.3.0
./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin"
make
make install
make distclean
4、libx264
cd ~/ffmpeg_sources
wget http://download.videolan.org/pub/x264/snapshots/last_x264.tar.bz2
tar xjvf last_x264.tar.bz2
cd x264-snapshot*
PATH="$HOME/bin:$PATH" ./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" --enable-static
PATH="$HOME/bin:$PATH" make
make install
make distclean
问题:不知道是不是环境变量的关系,很多标准command不能用,参考另一个笔记:linux下提示bash:command not found
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
5、libx265
265的源一直没下载下来,也暂时不用x265,所以没有安装,后续编译ffmpeg不编译x265就可以。
6、libfdk-aac
cd ~/ffmpeg_sources
wget -O fdk-aac.tar.gz https://github.com/mstorsjo/fdk-aac/tarball/master
git clone https://github.com/mstorsjo/fdk-aac.git https://github.com/mstorsjo/fdk-aac/archive/master.zip tar xzvf fdk-aac.tar.gz
cd mstorsjo-fdk-aac*
autoreconf -fiv
./configure --prefix="$HOME/ffmpeg_build" --disable-shared
make
make install
make distclean
7、libmp3lame
sudo apt-get install nasm
cd ~/ffmpeg_sources
wget http://downloads.sourceforge.net/project/lame/lame/3.99/lame-3.99.5.tar.gz
tar xzvf lame-3.99.5.tar.gz
cd lame-3.99.5
./configure --prefix="$HOME/ffmpeg_build" --enable-nasm --disable-shared
make
make install
make distclean
8、libopus
cd ~/ffmpeg_sources
wget http://downloads.xiph.org/releases/opus/opus-1.1.tar.gz
tar xzvf opus-1.1.tar.gz
cd opus-1.1
./configure --prefix="$HOME/ffmpeg_build" --disable-shared
make
make install
make distclean
9、libvpx
cd ~/ffmpeg_sources
wget http://webm.googlecode.com/files/libvpx-v1.3.0.tar.bz2 ## !!!!! 这个应该下不下来,可以百度一下替代, 换上最新版本的,不要用这个,有点太低了。
http://ftp.osuosl.org/pub/blfs/conglomeration/libvpx/
wget -c http://ftp.osuosl.org/pub/blfs/conglomeration/libvpx/libvpx-1.7.0.tar.gz
tar xjvf libvpx-v1.3.0.tar.bz2
cd libvpx-v1.3.0
PATH="$HOME/bin:$PATH" ./configure --prefix="$HOME/ffmpeg_build" --disable-examples --disable-unit-tests
PATH="$HOME/bin:$PATH" make
make install
make clean ## 下面的这个不必了,直接上github上下载源码即可, https://github.com/FFmpeg/FFmpeg.git
安装编译ffmpeg
cd ~/ffmpeg_sources
wget http://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2
tar xjvf ffmpeg-snapshot.tar.bz2
cd ffmpeg
PATH="$HOME/bin:$PATH" PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure \
--prefix="$HOME/ffmpeg_build" \
--pkg-config-flags="--static" \
--extra-cflags="-I$HOME/ffmpeg_build/include" \
--extra-ldflags="-L$HOME/ffmpeg_build/lib" \
--bindir="$HOME/bin" \
--enable-gpl \
--enable-libass \
--enable-libfdk-aac \
--enable-libfreetype \
--enable-libmp3lame \
--enable-libopus \
--enable-libtheora \
--enable-libvorbis \
--enable-libvpx \
--enable-libx264 \
--enable-libx265 \
--enable-nonfree
PATH="$HOME/bin:$PATH" make
make install
make distclean
hash -r
查看ffmpeg是否安装成功,用ffmpeg -version 之后我们就可以使用ffmpeg 将文件转化成ts文件,以备m3u8-segmenter切片,搭建hls流媒体服务器。
另外有参考源代码:
https://github.com/lspbeyond/p264decoder.git
思科家的: https://github.com/cisco/openh264.git
--------------------------------------------------------------------------- 分割线 -------------------------------------------------------------------------
5.测试环境
#include <stdio.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavfilter/avfilter.h> #define dbmsgc(fmt, args ...) printf("cong:%s[%d]: "fmt"\n", __FUNCTION__, __LINE__,##args)
//#define dbmsg(fmt, args ...) printf("cong:%s:%s[%d]: "fmt"\n",__FILE__, __FUNCTION__, __LINE__,##args)
int main(int argc, char **argv)
{
int i=0;
AVFormatContext *pFormatCtx = NULL;
avcodec_register_all();
#if CONFIG_AVDEVICE
avdevice_register_all();
#endif
avfilter_register_all();
av_register_all(); if(avformat_open_input(&pFormatCtx, argv[1], NULL, NULL)!=0)
return -1; // Couldn't open file if(avformat_find_stream_info(pFormatCtx, NULL)<0)
return -1; // Couldn't find stream inform
av_dump_format(pFormatCtx,0, 0, 0); return 0;
}
6..编写Makefile
FFMPEG=/usr/local/ffmpeg
CC=gcc
CFLAGS=-g -I$(FFMPEG)/include
LDFLAGS = -L$(FFMPEG)/lib/ -lswscale -lswresample -lavformat -lavdevice -lavcodec -lavutil -lavfilter -lm
TARGETS=test
all: $(TARGETS)
test:test.c
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -std=c++11 #注意这里的-std=c++11 clean:
rm -rf $(TARGETS)
7.make
8../test
测试代码2:
/*
* Copyright (c) 2015 Ludmila Glinskih
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/ /**
* H264 codec test.
*/ #include "libavutil/adler32.h"
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavutil/imgutils.h" static int video_decode_example(const char *input_filename)
{
AVCodec *codec = NULL;
AVCodecContext *ctx= NULL;
AVCodecParameters *origin_par = NULL;
AVFrame *fr = NULL;
uint8_t *byte_buffer = NULL;
AVPacket pkt;
AVFormatContext *fmt_ctx = NULL;
int number_of_written_bytes;
int video_stream;
int got_frame = 0;
int byte_buffer_size;
int i = 0;
int result;
int end_of_stream = 0; result = avformat_open_input(&fmt_ctx, input_filename, NULL, NULL);
if (result < 0) {
av_log(NULL, AV_LOG_ERROR, "Can't open file\n");
return result;
} result = avformat_find_stream_info(fmt_ctx, NULL);
if (result < 0) {
av_log(NULL, AV_LOG_ERROR, "Can't get stream info\n");
return result;
} video_stream = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
if (video_stream < 0) {
av_log(NULL, AV_LOG_ERROR, "Can't find video stream in input file\n");
return -1;
} origin_par = fmt_ctx->streams[video_stream]->codecpar; codec = avcodec_find_decoder(origin_par->codec_id);
if (!codec) {
av_log(NULL, AV_LOG_ERROR, "Can't find decoder\n");
return -1;
} ctx = avcodec_alloc_context3(codec);
if (!ctx) {
av_log(NULL, AV_LOG_ERROR, "Can't allocate decoder context\n");
return AVERROR(ENOMEM);
} result = avcodec_parameters_to_context(ctx, origin_par);
if (result) {
av_log(NULL, AV_LOG_ERROR, "Can't copy decoder context\n");
return result;
} result = avcodec_open2(ctx, codec, NULL);
if (result < 0) {
av_log(ctx, AV_LOG_ERROR, "Can't open decoder\n");
return result;
} fr = av_frame_alloc();
if (!fr) {
av_log(NULL, AV_LOG_ERROR, "Can't allocate frame\n");
return AVERROR(ENOMEM);
} byte_buffer_size = av_image_get_buffer_size(ctx->pix_fmt, ctx->width, ctx->height, 16);
byte_buffer = av_malloc(byte_buffer_size);
if (!byte_buffer) {
av_log(NULL, AV_LOG_ERROR, "Can't allocate buffer\n");
return AVERROR(ENOMEM);
} printf("#tb %d: %d/%d\n", video_stream, fmt_ctx->streams[video_stream]->time_base.num, fmt_ctx->streams[video_stream]->time_base.den);
i = 0;
av_init_packet(&pkt);
do {
if (!end_of_stream)
if (av_read_frame(fmt_ctx, &pkt) < 0)
end_of_stream = 1;
if (end_of_stream) {
pkt.data = NULL;
pkt.size = 0;
}
if (pkt.stream_index == video_stream || end_of_stream) {
got_frame = 0;
if (pkt.pts == AV_NOPTS_VALUE)
pkt.pts = pkt.dts = i;
result = avcodec_decode_video2(ctx, fr, &got_frame, &pkt);
if (result < 0) {
av_log(NULL, AV_LOG_ERROR, "Error decoding frame\n");
return result;
}
if (got_frame) {
number_of_written_bytes = av_image_copy_to_buffer(byte_buffer, byte_buffer_size,
(const uint8_t* const *)fr->data, (const int*) fr->linesize,
ctx->pix_fmt, ctx->width, ctx->height, 1);
if (number_of_written_bytes < 0) {
av_log(NULL, AV_LOG_ERROR, "Can't copy image to buffer\n");
return number_of_written_bytes;
}
printf("%d, %10"PRId64", %10"PRId64", %8"PRId64", %8d, 0x%08lx\n", video_stream,
fr->pts, fr->pkt_dts, fr->pkt_duration,
number_of_written_bytes, av_adler32_update(0, (const uint8_t*)byte_buffer, number_of_written_bytes));
}
av_packet_unref(&pkt);
av_init_packet(&pkt);
}
i++;
} while (!end_of_stream || got_frame); av_packet_unref(&pkt);
av_frame_free(&fr);
avcodec_close(ctx);
avformat_close_input(&fmt_ctx);
avcodec_free_context(&ctx);
av_freep(&byte_buffer);
return 0;
} int main(int argc, char **argv)
{
if (argc < 2)
{
av_log(NULL, AV_LOG_ERROR, "Incorrect input\n");
return 1;
} if (video_decode_example(argv[1]) != 0)
return 1; return 0;
}
测试代码3:
/*
* Copyright (c) 2015 Ludmila Glinskih
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/ /**
* draw_horiz_band test.
*/ #include "libavutil/adler32.h"
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavutil/imgutils.h" uint8_t *slice_byte_buffer;
uint8_t slice_byte_buffer_size;
int draw_horiz_band_called; static void draw_horiz_band(AVCodecContext *ctx, const AVFrame *fr, int offset[4],
int slice_position, int type, int height)
{
int i;
const AVPixFmtDescriptor *pix_fmt_desc;
int chroma_w, chroma_h;
int shift_slice_position;
int shift_height; draw_horiz_band_called = 1; pix_fmt_desc = av_pix_fmt_desc_get(ctx->pix_fmt);
chroma_w = -((-ctx->width) >> pix_fmt_desc->log2_chroma_w);
chroma_h = -((-height) >> pix_fmt_desc->log2_chroma_h);
shift_slice_position = -((-slice_position) >> pix_fmt_desc->log2_chroma_h);
shift_height = -((-ctx->height) >> pix_fmt_desc->log2_chroma_h); for (i = 0; i < height; i++) {
memcpy(slice_byte_buffer + ctx->width * slice_position + i * ctx->width,
fr->data[0] + offset[0] + i * fr->linesize[0], ctx->width);
}
for (i = 0; i < chroma_h; i++) {
memcpy(slice_byte_buffer + ctx->width * ctx->height + chroma_w * shift_slice_position + i * chroma_w,
fr->data[1] + offset[1] + i * fr->linesize[1], chroma_w);
}
for (i = 0; i < chroma_h; i++) {
memcpy(slice_byte_buffer + ctx->width * ctx->height + chroma_w * shift_height + chroma_w * shift_slice_position + i * chroma_w,
fr->data[2] + offset[2] + i * fr->linesize[2], chroma_w);
}
} static int video_decode(const char *input_filename)
{
AVCodec *codec = NULL;
AVCodecContext *ctx= NULL;
AVCodecParameters *origin_par = NULL;
uint8_t *byte_buffer = NULL;
AVFrame *fr = NULL;
AVPacket pkt;
AVFormatContext *fmt_ctx = NULL;
int number_of_written_bytes;
int video_stream;
int got_frame = 0;
int byte_buffer_size;
int result;
int end_of_stream = 0; draw_horiz_band_called = 0; result = avformat_open_input(&fmt_ctx, input_filename, NULL, NULL);
if (result < 0) {
av_log(NULL, AV_LOG_ERROR, "Can't open file\n");
return result;
} result = avformat_find_stream_info(fmt_ctx, NULL);
if (result < 0) {
av_log(NULL, AV_LOG_ERROR, "Can't get stream info\n");
return result;
} video_stream = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
if (video_stream < 0) {
av_log(NULL, AV_LOG_ERROR, "Can't find video stream in input file\n");
return -1;
} origin_par = fmt_ctx->streams[video_stream]->codecpar; codec = avcodec_find_decoder(origin_par->codec_id);
if (!codec) {
av_log(NULL, AV_LOG_ERROR, "Can't find decoder\n");
return -1;
} ctx = avcodec_alloc_context3(codec);
if (!ctx) {
av_log(NULL, AV_LOG_ERROR, "Can't allocate decoder context\n");
return AVERROR(ENOMEM);
} result = avcodec_parameters_to_context(ctx, origin_par);
if (result) {
av_log(NULL, AV_LOG_ERROR, "Can't copy decoder context\n");
return result;
} ctx->draw_horiz_band = draw_horiz_band;
ctx->thread_count = 1; result = avcodec_open2(ctx, codec, NULL);
if (result < 0) {
av_log(ctx, AV_LOG_ERROR, "Can't open decoder\n");
return result;
} fr = av_frame_alloc();
if (!fr) {
av_log(NULL, AV_LOG_ERROR, "Can't allocate frame\n");
return AVERROR(ENOMEM);
} if (strcmp(codec->name, "flv") && strcmp(codec->name, "mpeg4") && strcmp(codec->name, "huffyuv")) {
av_log(NULL, AV_LOG_ERROR, "Wrong codec\n");
return -1;
} byte_buffer_size = av_image_get_buffer_size(ctx->pix_fmt, ctx->width, ctx->height, 32);
byte_buffer = av_malloc(byte_buffer_size);
if (!byte_buffer) {
av_log(NULL, AV_LOG_ERROR, "Can't allocate buffer\n");
return AVERROR(ENOMEM);
} slice_byte_buffer = av_malloc(byte_buffer_size);
if (!slice_byte_buffer) {
av_log(NULL, AV_LOG_ERROR, "Can't allocate buffer\n");
return AVERROR(ENOMEM);
}
memset(slice_byte_buffer, 0, byte_buffer_size);
slice_byte_buffer_size = byte_buffer_size; av_init_packet(&pkt);
do {
if (!end_of_stream) {
if (av_read_frame(fmt_ctx, &pkt) < 0) {
end_of_stream = 1;
}
}
if (end_of_stream) {
pkt.data = NULL;
pkt.size = 0;
}
if (pkt.stream_index == video_stream || end_of_stream) {
got_frame = 0;
result = avcodec_decode_video2(ctx, fr, &got_frame, &pkt);
if (result < 0) {
av_log(NULL, AV_LOG_ERROR, "Error decoding frame\n");
return result;
}
if (got_frame) {
number_of_written_bytes = av_image_copy_to_buffer(byte_buffer, byte_buffer_size,
(const uint8_t* const *)fr->data, (const int*) fr->linesize,
ctx->pix_fmt, ctx->width, ctx->height, 1);
if (number_of_written_bytes < 0) {
av_log(NULL, AV_LOG_ERROR, "Can't copy image to buffer\n");
return number_of_written_bytes;
}
if (draw_horiz_band_called == 0) {
av_log(NULL, AV_LOG_ERROR, "draw_horiz_band haven't been called!\n");
return -1;
}
if (av_adler32_update(0, (const uint8_t*)byte_buffer, number_of_written_bytes) !=
av_adler32_update(0, (const uint8_t*)slice_byte_buffer, number_of_written_bytes)) {
av_log(NULL, AV_LOG_ERROR, "Decoded frames with and without draw_horiz_band are not the same!\n");
return -1;
}
}
av_packet_unref(&pkt);
av_init_packet(&pkt);
}
} while (!end_of_stream || got_frame); av_packet_unref(&pkt);
av_frame_free(&fr);
avcodec_close(ctx);
avformat_close_input(&fmt_ctx);
avcodec_free_context(&ctx);
av_freep(&byte_buffer);
av_freep(&slice_byte_buffer);
return 0;
} int main(int argc, char **argv)
{
if (argc < 2)
{
av_log(NULL, AV_LOG_ERROR, "Incorrect input: expected %s <name of a video file>\nNote that test works only for huffyuv, flv and mpeg4 decoders\n", argv[0]);
return 1;
} if (video_decode(argv[1]) != 0)
return 1; return 0;
}
本文参考了:
https://blog.csdn.net/wawayu_0/article/details/80564349
https://www.cnblogs.com/candycaicai/p/4689459.html
特此致谢。
Ubuntu 16.04.5下FFmpeg编译与开发环境搭建的更多相关文章
- 配置ubuntu 16.04.1 LTS odoo 10.0开发环境
使用VMware Fusion 8.5.0创建ubuntu 64bit虚拟机:使用ubuntu-16.04.1-desktop-amd64.iso镜像缺省安装ubuntu,用户名odoo,密码1234 ...
- 在Ubuntu 16.04 LTS下编译安装OpenCV 4.1.1
目录 一 安装前的准备 二 编译并安装OpenCV 4.1.1 注:原创不易,转载请务必注明原作者和出处,感谢支持! OpenCV目前(2019-8-1)的最新版本为4.1.1.本文将介绍如何在Ubu ...
- Ubuntu 16.04.4下安装apache服务
Ubuntu 16.04.4下安装apache服务: 一.首先,准备需要的预装环境 需要c++,make,gcc,apr apr-util pcre.(如果后面报错缺少什么组件,可以百度搜方法. ...
- Ubuntu 16.04系统下安装Discuz出现“HTTP ERROR 500”目前无法处理此请求
问题:当我们在Ubuntu 16.04系统下安装Disucz X3时,修改好文件的权限,浏览器输入地址安装时出现如下图所示问题: 问题查询: 在终端输入: tail -f /var/log/apach ...
- FFmpeg开发笔记(三):ffmpeg介绍、windows编译以及开发环境搭建
前言 本篇章是对之前windows环境的补充,之前windows的是无需进行编译的,此篇使用源码进行编译,版本就使用3.4.8. FFmpeg简介 FFmpeg是领先的多媒体框架,能够解码 ...
- mac10.9下eclipse的storm开发环境搭建
--------------------------------------- 博文作者:迦壹 博客地址:http://idoall.org/home.php?mod=space&uid=1& ...
- win10 + VS2010 + OpenCV2.4.10重编译OpenCV开发环境搭建
win10 + VS2010 + OpenCV2.4.10重编译OpenCV开发环境搭建 重编译的优点:能够调试的时候看OpenCV的源码. 重编译要得到的东西:Debug版本号和Release版本号 ...
- 《Node.js入门》CentOS 6.5下Node.js Web开发环境搭建笔记
近期想尝试一下英特尔的基于WebRTC协同通信开发套件,所以须要在本地搭建Node.js Web的开发測试环境. 这里讲的是CentOS 下的搭建方法.使用Windows的小伙伴请參考: <No ...
- Ubuntu 16.04上源码编译和安装pytorch教程,并编写C++ Demo CMakeLists.txt | tutorial to compile and use pytorch on ubuntu 16.04
本文首发于个人博客https://kezunlin.me/post/54e7a3d8/,欢迎阅读最新内容! tutorial to compile and use pytorch on ubuntu ...
随机推荐
- Codeforces Round #503 (by SIS, Div. 2) C. Elections(枚举,暴力)
原文地址 C. Elections time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...
- [BZOJ 4031] 小Z的房间
Link: BZOJ 4031 传送门 Solution: 矩阵树定理的模板题 看完下面两篇文章就会啦: 周冬论文:https://wenku.baidu.com/view/872eb02de2bd9 ...
- MTD
内存技术设备(英语:Memory Technology Device,缩写为 MTD),是Linux系统中设备文件系统的一个类别,主要用于快闪存储器的应用,是一种快闪存储器转换层(Flash Tran ...
- zookeeper 学习笔记2
ephemeral 英[ɪˈfemərəl]美[ɪˈfɛmərəl]adj. 朝生暮死; 短暂的,瞬息的; 朝露; 一年生; ZooKeeper Watcher 机制 集群状态监控示例 为了确保集群能 ...
- IOS提示控件UIActionSheet,UIAlertView
iphone中常用的消息提示控件,就是UIActionSheet和UIAlertView了,在Web开发中,UIActionSheet就像是confirm(),而UIAlertView就像是alert ...
- Java获取运行环境信息
在做视频截取封面的时候用到了ffmpeg.我采用的是通过Java调用bat或sh脚本然后生成图片文件. 在线上使用的是Centos 7.所以程序中需要获取到当前运行环境的信息来选择调用bat命令还是s ...
- ANGULARJS: UNDERSTANDING DIRECTIVE SCOPE
https://www.3pillarglobal.com/insights/angularjs-understanding-directive-scope --------------------- ...
- 转: 由socket的accept说开去
from: http://ticktick.blog.51cto.com/823160/779866 今天与同学争执一个话题:由于socket的accept函数在有客户端连接的时候产生了新的socke ...
- OC第五课
主要内容:字典.集合.数组排序 一.字典 演示样例: name : @" 张三 " .sex:@" 男 " ; age :@" 21 " ; ...
- EffectiveJava(15)强化对象和域的不可变性
概念: 不可变类是其实例不能被修改的类,不可变类比可变类更加易于设计 实现和使用.它们不容易出错,而且更加安全. 优点 1.不可变对象只有创建时状态. 2.不可变对象本质上是线程安全的,它们不要求同步 ...