青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

socketref,再見!高德

https://github.com/adoggie

  C++博客 :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
  246 Posts :: 4 Stories :: 312 Comments :: 0 Trackbacks

常用鏈接

留言簿(54)

我參與的團隊

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

項目需求開發(fā)網(wǎng)絡(luò)流媒體播放器,整個項目就一人開發(fā),整個系統(tǒng)平臺,包括調(diào)度,存儲集群服務(wù),影像同步導(dǎo)入、系統(tǒng)api接口、視頻查詢和播放客戶端,一切有了python就變得簡單。一個人在戰(zhàn)斗,還是蠻有勁道。

pyqt開發(fā)播放界面,python用于網(wǎng)絡(luò)通信和粘合邏輯,ffmpeg用于解碼,google一圈試用了幾個pyffmpeg的庫,非常不理想,干脆自己做:

采用ctypes訪問dll,測試解碼并將視頻幀轉(zhuǎn)換RGB24寫入PPM文件,imagemagick轉(zhuǎn)換為jpg,okay。。

C動態(tài)庫
結(jié)構(gòu)定義: 
 1 #define FF_BOOL int
 2 #define FF_TRUE 1
 3 #define FF_FALSE 0
 4 
 5 typedef unsigned char  StreamByte_t;
 6 
 7 //視頻流信息
 8 struct MediaStreamInfo_t{
 9     int codec_type;
10     int codec_id;
11     int width;
12     int height;
13     int gopsize;
14     int pixfmt;
15     int tb_num;
16     int tb_den;
17     int bitrate;
18     int frame_number;
19     int videostream; //視頻流編號
20 };
21 
22 struct MediaVideoFrame_t{
23     StreamByte_t *    rgb24;
24     size_t            size;
25     int                width;
26     int                height;
27     unsigned int    sequence; //控制播放順序
28     unsigned int    duration; //播放時間
29 };
30 
31 struct MediaPacket_t{
32      StreamByte_t*    data;
33      size_t            size;
34     AVPacket    *    pkt;
35     int                stream;    //流編號 
36     int                dts;
37     int                pts;
38     size_t            sequence;
39     size_t            duration;
40 
41 };
42 
43 struct MediaFormatContext_t;
44 
45 //解碼器
46 struct MediaCodecContext_t{
47     AVCodecContext * codecCtx;    //AVCodecContext*
48     AVCodec *        codec;    
49     int                stream; //流編號
50     AVFrame *        rgbframe24; //
51     AVFrame*        frame;    //
52     StreamByte_t*    buffer;
53     size_t            bufsize;
54     void *            user;
55     MediaStreamInfo_t si;
56 };
57 
58 struct MediaFormatContext_t{
59     AVFormatContext * fc; //AVFormatContext* 
60     MediaStreamInfo_t video;    //視頻信息
61     
62 };

實現(xiàn)部分
  1 
  2 MEDIACODEC_API   FF_BOOL InitLib(){
  3     avcodec_init();
  4     av_register_all();
  5     return FF_TRUE;
  6 }
  7 
  8 MEDIACODEC_API void Cleanup(){
  9 
 10 }
 11 
 12 MEDIACODEC_API  MediaCodecContext_t* InitAvCodec(MediaStreamInfo_t* si){
 13     MediaCodecContext_t* ctx;
 14     AVCodecContext * codecCtx;
 15     
 16 
 17     codecCtx = avcodec_alloc_context();
 18     codecCtx->width = si->width;
 19     codecCtx->height = si->height;
 20     codecCtx->time_base.num = si->tb_num;
 21     codecCtx->time_base.den = si->tb_den;
 22     codecCtx->bit_rate = si->bitrate;
 23     codecCtx->frame_number = si->frame_number;
 24     codecCtx->codec_type =(AVMediaType) si->codec_type;
 25     codecCtx->codec_id = (CodecID)si->codec_id;
 26 
 27     AVCodec *codec;
 28     codec = avcodec_find_decoder(codecCtx->codec_id);
 29     if(codec == NULL){
 30         //avcodec_free_context()
 31         return NULL;
 32     }
 33     if(avcodec_open(codecCtx, codec)<0){
 34         return NULL;
 35     }
 36 
 37     ctx = new MediaCodecContext_t();
 38     ctx->codecCtx    = codecCtx;
 39     ctx->codec        = codec;
 40     ctx->stream        = si->videostream;
 41     ctx->si = *si;
 42 
 43     uint8_t *buffer;
 44     size_t numBytes;
 45     ctx->rgbframe24 = avcodec_alloc_frame();
 46     ctx->frame =  avcodec_alloc_frame();
 47 
 48     numBytes=avpicture_get_size(PIX_FMT_RGB24, codecCtx->width,codecCtx->height);
 49     buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
 50     ctx->buffer = (StreamByte_t*)buffer;
 51     ctx->bufsize = numBytes;
 52 
 53     avpicture_fill((AVPicture *)ctx->rgbframe24, buffer, PIX_FMT_RGB24,codecCtx->width, codecCtx->height); // bind buffer with frame
 54 
 55     return ctx;
 56 }
 57 
 58 
 59 MEDIACODEC_API void FreeAvCodec(MediaCodecContext_t* ctx){
 60     AVCodecContext * codecCtx;
 61     AVCodec *codec;
 62     codecCtx = (AVCodecContext*) ctx->codecCtx;
 63     codec = (AVCodec*) ctx->codec;
 64     avcodec_close(codecCtx);
 65     
 66     av_free(ctx->buffer);
 67     av_free(ctx->rgbframe24);
 68     av_free(ctx->frame);
 69     delete ctx;
 70 }
 71 
 72 
 73 //圖像格式轉(zhuǎn)換
 74 int convert_picture(AVFrame *rgbframe, AVFrame *frame, int width, int height, PixelFormat format,PixelFormat toformat){
 75     struct SwsContext *sws;
 76 
 77     if (format == PIX_FMT_YUV420P){        
 78         sws = sws_getContext(width, height, format, width, height, toformat, SWS_FAST_BILINEAR, NULL, NULL, NULL);
 79         if (sws == 0){
 80             return -1;
 81         }
 82         if (sws_scale(sws, frame->data, frame->linesize, 0, height, rgbframe->data, rgbframe->linesize)){
 83             //return -1;
 84         }
 85     }else{
 86         return -1;
 87     }
 88     return 0;
 89 }
 90 
 91 MEDIACODEC_API MediaVideoFrame_t * DecodeVideoFrame(MediaCodecContext_t* ctx,MediaPacket_t* pkt){
 92     MediaVideoFrame_t * frame;
 93     
 94     if(pkt->stream != ctx->stream){
 95         return NULL;
 96     }
 97     int frameFinished;
 98     
 99     AVCodecContext* codecCtx;
100     codecCtx = (AVCodecContext*)ctx->codecCtx;
101 
102     avcodec_decode_video(codecCtx, ctx->frame, &frameFinished,pkt->data, pkt->size);
103     if( !frameFinished ){
104         return NULL;
105     }
106     int r;
107     r = convert_picture(ctx->rgbframe24,ctx->frame,codecCtx->width,codecCtx->height,codecCtx->pix_fmt,PIX_FMT_RGB24);
108     if(r){
109         return NULL;
110     }
111     // 復(fù)制一份
112     frame = new MediaVideoFrame_t();
113     frame->rgb24 = (StreamByte_t*)malloc(ctx->bufsize);
114     frame->size =ctx->bufsize;
115     memcpy(frame->rgb24,ctx->buffer,ctx->bufsize);
116     frame->width = ctx->frame->width;
117     frame->height = ctx->frame->height;
118     frame->sequence = pkt->sequence;
119     frame->duration = pkt->duration;
120 
121     return frame;
122 }
123 
124 MEDIACODEC_API void FreeVideoFrame(MediaVideoFrame_t* frame){
125     if(frame->rgb24){
126         free(frame->rgb24);
127     }
128     delete frame;
129 }
130 
131 MEDIACODEC_API MediaPacket_t * AllocPacket(){
132     MediaPacket_t *pkt;
133 
134     pkt = new MediaPacket_t();
135     pkt->pkt =new AVPacket();
136     pkt->size = 0;
137     pkt->data = NULL;
138     pkt->stream = -1;
139     return pkt;
140 }
141 
142 // s - 0 : 不釋放內(nèi)部的 av_free_packet(); 1 - 釋放packet內(nèi)部數(shù)據(jù)
143 MEDIACODEC_API void FreePacket(MediaPacket_t* pkt,int s){
144     AVPacket* packet;
145     packet = pkt->pkt;
146     if(s){
147         av_free_packet(packet);
148     }
149     delete packet;
150     delete pkt;
151 }
152 
153 
154 MEDIACODEC_API MediaFormatContext_t* InitAvFormatContext(char * file){
155     MediaFormatContext_t* ctx;
156     AVFormatContext *ic;
157     int videoStream=-1;
158     unsigned int i;
159     AVCodecContext *codecCtx;
160 
161 
162     
163     
164     ic = avformat_alloc_context();
165     if(avformat_open_input(&ic, file, NULL,NULL)!=0){
166         avformat_free_context(ic);
167         return NULL; 
168     }
169     
170     if(av_find_stream_info(ic)<0){//查詢文件流信息
171         avformat_free_context(ic);
172         return NULL;
173     }
174     
175     
176     for(i=0; i < ic->nb_streams; i++){
177         if(ic->streams[i]->codec->codec_type== CODEC_TYPE_VIDEO) {
178             videoStream=i;
179             break;
180         }
181     }
182     if( videoStream ==-1){
183         avformat_free_context(ic);
184         return NULL;
185     }
186     codecCtx = ic->streams[videoStream]->codec;
187 
188     ctx = new MediaFormatContext_t();
189     ctx->fc = ic;
190     ctx->video.codec_type = (int)CODEC_TYPE_VIDEO;
191     ctx->video.codec_id = (int)codecCtx->codec_id;
192     ctx->video.bitrate = codecCtx->bit_rate;
193     ctx->video.frame_number = codecCtx->frame_number;
194     ctx->video.gopsize = codecCtx->gop_size;
195     ctx->video.height = codecCtx->height;
196     ctx->video.pixfmt = codecCtx->pix_fmt;
197     ctx->video.tb_den = codecCtx->time_base.den;
198     ctx->video.tb_num = codecCtx->time_base.num;
199     ctx->video.width = codecCtx->width;
200     ctx->video.videostream = videoStream;
201     return ctx;
202 }
203 
204 MEDIACODEC_API void FreeAvFormatContext(MediaFormatContext_t* ctx){
205     if(ctx->fc){
206         avformat_free_context((AVFormatContext*)ctx->fc);
207     }
208     delete ctx;
209 }
210 
211 MEDIACODEC_API MediaPacket_t* ReadNextPacket(MediaFormatContext_t* ctx){
212     MediaPacket_t* pkt = NULL;
213     
214     while(1){
215         pkt = AllocPacket();
216         if( pkt == NULL){
217             return NULL;
218         }
219         if( av_read_frame((AVFormatContext*)ctx->fc, (AVPacket*)pkt->pkt) <0 ){
220             FreePacket(pkt,0); //并沒有釋放內(nèi)部的packet數(shù)據(jù)
221             //printf("read_fream error!\n");
222             return NULL;
223         }
224         if( ctx->video.videostream == pkt->pkt->stream_index){
225             pkt->data = pkt->pkt->data;
226             pkt->size = pkt->pkt->size;
227             pkt->stream = pkt->pkt->stream_index;
228             pkt->duration = pkt->pkt->duration;
229             return pkt;    
230         }        
231         FreePacket(pkt,1);
232     }
233 
234     return NULL;
235 }
236 
237 MEDIACODEC_API void FlushBuffer(MediaCodecContext_t* codec){
238     avcodec_flush_buffers(codec->codecCtx);
239 }
240 
241 
242 //跳轉(zhuǎn)到指定時間 
243 MEDIACODEC_API int SeekToTime(MediaFormatContext_t* ctx,int timesec){
244 //avcodec_flush_buffers(pFormatCtx->streams[video_stream]->codec);
245     
246     if( av_seek_frame(ctx->fc,-1,timesec*AV_TIME_BASE,AVSEEK_FLAG_BACKWARD)<0){
247         return -1;
248     }
249     //avcodec_flush_buffers(ctx->streams[video_stream]->codec);
250     return 0;
251 }
252 
253 MEDIACODEC_API void ReadReset(MediaFormatContext_t* ctx){
254     SeekToTime(ctx,0);
255 }
256 

python測試代碼: 

 1 
 2 import ffmpeg
 3 
 4 
 5 def printStreamInfo(s):
 6     print s.codec_type,'codec_id:',s.codec_id,\
 7         'width:',s.width,'height:',s.height,\
 8         'gopsize:',s.gopsize,'pixfmt:',s.pixfmt,\
 9         'timebase_num:',s.tb_num,'timebase_den:',s.tb_den,\
10         'bitrate:',s.bitrate,'framenumber:',s.frame_number,\
11         'streamindex:',s.videostream
12 
13 def printFrameInfo(f):
14     print len(f.rgb24[:f.size]),'width:',f.width,'height:',f.height,'duration:',f.duration,'size:',f.size
15     
16 
17 def saveppm(f,file):
18     fp = open(file,'wb')
19     if not fp:
20         return
21     fp.write( "P6\n%d %d\n255\n"%(f.width,f.height) )
22     fp.write(f.rgb24[:f.size])
23     fp.close()
24     print file
25         
26     
27 ffmpeg.InitLib()
28 fc =  ffmpeg.InitAvFormatContext('d:/movies/marieMcCray.avi')
29 printStreamInfo(fc.contents.video)
30 bytes=0
31 codec = ffmpeg.InitAvCodec(fc.contents.video)
32 print codec #apply a codec
33 
34 cnt=0
35 while True:
36     pkt = ffmpeg.ReadNextPacket(fc)
37     if not pkt:break
38     bytes += pkt.contents.size
39     frame = ffmpeg.DecodeVideoFrame(codec,pkt)
40     if frame:
41         cnt+=1
42         printFrameInfo(frame.contents)
43         if cnt < 100:
44             saveppm(frame.contents,"d:/temp4/%s_xx.ppm"%cnt)
45             os.system('convertx %s %s'%("d:/temp4/%s_xx.ppm"%cnt,"d:/temp4/%s_xx.jpg"%cnt))
46         ffmpeg.FreeVideoFrame(frame) #memory leak
47     print pkt.contents.stream,pkt.contents.size,pkt.contents.duration
48     ffmpeg.FreePacket(pkt,1)
49 







posted on 2012-03-15 02:01 放屁阿狗 閱讀(1554) 評論(0)  編輯 收藏 引用

只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲久久一区| 亚洲精品国精品久久99热| 在线午夜精品| 欧美a级一区| 亚洲一区二区三区成人在线视频精品| 久久久久久久久久久一区| 国产精品日本一区二区| 在线视频欧美一区| 一级成人国产| 亚洲高清色综合| 女人香蕉久久**毛片精品| 在线色欧美三级视频| 免费不卡亚洲欧美| 久久精品国产99国产精品| 欧美成人精品一区| 亚洲精品欧美日韩专区| 欧美日韩国产成人在线观看| 日韩写真在线| 欧美日韩www| 欧美一区二区高清在线观看| 国产农村妇女精品一二区| 欧美一区国产一区| 欧美一区二区三区免费看| 国产午夜亚洲精品羞羞网站| 久久久久久久999| 久久深夜福利| 亚洲国产一区二区在线| 亚洲精品网站在线播放gif| 欧美吻胸吃奶大尺度电影| 欧美一二三区在线观看| 久久久亚洲国产天美传媒修理工| 你懂的成人av| 一本久道久久综合婷婷鲸鱼 | 久久久7777| 亚洲人成绝费网站色www| 日韩亚洲视频| 一区二区三区四区五区精品视频| 亚洲七七久久综合桃花剧情介绍| 欧美日韩三区| 欧美有码视频| 蜜臀av性久久久久蜜臀aⅴ四虎 | 亚洲精品午夜精品| 国产欧美精品日韩| 亚洲电影在线看| 国产精品久久久久av| 久久综合网色—综合色88| 欧美激情在线免费观看| 欧美伊人久久久久久久久影院| 久久久国产视频91| 亚洲网站在线观看| 久久影视精品| 欧美一区二区三区精品| 免费美女久久99| 国产美女精品| 欧美激情一区| 国产午夜精品福利| 亚洲日本久久| 伊伊综合在线| 亚洲一区中文字幕在线观看| 亚洲高清一二三区| 国产精品热久久久久夜色精品三区 | 欧美在线视频二区| 亚洲一二区在线| 乱码第一页成人| 久久国产精品一区二区| 欧美四级在线观看| 亚洲国产高清视频| 激情小说亚洲一区| 亚洲综合三区| 亚洲一区在线视频| 欧美极品色图| 亚洲国产精品传媒在线观看| 久久精品亚洲精品| 欧美一区三区二区在线观看| 欧美另类视频在线| 欧美黄色视屏| 激情一区二区| 欧美综合激情网| 欧美成人官网二区| 伊人久久大香线蕉综合热线| 亚洲免费一级电影| 亚洲欧美日韩精品一区二区 | 中国亚洲黄色| 欧美美女操人视频| 亚洲国产精品一区二区久| 在线观看亚洲精品| 久久先锋影音av| 免费在线观看精品| 精品91免费| 久久综合亚洲社区| 鲁大师成人一区二区三区| 红杏aⅴ成人免费视频| 欧美在线免费观看| 久久性天堂网| 久久国产免费看| 久久久久久一区二区| 国产一区二三区| 久久精品视频亚洲| 欧美在线视频一区二区| 国产人妖伪娘一区91| 一本色道久久综合亚洲精品小说| 欧美电影在线免费观看网站| 亚洲国产欧美一区二区三区久久| 久久香蕉国产线看观看网| 欧美激情欧美激情在线五月| 亚洲日本va午夜在线电影 | 在线视频欧美精品| 国产精品成人免费| 欧美一区二区久久久| 久久综合九色| 亚洲乱码国产乱码精品精可以看| 欧美日韩高清在线观看| 亚洲素人一区二区| 久久久久综合| 亚洲精品网址在线观看| 欧美视频在线免费看| 久久久久成人精品免费播放动漫| 国产专区欧美精品| 欧美成熟视频| 亚洲尤物视频在线| 免费成人毛片| 国产精品99久久久久久白浆小说| 国产伦精品一区二区三区视频黑人 | 欧美日韩性视频在线| 中文一区二区| 久久久天天操| 一本久久a久久精品亚洲| 国产精品男女猛烈高潮激情| 欧美中文字幕不卡| 亚洲免费大片| 老司机午夜精品视频| 制服丝袜激情欧洲亚洲| 国产一区免费视频| 欧美午夜精品久久久久久久| 久久精品视频在线播放| 亚洲蜜桃精久久久久久久| 久久精品一本久久99精品| 日韩一区二区高清| 国产真实乱偷精品视频免| 亚洲欧洲精品一区二区三区| 亚洲在线观看免费视频| 狠狠色2019综合网| 欧美色精品在线视频| 麻豆成人在线播放| 欧美亚洲三级| 一区二区高清视频| 国产精品狠色婷| 亚洲精品一二区| 男男成人高潮片免费网站| 亚洲欧美另类中文字幕| 91久久精品国产| 精品999网站| 国产精品日韩久久久| 欧美日本中文字幕| 免费日韩成人| 久久一区亚洲| 欧美一区二区三区另类| 亚洲一区999| 亚洲精品日韩久久| 亚洲国产成人不卡| 免费欧美高清视频| 米奇777在线欧美播放| 久久久91精品国产| 欧美一区二区精品| 午夜一级久久| 午夜一区二区三区不卡视频| 亚洲免费视频一区二区| 在线视频一区二区| 亚洲乱码久久| 欧美日韩成人一区二区| 欧美成人国产一区二区| 久久免费视频在线观看| 久久久在线视频| 久久久精品网| 久久久久99精品国产片| 久久久久久婷| 久久久噜噜噜久久中文字免| 在线综合亚洲欧美在线视频| 国产精品二区三区四区| 欧美午夜电影在线| 欧美视频三区在线播放| 欧美视频在线观看 亚洲欧| 国产精品进线69影院| 国产精品一区二区三区久久| 国产欧美一区二区精品性| 国产欧美综合在线| 韩国三级电影久久久久久| 在线播放豆国产99亚洲| 亚洲国产三级| 一区二区三区日韩精品| 亚洲欧美精品中文字幕在线| 久久爱另类一区二区小说| 久久人人看视频| 欧美国产日韩二区| 亚洲精品网址在线观看| 亚洲一区二区免费| 久久精品国产91精品亚洲| 欧美电影电视剧在线观看| 欧美午夜视频| 狠狠干综合网|