音视频学习ffmpeg+sdl

本文档介绍了作者使用ffmpeg和SDL库进行音视频播放的学习过程,包括关键代码实现,如读取、解码、播放音视频流等。通过创建线程进行数据读取和解码,实现播放功能。同时,提供了播放器的控制逻辑,如音量调节、暂停、快进快退等操作。
摘要由CSDN通过智能技术生成
  1.        

         本人学习ffmpeg+sdl有一年多了,在网上自学了很多,特别是雷神的,谢谢他。还有其他人,谢他们了。

 现总结代码如下:运行环境vs2019专业版,其他版本也行。

#include<conio.h>
#include<stdio.h>
#include<string.h>
#include<SDL.h>
#include<stdlib.h>
#include<iostream>
extern "C"
{
#include<libavcodec/avcodec.h>
#include<libavdevice/avdevice.h>
#include<libavformat/avformat.h>
#include<libavutil/avutil.h>
#include<libavfilter/avfilter.h>
#include<libswscale/swscale.h>
#include<libswresample/swresample.h>
#include<libpostproc/postprocess.h>
#include<libavutil/imgutils.h>
}
typedef struct sp11
{
    int buffer_size;
    int channels;
    int samples_rate;
    int nb_samples;
    Uint8* buffer;
    int64_t in_channel_layout;
    int64_t out_channel_layout;
    AVSampleFormat sample_fmt;
};
typedef struct queue
{
    AVPacketList* head, * end;
    SDL_cond* cond;
    SDL_mutex* mutex;
};
typedef struct start
{
    char filename[512];
    AVFormatContext* fmt;
    AVStream* ast, * vst;
    AVCodecParameters* apar, * vpar;
    AVCodecContext* acct, * vcct;
    AVPacket* apack, * vpack;
    AVFrame* aframe, * vframe, * frameyuv;
    SwsContext* sws;
    SwrContext* swr;
    int audioindex, videoindex;
    queue* aq, * vq;
    int yuvw=0, yuvh=0;
};
start* is;
SDL_Window* win;
SDL_Renderer* er;
SDL_Texture* ure;
SDL_Rect rect = { 0 };
sp11 sp = { 0 };
SDL_AudioSpec spec = { 0 };
int stop = 1, quit = 1, xunhuan = 0, daodai = 0, pause = 0;
int vol = 20, index = 0;
double apts = 0, vpts = 0;
int pcm = 0,yuv=0;
int64_t sum = 0, duration = 0;
int s = SDL_WINDOWPOS_UNDEFINED;
int g = SDL_WINDOWPOS_UNDEFINED;
Uint8* buffer, * pos = 0,*pos2=0,*buffer1;
int32_t len1 = 0,len2=0;
int x = 500, y = 20, w = 300, h = 150;
AVPacket flush_p;
FILE* fp = NULL;
char* ret = NULL, * re = NULL;
int cong = 0;

void dest()
{
    is->fmt = NULL;
    is->acct = NULL;
    is->vcct = NULL;
    is->apack = NULL;
    is->vpack = NULL;
    is->aq = NULL;
    is->ast = NULL;
    is->vq = NULL;
    is->vframe = NULL;
    is->frameyuv = NULL;
    is->vst = NULL;
    is->vpar = NULL;
    is->apar = NULL;
    is->aframe = NULL;
    is->swr = NULL;
    is->sws = NULL;
    win = NULL;
    er = NULL;
    ure = NULL;
    sp = { 0 };
    spec = { 0 };

}
void queue_flush(queue* q)
{
    AVPacketList* p1, * p;
    SDL_LockMutex(q->mutex);
    for (p1 = q->head; p1 != NULL; p1 = p)
    {
        p = p1->next;
        av_packet_unref(&p1->pkt);
        av_freep(p1);
    }
    q->head = NULL;
    q->end = NULL;
    SDL_UnlockMutex(q->mutex);
}
void queue_init(queue* q)
{
    SDL_memset(q, 0, sizeof(queue));
    q->cond = SDL_CreateCond();
    q->mutex = SDL_CreateMutex();

}
int queue_put(queue* q, AVPacket* p)
{
    AVPacketList* p1;
    if (p != &flush_p && av_dup_packet(p) < 0)
    {
        return -1;
    }
    if (!quit)
    {
        return -1;
    }
    p1 = (AVPacketList*)av_malloc(sizeof(AVPacketList));
    p1->pkt = *p;
    p1->next = NULL;
    SDL_LockMutex(q->mutex);
    if (!q->end)
    {
        q->head = p1;
    }
    else
    {
        q->end->next = p1;
    }
    q->end = p1;
    SDL_CondSignal(q->cond);
    SDL_UnlockMutex(q->mutex);
    return 0;
}
int queue_get(queue* q, AVPacket* p, int block)
{
    AVPacketList* p1;
    SDL_LockMutex(q->mutex);
    
    for (;;)
    {
      if (!quit)
      {
        return -1;
      }

        p1 = q->head;
        if (p1)
        {
            q->head = p1->next;
            if (!q->head)
            {
                q->end = NULL;
            }
            *p = p1->pkt;
            av_free(p1);
            break;
        }
        if (!block)
        {
            return -1;
        }
        else
        {
            SDL_CondWait(q->cond, q->mutex);

        }

    }
    SDL_UnlockMutex(q->mutex);
    return 0;
}

int read(void* x)
{
    int luan = -1;
    AVPacket* pack = av_packet_alloc();
    AVRational a = { 1,AV_TIME_BASE };
    if (is->videoindex >= 0)
    {
        luan = is->videoindex;
        //duration = is->fmt->streams[is->audioindex]->duration * av_q2d(is->fmt->streams[is->audioindex]->time_base);
    }
    else
    {
        luan = is->audioindex;
        // duration = is->fmt->streams[is->videoindex]->duration * av_q2d(is->fmt->streams[is->videoindex]->time_base);
    }

    duration = is->fmt->streams[luan]->duration * av_q2d(is->fmt->streams[luan]->time_base);

     
    while (quit)
    {
         
        SDL_Delay(6);
        if (xunhuan)
        {
            if (apts >= duration || vpts >= duration)
            {
                index = 0;
                apts = 0;
                vpts = 0;
                av_seek_frame(is->fmt, -1, 0, AVSEEK_FLAG_BACKWARD);

                if (is->audioindex >= 0)
                {
                    queue_flush(is->aq);
                    queue_put(is->aq, &flush_p);
                }
                if (is->videoindex >= 0)
                {
                    queue_flush(is->vq);
                    queue_put(is->vq, &flush_p);
                }


            }

        }
        if (daodai)
        {   
            if (luan >

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值