音视频原始数据产生器
来源:互联网 发布:淘宝教程我要自学网 编辑:程序博客网 时间:2024/05/22 10:24
由于研究ffmpeg,有时候你需要音频原始数据PCM和视频原始数据YUV,所以自己写了一个类,用来产生原始数据。有的格式是可以的,但有的可是好像不行,原因为深入研究,现在也不弄音视频了,所以就放下了。半年前的东西那出来就是希望帮助到需要的人。
下面是头文件和cpp
decodec.h
#ifndef DECODEC_HH#define DECODEC_HH/************************************************@描述:将输入的媒体文件解码成原始数据,(yuv and pcm);**生成的音频数据可使用Audacity查看,->导入裸数据。。。**生成的视频数据可使用ffplay查看,命令如:ffplay -pix_fmt yuv420p -s 720x480 -i D:\FFM\No_mkv\yuv420p_720_480.yuv@作者:毕竟小白@日期:2015/3/3*************************************************/#ifdef __cplusplusextern "C"{#endif#include "libavcodec/avcodec.h"#include "libavformat/avformat.h"#ifdef __cplusplus};#endif#include <fstream>#include <string>#include <vector>#include <map>using namespace std;class Decodec{public:Decodec(string InFileName);~Decodec(void);void decodec();private:int openFile();void closeFile();void writeData();void flushData();private:stringm_InFile;stringm_dirFile;ofstream m_vfout;map<int, ofstream*>m_afout;stringm_outPath;char*m_buff;intm_buffSize;AVFormatContext*m_ifmt_ctx;};#endif //DECODEC_HH
</pre><pre name="code" class="cpp">decodec.cpp
</pre><pre name="code" class="cpp">#include "Decodec.h"#ifdef __cplusplusextern "C"{#endif#include "libavutil\pixdesc.h"#ifdef __cplusplus};#endif#include <iostream>#include <direct.h>Decodec::Decodec(std::string InFileName):m_InFile(InFileName){m_buff = NULL;m_buffSize = 0;m_ifmt_ctx = NULL;}Decodec::~Decodec(void){}void Decodec::decodec(){if(m_InFile.empty()){cout << "InFile is empty!" << endl;return;}av_register_all();if(openFile() < 0) goto end;writeData();flushData();end:closeFile();}int Decodec::openFile(){int ret = 0;ret = avformat_open_input(&m_ifmt_ctx, m_InFile.c_str(), NULL, NULL);if (ret < 0) {cout << "Could not open input!" << endl;return ret;}ret = avformat_find_stream_info(m_ifmt_ctx, NULL);if (ret < 0) {cout << "Could not find stream information!" << endl;return ret;}int pos = m_InFile.rfind('.');m_dirFile = m_InFile.substr(0, pos);if(pos < m_InFile.size())m_dirFile = m_dirFile + "_" + m_InFile.substr(pos+1);ret = _mkdir(m_dirFile.c_str());// if(ret < 0)// {// cout << "Failed to creat directory !" << endl;// return ret;// }for(int index = 0; index < m_ifmt_ctx->nb_streams; index++){AVStream* stream = m_ifmt_ctx->streams[index];AVCodecContext* codec_ctx = m_ifmt_ctx->streams[index]->codec;AVCodec *codec = avcodec_find_decoder(codec_ctx->codec_id);ret = avcodec_open2(codec_ctx, codec, NULL);if(ret < 0) {cout << "Can't open this CodecContext, stream index is " << index << endl;return ret;}char temp[64] = "";if(AVMEDIA_TYPE_VIDEO == stream->codec->codec_type){string pixfmt(av_get_pix_fmt_name(codec_ctx->pix_fmt));string file = m_dirFile + "\\" + pixfmt + "_" + itoa(codec_ctx->width, temp, 10) + "_" + itoa(codec_ctx->height, temp, 10) + ".yuv";m_vfout.open(file.c_str(), ios::out|ios::binary);if(!m_vfout.is_open()) return -1;m_buffSize = avpicture_get_size(codec_ctx->pix_fmt, codec_ctx->width, codec_ctx->height);m_buff = new char[m_buffSize];if(NULL == m_buff) return -1;}else if(AVMEDIA_TYPE_AUDIO == stream->codec->codec_type){string sample_fmt(av_get_sample_fmt_name(codec_ctx->sample_fmt));string file = m_dirFile + "\\" + sample_fmt + "_" + itoa(codec_ctx->sample_rate, temp, 10) +"_" + itoa(codec_ctx->channels, temp, 10) + "_" + itoa(index, temp, 10);ofstream* fout = new ofstream;fout->open(file.c_str(), ios::out|ios::binary);if(!fout->is_open()) return -1;m_afout[index] = fout;}}return ret;}void Decodec::closeFile(){avformat_close_input(&m_ifmt_ctx);if(m_buffSize != 0) delete[] m_buff;if(m_vfout.is_open()) m_vfout.close();for(map<int, ofstream*>::iterator iterMap = m_afout.begin();iterMap != m_afout.end();iterMap++){iterMap->second->close();delete iterMap->second;}}void Decodec::writeData(){AVPacket pkt;av_init_packet(&pkt);pkt.data = NULL;pkt.size = 0;while (av_read_frame(m_ifmt_ctx, &pkt) >= 0){AVFrame* frame = av_frame_alloc();AVCodecContext* codec_ctx = m_ifmt_ctx->streams[pkt.stream_index]->codec;int got_frame = 0, len = 0;if(AVMEDIA_TYPE_AUDIO == codec_ctx->codec_type){ofstream* fout = m_afout[pkt.stream_index];len = avcodec_decode_audio4(codec_ctx, frame, &got_frame, &pkt);if(len < 0){cout << "Error while decoding !" << endl;return;}if(got_frame){int sampleByte = av_get_bytes_per_sample(codec_ctx->sample_fmt);if(av_sample_fmt_is_planar(codec_ctx->sample_fmt)){for(int nbsample = 0; nbsample < frame->nb_samples; nbsample++){for(int channel = 0; channel < frame->channels; ++channel){fout->write(reinterpret_cast<char*>(frame->data[channel]+nbsample*sampleByte), sampleByte);}}}else{fout->write(reinterpret_cast<char*>(frame->data[0]), sampleByte*frame->nb_samples*frame->channels);}}}else if(AVMEDIA_TYPE_VIDEO == codec_ctx->codec_type){len = avcodec_decode_video2(codec_ctx, frame, &got_frame, &pkt);if(len < 0){cout << "Error while decoding !" << endl;return;}if(got_frame){int ret = avpicture_layout(reinterpret_cast<const AVPicture*>(frame), codec_ctx->pix_fmt, frame->width, frame->height,reinterpret_cast<unsigned char*>(m_buff), m_buffSize);if(ret < 0) return;m_vfout.write(m_buff, m_buffSize);}}av_free_packet(&pkt);av_frame_free(&frame);}}void Decodec::flushData(){AVPacket pkt;av_init_packet(&pkt);pkt.data = NULL;pkt.size = 0;for(int index = 0; index < m_ifmt_ctx->nb_streams; ++index){AVFrame* frame = av_frame_alloc();AVCodecContext* codec_ctx = m_ifmt_ctx->streams[index]->codec;int got_frame = 0, len = 0;if(AVMEDIA_TYPE_AUDIO == codec_ctx->codec_type){ofstream* fout = m_afout[index];while( len = avcodec_decode_audio4(codec_ctx, frame, &got_frame, &pkt) ){if(len < 0) break; if(got_frame){int sampleByte = av_get_bytes_per_sample(codec_ctx->sample_fmt);if(av_sample_fmt_is_planar(codec_ctx->sample_fmt)){for(int nbsample = 0; nbsample < frame->nb_samples; nbsample++){for(int channel = 0; channel < frame->channels; ++channel){fout->write(reinterpret_cast<char*>(frame->data[channel]+nbsample*sampleByte), sampleByte);}}}else{fout->write(reinterpret_cast<char*>(frame->data[0]), sampleByte*frame->nb_samples*frame->channels);}}}}else if(AVMEDIA_TYPE_VIDEO == codec_ctx->codec_type){while( len = avcodec_decode_video2(codec_ctx, frame, &got_frame, &pkt) ){if(len < 0) break;if(got_frame){<span style="white-space:pre"></span>int ret = avpicture_layout(reinterpret_cast<const AVPicture*>(frame), codec_ctx->pix_fmt, frame->width,
frame->height, reinterpret_cast<unsigned char*>(m_buff), m_buffSize);if(ret < 0) return;m_vfout.write(m_buff, m_buffSize);}}}av_frame_free(&frame);}}
</pre><pre name="code" class="cpp"></pre><pre name="code" class="cpp">
main.cpp
</pre><pre name="code" class="cpp"></pre><pre name="code" class="cpp">#include "Decodec.h"int main(void){<span style="white-space:pre"></span>Decodec de("test.mp4");<span style="white-space:pre"></span>de.decodec();<span style="white-space:pre"></span>return 0;}
工程下载链接
0 0
- 音视频原始数据产生器
- 原始数据
- 原始数据
- 如何从H264原始数据SPS里面得到视频的长宽
- 如何从H264原始数据SPS里面得到视频的长宽
- AIS原始数据
- 原始数据类型
- 随机数产生器
- 随机数产生器
- 使用 ffmpeg 进行网络推流:拉流->解封装->解码->处理原始数据(音频、视频)->编码->编码->推流
- php获取post原始数据
- java原始数据类型介绍
- javascript 基础-原始数据类型
- javascript 基础-原始数据类型
- java原始数据类型案例
- 不要向外暴露原始数据
- Java的原始数据类型
- 中海达原始数据转RINEX
- Android处理图片OOM的若干方法小结
- Android性能(时间)分析工具-TraceView的使用
- Android内存管理试验——浅谈ImageView的Bitmap的使用
- 牛顿法-最优化方法
- 毕业生-告诫自己每天看一遍,你将获益终生。
- 音视频原始数据产生器
- js 金钱格式转化
- 解决Unsupported major.minor version 51.0问题的感悟
- IDF实验室:百密一疏--笨笨的小猪
- Android从资源文件中读取文件全
- 随笔——2015.05.25
- android 多线程 - 并行包线程池为例说说线程池的设计需求及使用
- Struts2的Action接受参数的方法介绍
- openwrt 编译命令记录