从mpeg ts文件中提取I帧(5):I帧的解码

2023-11-16

找到含有I帧的pes后就可以对其进行解码,对I帧的解码我们使用ffmpeg,这里用到的版本是3.0.0。

一、pes解码为yuv,ffmpeg一般都是这个套路,直接上代码:

int ffdecode_pes(uint8_t *pes_data, int32_t pes_size, ffbuffer_t *ffbuffer, char *out_file)
{
    int ret = 0;
    
    AVPacket packet;
    AVCodec *codec = NULL;
    AVCodecContext *codec_ctx  = NULL;
    AVFrame *frame = NULL;
    int got_picture = 0;
    
    if (NULL != out_file) {
        write_pes_file(pes_data, pes_size, out_file);
    }

    avcodec_register_all();
    
    codec = avcodec_find_decoder(AV_CODEC_ID_MPEG2VIDEO);
    codec_ctx = avcodec_alloc_context3(codec);
    ret = avcodec_open2(codec_ctx, codec, NULL);

    av_init_packet(&packet);
    packet.data = NULL;
    packet.size = 0;

    frame = av_frame_alloc();

    packet.size = pes_size;  
    packet.data = pes_data;

    while (1) {
        ret = avcodec_decode_video2(codec_ctx, frame, &got_picture, (const AVPacket *)&packet);
        if (got_picture) {
            frame->format = codec_ctx->pix_fmt;
            ffdecode_rgb(frame, ffbuffer);
            if (NULL != out_file) {
                write_yuv_file(frame   , out_file);
                write_rgb_file(ffbuffer, out_file);
                write_bmp_file(ffbuffer, out_file);
            }
            break;
        }
        
        av_packet_unref(&packet);
    }

    av_packet_unref(&packet);
    av_frame_free(&frame);
    avcodec_close(codec_ctx);
    avcodec_free_context(&codec_ctx);

    return ret;
}

二、yuv解码为rbg,同样也是使用ffmpeg提供的api

int ffdecode_rgb(AVFrame *frame_yuv, ffbuffer_t *buffer_rgb)
{
    struct SwsContext *sws_ctx = NULL;
    AVFrame *frame_rgb = NULL;
    
    int32_t r = 0;
    int32_t w = frame_yuv->width;
    int32_t h = frame_yuv->height;  
    
    frame_rgb = av_frame_alloc();

    r = av_image_fill_arrays(frame_rgb->data, frame_rgb->linesize, \
                             buffer_rgb->data, buffer_rgb->format, w, h, 1);

    sws_ctx = sws_getContext(w, h, frame_yuv->format, \
                             w, h, AV_PIX_FMT_BGR24, SWS_FAST_BILINEAR, 0, 0, 0);
    if (sws_ctx == NULL) {
        print_err("sws_getContext() failed. \n");
        return -1;
    }

    r = sws_scale(sws_ctx, (const uint8_t* const*)frame_yuv->data, frame_yuv->linesize, 0, h, frame_rgb->data, frame_rgb->linesize);

    av_frame_free(&frame_rgb);
    sws_freeContext(sws_ctx);

    return r;
}

三、yuv保存为文件
这里保存的是yuv 4:2:0 planer格式,逐行写入,uv分量各占y分量的4分之一。
保存的文件可以用yuv播放器进行播放。

static int write_yuv_file(AVFrame *frame, char *out_file)
{
    FILE *fd = NULL;
    int i = 0;
    char file_name[64];

    memset(file_name, 0x00, sizeof(char)*64);
    snprintf(file_name, 64, "%s.yuv", out_file);
    fd = fopen(file_name, "wb");
    
    /*yuv 4:2:0 planer*/
    /*write y*/
    for (i = 0; i<frame->height; i++) {
        fwrite(frame->data[0]+i*frame->linesize[0], 1, frame->width  , fd);
    }

    /*write u*/
    for (i = 0; i<(frame->height/2); i++) {
        fwrite(frame->data[1]+i*frame->linesize[1], 1, frame->width/2, fd);
    }

    /*write v*/
    for (i = 0; i<(frame->height/2); i++) {
        fwrite(frame->data[2]+i*frame->linesize[2], 1, frame->width/2, fd);
    }
    
    fclose(fd);
    print_log("%s\n", file_name);
    return 0;
}

四、rgb保存为bmp文件
bmp实际就是位图头+rgb数据,需要说明就是高度可能为负数。
可以参考下面这一段解释:
bmp图象的高度,以象素为单位。
这个值除了用于描述图像的高度之外,它还有另一个用处,就是指明该图像是倒向的位图,还是正向的位图。
如果该值是一个正数,说明图像是倒向的,即:数据的第一行其实是图像的最后一行,
如果该值是一个负数,则说明图像是正向的。
大多数的BMP文件都是倒向的位图,也就是时,高度值是一个正数
代码如下:

static int write_bmp_file(ffbuffer_t *buffer_rgb, char *out_file)
{
    bitmap_info_header_t biheader;
    bitmap_file_header_t bfheader;
    char file_name[64];
    FILE* pd = NULL;
    int r = 0;

    biheader.bi_size            = sizeof(bitmap_info_header_t);
    biheader.bi_width           = buffer_rgb->width;
    biheader.bi_height          = buffer_rgb->height*(-1);
    biheader.bi_planes          = 1;
    biheader.bi_bit_count       = 24;
    biheader.bi_compression     = 0;
    biheader.bi_size_image      = 0;
    biheader.bi_xpels_per_meter = 0;
    biheader.bi_ypels_per_meter = 0;
    biheader.bi_clr_used        = 0;
    biheader.bi_clr_important   = 0;
    
    bfheader.bf_type      = 0x4d42;
    bfheader.bf_size      = sizeof(bitmap_file_header_t) + sizeof(bitmap_info_header_t) + buffer_rgb->size;
    bfheader.bf_reserved1 = 0;
    bfheader.bf_reserved2 = 0;
    bfheader.bf_off_bits  = sizeof(bitmap_file_header_t) + sizeof(bitmap_info_header_t);
    
    memset(file_name, 0x00, sizeof(char)*64);
    snprintf(file_name, 64, "%s.bmp", out_file);

    pd = fopen(file_name, "wb");
    r = fwrite(&bfheader.bf_type         , sizeof(uint16_t), 1, pd);
    r = fwrite(&bfheader+sizeof(uint16_t), sizeof(bfheader)-sizeof(uint16_t), 1, pd);
    r = fwrite(&biheader                 , sizeof(biheader), 1, pd);
    r = fwrite(buffer_rgb->data          , buffer_rgb->size, 1, pd);
    fclose(pd);
    print_log("%s\n", file_name);
    return r;
}

mpeg2标准:https://download.csdn.net/download/maxzero/10402761
完整的代码:https://download.csdn.net/download/maxzero/10572383

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从mpeg ts文件中提取I帧(5):I帧的解码 的相关文章

  • 使用 ffmpeg 或 OpenCV 处理原始图像

    看完之后维基百科页面 http en wikipedia org wiki Raw image format原始图像格式 是任何图像的数字负片 为了查看或打印 相机图像传感器的输出具有 进行处理 即转换为照片渲染 场景 然后以标准光栅图形格
  • ffmpeg:音频样本的字节顺序

    我使用 ffmpeg 的 avcodec 从我的 C 应用程序中的音乐文件中检索原始音频样本 对于我测试的文件 这些文件样本的字节序似乎是小字节序 但我想知道对于我尝试解码的所有文件是否总是如此 即来自 ffmpeg 的实现或至少它的体系结
  • Python 子进程(ffmpeg)仅在我按 Ctrl-C 程序时启动?

    我正在尝试使用 Cygwin 和 Python 2 7 并行运行一些 ffmpeg 命令 这大概是我所拥有的 import subprocess processes set commands ffmpeg i input mp4 outpu
  • FFmpeg - 来自 NodeJS 的 RTMP 流,流比实时更快

    我的目标是在 Node 中渲染画布 并将该画布流式传输到 RTMP 服务器 最终是 Twitch 但现在我正在在本地 RTMP 服务器上测试 流式传输到 RTMP 的标准方式似乎是ffmpeg 所以我使用它 从 NodeJS 中作为子进程生
  • 从 ffmpeg 获取实时输出以在进度条中使用(PyQt4,stdout)

    我已经查看了很多问题 但仍然无法完全弄清楚 我正在使用 PyQt 并且希望能够运行ffmpeg i file mp4 file avi并获取流式输出 以便我可以创建进度条 我看过这些问题 ffmpeg可以显示进度条吗 https stack
  • 使用FFMpeg确定视频类型,然后进行转换?

    我正在尝试以编程方式确定文件的真实类型 看来我必须使用 FFMPeg 来实现这一点 我想确定上传的文件实际上是否是 MP4 或 FLV 对于 Flash 视频 或 WebM 对于 HTML5 我知道 FFMPeg 中的 i 运算符 但我不知
  • Java - 红、绿、蓝获取RGB

    通过致电getRGB int x int y with a BufferedImage对象 得到一个负数 如何将三个不同的值 红色 绿色和蓝色 转换为这个单个负数 使用颜色类 new Color r g b getRGB
  • Bash 脚本:自动为 mpeg-dash 进行 ffmpeg 编码

    我正在编写一个 bash 文件来创建视频编码和串联 以供 dash 实时流媒体使用 基本上 它读取输入视频文件夹 将所有视频编码为三种分辨率格式 然后将它们连接起来创建三个适应集 DIAGRAM 该脚本检查 fps 一致性 如果输入不是 1
  • 转换为 JPEG 时 HEIC 切片损坏

    我在将 HEIC 图像转换为 jpeg 时遇到问题 HEIC 文件是使用运行最新 iOS 公共测试版的 iPhone 拍摄的图像 我正在使用诺基亚提供的库 https github com nokiatech heif 要解析文件并从 HE
  • Node.js - 将数据缓冲到 Ffmpeg

    我使用 Node js 和 Ffmpeg 来创建动画 因为我试图避免第三方 avi mp4 解析器 所以我决定将动画输出为原始 rgb24 数据文件 然后使用一些程序将其转换为 mp4 文件 我发现 Ffmpeg 是免费且开源的 它完全可以
  • 如何使用 ffmpeg 设置默认流

    我有一些 m4v 文件 我想用 ffmpeg 添加字幕 我知道我需要映射流以将它们放入输出文件中 但如何确保此字幕流将是默认流 字幕是 srt 人们似乎说它们与 mp4 容器不兼容 我需要先将字幕转换为什么 另外 各种流的顺序重要吗 视频流
  • id3 图像编辑后播放 mp3 时遇到问题

    由于硬件限制 我们生产的软件试图确保导入到其库中的任何音频文件 准备复制到硬件上 都是可接受的比特率 最近 我们开始使用 FFmpeg 将许多不同的音频类型转换为 mp3 以便在我们的硬件上导入和使用它们 虽然转换工作正常并且 mp3 文件
  • FFMPEG - 具有持续时间过滤器问题的连接解复用器

    我正在尝试使用图像生成视频ffmpeg concat 解复用器 我正在创建一个带有图像文件路径的文本文件 由于图像的持续时间可能不同 我正在使用duration过滤器指定每个图像的持续时间 示例文本文件如下 文件1 jpg 持续时间3 文件
  • ffmpeg计算视频比特率

    我想知道如何计算该视频的比特率 http jell yfish us media jellyfish 30 mbps hd hevc mkv http jell yfish us media jellyfish 30 mbps hd hev
  • FFMPEG 帧到 DirectX 表面

    给定一个指向 FFMPEG 的 AVFrame 的指针avcodec decode video 函数如何将图像复制到 DirectX 表面 假设我有一个指向适当大小的 DX X8R8G8B8 表面的指针 Thanks John 您可以使用
  • 如何使用 ffmpeg av_seek_frame() 在具有帧号的情况下读取任何帧

    int64 t timeBase timeBase int64 t pavStrm gt time base num AV TIME BASE int64 t pavStrm gt time base den int64 t seekTar
  • PowerShell 脚本 ffmpeg

    作为一名优秀的 Windows 系统管理员 我终于开始学习 PowerShell 话虽这么说 我不知道我在做什么 惊讶 惊讶 我认为远离生产环境 在家里使用 PowerShell 对我来说将是一次很好的学习经历 最近 我开始使用 FFMPE
  • 使用 ffmpeg 将 mp4 转换为 gif 时帧率较低

    我正在使用 ffmpeg 将高质量视频转换为 gif 大多数视频都是 60fps 及以上720p 但是当我使用下面的代码将视频转换为 gif 时 我得到的 gif 输出的 fps 非常低 usr bin env palette tmp pa
  • 使用 getRGB() 时负数的含义是什么?

    我对颜色 渲染等很陌生 并且观看了一些有关渲染等的教程视频 我的问题是 当我致电getRGB像素上的方法 它返回一个负整数 这个负数是什么意思 例如 当我打电话时getRGB对于 r 186 g 186 b 186 的颜色 它返回 4539
  • 使用 mp4box 直播破折号内容

    我正在尝试直播H 264内容到HTML5使用媒体源扩展 API 下面的方法效果很好 ffmpeg i rtsp 10 50 1 29 media video1 vcodec copy f mp4 reset timestamps 1 mov

随机推荐