只贴出部分代码,重在说明过程。
与解码文件的大致过程类似,只不过自定义了AVFormatContext struct IOData { char* data; size_t len; }; int FrVideoAcqHT::io_get_data(void *opaque, uint8_t *buf, int buf_size) { FrVideoAcqHT* acq = (FrVideoAcqHT*)opaque; //以下为通过缓冲区读文件解码方式 /*if (!feof(acq->f)) { int true_size = fread(buf, 1, 1024, acq->f); printf("read:%d\n", true_size); return true_size; } else { printf("read failed\n"); return -1; }*/ //不断读取数据 while (true) { IOData data; if (acq->data_queue.Pop(data)) { memcpy(buf, data.data, data.len); return data.len; } else { Sleep(1000); } } } av_register_all(); AVFormatContext* fctx = avformat_alloc_context(); av_buf = av_malloc(AV_IO_BUF_LEN); avio = avio_alloc_context((uchar*)av_buf, AV_IO_BUF_LEN, 0, this, io_get_data, NULL, NULL); fctx->pb = avio; err = avformat_open_input(&fctx, "none", NULL, NULL); printf("open input:%d\n", err); err = avformat_find_stream_info(fctx, NULL); printf("find stream info:%d, streams:%d\n", err, fctx->nb_streams); int video_id = -1; for (int i = 0; i < fctx->nb_streams; i++) //区分视频流和音频流 { if (fctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) //找到视频流,这里也可以换成音频 { video_id = i; break; } } printf("video_id:%d\n", video_id); AVCodec* codec = avcodec_find_decoder(fctx->streams[video_id]->codec->codec_id); AVCodecContext* cctx = fctx->streams[video_id]->codec; err = avcodec_open2(cctx, codec, NULL); // 打开解码器 printf("open codec:%d\n", err); int width = cctx->width; int height = cctx->height; printf("width:%d, height:%d\n", width, height); AVRational frame_rate = fctx->streams[video_id]->r_frame_rate; AVPicture pc; AVPicture* pic = &pc; avpicture_alloc(pic, PIX_FMT_RGB24, width, height); AVFrame* frame = av_frame_alloc(); SwsContext* sctx = sws_getContext(width, height, cctx->pix_fmt, width, height, (PixelFormat)PIX_FMT_BGR24, SWS_BICUBIC, NULL, NULL, NULL); IplImage* img = cvCreateImageHeader(cvSize(width, height), IPL_DEPTH_8U, 3); img->imageSize = pic->linesize[0]; img->imageData = (char *)pic->data[0]; int id = 0; AVPacket* pck = new AVPacket; while (av_read_frame(fctx, pck) >= 0) { if (pck->stream_index == video_id) { int got; err = avcodec_decode_video2(cctx, frame, &got, pck); if (err < 0) { printf("decode err:%d\n", err); return; } if (got) { printf("got img:%d\n", id); sws_scale(sctx, frame->data, frame->linesize, 0, height, pic->data, pic->linesize); char fname[100]; sprintf(fname, "./img/%d.jpg", id); cvSaveImage(fname, img); id++; } } }
时间: 2024-11-09 03:09:31