音视频原始数据产生器

来源:互联网 发布:淘宝教程我要自学网 编辑:程序博客网 时间: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