Javacv: Decoding H.264 “live” stream coming from red5 server on android device

后端 未结 1 1617
盖世英雄少女心
盖世英雄少女心 2020-12-15 12:27

Here is my problem, I have implemented a server side application using Red5, which sends H.264 encoded live stream, on client side the stream is received as byte[]
In or

相关标签:
1条回答
  • 2020-12-15 12:53

    Atlast... finally got to working after lots of RnD.
    What i am missing is alalyze the video frame structure. Video is made up of "I" , "P" frames.. "I" frame is information frame, which stores the information about next subsequent frames. "P" frame is picture frame, which holds actual video frame...
    So i need to decode the "P" frames w.r.t information in "I" frame.. So the final code is something as follows

    public IplImage decodeFromVideo(byte[] data, long timeStamp) {
    avcodec.av_init_packet(reveivedVideoPacket); // Empty AVPacket
    /*
     * Determine if the frame is a Data Frame or Key. IFrame 1 = PFrame 0 = Key
     * Frame
     */
    byte frameFlag = data[1];
    byte[] subData = Arrays.copyOfRange(data, 5, data.length);
    
    BytePointer videoData = new BytePointer(subData);
    if (frameFlag == 0) {
        avcodec.AVCodec codec = avcodec
                .avcodec_find_decoder(avcodec.AV_CODEC_ID_H264);
        if (codec != null) {
            videoCodecContext = null;
            videoCodecContext = avcodec.avcodec_alloc_context3(codec);
            videoCodecContext.width(320);
            videoCodecContext.height(240);
            videoCodecContext.pix_fmt(avutil.AV_PIX_FMT_YUV420P);
            videoCodecContext.codec_type(avutil.AVMEDIA_TYPE_VIDEO);
            videoCodecContext.extradata(videoData);
            videoCodecContext.extradata_size(videoData.capacity());
    
            videoCodecContext.flags2(videoCodecContext.flags2()
                    | avcodec.CODEC_FLAG2_CHUNKS);
            avcodec.avcodec_open2(videoCodecContext, codec,
                    (PointerPointer) null);
    
            if ((videoCodecContext.time_base().num() > 1000)
                    && (videoCodecContext.time_base().den() == 1)) {
                videoCodecContext.time_base().den(1000);
            }
        } else {
            Log.e("test", "Codec could not be opened");
        }
    }
    
    if ((decodedPicture = avcodec.avcodec_alloc_frame()) != null) {
        if ((processedPicture = avcodec.avcodec_alloc_frame()) != null) {
            int width = getImageWidth() > 0 ? getImageWidth()
                    : videoCodecContext.width();
            int height = getImageHeight() > 0 ? getImageHeight()
                    : videoCodecContext.height();
    
            switch (imageMode) {
            case COLOR:
            case GRAY:
                int fmt = 3;
                int size = avcodec.avpicture_get_size(fmt, width, height);
                processPictureBuffer = new BytePointer(
                        avutil.av_malloc(size));
                avcodec.avpicture_fill(new AVPicture(processedPicture),
                        processPictureBuffer, fmt, width, height);
                returnImageFrame = opencv_core.IplImage.createHeader(320,
                        240, 8, 1);
                break;
            case RAW:
                processPictureBuffer = null;
                returnImageFrame = opencv_core.IplImage.createHeader(320,
                        240, 8, 1);
                break;
            default:
                Log.d("showit",
                        "At default of swith case 1.$SwitchMap$com$googlecode$javacv$FrameGrabber$ImageMode[ imageMode.ordinal()]");
            }
    
            reveivedVideoPacket.data(videoData);
            reveivedVideoPacket.size(videoData.capacity());
    
            reveivedVideoPacket.pts(timeStamp);
            videoCodecContext.pix_fmt(avutil.AV_PIX_FMT_YUV420P);
            decodedFrameLength = avcodec.avcodec_decode_video2(videoCodecContext,
                    decodedPicture, isVideoDecoded, reveivedVideoPacket);
    
    if ((decodedFrameLength >= 0) && (isVideoDecoded[0] != 0)) {
     .... Process image same as javacv .....
    }
    

    Hope it wil help others..

    0 讨论(0)
提交回复
热议问题