ffmpeg4教程工具方法
阿新 • • 發佈:2018-12-20
//win32顯示 static void Show(HWND hwnd, unsigned char* rgb, int w, int h, bool fill) { HDC hdc = GetDC(hwnd);//獲取當前的顯示裝置上下文 RECT rect; GetClientRect(hwnd, &rect); int cxClient = rect.right; int cyClient = rect.bottom; if (cxClient <= 0 || cyClient <= 0) { return; } HDC hdcsource = CreateCompatibleDC(NULL);//建立存放圖象的顯示緩衝 HBITMAP bitmap = CreateCompatibleBitmap(hdc, cxClient, cyClient); SelectObject(hdcsource, bitmap); //將點陣圖資源裝入顯示緩衝 SetStretchBltMode(hdcsource, COLORONCOLOR); BITMAPINFO bmi; bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = w; bmi.bmiHeader.biHeight = -h; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biBitCount = 24; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biClrUsed = 0; bmi.bmiHeader.biClrImportant = 0; bmi.bmiHeader.biSizeImage = 0; if (!fill) { int des_x = 0; int des_y = 0; int des_w = 0; int des_h = 0; if (1.0*cxClient / cyClient > 1.0*w / h) { des_h = cyClient; des_w = des_h * w / h; des_x = (cxClient - des_w) / 2; des_y = 0; } else { des_w = cxClient; des_h = des_w * h / w; des_x = 0; des_y = (cyClient - des_h) / 2; } BitBlt(hdcsource, 0, 0, cxClient, cyClient, hdcsource, 0, 0, SRCCOPY); StretchDIBits(hdcsource, des_x, des_y, des_w, des_h, \ 0, 0, w, h, rgb, &bmi, DIB_RGB_COLORS, SRCCOPY); BitBlt(hdc, 0, 0, cxClient, cyClient, hdcsource, 0, 0, SRCCOPY); } else { StretchDIBits(hdcsource, 0, 0, rect.right - rect.left, rect.bottom - rect.top, \ 0, 0, w, h, rgb, &bmi, DIB_RGB_COLORS, SRCCOPY); BitBlt(hdc, 0, 0, cxClient, cyClient, hdcsource, 0, 0, SRCCOPY);//將圖象顯示緩衝的內容直接顯示到螢幕 } DeleteObject(bitmap); DeleteDC(hdcsource); ReleaseDC(hwnd, hdc); }
static LRESULT CALLBACK WinProc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam) { switch (umsg) { case WM_KEYDOWN: { if (wparam == VK_SPACE) { } } break; case WM_LBUTTONDOWN: { } break; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, umsg, wparam, lparam); }
static char *dup_wchar_to_utf8(wchar_t *w) { char *s = NULL; int l = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0); s = (char *)av_malloc(l); if (s) WideCharToMultiByte(CP_UTF8, 0, w, -1, s, l, 0, 0); return s; }
//
static int write_frame(AVFormatContext *fmt_ctx, const AVRational *time_base, AVStream *st, AVPacket *pkt)
{
/* rescale output packet timestamp values from codec to stream timebase */
av_packet_rescale_ts(pkt, *time_base, st->time_base);
pkt->stream_index = st->index;
/* Write the compressed frame to the media file. */
av_interleaved_write_frame(fmt_ctx, NULL);
//log_packet(fmt_ctx, pkt);
return av_interleaved_write_frame(fmt_ctx, pkt);
}
聲音avframe建立
static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt, uint64_t channel_layout, int chnls, int sample_rate, int nb_samples)
{
AVFrame *frame = av_frame_alloc();
int ret;
if (!frame) {
fprintf(stderr, "Error allocating an audio frame\n");
return NULL;
}
frame->format = sample_fmt;
frame->channel_layout = channel_layout;
frame->channels = chnls;
frame->sample_rate = sample_rate;
frame->nb_samples = nb_samples;
if (nb_samples) {
ret = av_frame_get_buffer(frame, 1);
if (ret < 0) {
fprintf(stderr, "Error allocating an audio buffer\n");
return NULL;
}
}
return frame;
}
//圖片avframe建立
static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height)
{
AVFrame *picture;
int ret;
picture = av_frame_alloc();
if (!picture)
return NULL;
picture->format = pix_fmt;
picture->width = width;
picture->height = height;
/* allocate the buffers for the frame data */
ret = av_frame_get_buffer(picture, 4);
if (ret < 0) {
fprintf(stderr, "Could not allocate frame data.\n");
return NULL;
}
return picture;
}
//連結串列佇列
static int initFrameList(FrameList **pFrameList, int max) {
int ret = 0;
FrameList* p = NULL;
*pFrameList = (FrameList*)av_mallocz(sizeof(FrameList));
p = *pFrameList;
if (p == NULL) return -1;
ret = pthread_mutex_init(&p->mutex, NULL);
if (ret != 0) {
av_freep(p);
return -1;
}
ret = pthread_cond_init(&p->cond, NULL);
if (ret != 0) {
av_freep(&p);
return -1;
}
ret = pthread_cond_init(&p->wait, NULL);
if (ret != 0) {
av_freep(&p);
return -1;
}
p->max = max;
return 0;
}
static int pushFrame(FrameList *p, AVFrame *avframe, int64_t pts) {
int ret = 0;
Frame *frm = NULL;
if (p == NULL || p->exit) { return 0; }
pthread_mutex_lock(&p->mutex);
while (!p->exit && p->frmSize > p->max) {
pthread_cond_wait(&p->wait, &p->mutex);
}
if (p->exit) {
pthread_mutex_unlock(&p->mutex);
return 0;
}
frm = (Frame*)av_mallocz(sizeof(Frame));
if (frm) {
frm->pts = pts;
frm->avframe = alloc_picture((AVPixelFormat)avframe->format, avframe->width, avframe->height);
av_frame_copy(frm->avframe, avframe);
if (p->end == NULL) {
p->frame = frm;
}
else {
p->end->next = frm;
}
p->end = frm;
p->frmSize++;
ret = 1;
pthread_cond_signal(&p->cond);
}
pthread_mutex_unlock(&p->mutex);
return ret;
}
static int64_t popFrame(FrameList *p, AVFrame **avframe) {
int64_t ret = 0;
if (p == NULL || p->exit) return 0;
pthread_mutex_lock(&p->mutex);
while (!p->exit && p->frmSize < 1) {
pthread_cond_wait(&p->cond, &p->mutex);
}
if (p->exit) {
pthread_mutex_unlock(&p->mutex);
return -1;
}
if (p->frame == p->end) {
ret = p->frame->pts;
*avframe = alloc_picture((AVPixelFormat)p->frame->avframe->format, p->frame->avframe->width, p->frame->avframe->height);
av_frame_copy(*avframe, p->frame->avframe);
av_frame_free(&p->frame->avframe);
av_freep(&p->frame);
p->frame = NULL;
p->end = NULL;
}
else {
Frame *temp = p->frame;
p->frame = temp->next;
ret = temp->pts;
if (temp->avframe != NULL) {
*avframe = alloc_picture((AVPixelFormat)temp->avframe->format, temp->avframe->width, temp->avframe->height);
av_frame_copy(*avframe, temp->avframe);
av_frame_free(&temp->avframe);
}
av_freep(&temp);
}
p->frmSize--;
pthread_cond_signal(&p->wait);
pthread_mutex_unlock(&p->mutex);
return ret;
}
static void destoryFrameList(FrameList *pFrameList) {
if (pFrameList == NULL) return;
{
Frame *frm = NULL;
FrameList *p = pFrameList;
pthread_mutex_lock(&p->mutex);
p->exit = 1;
frm = p->frame;
while (frm) {
Frame *temp = frm->next;
if (temp != NULL) {
av_frame_unref(temp->avframe);
}
frm = temp;
}
pthread_mutex_unlock(&p->mutex);
}
}
static void clearFrameList(FrameList *pFrameList) {
if (pFrameList == NULL) return;
{
Frame *frm = NULL;
FrameList *p = pFrameList;
if (p->frmSize < 1) {
return;
}
pthread_mutex_lock(&p->mutex);
frm = p->frame;
while (frm) {
Frame *temp = frm->next;
if (temp != NULL) {
av_frame_free(&temp->avframe);
}
frm = temp;
}
p->frmSize = 0;
pthread_mutex_unlock(&p->mutex);
}
}