ffmpeg學習---7.音視訊同步之視訊同步音訊
阿新 • • 發佈:2019-02-14
- #include <libavcodec/avcodec.h>
-
#include <libavformat/avformat.h>
-
#include <libswscale/swscale.h>
-
#include <libswresample/swresample.h>
-
#include <libavutil/avstring.h>
-
#include <libavutil/pixfmt.h>
-
#include <libavutil/log.h>
-
#include <libavutil/
-
#include <SDL/SDL.h>
-
#include <SDL/SDL_thread.h>
-
#include <stdio.h>
-
#include <math.h>
-
#define SDL_AUDIO_BUFFER_SIZE 4096
-
#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000
-
#define MAX_AUDIOQ_SIZE (5 * 16 * 1024)
-
#define MAX_VIDEOQ_SIZE (
-
#define AV_SYNC_THRESHOLD 0.01
-
#define AV_NOSYNC_THRESHOLD 10.0
-
#define FF_REFRESH_EVENT (SDL_USEREVENT)
-
#define FF_QUIT_EVENT (SDL_USEREVENT + 1)
-
typedef struct PacketQueue
-
{
-
AVPacketList * first_pkt, *last_pkt;
-
int nb_packets;
-
int size;
-
SDL_mutex *
-
SDL_cond * cond;
-
}PacketQueue;
-
static int signal_quit = 0;
-
SDL_mutex *affmutex;
-
SDL_Event sdlevent;
-
#define VIDEO_PICTURE_QUEUE_SIZE 1
-
typedef struct VideoState {
-
int videoindex;
-
int sndindex;
-
int frameFinished;
-
int wanted_freq;
-
int wanted_samples;
-
int wanted_channels;
-
int pictq_size, pictq_rindex, pictq_windex;
-
unsigned int audio_buf_size;
-
unsigned int audio_buf_index;
-
double frame_timer;
-
double frame_last_pts;
-
double now_video_pts;
-
double frame_last_delay;
-
double video_clock;
-
double audio_clock;
-
SDL_Thread* video_tid;
-
AVFormatContext* pFormatCtx;
-
AVCodecContext* vdoCodecCtx;
-
AVCodecContext* sndCodecCtx;
-
AVCodec* vdoCodec;
-
AVCodec* sndCodec;
-
AVStream* vdoStream;
-
AVStream* sndStream;
-
AVFrame* pFrameYUV;
-
AVPacket* packet;
-
struct SwsContext *img_convert_ctx;
-
struct SwrContext *swr_ctx;
-
SDL_mutex *pictq_mutex;
-
SDL_cond *pictq_cond;
-
SDL_Surface* psscreen;
-
SDL_Overlay* overlay;
-
SDL_Rect rect;
-
SDL_mutex *screen_mutex;
-
enum AVSampleFormat wanted_fmt;
-
int64_t wanted_channel_layout;
-
PacketQueue audioq;
-
PacketQueue videoq;
-
DECLARE_ALIGNED(16,uint8_t,audio_buf2) [AVCODEC_MAX_AUDIO_FRAME_SIZE * 4];
-
}VideoState;
-
static void video_refresh_timer(void* arg);
-
double synchronize_video(VideoState *is, AVFrame *src_frame, double
pts) ; //這兩個函式是新加的
-
double get_audio_clock(VideoState *is);
-
static int sdl_event_thread(void* data)
-
{
-
while((0==signal_quit))
-
{
-
SDL_LockMutex(affmutex);
-
while(SDL_PollEvent(&sdlevent))
-
{
-
switch(sdlevent.type)
-
{
-
case FF_QUIT_EVENT:
-
case SDL_QUIT:
-
{
-
signal_quit = 1;
-
SDL_Quit();
-
exit(0);
-
}
-
break;
-
case FF_REFRESH_EVENT:
-
video_refresh_timer(sdlevent.user.data1);
-
break;
-
default:
-
break;
-
}
-
}
-
SDL_UnlockMutex(affmutex);
-
}
-
return 0;
-
}
-
static void packet_queue_init(PacketQueue *q)
-
{
-
memset(q, 0, sizeof(PacketQueue));
-
q->mutex = SDL_CreateMutex();
-
q->cond = SDL_CreateCond();
-
}
-
static int packet_queue_put(PacketQueue *q, AVPacket *pkt)
-
{
-
AVPacketList *pkt1;
-
pkt1 = av_malloc(sizeof(AVPacketList));
-
if (!pkt1)
-
return -1;
-
pkt1->pkt = *pkt;
-
pkt1->next = NULL;
-
SDL_LockMutex(q->mutex);
-
if (!q->last_pkt)
-
q->first_pkt = pkt1;
-
else
-
q->last_pkt->next = pkt1;
-
q->last_pkt = pkt1;
-
q->nb_packets++;
-
q->size += pkt1->pkt.size;
-
//dbmsg("put_queue
and send singal");
-
SDL_CondSignal(q->cond);
-
SDL_UnlockMutex(q->mutex);
-
return 0;
-
}
-
static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
-
{
-
AVPacketList *pkt1;
-
int ret;
-
SDL_LockMutex(q->mutex);
-
for(;;)
-
{
-
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 {
-
SDL_CondWait(q->cond, q->mutex);
-
}
-
}
-
SDL_UnlockMutex(q->mutex);
-
return ret;
-
}
-
double get_audio_clock(VideoState *is) {
-
double pts;
-
int hw_buf_size, bytes_per_sec, n;
-
pts = is->audio_clock; /* maintained in the
audio thread */
- hw_buf_size = is-