/*
* SDL_Lesson.c
*
* Created on: Aug 12, 2014
* Author: clarck
*/
#define inline _inline
#include "sdl/SDL.h"
#include "sdl/SDL_thread.h"
#include "sdl/SDL_events.h"
//#include "../include/logger.h"
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavutil/pixfmt.h"
#include "libswscale/swscale.h"
#include "libswresample/swresample.h"
#define SDL_AUDIO_BUFFER_SIZE 1024
#define MAX_AUDIO_SIZE (5 * 16 * 1024)
#define MAX_VIDEO_SIZE (5 * 256 * 1024)
#define FF_ALLOC_EVENT (SDL_USEREVENT)
#define FF_REFRESH_EVENT (SDL_USEREVENT + 1)
#define FF_QUIT_EVENT (SDL_USEREVENT + 2)
#define VIDEO_PICTURE_QUEUE_SIZE 1
#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio
#define AV_SYNC_THRESHOLD 0.01
#define AV_NOSYNC_THRESHOLD 10.0
typedef struct PacketQueue {
AVPacketList *first_pkt, *last_pkt;
int nb_packets;
int size;
SDL_mutex *mutex;
SDL_cond *cond;
} PacketQueue;
typedef struct VideoPicture {
SDL_Window *screen;
SDL_Renderer *renderer;
SDL_Texture *bmp;
AVFrame* rawdata;
int width, height; /*source height & width*/
int allocated;
double pts;
} VideoPicture;
typedef struct VideoState {
char filename[1024];
AVFormatContext *ic;
int videoStream, audioStream;
AVStream *audio_st;
AVFrame *audio_frame;
PacketQueue audioq;
unsigned int audio_buf_size;
unsigned int audio_buf_index;
AVPacket audio_pkt;
uint8_t *audio_pkt_data;
int audio_pkt_size;
int audio_hw_buf_size;// Tian
uint8_t *audio_buf;
DECLARE_ALIGNED(16,uint8_t,audio_buf2) [AVCODEC_MAX_AUDIO_FRAME_SIZE * 4];
enum AVSampleFormat audio_src_fmt;
enum AVSampleFormat audio_tgt_fmt;
int audio_src_channels;
int audio_tgt_channels;
int64_t audio_src_channel_layout;
int64_t audio_tgt_channel_layout;
int audio_src_freq;
int audio_tgt_freq;
struct SwrContext *swr_ctx;
double audio_clock;
double frame_timer;
double frame_last_pts;
double frame_last_delay;
double video_clock;
AVStream *video_st;
PacketQueue videoq;
VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE];
int pictq_size, pictq_rindex, pictq_windex;
SDL_mutex *pictq_mutex;
SDL_cond *pictq_cond;
SDL_Thread *parse_tid;
SDL_Thread *audio_tid;
SDL_Thread *video_tid;
AVIOContext *io_ctx;
struct SwsContext *sws_ctx;
int quit;
} VideoState;
VideoState *global_video_state;
uint64_t global_video_pkt_pts = AV_NOPTS_VALUE;
void packet_queue_init(PacketQueue *q) {
memset(q, 0, sizeof(PacketQueue));
q->mutex = SDL_CreateMutex();
q->cond = SDL_CreateCond();
}
int packet_queue_put(PacketQueue *q, AVPacket *pkt) {
AVPacketList *pkt1;
pkt1 = (AVPacketList *) 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;
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 (;;) {
if (global_video_state->quit) {
ret = -1;
break;
}
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->audio_buf_size - is->audio_buf_index;
bytes_per_sec = 0;
n = is->audio_st->codec->channels * 2;
if (is->audio_st)
{
bytes_per_sec = is->audio_st->codec->sample_rate * n;
}
if (bytes_per_sec)
{
pts -= (double)hw_buf_size / bytes_per_sec;
}
return pts;
}
int audio_decode_frame(VideoState *is) {
int len1=0, len2=0, decoded_data_size;
AVPacket *pkt = &is->audio_pkt;
// double audio_clock0;
int got_frame = 0;
int64_t dec_channel_layout;
int wanted_nb_samples, resampled_data_size;
for (;;) {
while (is->audio_pkt_size > 0) {
if (!is->audio_frame) {
if (!(is->audio_frame = av_frame_alloc())) {
return AVERROR(ENOMEM);
}
} else
av_frame_unref(is->audio_frame);
// avcodec_get_frame_defaults(is->audio_frame);
/**
* 当AVPacket中装得是音频时,有可能一个AVPacket中有多个AVFrame,
* 而某些解码器只会解出第一个AVFrame,这种情况我们必须循环解码出后续AVFrame
*/
len1 = avcodec_decode_audio4(is->audio_st->codec, is->audio_frame,
&got_frame, pkt);
if (len1 < 0) {
// error, skip the frame
is->audio_pkt_size = 0;
break;
}
is->audio_pkt_data += len1;
is->audio_pkt_size -= len1;
if (!got_frame)
continue;
//执行到这里我们得到了一个AVFrame
/* 计算解码出来的桢需要的缓冲大小 */
decoded_data_size = av_samples_get_buffer_size(NULL,
is->audio_frame->channels, is->audio_frame->nb_samples,
is->audio_frame->format, 1);
dec_channel_layout =
(is->audio_frame->channel_layout
&& is->audio_frame->channels
== av_get_channel_layout_nb_channels(
is->audio_frame->channel_layout)) ?
is->audio_frame->channel_layout :
av_get_default_channel_layout(
is->audio_frame->channels);
//这个AVFrame每个声道的采样数
wanted_nb_samples = is->audio_frame->nb_samples;
/**
* 接下来判断我们之前设置SDL时设置的声音格式(AV_SAMPLE_FMT_S16),声道布局,
* 采样频率,每个AVFrame的每个声道采样数与
* 得到的该AVFrame分别是否相同,如有任意不同,我们就需要swr_convert该AvFrame,
* 然后才能符合之前设置好的SDL的需要,才能播放
*/
if (is->audio_frame->format != is->audio_src_fmt
|| dec_channel_layout != is->audio_src_channel_layout
|| is->audio_frame->sample_rate != is->audio_src_freq
|| (wanted_nb_samples != is->audio_frame->nb_samples
&& !is->swr_ctx)) {
if (is->swr_ctx)
swr_free(&is->swr_ctx);
is->swr_ctx = swr_alloc_set_opts(NULL,
is->audio_tgt_channel_layout, is->audio_tgt_fmt,
is->audio_tgt_freq, dec_channel_layout,
is->audio_frame->format, is->audio_frame->sample_rate,
0, NULL);
if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
fprintf(stderr, "swr_init() failed\n");
break;
}
is->audio_src_channel_layout = dec_channel_layout;
is->audio_src_channels = is->audio_st->codec->channels;
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
视频同步播放器(简单的) (203个子文件)
fplay_sync_and.c.bak 31KB
fplay_sync_and.c 31KB
avcodec-56.dll 20.27MB
avformat-56.dll 5.66MB
avfilter-5.dll 2.28MB
avdevice-56.dll 1.32MB
SDL2.dll 984KB
avutil-54.dll 471KB
swscale-3.dll 442KB
swresample-1.dll 274KB
postproc-53.dll 128KB
fplay_sync.exe 54KB
fplay_sync.vcxproj.filters 953B
cuc_ieschool.flv 912KB
SDL_opengl.h 622KB
avcodec.h 178KB
SDL_opengles2.h 129KB
avformat.h 102KB
avfilter.h 56KB
SDL_haptic.h 38KB
opt.h 37KB
pixfmt.h 33KB
SDL_video.h 33KB
SDL_render.h 32KB
SDL_events.h 26KB
frame.h 24KB
avio.h 22KB
SDL_audio.h 20KB
SDL_hints.h 19KB
swresample.h 19KB
SDL_surface.h 18KB
intreadwrite.h 18KB
avdevice.h 18KB
SDL_pixels.h 15KB
SDL_scancode.h 15KB
pixdesc.h 15KB
SDL_keycode.h 14KB
mem.h 14KB
common.h 14KB
old_pix_fmts.h 14KB
SDL_stdinc.h 14KB
avstring.h 13KB
SDL_test_fuzzer.h 13KB
swscale.h 12KB
SDL_assert.h 10KB
log.h 10KB
old_codec_ids.h 10KB
SDL_gamecontroller.h 10KB
samplefmt.h 10KB
SDL_thread.h 10KB
buffer.h 10KB
channel_layout.h 9KB
SDL_atomic.h 9KB
avutil.h 8KB
imgutils.h 8KB
SDL_joystick.h 8KB
vdpau.h 8KB
dict.h 8KB
bprint.h 8KB
parseutils.h 7KB
buffersink.h 7KB
SDL_mouse.h 7KB
SDL_rwops.h 7KB
SDL_syswm.h 7KB
SDL_system.h 7KB
SDL_mutex.h 7KB
version.h 6KB
SDL_keyboard.h 6KB
SDL_log.h 6KB
xvmc.h 6KB
SDL_endian.h 6KB
SDL_shape.h 6KB
SDL_config.h 5KB
error.h 5KB
vda.h 5KB
SDL.h 5KB
timecode.h 5KB
eval.h 5KB
SDL_filesystem.h 5KB
mathematics.h 5KB
SDL_version.h 5KB
fifo.h 5KB
SDL_test_common.h 5KB
buffersrc.h 5KB
cpu.h 5KB
SDL_test_md5.h 5KB
SDL_messagebox.h 5KB
audio_fifo.h 4KB
SDL_main.h 4KB
SDL_platform.h 4KB
SDL_test_harness.h 4KB
attributes.h 4KB
rational.h 4KB
begin_code.h 4KB
SDL_rect.h 4KB
version.h 4KB
SDL_cpuinfo.h 4KB
vaapi.h 4KB
dv_profile.h 4KB
stereo3d.h 4KB
共 203 条
- 1
- 2
- 3
资源评论
- xhdjlh2017-11-20测试了下,可以使用
- tommy_zhang2015-10-23测试了下,可以使用!ustb_atrx2015-11-02此工程里面的这句代码 pFormatCtx->streams[i]->codec->coder_type == AVMEDIA_TYPE_VIDEO需要把coder_type改成codec_type。不然又得格式会出问题ustb_atrx2015-11-02http://download.csdn.net/detail/ustb_atrx/9203735 这是ffmpeg tutorial。同步搞的比较好。想要学习同步的可以下载
ustb_atrx
- 粉丝: 17
- 资源: 65
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 项目1.dev
- 太阁立志传5修改器整合
- springboot024基于SpringBoot的企业客户管理系统的设计与实现.rar
- 简历-求职简历-word-文件-简历模版免费分享-应届生-高颜值简历模版-个人简历模版-简约大气-大学生在校生-求职-实习
- jpegli、JPEG XL官方版,windows运行版
- 智微系列JMF60X JMF602 JMF606-607
- springboot021校园周边美食探索及分享平台的设计与实现.rar
- 数字电子技术课程实验工具Multisim12实验报告及源码等,含JK触发器、九进制计数器、半加器电路、译码器74LS138N仿真
- Qt+QMetaObject+提取并显示Qt类本身的详细信息示例代码
- Javaweb仓库管理系统项目源码
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功