欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 国际 > RV1126解码—ffmpeg_read_thread线程的讲解

RV1126解码—ffmpeg_read_thread线程的讲解

2025/2/22 20:34:54 来源:https://blog.csdn.net/weixin_49529507/article/details/145730079  浏览:    关键词:RV1126解码—ffmpeg_read_thread线程的讲解

fmpeg_read_thread线程的用处

        解码这一块,在第一篇的时候就看到了,有三个线程,这篇先介绍一个线程的作用是怎么样的。

        ffmpeg_read_thread线程的主要作用是读取每一帧流媒体文件,这个流媒体文件可以是复合流文件。如:TS文件、MP4文件等等,也可以包括网络流媒体文件:如RTMP、RTSP等等。然后抽取每一帧视频帧插入到队列里面。所以就是作用就是读取每一帧视频帧入队。

         下面代码要看一下。

        第一步:avformat_open_input() 打开输入的流媒体文件

#define LOCAL_TS "test_local.ts" //本地文件地址./ymx,也可以是网络地址例如:rtsp://172.0.0.1:8554/rtsp1//读取每一帧流文件,然后抽取每一帧视频帧插入到队列里面
void* ffmpeg_read_thread(void* args)
{int ret;//线程分离pthread_detach(pthread_self());//定义出一个大管家AVFormatContext* ctx = nullptr;//该函数用于打开多媒体数据并且获得一些相关的信息ret = avformat_open_input(&ctx, LOCAL_TS, 0, 0); if(ret < 0){printf("复合文件或者网络文件打开失败\n");return 0;}printf("==> 流媒体文件输入成功!\n");}

        第二步:avformat_find_stream_info() :可以使用avformat_find_stream_info()获取更多的码流信息。比如获取视频帧率、视频宽高,重新计算最大分析时长,打开解码器解码获取codec数据。

#define LOCAL_TS "test_local.ts" //本地文件地址./ymx,也可以是网络地址例如:rtsp://172.0.0.1:8554/rtsp1//读取每一帧流文件,然后抽取每一帧视频帧插入到队列里面
void* ffmpeg_read_thread(void* args)
{int ret;//线程分离pthread_detach(pthread_self());//定义出一个大管家AVFormatContext* ctx = nullptr;//该函数用于打开多媒体数据并且获得一些相关的信息ret = avformat_open_input(&ctx, LOCAL_TS, 0, 0); if(ret < 0){printf("复合文件或者网络文件打开失败\n");return 0;}printf("==> 流媒体文件输入成功!\n");// 可以使用avformat_find_stream_info()获取更多的码流信息。比如获取视频帧率、视频宽高,重新计算最大分析时长,打开解码器解码获取codec数据avformat_find_stream_info(m_pInFmtCtx, nullptr);printf("===========Input Information==========\n");// 通过av_find_best_stream()函数来获取流的索引 “AVMEDIA_TYPE_VIDEO”找视频的索引int nVideo_indx = av_find_best_stream(m_pInFmtCtx, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0);if (nVideo_indx < 0){//todo......}printf("==> av_find_best_stream!\n");}

        第一步和第二步就相当于初始化工作已经完成了,接下来就是这个线程最重要的一个函数“av_read_frame()”,

        先来说一下这个“av_read_frame()”,函数的一些底层的逻辑,看看是怎么工作的,

        假设下图是H264的一个连续的视频码流,视频源源不断通摄像头那边传输过来,除非停止。

         假设我把这些连续的码流整体塞给解码器,和下图一样,加密器能否正常解析出来,因为这些码流最终都要送到解码器里面解析的,但是,一下子全部给它能否工作?答案是不行的,在解码器里面是没有办法解析一个整体的数据,整体的数据就是左边的这个东西。因为解码器没有办法提取每一帧数据。

        所以我们要想它解码器能正常工作,我们要在码流中提取一帧一帧数据,送到解码器这里,那怎么提取,就是与“00 00 00 01”为切割符,是一帧数据的起始符。

        所以这也也就是av_read_frame的作用,就是提取视频里中的每一帧数据,这个时候解码器就可以工作了。

av_read_frame:这个API的具体作用是读取码流中提取一帧完整的视频帧或者音频帧。对于编解码器来说,开发者需要获取一帧完整的数据帧才能够对其进行数据的编解码

#define LOCAL_TS "test_local.ts" //本地文件地址./ymx,也可以是网络地址例如:rtsp://172.0.0.1:8554/rtsp1//读取每一帧流文件,然后抽取每一帧视频帧插入到队列里面
void* ffmpeg_read_thread(void* args)
{int ret;//线程分离pthread_detach(pthread_self());//定义出一个大管家AVFormatContext* ctx = nullptr;//该函数用于打开多媒体数据并且获得一些相关的信息ret = avformat_open_input(&ctx, LOCAL_TS, 0, 0); if(ret < 0){printf("复合文件或者网络文件打开失败\n");return 0;}printf("==> 流媒体文件输入成功!\n");// 可以使用avformat_find_stream_info()获取更多的码流信息。比如获取视频帧率、视频宽高,重新计算最大分析时长,打开解码器解码获取codec数据avformat_find_stream_info(m_pInFmtCtx, nullptr);printf("===========Input Information==========\n");// 通过av_find_best_stream()函数来获取流的索引 “AVMEDIA_TYPE_VIDEO”找视频的索引int nVideo_indx = av_find_best_stream(m_pInFmtCtx, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0);if (nVideo_indx < 0){//todo......}printf("==> av_find_best_stream!\n");AVPacket *packet = av_packet_alloc();// 通过av_read_frame获取每一帧视频帧while (av_read_frame(m_pInFmtCtx, packet) >= 0){if (packet->stream_index == nVideo_indx)//找到这个索引看看是视频的还是音频{video_data_packet_t *video_data_packet = (video_data_packet_t *)malloc(sizeof(video_data_packet_t));memcpy(video_data_packet->buffer, packet->data, packet->size);video_data_packet->video_frame_size = packet->size;//入队video_queue->putVideoPacketQueue(video_data_packet);}}return NULL;}

         

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词