av_register_all();      if(av_open_input_file(&pFormatCtx, filename, NULL, 0, NULL)!=0) {          PRintf("error!/n"); }     if(av_find_stream_info(pFormatCtx)<0)   {        printf("error!/n");   }   videoStream=-1;      for(i=0; i<pFormatCtx->nb_streams; i++)   {        if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)           {               videoStream=i;               break;           }   	if(videoStream==-1)   	{		printf("error!/n");// Didn't find a video stream  	}        // 得到視頻流編碼上下文的指針       pCodecCtx=pFormatCtx->streams[videoStream]->codec;  }用兩種方式,一是利用ffmpeg提供的可執(zhí)行文件進(jìn)行提取,另外就是用ffmpeg的sdk,進(jìn)行開發(fā)。我下面說一下如何使用ffmpeg sdk進(jìn)行提取(假設(shè)把提取的關(guān)鍵幀保存成bmp,源文件名是sample.mpg):首先獲取文件中的視頻流: 然后選擇解碼器進(jìn)行解碼:AVCodec *pCodec;   //  尋找視頻流的解碼器   pCodec=avcodec_find_decoder(pCodecCtx->codec_id);   if(pCodec==NULL)  {     printf("error!/n");// 找不到解碼器   }// 打開解碼器   if(avcodec_open(pCodecCtx, pCodec)<0)   {    printf("error!/n"); // 打不開解碼器  }現(xiàn)在開始,進(jìn)入解碼和提取關(guān)鍵幀的過程:pFrame=avcodec_alloc_frame();   pFrameRGB = avcodec_alloc_frame();   numBytes=avpicture_get_size(PIX_FMT_BGR24, pCodecCtx->width,pCodecCtx->height);   buffer=new uint8_t[numBytes];   avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,pCodecCtx->width, pCodecCtx->height);   pSWSCtx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);      i=0;   while(av_read_frame(pFormatCtx,&packet)>=0)   {       if(packet.stream_index==videoStream)       {           avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,packet.data, packet.size);           if(frameFinished)           {               if(pFrame->key_frame==1) // 這就是關(guān)鍵幀               {                   sws_scale(pSWSCtx, pFrame->data, pFrame->linesize,0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);                   // 保存到磁盤                   char pic[200];                   sprintf(pic,"pic%d.bmp",i);                   i++;                    av_create_bmp(pic,pFrameRGB->data[0],pCodecCtx->width,pCodecCtx->height,24);               }           }       }       av_free_packet(&packet);   } 最后,釋放資源和句柄// 釋放 RGB 圖象   av_free(pFrameRGB);  // 釋放YUV 幀   av_free(pFrame);   sws_freeContext(pSWSCtx);   // 關(guān)閉解碼器(codec)   avcodec_close(pCodecCtx);  // 關(guān)閉視頻文件   av_close_input_file(pFormatCtx);  ffmpeg相關(guān)知識(shí)轉(zhuǎn)自:http://fengqing888.blog.163.com/blog/static/330114162011111632548120/
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注