FFmpeg学习(一)-- ffmpeg 播放器的基础

2023-05-16

 

《FFmpeg学习(一)》
《FFmpeg学习(二)》
《FFmpeg学习(三)》

 

        FFmpeg的的是一套可以用来记录,转换数字音频,视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制,转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec的的,为了保证高可移植性和编解码质量,libavcodec的的里很多代码都是从头开发的。

        ffmpeg的的官网:点击打开链接

        ffmpeg的的各个版本下载地址:点击打开链接

        ffmpeg的的学习资料:

                雷博士的博客:点击打开链接

                专栏:ffmpeg实战教程

                ffmpeg 2.5.6  整理的文档

                ffmpeg 3.4.2  整理的文档

                ffmpeg 4.0整理的文档

                SDL2.0.8  整理文档

知乎上对的ffmpeg的的解读:点击打开链接

下面开始我的ffmpeg开发:VS2013 + ffmpeg-4.0 + SDL2.0.8

解决VS2013模块对于SAFESEH映像是不安全

common.h

#ifndef COMMON_H_
#define COMMON_H_

#include <windows.h>
#ifdef __cplusplus
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavutil/avutil.h"
#include "libavutil/imgutils.h"
#include "libavutil/time.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "SDL2/SDL.h"
#include "SDL2/SDL_thread.h"
}
#endif


#endif // COMMON_H_

main.cpp

#include <stdio.h>
#include "common.h"

#undef main
int main()
{
	av_register_all();//ע  
	unsigned int nVersion = avcodec_version();
	return 0;
}

 

Git的学习请看我这篇:《 Git上传代码到github上 》

 

完整工程地址:https://gitee.com/harray/MyFFmpegStudy

我的代码存放地址:https://gitee.com/harray/

testyuv分支,专门用来测试yuv的

分支地址:https://gitee.com/harray/MyFFmpegStudy/tree/testyuv

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"

#undef main
int main()
{
	//读取文件test_yuv420p_320x180.yuv
	FILE* fp_yuv = fopen("test_yuv420p_320x180.yuv", "rb");
	//写入文件frame.yuv
	FILE* fp_frame = fopen("frame_320x180_out.yuv", "wb");
	//开辟内存读取test_yuv420p_320x180.yuv文件的第一帧的亮度数据(Y)
	char* buffer_y = (char*)malloc(sizeof(char)* 320 * 180);
	char* buffer_u = (char*)malloc(sizeof(char)* 320 * 180 / 4);
	char* buffer_v = (char*)malloc(sizeof(char)* 320 * 180 / 4);

	//读取函数,将test_yuv420p_320x180.yuv的第一帧存入buff指向的内存
	for (int i = 0; i < 30; i++)
	{
		fread(buffer_y, 320 * 180, 1, fp_yuv);
		fread(buffer_u, 320 * 180 / 4, 1, fp_yuv);
		fread(buffer_v, 320 * 180 / 4, 1, fp_yuv);

		//for(int i=0;i<320*180/4;i++){
		//	buffer_u[i]=128;
		//	buffer_v[i]=128;
		//}

		memset(buffer_u, 128, 320 * 180 / 4);
		memset(buffer_v, 128, 320 * 180 / 4);

		fwrite(buffer_y, 320 * 180, 1, fp_frame);
		fwrite(buffer_u, 320 * 180 / 4, 1, fp_frame);
		fwrite(buffer_v, 320 * 180 / 4, 1, fp_frame);
	}
	//fread(buff,320*180,1,fp_yuv);
	//将buff指向的内存写入frame.yuv

	free(buffer_y);
	free(buffer_u);
	free(buffer_v);
	fclose(fp_yuv);
	fclose(fp_frame);

	return 0;
}

decoder分支地址:https://gitee.com/harray/MyFFmpegStudy/tree/decoder

#include <stdio.h>
#include "common.h"

#define __STDC_CONSTANT_MACROS

#undef main
int main()
{
	AVFormatContext	*pFormatCtx;
	int				i, videoindex;
	AVCodecContext	*pCodecCtx;
	AVCodec			*pCodec;
	AVFrame	*pFrame, *pFrameYUV;
	uint8_t *out_buffer;
	AVPacket *packet;
	int y_size;
	int ret, got_picture;
	struct SwsContext *img_convert_ctx;
	//输入文件路径
	char filepath[] = "Titanic.ts";

	int frame_cnt;

	av_register_all();
	avformat_network_init();
	pFormatCtx = avformat_alloc_context();

	if (avformat_open_input(&pFormatCtx, filepath, NULL, NULL) != 0)
	{
		printf("Couldn't open input stream.\n");
		return -1;
	}
	if (avformat_find_stream_info(pFormatCtx, NULL)<0)
	{
		printf("Couldn't find stream information.\n");
		return -1;
	}
	videoindex = -1;
	for (i = 0; i<pFormatCtx->nb_streams; i++)
	if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
	{
		videoindex = i;
		break;
	}
	if (videoindex == -1)
	{
		printf("Didn't find a video stream.\n");
		return -1;
	}

	pCodecCtx = pFormatCtx->streams[videoindex]->codec;
	pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
	if (pCodec == NULL)
	{
		printf("Codec not found.\n");
		return -1;
	}
	if (avcodec_open2(pCodecCtx, pCodec, NULL)<0)
	{
		printf("Could not open codec.\n");
		return -1;
	}
	/*
	* 在此处添加输出视频信息的代码
	* 取自于pFormatCtx,使用fprintf()
	*/
	pFrame = av_frame_alloc();
	pFrameYUV = av_frame_alloc();
	out_buffer = (uint8_t *)av_malloc(avpicture_get_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height));
	avpicture_fill((AVPicture *)pFrameYUV, out_buffer, AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
	packet = (AVPacket *)av_malloc(sizeof(AVPacket));
	//Output Info-----------------------------
	printf("--------------- File Information ----------------\n");
	av_dump_format(pFormatCtx, 0, filepath, 0);
	printf("-------------------------------------------------\n");
	img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
		pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);

	frame_cnt = 0;
	while (av_read_frame(pFormatCtx, packet) >= 0)
	{
		if (packet->stream_index == videoindex)
		{
			/*
			* 在此处添加输出H264码流的代码
			* 取自于packet,使用fwrite()
			*/
			ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
			if (ret < 0)
			{
				printf("Decode Error.\n");
				return -1;
			}
			if (got_picture){
				sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height,
					pFrameYUV->data, pFrameYUV->linesize);
				printf("Decoded frame index: %d\n", frame_cnt);

				/*
				* 在此处添加输出YUV的代码
				* 取自于pFrameYUV,使用fwrite()
				*/

				frame_cnt++;
			}
		}
		av_free_packet(packet);
	}
	sws_freeContext(img_convert_ctx);
	av_frame_free(&pFrameYUV);
	av_frame_free(&pFrame);
	avcodec_close(pCodecCtx);
	avformat_close_input(&pFormatCtx);

	return 0;
}

play_video地址:https://gitee.com/harray/MyFFmpegStudy/tree/play_video

#include <stdio.h>
#include "common.h"

const int bpp = 12;
int screen_w = 640, screen_h = 360;
const int pixel_w = 640, pixel_h = 360;
unsigned char buffer[pixel_w*pixel_h*bpp / 8];

//Refresh Event
#define REFRESH_EVENT  (SDL_USEREVENT + 1)
//Break
#define BREAK_EVENT  (SDL_USEREVENT + 2)

int thread_exit = 0;

int refresh_video(void *opaque)
{
	thread_exit = 0;
	while (thread_exit == 0) 
	{
		SDL_Event event;
		event.type = REFRESH_EVENT;
		SDL_PushEvent(&event);
		SDL_Delay(40);
	}
	thread_exit = 0;
	//Break
	SDL_Event event;
	event.type = BREAK_EVENT;
	SDL_PushEvent(&event);
	return 0;
}

#undef main
int main()
{
	if (SDL_Init(SDL_INIT_VIDEO))
	{
		printf("Could not initialize SDL - %s\n", SDL_GetError());
		return -1;
	}
	SDL_Window *screen = SDL_CreateWindow("Simplest Video Play SDL2", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
		screen_w, screen_h, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
	if (!screen) 
	{
		printf("SDL: could not create window - exiting:%s\n", SDL_GetError());
		return -1;
	}
	SDL_Renderer* sdlRenderer = SDL_CreateRenderer(screen, -1, 0);
	Uint32 pixformat = 0;
	//IYUV: Y + U + V  (3 planes)
	//YV12: Y + V + U  (3 planes)
	pixformat = SDL_PIXELFORMAT_IYUV;
	SDL_Texture* sdlTexture = SDL_CreateTexture(sdlRenderer, pixformat, SDL_TEXTUREACCESS_STREAMING, pixel_w, pixel_h);
	FILE *fp = NULL;
	fp = fopen("sintel_640_360.yuv", "rb+");
	if (fp == NULL)
	{
		printf("cannot open this file\n");
		return -1;
	}

	SDL_Rect sdlRect;
	SDL_Thread *refresh_thread = SDL_CreateThread(refresh_video, NULL, NULL);
	SDL_Event event;
	while (1)
	{
		//Wait
		SDL_WaitEvent(&event);
		if (event.type == REFRESH_EVENT){
			if (fread(buffer, 1, pixel_w*pixel_h*bpp / 8, fp) != pixel_w*pixel_h*bpp / 8)
			{
				// Loop
				fseek(fp, 0, SEEK_SET);
				fread(buffer, 1, pixel_w*pixel_h*bpp / 8, fp);
			}

			SDL_UpdateTexture(sdlTexture, NULL, buffer, pixel_w);

			//FIX: If window is resize
			sdlRect.x = 0;
			sdlRect.y = 0;
			sdlRect.w = screen_w;
			sdlRect.h = screen_h;

			SDL_RenderClear(sdlRenderer);
			SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, &sdlRect);
			SDL_RenderPresent(sdlRenderer);

		}
		else if (event.type == SDL_WINDOWEVENT)
		{
			//If Resize
			SDL_GetWindowSize(screen, &screen_w, &screen_h);
		}
		else if (event.type == SDL_QUIT)
		{
			thread_exit = 1;
		}
		else if (event.type == BREAK_EVENT)
		{
			break;
		}

	}
	SDL_Quit();
	return 0;
}

play_su版本地址:https://gitee.com/harray/MyFFmpegStudy/tree/play_su

#include <stdio.h>
#include "common.h"


//Refresh Event
#define SFM_REFRESH_EVENT  (SDL_USEREVENT + 1)

#define SFM_BREAK_EVENT  (SDL_USEREVENT + 2)

int thread_exit = 0;

int sfp_refresh_thread(void *opaque)
{
	thread_exit = 0;
	while (!thread_exit)
	{
		SDL_Event event;
		event.type = SFM_REFRESH_EVENT;
		SDL_PushEvent(&event);
		SDL_Delay(40);
	}
	thread_exit = 0;
	//Break
	SDL_Event event;
	event.type = SFM_BREAK_EVENT;
	SDL_PushEvent(&event);

	return 0;
}

#undef main
int main(int argc, char* argv[])
{

	AVFormatContext	*pFormatCtx;
	int				i, videoindex;
	AVCodecContext	*pCodecCtx;
	AVCodec			*pCodec;
	AVFrame	*pFrame, *pFrameYUV;
	uint8_t *out_buffer;
	AVPacket *packet;
	int ret, got_picture;

	//------------SDL----------------
	int screen_w, screen_h;
	SDL_Window *screen;
	SDL_Renderer* sdlRenderer;
	SDL_Texture* sdlTexture;
	SDL_Rect sdlRect;
	SDL_Thread *video_tid;
	SDL_Event event;

	struct SwsContext *img_convert_ctx;

	char filepath[] = "˿ʿ.mov";

	av_register_all();
	avformat_network_init();
	pFormatCtx = avformat_alloc_context();

	if (avformat_open_input(&pFormatCtx, filepath, NULL, NULL) != 0)
	{
		printf("Couldn't open input stream.\n");
		return -1;
	}
	if (avformat_find_stream_info(pFormatCtx, NULL) < 0)
	{
		printf("Couldn't find stream information.\n");
		return -1;
	}
	videoindex = -1;
	for (i = 0; i < pFormatCtx->nb_streams; i++)
	if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
	{
		videoindex = i;
		break;
	}
	if (videoindex == -1){
		printf("Didn't find a video stream.\n");
		return -1;
	}
	pCodecCtx = pFormatCtx->streams[videoindex]->codec;
	pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
	if (pCodec == NULL)
	{
		printf("Codec not found.\n");
		return -1;
	}
	if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
	{
		printf("Could not open codec.\n");
		return -1;
	}
	pFrame = av_frame_alloc();
	pFrameYUV = av_frame_alloc();
	out_buffer = (uint8_t *)av_malloc(avpicture_get_size(AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height));
	avpicture_fill((AVPicture *)pFrameYUV, out_buffer, AV_PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);

	img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
		pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);


	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER))
	{
		printf("Could not initialize SDL - %s\n", SDL_GetError());
		return -1;
	}
	//SDL 2.0 Support for multiple windows
	screen_w = pCodecCtx->width;
	screen_h = pCodecCtx->height;
	screen = SDL_CreateWindow("ffmpeg player", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
		screen_w, screen_h, SDL_WINDOW_OPENGL);

	if (!screen)
	{
		printf("SDL: could not create window - exiting:%s\n", SDL_GetError());
		return -1;
	}
	sdlRenderer = SDL_CreateRenderer(screen, -1, 0);
	//IYUV: Y + U + V  (3 planes)
	//YV12: Y + V + U  (3 planes)
	sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING, pCodecCtx->width, pCodecCtx->height);

	sdlRect.x = 0;
	sdlRect.y = 0;
	sdlRect.w = screen_w;
	sdlRect.h = screen_h;

	packet = (AVPacket *)av_malloc(sizeof(AVPacket));

	video_tid = SDL_CreateThread(sfp_refresh_thread, NULL, NULL);
	//------------SDL End------------
	//Event Loop

	for (;;)
	{
		//Wait
		SDL_WaitEvent(&event);
		if (event.type == SFM_REFRESH_EVENT)
		{
			//------------------------------
			if (av_read_frame(pFormatCtx, packet) >= 0)
			{
				if (packet->stream_index == videoindex)
				{
					ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
					if (ret < 0)
					{
						printf("Decode Error.\n");
						return -1;
					}
					if (got_picture)
					{
						sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);
						//SDL---------------------------
						SDL_UpdateTexture(sdlTexture, NULL, pFrameYUV->data[0], pFrameYUV->linesize[0]);
						SDL_RenderClear(sdlRenderer);
						//SDL_RenderCopy( sdlRenderer, sdlTexture, &sdlRect, &sdlRect );  
						SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, NULL);
						SDL_RenderPresent(sdlRenderer);
						//SDL End-----------------------
					}
				}
				av_free_packet(packet);
			}
			else
			{
				//Exit Thread
				thread_exit = 1;
			}
		}
		else if (event.type == SDL_QUIT)
		{
			thread_exit = 1;
		}
		else if (event.type == SFM_BREAK_EVENT)
		{
			break;
		}

	}

	sws_freeContext(img_convert_ctx);

	SDL_Quit();
	//--------------
	av_frame_free(&pFrameYUV);
	av_frame_free(&pFrame);
	avcodec_close(pCodecCtx);
	avformat_close_input(&pFormatCtx);

	return 0;
}

以上摘自雷霄骅博士的《基于 FFmpeg + SDL 的视频播放器的制作》

相关的视频下载地址:点击打开链接

密码:n4ji

从下一章开始,开始写Qt + ffmpeg的实例了

主要是用来记录与分享自己的学习的心得

欢迎大家加我的群:460952208

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FFmpeg学习(一)-- ffmpeg 播放器的基础 的相关文章

  • 我可以从带时间戳的图像创建 VFR 视频吗?

    首先 我对图像制作视频的经验几乎为零 我拥有的是一组带有 BMP 时间戳的图像 我想从中生成视频 由于时间戳的间隔不相等 我不能简单地使用从图像创建恒定帧速率视频的软件 一个可能的解决方案是在固定的时间间隔创建人造图像 但如果我无法制作 V
  • ffprobe/ffmpg 静音检测命令

    我正在研究流静音检测 它正在 ffmpeg 中执行以下命令 ffmpeg i http mystream com stream af silencedetect n 50dB d 0 5 f null 2 gt log txt 我想获得日志
  • 为视频添加水印的命令

    我尝试在一个视频上添加水印 但 FFmpeg 命令不会执行 错误代码为 3037 我运行相同的代码来修剪视频 视频已成功修剪 因此没有问题inputpath or outputpath我也有ic watermark png在资产文件夹中 我
  • ffmpeg创建RTP流

    我正在尝试使用 ffmpeg 进行编码和流式传输 libavcodec libavformat MSVC x64 with Zeranoe builds 这是我的代码 很大程度上改编自编码示例 删除了错误处理 include stdafx
  • 使用 ffmpeg 从 unix 命令批量将 wav 文件转换为 16 位

    我有一个由许多子文件夹组成的文件夹 每个子文件夹都有其他子文件夹 其中包含 wav 文件 我想像这样转换所有文件 ffmpeg i BmBmGG BmBmBmBm wav acodec pcm s16le ar 44100 BmBmGG B
  • 使用 ffmpeg 将 h.264 avi 容器转换为 mp4

    我想使用 ffmpeg 将 h 264 avi 容器转换为 mp4 容器 我发现这个有效 ffmpeg i myfile avi vcodec copy myfile mp4 ffmpeg version N 51169 gcedf276
  • Google Cloud Platform:将上传的 MP4 文件转换为 HLS 文件

    我正在构建一个平台 允许用户将一些视频文件 20 40 秒 从手机上传到服务器 所有这些上传目前都运行良好 文件通过nodejs云功能存储在谷歌存储桶中 现在我想创建一个 gcp 转码器作业 它将上传的 mp4 视频文件转换为 hls 视频
  • 从编码视频文件中提取运动向量

    我正在尝试从编码的 mp4 文件中提取运动矢量数据 在之前的帖子中我发现 一个答案http www princeton edu jiasic cos435 motion vector c http www princeton edu jia
  • 如何在Android项目中使用libffmpeg.so?

    我正在尝试在 Android 中创建一个屏幕录制应用程序 为此 我使用 FFmpeg 我已经创建了 libffmpeg so 文件 现在我想在 Android 项目中使用相同的方法来调用它的本机函数 我怎样才能做到这一点 本教程提供了有关此
  • 如何使用android ndk r9b为Android编译FFMPEG

    我想设计一个Android应用程序 可以通过FFMPEG命令播放和编辑视频 但我不知道如何在Android上使用FFMPEG 我尝试过从Google搜索到的许多方法 但它们太旧了 无法实现 现在 FFMPEG的最新版本是2 1 1 Andr
  • Python 用静态图像将 mp3 转换为 mp4

    我有x文件包含一个列表mp3我想转换的文件mp3文件至mp4文件带有static png photo 似乎这里唯一的方法是使用ffmpeg但我不知道如何实现它 我编写了脚本来接受输入mp3文件夹和一个 png photo 然后它将创建新文件
  • Python 子进程(ffmpeg)仅在我按 Ctrl-C 程序时启动?

    我正在尝试使用 Cygwin 和 Python 2 7 并行运行一些 ffmpeg 命令 这大概是我所拥有的 import subprocess processes set commands ffmpeg i input mp4 outpu
  • 如何使用 ffmpeg 将两个视频/音频流混合为一个

    我有两个视频 v1 flv 和 v2 flv 想要创建 v3 flv 其中包含来自 v1 flv 的视频流以及来自 v1 flv 和 v2 flv 的 混合 音频流 使用 ffmpeg 命令可以实现类似的操作吗 谢谢 我认为使用 ffmpe
  • OpenCV VideoWriter 未写入 Output.avi

    我正在尝试编写一段简单的代码来获取视频 裁剪视频并写入输出文件 系统设置 OS Windows 10 Conda Environment Python Version 3 7 OpenCV Version 3 4 2 ffmpeg Vers
  • Bash 脚本:自动为 mpeg-dash 进行 ffmpeg 编码

    我正在编写一个 bash 文件来创建视频编码和串联 以供 dash 实时流媒体使用 基本上 它读取输入视频文件夹 将所有视频编码为三种分辨率格式 然后将它们连接起来创建三个适应集 DIAGRAM 该脚本检查 fps 一致性 如果输入不是 1
  • Ffmpeg 无法正确转换为 ogg [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我正在使用 ffmpeg 在我的网站上转换音频和视频 Ffmpeg 可以正确转换为其他格式 如 mp3 mp4 等 但无法正确转换为 ogg 虽然 f
  • Chromium 中的 MP4 编解码器支持

    我们已将 Chromium 嵌入式框架集成到我们的 Windows 游戏中 以允许我们从应用程序内渲染网页 并且一切正常 除了 MP4 视频 据我所知 由于许可问题 Chromium 不包含此编解码器 但任何人都可以提供有关我们如何添加支持
  • Node.js - 将数据缓冲到 Ffmpeg

    我使用 Node js 和 Ffmpeg 来创建动画 因为我试图避免第三方 avi mp4 解析器 所以我决定将动画输出为原始 rgb24 数据文件 然后使用一些程序将其转换为 mp4 文件 我发现 Ffmpeg 是免费且开源的 它完全可以
  • 如何使用 ffmpeg 设置默认流

    我有一些 m4v 文件 我想用 ffmpeg 添加字幕 我知道我需要映射流以将它们放入输出文件中 但如何确保此字幕流将是默认流 字幕是 srt 人们似乎说它们与 mp4 容器不兼容 我需要先将字幕转换为什么 另外 各种流的顺序重要吗 视频流
  • 如何在 RTMP 流中嵌入 pic_timing SEI 挂钟时间码?

    我需要将我的桌面流式传输到 AWS MediaLive 服务 并且根据要求 我必须在流中包含挂钟时间码 AWS 支持人员善意地通知我 对于 h 264 编码流 我需要提供时间码作为 pic timing SEI 消息 我在 Windows

随机推荐

  • Flutter状态管理之Riverpod 2.0

    两年前分享过一篇Flutter状态管理之Riverpod xff0c 当时riverpod的版本还是0 8 0 xff08 后来文章更新到0 14版本 xff09 当时提到过有一些不足之处 xff1a 毕竟诞生不久 xff0c 它还不能保证
  • Python:元组和字典简述

    目录 1 列表的方法2 for循环遍历列表2 1 语法2 2 range 函数 3 元组3 1 元组的基本概念3 2 元组的创建3 3 元组的解包3 3 1 号在解包中的用法 4 字典4 1 字典的基本概念4 2 字典的使用4 2 1 字典
  • 七种常见软件开发模型

    目录 瀑布模型 xff08 面向文档的软件开发模型 xff09 演化模型 螺旋模型 增量模型 构件组装模型 统一过程 xff08 up xff09 xff08 迭代的软件过程 xff0c 以架构为中心 xff09 敏捷开发模型 瀑布模型 x
  • IP安全策略:只允许指定IP连接远程桌面,限制IP登录

    一 xff0c 新建IP安全策略 WIN 43 R打开运行对话框 xff0c 输入gpedit msc进入组策略编辑器 依次打开 本地计算机 策略 计算机配置 Windows设置 安全设置 IP安全策略 在 本地计算机上 在右面的空白处右击
  • 2022年终总结

    不知不觉就到了年末 xff0c 感叹时间过的真快 我自己坚持写了七年多的博客 xff0c 但这其实是我第一次去写年终总结 也不知道怎么写 xff0c 就简单聊聊 写博客的初衷就是个人收获 xff0c 学习的记录 xff0c 分享出来如果能帮
  • Rust库交叉编译以及在Android与iOS中使用

    本篇是关于交叉编译Rust库 xff0c 生成Android和iOS的二进制文件 xff08 so与a文件 xff09 xff0c 以及简单的集成使用 1 环境 系统 xff1a macOS 13 0 M1 Pro xff0c Window
  • 利用Rust与Flutter开发一款小工具

    1 起因 起因是年前看到了一篇Rust 43 iOS amp Android xff5c 未入门也能用来造轮子 xff1f 的文章 xff0c 作者使用Rust做了个实时查看埋点的工具 其中作者的一段话给了我启发 xff1a 无论是 Loo
  • 在Android与iOS中使用LLDB调试Rust程序

    在Rust中通过println 打印的日志信息在Xcode中可以显示 xff0c 但是Android Studio里不显示 所以Android可以使用android logger实现日志输出 但是开发中仅使用打印日志的方式进行调试还是不够的
  • 使用jni-rs实现Rust与Android代码互相调用

    本篇主要是介绍如何使用jni rs 有关jni rs内容基于版本0 20 0 xff0c 新版本写法有所不同 入门用法 在Rust库交叉编译以及在Android与iOS中使用中我简单说明了jni rs及demo代码 xff0c 现在接着补充
  • Android 13 变更及适配攻略

    准备工作 首先将我们项目中的 targetSdkVersion和compileSdkVersion 升至 33 影响Android 13上所有应用 1 通知受限 对新安装的应用的影响 xff1a 如果用户在搭载 Android 13 或更高
  • 洛谷 P1185 绘制二叉树

    一道极为恐怖的模拟题 xff0c 以定义函数的方式确定每个点的x xff0c y就能轻松的做出这道题 xff0c 参考神犇题解 洛谷 P1185 KH 39 s blog 洛谷博客 遇到这种题估计就是放弃了 AC代码 xff08 抄的 xf
  • 洛谷 P3366 【模板】最小生成树#Kruskal+并查集

    说了最小生成树 xff0c 那么就用经典的Prim或者Kruskal xff0c 不过Prim实现代码有点多 xff0c 这里用Kruskal举例 注意事项 1 Kruskal是用来找最小生成树的 根据树的定义可以知道 树是无向图 所以Kr
  • STM32MP157AAA3裸机点灯(汇编)

    STM32MP157AAA3裸机点灯 汇编 MP157的A7核裸机点灯 使用的开发板为华清远见的MP157开发板 xff0c 默认板内emmc已经烧写好了uboot 这篇就只记录一下汇编点灯过程 xff0c uboot等内容暂不涉及 xff
  • 用tkinter写出you-get下载器界面,并用pyinstaller打包成exe文件

    写在前面 xff1a 本文为笔者最早于 2019 05 11 23 15 以 64 拼命三郎 的身份发表于博客园 本文为原创文章 xff0c 转载请标明出处 一 you get介绍 you get是一个基于 python3 的下载工具 xf
  • Linux网络协议栈4--bridge收发包

    bridge 是linux上的虚拟交换机 xff0c 具有交换机的功能 网卡收到包后 xff0c 走到 netif receive skb core后 xff0c 剥完vlan找到vlan子接口 xff08 如果有的话 xff09 xff0
  • linux redis启动时报错WARNING overcommit_memory is set to 0! Background save may fail under low memory con

    报错 xff1a WARNING overcommit memory is set to 0 Background save may fail under low memory condition To fix this issue add
  • STM32编程语言介绍

    STM32入门100步 第8期 编程语言介绍 杜洋 洋桃电子 上一期我们在电脑上安装好了KEIL软件 xff0c 也新建了工程 xff0c 在工程中安装了固件库 准备工作完成后 xff0c 接着就是在工程中编写程序了 只有程序使ARM内核有
  • VMware虚拟机安装Linux教程(超详细)

    写给读者 为了帮助Linux系统初学者学习的小伙伴更好的学习 xff0c VMware虚拟机是不可避免的 xff0c 因此下载 安装VMware和完成Linux的系统安装是非常必要的 接下来 xff0c 我们就来系统的学习一下VMware虚
  • Markdown中的LaTeX公式——希腊字母详解

    若要在Markdown中使用 xff0c 则在两个美元符号之间敲入对应LaTeX代码实现公式行显示效果 xff0c 若为公式块 xff0c 则要在四个美元符号中间敲入 xff0c 类似Markdown代码行和代码块 共24个希腊字母 xff
  • FFmpeg学习(一)-- ffmpeg 播放器的基础

    FFmpeg学习 xff08 一 xff09 FFmpeg学习 xff08 二 xff09 FFmpeg学习 xff08 三 xff09 FFmpeg的的是一套可以用来记录 xff0c 转换数字音频 xff0c 视频 xff0c 并能将其转