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

原创 2012年03月31日 09:58:22


H264解码器源码,移植ffmpeg中的H264解码部分到Android,深度删减优化,在模拟器(320x480)中验证通过。

程序的采用jni架构。界面部分,文件读取,视频显示都是用java做的,底层的视频解码用C来做满足速度的要求。

在这个版本中,从H264码流中分割出Nal是在java层做的,这样在java层直接调用解码时就知道是否有显示视频,缺点的就是耦合度/封装性差一点。

如果采用在底层做Nal分割的方法,可以封装得好看一些,但是每次送的数据有限制,如果送的数据太多,底层可能会一次解码出好几帧视频,但是通知到界面层只能显示一帧,造成丢帧的现象。 如果每次送的数据较少,就会有很多次底层调用没有进行实质解码,很小气的做法,比如有一压缩数据帧需要600字节,如果一次送100个字节给解码器,那么要送6次才会进行实质解码,因为每个数据帧有大有小,所以只能取极小值才不会导致丢帧。

不过所有的编码解码都是各种因素平衡折中的结果,具体用什么方法具体分析。

 

 

如果程序崩溃退出,优先考虑:

1)是否是baseline
2)byte [] NalBuf = new byte[40980]; 缓冲区是否溢出。

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

 

 

为便于支持不同分辨率的码流,修改了代码。现在只需要修改H264Android.java文件中第51,74,75行就可测试新分辨率。

有些大分辨率的码流可能会异常,优先修改H264Android.java文件中第161行把Nal缓冲区改大。

 

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

注意 /jni/H264Android.cpp文件添加了extern "C" 关键声明。

 

解码源码下载地址:http://files.cnblogs.com/mcodec/H264Android.7z  

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

 

测试码流(240x320)下载地址:http://files.cnblogs.com/mcodec/butterfly.h264.rar

测试码流(352x288)下载地址:http://files.cnblogs.com/mcodec/352x288.264.7z




把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.o
	gcc $^ -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.h

mpegvideo.o:  avcodec.h common.h dsputil.h mpegvideo.h

clean:
	-rm main *.o


在QT中使用时,修改while中语句就可以把yuv格式转成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格式的图片转成RGB16 格式
                            ,c->width, c->height,picture->linesize[0],picture->linesize[2], iWidth);        
                image= QImage(a1, iWidth, iHeight, QImage::Format_RGB16);   //把RGB16格式图片复制到QImage中!
                widget->update(); //调用刷新   //博客前面"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();
                        }
                        // */
                //}
        }



QT显示解码h264文件显示视频

  • 2017年09月26日 22:16
  • 13.05MB
  • 下载

Qt基于FFmpeg播放本地 H.264(H264)文件

最近在弄H264的硬件编解码,基于DM3730,但是为了调试方便,在小红帽上用FFmpeg实现了H264的软件编解码。现在弄了一个Windows的例子,给需要的同学参考一下,如果大家觉得有帮助,可以小...
  • caoshangpa
  • caoshangpa
  • 2016年07月19日 11:06
  • 5396

Qt基于FFmpeg播放本地 H.264(H264)文件

  • 2016年07月19日 11:21
  • 12.39MB
  • 下载

H.264(H264)解码SPS获取分辨率和帧率

#include #include #include #include typedef unsigned int UINT; typedef unsigned char BYTE; ty...
  • caoshangpa
  • caoshangpa
  • 2016年11月08日 16:24
  • 5266

Qt + ffmpeg 视频解码

1.创建Qt项目,选择编译器为Android_for_armeabi_v7。2.使用之前编译好的ffmpeg头文件和库文件 a.在项目目录创建ffmpeg目录,目录里面包含include目录和lib目...
  • sunvi
  • sunvi
  • 2014年12月17日 17:49
  • 4207

linux下编译ffmpeg,并加入H264编码支持

1.libx264 编译 ./configure --enable-static --disable-asm --prefix=/usr/local/ffmpegRedHat 2.ffmpeg 编译...
  • caoshangpa
  • caoshangpa
  • 2016年05月13日 09:21
  • 3761

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

H264解码器源码,移植ffmpeg中的H264解码部分到Android,深度删减优化,在模拟器(320x480)中验证通过。 程序的采用jni架构。界面部分,文件读取,视频显示都是用java做...
  • feixiaku
  • feixiaku
  • 2013年04月29日 13:46
  • 833

ffmpeg解码RTSP/TCP视频流H.264(QT界面显示视频画面)

我用的ffmpeg版本为 ffmpeg-2.1.8.tar.bz2 版本低了恐怕有些头文件和API找不到。 在Linux下解压后编译,Linux下编译很简单,我这里生成的动态库: ./confi...
  • liukang325
  • liukang325
  • 2015年05月29日 15:40
  • 16176

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

H264解码器源码,移植ffmpeg中的H264解码部分到Android,深度删减优化,在模拟器(320x480)中验证通过。 程序的采用jni架构。界面部分,文件读取,视频显示都是用java做...
  • xyyangkun
  • xyyangkun
  • 2012年03月31日 09:58
  • 2575

H264编解码算法在网络视频传输中的应用

http://www.docin.com/p-80029120.html?docfrom=rrela
  • wishfly
  • wishfly
  • 2017年02月17日 10:41
  • 992
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:H264解码器源码(Android 1.6 版和QT都可以调用)
举报原因:
原因补充:

(最多只允许输入30个字)