开发者社区> 问答> 正文

解码视频只显示最后一帧图像

本人第一次分析视频文件,处理完后,可是貌似每次只是显示视频文件的最后一帧图像,希望大家能够给予建议。。。 xcode 4.5,第三方 ffmpeg

-(void)translate
{

int  videoStream= -1;
int     frameFinished ;
uint8_t *buf;
 
avcodec_register_all();
avformat_network_init();
av_register_all() ;
 
if( avformat_open_input(&pFormatCtx, [fLocalFileName UTF8String], NULL, NULL) != 0)
{
    NSLog(@"av  open  input  file  failed!\n");
    return ;
}
//从文件中提取流信息
if( avformat_find_stream_info(pFormatCtx, NULL) < 0 )
{
    NSLog(@"av  find  input  file  failed!\n");
    return ;
}
 
//获取视频流
    if(   (videoStream = av_find_best_stream(pFormatCtx, AVMEDIA_TYPE_VIDEO, NULL, NULL, &pCodec, 0) )  < 0 )
    {
        NSLog(@"Cannot find a video stream in the input file\n");
        return ;
    }
  //查找对应的解码器
pCodecCtx  = pFormatCtx->streams[videoStream]->codec ;
pCodec = avcodec_find_decoder( pCodecCtx->codec_id );
if( pCodec == NULL)
{
    NSLog(@"\n");
    return ;
}
//打开编译解码器
if( avcodec_open2(pCodecCtx, pCodec, NULL) < 0 )
{
    NSLog(@"\n");
    return ;
}
//为解码帧分配内存

pFrame = avcodec_alloc_frame();

 if( pFrame== NULL  )
{
    NSLog(@"\n");
    return ;
}

// avpicture_alloc(&picture, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height );

 
buf = (uint8_t*)av_malloc( avpicture_get_size (PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height) );
 
if ( buf == NULL )
{
    printf( "av malloc failed!\n");
    exit(1);
}
avpicture_fill ( &picture, buf, PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height);
 

// 设置图像转换上下文

static int sws_flags =  SWS_FAST_BILINEAR;
img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, sws_flags, NULL, NULL, NULL );
 

//不停地从码流中取出帧数据

while ( av_read_frame(pFormatCtx, &packet) >= 0 )
{
    if( packet.stream_index  ==  videoStream )
    {
        avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet );
        if(frameFinished)
        {
            //转换图像格式
            sws_scale (img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, picture.data, picture.linesize);              
             
            //保存
            CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
            CFDataRef data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, picture.data[0], picture.linesize[0]*pCodecCtx->height,kCFAllocatorNull);
            CGDataProviderRef provider = CGDataProviderCreateWithCFData(data);
            CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
            CGImageRef cgImage = CGImageCreate(pCodecCtx->width,
                                               pCodecCtx->height,
                                               8,
                                               24,
                                               picture.linesize[0],
                                               colorSpace,
                                               bitmapInfo,
                                               provider,
                                               NULL,
                                               NO,
                                               kCGRenderingIntentDefault);
            CGColorSpaceRelease(colorSpace);
            UIImage *image = [UIImage imageWithCGImage:cgImage];
            CGImageRelease(cgImage);
            CGDataProviderRelease(provider);
            CFRelease(data);
            [mutableImg  addObject: image];

// [img_Decode setImage:image];

        }
    }
     
    av_free_packet(&packet);
}
 
sws_freeContext(img_convert_ctx);
av_free(pFrame);
avcodec_close(pCodecCtx);
av_close_input_stream(pFormatCtx);
 

}

展开
收起
杨冬芳 2016-06-30 18:06:10 2828 0
1 条回答
写回答
取消 提交回答
  • IT从业

    哈。你把解码出来的数据导出到文件里,然后用yuvview之类的软件播放不是更简单吗?

    2019-07-17 19:49:37
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载