osbornZ 2013-07-30 00:34 采纳率: 0%
浏览 3067

解码视频处理播放时只显示最后一帧图像,大家帮忙看看。。。

-(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);

}

  • 写回答

1条回答

  • ChatGPTᴼᴾᴱᴺᴬᴵ 2023-01-09 14:43
    关注

    这段代码中视频解码、图像格式转换和图像保存功能。


    在解码后,使用 sws_scale 函数将图像从 pCodecCtx->pix_fmt 格式转换为 PIX_FMT_RGB24 格式,并将转换后的图像保存到 picture 结构体中。


    接着,使用 CGBitmapInfo、CFDataRef、CGDataProviderRef、CGColorSpaceRef 和 CGImageRef 等 Core Graphics 库中的类型和函数将 picture 中的图像保存到 UIImage 对象中,并将 UIImage 对象显示到 UIImageView 中。


    针对您的问题,可能是因为在解码过程中出现了问题,导致 frameFinished 变量一直为 0,从而只显示了最后一帧图像。您可以尝试在 while 循环外打印 frameFinished 变量的值,如果一直为 0 则说明可能是解码过程出现了问题。

    评论

报告相同问题?

悬赏问题

  • ¥15 python天天向上类似问题,但没有清零
  • ¥30 3天&7天&&15天&销量如何统计同一行
  • ¥30 帮我写一段可以读取LD2450数据并计算距离的Arduino代码
  • ¥15 C#调用python代码(python带有库)
  • ¥15 矩阵加法的规则是两个矩阵中对应位置的数的绝对值进行加和
  • ¥15 活动选择题。最多可以参加几个项目?
  • ¥15 飞机曲面部件如机翼,壁板等具体的孔位模型
  • ¥15 vs2019中数据导出问题
  • ¥20 云服务Linux系统TCP-MSS值修改?
  • ¥20 关于#单片机#的问题:项目:使用模拟iic与ov2640通讯环境:F407问题:读取的ID号总是0xff,自己调了调发现在读从机数据时,SDA线上并未有信号变化(语言-c语言)