国产精品久久久久影院,成人午夜福利视频,国产精品久久久久高潮,国产精品 欧美 亚洲 制服,国产精品白浆无码流出

韋東山嵌入式Linux_3期之USB攝像頭監(jiān)控_手機(jī)App增加錄像功能(二)

發(fā)布者:快樂(lè)的成長(zhǎng)最新更新時(shí)間:2024-07-11 來(lái)源: elecfans關(guān)鍵字:韋東山  Linux  手機(jī)App 手機(jī)看文章 掃描二維碼
隨時(shí)隨地手機(jī)看文章

一、模塊劃分

   i) (主體模塊)視頻采集播放

   ii) 顯示模式切換

   iii) 拍照

   iv) 錄像

   v) fps顯示

   vi) 錄像的瀏覽和刪除

回到頂部(go to top)

二、各模塊的實(shí)現(xiàn)

2.1(主體模塊)視頻采集播放

2.1.1 參考資料:

1)主體框架(解碼、讀幀)參考雷霄驊的:100行代碼實(shí)現(xiàn)最簡(jiǎn)單的基于FFMPEG+SDL的視頻播放器(SDL1.x)

      主體框架的流程,可參考雷霄驊的上述博文,這里不再贅述

2)幀的顯示,參考:Android 使用 FFmpeg (二)——視屏流播放簡(jiǎn)單實(shí)現(xiàn)

     幀顯示的流程,大致如下:

     image

2.2 顯示模式切換

實(shí)現(xiàn)思路:利用av_filter的scale和pad功能,對(duì)獲取到的每一個(gè)原始幀進(jìn)行縮放和必要的四邊填充。

主框架體代碼參考FFMPEG filter使用實(shí)例(實(shí)現(xiàn)視頻縮放,裁剪,水印等),這里不再贅述。

至于怎樣實(shí)現(xiàn)兩種顯示模式下的scale參數(shù)(以及pad參數(shù))的切換, 尚未找到最優(yōu)方法(經(jīng)測(cè),av_opt_set()只對(duì)draw_text有效(詳見(jiàn)下文:2.5 fps顯示),而對(duì)scale和pad無(wú)效),

目前暫時(shí)采用較笨的辦法:

1)定義兩個(gè)filter_descr模板,以及對(duì)應(yīng)的AVFilterGraph、AVFilterContext


/* 用于保持長(zhǎng)寬比顯示模式 */

const char *m_filter_descr_template = 'scale=%d:%d,pad=%d:%d:%d:%d:blue,drawtext=fontfile=/sdcard/data/FreeSerif.ttf:fontsize=20:text=fps:x=(w-tw-%d):y=%d';

char  m_filter_descr[200];

/* 用于全屏顯示模式 */

const char *m_filter_descr2_template = 'scale=%d:%d,pad=%d:%d:%d:%d:blue,drawtext=fontfile=/sdcard/data/FreeSerif.ttf:fontsize=20:text=fps:x=(w-tw-5):y=5';

char  m_filter_descr2[200];


/* 用于保持長(zhǎng)寬比顯示模式 */

AVFilterContext *m_buffersink_ctx1;

AVFilterContext *m_buffersrc_ctx1;

AVFilterGraph *m_filter_graph1;


/* 用于全屏顯示模式 */

AVFilterContext *m_buffersink_ctx2;

AVFilterContext *m_buffersrc_ctx2;

AVFilterGraph *m_filter_graph2;


2)初始化時(shí),先調(diào)用keep_img_AR()來(lái)預(yù)先計(jì)算好兩種顯示模式對(duì)應(yīng)的filter_descr的值


int keep_img_AR(int nSrcW ,int nSrcH,int nDstW, int nDstH )

{

    /* 計(jì)算保持寬高比例后上下有黑邊,還是左右有黑邊,黑邊多少 */

    int imgW = 0,imgH = 0;

    int padW = 0,padH = 0;

    //必須規(guī)整為2的倍數(shù),否則ffmpeg計(jì)算pad時(shí)會(huì)報(bào)錯(cuò):Input area not within the padded area or zero-sized

    nDstW = nDstW/2*2;

    nDstH = nDstH/2*2;


    imgW = nSrcW*nDstH/nSrcH/2*2;

    imgH = nSrcH*nDstW/nSrcW/2*2;

    if(imgW        padW=(nDstW-imgW)/2;

        imgH = nDstH/2*2;

        //imgW = -1;

    }

    else if(imgH        padH=(nDstH-imgH)/2;

        imgW = nDstW/2*2;

        //imgH = -1;

    }

    sprintf(m_filter_descr, m_filter_descr_template, imgW, imgH, nDstW, nDstH, padW, padH, padW+5, padH+5);

    sprintf(m_filter_descr2, m_filter_descr2_template, nDstW, nDstH, nDstW, nDstH, 0, 0);


    return 1 ;

}


3)然后調(diào)用init_filters()來(lái)初始化m_filter_graph1、m_buffersink_ctx1、m_buffersrc_ctx1和m_filter_graph2、m_buffersink_ctx2、m_buffersrc_ctx2


     init_filters()的代碼參考FFMPEG filter使用實(shí)例(實(shí)現(xiàn)視頻縮放,裁剪,水印等),這里不再贅述


4)而切換播放模式,其實(shí)就是切換(m_filter_graph1、m_buffersink_ctx1、m_buffersrc_ctx1)和(m_filter_graph2、m_buffersink_ctx2、m_buffersrc_ctx2)三元組


/**

 * 播放視頻時(shí)保持長(zhǎng)寬比

 */

void playVideoKeepAspectRatio()

{

    m_play_video_mode = PLAY_VIDEO_KEEP_ASPECT_RATIO;

    m_filter_graph =   m_filter_graph1;

    m_buffersrc_ctx = m_buffersrc_ctx1;

    m_buffersink_ctx = m_buffersink_ctx1;

}


/**

 * 播放視頻時(shí)填滿顯示區(qū)域

 */

void playVideoFullScreen( )

{

    m_play_video_mode = PLAY_VIDEO_FULL_SCREEN;

    m_filter_graph =   m_filter_graph2;

    m_buffersrc_ctx = m_buffersrc_ctx2;

    m_buffersink_ctx = m_buffersink_ctx2;

}


注:關(guān)于顯示模式切換,另一種實(shí)現(xiàn)的辦法是利用sws_scale()和av_picture_pad(),參考:使用ffmpeg的lib庫(kù)實(shí)現(xiàn)視頻窗口 原始寬高比例/拉伸鋪滿


但代碼量較大,而且經(jīng)測(cè)試,發(fā)現(xiàn)有些問(wèn)題,比如:


- 加上av_filter的draw_text后,fps的顯示會(huì)出現(xiàn)小幅度的上下跳動(dòng),原因待查


- fps的定位較難實(shí)現(xiàn)(因?yàn)橐紤]到pad的寬度)


所以最終沒(méi)有采用這個(gè)辦法(但keep_img_AR()里計(jì)算scale和pad的算法參考了這篇文章)。


2.3 拍照

實(shí)現(xiàn)思路:


1)定義m_pFrameCur代表當(dāng)前獲取到的幀


2)在視頻播放函數(shù)videoStreamStartPlay()的while循環(huán)里,用av_frame_ref(m_pFrameCur, pFrame)使m_pFrameCur指向當(dāng)前獲取到的幀


3)__save_frame_2_jpeg(file_path, m_pFrameCur, m_input_codec_ctx->pix_fmt)實(shí)現(xiàn)把當(dāng)前幀保存到指定的文件中


     代碼參考:ffmpeg實(shí)現(xiàn)mjpeg攝像頭的采集-預(yù)覽-拍照,這里不再贅述


2.4 錄像

參考:如何用FFmpeg API采集攝像頭視頻和麥克風(fēng)音頻,并實(shí)現(xiàn)錄制文件的功能


該文章的demo里,把錄像功能很好的封裝在了一個(gè)類CAVOutputStream里,我基本上原封不動(dòng)的拿來(lái)用于錄像功能的底層實(shí)現(xiàn)。


我所添加的工作,是在視頻播放函數(shù)videoStreamStartPlay()的while循環(huán)里,調(diào)用狀態(tài)機(jī)video_capture_state_machine(),代碼大致如下:


void video_capture_state_machine(AVFrame *pFrame)

{

    switch(m_video_capture_state)

    {

        case VIDEO_CAPTURE_START:

            LOGD('VIDEO_CAPTURE_START');

            m_start_time = av_gettime();

            m_OutputStream.SetVideoCodec(AV_CODEC_ID_H264); //設(shè)置視頻編碼器屬性

            if(true == m_OutputStream.OpenOutputStream(m_save_video_path.c_str()))

                m_video_capture_state = VIDEO_CAPTURE_IN_PROGRESS;

            else

                m_video_capture_state = VIDEO_CAPTURE_IDLE;

            break;

        case VIDEO_CAPTURE_IN_PROGRESS:

            LOGD('VIDEO_CAPTURE_IN_PROGRESS');

            m_OutputStream.write_video_frame(m_input_format_ctx->streams[m_video_stream_index], m_input_format_ctx->streams[m_video_stream_index]->codec->pix_fmt, pFrame, av_gettime() - m_start_time);

            break;

        case VIDEO_CAPTURE_STOP:

            LOGD('VIDEO_CAPTURE_STOP');

            m_OutputStream.CloseOutput();

            m_video_capture_state = VIDEO_CAPTURE_IDLE;

            break;

        default:

            if(m_video_capture_state == VIDEO_CAPTURE_IDLE){

                LOGD('VIDEO_CAPTURE_IDLE');

            }

            else{

                LOGD('m_video_capture_state: %d', m_video_capture_state);

            }

            break;

    }//eo switch(m_video_capture_state)

}


而native層和JAVA層的接口如下:


/* 開(kāi)始錄像 */

void videoStreamStartCapture(const char* file_path)

{

    m_save_video_path = file_path;

    m_video_capture_state = VIDEO_CAPTURE_START;

}


/* 停止錄像 */

void videoStreamStopCapture( )

{

    m_video_capture_state = VIDEO_CAPTURE_STOP;

}


2.5 fps顯示

實(shí)現(xiàn)思路同:2.2 顯示模式切換。


而fps值的動(dòng)態(tài)顯示,是利用av_opt_set(filter_ctx_draw_text->priv, 'text', str_fps, 0 )來(lái)實(shí)現(xiàn)的。


2.6 錄像的瀏覽和刪除

實(shí)現(xiàn)思路:基本上利用了app的原框架,只做了少量改動(dòng)。主要如下:


1) MainActivity.java


      當(dāng)用戶點(diǎn)擊“照片”按鈕后,彈出AlertDialog,提示選擇瀏覽類型,然后根據(jù)用戶的選擇,在startActivity(intent)前,調(diào)用


      intent.putExtra('picturePath', picturePath);


      intent.putExtra('scan_type', ScanPicActivity.SCAN_TYPE_VIDEO);


      或者


      intent.putExtra('picturePath', videoRecordPath);


      intent.putExtra('scan_type', ScanPicActivity.SCAN_TYPE_PIC);


2)ScanPicActivity.java


      - 在init()函數(shù)中,scan_type =  getIntent().getIntExtra('scan_type', SCAN_TYPE_PIC);保存當(dāng)前的瀏覽類型


      - 在每一處涉及“jpeg”字符串的地方,都加入scan_type判斷。代碼從略,詳見(jiàn)項(xiàng)目源代碼


3)Generic.java


      仿照getShrinkedPic(),添加函數(shù)getShrinkedPicFromVideo(),核心是ThumbnailUtils.createVideoThumbnail()。代碼從略,詳見(jiàn)項(xiàng)目源代碼


回到頂部(go to top)

參考資料:

1)韋東山嵌入式linux培訓(xùn)3期項(xiàng)目實(shí)戰(zhàn)之usb攝像頭監(jiān)控,手機(jī)App源代碼


2)Android 官方教程:https://developer.android.google.cn/guide/


3)AndroidStudio3.x開(kāi)發(fā)調(diào)試Android-NDK的C++代碼


4)NDK開(kāi)發(fā)筆記---CMake構(gòu)建JNI


5)雷霄驊的博客系列文章:[總結(jié)]FFMPEG視音頻編解碼零基礎(chǔ)學(xué)習(xí)方法


6)Android 使用 FFmpeg (二)——視屏流播放簡(jiǎn)單實(shí)現(xiàn)


7)如何用FFmpeg API采集攝像頭視頻和麥克風(fēng)音頻,并實(shí)現(xiàn)錄制文件的功能


8)ffmpeg實(shí)現(xiàn)mjpeg攝像頭的采集-預(yù)覽-拍照


9)FFMPEG filter使用實(shí)例(實(shí)現(xiàn)視頻縮放,裁剪,水印等)


10)使用ffmpeg的lib庫(kù)實(shí)現(xiàn)視頻窗口 原始寬高比例/拉伸鋪滿


11)ffmpeg實(shí)現(xiàn)動(dòng)態(tài)調(diào)整字幕內(nèi)容


12)Ffmpeg用法總結(jié)(下)


13)在Android logcat中打印FFmpeg調(diào)試信息


關(guān)鍵字:韋東山  Linux  手機(jī)App 引用地址:韋東山嵌入式Linux_3期之USB攝像頭監(jiān)控_手機(jī)App增加錄像功能(二)

上一篇:韋東山嵌入式Linux_3期之USB攝像頭監(jiān)控_手機(jī)App增加錄像功能(一)
下一篇:ALSA聲卡_從零編寫(xiě)之參數(shù)設(shè)置(基于優(yōu)龍F(tuán)S2410開(kāi)發(fā)板,UDA1341聲卡)

推薦閱讀最新更新時(shí)間:2025-07-13 22:38

使用USB無(wú)線網(wǎng)卡和USB攝像頭打造mini2440無(wú)線監(jiān)控系統(tǒng)
一、我的mini2440開(kāi)發(fā)板上使用的網(wǎng)卡設(shè)備為水星MERCURY54M無(wú)線USB網(wǎng)卡 MW54U ver:7.0,其內(nèi)部芯片型號(hào)為ATHEROS的ar9271。mini2440的自帶linux系統(tǒng)里面是沒(méi)有這個(gè)驅(qū)動(dòng)程序的,但是在官網(wǎng)上usb-wifi-kits-for-mini2440-linux-2.6.32.2-20100728.tar.gz這個(gè)安裝包里面是有ar9271這個(gè)驅(qū)動(dòng)的。 所以首先就得,先把usb-wifi-kits-for-mini2440-linux-2.6.32.2-20100728.tar.gz這個(gè)壓縮包拷貝到mini2440的linux系統(tǒng)中,然后直接在根系統(tǒng)下面解壓縮,使用以下命令: #tar -xz
[單片機(jī)]
開(kāi)源安卓 App 開(kāi)發(fā)商 Simple Mobile Tools 要造手機(jī)
IT之家 5 月 16 日消息,Simple Mobile Tools 是一個(gè)知名的開(kāi)源安卓 App 開(kāi)發(fā)商,推出了許多基礎(chǔ)的開(kāi)源 App,包括聯(lián)系人、撥號(hào)器、計(jì)算器、文件管理器、圖庫(kù)等。 該品牌近日宣布要造手機(jī)了。在 Reddit 上,Simple Mobile Tools 官方開(kāi)發(fā)者宣布將很快發(fā)布一款注重隱私的手機(jī),將預(yù)裝旗下的 22 款開(kāi)源 App。 但是,Simple Mobile Tools 還沒(méi)有開(kāi)發(fā)瀏覽器、電子郵件等,因此詢問(wèn)網(wǎng)友有哪些其他的開(kāi)源軟件可供推薦。 目前尚不清楚這款手機(jī)的硬件參數(shù)或是外觀,我們也只能等待官方公布了。不過(guò),作為一個(gè)小型軟件開(kāi)發(fā)商造出來(lái)的手機(jī),可能在很多方面都不如主流手機(jī)大廠,面向的用
[手機(jī)便攜]
開(kāi)源安卓 <font color='red'>App</font> 開(kāi)發(fā)商 Simple Mobile Tools 要造<font color='red'>手機(jī)</font>了
小米貸款App獨(dú)立發(fā)布:面向所有安卓手機(jī)
如昨日MIUI微博預(yù)告,今天上午,小米官方宣布,小米貸款A(yù)pp獨(dú)立發(fā)布,面向所有安卓手機(jī)用戶提供小額信貸服務(wù)。 據(jù)悉,小米貸款獲貸簡(jiǎn)單,僅需“認(rèn)證-申請(qǐng)-放貸”3步搞定。整個(gè)過(guò)程不到2分鐘,規(guī)范透明。按天計(jì)算利息也很靈活,用起來(lái)沒(méi)壓力。 小米貸款A(yù)pp獨(dú)立發(fā)布:面向所有安卓手機(jī) 資料顯示,2015年9月16日,小米金融發(fā)布了信貸產(chǎn)品“小米貸款”,并進(jìn)行首批公測(cè)。小米貸款是面向小米用戶的純信用、無(wú)抵押貸款產(chǎn)品,在小米金融對(duì)用戶行為綜合評(píng)估后明確相應(yīng)的貸款額度,單筆貸款額度最低為100元,根據(jù)每個(gè)人的信用,可申請(qǐng)額度也會(huì)不同。 如今,小米貸款A(yù)pp獨(dú)立發(fā)布,等于讓其它安卓手機(jī)用戶也能享受該服務(wù)了。 目前,小米貸款A(yù)pp已上架各大
[手機(jī)便攜]
基于ok6410的韋東山驅(qū)動(dòng)視頻簡(jiǎn)要分析--USB驅(qū)動(dòng)
注意:本篇講的鼠標(biāo)驅(qū)動(dòng)僅能實(shí)現(xiàn)鼠標(biāo)左右鍵跟滑輪這三個(gè)按鍵類似button的功能,按下左鍵則打出 l ,右鍵打出“s”,滑輪打出“enter”。如果要實(shí)現(xiàn)正常的鼠標(biāo)驅(qū)動(dòng),參考內(nèi)核的鼠標(biāo)驅(qū)動(dòng),修改input的一些參數(shù)即可。 一、寫(xiě)驅(qū)動(dòng)的步驟(新手稍微看下即可,內(nèi)容有點(diǎn)搞) 1、復(fù)制頭文件; 2、寫(xiě)入口函數(shù),出口函數(shù),再加上協(xié)議; 3、分配注冊(cè)u(píng)sb_driver結(jié)構(gòu)體(拷別人的), static struct usb_driver usb_mk_driver = {}; 在init中注冊(cè)該結(jié)構(gòu)體:usb_register(&usb_mk_driver); 在exit中注銷該結(jié)構(gòu)體:usb_deregi
[單片機(jī)]
IMX6ULL開(kāi)發(fā)平臺(tái)Linux-LED實(shí)驗(yàn)
在前面的章節(jié)中,我們學(xué)習(xí)了解了字符設(shè)備驅(qū)動(dòng),以及如何在設(shè)備樹(shù)文件中添加設(shè)備信息,接下來(lái)就來(lái)看一下i.MX6UL終結(jié)者開(kāi)發(fā)板的實(shí)際硬件是如何添加的。我們先以最簡(jiǎn)單的LED設(shè)備來(lái)看一下具體的注冊(cè)流程。 36.1 LED設(shè)備注冊(cè)流程 在i.MX6UL終結(jié)者開(kāi)發(fā)板上有一個(gè)LED設(shè)備,如果想要通過(guò)Linux系統(tǒng)/dev目錄下的設(shè)備節(jié)點(diǎn)來(lái)控制LED,就需要在內(nèi)核中添加LED的驅(qū)動(dòng),具體的流程可以分為下面幾個(gè)步驟: ① 硬件原理圖分析,確定控制LED的GPIO信息。 ② 根據(jù)GPIO信息在設(shè)備樹(shù)文件中添加pinctrl信息 ③ 在設(shè)備樹(shù)中創(chuàng)建LED的設(shè)備節(jié)點(diǎn),并加入GPIO信息 ④ 編寫(xiě)LED設(shè)備驅(qū)動(dòng)程序 接下來(lái)根據(jù)上面這四步來(lái)添加一下LED的
[單片機(jī)]
IMX6ULL開(kāi)發(fā)平臺(tái)<font color='red'>Linux</font>-LED實(shí)驗(yàn)
2.1 linux中uboot移植
(一)友善之臂介紹: README for FriendlyARM Tiny4412 說(shuō)明:本u-boot源代碼由三星原廠提供,并由友善之臂修改移植,以適用于Tiny4412開(kāi)發(fā)板平臺(tái)。 僅供嵌入式愛(ài)好者學(xué)習(xí)研究之用,友善之臂不對(duì)此提供任何技術(shù)支持和維護(hù)。 ----------------------------------------------------- 1. Build uboot a) 安裝好toolchain (arm-linux-gcc-4.5.1-v6-vfp-20120301.tgz)并設(shè)置好 環(huán)境變量PATH,保證可以正常使用。 b) 解壓 uboot_tiny4412-20130729.tgz 并進(jìn)入相應(yīng)的
[單片機(jī)]
2.1 <font color='red'>linux</font>中uboot移植
Linux 下使用s3c6410的post處理器的進(jìn)行硬件縮放
在嵌入式下,在移植軟件時(shí)經(jīng)常會(huì)碰到這樣的問(wèn)題,就是顯示分辯率的變化.一般軟件往往針對(duì)桌面機(jī)的環(huán)境編譯沒(méi)有太多問(wèn)題,但是在嵌入式環(huán)境下,受限的LCD顯示有著很大的問(wèn)題. 這種情況下,一種方法是修改代碼,讓其在嵌入式的LCD上顯示.另外一種是使用軟件進(jìn)行顯示縮放. 這兩個(gè)方法只在部分條件有效,而且修改的工作量極大,更多情況是無(wú)法修改,比如SDL下的Dosbox是針對(duì) 640*480,修改源碼的分辯率成 480*272 后,基本屏幕顯示完全錯(cuò)位.軟件無(wú)法正常運(yùn)行. 這里有一種思路是使用s3c6410的post process.它是一個(gè)硬件進(jìn)行圖像和視頻縮放的的模塊.用POST后,只需要簡(jiǎn)單調(diào)整frame buffer顯示庫(kù)代碼,即可
[單片機(jī)]
Linux驅(qū)動(dòng)學(xué)習(xí)筆記之觸摸屏驅(qū)動(dòng)
觸摸屏歸納為輸入子系統(tǒng),這里主要是針對(duì)電阻屏,其使用過(guò)程如下 當(dāng)用觸摸筆按下時(shí),產(chǎn)生中斷。 在中斷處理函數(shù)處理函數(shù)中啟動(dòng)ADC轉(zhuǎn)換x,y坐標(biāo)。 ADC結(jié)束,產(chǎn)生ADC中斷 在ADC中斷處理函數(shù)里上報(bào)(input_event)啟動(dòng)定時(shí)器 再次啟動(dòng)定時(shí)器(可以處理滑動(dòng)、長(zhǎng)按) 松開(kāi)按鍵 其驅(qū)動(dòng)程序的寫(xiě)法和之前寫(xiě)輸入子系統(tǒng)的寫(xiě)法基本上一致。 寫(xiě)出入口函數(shù),出口函數(shù)并加以修飾,加入相關(guān)頭文件,然后開(kāi)始完善各函數(shù),在入口函數(shù)中分配input_dev結(jié)構(gòu)體,設(shè)置(能產(chǎn)生哪類事件,能產(chǎn)生這類事件中的哪些事件),注冊(cè)設(shè)備,硬件相關(guān)的操作等。出口函數(shù)中主要對(duì)之前注冊(cè)、分配的一些資源進(jìn)行釋放。 還應(yīng)根據(jù)2440數(shù)據(jù)手冊(cè)ADC轉(zhuǎn)換和觸摸屏那一章,對(duì)
[單片機(jī)]
小廣播
設(shè)計(jì)資源 培訓(xùn) 開(kāi)發(fā)板 精華推薦

最新單片機(jī)文章

 
EEWorld訂閱號(hào)

 
EEWorld服務(wù)號(hào)

 
汽車(chē)開(kāi)發(fā)圈

 
機(jī)器人開(kāi)發(fā)圈

電子工程世界版權(quán)所有 京ICP證060456號(hào) 京ICP備10001474號(hào)-1 電信業(yè)務(wù)審批[2006]字第258號(hào)函 京公網(wǎng)安備 11010802033920號(hào) Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved