#include "FFmpegPlayer.h"
#include<QDebug>
#include<windows.h>
#include<QTime>
#include<QImage>
#include"Global_ValueGather.h"
#define USE_MUTE 1
static bool isquit=false; //清空了
int VOL=80;
// 包队列初始化
void packet_queue_init(PacketQueue* q)
{
q->last_pkt = NULL;
q->first_pkt = NULL;
#if USE_MUTE
q->mutex = SDL_CreateMutex();
q->cond = SDL_CreateCond();
#endif
}
// 放入packet到队列中,不带头指针的队列
int packet_queue_put(PacketQueue*q, AVPacket *pkt)
{
AVPacketList *pktl;
if (av_dup_packet(pkt) < 0)
return -1;
pktl = (AVPacketList*)av_malloc(sizeof(AVPacketList));
if (!pktl)
return -1;
pktl->pkt = *pkt;
pktl->next = nullptr;
#if USE_MUTE
SDL_LockMutex(q->mutex);
#endif
if (!q->last_pkt) // 队列为空,新插入元素为第一个元素
q->first_pkt = pktl;
else // 插入队尾
q->last_pkt->next = pktl;
q->last_pkt = pktl;
q->nb_packets++;
q->size += pkt->size;
#if USE_MUTE
SDL_CondSignal(q->cond);
SDL_UnlockMutex(q->mutex);
#endif
return 0;
}
// 从队列中取出packet
int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block) {
AVPacketList *pkt1=NULL;
int ret;
#if USE_MUTE
SDL_LockMutex(q->mutex);
#endif
for (;;)
{
if (isquit)
return -1;
pkt1 = q->first_pkt;
if (pkt1) {
q->first_pkt = pkt1->next;
if (!q->first_pkt) {
q->last_pkt = NULL;
}
q->nb_packets--;
q->size -= pkt1->pkt.size;
*pkt = pkt1->pkt;
av_free(pkt1);
ret = 1;
break;
} else if (!block) {
ret = 0;
break;
} else {
#if USE_MUTE
SDL_CondWait(q->cond, q->mutex);
#endif
}
}
#if USE_MUTE
SDL_UnlockMutex(q->mutex);
#endif
return ret;
}
void packet_queue_flush(PacketQueue *q)
{
#if USE_MUTE
SDL_LockMutex(q->mutex);
#endif
AVPacketList *pkt=NULL, *pkt1=NULL;
for(pkt = q->first_pkt; pkt != NULL; pkt = pkt1)
{
pkt1 = pkt->next;
if(pkt1->pkt.data != (uint8_t *)"FLUSH")
{
}
av_free_packet(&pkt->pkt);
av_freep(&pkt);
}
q->last_pkt = NULL;
q->first_pkt = NULL;
q->nb_packets = 0;
q->size = 0;
#if USE_MUTE
SDL_UnlockMutex(q->mutex);
#endif
}
//////////////////////////////////////////////解码音频数据
int audio_decode_frame(mediaState* MS, uint8_t* audio_buf, int buf_size)
{
int len1;
int data_size = 0;
if (isquit)
return -1;
while (true)
{
while (MS->audio_pkt_size > 0)
{
int got_frame = 0;
len1 = avcodec_decode_audio4(MS->acct, MS->frame, &got_frame, &MS->pkt);
if (len1 < 0) // 出错,跳过
{
MS->audio_pkt_size = 0;
break;
}
MS->audio_pkt_data += len1;
MS->audio_pkt_size -= len1;
data_size = 0;
if (got_frame)
data_size = av_samples_get_buffer_size(nullptr, MS->acct->channels,MS-> frame->nb_samples, MS->acct->sample_fmt, 1);
if (MS->frame->channels > 0 && MS->frame->channel_layout == 0)
MS->frame->channel_layout = av_get_default_channel_layout(MS->frame->channels);
else if (MS->frame->channels == 0 && MS->frame->channel_layout > 0)
MS->frame->channels = av_get_channel_layout_nb_channels(MS->frame->channel_layout);
if (MS->swr_ctx)
{
swr_free(&MS->swr_ctx);
MS->swr_ctx = nullptr;
}
MS->swr_ctx = swr_alloc_set_opts(nullptr, MS->wanted_frame->channel_layout,
(AVSampleFormat)MS->wanted_frame->format,
MS->wanted_frame->sample_rate,
MS->frame->channel_layout,
(AVSampleFormat)MS->frame->format,
MS->frame->sample_rate, 0, nullptr);
if (!MS->swr_ctx || swr_init(MS->swr_ctx) < 0)
{
qDebug() << "swr_init failed:" << endl;
break;
}
int dst_nb_samples = av_rescale_rnd(swr_get_delay(MS->swr_ctx, MS->frame->sample_rate) + MS->frame->nb_samples, MS->frame->sample_rate, MS->frame->sample_rate, AVRounding(1));
int len2 = swr_convert(MS->swr_ctx, &audio_buf, dst_nb_samples,(const uint8_t**)MS->frame->data, MS->frame->nb_samples);//这个才是最重要的~前面所做的工作都是为这个
if (len2 < 0)
{
qDebug() << "swr_convert failed\n";
break;
}
//[][]相当重要的一步,转换成时间
int resampled_data_size = len2 * MS->wanted_frame->channels* av_get_bytes_per_sample((AVSampleFormat)MS->wanted_frame->format);
int n = 2 * MS->audio_st->codec->channels;
MS->audio_clock += (double)resampled_data_size/(double)(n * MS->audio_st->codec->sample_rate);
//[][]
return MS->wanted_frame->channels * len2 * av_get_bytes_per_sample((AVSampleFormat)MS->wanted_frame->format);
} //end while
if (MS->pkt.buf)
av_free_packet(&MS->pkt); //删除包
if (packet_queue_get(&MS->audioq,&MS->pkt,0)<=0) //重新从队列中获取包
{
return -1;
}
//收到这个数据 说明刚刚执行过跳转 现在需要把解码器的数据 清除一下
if(strcmp((char*)MS->pkt.data,FLUSH_DATA) == 0)
{
avcodec_flush_buffers(MS->audio_st->codec);
av_free_packet(&MS->pkt);
continue;
}
if (MS->pkt.pts != AV_NOPTS_VALUE)
{
MS->audio_clock = (double)av_q2d(MS->audio_st->time_base) * (double)MS->pkt.pts;
}
MS->audio_pkt_data =MS->pkt.data;
MS->audio_pkt_size = MS->pkt.size;
}
}
// 解码后的回调函数
void audio_callback(void* userdata, Uint8* stream, int len)
{
mediaState* MS = (mediaState*)userdata;
int len1, audio_size;
SDL_memset(stream, 0, len);
if (isquit)
return;
while (len > 0)
{
uint8_t audio_buff[MAX_AUDIO_FRAME_SIZE*2];
if (MS->audio_buf_index >= MS->audio_buf_size)
{
audio_size = audio_decode_frame(MS, audio_buff, sizeof(audio_buff));
if (isquit)
return;
if (audio_size < 0)
{
MS->audio_buf_size = 1024;
SDL_memset(audio_buff, 0, MS->audio_buf_size);
}
else
MS->audio_buf_size = audio_size;
MS->audio_buf_index = 0;
}
len1 = MS->audio_buf_size - MS->audio_buf_index;
if (len1 > len)
len1 = len;
SDL_MixAudio(stream, audio_buff + MS->audio_buf_index, len, VOL);
len -= len1;
stream += len1;
MS->audio_buf_index += len1;
}
}
static double synchronize_video(mediaState *MS, AVFrame *src_frame, double pts) {
double frame_delay;
if (pts != 0)
{
/* if we have pts, set video clock to it */
MS->video_clock = pts;
} else
{
/* if we aren't given a pts, set it to the clock */
pts = MS->video_clock;
}
/* update the video clock */
frame_delay = av_q2d(MS->video_st->codec->time_base);
/* if we are repeating a frame, adjust clock accordingly */
frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
MS->video_clock += frame_delay;
return pts;
}
int video_thread(void *arg)
{
mediaState *is = (mediaState *) arg;
AVPacket pkt1, *packet = &pkt1;
int ret, got_picture, numBytes;
double video_pts = 0; //当前视频的pts
double audio_pts = 0; //音频pts
///�
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
qt5 开发的酷狗播放器源码,GUI完全仿酷狗,很值得学习的资源 (543个子文件)
libavutil.dll.a 307KB
libavcodec.dll.a 158KB
libavformat.dll.a 115KB
libavfilter.dll.a 42KB
libswscale.dll.a 22KB
libswresample.dll.a 15KB
libavdevice.dll.a 13KB
libpostproc.dll.a 7KB
FFmpegPlayer.cpp 20KB
FFmpegPlayer-v1.1.cpp 20KB
mainwindow.cpp 20KB
mytablewidget.cpp 20KB
lyriclabel.cpp 15KB
middleLeftStackWidget0.cpp 14KB
mynetwork.cpp 14KB
myTablePlayListFinal.cpp 14KB
middleSearchWidget.cpp 12KB
FFmpegPlayer-succ.cpp 12KB
myshowtablebutton.cpp 12KB
bottomWidgets.cpp 12KB
myPushButton.cpp 11KB
skinWidget.cpp 11KB
middleSearchTableWidget.cpp 10KB
topwidgets.cpp 10KB
FFmpegPlayer-ori.cpp 10KB
middleWidgetRight.cpp 9KB
playingWidget.cpp 7KB
trayiconmenu.cpp 7KB
middlewidgetleft.cpp 7KB
AbsFrameLessAutoSize.cpp 7KB
deskTopLrcWidget.cpp 7KB
myDataBase.cpp 6KB
lyric.cpp 5KB
mainWindowContentWidget.cpp 5KB
myPlayer.cpp 5KB
pushButtonOnTable.cpp 4KB
topSearchTipsWidget.cpp 4KB
basewindow.cpp 3KB
middleconvienttwobutton.cpp 3KB
middleLeftStackWidget1.cpp 3KB
qsingleapplication.cpp 3KB
middleWidgets.cpp 3KB
baseDialog.cpp 2KB
main.cpp 2KB
buttonstackedwidget.cpp 2KB
middleLeftStackWidget3.cpp 2KB
TextMovingWidget.cpp 2KB
myMediaList.cpp 2KB
myTableAddWidget.cpp 2KB
mySlider.cpp 1KB
skinWidgetSliderWidget.cpp 1KB
baseWidget.cpp 819B
MvWidget.cpp 670B
middleLeftStackWidget4.cpp 667B
middleLeftStackWidget2.cpp 545B
Global_ValueGather.cpp 520B
WebWidget.cpp 322B
QWebViewStyle.css 479B
avutil-55.def 11KB
avcodec-57.def 6KB
avformat-57.def 4KB
avfilter-6.def 2KB
zlib.def 1KB
swscale-4.def 756B
avdevice-57.def 554B
swresample-2.def 478B
postproc-54.def 233B
myTablePlayListFinal.h.gV2568 2KB
SDL_opengl.h 622KB
avcodec.h 206KB
SDL_opengles2.h 129KB
avformat.h 111KB
avfilter.h 40KB
SDL_haptic.h 38KB
opt.h 35KB
SDL_video.h 33KB
SDL_render.h 32KB
pixfmt.h 31KB
avio.h 29KB
SDL_events.h 26KB
frame.h 24KB
mem.h 23KB
swresample.h 21KB
SDL_audio.h 20KB
SDL_hints.h 19KB
SDL_surface.h 18KB
intreadwrite.h 18KB
avdevice.h 18KB
hwcontext.h 16KB
common.h 15KB
SDL_pixels.h 15KB
SDL_scancode.h 15KB
SDL_keycode.h 14KB
pixdesc.h 14KB
SDL_stdinc.h 14KB
avstring.h 14KB
SDL_test_fuzzer.h 13KB
swscale.h 12KB
log.h 11KB
SDL_assert.h 10KB
共 543 条
- 1
- 2
- 3
- 4
- 5
- 6
资源评论
- xuelicun2019-01-09拿人家的代码干啥,还一模一样
- Hi斩月2017-08-13界面挺漂亮的,缺少ffmpeg的运行库,没有说明是QT5的哪个版本
布鲁克斯南南
- 粉丝: 26
- 资源: 14
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功