/**
* 叶海辉
* QQ群121376426
* http://blog.yundiantech.com/
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <QDebug>
extern"C"
{
#include "libavutil/mathematics.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "SDL.h"
#include "SDL_thread.h"
#include "SDL_events.h"
}
#define WIDTH 176
#define HEIGHT 144
#define PCM_FILE_NAME "in.pcm"
#define YUV_FILE_NAME "in.yuv"
#define OUT_VIDEO_FILENAME "out.mp4"
uint8_t picture_buf[WIDTH*HEIGHT*4];
bool isStop = false;
static float t, tincr, tincr2;
static int16_t *samples;
static uint8_t *audio_outbuf;
static int audio_outbuf_size;
int audio_input_frame_size;
#define STREAM_DURATION 200.0 //视频总长度单位秒
#define STREAM_FRAME_RATE 25 /* 25 images/s */
#define STREAM_NB_FRAMES ((int)(STREAM_DURATION * STREAM_FRAME_RATE))
#define STREAM_PIX_FMT PIX_FMT_YUV420P /* default pix_fmt */
/**************************************************************/
/* audio output */
struct BufferDataNode
{
uint8_t * buffer;
int bufferSize;
BufferDataNode * next;
};
SDL_mutex *videoMutex = SDL_CreateMutex();
BufferDataNode * videoDataQueneHead = NULL;
BufferDataNode * videoDataQueneTail = NULL;
SDL_mutex *audioMutex = SDL_CreateMutex();
BufferDataNode * AudioDataQueneHead = NULL;
BufferDataNode * AudioDataQueneTail = NULL;
void videoDataQuene_Input(uint8_t * buffer,int size)
{
BufferDataNode * node = (BufferDataNode*)malloc(sizeof(BufferDataNode));
node->buffer = (uint8_t *)malloc(size);
node->bufferSize = size;
node->next = NULL;
memcpy(node->buffer,buffer,size);
SDL_LockMutex(videoMutex);
if (videoDataQueneHead == NULL)
{
videoDataQueneHead = node;
}
else
{
videoDataQueneTail->next = node;
}
videoDataQueneTail = node;
SDL_UnlockMutex(videoMutex);
}
static BufferDataNode *videoDataQuene_get()
{
BufferDataNode * node = NULL;
SDL_LockMutex(videoMutex);
if (videoDataQueneHead != NULL)
{
node = videoDataQueneHead;
if (videoDataQueneTail == videoDataQueneHead)
{
videoDataQueneTail = NULL;
}
videoDataQueneHead = videoDataQueneHead->next;
}
SDL_UnlockMutex(videoMutex);
return node;
}
void audioDataQuene_Input(uint8_t * buffer,int size)
{
BufferDataNode * node = (BufferDataNode*)malloc(sizeof(BufferDataNode));
node->buffer = (uint8_t *)malloc(size);
node->bufferSize = size;
node->next = NULL;
memcpy(node->buffer,buffer,size);
SDL_LockMutex(audioMutex);
if (AudioDataQueneHead == NULL)
{
AudioDataQueneHead = node;
}
else
{
AudioDataQueneTail->next = node;
}
AudioDataQueneTail = node;
SDL_UnlockMutex(audioMutex);
}
static BufferDataNode *audioDataQuene_get()
{
BufferDataNode * node = NULL;
SDL_LockMutex(audioMutex);
if (AudioDataQueneHead != NULL)
{
node = AudioDataQueneHead;
if (AudioDataQueneTail == AudioDataQueneHead)
{
AudioDataQueneTail = NULL;
}
AudioDataQueneHead = AudioDataQueneHead->next;
}
SDL_UnlockMutex(audioMutex);
return node;
}
/*
* add an audio output stream
*/
static AVStream *add_audio_stream(AVFormatContext *oc, AVCodecID codec_id)
{
AVCodecContext *c;
AVStream *st;
st = avformat_new_stream(oc, NULL);
if (!st) {
fprintf(stderr, "Could not alloc stream\n");
exit(1);
}
st->id = 1;
c = st->codec;
c->codec_id = codec_id;
c->codec_type = AVMEDIA_TYPE_AUDIO;
/* put sample parameters */
c->sample_fmt = AV_SAMPLE_FMT_S16;
c->bit_rate = 44100;
c->sample_rate = 44100;
c->channels = 2;
// some formats want stream headers to be separate
if (oc->oformat->flags & AVFMT_GLOBALHEADER)
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
return st;
}
static void open_audio(AVFormatContext *oc, AVStream *st)
{
AVCodecContext *c;
AVCodec *codec;
c = st->codec;
/* find the audio encoder */
codec = avcodec_find_encoder(c->codec_id);
if (!codec) {
fprintf(stderr, "codec not found\n");
exit(1);
}
/* open it */
if (avcodec_open2(c, codec,NULL) < 0) {
fprintf(stderr, "could not open codec\n");
exit(1);
}
/* init signal generator */
t = 0;
tincr = 2 * M_PI * 110.0 / c->sample_rate;
/* increment frequency by 110 Hz per second */
tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;
audio_outbuf_size = 10000;
audio_outbuf = (uint8_t *)av_malloc(audio_outbuf_size);
if (c->frame_size <= 1) {
audio_input_frame_size = audio_outbuf_size / c->channels;
switch(st->codec->codec_id) {
case CODEC_ID_PCM_S16LE:
case CODEC_ID_PCM_S16BE:
case CODEC_ID_PCM_U16LE:
case CODEC_ID_PCM_U16BE:
audio_input_frame_size >>= 1;
break;
default:
break;
}
} else {
audio_input_frame_size = c->frame_size;
}
samples = (int16_t *)av_malloc(audio_input_frame_size * 2 * c->channels);
}
static void write_audio_frame(AVFormatContext *oc, AVStream *st)
{
AVCodecContext *c;
AVPacket pkt;
av_init_packet(&pkt);
c = st->codec;
BufferDataNode *node = audioDataQuene_get();
if (node == NULL)
{
SDL_Delay(1); //延时1ms
return;
}
else
{
memcpy(samples,node->buffer, node->bufferSize);
free(node->buffer);
free(node);
}
// fread(samples, 1, audio_input_frame_size*4, pcmInFp);
pkt.size = avcodec_encode_audio(c, audio_outbuf, audio_outbuf_size, samples);
if (c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE)
pkt.pts= av_rescale_q(c->coded_frame->pts, c->time_base, st->time_base);
pkt.flags |= AV_PKT_FLAG_KEY;
pkt.stream_index = st->index;
pkt.data = audio_outbuf;
/* write the compressed frame in the media file */
if (av_interleaved_write_frame(oc, &pkt) != 0) {
fprintf(stderr, "Error while writing audio frame\n");
exit(1);
}
}
static void close_audio(AVFormatContext *oc, AVStream *st)
{
avcodec_close(st->codec);
av_free(samples);
av_free(audio_outbuf);
}
/**************************************************************/
/* video output */
static AVFrame *picture, *tmp_picture;
static uint8_t *video_outbuf;
static int video_outbuf_size;
/* add a video output stream */
static AVStream *add_video_stream(AVFormatContext *oc, AVCodecID codec_id)
{
AVCodecContext *c;
AVStream *st;
AVCodec *codec;
st = avformat_new_stream(oc, NULL);
if (!st) {
fprintf(stderr, "Could not alloc stream\n");
exit(1);
}
c = st->codec;
/* find the video encoder */
codec = avcodec_find_encoder(codec_id);
if (!codec) {
fprintf(stderr, "codec not found\n");
exit(1);
}
avcodec_get_context_defaults3(c, codec);
c->codec_id = codec_id;
/* put sample parameters */
c->bit_rate = 400000;
/* resolution must be a multiple of two */
c->width = WIDTH;
c->height = HEIGHT;
/* time base: this is the fundamental unit of time (in seconds) in terms
of which frame timestamps are represented. for fixed-fps content,
timebase should be 1/framerate and timestamp increments should be
identically 1. */
c->time_base.den = STREAM_FRAME_RATE;
c->time_base.num = 1;
c->gop_size = 12; /* emit one intra frame every twelve frames at mos
没有合适的资源?快使用搜索试试~ 我知道了~
从零开始学习音视频编程技术(十九) 录屏软件开发之YUV AAC合成MP4
共275个文件
h:219个
lib:14个
dll:12个
4星 · 超过85%的资源 需积分: 17 121 下载量 38 浏览量
2017-04-26
15:04:35
上传
评论
收藏 23.74MB RAR 举报
温馨提示
从零开始学习音视频编程技术(十九) 录屏软件开发之YUV AAC合成MP4 这是Qt的工程,建议使用Qt Creator 打开 Qt的版本是4.8.4,当然是用Qt5也是没有影响的,不过编译器记得使用Mingw。 FFMPEG的版本是2.5.2 记得将ffmpeg/bin目录下的dll文件拷贝到编译生成的exe所在的目录下,否则会无法运行。 关于代码的解释 请参考: http://blog.yundiantech.com/?log=blog&id=26 Qt开发环境的搭建 请参考: http://blog.yundiantech.com/?log=blog&id=6 Qt中引用FFMPEG库文件 请参考: http://blog.yundiantech.com/?log=blog&id=7 学习音视频技术欢迎访问 http://blog.yundiantech.com 音视频技术交流讨论欢迎加 QQ群 121376426
资源推荐
资源详情
资源评论
收起资源包目录
从零开始学习音视频编程技术(十九) 录屏软件开发之YUV AAC合成MP4 (275个子文件)
libSDL2.a 5.52MB
libSDL2_test.a 502KB
libSDL2.dll.a 336KB
libavutil.dll.a 275KB
libavcodec.dll.a 142KB
libavformat.dll.a 103KB
libavfilter.dll.a 54KB
libswscale.dll.a 23KB
libswresample.dll.a 14KB
libavdevice.dll.a 11KB
libSDL2main.a 8KB
libpostproc.dll.a 7KB
main.cpp 18KB
avutil-54.def 10KB
avcodec-56.def 6KB
avformat-56.def 4KB
avfilter-5.def 2KB
swscale-3.def 781B
avdevice-56.def 491B
swresample-1.def 433B
postproc-53.def 233B
avcodec-56.dll 18.74MB
avformat-56.dll 5.57MB
avfilter-5.dll 2.21MB
avdevice-56.dll 1.3MB
SDL2.dll 1.13MB
SDL2.dll 984KB
SDL2.dll 982KB
SDL2.dll 982KB
avutil-54.dll 442KB
swscale-3.dll 437KB
swresample-1.dll 264KB
postproc-53.dll 119KB
ffmpeg.exe 317KB
SDL_opengl.h 622KB
SDL_opengl.h 622KB
avcodec.h 176KB
SDL_opengles2.h 129KB
SDL_opengles2.h 129KB
avformat.h 100KB
avfilter.h 56KB
SDL_haptic.h 38KB
SDL_haptic.h 38KB
opt.h 37KB
SDL_video.h 33KB
SDL_video.h 33KB
SDL_render.h 32KB
SDL_render.h 32KB
pixfmt.h 32KB
SDL_events.h 26KB
SDL_events.h 26KB
frame.h 23KB
SDL_audio.h 20KB
SDL_audio.h 20KB
SDL_hints.h 19KB
swresample.h 19KB
avio.h 18KB
SDL_surface.h 18KB
SDL_surface.h 18KB
intreadwrite.h 18KB
avdevice.h 16KB
SDL_hints.h 16KB
SDL_pixels.h 15KB
SDL_pixels.h 15KB
SDL_scancode.h 15KB
SDL_scancode.h 15KB
SDL_keycode.h 14KB
SDL_keycode.h 14KB
mem.h 14KB
old_pix_fmts.h 14KB
pixdesc.h 14KB
SDL_stdinc.h 14KB
common.h 14KB
SDL_stdinc.h 14KB
SDL_test_fuzzer.h 13KB
SDL_test_fuzzer.h 13KB
avstring.h 13KB
swscale.h 12KB
SDL_assert.h 10KB
SDL_assert.h 10KB
old_codec_ids.h 10KB
SDL_gamecontroller.h 10KB
SDL_gamecontroller.h 10KB
log.h 10KB
samplefmt.h 10KB
SDL_thread.h 10KB
SDL_thread.h 10KB
buffer.h 10KB
channel_layout.h 9KB
SDL_atomic.h 9KB
SDL_atomic.h 9KB
avutil.h 8KB
imgutils.h 8KB
SDL_joystick.h 8KB
SDL_joystick.h 8KB
dict.h 8KB
bprint.h 8KB
buffersink.h 7KB
SDL_mouse.h 7KB
SDL_mouse.h 7KB
共 275 条
- 1
- 2
- 3
资源评论
- luwell19902020-05-27可以用作学习
- w_howell2018-10-08有点用处,可以研究下。
雲天之巔
- 粉丝: 659
- 资源: 46
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功