- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #define DEBUG_INFO
-
- typedef struct FileHeader {
- unsigned char type[4];
- unsigned char versions;
- unsigned char stream_info;
- unsigned int length;
- }_FileHeader;
-
- typedef struct TagHeader {
- unsigned char type;
- unsigned int data_size;
- unsigned int timestemp;
- unsigned char time_stamp_extended;
- unsigned int stream_id;
- }_TagHeader;
-
- typedef struct Tag {
- _TagHeader *header;
- unsigned char *data;
- }_Tag;
-
- _Tag *malloc_tag()
- {
- _Tag *tag = malloc(sizeof(_Tag));
- if (tag == NULL) {
- fprintf(stderr, "malloc tag error\n");
- perror("malloc error:");
- return NULL;
- }
-
- tag->header = NULL;
- tag->data = NULL;
-
- return tag;
- }
-
- void free_tag(_Tag **tag)
- {
- if(tag != NULL){
- if(*tag == NULL){
- return;
- }
-
- if ((*tag)->header != NULL) {
- free((*tag)->header);
- (*tag)->header = NULL;
- }
-
- if ((*tag)->data != NULL) {
- free((*tag)->data);
- (*tag)->data = NULL;
- }
-
- *tag = NULL;
- }
- }
-
- int reverse_32(unsigned int a)
- {
- union {
- int i;
- char c[4];
- } u, r;
-
- u.i = a;
- r.c[0] = u.c[3];
- r.c[1] = u.c[2];
- r.c[2] = u.c[1];
- r.c[3] = u.c[0];
-
- return r.i;
- }
-
- int reverse_24(unsigned int a)
- {
- union {
- int i;
- char c[4];
- } u, r;
-
- u.i = a;
- r.c[0] = u.c[2];
- r.c[1] = u.c[1];
- r.c[2] = u.c[0];
- r.c[3] = 0;
-
- return r.i;
- }
-
- int read_file_header(FILE *pf, _FileHeader **p_header)
- {
- int ret = 0;
-
- _FileHeader *header = malloc(sizeof(_FileHeader));
- if (header == NULL) {
- fprintf(stderr, "malloc file header error\n");
- perror("malloc error:");
- return -1;
- }
- memset(header, 0, sizeof(_FileHeader));
-
-
- if ((ret = fread(header->type, 3, 1, pf)) <= 0) {
- goto __err_exit;
- }
-
-
- if ((ret = fread(&(header->versions), 1, 1, pf)) <= 0) {
- goto __err_exit;
- }
-
-
- if ((ret = fread(&(header->stream_info), 1, 1, pf)) <= 0) {
- goto __err_exit;
- }
-
-
- if((ret = fread(&(header->length), 4, 1, pf)) <= 0){
- goto __err_exit;
- }
- header->length = reverse_32(header->length);
- *p_header = header;
-
- #ifdef DEBUG_INFO
- printf("=========== file header=============\n");
- printf("type : %s\n", header->type);
- printf("versions : %u\n", header->versions);
- printf("stream_info : %u\n", header->stream_info);
- printf("length : %d\n", header->length);
- printf("====================================\n");
- #endif
-
- return 1;
- __err_exit:
- free(header);
- fprintf(stderr, "read file header error\n");
- perror("fread error:");
-
- return ret;
- }
-
- int check_file_header(_FileHeader *header)
- {
-
- if ((header->type[0] != 0x46
- fprintf(stderr, "check file header type error\n");
- return -1;
- }
-
-
-
-
- if (header->stream_info & 0x04) {
- printf("have audio tag\n");
- }
-
-
- if (header->stream_info & 0x01) {
- printf("have video tag\n");
- }
-
- return 1;
- }
-
- int read_last_tag_size(FILE *pf, unsigned int *p_last_tag_size)
- {
- int ret = 0;
- unsigned int last_tag_size = 0;
-
- if ((ret = fread(&last_tag_size, 4, 1, pf)) <= 0) {
- fprintf(stderr, "read last tag size error\n");
- perror("fread error:");
- return ret;
- }
- *p_last_tag_size = reverse_32(last_tag_size);
-
- #ifdef DEBUG_INFO
- printf("---last tag size %x\n", *p_last_tag_size);
- #endif
-
- return 1;
- }
-
- int read_tag_header(FILE *pf, _TagHeader **p_header)
- {
- int ret = 0;
- _TagHeader *header = NULL;
-
- header = malloc(sizeof(_TagHeader));
- if (header == NULL) {
- fprintf(stderr, "malloc tag header error\n");
- perror("malloc error:");
- return -1;
- }
-
-
- if ((ret = fread(&(header->type), 1, 1, pf)) <= 0) {
- goto __err_exit;
- }
-
-
- if ((ret = fread(&(header->data_size), 3, 1, pf)) <= 0) {
- goto __err_exit;
- }
- header->data_size = reverse_24(header->data_size);
-
-
- if ((ret = fread(&(header->timestemp), 3, 1, pf)) <= 0) {
- goto __err_exit;
- }
- header->timestemp = reverse_24(header->timestemp);
-
-
- if ((ret = fread(&(header->time_stamp_extended), 1, 1, pf)) <= 0) {
- goto __err_exit;
- }
-
-
- if ((ret = fread(&(header->stream_id), 3, 1, pf)) <= 0) {
- goto __err_exit;
- }
- header->stream_id = reverse_24(header->stream_id);
- *p_header = header;
-
- #ifdef DEBUG_INFO
- printf("======= tag header =======\n");
- printf("tag_type:%x\n", header->type);
- printf("data_size:%x\n", header->data_size);
- printf("timestemp:%x\n", header->timestemp);
- printf("time_stamp_extended:%x\n", header->time_stamp_extended);
- printf("stream_id:%x\n", header->stream_id);
- #endif
-
- return 1;
- __err_exit:
- free(header);
- fprintf(stderr, "read tag header error\n");
- perror("fread error:");
-
- return ret;
- }
-
- int read_tag_data(FILE *pf, unsigned char **p_data, unsigned int size)
- {
- int ret = 0;
- unsigned char *data = NULL;
-
- data = malloc(size + 1);
- if (data == NULL) {
- fprintf(stderr, "malloc tag data error\n");
- perror("malloc error:");
- return -1;
- }
- data[size] = 0;
-
- if ((ret = fread(data, size, 1, pf)) <= 0) {
- free(data);
- fprintf(stderr, "read tag data error\n");
- perror("fread error:");
- return ret;
- }
-
- *p_data = data;
-
- return 1;
- }
-
- void audio_tag_data(unsigned char *data)
- {
- unsigned char audio_info = 0;
- unsigned char audio_format = 0;
- unsigned char audio_samplerate = 0;
- unsigned char audio_samplelenght = 0;
- unsigned char audio_type = 0;
-
-
- audio_info = data[0];
-
-
-
-
-
-
-
- audio_format = audio_info & 0xf0;
- audio_format >>= 4;
-
-
-
-
-
-
- audio_samplerate = audio_info & 0x0c;
- audio_samplerate >>= 2;
-
-
-
-
- audio_samplelenght = audio_info & 0x02;
- audio_samplelenght >>= 1;
-
-
-
-
- audio_type = audio_info & 0x01;
-
- #ifdef DEBUG_INFO
- printf("=======audio_info====\n");
- printf("format:%x\n", audio_format);
- printf("samplerate:%x\n", audio_samplerate);
- printf("samplelenght:%x\n", audio_samplelenght);
- printf("type:%x\n", audio_type);
- #endif
- }
-
- void video_tag_data(unsigned char *data)
- {
- int size = 0;
- unsigned char video_info = 0;
- unsigned char video_frame_type = 0;
- unsigned char video_code_id = 0;
-
-
- video_info = data[0];
-
-
-
-
-
- video_frame_type = video_info & 0xf0;
- video_frame_type >>= 4;
-
-
-
-
-
-
-
- video_code_id = video_info & 0x0f;
-
- #ifdef DEBUG_INFO
- printf("=======video_info====\n");
- printf("frame_type:%x\n", video_frame_type);
- printf("code_id:%x\n", video_code_id);
- #endif
- }
-
- void script_tag_data(unsigned char *data)
- {
-
-
-
-
- }
-
- int read_tag(FILE *pf, unsigned int *p_last_tag_size, _Tag *tag)
- {
- int ret = 0;
-
-
- if ((ret = read_last_tag_size(pf, p_last_tag_size)) <= 0) {
- return ret;
- }
-
-
- if ((ret = read_tag_header(pf, &(tag->header))) <= 0) {
- return ret;
- }
-
-
- if ((ret = read_tag_data(pf, &(tag->data), tag->header->data_size)) <= 0) {
- return ret;
- }
-
-
- switch(tag->header->type){
- case 0x8:
- audio_tag_data(tag->data);
- break;
- case 0x9:
- video_tag_data(tag->data);
- break;
- case 0x12:
- script_tag_data(tag->data);
- break;
- }
-
- return 1;
- }
-
- int main()
- {
- FILE *pf = NULL;
- _FileHeader *file_header = NULL;
- unsigned int last_tag_size = 0;
- _Tag *tag = NULL;
-
-
- if ((pf = fopen("./sample.flv", "rb")) == NULL) {
- perror("fopen error:");
- return -1;
- }
-
-
- if (read_file_header(pf, &file_header) <= 0) {
- fclose(pf);
- fprintf(stderr, "read_file_header error\n");
- return -1;
- }
-
-
- if(check_file_header(file_header) <= 0){
- fclose(pf);
- free(file_header);
- fprintf(stderr, "check_file_header error\n");
- return -1;
- }
-
- for ( ; ; ) {
- free_tag(&tag);
- tag = malloc_tag();
- if(tag == NULL){
- fprintf(stderr, "malloc tag error\n");
- perror("malloc error:");
- break;
- }
- if (read_tag(pf, &last_tag_size, tag) <= 0){
- break;
- }
-
- }
-
- free_tag(&tag);
- free(file_header);
- fclose(pf);
-
- return 0;
- }
点击右上角即可分享
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2017-05-10 Windows录音API学习笔记--转
2017-05-10 Windows基础-实时录音程序(WaveXXX)
2017-05-10 Windows基础-使用XAudio2播放音频(本质是WASAPI)
2017-05-10 XAudio2播放PCM
2017-05-10 C++ 调节PCM音频音量大小
2017-05-10 C++ 采集音频流(PCM裸流)实现录音功能
2017-05-10 C++ 播放音频流(PCM裸流)--改善