调用ffmpeg的库从文件中读出视频流信息,利用av_read_frame提取帧,最后调用avcodec_decode_video2接口对帧进行解码,代码如下:
AVFormatContext *pFormatCtx;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame2;
AVPacket packet2;
int H264GetStream()
{
int i, videoindex;
char filepath[]="sample.mp4";
av_register_all();
pFormatCtx = avformat_alloc_context();
if(avformat_open_input(&pFormatCtx,filepath,NULL,NULL)!=0){
printf("无法打开文件\n");
return -1;
}
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;
}
printf("pCodec=%d\n",pCodec->id);
if(avcodec_open2(pCodecCtx, pCodec,NULL)<0)
{
printf("Could not open codec.\n");
return -1;
}
pFrame2=avcodec_alloc_frame();
int ret, got_picture;
int y_size = pCodecCtx->width * pCodecCtx->height;
//packet2=(AVPacket *)malloc(sizeof(AVPacket));
//av_new_packet(packet2, y_size);
av_init_packet(&packet2);
char filepath_out[]="bigbuckbunny_1920x1080.yuv";
fp_out = fopen(filepath_out, "wb");
if (!fp_out) {
printf("Could not open output YUV file\n");
return -1;
}
//输出一下信息-----------------------------
printf("文件信息-----------------------------------------\n");
av_dump_format(pFormatCtx,0,filepath,0);
printf("-------------------------------------------------\n");
//------------------------------
while(av_read_frame(pFormatCtx, &packet2)>=0)
{
printf("packet2->stream_index=%d\n",packet2.stream_index);
printf("videoindex=%d\n",videoindex);
if(packet2.stream_index==videoindex)
{
printf("decode start!");
//packet->data[0]=0;packet->data[1]=0;packet->data[2]=0;packet->data[3]=1;
// packet->size-=4;
printf("packet2->data=%d %d %d %d\n",packet2.data[0],packet2.data[1],packet2.data[2],packet2.data[3]);
printf("packet2->size=%d\n",packet2.size);
ret = avcodec_decode_video2(pCodecCtx, pFrame2, &got_picture, &packet2);
printf("got_picture=%x\n",got_picture);
if(ret < 0)
{
printf("decode error!\n");
return -1;
}
if(got_picture)
{
printf("got_picture=%x\n",got_picture);
//Y, U, V
int i;
for(i=0;i<pFrame->height;i++)
{
fwrite(pFrame->data[0]+pFrame->linesize[0]*i,1,pFrame->width,fp_out);
}
for(i=0;i<pFrame->height/2;i++)
{
fwrite(pFrame->data[1]+pFrame->linesize[1]*i,1,pFrame->width/2,fp_out);
}
for(i=0;i<pFrame->height/2;i++)
{
fwrite(pFrame->data[2]+pFrame->linesize[2]*i,1,pFrame->width/2,fp_out);
}
printf("Succeed to decode 1 frame!\n");
}
}
av_free_packet(&packet2);
}
//av_free(pFrameYUV);
avcodec_close(pCodecCtx);
avformat_close_input(&pFormatCtx);
return 0;
}
每次运行到ret = avcodec_decode_video2(pCodecCtx, pFrame2, &got_picture, &packet2)这一步程序就不再运行下去了,也没有任何返回值。
在这里打印信息检查了一下
while(av_read_frame(pFormatCtx, &packet2)>=0)
{
printf("packet2->stream_index=%d\n",packet2.stream_index);
printf("videoindex=%d\n",videoindex);
发现packet2.stream_index的值一直不变,按道理应该还有一路音频流。
程序是在linux平台下运行的,求问哪里出错了!