需求:把两路视频合成一路,即一个画面同时显示两路视频,其中一路缩小成小视频叠在大视频上面,和电视机的画中画效果类似。

思路:用h264编码的视频举例,文件中存储的es流是h264,经过解码成yuv,yuv可以转换成rgb格式。把小视频的rgb复制到大视频需要被覆盖的位置上。将重新合成的rgb转换成yuv,利用ffmpeg 或 x264重新编码出新的视频即可。

方法:编解码还是利用ffmpeg 。 ffmpeg 解码两路视频,解码后都是yuv。利用ffmpeg· 的sws_getContext 函数改变小图的大小。之后利用OpenCV完成两个图片的合成(opencv这种高大上的库被我用成了这样····实在汗颜。其实此处的合并rgb可以自己写算法实现,本质是把小图的rgb复制到大图的对应位置上。)合成好后将rbg转成yuv格式,利用x264重新编码成h264
,就看到了大视频左上角有个小视频了。

代码思路:

两个线程,各自解码,主视频的线程解码一帧后通知副视频的线程进行解码并转化图片大小,副视频的线程解码完成后通知主线程合成视频并编码。合成视频的时候用opencv很简单,直接把yuv转化成rgb,之后在主视频上设置敏感区,把小视频叠加上就行。

主副线程解码套路一样,ffmpeg的基本使用套路。把yuv转成opencv mat类型的rgb套路也一样,上副视频解码线程的代码进行说明。

全局变量:

cv::Mat littlergb,bigrgb;//大小视频的rgb  

cv::Mat littleframe,bigframe;//大小视频的yuv

副视频解码线程内的代码:

while(av_read_frame(pInputFormatContext, &InPack) >=0)  

    {  

        len = avcodec_decode_video2(pInputCodecContext, &OutFrame, &nComplete, &InPack);//解码视频  

        if (nComplete>0)  

        {     

            if (GetMessage(&msg, NULL, 0, 0))  

            {  

                switch(msg.message)  

                {  

                case MY_MSG_DECODE:  

                    sws_scale(m_pSwsContext,OutFrame.data,OutFrame.linesize, 0,OutFrame.height,dst->data,dst->linesize);//转换图片大小  

  

                    memcpy(littleframe.data,dst->data[0], 640*480);  //以下将ffmpeg的yuv数据存到opencv的mat类型中。即opencv存储的yuv数据  

                    memcpy(littleframe.data+640*480,dst->data[1], 640*480/4);    

                    memcpy(littleframe.data+640*480*5/4,dst->data[2], 640*480/4);   

                    SetEvent(hEncodeEvent);  

  

                    break;  

                }  

            }  

  

        }  

        av_free_packet(&InPack);  

    }

合并图片直接用opencv,代码如下:

cv::cvtColor(littleframe, littlergb,CV_YUV2BGR_I420);   

cv::cvtColor(bigframe, bigrgb,CV_YUV2BGR_I420); //以上yuv转rgb  

Mat roi(bigrgb,Rect(0,0,640,480));//大图上设置敏感区  

littlergb.copyTo(roi);  //把小图拷贝过去  

Mat outframe;  

cv::cvtColor(bigrgb, outframe,CV_BGR2YUV_I420); //rgb到yuv

这样就获得了合并后的图片的yuv。

之后进行编码即可。编码出来的视频就是画中画了。

【VS开发】【视频开发】利用ffmpeg+opencv实现画中画的更多相关文章

  1. 音视频开发-FFmpeg

    音视频开发是个非常复杂的,庞大的开发话题,初涉其中,先看一下结合 OEIP(开源项目) 新增例子. 可以打开flv,mp4类型文件,以及rtmp协议音视频数据,声音的播放使用SDL. 把采集的麦/声卡 ...

  2. 开发环境配置--Ubuntu+Qt4+OpenCV(一)

    同系列的文章 1. 开发环境配置--Ubuntu+Qt4+OpenCV(一) 2. 开发环境配置--Ubuntu+Qt4+OpenCV(二) 3. 开发环境配置--Ubuntu+Qt4+OpenCV( ...

  3. 浅谈iOS视频开发

     浅谈iOS视频开发 这段时间对视频开发进行了一些了解,在这里和大家分享一下我自己觉得学习步骤和资料,希望对那些对视频感兴趣的朋友有些帮助. 一.iOS系统自带播放器 要了解iOS视频开发,首先我们从 ...

  4. iOS 视频开发学习

    原文:浅谈iOS视频开发 这段时间对视频开发进行了一些了解,在这里和大家分享一下我自己觉得学习步骤和资料,希望对那些对视频感兴趣的朋友有些帮助. 一.iOS系统自带播放器 要了解iOS视频开发,首先我 ...

  5. Android 音视频开发学习思路

    Android 音视频开发这块目前的确没有比较系统的教程或者书籍,网上的博客文章也都是比较零散的.只能通过一点点的学习和积累把这块的知识串联积累起来. 初级入门篇: Android 音视频开发(一) ...

  6. 利用Ffmpeg获得flv视频缩略图和视频时间的代码

    问题描述:获得flv视频的缩略图和视频时间长度 谷歌了半天发现可以使用Ffmpeg获得视频的一些信息,先介绍一下FFMEPG 这里简单说一下:FFmpeg是用于录制.转换和流化音频和视频的完整解决方案 ...

  7. 短视频技术详解:Android端的短视频开发技术

    在 <如何快速实现移动端短视频功能?>中,我们主要介绍了当前短视频的大热趋势以及开发一个短视频应用所涉及到的功能和业务.在本篇文章中,我们主要谈一谈短视频在Android端上的具体实现技术 ...

  8. Android 音视频开发(一):PCM 格式音频的播放与采集

    什么是 PCM 格式 声音从模拟信号转化为数字信号的技术,经过采样.量化.编码三个过程将模拟信号数字化. 采样 顾名思义,对模拟信号采集样本,该过程是从时间上对信号进行数字化,例如每秒采集 44100 ...

  9. 【秒懂音视频开发】23_H.264编码

    本文主要介绍一种非常流行的视频编码:H.264. 计算一下:10秒钟1080p(1920x1080).30fps的YUV420P原始视频,需要占用多大的存储空间? (10 * 30) * (1920 ...

随机推荐

  1. 使用eclipse-hadoop插件无法再eclipse操作(上传、删除文件)

    再conf中的hdfs-site.xml添加如下配置: <property><name>dfs.permissions</name><value>fal ...

  2. Import declarations are not supported by current JavaScript version

    原因为:不支持当前的js版本,在perference中进行设置javascript的版本即可 注意:在perference中进行更改,而不是defeaut perference,快捷键操作为:comm ...

  3. WinDbg常用命令系列---.effmach

    .effmach (Effective Machine) .effmach命令显示或更改调试器使用的处理器模式. .effmach [MachineType] 参数: MachineType指定调试器 ...

  4. python(二)——if条件语句与基本数据类型

    if语句 缩进要保持一致 if 1 == 1: print('hello') if 2 == 2: print('world') else: print('python') elif inp = in ...

  5. Lightning Web Components 组件样式(四)

    要将样式与组件进行绑定,需要创建一个同名的样式文件,这样样式将会自动应用到组件 在组件中定义的样式的作用域是属于组件的,这样允许组件可以在不同的上下文中可以复用, 可以阻止其他组件的样式的复写 css ...

  6. 洛谷P1270 访问美术馆

    题目 树形DP,首先考虑递归建图,类似于线段树的中序遍历.然后取状态dp[i][j]表示i点花费j时间所偷到的最多的画,有方程: \(dp[now][nwt] = max(dp[now][nwt], ...

  7. windows环境搭建dubbo服务

    windows环境搭建dubbo服务 1:首先需要下载dubbo的注册中心 zookeeper zookeeper注册中心下载地址链接:http://mirror.bit.edu.cn/apache/ ...

  8. 微信小程序之数据缓存

    关于缓存,举个示例,假定我不是通过微信授权登录的方式,小程序又是如何识别我登录后的身份呢???效果图: 这个功能我是通过缓存实现的. 关键核心代码如下: wx.setStorage({ key: 'u ...

  9. Net core学习系列(六)——Net Core路由

    一.概述 路由主要有两个主要功能: 1.将请求的URL与已定义的路由进行匹配,找到该URL对应的处理程序并传入该请求进行处理. 2.根据已定义的路由生成URL 这两个功能看起来这两个是相反的. A.路 ...

  10. 去掉 vue 的 "You are running Vue in development mode" 提示

    去掉 vue 的 "You are running Vue in development mode" 提示 在项目的 main.js 中已经配置了 Vue.config.produ ...