多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內(nèi)最全IT社區(qū)平臺 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁 > php開源 > php教程 > 最簡單的基于FFmpeg的編碼器-純凈版(不包含libavformat)

最簡單的基于FFmpeg的編碼器-純凈版(不包含libavformat)

來源:程序員人生   發(fā)布時間:2015-01-04 09:06:54 閱讀次數(shù):4244次

=====================================================

最簡單的基于FFmpeg的視頻編碼器文章列表:

最簡單的基于FFMPEG的視頻編碼器(YUV編碼為H.264)

最簡單的基于FFmpeg的視頻編碼器-更新版(YUV編碼為HEVC(H.265))

最簡單的基于FFmpeg的編碼器-純凈版(不包括libavformat)

=====================================================


本文記錄1個更加“純凈”的基于FFmpeg的視頻編碼器。此前記錄過1個基于FFmpeg的視頻編碼器:

 《最簡單的基于FFmpeg的視頻編碼器-更新版(YUV編碼為HEVC(H.265))》

這個視頻編碼器調(diào)用了FFmpeg中的libavformat和libavcodec兩個庫完成了視頻編碼工作。但是這不是1個“純凈”的編碼器。上述兩個庫中l(wèi)ibavformat完成封裝格式處理,而libavcodec完成編碼工作。1個“純凈”的編碼器,理論上說只需要使用libavcodec就足夠了,其實不需要使用libavformat。本文記錄的編碼器就是這樣的1個“純凈”的編碼器,它僅僅通過調(diào)用libavcodec將YUV數(shù)據(jù)編碼為H.264/HEVC等格式的緊縮視頻碼流。


流程圖

僅使用libavcodec(不使用libavformat)編碼視頻的流程以下圖所示。


流程圖中關(guān)鍵函數(shù)的作用以下所列:

avcodec_register_all():注冊所有的編解碼器。
avcodec_find_encoder():查找編碼器。
avcodec_alloc_context3():為AVCodecContext分配內(nèi)存。
avcodec_open2():打開編碼器。
avcodec_encode_video2():編碼1幀數(shù)據(jù)。

兩個存儲數(shù)據(jù)的結(jié)構(gòu)體以下所列:
AVFrame:存儲1幀未編碼的像素數(shù)據(jù)。
AVPacket:存儲1幀緊縮編碼數(shù)據(jù)。

對照

簡單記錄1下這個只使用libavcodec的“純凈版”視頻編碼器和使用libavcodec+libavformat的視頻編碼器的不同。

PS:使用libavcodec+libavformat的編碼器參考文章 《最簡單的基于FFmpeg的視頻編碼器-更新版(YUV編碼為HEVC(H.265))》

(1) 以下與libavformat相干的函數(shù)在“純凈版”視頻編碼器中都不存在。
av_register_all():注冊所有的編解碼器,復(fù)用/解復(fù)用器等等組件。其中調(diào)用了avcodec_register_all()注冊所有編解碼器相干的組件。
avformat_alloc_context():創(chuàng)建AVFormatContext結(jié)構(gòu)體。
avformat_alloc_output_context2():初始化1個輸出流。
avio_open():打開輸出文件。
avformat_new_stream():創(chuàng)建AVStream結(jié)構(gòu)體。avformat_new_stream()中會調(diào)用avcodec_alloc_context3()創(chuàng)建AVCodecContext結(jié)構(gòu)體。
avformat_write_header():寫文件頭。
av_write_frame():寫編碼后的文件幀。
av_write_trailer():寫文件尾。
(2) 新增了以下幾個函數(shù)
avcodec_register_all():只注冊編解碼器有關(guān)的組件。

avcodec_alloc_context3():創(chuàng)建AVCodecContext結(jié)構(gòu)體。

可以看出,相比于“完全”的編碼器,這個純凈的編碼器函數(shù)調(diào)用更加簡單,功能相對少1些,相對來講更加的“輕量”。


源代碼

/** * 最簡單的基于FFmpeg的視頻編碼器(純凈版) * Simplest FFmpeg Video Encoder Pure * * 雷霄驊 Lei Xiaohua * leixiaohua1020@126.com * 中國傳媒大學(xué)/數(shù)字電視技術(shù) * Communication University of China / Digital TV Technology * http://blog.csdn.net/leixiaohua1020 * * 本程序?qū)崿F(xiàn)了YUV像素數(shù)據(jù)編碼為視頻碼流(H264,MPEG2,VP8等等)。 * 它僅僅使用了libavcodec(而沒有使用libavformat)。 * 是最簡單的FFmpeg視頻編碼方面的教程。 * 通過學(xué)習(xí)本例子可以了解FFmpeg的編碼流程。 * This software encode YUV420P data to video bitstream * (Such as H.264, H.265, VP8, MPEG2 etc). * It only uses libavcodec to encode video (without libavformat) * It's the simplest video encoding software based on FFmpeg. * Suitable for beginner of FFmpeg */ #include <stdio.h> extern "C" { #include "libavutilopt.h" #include "libavcodecavcodec.h" #include "libavutilimgutils.h" }; //test different codec #define TEST_H264 0 #define TEST_HEVC 1 int main(int argc, char* argv[]) { AVCodec *pCodec; AVCodecContext *pCodecCtx= NULL; int i, ret, x, y, got_output; FILE *fp_in; FILE *fp_out; AVFrame *pFrame; AVPacket pkt; int y_size; int framecnt=0; char filename_in[]="../ds_480x272.yuv"; #if TEST_HEVC AVCodecID codec_id=AV_CODEC_ID_HEVC; char filename_out[]="ds.hevc"; #else AVCodecID codec_id=AV_CODEC_ID_H264; char filename_out[]="ds.h264"; #endif int in_w=480,in_h=272; int framenum=100; avcodec_register_all(); pCodec = avcodec_find_encoder(codec_id); if (!pCodec) { printf("Codec not found "); return ⑴; } pCodecCtx = avcodec_alloc_context3(pCodec); if (!pCodecCtx) { printf("Could not allocate video codec context "); return ⑴; } pCodecCtx->bit_rate = 400000; pCodecCtx->width = in_w; pCodecCtx->height = in_h; pCodecCtx->time_base.num=1; pCodecCtx->time_base.den=25; pCodecCtx->gop_size = 10; pCodecCtx->max_b_frames = 1; pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P; if (codec_id == AV_CODEC_ID_H264) av_opt_set(pCodecCtx->priv_data, "preset", "slow", 0); if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) { printf("Could not open codec "); return ⑴; } pFrame = av_frame_alloc(); if (!pFrame) { printf("Could not allocate video frame "); return ⑴; } pFrame->format = pCodecCtx->pix_fmt; pFrame->width = pCodecCtx->width; pFrame->height = pCodecCtx->height; ret = av_image_alloc(pFrame->data, pFrame->linesize, pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, 16); if (ret < 0) { printf("Could not allocate raw picture buffer "); return ⑴; } //Input raw data fp_in = fopen(filename_in, "rb"); if (!fp_in) { printf("Could not open %s ", filename_in); return ⑴; } //Output bitstream fp_out = fopen(filename_out, "wb"); if (!fp_out) { printf("Could not open %s ", filename_out); return ⑴; } y_size = pCodecCtx->width * pCodecCtx->height; //Encode for (i = 0; i < framenum; i++) { av_init_packet(&pkt); pkt.data = NULL; // packet data will be allocated by the encoder pkt.size = 0; //Read raw YUV data if (fread(pFrame->data[0],1,y_size,fp_in)< 0|| // Y fread(pFrame->data[1],1,y_size/4,fp_in)< 0|| // U fread(pFrame->data[2],1,y_size/4,fp_in)< 0){ // V return ⑴; }else if(feof(fp_in)){ break; } pFrame->pts = i; /* encode the image */ ret = avcodec_encode_video2(pCodecCtx, &pkt, pFrame, &got_output); if (ret < 0) { printf("Error encoding frame "); return ⑴; } if (got_output) { printf("Succeed to encode frame: %5d size:%5d ",framecnt,pkt.size); framecnt++; fwrite(pkt.data, 1, pkt.size, fp_out); av_free_packet(&pkt); } } //Flush Encoder for (got_output = 1; got_output; i++) { ret = avcodec_encode_video2(pCodecCtx, &pkt, NULL, &got_output); if (ret < 0) { printf("Error encoding frame "); return ⑴; } if (got_output) { printf("Flush Encoder: Succeed to encode 1 frame! size:%5d ",pkt.size); fwrite(pkt.data, 1, pkt.size, fp_out); av_free_packet(&pkt); } } fclose(fp_out); avcodec_close(pCodecCtx); av_free(pCodecCtx); av_freep(&pFrame->data[0]); av_frame_free(&pFrame); return 0; }


運行結(jié)果

通過設(shè)定定義在程序開始的宏,肯定需要使用的編碼器。

//test different codec #define TEST_H264 0 #define TEST_HEVC 1

當(dāng)TEST_H264設(shè)置為1的時候,編碼H.264文件“ds.h264”。
當(dāng)TEST_HEVC設(shè)置為1的時候,解碼HEVC文件“ds.hevc”。
輸入文件是“ds_480x272.yuv”。

程序運行的截圖以下所示。


輸入的YUV文件以下圖所示。


輸出的HEVC文件以下圖所示。


下載

Simplest ffmpeg encoder pure工程被作為子工程添加到了simplest ffmpeg video encoder工程中。新版的simplest ffmpeg video encoder的信息以下。


Simplest ffmpeg video encoder

SourceForge主頁:https://sourceforge.net/projects/simplestffmpegvideoencoder/
CSDN下載地址:http://download.csdn.net/detail/leixiaohua1020/8322003


本程序?qū)崿F(xiàn)了YUV像素數(shù)據(jù)編碼為視頻碼流(H.265,H264,MPEG2,VP8等等)。

是最簡單的FFmpeg視頻編碼方面的教程。

它包括以下兩個子項目:

simplest_ffmpeg_video_encoder:最簡單的基于FFmpeg的視頻編碼器。使用libavcodec和libavformat編碼并且封裝視頻。
simplest_ffmpeg_video_encoder_pure:最簡單的基于FFmpeg的視頻編碼器-純凈版。僅使用libavcodec編碼視頻,不使用libavformat。


生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: www在线观看视频免费 | 国产亚洲精品久久77777 | 中文字幕精品在线观看 | 尤物视频在线观看 | 久久久久国产精品嫩草影院 | 日韩性生活视频 | 国产日韩欧美精品 | 亚洲人免费 | 校园春色激情网 | 一级毛片一 | 午夜视频你懂的 | 日韩一区二区久久久久久 | 欧美性猛交xxxx乱大交丰满 | 黄色中文字幕在线观看 | 激情文学激情图片 | 成人在线一区二区 | 欧美综合视频在线观看 | 午夜精品久久久 | 午夜视频网站 | 福利片在线观看免费高清 | 最近中文国语字幕在线播放视频 | 日韩精品国产精品 | 宇都宫紫苑番号 | 成年人视频网站免费 | 亚洲图片校园另激情类小说 | 最近免费中文字幕中文高清 | fxxxx性欧美高清 | 看黄色的网址 | 一区二区精品在线观看 | 国内精品久久久久久久亚洲 | 欧美一级乱妇老太婆特黄 | 亚洲精品综合一二三区在线 | 波多野结衣综合 | www.xxxx欧美| 亚洲精品久久久午夜伊人 | 国产99精品一区二区三区免费 | 成人自拍视频网 | 国产精品久久久久久久久免费观看 | 国产精品日韩欧美一区二区三区 | 亚洲日韩中文字幕在线播放 | 亚洲精品国产一区二区三区四区 |