本人学习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 >