程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python&C++相互混合調用編程全面實戰-31完成擴展庫中打開ffmpeg解碼器

編輯:Python

作者:虛壞叔叔
博客:https://xuhss.com

早餐店不會開到晚上,想吃的人早就來了!

完成擴展庫中打開ffmpeg解碼器

一、添加解碼器上下文成員變量

XFFmpeg.h添加成員變量

解碼器上下文:AVCodecContext *vcodec

添加Close函數用於釋放上下文

 void Close();

完整代碼如下

#pragma once
struct AVFormatContext;
struct AVPacket;
struct AVCodecContext;
class XFFmpeg
{
public:
// 打開視頻
bool Open(const char *url);
// 讀取一陣視頻 在內部存儲
bool Read();
void Close();
XFFmpeg();
~XFFmpeg();
int totalms = 0;
protected:
// 解封裝上下文
AVFormatContext *ic = 0;
// 讀取視頻幀
AVPacket *pkt = 0;
// 解碼器上下文
AVCodecContext *vcodec = 0;
};

二、分配解碼器並完成解碼器相關內存釋放

XFFmpeg.cpp添加open和close函數的實現

open函數的實現

bool XFFmpeg::Open(const char *url)
{

printf("XFFmpeg::open %s\n", url);
// 打開視頻 解封裝
int re =avformat_open_input(&ic, url, 0, 0);
if (re != 0)
{

char buf[1024] = {
 0 };
av_strerror(re, buf, 1023);
printf("avformat open fail:%s\n", buf);
return false;
}
// 獲取流
avformat_find_stream_info(ic, 0);
// 獲取視頻總時長
this->totalms = ic->duration / (AV_TIME_BASE / 1000);
printf("Total Ms =%d\n", totalms);
// 打開解碼器 0視頻 1音頻
AVCodecParameters *para = ic->streams[0]->codecpar;
// 找到解碼器
AVCodec * codec = avcodec_find_decoder(para->codec_id);
if (!codec)
{

printf("avcodec_find_decoder %d failed!\n", para->codec_id);
}
// 分配解碼器上下文
vcodec = avcodec_alloc_context3(codec);
// 配置解碼器上下文
avcodec_parameters_to_context(vcodec, para);
// 多線程解碼
vcodec->thread_count = 8;
// 打開上下文
re = avcodec_open2(vcodec, 0, 0);
if (re != 0)
{

avcodec_free_context(&vcodec);
char buf[1024];
av_strerror(re, buf, sizeof(buf) - 1);
printf("avcodec_open2 failec:%s!\n", buf);
}
printf("avcodec_open2 successed \n");
return true;
}

Close函數實現那:

void XFFmpeg::Close()
{

printf("XFFmpeg::Close\n");
if (ic)
{

avformat_close_input(&ic);
}
if (vcodec)
{

avcodec_free_context(&vcodec);
}
if (pkt)
{

av_packet_free(&pkt);
}
}

完整代碼如下

#include "XFFmpeg.h"
#include <stdio.h>
extern "C" {

#include "libavformat\avformat.h"
}
void XFFmpeg::Close()
{

printf("XFFmpeg::Close\n");
if (ic)
{

avformat_close_input(&ic);
}
if (vcodec)
{

avcodec_free_context(&vcodec);
}
if (pkt)
{

av_packet_free(&pkt);
}
}
bool XFFmpeg::Open(const char *url)
{

printf("XFFmpeg::open %s\n", url);
// 打開視頻 解封裝
int re =avformat_open_input(&ic, url, 0, 0);
if (re != 0)
{

char buf[1024] = {
 0 };
av_strerror(re, buf, 1023);
printf("avformat open fail:%s\n", buf);
return false;
}
// 獲取流
avformat_find_stream_info(ic, 0);
// 獲取視頻總時長
this->totalms = ic->duration / (AV_TIME_BASE / 1000);
printf("Total Ms =%d\n", totalms);
// 打開解碼器 0視頻 1音頻
AVCodecParameters *para = ic->streams[0]->codecpar;
// 找到解碼器
AVCodec * codec = avcodec_find_decoder(para->codec_id);
if (!codec)
{

printf("avcodec_find_decoder %d failed!\n", para->codec_id);
}
// 分配解碼器上下文
vcodec = avcodec_alloc_context3(codec);
// 配置解碼器上下文
avcodec_parameters_to_context(vcodec, para);
// 多線程解碼
vcodec->thread_count = 8;
// 打開上下文
re = avcodec_open2(vcodec, 0, 0);
if (re != 0)
{

avcodec_free_context(&vcodec);
char buf[1024];
av_strerror(re, buf, sizeof(buf) - 1);
printf("avcodec_open2 failec:%s!\n", buf);
}
printf("avcodec_open2 successed \n");
return true;
}
bool XFFmpeg::Read()
{

if (!ic)
return false;
// 視頻幀的存儲空間
if (!pkt)
{

// 分配對象空間
pkt = av_packet_alloc();
}
else
{

// 引用計數 -1 清理視頻幀
av_packet_unref(pkt);
}
int re = 0;
bool isFindVideo = false;
// 音頻數據丟掉
for (int i = 0; i < 20; i++)
{

// 讀取一幀數據
re = av_read_frame(ic, pkt);
// 讀取失敗或者讀取到文件結尾
if (re != 0)
{

return false;
}
// 是否是視頻幀
if (pkt->stream_index == 0)
{

isFindVideo = true;
break;
}
// 音頻幀 清理packet
av_packet_unref(pkt);
}
return isFindVideo;
}
XFFmpeg::XFFmpeg()
{

printf("Create XFFmpeg\n");
}
XFFmpeg::~XFFmpeg()
{

printf("Delete XFFmpeg\n");
}

PyFFmpeg.cpp中添加Close函數的調用:

void PyFFmpeg::Close(PyFFmpeg*self)
{

printf("PyFFmpeg::Close\n");
self->ff->Close();
delete self->ff;
Py_TYPE(self)->tp_free(self);
}

運行後,你會發現,解碼器上下文加載成功

三、總結

  • 本文完成擴展庫中打開ffmpeg解碼器 。
  • 如果覺得文章對你有用處,記得 點贊收藏轉發 一波哦,博主也支持為鐵粉絲制作專屬動態壁紙哦~

往期優質文章分享

  • C++ QT結合FFmpeg實戰開發視頻播放器-01環境的安裝和項目部署
  • 解決QT問題:運行qmake:Project ERROR: Cannot run compiler ‘cl‘. Output:
  • 解決安裝QT後MSVC2015 64bit配置無編譯器和調試器問題
  • Qt中的套件提示no complier set in kit和no debugger,出現黃色感歎號問題解決(MSVC2017)
  • Python+selenium 自動化 - 實現自動導入、上傳外部文件(不彈出windows窗口)

優質教程分享

  • 如果感覺文章看完了不過瘾,可以來我的其他 專欄 看一下哦~
  • 比如以下幾個專欄:Python實戰微信訂餐小程序、Python量化交易實戰、C++ QT實戰類項目 和 算法學習專欄
  • 可以學習更多的關於C++/Python的相關內容哦!直接點擊下面顏色字體就可以跳轉啦!
學習路線指引(點擊解鎖)知識定位人群定位🧡 Python實戰微信訂餐小程序 🧡進階級本課程是python flask+微信小程序的完美結合,從項目搭建到騰訊雲部署上線,打造一個全棧訂餐系統。Python量化交易實戰入門級手把手帶你打造一個易擴展、更安全、效率更高的量化交易系統️ C++ QT結合FFmpeg實戰開發視頻播放器️難度偏高分享學習QT成品的視頻播放器源碼,需要有扎實的C++知識! 游戲愛好者九萬人社區互助/吹水九萬人游戲愛好者社區,聊天互助,白嫖獎品 Python零基礎到入門 Python初學者針對沒有經過系統學習的小伙伴,核心目的就是讓我們能夠快速學習Python的知識以達到入門

資料白嫖,溫馨提示

關注下面卡片即刻獲取更多編程知識,包括各種語言學習資料,上千套PPT模板和各種游戲源碼素材等等資料。更多內容可自行查看哦!


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved