sdl+ffmpeg视频播放器

本文介绍了一款在Windows XP环境下利用SDL2版本2.0.3和ffmpeg版本2.4开发的视频播放器。开发环境为CodeBlocks13.12,尽管声音和视频播放功能已实现,但SDL的事件处理存在一个问题,即当窗口被拖动或长时间点击时,音频播放会停止,而视频仍能继续播放。作者提供了ffmpeg的教程链接和工程代码以供参考,希望寻求解决方案。
摘要由CSDN通过智能技术生成

主机环境:Windows XP

SDL版本:SDL2-2.0.3

ffmpeg版本:ffmpeg.2.4

ffmpeg库版本:ffmpeg-20140916-git-b76d613-win32-dev.7z、ffmpeg-20140916-git-b76d613-win32-shared.7z

开发环境:CodeBlocks13.12

结合之前的音频播放器和视频播放器代码,如下

#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavformat/avio.h>
#include <libavutil/file.h>
#include <libavutil/mem.h>
#include <libswscale/swscale.h>
#include <libavutil/channel_layout.h>
#include <libavutil/samplefmt.h>
#include <libswresample/swresample.h>
#include <libavutil/opt.h>
#include <SDL2/SDL.h>
#include <stdbool.h>

#if SDL_BYTEORDER == SDL_BIG_ENDIAN
#define    rmask 0xff000000
#define    gmask 0x00ff0000
#define    bmask 0x0000ff00
#define    amask 0x000000ff
#else
#define    rmask  0x000000ff
#define    gmask  0x0000ff00
#define    bmask  0x00ff0000
#define    amask  0xff000000
#endif

#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000
typedef struct PacketQueue
{
    AVPacketList *first_pkt, *last_pkt;//首尾指针
    int nb_packets;//包数
    int size;//包中的字节数
    SDL_mutex *mutex;//互斥变量
    SDL_cond *cond;//条件变量
} PacketQueue;
PacketQueue audioQ;

struct SwrContext *audio_swr_ctx;//重采样上下文
uint64_t out_ch_layout = AV_CH_LAYOUT_STEREO;//输出声道布局
int out_nb_samples = 1024;
enum AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_S16;//输出源采样格式
int out_rate = 44100;//输出源的采样率
int out_nb_channels = 0;//得到通道数
int out_buffer_size = 0;//输出源的缓存大小

void packet_queue_init(PacketQueue *pq)
{
    memset(pq,0,sizeof(PacketQueue));//清空结构体
    pq->mutex = SDL_CreateMutex();//创建一个互斥量
    pq->cond = SDL_CreateCond();//创建一个条件量
}
/**
first_pkt指针指向第一个数据包元素,每次更新last_pkt指针,指向最后一个数据包元素
**/
int packet_queue_put(PacketQueue *pq, AVPacket *pkt)
{
    AVPacketList *pktlist;
    if(av_dup_packet(pkt) < 0)
    {
        printf("dup packet error!\n");
        //将数据拷贝至私有缓存中
        return -1;
    }
    pktlist = av_malloc(sizeof(AVPacketList));
    if(!pktlist)
    {
        return -1;
    }
    pktlist->pkt = *pkt;//初始化列表元素
    pktlist->next = NULL;//初始化列表元素

    SDL_LockMutex(pq->mutex);//上锁
    if(!pq->last_pkt)
    {
        //如果last_pkt指针为空,则重新链接first_pkt指针至新建的pktlist元素
        pq->first_pkt = pktlist;
    }
    else
    {
        //如果last指针不为空,则将pktlist元素添加到last链表末端
        pq->last_pkt->next = pktlist;
    }
    pq->last_pkt = pktlist;//将last_pkt指针指向新添加的pktlist元素,移动last_pkt指针
    pq->nb_packets++;//数据包个数增加
    pq->size+=pktlist->pkt.size;//数据大小增加
    SDL_CondSignal(pq->cond);//通知条件变量
    SDL_UnlockMutex(pq->mutex);//解锁
    return 0;
}
int quit = 0;
/**
从队列中取出一个数据包block:标记是否以阻塞方式取数据包
**/
static int packet_queue_get(PacketQueue *pq, AVPacket *ptk, int block)
{
    AVPacketList *pktlist;
    int ret;
    SDL_LockMutex(pq->mutex);//上锁
    static bool flag = fal
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值