FFMpeg的output_example.c例子分析

?

該例子講了如何輸出一個libavformat庫所支持格式的媒體文件。 (1)av_register_all(),初始化libavcodec庫,并注冊所有的編解碼器和格式。 (2)guess_format(),根據文件名來獲取輸出文件格式,默認為mpeg。 (3)av_alloc_format_context()分配輸出媒體內容。   ov->oformat = fmt;   snprintf( oc->filename, sizeof(oc->filename), “%s”, filename ); (4)add_video_stream()使用默認格式的編解碼器來增加一個視頻流,并初始化編解碼器。   (4.1)av_new_stream()增加一個新的流到一個媒體文件。   (4.2)初始化編解碼器:     c = st->codec;     c->codec_id = codec_id;     c->codec_type = CODEC_TYPE_VIDEO;     c->bit_rate = 400000;     c->width = 352;     c->height = 288;     c->time_base.den = STREAM_FRAME_RATE; //每秒25副圖像     c->time_base.num = 1;     c->gop_size = 12;     c->pix_fmt = STREAM_PIX_FMT; //默認格式為PIX_FMT_YUV420P     …… …… (5)av_set_parameters()設置輸出參數,即使沒有參數,該函數也必須被調用。 (6)dump_format()輸出格式信息,用于調試。 (7)open_video()打開視頻編解碼器并分配必要的編碼緩存。   (7.1)avcodec_find_encoder()尋找c->codec_id指定的視頻編碼器。   (7.2)avcodec_open()打開編碼器。   (7.3)分配視頻輸出緩存:     video_outbuf_size = 200000;     video_outbuf = av_malloc( video_outbuf_size );   (7.4)picture = alloc_picture()分配原始圖像。     (7.4.1)avcodec_alloc_frame()分配一個AVFrame并設置默認值。     (7.4.2)size = avpicture_get_size()計算對于給定的圖片格式以及寬和高,所需占用多少內存。     (7.4.3)picture_buf = av_malloc( size )分配所需內存。     (7.4.4)avpicture_fill()填充AVPicture的域。   (7.5)可選。如果輸出格式不是YUV420P,那么臨時的YUV420P格式的圖像也是需要的,由此再轉換為我們所需的格式,因此需要為臨時的YUV420P圖像分配緩存:   tmp_picture = alloc_picture() 說明:tmp_picture,picture,video_outbuf。如果輸出格式為YUV420P,則直接通過avcodec_ encode_video()函數將picture緩存中的原始圖像編碼保存到video_outbuf緩存中;如果輸出格式不是YUV420P,則需要先通過sws_scale()函數,將YUV420P格式轉換為目標格式,此時tmp_picture緩存存放的是YUV420P格式的圖像,而picture緩存為轉換為目標格式后保存的圖像,進而再將picture緩存中的圖像編碼保存到video_outbuf緩存中。 (8)url_fopen()打開輸出文件,如果需要的話。 (9)av_write_header()寫流動頭部。 (10)LOOP循環{     計算當前視頻時間video_pts     是否超時退出循環?     write_video_frame()視頻編碼   }   (10.1)write_video_frame()     如果圖片不是YUV420P,則需要用sws_scale()函數先進行格式轉換。     若需要原始圖像:       av_init_packet()初始化一個包的選項域。       av_write_frame()向輸出媒體文件寫一個包,該包會包含一個視頻幀。     若需要編碼圖像:       avcodec_encode_video()編碼一視頻幀。       av_init_packet()       av_write_frame() (11)close_video()關閉每個編解碼器。 (12)av_write_trailer()寫流的尾部。 (13)釋放資源   av_freep()釋放AVFormatContext下的AVStream->AVCodecContext和AVStream:     for( i = 0; i < oc->nb_streams; i++ ){       av_freep( &oc->streams[i]->codec );       av_freep( &oc->streams[i] );     }   url_fclose()關閉輸出文件。   av_free()釋放AVFormatContext。 apiexample.c例子教我們如何去利用ffmpeg庫中的api函數來自己編寫編解碼程序。 (1)首先,main函數中一開始會去調用avcodec_init()函數,該函數的作用是初始化libavcodec,而我們在使用avcodec庫時,該函數必須被調用。   (2)avcodec_register_all()函數,注冊所有的編解碼器(codecs),解析器(parsers)以及碼流過濾器(bitstream filters)。當然我們也可以使用個別的注冊函數來注冊我們所要支持的格式。   (3)video_encode_example()函數用于視頻編碼,由圖可知,所有的編碼工作都在該函數內完成。   (4)avcodec_find_encoder()函數用于查找一個與codec ID相匹配的已注冊的編碼器。   (5)avcodec_alloc_context()函數用于分配一個AVCodecContext并設置默認值,如果失敗返回NULL,并可用av_free()進行釋放。   (6)avcodec_alloc_frame()函數用于分配一個AVFrame并設置默認值,如果失敗返回NULL,并可用av_free()進行釋放。   (7)設置參數:     設置采樣參數,即比特率。     c->bit_rate = 400000;     設置分辨率,必須是2的倍數。     c->width = 352;     c->height = 288;     設置幀率。     c->time_base = (AVRational){1,25}; 該幀率為25,其實timebase = 1/framerate,花括號內分別為分子和分母。     設置GOP大小。     c->gop_size = 10; 該值表示每10幀會插入一個I幀(intra frame)。     設置B幀最大數。     c->max_b_frames = 1; 該值表示在兩個非B幀之間,所允許插入的B幀的最大幀數。     設置像素格式。     c->pix_fmt = PIX_FMT_YUV420P; 該值將像素格式設置為YUV420P。   (8)avcodec_open()函數用給定的AVCodec來初始化AVCodecContext。   (9)接著是打開文件,f = fopen( filename, “wb” ); (10)分配圖像和輸出緩存。     申請100KB左右的內存作為輸出緩存。 outbuf_size = 100000;     outbuf = malloc( outbuf_size );     根據幀的大小來確定YUV420所占內存大小,一個像素,RGB格式占用3個字節,而YUV420格式只占用兩個字節。YUV420格式是指,每個像素都保留一個Y(亮度)分量,而在水平方向上,不是每行都取U和V分量,而是一行只取U分量,則其接著一行就只取V分量,以此重復,所以420不是指沒有V,而是指一行采樣只取U,另一行采樣只取V。在取U和V時,每兩個Y之間取一個U或V。但從4x4矩陣列來看,每4個矩陣點Y區域中,只有一個U和V,所以它們的比值是4:1。所以對于一個像素,RGB需要8 * 3 = 24位,即占3個字節;而YUV420P,8 + 8/4 + 8/4 = 12位,即占2個字節,其中8指Y分量,8/4指U和V分量。     size = c->width * c->height;     picture_buf = malloc( (size * 3) / 2 );     picture->data[0] = picture_buf;     picture->data[1] = picture->data[0] + size;     picture->data[2] = picture->data[1] + size / 4;     picture->linesize[0] = c->width;     picture->linesize[1] = c->width / 2;     picture->linesize[2] = c->width / 2;     其中,data[0]存放Y,data[1]存放U,data[2]存放V【FixMe】。linesize[0]表示Y分量的寬度,linesize[1]表示U分量的寬度,linesize[2]表示V分量的寬度。   (11)編碼一秒鐘的視頻,幀率為25,所以需要循環25次,每次編碼一幀。   (11.1)準備一幅偽圖像,即自己自定義往里面塞數據。     for(y=0;yheight;y++){ for(x=0;xwidth;x++){ picture->data[0][y*picture->linesize[0]+x]=x+y+i*3; } } for(y=0;yheight/2;y++){ for(x=0;xwidth/2;x++){ picture->data[1][y*picture->linesize[1]+x]=128+y+i*2; picture->data[2][y*picture->linesize[2]+x]=64+x+i*5; } }   (11.2)avcodec_encode_video()從picture中編碼一幀視頻數據,并存入到outbuf中,而期間所使用的編碼器為c。   (11.3)將編碼完的數據寫入到文件里。   (12)對延時的幀數據進行編碼。因為像MPEG4中,I幀、P幀和B幀之間存在一定的延時【FixMe】。同樣是avcodec_encode_video(),然后寫入文件。   (13)添加結束代碼,使其成為一個真正的mpeg文件。     outbuf[0] = 0x00;     outbuf[1] = 0x00;     outbuf[2] = 0x01;     outbuf[3] = 0xb7;     fwrite( outbuf, 1, 4, f );   這個結束代碼表示什么???   (14)釋放資源。     fclose(f);     free(picture_buf);     free(outbuf);     avcodec_close(c);     av_free(c);     av_free(picture);

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/455431.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/455431.shtml
英文地址,請注明出處:http://en.pswp.cn/news/455431.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

大量數據+同步+多線程_Vulkan 多線程渲染

1. Overview of Vulkan1.1 計算機圖形軟件圖形軟件有兩個大類&#xff1a;專用軟件包&#xff08;special-purpose packages&#xff09;和通用編程軟件包&#xff08;general programming packages&#xff09;。專用軟件包通常提供一種UI設計語言&#xff0c;讓用戶直接生成想…

飛康任命Gartner前分析師擔任亞洲區市場總監

在虛擬化、數據保護和數據遷移領域具備15年創新經驗的美國飛康軟件公司&#xff08;FalconStor Software, Inc.&#xff0c;NASDAQ&#xff1a;FALC&#xff09;近日宣布任命張瑾&#xff08;Jimmie Chang&#xff09;先生擔任該公司亞洲區市場部門負責人。 飛康公司近日面向全…

12_登陸案例

13131轉載于:https://www.cnblogs.com/ZHONGZHENHUA/p/7044846.html

如何基于FFMPEG和SDL寫一個少于1000行代碼的視頻播放器

http://blog.csdn.net/eplaylity/archive/2008/12/05/3454431.aspx http://www.cnblogs.com/konyel/tag/SDLGuide%E4%B8%AD%E6%96%87%E8%AF%91%E7%89%88/ ffmpeg文檔http://blog.sina.com.cn/s/blog_46dc65a90100a91b.html http://dranger.com/ffmpeg/ffmpeg.html VLC核心功能部…

Flask 概述

什么是Web Framework&#xff1f; Web Application Framework&#xff08;Web應用程序框架&#xff09;或簡單的Web Framework&#xff08;Web框架&#xff09;表示一個庫和模塊的集合&#xff0c;使Web應用程序開發人員能夠編寫應用程序&#xff0c;而不必擔心協議&#xff0…

(五)Maven中的聚合和繼承

一、為什么要聚合&#xff1f; 定義&#xff1a;我們在開發過程中&#xff0c;創建了2個以上的模塊&#xff0c;每個模塊都是一個獨立的maven project&#xff0c;在開始的時候我們可以獨立的編譯和測試運行每個模塊&#xff0c;但是隨著項目的不斷變大和復雜化&#xff0c;我們…

python堆棧反向輸出列表_python - IPython:將Python腳本的輸出重定向到文件(如bash) - 堆棧內存溢出...

IPython有自己的上下文管理器來捕獲stdout / err &#xff0c;但它沒有重定向到文件&#xff0c;它重定向到一個對象&#xff1a;from IPython.utils import iowith io.capture_output() as captured:%run my_script.pyprint captured.stdout # prints stdout from your script…

關于datagrid

基本在公司使用的datagrid不需要自己寫前臺代碼&#xff0c;只需要自己給grid明確id&#xff0c;url以及列屬性即可。 后臺需要返回一個數據類型&#xff1a;{recordsFiltered2, data[], drawnull, recordsTotal2}&#xff0c;通常返回這個數據類型的話&#xff0c;只需要調用d…

M-JPEG、MPEG4、H.264都有何區別 依維安防論壇

壓縮方式是網絡視頻服務器和網絡攝像機的核心技術&#xff0c;壓縮方式很大程度上決定著圖像的質量、壓縮比、傳輸效率、傳輸速度等性能&#xff0c;它是評價網絡視頻服務器和網絡攝像機性能優劣的重要一環。 隨著多媒體技術的發展&#xff0c;相繼推出了許多壓縮編碼標準&…

Django/Flask/Tornado三大web框架性能分析

寫在前面&#xff1a;本文的數據涉及到之前遇到過的問題&#xff0c;大概一次 http 請求到收到響應需要多少時間。這個問題在實際工作中與框架有比較大的關系&#xff0c;因此特別就框架的性能做了一次分析。這里使用之前的一個報告數據&#xff1a; Pythons Web Framework Ben…

python urllib模塊學習筆記

這個模塊是最基本最常用的&#xff0c;以前看過&#xff0c;總結一下 #coding : utf-8import urlliburl http://cnblogs.com#代理服務器proxies {http:http://127.0.0.1:8087}#使用代理服務器打開r urllib.urlopen(url,proxies proxies)print r.info()print r.getcode()pri…

hibernate基礎工具findBySQL學習

public List<Map<String,Object>> findBySQL(String sql,Map<String,Object> param,int start,int max) {log.debug("finding List by hql");try {       //最后返回map map的key可為別名和數據庫字段SQLQuery querysessionFactory.getCurr…

python處理ini文件_python對ini配置文件處理

>>> cf.read("test.ini") #讀取配置文件[test.ini]>>> cf.sections() #片段名[base, callback]>>> cf.options("callback") #配置…

Python實現自動推本地github博客到遠程倉庫

Python實現自動推本地github博客到遠程倉庫 以前的簡單版本 通過python中的os模塊操作系統命令 詳情可參考:Python實現一行代碼推本地git到遠程倉庫 升級版本 本次加入了監聽文件修改功能 這樣腳本只需在后臺運行,即可檢測到對應的文件夾中的內容是否變化 如果變化,則調用…

H.264/MPEG-4 AVC

維基百科&#xff0c;自由的百科全書跳轉到&#xff1a; 導航, 搜索 跳過字詞轉換說明 漢漢▼▲為了閱讀方便&#xff0c;本文使用全文手工轉換。轉換內容&#xff1a;本文采用電腦和信息技術組全文轉換 [查看] ? [編輯] ? [強制刷新] 以下為本條目單獨的全文轉換&#xff0c…

JavaScript 專題之函數柯里化

JavaScript 專題系列第十三篇&#xff0c;講解函數柯里化以及如何實現一個 curry 函數 定義 維基百科中對柯里化 (Currying) 的定義為&#xff1a; In mathematics and computer science, currying is the technique of translating the evaluation of a function that takes m…

機器學習模板

根據心情補充&#xff0c;語言都是Python hash&#xff0c;把所有的文本轉化成數字 from sklearn.preprocessing import LabelEncoder for c in train.columns:if train[c].dtype object:lbl LabelEncoder()lbl.fit(list(train[c].values) list(test[c].values))train[c] l…

漂亮特殊字體可復制_12個創意字體免費下載網站

今天為大家介紹12個創意字體的網站&#xff0c;這些網站都有提供免費下載的字體哦&#xff0c;希望對大家在創作上面有所幫助。FontSpace在Fontspace上有超過42000種免費字體。在這里字體被整齊的分門歸類&#xff0c;幫助你找到想要的字體。除了典型的“serif” “script”等&…

使用postman測試接口

Postman是一款功能強大的網頁調試與發送網頁HTTP請求的Chrome插件。在java web開發中使用非常多&#xff0c;經常用來測試接口。 使用postman模擬json數據的發送 第一步:在header里邊設置發送數據的類型 Paste_Image.png設置發送數據類型為json&#xff0c;也就是key為Content-…

刪除github上的commit歷史記錄

刪除github上的commit歷史記錄 起步 今天小編發現了git克隆下來的遠程庫特別大: 經過查詢之后發現是每次推送之后都會留下記錄緩存&#xff0c;這樣很多沒用的記錄就會占用多余的空間&#xff0c;別人克隆的時候也會多耗費時間&#xff0c;今天我查到了一個清除無用記錄的方…