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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

最简单的基于FFmpeg的AVDevice例子(读取摄像头)

發(fā)布時間:2024/4/11 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 最简单的基于FFmpeg的AVDevice例子(读取摄像头) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

=====================================================
最簡單的基于FFmpeg的AVDevice例子文章列表:

最簡單的基于FFmpeg的AVDevice例子(讀取攝像頭)

最簡單的基于FFmpeg的AVDevice例子(屏幕錄制)
=====================================================


FFmpeg中有一個和多媒體設(shè)備交互的類庫:Libavdevice。使用這個庫可以讀取電腦(或者其他設(shè)備上)的多媒體設(shè)備的數(shù)據(jù),或者輸出數(shù)據(jù)到指定的多媒體設(shè)備上。

Libavdevice支持以下設(shè)備作為輸入端:
alsa
avfoundation
bktr
dshow
dv1394
fbdev
gdigrab
iec61883
jack
lavfi
libcdio
libdc1394
openal
oss
pulse
qtkit
sndio
video4linux2, v4l2
vfwcap
x11grab
decklink
Libavdevice支持以下設(shè)備作為輸出端:
alsa
caca
decklink
fbdev
opengl
oss
pulse
sdl
sndio
xv


libavdevice使用

計劃記錄兩個基于FFmpeg的libavdevice類庫的例子,分成兩篇文章寫。本文記錄一個基于FFmpeg的Libavdevice類庫讀取攝像頭數(shù)據(jù)的例子。下一篇文章記錄一個基于FFmpeg的Libavdevice類庫錄制屏幕的例子。本文程序讀取計算機上的攝像頭的數(shù)據(jù)并且解碼顯示出來。有關(guān)解碼顯示方面的代碼本文不再詳述,可以參考文章:
100行代碼實現(xiàn)最簡單的基于FFMPEG+SDL的視頻播放器(SDL1.x)


本文主要記錄使用libavdevice需要注意的步驟。

首先,使用libavdevice的時候需要包含其頭文件:
[cpp]?view plaincopy
  • #include?"libavdevice/avdevice.h"??
  • 然后,在程序中需要注冊libavdevice:
    [cpp]?view plaincopy
  • avdevice_register_all();??

  • 接下來就可以使用libavdevice的功能了。
    使用libavdevice讀取數(shù)據(jù)和直接打開視頻文件比較類似。因為系統(tǒng)的設(shè)備也被FFmpeg認(rèn)為是一種輸入的格式(即AVInputFormat)。使用FFmpeg打開一個普通的視頻文件使用如下函數(shù):
    [cpp]?view plaincopy
  • AVFormatContext?*pFormatCtx?=?avformat_alloc_context();??
  • avformat_open_input(&pFormatCtx,?"test.h265",NULL,NULL);??

  • 使用libavdevice的時候,唯一的不同在于需要首先查找用于輸入的設(shè)備。在這里使用av_find_input_format()完成:
    [cpp]?view plaincopy
  • AVFormatContext?*pFormatCtx?=?avformat_alloc_context();??
  • AVInputFormat?*ifmt=av_find_input_format("vfwcap");??
  • avformat_open_input(&pFormatCtx,?0,?ifmt,NULL);??

  • 上述代碼首先指定了vfw設(shè)備作為輸入設(shè)備,然后在URL中指定打開第0個設(shè)備(在我自己計算機上即是攝像頭設(shè)備)。
    在Windows平臺上除了使用vfw設(shè)備作為輸入設(shè)備之外,還可以使用DirectShow作為輸入設(shè)備:
    [cpp]?view plaincopy
  • AVFormatContext?*pFormatCtx?=?avformat_alloc_context();??
  • AVInputFormat?*ifmt=av_find_input_format("dshow");??
  • avformat_open_input(&pFormatCtx,"video=Integrated?Camera",ifmt,NULL)?;??

  • 使用ffmpeg.exe打開vfw設(shè)備和Directshow設(shè)備的方法可以參考文章:
    FFmpeg獲取DirectShow設(shè)備數(shù)據(jù)(攝像頭,錄屏)

    注意事項

    1. URL的格式是"video={設(shè)備名稱}",但是設(shè)備名稱外面不能加引號。例如在上述例子中URL是"video=Integrated Camera",而不能寫成"video=\"Integrated Camera\"",否則就無法打開設(shè)備。這與直接使用ffmpeg.exe打開dshow設(shè)備(命令為: ffmpeg?-list_options?true?-f?dshow?-i?video="Integrated?Camera" )有很大的不同。
    2. Dshow的設(shè)備名稱必須要提前獲取,在這里有兩種方法:

    (1) 通過FFmpeg編程實現(xiàn)。使用如下代碼:

    [cpp]?view plaincopy
  • //Show?Device??
  • void?show_dshow_device(){??
  • ????AVFormatContext?*pFormatCtx?=?avformat_alloc_context();??
  • ????AVDictionary*?options?=?NULL;??
  • ????av_dict_set(&options,"list_devices","true",0);??
  • ????AVInputFormat?*iformat?=?av_find_input_format("dshow");??
  • ????printf("Device?Info=============\n");??
  • ????avformat_open_input(&pFormatCtx,"video=dummy",iformat,&options);??
  • ????printf("========================\n");??
  • }??

  • 上述代碼實際上相當(dāng)于輸入了下面一條命令:
    [plain]?view plaincopy
  • ffmpeg?-list_devices?true?-f?dshow?-i?dummy????

  • 執(zhí)行的結(jié)果如下圖所示:

    ?

    該方法好處是可以使用程序自動獲取名稱。但是當(dāng)設(shè)備名稱中包含中文字符的時候,會出現(xiàn)設(shè)備名稱為亂碼的情況。如果直接把亂碼的設(shè)備名作為輸入的話,是無法打開該設(shè)備的。這時候需要把亂碼ANSI轉(zhuǎn)換為UTF-8。例如上圖中的第一個音頻設(shè)備顯示為“鍐呰楹﹀厠椋?(Conexant 20672 SmartAudi”,轉(zhuǎn)碼之后即為“內(nèi)裝麥克風(fēng) (Conexant 20672 SmartAudi”。使用轉(zhuǎn)碼之后的名稱即可打開該設(shè)備。


    (2) 自己去系統(tǒng)中看。
    這個方法更簡單一些,但是缺點是需要手工操作。該方法使用DirectShow的調(diào)試工具GraphEdit(或者網(wǎng)上下一個GraphStudioNext)即可查看輸入名稱。
    打開GraphEdit選擇“圖像->插入濾鏡”
    然后就可以通過查看Audio Capture Sources來查看音頻輸入設(shè)備的簡體中文名稱了。從圖中可以看出是“內(nèi)裝麥克風(fēng) (Conexant 20672 SmartAudi”。


    在Linux平臺上可以使用video4linux2打開視頻設(shè)備;在MacOS上,可以使用avfoundation打開視頻設(shè)備,這里不再詳述。


    代碼

    下面直接貼上程序代碼:

    [cpp]?view plaincopy
  • /**?
  • ?*?最簡單的基于FFmpeg的AVDevice例子(讀取攝像頭)?
  • ?*?Simplest?FFmpeg?Device?(Read?Camera)?
  • ?*?
  • ?*?雷霄驊?Lei?Xiaohua?
  • ?*?leixiaohua1020@126.com?
  • ?*?中國傳媒大學(xué)/數(shù)字電視技術(shù)?
  • ?*?Communication?University?of?China?/?Digital?TV?Technology?
  • ?*?http://blog.csdn.net/leixiaohua1020?
  • ?*?
  • ?*?本程序?qū)崿F(xiàn)了本地攝像頭數(shù)據(jù)的獲取解碼和顯示。是基于FFmpeg?
  • ?*?的libavdevice類庫最簡單的例子。通過該例子,可以學(xué)習(xí)FFmpeg中?
  • ?*?libavdevice類庫的使用方法。?
  • ?*?本程序在Windows下可以使用2種方式讀取攝像頭數(shù)據(jù):?
  • ?*??1.VFW:?Video?for?Windows?屏幕捕捉設(shè)備。注意輸入URL是設(shè)備的序號,?
  • ?*??????????從0至9。?
  • ?*??2.dshow:?使用Directshow。注意作者機器上的攝像頭設(shè)備名稱是?
  • ?*?????????“Integrated?Camera”,使用的時候需要改成自己電腦上攝像頭設(shè)?
  • ?*??????????備的名稱。?
  • ?*?在Linux下可以使用video4linux2讀取攝像頭設(shè)備。?
  • ?*?在MacOS下可以使用avfoundation讀取攝像頭設(shè)備。?
  • ?*?
  • ?*?This?software?read?data?from?Computer's?Camera?and?play?it.?
  • ?*?It's?the?simplest?example?about?usage?of?FFmpeg's?libavdevice?Library.??
  • ?*?It's?suiltable?for?the?beginner?of?FFmpeg.?
  • ?*?This?software?support?2?methods?to?read?camera?in?Microsoft?Windows:?
  • ?*??1.gdigrab:?VfW?(Video?for?Windows)?capture?input?device.?
  • ?*?????????????The?filename?passed?as?input?is?the?capture?driver?number,?
  • ?*?????????????ranging?from?0?to?9.?
  • ?*??2.dshow:?Use?Directshow.?Camera's?name?in?author's?computer?is??
  • ?*?????????????"Integrated?Camera".?
  • ?*?It?use?video4linux2?to?read?Camera?in?Linux.?
  • ?*?It?use?avfoundation?to?read?Camera?in?MacOS.?
  • ?*??
  • ?*/??
  • ??
  • ??
  • #include?<stdio.h>??
  • ??
  • #define?__STDC_CONSTANT_MACROS??
  • ??
  • #ifdef?_WIN32??
  • //Windows??
  • extern?"C"??
  • {??
  • #include?"libavcodec/avcodec.h"??
  • #include?"libavformat/avformat.h"??
  • #include?"libswscale/swscale.h"??
  • #include?"libavdevice/avdevice.h"??
  • #include?"SDL/SDL.h"??
  • };??
  • #else??
  • //Linux...??
  • #ifdef?__cplusplus??
  • extern?"C"??
  • {??
  • #endif??
  • #include?<libavcodec/avcodec.h>??
  • #include?<libavformat/avformat.h>??
  • #include?<libswscale/swscale.h>??
  • #include?<libavdevice/avdevice.h>??
  • #include?<SDL/SDL.h>??
  • #ifdef?__cplusplus??
  • };??
  • #endif??
  • #endif??
  • ??
  • //Output?YUV420P???
  • #define?OUTPUT_YUV420P?0??
  • //'1'?Use?Dshow???
  • //'0'?Use?VFW??
  • #define?USE_DSHOW?0??
  • ??
  • ??
  • //Refresh?Event??
  • #define?SFM_REFRESH_EVENT??(SDL_USEREVENT?+?1)??
  • ??
  • #define?SFM_BREAK_EVENT??(SDL_USEREVENT?+?2)??
  • ??
  • int?thread_exit=0;??
  • ??
  • int?sfp_refresh_thread(void?*opaque)??
  • {??
  • ????thread_exit=0;??
  • ????while?(!thread_exit)?{??
  • ????????SDL_Event?event;??
  • ????????event.type?=?SFM_REFRESH_EVENT;??
  • ????????SDL_PushEvent(&event);??
  • ????????SDL_Delay(40);??
  • ????}??
  • ????thread_exit=0;??
  • ????//Break??
  • ????SDL_Event?event;??
  • ????event.type?=?SFM_BREAK_EVENT;??
  • ????SDL_PushEvent(&event);??
  • ??
  • ????return?0;??
  • }??
  • ??
  • ??
  • //Show?Dshow?Device??
  • void?show_dshow_device(){??
  • ????AVFormatContext?*pFormatCtx?=?avformat_alloc_context();??
  • ????AVDictionary*?options?=?NULL;??
  • ????av_dict_set(&options,"list_devices","true",0);??
  • ????AVInputFormat?*iformat?=?av_find_input_format("dshow");??
  • ????printf("========Device?Info=============\n");??
  • ????avformat_open_input(&pFormatCtx,"video=dummy",iformat,&options);??
  • ????printf("================================\n");??
  • }??
  • ??
  • //Show?Dshow?Device?Option??
  • void?show_dshow_device_option(){??
  • ????AVFormatContext?*pFormatCtx?=?avformat_alloc_context();??
  • ????AVDictionary*?options?=?NULL;??
  • ????av_dict_set(&options,"list_options","true",0);??
  • ????AVInputFormat?*iformat?=?av_find_input_format("dshow");??
  • ????printf("========Device?Option?Info======\n");??
  • ????avformat_open_input(&pFormatCtx,"video=Integrated?Camera",iformat,&options);??
  • ????printf("================================\n");??
  • }??
  • ??
  • //Show?VFW?Device??
  • void?show_vfw_device(){??
  • ????AVFormatContext?*pFormatCtx?=?avformat_alloc_context();??
  • ????AVInputFormat?*iformat?=?av_find_input_format("vfwcap");??
  • ????printf("========VFW?Device?Info======\n");??
  • ????avformat_open_input(&pFormatCtx,"list",iformat,NULL);??
  • ????printf("=============================\n");??
  • }??
  • ??
  • //Show?AVFoundation?Device??
  • void?show_avfoundation_device(){??
  • ????AVFormatContext?*pFormatCtx?=?avformat_alloc_context();??
  • ????AVDictionary*?options?=?NULL;??
  • ????av_dict_set(&options,"list_devices","true",0);??
  • ????AVInputFormat?*iformat?=?av_find_input_format("avfoundation");??
  • ????printf("==AVFoundation?Device?Info===\n");??
  • ????avformat_open_input(&pFormatCtx,"",iformat,&options);??
  • ????printf("=============================\n");??
  • }??
  • ??
  • ??
  • int?main(int?argc,?char*?argv[])??
  • {??
  • ??
  • ????AVFormatContext?*pFormatCtx;??
  • ????int?????????????i,?videoindex;??
  • ????AVCodecContext??*pCodecCtx;??
  • ????AVCodec?????????*pCodec;??
  • ??????
  • ????av_register_all();??
  • ????avformat_network_init();??
  • ????pFormatCtx?=?avformat_alloc_context();??
  • ??????
  • ????//Open?File??
  • ????//char?filepath[]="src01_480x272_22.h265";??
  • ????//avformat_open_input(&pFormatCtx,filepath,NULL,NULL)??
  • ??
  • ????//Register?Device??
  • ????avdevice_register_all();??
  • ??
  • //Windows??
  • #ifdef?_WIN32??
  • ??
  • ????//Show?Dshow?Device??
  • ????show_dshow_device();??
  • ????//Show?Device?Options??
  • ????show_dshow_device_option();??
  • ????//Show?VFW?Options??
  • ????show_vfw_device();??
  • ??
  • #if?USE_DSHOW??
  • ????AVInputFormat?*ifmt=av_find_input_format("dshow");??
  • ????//Set?own?video?device's?name??
  • ????if(avformat_open_input(&pFormatCtx,"video=Integrated?Camera",ifmt,NULL)!=0){??
  • ????????printf("Couldn't?open?input?stream.\n");??
  • ????????return?-1;??
  • ????}??
  • #else??
  • ????AVInputFormat?*ifmt=av_find_input_format("vfwcap");??
  • ????if(avformat_open_input(&pFormatCtx,"0",ifmt,NULL)!=0){??
  • ????????printf("Couldn't?open?input?stream.\n");??
  • ????????return?-1;??
  • ????}??
  • #endif??
  • #elif?defined?linux??
  • ????//Linux??
  • ????AVInputFormat?*ifmt=av_find_input_format("video4linux2");??
  • ????if(avformat_open_input(&pFormatCtx,"/dev/video0",ifmt,NULL)!=0){??
  • ????????printf("Couldn't?open?input?stream.\n");??
  • ????????return?-1;??
  • ????}??
  • #else??
  • ????show_avfoundation_device();??
  • ????//Mac??
  • ????AVInputFormat?*ifmt=av_find_input_format("avfoundation");??
  • ????//Avfoundation??
  • ????//[video]:[audio]??
  • ????if(avformat_open_input(&pFormatCtx,"0",ifmt,NULL)!=0){??
  • ????????printf("Couldn't?open?input?stream.\n");??
  • ????????return?-1;??
  • ????}??
  • #endif??
  • ??
  • ??
  • ????if(avformat_find_stream_info(pFormatCtx,NULL)<0)??
  • ????{??
  • ????????printf("Couldn't?find?stream?information.\n");??
  • ????????return?-1;??
  • ????}??
  • ????videoindex=-1;??
  • ????for(i=0;?i<pFormatCtx->nb_streams;?i++)???
  • ????????if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)??
  • ????????{??
  • ????????????videoindex=i;??
  • ????????????break;??
  • ????????}??
  • ????if(videoindex==-1)??
  • ????{??
  • ????????printf("Couldn't?find?a?video?stream.\n");??
  • ????????return?-1;??
  • ????}??
  • ????pCodecCtx=pFormatCtx->streams[videoindex]->codec;??
  • ????pCodec=avcodec_find_decoder(pCodecCtx->codec_id);??
  • ????if(pCodec==NULL)??
  • ????{??
  • ????????printf("Codec?not?found.\n");??
  • ????????return?-1;??
  • ????}??
  • ????if(avcodec_open2(pCodecCtx,?pCodec,NULL)<0)??
  • ????{??
  • ????????printf("Could?not?open?codec.\n");??
  • ????????return?-1;??
  • ????}??
  • ????AVFrame?*pFrame,*pFrameYUV;??
  • ????pFrame=av_frame_alloc();??
  • ????pFrameYUV=av_frame_alloc();??
  • ????//unsigned?char?*out_buffer=(unsigned?char?*)av_malloc(avpicture_get_size(AV_PIX_FMT_YUV420P,?pCodecCtx->width,?pCodecCtx->height));??
  • ????//avpicture_fill((AVPicture?*)pFrameYUV,?out_buffer,?AV_PIX_FMT_YUV420P,?pCodecCtx->width,?pCodecCtx->height);??
  • ????//SDL----------------------------??
  • ????if(SDL_Init(SDL_INIT_VIDEO?|?SDL_INIT_AUDIO?|?SDL_INIT_TIMER))?{????
  • ????????printf(?"Could?not?initialize?SDL?-?%s\n",?SDL_GetError());???
  • ????????return?-1;??
  • ????}???
  • ????int?screen_w=0,screen_h=0;??
  • ????SDL_Surface?*screen;???
  • ????screen_w?=?pCodecCtx->width;??
  • ????screen_h?=?pCodecCtx->height;??
  • ????screen?=?SDL_SetVideoMode(screen_w,?screen_h,?0,0);??
  • ??
  • ????if(!screen)?{????
  • ????????printf("SDL:?could?not?set?video?mode?-?exiting:%s\n",SDL_GetError());????
  • ????????return?-1;??
  • ????}??
  • ????SDL_Overlay?*bmp;???
  • ????bmp?=?SDL_CreateYUVOverlay(pCodecCtx->width,?pCodecCtx->height,SDL_YV12_OVERLAY,?screen);???
  • ????SDL_Rect?rect;??
  • ????rect.x?=?0;??????
  • ????rect.y?=?0;??????
  • ????rect.w?=?screen_w;??????
  • ????rect.h?=?screen_h;????
  • ????//SDL?End------------------------??
  • ????int?ret,?got_picture;??
  • ??
  • ????AVPacket?*packet=(AVPacket?*)av_malloc(sizeof(AVPacket));??
  • ??
  • #if?OUTPUT_YUV420P???
  • ????FILE?*fp_yuv=fopen("output.yuv","wb+");????
  • #endif????
  • ??
  • ????struct?SwsContext?*img_convert_ctx;??
  • ????img_convert_ctx?=?sws_getContext(pCodecCtx->width,?pCodecCtx->height,?pCodecCtx->pix_fmt,?pCodecCtx->width,?pCodecCtx->height,?AV_PIX_FMT_YUV420P,?SWS_BICUBIC,?NULL,?NULL,?NULL);???
  • ????//------------------------------??
  • ????SDL_Thread?*video_tid?=?SDL_CreateThread(sfp_refresh_thread,NULL);??
  • ????//??
  • ????SDL_WM_SetCaption("Simplest?FFmpeg?Read?Camera",NULL);??
  • ????//Event?Loop??
  • ????SDL_Event?event;??
  • ??
  • ????for?(;;)?{??
  • ????????//Wait??
  • ????????SDL_WaitEvent(&event);??
  • ????????if(event.type==SFM_REFRESH_EVENT){??
  • ????????????//------------------------------??
  • ????????????if(av_read_frame(pFormatCtx,?packet)>=0){??
  • ????????????????if(packet->stream_index==videoindex){??
  • ????????????????????ret?=?avcodec_decode_video2(pCodecCtx,?pFrame,?&got_picture,?packet);??
  • ????????????????????if(ret?<?0){??
  • ????????????????????????printf("Decode?Error.\n");??
  • ????????????????????????return?-1;??
  • ????????????????????}??
  • ????????????????????if(got_picture){??
  • ????????????????????????SDL_LockYUVOverlay(bmp);??
  • ????????????????????????pFrameYUV->data[0]=bmp->pixels[0];??
  • ????????????????????????pFrameYUV->data[1]=bmp->pixels[2];??
  • ????????????????????????pFrameYUV->data[2]=bmp->pixels[1];???????
  • ????????????????????????pFrameYUV->linesize[0]=bmp->pitches[0];??
  • ????????????????????????pFrameYUV->linesize[1]=bmp->pitches[2];?????
  • ????????????????????????pFrameYUV->linesize[2]=bmp->pitches[1];??
  • ????????????????????????sws_scale(img_convert_ctx,?(const?unsigned?char*?const*)pFrame->data,?pFrame->linesize,?0,?pCodecCtx->height,?pFrameYUV->data,?pFrameYUV->linesize);??
  • ??
  • #if?OUTPUT_YUV420P????
  • ????????????????????????int?y_size=pCodecCtx->width*pCodecCtx->height;??????
  • ????????????????????????fwrite(pFrameYUV->data[0],1,y_size,fp_yuv);????//Y?????
  • ????????????????????????fwrite(pFrameYUV->data[1],1,y_size/4,fp_yuv);??//U????
  • ????????????????????????fwrite(pFrameYUV->data[2],1,y_size/4,fp_yuv);??//V????
  • #endif????
  • ??
  • ????????????????????????SDL_UnlockYUVOverlay(bmp);???
  • ??????????????????????????
  • ????????????????????????SDL_DisplayYUVOverlay(bmp,?&rect);???
  • ??
  • ????????????????????}??
  • ????????????????}??
  • ????????????????av_free_packet(packet);??
  • ????????????}else{??
  • ????????????????//Exit?Thread??
  • ????????????????thread_exit=1;??
  • ????????????}??
  • ????????}else?if(event.type==SDL_QUIT){??
  • ????????????thread_exit=1;??
  • ????????}else?if(event.type==SFM_BREAK_EVENT){??
  • ????????????break;??
  • ????????}??
  • ??
  • ????}??
  • ??????
  • ??
  • ????sws_freeContext(img_convert_ctx);??
  • ??
  • #if?OUTPUT_YUV420P???
  • ????fclose(fp_yuv);??
  • #endif???
  • ??
  • ????SDL_Quit();??
  • ??
  • ????//av_free(out_buffer);??
  • ????av_free(pFrameYUV);??
  • ????avcodec_close(pCodecCtx);??
  • ????avformat_close_input(&pFormatCtx);??
  • ??
  • ????return?0;??
  • }??


  • 結(jié)果

    程序的運行效果如下。輸出了攝像頭的數(shù)據(jù)。


    可以通過下面的宏定義來確定是否將解碼后的YUV420P數(shù)據(jù)輸出成文件:
    [cpp]?view plaincopy
  • #define?OUTPUT_YUV420P?0??
  • 可以通過下面的宏定義來確定使用VFW或者是Dshow打開攝像頭:

    [cpp]?view plaincopy
  • //'1'?Use?Dshow???
  • //'0'?Use?VFW??
  • #define?USE_DSHOW?0??

  • 下載


    Simplest FFmpeg Device?


    項目主頁

    SourceForge:https://sourceforge.net/projects/simplestffmpegdevice/

    Github:https://github.com/leixiaohua1020/simplest_ffmpeg_device

    開源中國:http://git.oschina.net/leixiaohua1020/simplest_ffmpeg_device


    CSDN下載地址:

    http://download.csdn.net/detail/leixiaohua1020/7994049

    注:

    ?本工程包含兩個基于FFmpeg的libavdevice的例子:
    ?simplest_ffmpeg_grabdesktop:屏幕錄制。
    ?simplest_ffmpeg_readcamera:讀取攝像頭。


    更新-1.1(2015.1.9)=========================================

    該版本中,修改了SDL的顯示方式,彈出的窗口可以移動了。

    CSDN下載地址:http://download.csdn.net/detail/leixiaohua1020/8344695


    更新-1.2 (2015.2.13)=========================================

    這次考慮到了跨平臺的要求,調(diào)整了源代碼。經(jīng)過這次調(diào)整之后,源代碼可以在以下平臺編譯通過:

    VC++:打開sln文件即可編譯,無需配置。

    cl.exe:打開compile_cl.bat即可命令行下使用cl.exe進行編譯,注意可能需要按照VC的安裝路徑調(diào)整腳本里面的參數(shù)。編譯命令如下。

    [plain]?view plaincopy
  • ::VS2010?Environment??
  • call?"D:\Program?Files\Microsoft?Visual?Studio?10.0\VC\vcvarsall.bat"??
  • ::include??
  • @set?INCLUDE=include;%INCLUDE%??
  • ::lib??
  • @set?LIB=lib;%LIB%??
  • ::compile?and?link??
  • cl?simplest_ffmpeg_readcamera.cpp?/MD?/link?SDL.lib?SDLmain.lib?avcodec.lib?^??
  • avformat.lib?avutil.lib?avdevice.lib?avfilter.lib?postproc.lib?swresample.lib?swscale.lib?^??
  • /SUBSYSTEM:WINDOWS?/OPT:NOREF??
  • MinGW:MinGW命令行下運行compile_mingw.sh即可使用MinGW的g++進行編譯。編譯命令如下。

    [plain]?view plaincopy
  • g++?simplest_ffmpeg_readcamera.cpp?-g?-o?simplest_ffmpeg_readcamera.exe?\??
  • -I?/usr/local/include?-L?/usr/local/lib?\??
  • -lmingw32?-lSDLmain?-lSDL?-lavformat?-lavcodec?-lavutil?-lavdevice?-lswscale??
  • GCC(Linux):Linux命令行下運行compile_gcc.sh即可使用GCC進行編譯。編譯命令如下。

    [plain]?view plaincopy
  • gcc?simplest_ffmpeg_readcamera.cpp?-g?-o?simplest_ffmpeg_readcamera.out?\??
  • -I?/usr/local/include?-L?/usr/local/lib?-lSDLmain?-lSDL?-lavformat?-lavcodec?-lavutil?-lavdevice?-lswscale??
  • GCC(MacOS):MacOS命令行下運行compile_gcc_mac.sh即可使用GCC進行編譯。Mac的GCC和Linux的GCC差別不大,但是使用SDL1.2的時候,必須加上“-framework Cocoa”參數(shù),否則編譯無法通過。編譯命令如下。

    [plain]?view plaincopy
  • gcc?simplest_ffmpeg_readcamera.cpp?-g?-o?simplest_ffmpeg_readcamera.out?\??
  • -framework?Cocoa?-I?/usr/local/include?-L?/usr/local/lib?-lSDLmain?-lSDL?-lavformat?-lavcodec?-lavutil?-lavdevice?-lswscale??

  • PS:相關(guān)的編譯命令已經(jīng)保存到了工程文件夾中

    此外,增加了MacOS下使用avfoundation讀取攝像頭的代碼。

    CSDN下載地址:http://download.csdn.net/detail/leixiaohua1020/8445747

    SourceForge上已經(jīng)更新。

    總結(jié)

    以上是生活随笔為你收集整理的最简单的基于FFmpeg的AVDevice例子(读取摄像头)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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