日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

视频编码案例

發(fā)布時間:2024/4/11 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 视频编码案例 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

視頻編碼案例


目錄

  • FFmpeg視頻編碼流程
  • H.264碼率設(shè)置
  • FFmpeg與H264編碼指南
  • X264參數(shù)之zerolatency的分析
  • YUV編碼成H.264案例

  • 1. FFmpeg視頻編碼流程

  • 從本地讀取YUV數(shù)據(jù)編碼為h264格式的數(shù)據(jù),然后再存?到本地,編碼后的數(shù)據(jù)有帶startcode。
  • 1. 函數(shù)說明

  • avcodec_find_encoder_by_name:根據(jù)指定的編碼器名稱查找注冊的編碼器。
  • avcodec_alloc_context3:為AVCodecContext分配內(nèi)存。
  • avcodec_open2:打開編解碼器。
  • avcodec_send_frame:將AVFrame?壓縮數(shù)據(jù)給編碼器。。
  • avcodec_receive_packet:獲取到編碼后的AVPacket數(shù)據(jù)。
  • av_frame_get_buffer: 為?頻或視頻數(shù)據(jù)分配新的buffer。在調(diào)?這個函數(shù)之前,必須在AVFame上設(shè)置好以下屬性:format(視頻為像素格式,?頻為樣本格式)、nb_samples(樣本個數(shù),針對?頻)、channel_layout(通道類型,針對?頻)、width/height(寬?,針對視頻)。
  • av_frame_make_writable:確保AVFrame是可寫的,盡可能避免數(shù)據(jù)的復(fù)制。如果AVFrame不是是可寫的,將分配新的buffer和復(fù)制數(shù)據(jù)。
  • av_image_fill_arrays: 存儲?幀像素數(shù)據(jù)存儲到AVFrame對應(yīng)的data buffer。
  • 編碼出來的h264數(shù)據(jù)可以直接使?ffplay播放,也可以使?VLC播放。
  • 2. av_image_get_buffer_size

    int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align);
  • 函數(shù)的作?是通過指定像素格式、圖像寬、圖像?來計算所需的內(nèi)存??
  • 重點說明?個參數(shù)align:此參數(shù)是設(shè)定內(nèi)存對?的對?數(shù),也就是按多?的字節(jié)進?內(nèi)存對?:
  • ?如設(shè)置為1,表示按1字節(jié)對?,那么得到的結(jié)果就是與實際的內(nèi)存???樣。
  • 再?如設(shè)置為4,表示按4字節(jié)對?。也就是內(nèi)存的起始地址必須是4的整倍數(shù)。
  • 3. av_image_alloc

  • av_image_alloc()是這樣定義的。此函數(shù)的功能是按照指定的寬、?、像素格式來分配圖像內(nèi)存。
  • int av_image_alloc(uint8_t *pointers[4], int linesizes[4], int w, int h, enum AVPixelFormat pix_fmt, int align);
  • pointers[4]:保存圖像通道的地址。如果是RGB,則前三個指針分別指向R,G,B的內(nèi)存地址。第四個指針保留不? linesizes[4]:保存圖像每個通道的內(nèi)存對?的步?,即??的對?內(nèi)存的寬度,此值??等于圖像寬度。
  • w: 要申請內(nèi)存的圖像寬度。
  • h: 要申請內(nèi)存的圖像?度。
  • pix_fmt: 要申請內(nèi)存的圖像的像素格式。
  • align: ?于內(nèi)存對?的值。
  • 返回值:所申請的內(nèi)存空間的總??。如果是負值,表示申請失敗。
  • 4. av_image_fill_arrays

    int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4], const uint8_t *src, enum AVPixelFormat pix_fmt, int width, int height, int align);
  • av_image_fill_arrays()函數(shù)?身不具備內(nèi)存申請的功能,此函數(shù)類似于格式化已經(jīng)申請的內(nèi)存,即通過av_malloc()函數(shù)申請的內(nèi)存空間,或者av_frame_get_buffer()函數(shù)申請的內(nèi)存空間。再者,av_image_fill_arrays()中參數(shù)具體說明:
  • dst_data[4]: [out]對申請的內(nèi)存格式化為三個通道后,分別保存其地址
  • dst_linesize[4]: [out]格式化的內(nèi)存的步?(即內(nèi)存對?后的寬度)
  • *src: [in]av_alloc()函數(shù)申請的內(nèi)存地址。
  • pix_fmt: [in] 申請 src內(nèi)存時的像素格式
  • width: [in]申請src內(nèi)存時指定的寬度
  • height: [in]申請scr內(nèi)存時指定的?度
  • align: [in]申請src內(nèi)存時指定的對?字節(jié)數(shù)

  • 2. H.264碼率設(shè)置

    1. 什么是視頻碼率

  • 視頻碼率是視頻數(shù)據(jù)(包含視頻?彩量、亮度量、像素量)每秒輸出的位數(shù)。?般?的單位是kbps。
  • 2. 設(shè)置視頻碼率的必要性

  • 在?絡(luò)視頻應(yīng)?中,視頻質(zhì)量和?絡(luò)帶寬占?是相?盾的。通常情況下,視頻流占?的帶寬越?則視頻質(zhì)量也越?,需要的?絡(luò)帶寬也越?,解決這??盾的鑰匙當然是視頻編解碼技術(shù)。評判?種視頻編解碼技術(shù)的優(yōu)劣,是?較在相同的帶寬條件下,哪個視頻質(zhì)量更好;在相同的視頻質(zhì)量條件下,哪個占?的?絡(luò)帶寬更少(?件體積?)。
  • 是不是視頻碼率越?,質(zhì)量越好呢?理論上是這樣的。然?在我們?眼分辨的范圍內(nèi),當碼率?到?定程度時,就沒有什么差別了。所以碼率設(shè)置有它的最優(yōu)值,H.264(也叫AVC或X264)的?件中,視頻的建議碼率如下
  • 視頻??分辨率推薦碼率
    480P720X4801800Kbps
    720P1280X7203500Kbps
    1080P1920X10808500Kbps

    3. ?機設(shè)置碼率建議

    項?計算公式192X144320X240480X360640X4801280X7201920X1080
    極低碼率(寬X?X3)/430kbps60kbps120kbps250kbps500kbps1000kbps
    低碼率(寬X?X3)/260kbps120kbps250kbps500kbps1000kbps2000kbps
    中碼率(寬X?X3)120kbps250kbps500kbps1000kbps2000kbps4000kbps
    ?碼率(寬X?X3)X2250kbps500kbps1000kbps2000kbps4000kbps8000kbps
    極?碼率(寬X?X3)X4500kbps1000kbps2000kbps4000kbps8000kbps16000kbps

    3. FFmpeg與H264編碼指南

  • 鑒于x264的參數(shù)眾多,各種參數(shù)的配合復(fù)雜,為了使?者?便,x264建議如?特別需要可使?preset和tune設(shè)置。這套開發(fā)者推薦的參數(shù)較為合理,可在此基礎(chǔ)上在調(diào)整?些具體參數(shù)以符合??需要,?動設(shè)定的參數(shù)會覆蓋preset和tune?的參數(shù)。

  • 使? ffmpeg -h encoder=libx264 命令查詢相關(guān)?持的參數(shù)

  • 英?地址:https://trac.ffmpeg.org/wiki/Encode/H.264。內(nèi)容有?定出?,但是可以借鑒學(xué)習(xí)。

  • x264是?個 H.264/MPEG4 AVC 編碼器,對于普通?戶通常有兩種碼率控制模式:CRF(Constant Rate Factor)和Two pass ABR。碼率控制是?種決定為每?個視頻幀分配多少?特數(shù)的?法,它將決定?件的??和質(zhì)量的分配。

  • 如果你在編譯和安裝libx264 ??需要幫助,請查看ffmpeg和x264編譯指南:

  • http://ffmpeg.org/trac/ffmpeg/wiki/CompilationGuide

  • 參考:h264編碼參數(shù)

  • 1. CRF(Constant Rate Factor):

    1. 選擇?個CRF值
  • 量化?例的范圍為0到51,其中0為?損模式,23為缺省值,51可能是最差的。該數(shù)字越?,圖像質(zhì)量越好。從主觀上講,18~28是?個合理的范圍。18往往被認為從視覺上看是?損的,它的輸出視頻質(zhì)量和輸?視頻?模?樣或者說相差??。但從技術(shù)的?度來講,它依然是有損壓縮。
  • 若CRF值加6,輸出碼率?概減少?半;若CRF值減6,輸出碼率翻倍。通常是在保證可接受視頻質(zhì)量的前提下選擇?個最?的CRF值,如果輸出視頻質(zhì)量很好,那就嘗試?個更?的值,如果看起來很糟,那就嘗試?個??點值。
  • 注釋:本?所提到的量化?例只適?于8-bit x264(10-bit x264的量化?例 為0~63),你可以使?x264 --help命令在Output bit depth選項查看輸出位深,在各種版本中,8bit是最常?的
  • 2. 選擇?個preset和tune
    1. preset
  • 預(yù)設(shè)是?系列參數(shù)的集合,這個集合能夠在編碼速度和壓縮率之間做出?個權(quán)衡。?個編碼速度稍慢的預(yù)設(shè)會提供更?的壓縮效率(壓縮效率是以?件??來衡量的)。這就是說,假如你想得到?個指定??的?件或者采?恒定?特率編碼模式,你可以采??個較慢的預(yù)設(shè)來獲得更好的質(zhì)量。同樣的,對于恒定質(zhì)量編碼模式,你可以通過選擇?個較慢的預(yù)設(shè)輕松地節(jié)省?特率。
  • 如果你很有耐?,通常的建議是使?最慢的預(yù)設(shè)。?前所有的預(yù)設(shè)按照編碼速度降序排列為:
  • ultrafast
  • superfast
  • veryfast
  • faster
  • fast
  • medium – default preset
  • slow
  • slower
  • veryslow
  • placebo - ignore this as it is not useful (see FAQ)
  • 默認為medium級別
  • 你可以使?–preset來查看預(yù)設(shè)列表,也可以通過x264 --fullhelp來查看預(yù)設(shè)所采?的參數(shù)配置。
  • 針對 libx264做過簡單的各選項對?測試,結(jié)果如下圖
  • 從圖中可以看出,當其他參數(shù)固定時,選擇不同的preset,對應(yīng)的碼率和編碼時間都不?樣
  • 2. tune
  • tune是x264中重要性僅次于preset的選項,它是視覺優(yōu)化的參數(shù),tune可以理解為視頻偏好(或者視頻類型),tune不是?個單?的參數(shù),?是由?組參數(shù)構(gòu)成-tune來改變參數(shù)設(shè)置。當前的 tune包括:

  • film:電影類型,對視頻的質(zhì)量?常嚴格時使?該選項
  • animation:動畫?,壓縮的視頻是動畫?時使?該選項
  • grain:顆粒物很重,該選項適?于顆粒感很重的視頻
  • stillimage:靜態(tài)圖像,該選項主要?于靜?畫??較多的視頻
  • psnr:提?psnr,該選項編碼出來的視頻psnr?較?
  • ssim:提?ssim,該選項編碼出來的視頻ssim?較?
  • fastdecode:快速解碼,該選項有利于快速解碼
  • zerolatency:零延遲,該選項主要?于視頻直播
  • 如果你不確定使?哪個選項或者說你的輸?與所有的tune皆不匹配,你可以忽略–tune 選項。

  • 你可以使?-tune來查看tune列表,也可以通過x264 --fullhelp來查看tune所采?的參數(shù)配置

  • 3. profile
  • 另外?個可選的參數(shù)是-profile:v,它可以將你的輸出限制到?個特定的 H.264 profile。?些?常?的或者要被淘汰的設(shè)備僅?持有限的選項,?如只?持baseline或者main。

  • 所有的profile 包括:

  • baseline profile:基本畫質(zhì)。?持I/P 幀,只?持?交錯(Progressive)和CAVLC;
  • extended profile:進階畫質(zhì)。?持I/P/B/SP/SI 幀,只?持?交錯(Progressive)和CAVLC;
  • main profile:主流畫質(zhì)。提供I/P/B 幀,?持?交錯(Progressive)和交錯(Interlaced),也?持CAVLC 和CABAC 的?持;
  • high profile:?級畫質(zhì)。在main Profile 的基礎(chǔ)上增加了8x8內(nèi)部預(yù)測、?定義量化、 ?損視頻編碼和更多的YUV 格式;
  • 想要說明H.264 high profile與H.264 main profile的區(qū)別就要講到H.264的技術(shù)發(fā)展了。JVT于2003年完成H.264基本部分標準制定?作,包含baseline profile、extended profile和main profile,分別包括不同的編碼?具。之后JVT?完成了H.264 FRExt(即:Fidelity Range Extensions)擴展部分(Amendment)的制定?作,包括high profile(HP)、high 10 profile(Hi10P)、high 4:2:2 profile(Hi422P)、high 4:4:4 profile(Hi444P)4個profile。

  • H.264 baseline profile、extended profile和main profile都是針對8位樣本數(shù)據(jù)、4:2:0格式的視頻序列,FRExt將其擴展到8~12位樣本數(shù)據(jù),視頻格式可以為4:2:0、4:2:2、4:4:4,設(shè)?了highprofile(HP)、high 10 profile(Hi10P)、high 4:2:2 profile(Hi422P)、high 4:4:4 profile(Hi444P) 4個profile,這4個profile都以main profile為基礎(chǔ)。

  • 在相同配置情況下,High profile(HP)可以?Main profile(MP)節(jié)省10%的碼流量,?MPEG-2MP節(jié)省60%的碼流量,具有更好的編碼性能。根據(jù)應(yīng)?領(lǐng)域的不同:

  • baseline profile多應(yīng)?于實時通信領(lǐng)域;
  • main profile多應(yīng)?于流媒體領(lǐng)域;
  • high profile則多應(yīng)?于?電和存儲領(lǐng)域
  • 擴展閱讀:H264編碼系列之profile & level控制

  • 如果你想讓你的視頻最?化的和?標播放設(shè)備兼容(?如?版本的的ios或者所有的android 設(shè)備),那么你可以這做:

  • -profile:v baseline
  • 這將會關(guān)閉很多?級特性,但是它會提供很好的兼容性。也許你可能不需要這些設(shè)置,因為?旦你?了這些設(shè)置,在同樣的視頻質(zhì)量下與更?的編碼檔次相?會使?特率稍有增加。
  • 關(guān)于profile列表和關(guān)于它們的描述,你可以運?x264 --fullhelp
  • 要牢記apple quick time 對于x264編碼的視頻只?持 YUV 420顏?空間,?且不?持任何?于 mianprofile編碼檔次。這樣對于quick time 只留下了兩個兼容選項baseline 和 main。其他的編碼檔次qucik time均不?持,雖然它們均可以在其它的播放設(shè)備上回放
  • 4. 問題與解答:
  • 兩遍編碼模式能夠?CRF模式提供更好的質(zhì)量嗎?
    不能,但它可以更加精確地控制?標?件??。
  • 為什么 placebo 是?個浪費時間的玩意??
    與 veryslow相?,它以極?的編碼時間為代價換取了?概1%的視頻質(zhì)量提升,這是?種收益遞減準則,veryslow 與 slower相?提升了3%;slower 與 slow相?提升了5%;slow 與 medium相?提升了5%~10%。
  • 為什么我的?損輸出看起來是?損的?
    這是由于rgb->yuv的轉(zhuǎn)換,如果你轉(zhuǎn)換到y(tǒng)uv444,它依然是?損的。
  • 顯卡能夠加速x264的編碼嗎?
    不,x264沒有使?(?少現(xiàn)在沒有),有?些私有編碼器使?了GPU加快了編碼速度,但這并不意味著它們經(jīng)過良好的優(yōu)化。也有可能還不如x264,或許速度更慢。總的來說,ffmpeg到?前為?還不?持GPU。翻譯注釋:x264在2013版中已經(jīng)開始?持基于opencl的顯卡加速,?于幀類型的判定。
  • 為Quick time 播放器壓制視頻
    你需要使?-pix_fmt yuv420p來是你的輸出?持QT 播放器。這是因為對于H.264視頻剪輯蘋果的Quicktime只?持 YUV420顏?空間。否則ffmpeg會根據(jù)你的視頻源輸出與Quick time 不兼容的視頻格式或者不是基于ffmpeg的視頻。

  • 4. X264參數(shù)之zerolatency的分析

  • X264參數(shù)之zerolatency的分析

  • 5. YUV編碼成H.264案例

    /** * @projectName 08-02-encode_video * @brief 視頻編碼,從本地讀取YUV數(shù)據(jù)進行H264編碼 */ #include <stdio.h> #include <stdlib.h> #include <string.h>#include <libavcodec/avcodec.h> #include <libavutil/time.h> #include <libavutil/opt.h> #include <libavutil/imgutils.h>int64_t get_time() {return av_gettime_relative() / 1000; // 換算成毫秒 }static int 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);/* 通過查閱代碼,使用x264進行編碼時,具體緩存幀是在x264源碼進行,* 不會增加avframe對應(yīng)buffer的reference*/ret = avcodec_send_frame(enc_ctx, frame);if (ret < 0) {fprintf(stderr, "Error sending a frame for encoding\n");return -1;}while (ret >= 0) {ret = avcodec_receive_packet(enc_ctx, pkt);if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {return 0;} else if (ret < 0) {fprintf(stderr, "Error encoding audio frame\n");return -1;}if (pkt->flags & AV_PKT_FLAG_KEY)printf("Write packet flags:%d pts:%3"PRId64" dts:%3"PRId64" (size:%5d)\n",pkt->flags, pkt->pts, pkt->dts, pkt->size);if (!pkt->flags)printf("Write packet flags:%d pts:%3"PRId64" dts:%3"PRId64" (size:%5d)\n",pkt->flags, pkt->pts, pkt->dts, pkt->size);fwrite(pkt->data, 1, pkt->size, outfile);}return 0; }/*** @brief 提取測試文件:ffmpeg -i test_1280x720.flv -t 5 -r 25 -pix_fmt yuv420p yuv420p_1280x720.yuv* 參數(shù)輸入: yuv420p_1280x720.yuv yuv420p_1280x720.h264 libx264* @param argc* @param argv* @return*/ int main(int argc, char **argv) {char *in_yuv_file = NULL;char *out_h264_file = NULL;FILE *infile = NULL;FILE *outfile = NULL;const char *codec_name = NULL;const AVCodec *codec = NULL;AVCodecContext *codec_ctx = NULL;AVFrame *frame = NULL;AVPacket *pkt = NULL;int ret = 0;if (argc < 4) {fprintf(stderr, "Usage: %s <input_file out_file codec_name >, argc:%d\n",argv[0], argc);return 0;}in_yuv_file = argv[1]; // 輸入YUV文件out_h264_file = argv[2];codec_name = argv[3];/* 查找指定的編碼器 */codec = avcodec_find_encoder_by_name(codec_name);if (!codec) {fprintf(stderr, "Codec '%s' not found\n", codec_name);exit(1);}codec_ctx = avcodec_alloc_context3(codec);if (!codec_ctx) {fprintf(stderr, "Could not allocate video codec context\n");exit(1);}/* 設(shè)置分辨率*/codec_ctx->width = 1280;codec_ctx->height = 720;/* 設(shè)置time base */codec_ctx->time_base = (AVRational) {1, 25};codec_ctx->framerate = (AVRational) {25, 1};/* 設(shè)置I幀間隔* 如果frame->pict_type設(shè)置為AV_PICTURE_TYPE_I, 則忽略gop_size的設(shè)置,一直當做I幀進行編碼*/codec_ctx->gop_size = 25; // I幀間隔codec_ctx->max_b_frames = 2; // 如果不想包含B幀則設(shè)置為0codec_ctx->pix_fmt = AV_PIX_FMT_YUV420P;//if (codec->id == AV_CODEC_ID_H264) {// 相關(guān)的參數(shù)可以參考libx264.c的 AVOption options// ultrafast all encode time:2270ms// medium all encode time:5815ms// veryslow all encode time:19836msret = av_opt_set(codec_ctx->priv_data, "preset", "medium", 0);if (ret != 0) {printf("av_opt_set preset failed\n");}ret = av_opt_set(codec_ctx->priv_data, "profile", "main", 0); // 默認是highif (ret != 0) {printf("av_opt_set profile failed\n");}ret = av_opt_set(codec_ctx->priv_data, "tune", "zerolatency", 0); // 直播是才使用該設(shè)置 // ret = av_opt_set(codec_ctx->priv_data, "tune","film",0); // 畫質(zhì)filmif (ret != 0) {printf("av_opt_set tune failed\n");}}/** 設(shè)置編碼器參數(shù)*//* 設(shè)置bitrate */codec_ctx->bit_rate = 3000000; // codec_ctx->rc_max_rate = 3000000; // codec_ctx->rc_min_rate = 3000000; // codec_ctx->rc_buffer_size = 2000000; // codec_ctx->thread_count = 4; // 開了多線程后也會導(dǎo)致幀輸出延遲, 需要緩存thread_count幀后再編程。 // codec_ctx->thread_type = FF_THREAD_FRAME; // 并 設(shè)置為FF_THREAD_FRAME/* 對于H264 AV_CODEC_FLAG_GLOBAL_HEADER 設(shè)置則只包含I幀,此時sps pps需要從codec_ctx->extradata讀取* 不設(shè)置則每個I幀都帶 sps pps sei*/ // codec_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; // 存本地文件時不要去設(shè)置/* 將codec_ctx和codec進行綁定 */ret = avcodec_open2(codec_ctx, codec, NULL);if (ret < 0) {fprintf(stderr, "Could not open codec: %s\n", av_err2str(ret));exit(1);}printf("thread_count: %d, thread_type:%d\n", codec_ctx->thread_count, codec_ctx->thread_type);// 打開輸入和輸出文件infile = fopen(in_yuv_file, "rb");if (!infile) {fprintf(stderr, "Could not open %s\n", in_yuv_file);exit(1);}outfile = fopen(out_h264_file, "wb");if (!outfile) {fprintf(stderr, "Could not open %s\n", out_h264_file);exit(1);}// 分配pkt和framepkt = av_packet_alloc();if (!pkt) {fprintf(stderr, "Could not allocate video frame\n");exit(1);}frame = av_frame_alloc();if (!frame) {fprintf(stderr, "Could not allocate video frame\n");exit(1);}// 為frame分配bufferframe->format = codec_ctx->pix_fmt;frame->width = codec_ctx->width;frame->height = codec_ctx->height;ret = av_frame_get_buffer(frame, 0);if (ret < 0) {fprintf(stderr, "Could not allocate the video frame data\n");exit(1);}// 計算出每一幀的數(shù)據(jù) 像素格式 * 寬 * 高// 1382400int frame_bytes = av_image_get_buffer_size(frame->format, frame->width,frame->height, 1);printf("frame_bytes %d\n", frame_bytes);uint8_t *yuv_buf = (uint8_t *) malloc(frame_bytes);if (!yuv_buf) {printf("yuv_buf malloc failed\n");return 1;}int64_t begin_time = get_time();int64_t end_time = begin_time;int64_t all_begin_time = get_time();int64_t all_end_time = all_begin_time;int64_t pts = 0;printf("start enode\n");for (;;) {memset(yuv_buf, 0, frame_bytes);size_t read_bytes = fread(yuv_buf, 1, frame_bytes, infile);if (read_bytes <= 0) {printf("read file finish\n");break;}/* 確保該frame可寫, 如果編碼器內(nèi)部保持了內(nèi)存參考計數(shù),則需要重新拷貝一個備份目的是新寫入的數(shù)據(jù)和編碼器保存的數(shù)據(jù)不能產(chǎn)生沖突*/int frame_is_writable = 1;if (av_frame_is_writable(frame) == 0) { // 這里只是用來測試printf("the frame can't write, buf:%p\n", frame->buf[0]);if (frame->buf && frame->buf[0]) // 打印referenc-counted,必須保證傳入的是有效指針printf("ref_count1(frame) = %d\n", av_buffer_get_ref_count(frame->buf[0]));frame_is_writable = 0;}ret = av_frame_make_writable(frame);if (frame_is_writable == 0) { // 這里只是用來測試printf("av_frame_make_writable, buf:%p\n", frame->buf[0]);if (frame->buf && frame->buf[0]) // 打印referenc-counted,必須保證傳入的是有效指針printf("ref_count2(frame) = %d\n", av_buffer_get_ref_count(frame->buf[0]));}if (ret != 0) {printf("av_frame_make_writable failed, ret = %d\n", ret);break;}int need_size = av_image_fill_arrays(frame->data, frame->linesize, yuv_buf,frame->format,frame->width, frame->height, 1);if (need_size != frame_bytes) {printf("av_image_fill_arrays failed, need_size:%d, frame_bytes:%d\n",need_size, frame_bytes);break;}pts += 40;// 設(shè)置ptsframe->pts = pts; // 使用采樣率作為pts的單位,具體換算成秒 pts*1/采樣率begin_time = get_time();ret = encode(codec_ctx, frame, pkt, outfile);end_time = get_time();printf("encode time:%lldms\n", end_time - begin_time);if (ret < 0) {printf("encode failed\n");break;}}/* 沖刷編碼器 */encode(codec_ctx, NULL, pkt, outfile);all_end_time = get_time();printf("all encode time:%lldms\n", all_end_time - all_begin_time);// 關(guān)閉文件fclose(infile);fclose(outfile);// 釋放內(nèi)存if (yuv_buf) {free(yuv_buf);}av_frame_free(&frame);av_packet_free(&pkt);avcodec_free_context(&codec_ctx);printf("main finish, please enter Enter and exit\n");getchar();return 0; }

    總結(jié)

    以上是生活随笔為你收集整理的视频编码案例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。