gpt4 book ai didi

Android h264 解码不存在的 PPS 0 引用

转载 作者:行者123 更新时间:2023-11-30 03:09:48 27 4
gpt4 key购买 nike

在 Android JNI 中,使用 ffmpeg with libx264 使用以下代码编码和解码原始 rgb 数据!。我应该按照 H.264 的要求使用 swscale 将 rgb565 转换为 yuv420p。但不清楚这种转换。请帮助,我错了,关于我得到的日志!

编码代码

codecinit()- 调用一次(JNI 包装函数)

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() - 在 while 循环中调用

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() 函数

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

我得到的日志

对于 decode_inline() 函数:


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

编辑:更改 GOP 值:

如果我按预期更改 c->gop_size = 3;,它会每三帧发出 一个 I 帧non-existing PPS 0 referenced 消息不会在每三次执行时出现,但所有其他程序都有此消息

最佳答案

在您的 decode_inline() 方法中,在指定大小之后,您可以使用以下一些编解码器参数来获得更高的质量。我填写了这些值以帮助您入门:

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

告诉我进展如何。

关于Android h264 解码不存在的 PPS 0 引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21169040/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com