access violation reading 0x0000000000000020
原因:
再次使用之前应该先释放一下内存:
av_freep(aviobuffer);
//printf("restart 4");
aviobuffer = (unsigned char *)av_malloc(32768);
加上之后继续报错:
OSError: exception: access violation reading 0xFFFFFFFFFFFFFFFF
代码:在下面:
int play_file(char* file_name, FrameFunc tcallback(char* a, int size,int num, int height, int width))
{
av_log_set_level(AV_LOG_WARNING);
av_register_all();
unsigned version = avcodec_version();
printf("FFmpeg version: %d\n", version);
AVFormatContext *pFormatCtx;
int i, videoindex;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
char filepath[] = "video.264";
avformat_network_init();
pFormatCtx = avformat_alloc_context();
//string patha = "C:\\Users\\sbd01\\Videos\\video.264";
//patha = "C:\\Users\\sbd01\\Pictures\\ffmpegtest\\Debug\\video.dat";
FILE *fp_open = fopen(file_name, "rb+");
unsigned char *aviobuffer = (unsigned char *)av_malloc(32768);
//printf("avio_alloc_context %d\n", cam_no);
AVIOContext *avio = avio_alloc_context(aviobuffer, 32768, 0, (void*)fp_open, file_buffer, NULL, NULL);
pFormatCtx->pb = avio;
//if (avformat_open_input(&pFormatCtx, patha.c_str(), NULL, NULL) != 0) {
if (avformat_open_input(&pFormatCtx, NULL, NULL, NULL) != 0) {
printf("Couldn't open input stream.\n");
return -1;
}
//-----
pFormatCtx->probesize = 1000 * 1024;
pFormatCtx->max_analyze_duration = 10 * AV_TIME_BASE;
pCodec = NULL;
while (pCodec == NULL) {
printf("start find stream info \n");
if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
printf("Couldn't find stream info\n");
goto restart_stream;
continue;
}
videoindex = -1;
for (i = 0; i < pFormatCtx->nb_streams; i++)
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
if (videoindex == -1) {
videoindex = i;
}
//break;
}
if (videoindex == -1) {
printf("Didn't find a video stream.\n");
goto restart_stream;
}
pCodecCtx = pFormatCtx->streams[videoindex]->codec;
//pCodec = avcodec_find_decoder(AV_CODEC_ID_H264);
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (pCodec == NULL) {
printf("Codec not found \n");
goto restart_stream;
//return -1;
}
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
printf("Could not open codec.\n");
goto restart_stream;
continue;
//return -1;
}
if (pCodecCtx->width <= 0 || pCodecCtx->height <= 0 || pCodecCtx->height >2000 || pCodecCtx->width >3000) {
printf("pCodecCtx error 1 width %d height %d ", pCodecCtx->width, pCodecCtx->height);
goto restart_stream;
}
goto ok;
restart_stream:
printf("restart 1 ");
avformat_free_context(pFormatCtx);
printf("restart 2 ");
//avformat_close_input(&pFormatCtx);
pFormatCtx = NULL;
pFormatCtx = avformat_alloc_context();
printf("restart 3 ");
av_freep(aviobuffer);
//printf("restart 4");
aviobuffer = (unsigned char *)av_malloc(32768);
printf("restart 4 ");
AVIOContext *avio2 = avio_alloc_context(aviobuffer, 32768, 0, &fp_open, file_buffer, NULL, NULL);
pFormatCtx->pb = avio2;
pFormatCtx->probesize = 1000 * 1024;
pFormatCtx->max_analyze_duration = 10 * AV_TIME_BASE;
if (avformat_open_input(&pFormatCtx, NULL, NULL, NULL) != 0) {
printf("2Couldn't open input stream\n");
//return -1;
}
printf("restart 5\n");
pCodec = NULL;
continue;
ok:
break;
}
//---------
/*if (avformat_find_stream_info(pFormatCtx, NULL)<0) {
printf("Couldn't find stream information.\n");
return -1;
}
videoindex = -1;
for (i = 0; i<pFormatCtx->nb_streams; i++)
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
videoindex = i;
break;
}
if (videoindex == -1) {
printf("Didn't find a video stream.\n");
return -1;
}
pCodecCtx = pFormatCtx->streams[videoindex]->codec;
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (pCodec == NULL) {
printf("Codec not found.\n");
return -1;
}
if (avcodec_open2(pCodecCtx, pCodec, NULL)<0) {
printf("Could not open codec.\n");
return -1;
}*/
AVFrame *pFrame, *pFrameYUV;
pFrame = av_frame_alloc();
pFrameYUV = av_frame_alloc();
/*if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
printf("Could not initialize SDL - %s\n", SDL_GetError());
return -1;
}*/
/*int screen_w = 0, screen_h = 0;
SDL_Surface *screen;
screen_w = pCodecCtx->width;
screen_h = pCodecCtx->height;
screen = SDL_SetVideoMode(screen_w, screen_h, 0, 0);
if (!screen) {
printf("SDL: could not set video mode - exiting:%s\n", SDL_GetError());
return -1;
}
SDL_Overlay *bmp;
bmp = SDL_CreateYUVOverlay(pCodecCtx->width, pCodecCtx->height, SDL_YV12_OVERLAY, screen);
SDL_Rect rect;
rect.x = 0;
rect.y = 0;
rect.w = screen_w;
rect.h = screen_h;*/
//SDL End------------------------
int ret, got_picture;
AVPacket *packet = (AVPacket *)av_malloc(sizeof(AVPacket));
struct SwsContext *img_convert_ctx;
img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
uint8_t *out_buffer;
out_buffer = new uint8_t[avpicture_get_size(AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height)];
avpicture_fill((AVPicture *)pFrameYUV, out_buffer, AV_PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
int need_decode = 1;
int is_key_frame = 0;
while (av_read_frame(pFormatCtx, packet) >= 0) {
if (packet->stream_index == videoindex) {
if (packet->size < 50) {
av_free_packet(packet);
printf("packet is too small %d\n", packet->size);
continue;
}
if (packet->flags &AV_PKT_FLAG_KEY){
is_key_frame = 1;
need_decode = 1;
printf("key frame %d\n", need_decode);
}
else {
is_key_frame = 0;
}
if (!need_decode) {
av_free_packet(packet);
printf("not key frame \n");
continue;
}
ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
if (ret < 0) {
printf("Decode Error %d \n", pCodecCtx->frame_d_flags);
if (is_key_frame) {
need_decode = 0;
}
continue;
}
if (got_picture) {
if (pCodecCtx->frame_d_flags) {
printf("got_picture err %d\n", pCodecCtx->frame_d_flags);
pCodecCtx->frame_d_flags = 0;
need_decode = 0;
av_free_packet(packet);
continue;
}
printf("decode ok %d %d\n", pCodecCtx->flags, pCodecCtx->flags2);
sws_scale(img_convert_ctx,pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);
/*fwrite(pFrameYUV->data[0], (pCodecCtx->width)*(pCodecCtx->height) * 3, 1, output);*/
tcallback((char*)pFrameYUV->data[0], pCodecCtx->height * pCodecCtx->width * 3, 1, pCodecCtx->height, pCodecCtx->width);
}
else {
printf("got_picture:%d %d %d\n", got_picture, pCodecCtx->flags, pCodecCtx->flags2);
}
}
av_free_packet(packet);
}
sws_freeContext(img_convert_ctx);
//fclose(fp_open);
//SDL_Quit();
//av_free(out_buffer);
av_free(pFrameYUV);
avcodec_close(pCodecCtx);
avformat_close_input(&pFormatCtx);
return 0;
}