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

socketref,再見!高德

https://github.com/adoggie

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

常用鏈接

留言簿(54)

我參與的團隊

搜索

  •  

最新評論

閱讀排行榜

評論排行榜

項目需求開發網絡流媒體播放器,整個項目就一人開發,整個系統平臺,包括調度,存儲集群服務,影像同步導入、系統api接口、視頻查詢和播放客戶端,一切有了python就變得簡單。一個人在戰斗,還是蠻有勁道。

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

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

C動態庫
結構定義: 
 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 };

實現部分
  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 //圖像格式轉換
 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     // 復制一份
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 : 不釋放內部的 av_free_packet(); 1 - 釋放packet內部數據
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); //并沒有釋放內部的packet數據
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 //跳轉到指定時間 
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 放屁阿狗 閱讀(1555) 評論(0)  編輯 收藏 引用

只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   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>
            亚洲欧美日韩人成在线播放| 久久久久久电影| 亚洲视频一区二区在线观看| 久久精品国产77777蜜臀| 欧美午夜a级限制福利片| 亚洲精品国久久99热| 欧美成人在线免费观看| 久久都是精品| 激情小说另类小说亚洲欧美| 久久精品在线免费观看| 亚洲在线免费| 国产精品视频xxx| 欧美一区二区三区免费观看视频| 99re6热在线精品视频播放速度 | 欧美看片网站| 日韩视频中文| 日韩一级黄色片| 欧美涩涩视频| 午夜精品美女自拍福到在线 | 国产在线不卡| 久久亚洲国产成人| 久久久91精品国产| 亚洲电影免费观看高清完整版在线 | 国产日韩一区二区三区在线| 欧美主播一区二区三区| 欧美一区网站| 亚洲国产精品久久久久| 91久久精品美女高潮| 欧美精品色综合| 一区二区三区四区精品| 亚洲天堂偷拍| 激情视频一区二区三区| 亚洲电影观看| 国产精品久久久| 久久久水蜜桃av免费网站| 老司机一区二区三区| 日韩视频二区| 欧美一级免费视频| 亚洲福利视频在线| 亚洲精品在线免费观看视频| 亚洲激情校园春色| 国产精品日韩精品| 猫咪成人在线观看| 欧美日韩国产综合视频在线观看中文 | 精品动漫3d一区二区三区| 亚洲国产精品一区| 国产欧美精品一区二区三区介绍| 久久久在线视频| 欧美日韩国产精品| 久久人人爽人人| 欧美色图首页| 欧美激情一区二区三区| 国产精品日韩二区| 亚洲国产精品一区二区久 | 亚洲美女电影在线| 亚洲免费婷婷| 亚洲免费成人av| 午夜免费日韩视频| 亚洲免费大片| 久久久最新网址| 欧美一级播放| 欧美日韩精品一区| 欧美成人激情视频| 国产精品自拍在线| 亚洲人成毛片在线播放| 国内精品嫩模av私拍在线观看| 亚洲精品国产欧美| 在线日本成人| 欧美在线观看网站| 亚洲欧美色一区| 欧美日本视频在线| 欧美成人福利视频| 狠狠色狠狠色综合日日tαg| 99av国产精品欲麻豆| 亚洲精品一区二区三区在线观看| 欧美一进一出视频| 亚洲欧美日韩精品久久奇米色影视| 欧美不卡视频| 欧美高清一区| 亚洲国产毛片完整版| 欧美在线观看视频在线 | 久久精品中文| 欧美中在线观看| 国产欧美视频一区二区三区| 99国内精品久久| 中文日韩电影网站| 欧美激情日韩| 亚洲国产日韩欧美综合久久| 亚洲国产乱码最新视频| 久久裸体艺术| 免费亚洲电影在线| 18成人免费观看视频| 久久久久久综合| 欧美成人精品不卡视频在线观看 | 午夜精品久久久久久久99水蜜桃| 一区二区三区黄色| 欧美精品国产精品| 亚洲乱码国产乱码精品精可以看| 亚洲美女啪啪| 欧美日本亚洲视频| 亚洲免费av观看| 亚洲一区二区三区在线视频| 欧美日韩久久久久久| 亚洲美女黄网| 亚洲一区二区精品| 国产美女扒开尿口久久久| 午夜久久tv| 欧美成人免费大片| 亚洲精品国产精品国自产观看| 你懂的成人av| 99国产精品99久久久久久粉嫩 | 亚洲午夜国产一区99re久久 | 欧美在线视频一区二区| 国产一区二区看久久| 久久亚洲图片| 亚洲人成绝费网站色www| 亚洲一区二区不卡免费| 国产精品视频久久久| 欧美在线观看视频一区二区| 欧美激情1区| 亚洲欧美国产视频| 在线免费日韩片| 欧美日韩综合视频网址| 久久激情综合| 亚洲国产精品va在线观看黑人| 一区二区欧美精品| 国产精品视频xxx| 蜜月aⅴ免费一区二区三区| 一区二区av| 免费成人网www| 亚洲一区二区三区乱码aⅴ| 国产一本一道久久香蕉| 欧美激情精品久久久久久黑人| 一区二区国产精品| 久久天堂av综合合色| 亚洲视频中文| 激情综合电影网| 欧美日本一区二区三区| 欧美一级成年大片在线观看| 91久久一区二区| 久久久精品国产免费观看同学| 亚洲精品一区二区在线| 国产欧美综合一区二区三区| 欧美激情1区2区3区| 午夜一区二区三视频在线观看| 亚洲国产成人久久综合一区| 久久成人精品视频| 亚洲自拍偷拍麻豆| 亚洲精品久久久久久久久久久久| 国产精品性做久久久久久| 欧美精品亚洲精品| 久久先锋影音av| 久久av最新网址| 亚洲欧美在线一区二区| 一区二区电影免费在线观看| 欧美黄色网络| 欧美1区视频| 久久在线免费视频| 久久精品国产99国产精品澳门| 亚洲视频高清| 亚洲美女在线看| 欧美午夜a级限制福利片| 你懂的国产精品| 国产精品区一区二区三| 久久伊人精品天天| 欧美在线播放高清精品| 亚洲欧美成人综合| 亚洲伊人第一页| 一区二区三区欧美激情| 亚洲乱码精品一二三四区日韩在线 | 美女黄网久久| 欧美在线日韩在线| 欧美一区二区视频观看视频| 亚洲欧美激情一区二区| 亚洲欧美日本精品| 亚洲综合导航| 亚洲中字黄色| 午夜精品福利一区二区三区av | 在线欧美视频| 国内精品免费午夜毛片| 国内精品久久久久伊人av| 国产欧美日韩不卡| 国产乱肥老妇国产一区二| 国产精品日韩精品欧美精品| 国产日本亚洲高清| 国产日韩欧美一二三区| 黄色欧美成人| 亚洲国产欧美精品| 日韩视频在线永久播放| 一区二区三区欧美| 亚洲欧美不卡| 久久精品国产2020观看福利| 久久精品男女| 欧美99在线视频观看| 亚洲国产精品一区| 在线一区二区三区四区五区| 亚洲欧美一区二区激情| 久久久精品动漫| 欧美国产精品中文字幕| 欧美少妇一区二区|