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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > Android >内容正文

Android

H264解码器源码(Android 1.6 版和QT都可以调用)

發(fā)布時(shí)間:2024/9/5 Android 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 H264解码器源码(Android 1.6 版和QT都可以调用) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.


H264解碼器源碼,移植ffmpeg中的H264解碼部分到Android,深度刪減優(yōu)化,在模擬器(320x480)中驗(yàn)證通過(guò)。

程序的采用jni架構(gòu)。界面部分,文件讀取,視頻顯示都是用java做的,底層的視頻解碼用C來(lái)做滿足速度的要求。

在這個(gè)版本中,從H264碼流中分割出Nal是在java層做的,這樣在java層直接調(diào)用解碼時(shí)就知道是否有顯示視頻,缺點(diǎn)的就是耦合度/封裝性差一點(diǎn)。

如果采用在底層做Nal分割的方法,可以封裝得好看一些,但是每次送的數(shù)據(jù)有限制,如果送的數(shù)據(jù)太多,底層可能會(huì)一次解碼出好幾幀視頻,但是通知到界面層只能顯示一幀,造成丟幀的現(xiàn)象。 如果每次送的數(shù)據(jù)較少,就會(huì)有很多次底層調(diào)用沒(méi)有進(jìn)行實(shí)質(zhì)解碼,很小氣的做法,比如有一壓縮數(shù)據(jù)幀需要600字節(jié),如果一次送100個(gè)字節(jié)給解碼器,那么要送6次才會(huì)進(jìn)行實(shí)質(zhì)解碼,因?yàn)槊總€(gè)數(shù)據(jù)幀有大有小,所以只能取極小值才不會(huì)導(dǎo)致丟幀。

不過(guò)所有的編碼解碼都是各種因素平衡折中的結(jié)果,具體用什么方法具體分析。

?

?

如果程序崩潰退出,優(yōu)先考慮:

1)是否是baseline
2)byte [] NalBuf = new byte[40980]; 緩沖區(qū)是否溢出。

如果有B幀,那肯定不是baseline。

?

?

為便于支持不同分辨率的碼流,修改了代碼?,F(xiàn)在只需要修改H264Android.java文件中第51,74,75行就可測(cè)試新分辨率。

有些大分辨率的碼流可能會(huì)異常,優(yōu)先修改H264Android.java文件中第161行把Nal緩沖區(qū)改大。

?

兩版本都是用 android-ndk-1.6_r1-windows.zip 和 cygwin 1.7.5-1, gcc4 4.3.4-3 (用 cygcheck -c查看) 編譯。

注意 /jni/H264Android.cpp文件添加了extern "C" 關(guān)鍵聲明。

?

解碼源碼下載地址:http://files.cnblogs.com/mcodec/H264Android.7z??

C++版本下載地址:http://files.cnblogs.com/mcodec/H264Android_CPP.7z

?

測(cè)試碼流(240x320)下載地址:http://files.cnblogs.com/mcodec/butterfly.h264.rar

測(cè)試碼流(352x288)下載地址:http://files.cnblogs.com/mcodec/352x288.264.7z

以上轉(zhuǎn)自:http://www.cnblogs.com/mcodec/articles/1780598.html

我的下載地址:http://download.csdn.net/detail/xyyangkun/4188806

把common.h改下就可以用gcc編譯了! 下面是common.h改后的文件的修改的部分: #ifndef COMMON_H #define COMMON_H#define WINCE #define HAVE_AV_CONFIG_H #define EMULATE_INTTYPES#define inline __inline#define ALT_BITSTREAM_READER#define LIBMPEG2_BITSTREAM_READER_HACK //add BERO#include <stdlib.h> #include <stdio.h> #include <string.h> #include <ctype.h>///* typedef signed char int8_t; typedef signed short int16_t; typedef signed int int32_t; typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t;typedef signed long long int64_t; typedef unsigned long long uint64_t;// */ 下面是makefile文件: main: cabac.o common.o dsputil.o golomb.o h264.o h264utils.o mpegvideo.o main.ogcc $^ -o $@ main.o: main.c cabac.o: common.h cabac.h common.o: avcodec.h common.h dsputil.o: common.h avcodec.h dsputil.h golomb.o: common.h h264.o: common.h avcodec.h h264.h dsputil.h mpegvideo.h h264data.h \golomb.h cabac.h h264utils.o: avcodec.h common.h dsputil.h mpegvideo.h h264.h \h264data.h golomb.h cabac.hmpegvideo.o: avcodec.h common.h dsputil.h mpegvideo.hclean:-rm main *.o

在QT中使用時(shí),修改while中語(yǔ)句就可以把yuv格式轉(zhuǎn)成QT中QImage類,用于顯示了。

while(!feof(inpf)) { nalLen = getNextNal(inpf, Buf); consumed_bytes= decode_frame(c, picture, &got_picture, Buf, nalLen); printf("ddd6\n"); #if 1 unsigned char a1[1000000];//保存RGB16 memset(a1, 0, sizeof(a1)); char *pppp=(char *)(picture->data); DisplayYUV_16((unsigned int *)a1, picture->data[0], picture->data[1], picture->data[2] //把AVFrame格式的圖片轉(zhuǎn)成RGB16 格式 ,c->width, c->height,picture->linesize[0],picture->linesize[2], iWidth); image= QImage(a1, iWidth, iHeight, QImage::Format_RGB16); //把RGB16格式圖片復(fù)制到QImage中! widget->update(); //調(diào)用刷新 //博客前面"qt界面刷新屏幕"有講 printf("update1 0k\n"); usleep(100000); //continue; #endif #if 0 //* for(i=0; i<c->height; i++) fwrite(picture->data[0] + i * picture->linesize[0], 1, c->width, outf); for(i=0; i<c->height/2; i++) fwrite(picture->data[1] + i * picture->linesize[1], 1, c->width/2, outf); for(i=0; i<c->height/2; i++) fwrite(picture->data[2] + i * picture->linesize[2], 1, c->width/2, outf); //return 0; // */ #endif /* if(iBytesPixel==2) { unsigned int *rgb = (unsigned int*)(iDDraw->BeginDraw()); DisplayYUV_16(rgb, picture->data[0], picture->data[1], picture->data[2], c->width, c->height, picture->linesize[0], picture->linesize[1], iWidth); iDDraw->EndDraw(); } else if(iBytesPixel==3) { unsigned char *rgb = (unsigned char*)(iDDraw->BeginDraw()); DisplayYUV_24(rgb, picture->data[0], picture->data[1], picture->data[2], c->width, c->height, picture->linesize[0], picture->linesize[1], iWidth); iDDraw->EndDraw(); } else if(iBytesPixel==4) { unsigned int *rgb = (unsigned int*)(iDDraw->BeginDraw()); DisplayYUV_32(rgb, picture->data[0], picture->data[1], picture->data[2], c->width, c->height, picture->linesize[0], picture->linesize[1], iWidth); iDDraw->EndDraw(); } // */ //} }


與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的H264解码器源码(Android 1.6 版和QT都可以调用)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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