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

被刻印的时光 ゝ 提交于 2019-11-28 23:56:21

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..

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!