Android h264 decode non-existing PPS 0 referenced

允我心安 提交于 2019-12-11 04:13:40

问题


In Android JNI, using ffmpeg with libx264 use below codes to encode and decode raw rgb data!. I should use swscale to convert rgb565 to yuv420p as required by H.264. But not clear about this conversion.Please help, where i am wrong, with regard the log i get!

Code for Encoding

codecinit()- called once(JNI wrapper function)

int Java_com_my_package_codecinit (JNIEnv *env, jobject thiz) {
avcodec_register_all();
codec = avcodec_find_encoder(AV_CODEC_ID_H264);//AV_CODEC_ID_MPEG1VIDEO);
if(codec->id == AV_CODEC_ID_H264)
    __android_log_write(ANDROID_LOG_ERROR, "set","h264_encoder");

if (!codec) {
    fprintf(stderr, "codec not found\n");
    __android_log_write(ANDROID_LOG_ERROR, "codec", "not found");

}
    __android_log_write(ANDROID_LOG_ERROR, "codec", "alloc-contest3");
c= avcodec_alloc_context3(codec);
if(c == NULL)
    __android_log_write(ANDROID_LOG_ERROR, "avcodec","context-null");

picture= av_frame_alloc();

if(picture == NULL)
    __android_log_write(ANDROID_LOG_ERROR, "picture","context-null");

c->bit_rate = 400000;
c->height = 800;
c->time_base= (AVRational){1,25};
c->gop_size = 10; 
c->max_b_frames=1;
c->pix_fmt = AV_PIX_FMT_YUV420P;
outbuf_size = 768000;
c->width = 480;

size = (c->width * c->height);

if (avcodec_open2(c, codec,NULL) < 0) {

__android_log_write(ANDROID_LOG_ERROR, "codec", "could not open");


}

ret = av_image_alloc(picture->data, picture->linesize, c->width, c->height,
                     c->pix_fmt, 32);
if (ret < 0) {
        __android_log_write(ANDROID_LOG_ERROR, "image","alloc-failed");
    fprintf(stderr, "could not alloc raw picture buffer\n");

}

picture->format = c->pix_fmt;
picture->width  = c->width;
picture->height = c->height;
return 0;

}

encodeframe()-called in a while loop

int Java_com_my_package_encodeframe (JNIEnv *env, jobject thiz,jbyteArray buffer) {
jbyte *temp= (*env)->GetByteArrayElements(env, buffer, 0);
Output = (char *)temp;
const uint8_t * const inData[1] = { Output }; 
const int inLinesize[1] = { 2*c->width };

//swscale should implement here

    av_init_packet(&pkt);
    pkt.data = NULL;    // packet data will be allocated by the encoder
    pkt.size = 0;

    fflush(stdout);
picture->data[0] = Output;
ret = avcodec_encode_video2(c, &pkt, picture,&got_output);

    fprintf(stderr,"ret = %d, got-out = %d \n",ret,got_output);
     if (ret < 0) {
                __android_log_write(ANDROID_LOG_ERROR, "error","encoding");
        if(got_output > 0)
        __android_log_write(ANDROID_LOG_ERROR, "got_output","is non-zero");

    }

    if (got_output) {
        fprintf(stderr,"encoding frame %3d (size=%5d): (ret=%d)\n", 1, pkt.size,ret);
        fprintf(stderr,"before caling decode");
        decode_inline(&pkt); //function that decodes right after the encode
        fprintf(stderr,"after caling decode");


        av_free_packet(&pkt);
    }


fprintf(stderr,"y val: %d \n",y);


(*env)->ReleaseByteArrayElements(env, buffer, Output, 0);
return ((ret));
}

decode_inline() function

decode_inline(AVPacket *avpkt){
AVCodec *codec;
AVCodecContext *c = NULL;
int frame, got_picture, len = -1,temp=0;

AVFrame *rawFrame, *rgbFrame;
uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
char buf[1024];
char rawBuf[768000],rgbBuf[768000];

struct SwsContext *sws_ctx;

memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
avcodec_register_all();

c= avcodec_alloc_context3(codec);
if(c == NULL)
    __android_log_write(ANDROID_LOG_ERROR, "avcodec","context-null");

codec = avcodec_find_decoder(AV_CODEC_ID_H264);
if (!codec) {
    fprintf(stderr, "codec not found\n");
    fprintf(stderr, "codec = %p \n", codec);
    }
c->pix_fmt = AV_PIX_FMT_YUV420P;
c->width = 480;
c->height = 800;

rawFrame = av_frame_alloc();
rgbFrame = av_frame_alloc();

if (avcodec_open2(c, codec, NULL) < 0) {
    fprintf(stderr, "could not open codec\n");
    exit(1);
    }
sws_ctx = sws_getContext(c->width, c->height,/*PIX_FMT_RGB565BE*/
            PIX_FMT_YUV420P, c->width, c->height, AV_PIX_FMT_RGB565/*PIX_FMT_YUV420P*/,
            SWS_BILINEAR, NULL, NULL, NULL);


frame = 0;

unsigned short *decodedpixels = &rawBuf;
rawFrame->data[0] = &rawBuf;
rgbFrame->data[0] = &rgbBuf;

fprintf(stderr,"size of avpkt %d \n",avpkt->size);
temp = avpkt->size;
while (temp > 0) {
        len = avcodec_decode_video2(c, rawFrame, &got_picture, avpkt);

        if (len < 0) {
            fprintf(stderr, "Error while decoding frame %d\n", frame);
            exit(1);
            }
        temp -= len;
        avpkt->data += len;

        if (got_picture) {
            printf("saving frame %3d\n", frame);
            fflush(stdout);
        //TODO  
        //memcpy(decodedpixels,rawFrame->data[0],rawFrame->linesize[0]); 
        //  decodedpixels +=rawFrame->linesize[0];

            frame++;
            }

        }

avcodec_close(c);
av_free(c);
//free(rawBuf);
//free(rgbBuf);
av_frame_free(&rawFrame);
av_frame_free(&rgbFrame);

}

The log i get

For the decode_inline() function:


01-02 14:50:50.160: I/stderr(3407): [h264 @ 0x8db540] non-existing PPS 0 referenced
01-02 14:50:50.160: I/stderr(3407): [h264 @ 0x8db540] decode_slice_header error
01-02 14:50:50.160: I/stderr(3407): [h264 @ 0x8db540] non-existing PPS 0 referenced
01-02 14:50:50.160: I/stderr(3407): [h264 @ 0x8db540] decode_slice_header error
01-02 14:50:50.160: I/stderr(3407): [h264 @ 0x8db540] non-existing PPS 0 referenced
01-02 14:50:50.160: I/stderr(3407): [h264 @ 0x8db540] decode_slice_header error
01-02 14:50:50.160: I/stderr(3407): [h264 @ 0x8db540] non-existing PPS 0 referenced
01-02 14:50:50.160: I/stderr(3407): [h264 @ 0x8db540] decode_slice_header error
01-02 14:50:50.160: I/stderr(3407): [h264 @ 0x8db540] non-existing PPS 0 referenced
01-02 14:50:50.160: I/stderr(3407): [h264 @ 0x8db540] decode_slice_header error
01-02 14:50:50.160: I/stderr(3407): [h264 @ 0x8db540] non-existing PPS 0 referenced
01-02 14:50:50.160: I/stderr(3407): [h264 @ 0x8db540] decode_slice_header error
01-02 14:50:50.160: I/stderr(3407): [h264 @ 0x8db540] non-existing PPS 0 referenced
01-02 14:50:50.160: I/stderr(3407): [h264 @ 0x8db540] decode_slice_header error
01-02 14:50:50.160: I/stderr(3407): [h264 @ 0x8db540] non-existing PPS 0 referenced
01-02 14:50:50.160: I/stderr(3407): [h264 @ 0x8db540] decode_slice_header error
01-02 14:50:50.160: I/stderr(3407): [h264 @ 0x8db540] non-existing PPS 0 referenced
01-02 14:50:50.160: I/stderr(3407): [h264 @ 0x8db540] decode_slice_header error
01-02 14:50:50.160: I/stderr(3407): [h264 @ 0x8db540] Invalid mix of idr and non-idr slices
01-02 14:50:50.160: I/stderr(3407): Error while decoding frame 0

Edit: Changing GOP value:

If i change c->gop_size = 3; as expected it emits one I frame every three frames. The non-existing PPS 0 referenced message is not there for in every third execution, but all other have this message


回答1:


In your decode_inline() method, right after specifying the size, here are some codec parameters that you can play with to get the higher quality. I filled in the values to get you started:

c->gop_size = 10;                                       // one intra frame every ten frames
c->max_b_frames = 1;                                    // max # of b-frames 
c->keyint_min = 1;                                      // min GOP size
c->i_quant_factor = (float)0.71;                        // qscale factor between P and I frames
c->b_frame_strategy = 20;                               
c->refs = 4;                                            // number of reference frames
c->trellis = 1;                                         // trellis RD Quantization
c->qcompress = (float)0.8;                              
c->qmin = 20;                                           // min quantizer
c->qmax = 51;                                           // max quantizer
c->max_qdiff = 4;                                       // max quantizer difference between frames

Let me know how it goes.



来源:https://stackoverflow.com/questions/21169040/android-h264-decode-non-existing-pps-0-referenced

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