I can now decode h264 using ffmpeg h264 decoder already but just limited to
one frame only. If I encode 30frames using x264 and output it into a single
test.264 file, in the decoder, I read all the content in the files at once
and stored in a buffer. When I pass the buffer to avcodec_decode_video2, it
will show the error that "Missing reference picture",
"decode_slice_header_error" and "number of frame exceeds max <probably
corrupt input>, discarding one". Why this will happen? Below is my code. Am
I do any mistake? This code is made by referring to api-example.c and
avcodec.h. If this 2 files are not enough, where else should i refer to.
av_open_input_files is not allow to be used as I want to pass in the buffer
that contains the h264 encoded data to the decoder only. I had tried to
write the 30 encoded frames data into 30 files and the decoder read the 30
files and stores those contents in 30 buffers, then pass one buffer each
time to the avcodec_decode_video2. But this is fail too. Same error occurs.
#include "stdafx.h"
#include <windows.h>
#include "stdint.h"
#include <time.h>
extern "C"
{
#include "avcodec.h"
#include "swscale.h"
}
int main()
{
AVCodec *codec;
AVCodecContext *c = NULL;
int frame, got_picture, len;
FILE *in;
FILE *out;
int i;
int j;
int ret;
int lsize;
__time32_t start, end;
AVFrame *picture;
uint8_t *inbuf;
AVPacket avpkt;
unsigned char *out_buff;
avcodec_init();
avcodec_register_all();
in = fopen("C:\\test.264", "rb");
if(in == NULL)
{
fprintf_s(stderr, "Cannot open infile.\n");
}
out = fopen("C:\\dec_ffmpeg.dat", "wb");
if (!out) {
fprintf(stderr, "could not open outfile.\n");
return -1;
}
fseek(in, 0, SEEK_END);
lsize = ftell(in);
rewind(in);
inbuf = new unsigned char[lsize + FF_INPUT_BUFFER_PADDING_SIZE];
av_init_packet(&avpkt);
memset(inbuf + lsize, 0, FF_INPUT_BUFFER_PADDING_SIZE);
fread(inbuf, lsize, 1, in);
codec = avcodec_find_decoder(CODEC_ID_H264);
if(!codec)
{
fprintf_s(stderr, "Codec not found.\n");
return -1;
}
c = avcodec_alloc_context();
picture = avcodec_alloc_frame();
c->coded_height = 288;
c->coded_width = 352;
c->width = 352;
c->height = 288;
if(codec->capabilities&CODEC_CAP_TRUNCATED)
c->flags|= CODEC_FLAG_TRUNCATED;
out_buff = new unsigned char[c->coded_width * c->coded_height * 3];
if (avcodec_open(c, codec) < 0) {
fprintf(stderr, "could not open codec\n");
return -1;
}
_time32(&start);
avpkt.size = lsize;
avpkt.data = inbuf;
while(avpkt.size > 0)
{
len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
if (len < 0) {
fprintf(stderr, "Error while decoding frame %d\n", frame);
exit(1);
}
if (got_picture) {
yuvtorgb();
}
avpkt.size -= len;
avpkt.data += len;
}
avpkt.data = NULL;
avpkt.size = 0;
len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
if (got_picture)
{
yuvtorgb();
}
_time32(&end);
fprintf_s(stdout, "Start time = %ld. End time = %ld.\n", start, end);
fclose(in);
fclose(out);
avcodec_close(c);
av_free(c);
av_free(picture);
delete[] inbuf;
delete[] out_buff;
return 0;
}
« Last Edit: Today at 06:39:49 pm by jamesl
_______________________________________________
libav-user mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/libav-user