精华内容
下载资源
问答
  • 这是一个用Ffmpeg进行h265编解码的实例,集成了demux,解码,编码相关的代码。
  • ffmpegH265解码

    2018-08-19 17:49:49
    博客地址: https://blog.csdn.net/g0415shenw/article/details/81839672 使用ffmpeg解析H265
  • 升级后编码器实现了YUV420P像素数据编码H.265码流。 尽管该视频编码器的代码十分简单,但是几乎包含了使用FFMPEG编码一个视频所有必备的API。十分适合FFmpeg的初学者。 工程基于VC2010。 使用了2014.9.16编译的...
  • 基于FFmpegH265编码

    万次阅读 热门讨论 2018-07-02 11:41:45
    H265编码器仍旧采用变换和预测的混合编码方法。输入帧以宏块为单位被编码器处理,首先按照帧内或帧间预测编码的方法进行处理;接着,预测值与当前块相减,相减后得到的残差块经变换、量化后产生一组量化后的变换系数...
    H265编码器仍旧采用变换和预测的混合编码方法。输入帧以宏块为单位被编码器处理,首先按照帧内或帧间预测编码的方法进行处理;接着,预测值与当前块相减,相减后得到的残差块经变换、量化后产生一组量化后的变换系数;最后,这组量化后的变换系数经过熵编码,与解码所需的一些头信息(如预测模式量化参数、运动矢量等)一起组成一个压缩后的码流,经NAL(网络自适应层)供传输和存储用。为了提供进一步预测用的参考图像,编码器必须有重建的功能。为了去除编解码环路中产生的噪声,提高参考帧的图像质量,从而提高图像压缩性能,设置了一个环路滤波器,滤波后的输出即是重建图像,可用作参考图像。
    H265的编解码流程主要功能:
    帧间和帧内预测 (Estimation):图像经过帧内预测和帧间预测后,与原始视频帧进行相减形成预测残差。
    变换(Transform)和反变换 :将图像的时域信号变换为频域的信号,在频域中信号的能量集中在低频区域,并使其码率相对于空间信号有大幅下降。
    量化(Quantization)和反量化 :不降低视觉效果的前提下,保留图像的细节,确定量化参数(QP),减少图像的编码长度。
    环路滤波(Loop Filter) :对块边界处的像素进行滤波以平滑像素值的突变,消除视频图像中的块效应,同时可以达到降低噪音的效果。
    熵编码(Entropy Coding) :利用信息的统计冗余进行数据压缩的无损编码方法。

    FFmpeg编码的流程图
    如下图是基于FFMPEG的H265视频编码器流程图,该编码器实现了YUV420P的像素数据编码为H265(H264,MPEG2,VP8)的压缩编码数据。
    首先用函数avcodec_find_encoder()查找编码器;然后用函数avcodec_alloc_context()申请CODEC,函数avcodec_alloc_frame()申请编码器中的图像帧空间;设置编码器参数,包括宽度、高度等;avcodec_open()打开编码器CODEC;获取图像数据;编码当前图像avcodec_encode_video();写入码流文件;编码完毕后,销毁各种资源,关闭编码器avcodec_close()等。
    (1)av_register_all():注册FFmpeg 的H265编码器。调用了avcodec_register_all(),avcodec_register_all()注册了H265编码器有关的组件:硬件加速器,编码器,Parser,Bitstream Filter等;
    (2)avformat_alloc_output_context2():初始化输出码流的AVFormatContext,获取输出文件的编码格式;
    (3)avio_open():打开输出文件,调用了2个函数:ffurl_open()和ffio_fdopen()。其中ffurl_open()用于初始化URLContext,ffio_fdopen()用于根据URLContext初始化AVIOContext。URLContext中包含的URLProtocol完成了具体的协议读写等工作。AVIOContext则是在URLContext的读写函数外面加上了一层“包装”;
    (4)av_new_stream():创建输出码流的AVStream结构体,为输出文件设置编码所需要的参数和格式;
    (5)avcodec_find_encoder():通过 codec_id查找H265编码器
    HEVC解码器对应的AVCodec结构体ff_hevc_decoder:
    AVCodec ff_hevc_decoder = {
        .name                  = "hevc",
        .long_name             = NULL_IF_CONFIG_SMALL("HEVC (High Efficiency Video Coding)"),
        .type                  = AVMEDIA_TYPE_VIDEO,
        .id                    = AV_CODEC_ID_HEVC,
        .priv_data_size        = sizeof(HEVCContext),
        .priv_class            = &hevc_decoder_class,
        .init                  = hevc_decode_init,
        .close                 = hevc_decode_free,
        .decode                = hevc_decode_frame,
        .flush                 = hevc_decode_flush,
        .update_thread_context = hevc_update_thread_context,
        .init_thread_copy      = hevc_init_thread_copy,
        .capabilities          = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
                                 AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS,
        .caps_internal         = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_EXPORTS_CROPPING,
        .profiles              = NULL_IF_CONFIG_SMALL(ff_hevc_profiles),
        .hw_configs            = (const AVCodecHWConfigInternal*[]) {
    #if CONFIG_HEVC_DXVA2_HWACCEL
                                   HWACCEL_DXVA2(hevc),
    #endif
    #if CONFIG_HEVC_D3D11VA_HWACCEL
                                   HWACCEL_D3D11VA(hevc),
    #endif
    #if CONFIG_HEVC_D3D11VA2_HWACCEL
                                   HWACCEL_D3D11VA2(hevc),
    #endif
    #if CONFIG_HEVC_NVDEC_HWACCEL
                                   HWACCEL_NVDEC(hevc),
    #endif
    #if CONFIG_HEVC_VAAPI_HWACCEL
                                   HWACCEL_VAAPI(hevc),
    #endif
    #if CONFIG_HEVC_VDPAU_HWACCEL
                                   HWACCEL_VDPAU(hevc),
    #endif
    #if CONFIG_HEVC_VIDEOTOOLBOX_HWACCEL
                                   HWACCEL_VIDEOTOOLBOX(hevc),
    #endif
                                   NULL
    (6)avcodec_open2():打开编码器。调用AVCodec的libx265_encode_init()初始化H265解码器 avcodec_open2()函数;
    avcodec_open2() -> libx265_encode_init() -> x265_param_alloc(), x265_param_default_preset(), x265_encoder_open()
    (7)avformat_write_header():写入编码的H265码流的文件头;
    (8)avcodec_encode_video2():编码一帧视频。将AVFrame(存储YUV像素数据)编码为AVPacket(存储H265格式的码流数据)。调用H265编码器的libx265_encode_frame()函数;
    avcodec_encode_video2() -> libx265_encode_frame() -> x265_encoder_encode()
    (9)av_write_frame():将编码后的视频码流写入文件中;
    (10)flush_encoder():输入的像素数据读取完成后调用此函数,用于输出编码器中剩余的AVPacket;
    (11)av_write_trailer():写入编码的H265码流的文件尾;
    (12)close():释放 AVFrame和图片buf,关闭H265编码器,调用AVCodec的libx265_encode_close()函数
    avcodec_close() -> libx265_encode_close() -> x265_param_free(), x265_encoder_close()

    源码
    /**
     * 基于FFmpeg的视频编码器
     * 功能:实现了YUV420像素数据编码为视频码流(H264,H265,MPEG2,VP8)。
     * ffmpeg编码yuv文件的命令:
     * H264:ffmpeg -s cif -i foreman_cif.yuv -vcodec libx264 -level 40 -profile baseline -me_method epzs -qp 23 -i_qfactor 1.0  -g 12 -refs 1 -frames 50 -r 25 output.264 
     * H265:ffmpeg -s cif -foreman_cif.yuv -vcodec libx265  -frames 100  output.265
     */
    
    #include <stdio.h>
    
    #define __STDC_CONSTANT_MACROS
    
    #ifdef _WIN32
    //Windows
    extern "C"
    {
    #include "libavutil/opt.h"
    #include "libavcodec/avcodec.h"
    #include "libavformat/avformat.h"
    };
    #else
    //Linux...
    #ifdef __cplusplus
    extern "C"
    {
    #endif
    #include <libavutil/opt.h>
    #include <libavcodec/avcodec.h>
    #include <libavformat/avformat.h>
    #ifdef __cplusplus
    };
    #endif
    #endif
    
    //H.265码流与YUV输入的帧数不同。经过观察对比其他程序后发现需要调用flush_encoder()将编码器中剩余的视频帧输出。当av_read_frame()循环退出的时候,实际上解码器中可能还包含剩余的几帧数据。
    //因此需要通过“flush_decoder”将这几帧数据输出。“flush_decoder”功能简而言之即直接调用avcodec_decode_video2()获得AVFrame,而不再向解码器传递AVPacket
    int flush_encoder(AVFormatContext *fmt_ctx, unsigned int stream_index){
    	int ret;
    	int got_frame;
    	AVPacket enc_pkt;
    
    	if (!(fmt_ctx->streams[stream_index]->codec->codec->capabilities &
    		CODEC_CAP_DELAY))
    		return 0;
    	while (1) {
    		enc_pkt.data = NULL;
    		enc_pkt.size = 0;
    		av_init_packet(&enc_pkt);
    		ret = avcodec_encode_video2(fmt_ctx->streams[stream_index]->codec, &enc_pkt,
    			NULL, &got_frame);
    		av_frame_free(NULL);
    		if (ret < 0)
    			break;
    		if (!got_frame){
    			ret = 0;
    			break;
    		}
    		printf("Flush Encoder: Succeed to encode 1 frame!\tsize:%5d\n", enc_pkt.size);
    		/* mux encoded frame */
    		ret = av_write_frame(fmt_ctx, &enc_pkt);
    		if (ret < 0)
    			break;
    	}
    	return ret;
    }
    
    int main(int argc, char* argv[])
    {
    	AVFormatContext* pFormatCtx = NULL;
    	AVOutputFormat* fmt;
    	AVStream* video_st;
    	AVCodecContext* pCodecCtx;
    	AVCodec* pCodec;
    	AVPacket pkt;
    	uint8_t* picture_buf;
    	AVFrame* pFrame;
    	int picture_size;
    	int y_size;
    	int framecnt = 0;
    	FILE *in_file = fopen("chezaiyundong_1280x720_30_300.yuv", "rb");
    	int in_w = 1280, in_h = 720;
    	int framenum = 10;
    	const char* out_file = "chezaiyundong_1280x720_30_300.hevc";
    
    	av_register_all();//注册FFmpeg所有编解码器
    	avformat_alloc_output_context2(&pFormatCtx, NULL, NULL, out_file);//初始化输出码流的AVFormatContext(获取输出文件的编码格式)
    	fmt = pFormatCtx->oformat;
    
    	// 打开文件的缓冲区输入输出,flags 标识为  AVIO_FLAG_READ_WRITE ,可读写;将输出文件中的数据读入到程序的 buffer 当中,方便之后的数据写入fwrite
    	if (avio_open(&pFormatCtx->pb, out_file, AVIO_FLAG_READ_WRITE) < 0){
    		printf("Failed to open output file! \n");
    		return -1;
    	}
    	video_st = avformat_new_stream(pFormatCtx, 0);//创建输出码流的AVStream。
    	// 设置 码率25 帧每秒(fps=25)
    	video_st->time_base.num = 1;
    	video_st->time_base.den = 25;
    	if (video_st == NULL){
    		return -1;
    	}
    
    	//为输出文件设置编码的参数和格式
    	pCodecCtx = video_st->codec;// 从媒体流中获取到编码结构体,一个 AVStream 对应一个  AVCodecContext
    	pCodecCtx->codec_id = fmt->video_codec;// 设置编码器的 id,例如 h265 的编码 id 就是 AV_CODEC_ID_H265
    	pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;//编码器视频编码的类型
    	pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;//设置像素格式为 yuv 格式
    	pCodecCtx->width = in_w; //设置视频的宽高
    	pCodecCtx->height = in_h;
    	pCodecCtx->time_base.num = 1;
    	pCodecCtx->time_base.den = 25;
    	pCodecCtx->bit_rate = 400000;  //采样的码率;采样码率越大,视频大小越大
    	pCodecCtx->gop_size = 250;//每250帧插入1个I帧,I帧越少,视频越小
    	pCodecCtx->qmin = 10;最大和最小量化系数 
    	//(函数输出的延时仅仅跟max_b_frames的设置有关,想进行实时编码,将max_b_frames设置为0便没有编码延时了)
    	pCodecCtx->max_b_frames = 3;// 设置 B 帧最大的数量,B帧为视频图片空间的前后预测帧, B 帧相对于 I、P 帧来说,压缩率比较大,采用多编码 B 帧提高清晰度
    
    	//设置编码速度
    	AVDictionary *param = 0;
    	//preset的参数调节编码速度和质量的平衡。
    	//tune的参数值指定片子的类型,是和视觉优化的参数,
    	//zerolatency: 零延迟,用在需要非常低的延迟的情况下,比如电视电话会议的编码
    	if (pCodecCtx->codec_id == AV_CODEC_ID_H264) {
    		av_dict_set(¶m, "preset", "slow", 0);
    		av_dict_set(¶m, "tune", "zerolatency", 0);
    		//av_dict_set(¶m, "profile", "main", 0);
    	}
    	//H.265
    	if (pCodecCtx->codec_id == AV_CODEC_ID_H265){
    		av_dict_set(¶m, "preset", "ultrafast", 0);
    		av_dict_set(¶m, "tune", "zero-latency", 0);
    	}
    
    	//输出格式的信息,例如时间,比特率,数据流,容器,元数据,辅助数据,编码,时间戳
    	av_dump_format(pFormatCtx, 0, out_file, 1);
    
    	pCodec = avcodec_find_encoder(pCodecCtx->codec_id);//查找编码器
    	if (!pCodec){
    		printf("Can not find encoder! \n");
    		return -1;
    	}
    	// 打开编码器,并设置参数 param
    	if (avcodec_open2(pCodecCtx, pCodec, ¶m) < 0){
    		printf("Failed to open encoder! \n");
    		return -1;
    	}
    
    	//设置原始数据 AVFrame
    	pFrame = av_frame_alloc();
    	if (!pFrame) {
    		printf("Could not allocate video frame\n");
    		return -1;
    	}
    	pFrame->format = pCodecCtx->pix_fmt;
    	pFrame->width = pCodecCtx->width;
    	pFrame->height = pCodecCtx->height;
    
    	// 获取YUV像素格式图片的大小
    	picture_size = avpicture_get_size(pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);
    	// 将 picture_size 转换成字节数据
    	picture_buf = (uint8_t *)av_malloc(picture_size);
    	// 设置原始数据 AVFrame 的每一个frame 的图片大小,AVFrame 这里存储着 YUV 非压缩数据
    	avpicture_fill((AVPicture *)pFrame, picture_buf, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);
    	//写封装格式文件头
    	avformat_write_header(pFormatCtx, NULL);
    	//创建编码后的数据 AVPacket 结构体来存储 AVFrame 编码后生成的数据  //编码前:AVFrame  //编码后:AVPacket
    	av_new_packet(&pkt, picture_size);
    	// 设置 yuv 数据中Y亮度图片的宽高,写入数据到 AVFrame 结构体中
    	y_size = pCodecCtx->width * pCodecCtx->height;
    
    	for (int i = 0; i<framenum; i++){
    		//Read raw YUV data
    		if (fread(picture_buf, 1, y_size * 3 / 2, in_file) <= 0){
    			printf("Failed to read raw data! \n");
    			return -1;
    		}
    		else if (feof(in_file)){
    			break;
    		}
    		pFrame->data[0] = picture_buf;              // 亮度Y
    		pFrame->data[1] = picture_buf + y_size;      // U 
    		pFrame->data[2] = picture_buf + y_size * 5 / 4;  // V
    		//顺序显示解码后的视频帧
    		pFrame->pts = i;
    		// 设置这一帧的显示时间
    		//pFrame->pts=i*(video_st->time_base.den)/((video_st->time_base.num)*25);
    		int got_picture = 0;
    		int ret = avcodec_encode_video2(pCodecCtx, &pkt, pFrame, &got_picture);//编码一帧视频。即将AVFrame(存储YUV像素数据)编码为AVPacket(存储H.264等格式的码流数据)
    		if (ret < 0){
    			printf("Failed to encode! \n");
    			return -1;
    		}
    
    		if (got_picture == 1){
    			printf("Succeed to encode frame: %5d\tsize:%5d\n", framecnt, pkt.size);
    			framecnt++;
    			pkt.stream_index = video_st->index;
    			printf("video_st->index = %d\n", video_st->index);
    			av_write_frame(pFormatCtx, &pkt);//将编码后的视频码流写入文件(fwrite)
    			av_free_packet(&pkt);//释放内存
    		}
    	}
    
    	//输出编码器中剩余的AVPacket
    	int ret = flush_encoder(pFormatCtx, 0);
    	if (ret < 0) {
    		printf("Flushing encoder failed\n");
    		return -1;
    	}
    
    	// 写入数据流尾部到输出文件当中,表示结束并释放文件的私有数据
    	av_write_trailer(pFormatCtx);
    
    	if (video_st){
    		// 关闭编码器
    		avcodec_close(video_st->codec);
    		// 释放 AVFrame
    		av_free(pFrame);
    		// 释放图片 buf
    		av_free(picture_buf);
    	}
    	// 关闭输入数据的缓存
    	avio_close(pFormatCtx->pb);
    	// 释放 AVFromatContext 结构体
    	avformat_free_context(pFormatCtx);
    	// 关闭输入文件
    	fclose(in_file);
    
    	return 0;
    }
    
    运行结果
    通过Elecard HEVC Analyzer 1.14,查看HEVC码流中的帧内预测、运动补偿相关的信息:

    展开全文
  • c++使用ffmpegh264/h265和mp3写入mp4文件,内含ffmpeg库、示例demo、视频素材。
  • FFmpeg4.1.4 编码h265编码

    千次阅读 2019-11-11 23:09:44
    FFmpeg1、编码 1、编码 /* * Copyright (c) 2001 Fabrice Bellard * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files...

    1、编码流程

    1、初始化AVFormatContext:avformat_alloc_output_context2(),包含有输出码流(AVStream)和解复用器(AVInputFormat)。
    2、打开输出文件:avio_open()。
    3、初始化AVCodecContext:avcodec_alloc_context3(),包含编码参数信息。
    4、创建视频码流:avformat_new_stream(),该函数生成一个空AVstream 该结构存放编码后的视频码流 。视频码流被拆分为AVPacket新式保存在AVStream中。
    5、拷贝编码参数信息:avcodec_parameters_from_context(),从AVCodecContext到输出流中。
    6、写头信息:avformat_write_header(),将封装格式的信息写入文件头部位置。
    7、查找编码器:avcodec_find_encoder()。
    8、设置编码器信息:AVCodecContext
    码率:bit_rate
    图像格式:pix_fmt
    分辨率:width、height
    帧率:framerate、time_base
    GOP大小:gop_size
    B帧:max_b_frames
    额外设置一些参数(如 h265 要设置qmax、qmin、qcompress参数才能正常使用h264编码)
    9、打开编码器:avcodec_open2(),根据前一步设置的编码器参数信息,来查找初始化一个编码器,并将其打开。
    10、分配AVPacket和AVFrame:av_packet_alloc()和av_frame_alloc()
    11、编码:avcodec_send_frame()和avcodec_receive_packet()。
    12、写入输出文件:av_interleaved_write_frame()。

    2、编码

    /*
     * Copyright (c) 2001 Fabrice Bellard
     *
     * 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.
     */
    
    /**
     * @file
     * video encoding with libavcodec API example
     *
     * @example encode_video.c
     */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #ifdef __cplusplus
    extern "C" {
    #endif // __cplusplus
    
    #include <libavcodec/avcodec.h>
    #include <libavutil/opt.h>
    #include <libavutil/imgutils.h>
    
    #ifdef __cplusplus
    }
    #endif // __cplusplus
    
    static void encode(AVCodecContext *enc_ctx, AVFrame *frame, AVPacket *pkt,
                       FILE *outfile)
    {
        int ret;
    
        /* send the frame to the encoder */
        if (frame)
            printf("Send frame %3"PRId64"\n", frame->pts);
    
        ret = avcodec_send_frame(enc_ctx, frame);
        if (ret < 0) {
            fprintf(stderr, "Error sending a frame for encoding\n");
            exit(1);
        }
    
        while (ret >= 0) {
            ret = avcodec_receive_packet(enc_ctx, pkt);
            if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
                return;
            else if (ret < 0) {
                fprintf(stderr, "Error during encoding\n");
                exit(1);
            }
    
            printf("Write packet %3"PRId64" (size=%5d)\n", pkt->pts, pkt->size);
            fwrite(pkt->data, 1, pkt->size, outfile);
            av_packet_unref(pkt);
        }
    }
    
    int main(int argc, char **argv)
    {
        const char *filename, *codec_name;
        const AVCodec *codec;
        AVCodecContext *c= NULL;
        AVCodecID codec_id = AV_CODEC_ID_HEVC;
        int i, ret, x, y;
        FILE *f;
        AVFrame *frame;
        AVPacket *pkt;
        uint8_t endcode[] = { 0, 0, 1, 0xb7 };
    
        if (argc <= 2) {
            fprintf(stderr, "Usage: %s <output file> <codec name>\n", argv[0]);
            exit(0);
        }
        filename = argv[1];
        codec_name = argv[2];
    
        /* find the mpeg1video encoder */
        codec = avcodec_find_encoder(codec_id);
        if (!codec) {
            fprintf(stderr, "Codec '%s' not found\n", codec_name);
            exit(1);
        }
    
        c = avcodec_alloc_context3(codec);
        if (!c) {
            fprintf(stderr, "Could not allocate video codec context\n");
            exit(1);
        }
    
        pkt = av_packet_alloc();
        if (!pkt)
            exit(1);
    
        /* put sample parameters */
        c->bit_rate = 400000;
        /* resolution must be a multiple of two */
        c->width = 352;
        c->height = 288;
        /* frames per second */
        c->time_base = (AVRational){1, 25};
        c->framerate = (AVRational){25, 1};
    
        /* emit one intra frame every ten frames
         * check frame pict_type before passing frame
         * to encoder, if frame->pict_type is AV_PICTURE_TYPE_I
         * then gop_size is ignored and the output of encoder
         * will always be I frame irrespective to gop_size
         */
        c->gop_size = 10;
        c->max_b_frames = 1;
        c->pix_fmt = AV_PIX_FMT_YUV420P;
    
        if (codec->id == AV_CODEC_ID_H264)
            av_opt_set(c->priv_data, "preset", "slow", 0);
    
        /* open it */
        ret = avcodec_open2(c, codec, NULL);
        if (ret < 0) {
            fprintf(stderr, "Could not open codec: %s\n", av_err2str(ret));
            exit(1);
        }
    
        f = fopen(filename, "wb");
        if (!f) {
            fprintf(stderr, "Could not open %s\n", filename);
            exit(1);
        }
    
        frame = av_frame_alloc();
        if (!frame) {
            fprintf(stderr, "Could not allocate video frame\n");
            exit(1);
        }
        frame->format = c->pix_fmt;
        frame->width  = c->width;
        frame->height = c->height;
    
        ret = av_frame_get_buffer(frame, 32);
        if (ret < 0) {
            fprintf(stderr, "Could not allocate the video frame data\n");
            exit(1);
        }
    
        /* encode 1 second of video */
        for (i = 0; i < 25; i++) {
            fflush(stdout);
    
            /* make sure the frame data is writable */
            ret = av_frame_make_writable(frame);
            if (ret < 0)
                exit(1);
    
            /* prepare a dummy image */
            /* Y */
            for (y = 0; y < c->height; y++) {
                for (x = 0; x < c->width; x++) {
                    frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
                }
            }
    
            /* Cb and Cr */
            for (y = 0; y < c->height/2; y++) {
                for (x = 0; x < c->width/2; x++) {
                    frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2;
                    frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5;
                }
            }
    
            frame->pts = i;
    
            /* encode the image */
            encode(c, frame, pkt, f);
        }
    
        /* flush the encoder */
        encode(c, NULL, pkt, f);
    
        /* add sequence end code to have a real MPEG file */
        fwrite(endcode, 1, sizeof(endcode), f);
        fclose(f);
    
        avcodec_free_context(&c);
        av_frame_free(&frame);
        av_packet_free(&pkt);
    
        return 0;
    }
    
    
    展开全文
  • demo_ffmpeg_h265.py

    2020-02-15 13:53:33
    本Demo基于Python调用ffmpeg4.2.2指令,执行流程如下 1.视频流抽帧 2.打开ffmpeg指令管道 3.实时进行RTP/RTMP推流(支持h264/h265编码
  • ffmpeg.exe支持对H265的RTMP推流,FLV复用. ffplay.exe可播放有H265的RTMP流和包含H265的FLV文件的播放
  • ffmpeg3.4.8_rtmp_h265.zip

    2020-11-18 11:26:01
    在jetson agx xavier上编译好的ffmpeg共享库文件,包含bin、include、lib、share文件。支持该编译平台的rtmp_h265拉流,推流。
  • ffmpeg h264编码

    热门讨论 2013-01-08 14:44:38
    带有编译好的ffmpeg动态链接库,及相应头文件,在VS2008下可以直接编译成功,并编码YUV文件 找了很久的好资源!
  • ffmpeg 编码H265H264对比

    万次阅读 2015-08-05 14:34:00
    --------编译 FFMPEG with h265-------- 1.安装 hg tool #yum install hg 2.下载 x265 source code 并 make #hg clone https://bitbucket.org/multicoreware/x265 #cd x265/build/lin

    OS:CentOS6.4-64bit

    --------编译 FFMPEG with h265--------

    1.安装 hg tool

    #yum install hg

    2.下载 x265 source code 并 make

    #hg clone https://bitbucket.org/multicoreware/x265

    #cd x265/build/linux

    #make

    #make install

    3.下载  x264 and ffmpeg source 并 make

    请参考我之前的一篇博客:

    使用Nginx+FFMPEG搭建HLS直播转码服务器 (http://blog.csdn.net/wutong_login/article/details/42292787)

    4.编译支持h265的 FFMPEG

    #PKG_CONFIG_PATH=/usr/local/lib/pkgconfig ./configure  --prefix=/opt/ffmpeg/ --enable-version3  --enable-libvpx --enable-libfaac --enable-libmp3lame  --enable-libvorbis --enable-libx264 --enable-libxvid --enable-shared --enable-gpl --enable-postproc --enable-nonfree  --enable-avfilter --enable-pthreads --enable-libx265

    #make

    #make install

    #ldd /opt/ffmpeg/bin/ffmpeg

    note: if libx265.so.40 is not found please cp it from /usr/local/lib to /usr/lib64

    --------compare h265 and h264--------

    1.编码264和265

    从网上找一段YUV文件,或者使用FFMPEG解码一个也可以,我使用的720P的,分别编码500Kbps。

    /opt/ffmpeg/bin/ffmpeg -s 1280*720 -i /home/edward/media/720-new.yuv -vcodec libx264 -b:v 2000k /home/edward/media/720-new-264.ts

    /opt/ffmpeg/bin/ffmpeg -s 1280*720 -i /home/edward/media/720-new.yuv -vcodec libx265 -b:v 2000k /home/edward/media/720-new-265.ts

    再解码为YUV数据:

    /opt/ffmpeg/bin/ffmpeg -i /home/edward/media/720-new-264.ts /home/edward/media/720-new-264.yuv

    /opt/ffmpeg/bin/ffmpeg -i /home/edward/media/720-new-265.ts /home/edward/media/720-new-265.yuv


    任意找一帧进行比较:

    源图:

    265:

    264:

    我们可以看到,264编码500k的情况下,图中红框中的几个数字,基本已经看不清了。


    展开全文
  • FFMPEG H264/H265 编码延迟问题

    千次阅读 2020-12-24 10:41:54
    最新使用FFmpeg进行H264的编码时,发现视频编码有延迟,不是实时编码。进过一番研究发现,仅仅要在调用avcodec_open2函数打开编码器时,设置AVDictionary參数就可以。关键代码例如以下:avcodec_open2函数:int ...

    最新使用FFmpeg进行H264的编码时,发现视频编码有延迟,不是实时编码。进过一番研究发现,仅仅要在调用avcodec_open2函数

    打开编码器时,设置AVDictionary參数就可以。关键代码例如以下:

    avcodec_open2函数:

    int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);

    解决方式:

    AVDictionary *param = NULL;

    //H264, 设置为编码延迟为马上编码

    if(c->codec_id == AV_CODEC_ID_H264)

    {

    av_dict_set(¶m, "preset", "superfast", 0);

    av_dict_set(¶m, "tune", "zerolatency", 0);

    }

    //H.265

    if(c->codec_id == AV_CODEC_ID_H265)

    {

    av_dict_set(¶m, "x265-params", "qp=20", 0);

    av_dict_set(¶m, "preset", "ultrafast", 0);

    av_dict_set(¶m, "tune", "zero-latency", 0);

    }

    //使用给定的AVCodec初始化AVCodecContext

    ret = avcodec_open2(參数, 參数, ¶m);

    展开全文
  • ffmpeg转换h265编码视频到h264编码

    千次阅读 2021-03-17 15:54:34
    ffmpeg -i inputfile -map 0 -c:a copy -c:s copy -c:v libx264 output.mkv
  • 基于ffmpeg和live555开发的rtsp服务器,支持h264/h265编码,支持mp4等格式。测试文件放在执行文件当前目录,URL格式为:rtsp://ip:port/filename
  • H265编码解码/推流

    2018-09-20 16:03:26
    随着高清显示设备的发展和高清数字视频内容的日益增多,人们对于视频观看体验的要求也越来越高。新一代视频编码技术H.265/HEVC应运而生,作为新一代视频编码技术
  • 1、编译x264 ...cd x264 ./configure --enable-shared --enable-static --disable-asm ...x264, the best H.264/AVC encoder - VideoLAN 2、编译x265 hg clone http://hg.videolan.org/x265 cd x265/buil.
  • FFmpeg h264转h265命令(九)

    千次阅读 2020-09-11 11:15:45
    1.裸流之间的转换 # ffmpeg -i test.h264 test.hevc 2.MO4封装h264转换到h265 # ffmpeg -i input.mp4 -c:v libx265 output.mp4
  • Linux实现ffmpeg H.265视频编码 几乎所有观看的视频,数字地面电视,电缆,卫星或互联网上的压缩。原始的,未压缩的视频太大,会浪费太多的带宽。在DVD和Blu-ray之前,有视频CD(VCD)。这是用于在标准120mm(4.7...
  • 该代码通过调用ffmpeg实现了视频的编码编码为封装的类,代码是跨库平台的,同时支持windows和linux 2.在windows下使用说明: 从ffmpeg官网下载win64-dev版本,它包含开发使用的lib和include;下载win64-share版本...
  • 学习ffmpeg有一段时间了,由于身边没有人可以请教,所有基本上都是出了问题就上网查资料。到现在勉强能完成工作任务了。
  • 硬件NVIDIA:ffmpeg.exe -i...软件 :ffmpeg.exe -i input.avi[-c:a copy] -c:v libx265 output.mp4 i7 6700 8G GTX960 Windows 10 H264: ffmpeg -i source.mp4 -c:v libx264 -crf 24 -deinterlace destin...
  • ffmpeg h264硬编码插件

    2014-06-22 19:04:04
    基于i.mx soc芯片编写的最新版本的ffmpeg下的h264硬件编码插件,里面含有编译脚本
  • 实践介绍视频技术:图像、视频、编解码器(av1、h264 h265)和(ffmpeg编码)
  • FFMPEG框架+硬件加速实现H.265编码
  • 但是我们当前大部分直播平台还是使用rtmp来推流,又想使用使用H265/Hevc来编码视频数据,怎么办呢,只能修改ffmpeg的flv解复用的相关部分代码。 先来看看使用原版的ffplay来拉H265的rtmp流,是一个什么样的效果: ...
  • 此程序和上一篇YUN编码H264类似,仅仅是修改几个参数 程序源码 /* * * 本程序实现了YUV像素数据编码为视频码流(H264) * */ #include <stdio.h> #define __STDC_CONSTANT_MACROS extern "C" { #...
  • 具有硬解的能力,但是需要android 4.1以上才能支持。 这个demo主要是测试硬解和软解h265裸流的能力,有一些手机可能不...硬解H265使用的是MediaCodec+ffmpeg方案,ffmepg负责拆包,MediaCodec负责解码和渲染,祝你愉快

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 22,279
精华内容 8,911
关键字:

ffmpegh265编码