H264 Decoder Source code (Android version 1.6 and QT can be called)

Source: Internet
Author: User


H264 decoder source code, porting the H264 decoding part of the FFmpeg to Android, depth pruning optimization, in the simulator (320x480) validated through.

The application of the JNI architecture. Interface section, file reading, video display is done in Java, the bottom of the video decoding with C to do to meet the speed requirements.

In this release, the NAL from the H264 stream is done in the Java layer, so that when the Java layer calls the decoding directly it knows if there is a video, the disadvantage is that the coupling/encapsulation is a little bit worse.

If used in the bottom do nal segmentation method, can be packaged better, but each send the data has restrictions, if send too much data, the bottom may be decoded several frames of video, but notice to the interface layer can only show a frame, causing the phenomenon of drop frame. If you send less data at a time, there will be many times the underlying call does not have a real decoding, very stingy practice, such as a compressed data frames need 600 bytes, if send 100 bytes to the decoder, then send 6 times before the real decoding, because each data frame has a great deal of small, Therefore, only the minimum value will not cause drop frames.

However, all the coding and decoding are the results of the balance of various factors, concrete analysis of what method.

If the program crashes and exits, it is preferred:

1) Whether it is baseline
2) byte [] nalbuf = new byte[40980]; Whether the buffer overflows.

If there's a frame B, it's definitely not baseline.

To facilitate support for different resolution of the code flow, the code has been modified. Now you just need to modify the first 51,74,75 line in the H264android.java file to test the new resolution.

Some large resolution of the code flow may be abnormal, the first modification of the H264android.java file in the 161th line of the NAL buffer to large.

Both versions are compiled with Android-ndk-1.6_r1-windows.zip and Cygwin 1.7.5-1, Gcc4 4.3.4-3 (viewed with cygcheck-c).

Note The/jni/h264android.cpp file adds an extern "C" key statement.

Decoding source download Address: http://files.cnblogs.com/mcodec/H264Android.7z

C + + version download address: http://files.cnblogs.com/mcodec/H264Android_CPP.7z

Test Stream (240x320) Download address: Http://files.cnblogs.com/mcodec/butterfly.h264.rar

Test Stream (352x288) Download address: http://files.cnblogs.com/mcodec/352x288.264.7z more than: http://www.cnblogs.com/mcodec/articles/1780598.html

My download Address: http://download.csdn.net/detail/xyyangkun/4188806

Change the common.h and you can compile it with GCC. The following is the modified part of the Common.h file:

#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;

// */
Here is the makefile file:
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
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

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

:
	-rm main *.O


when used in Qt, modifying a while statement can turn the YUV format into the Qimage class in Qt for display.

        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];//save 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]// Turn the avframe format picture into RGB16 format
                            , C->width, c->height,picture->linesize[0],picture->linesize[2], iwidth);        
                Image= QImage (A1, Iwidth, Iheight, QIMAGE::FORMAT_RGB16);   Copy the RGB16 format picture to the Qimage.
                Widget->update (); Call Refresh   //Blog front "QT Interface Refresh screen" There is talk
                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 ();
                        }
                        // */
                //}
        }


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.