本章只记录h264封装成avi格式视频,参考ffmpeg项目的avienc.c,avi封装格式图请查看这个博客:https://blog.csdn.net/houxiaoni01/article/details/84341885

结构体如下:

typedef struct
{long   fdes;              /* File descriptor of AVI file */u_8    bExtFd;          //is extern fd,not closeu_8    recv[3];long   mode;              /* 0 for reading, 1 for writing */long   width;             /* Width  of a video frame */long   height;            /* Height of a video frame */double fps;               /* Frames per second */char   compressor[8];     /* Type of compressor, 4 bytes + padding for 0 byte */char   compressor2[8];     /* Type of compressor, 4 bytes + padding for 0 byte */long   video_strn;        /* Video stream number */long   video_frames;      /* Number of video frames */char   video_tag[4];      /* Tag of video data */long   video_pos;         /* Number of next frame to be read(if index present) */unsigned long max_len;    /* maximum video chunk present */track_t track[AVI_MAX_TRACKS];  // up to AVI_MAX_TRACKS audio tracks supportedoff_t pos;        /* position in file */long   n_idx;             /* number of index entries actually filled */long   max_idx;           /* number of index entries actually allocated */off_t v_codech_off;       /* absolut offset of video codec (strh) info */ off_t v_codecf_off;       /* absolut offset of video codec (strf) info */ unsigned char (*idx)[16]; /* index entries (AVI idx1 tag) */video_index_entry *video_index;off_t last_pos;          /* Position of last frame written */unsigned long last_len;          /* Length of last frame written */int must_use_index;              /* Flag if frames are duplicated */off_t movi_start;int anum;            // total number of audio tracks int aptr;            // current audio working track BITMAPINFOHEADER_avilib *bitmap_info_header;WAVEFORMATEX_avilib *wave_format_ex[AVI_MAX_TRACKS];s_8* sendBuf;u_32 sendLen;u_32 sndOut;u_32 sendAll;
} avi_t;

伪代码流程:

1.open一个avi文件句柄

2.找一个开始时间戳的I帧;

3.设置视频通道的分辨率、帧率

4.设置音频通道采样率,格式,码率

5.填充avi格式数据

6.写入h264 视频帧

7.close avi文件句柄

ok,先看看ffmpeg是怎么填充avi格式的。如下所示:


static int avi_write_header(AVFormatContext *s)
{AVIContext *avi = s->priv_data;AVIOContext *pb = s->pb;int bitrate, n, i, nb_frames, au_byterate, au_ssize, au_scale;int64_t max_stream_duration = 0;AVCodecParameters *video_par;AVStream *video_st = NULL;int64_t list1, list2, strh, strf;AVDictionaryEntry *t = NULL;int padding;if (s->nb_streams > AVI_MAX_STREAM_COUNT) {av_log(s, AV_LOG_ERROR, "AVI does not support "">"AV_STRINGIFY(AVI_MAX_STREAM_COUNT)" streams\n");return AVERROR(EINVAL);}for (n = 0; n < s->nb_streams; n++) {s->streams[n]->priv_data = av_mallocz(sizeof(AVIStream));if (!s->streams[n]->priv_data)return AVERROR(ENOMEM);}/* header list */avi->riff_id = 0;list1 = avi_start_new_riff(s, pb, "AVI ", "hdrl");/* avi header */ffio_wfourcc(pb, "avih");avio_wl32(pb, 14 * 4);bitrate = 0;video_par = NULL;for (n = 0; n < s->nb_streams; n++) {AVCodecParameters *par = s->streams[n]->codecpar;AVStream *st = s->streams[n];bitrate = FFMIN(bitrate + par->bit_rate, INT32_MAX);if (st->duration > 0) {int64_t stream_duration = av_rescale_q(st->duration, st->time_base, AV_TIME_BASE_Q);max_stream_duration = FFMAX(stream_duration, max_stream_duration);}if (par->codec_type == AVMEDIA_TYPE_VIDEO) {video_par = par;video_st = st;}}/* guess master index size based on bitrate and duration */if (!avi->reserve_index_space) {double duration_est, filesize_est;if (s->duration > 0)duration_est = (double)s->duration / AV_TIME_BASE;else if (max_stream_duration > 0)duration_est = (double)max_stream_duration / AV_TIME_BASE;elseduration_est = 10 * 60 * 60; /* default to 10 hours */filesize_est = duration_est * (bitrate / 8) * 1.10; /* add 10% safety margin for muxer+bitrate */avi->master_index_max_size = FFMAX((int)ceil(filesize_est / AVI_MAX_RIFF_SIZE) + 1,avi->master_index_max_size);av_log(s, AV_LOG_DEBUG, "duration_est:%0.3f, filesize_est:%0.1fGiB, master_index_max_size:%d\n",duration_est, filesize_est / (1024*1024*1024), avi->master_index_max_size);}nb_frames = 0;// TODO: should be avg_frame_rateif (video_st)avio_wl32(pb, (uint32_t) (INT64_C(1000000) * video_st->time_base.num /video_st->time_base.den));elseavio_wl32(pb, 0);avio_wl32(pb, bitrate / 8); /* XXX: not quite exact */avio_wl32(pb, 0); /* padding */if (!(pb->seekable & AVIO_SEEKABLE_NORMAL))avio_wl32(pb, AVIF_TRUSTCKTYPE | AVIF_ISINTERLEAVED);  /* flags */elseavio_wl32(pb, AVIF_TRUSTCKTYPE | AVIF_HASINDEX | AVIF_ISINTERLEAVED);  /* flags */avi->frames_hdr_all = avio_tell(pb); /* remember this offset to fill later */avio_wl32(pb, nb_frames); /* nb frames, filled later */avio_wl32(pb, 0); /* initial frame */avio_wl32(pb, s->nb_streams); /* nb streams */avio_wl32(pb, 1024 * 1024); /* suggested buffer size */if (video_par) {avio_wl32(pb, video_par->width);avio_wl32(pb, video_par->height);} else {avio_wl32(pb, 0);avio_wl32(pb, 0);}avio_wl32(pb, 0); /* reserved */avio_wl32(pb, 0); /* reserved */avio_wl32(pb, 0); /* reserved */avio_wl32(pb, 0); /* reserved *//* stream list */for (i = 0; i < n; i++) {AVStream *st = s->streams[i];AVCodecParameters *par = st->codecpar;AVIStream *avist = st->priv_data;list2 = ff_start_tag(pb, "LIST");ffio_wfourcc(pb, "strl");/* stream generic header */strh = ff_start_tag(pb, "strh");switch (par->codec_type) {case AVMEDIA_TYPE_SUBTITLE:// XSUB subtitles behave like video tracks, other subtitles// are not (yet) supported.if (par->codec_id != AV_CODEC_ID_XSUB) {avpriv_report_missing_feature(s, "Subtitle streams other than DivX XSUB");return AVERROR_PATCHWELCOME;}case AVMEDIA_TYPE_VIDEO:ffio_wfourcc(pb, "vids");break;case AVMEDIA_TYPE_AUDIO:ffio_wfourcc(pb, "auds");break;
//      case AVMEDIA_TYPE_TEXT:
//          ffio_wfourcc(pb, "txts");
//          break;case AVMEDIA_TYPE_DATA:ffio_wfourcc(pb, "dats");break;}if (par->codec_type == AVMEDIA_TYPE_VIDEO ||par->codec_id == AV_CODEC_ID_XSUB)avio_wl32(pb, par->codec_tag);elseavio_wl32(pb, 1);avist->strh_flags_offset = avio_tell(pb);avio_wl32(pb, 0); /* flags */avio_wl16(pb, 0); /* priority */avio_wl16(pb, 0); /* language */avio_wl32(pb, 0); /* initial frame */ff_parse_specific_params(st, &au_byterate, &au_ssize, &au_scale);if (   par->codec_type == AVMEDIA_TYPE_VIDEO&& par->codec_id != AV_CODEC_ID_XSUB&& au_byterate > 1000LL*au_scale) {au_byterate = 600;au_scale    = 1;}avpriv_set_pts_info(st, 64, au_scale, au_byterate);if (par->codec_id == AV_CODEC_ID_XSUB)au_scale = au_byterate = 0;avio_wl32(pb, au_scale); /* scale */avio_wl32(pb, au_byterate); /* rate */avio_wl32(pb, 0); /* start *//* remember this offset to fill later */avist->frames_hdr_strm = avio_tell(pb);if (!(pb->seekable & AVIO_SEEKABLE_NORMAL))/* FIXME: this may be broken, but who cares */avio_wl32(pb, AVI_MAX_RIFF_SIZE);elseavio_wl32(pb, 0);  /* length, XXX: filled later *//* suggested buffer size, is set to largest chunk size in avi_write_trailer */if (par->codec_type == AVMEDIA_TYPE_VIDEO)avio_wl32(pb, 1024 * 1024);else if (par->codec_type == AVMEDIA_TYPE_AUDIO)avio_wl32(pb, 12 * 1024);elseavio_wl32(pb, 0);avio_wl32(pb, -1); /* quality */avio_wl32(pb, au_ssize); /* sample size */avio_wl32(pb, 0);avio_wl16(pb, par->width);avio_wl16(pb, par->height);ff_end_tag(pb, strh);if (par->codec_type != AVMEDIA_TYPE_DATA) {int ret, flags;enum AVPixelFormat pix_fmt;strf = ff_start_tag(pb, "strf");switch (par->codec_type) {case AVMEDIA_TYPE_SUBTITLE:/* XSUB subtitles behave like video tracks, other subtitles* are not (yet) supported. */if (par->codec_id != AV_CODEC_ID_XSUB)break;case AVMEDIA_TYPE_VIDEO:/* WMP expects RGB 5:5:5 rawvideo in avi to have bpp set to 16. */if (  !par->codec_tag&& par->codec_id == AV_CODEC_ID_RAWVIDEO&& par->format == AV_PIX_FMT_RGB555LE&& par->bits_per_coded_sample == 15)par->bits_per_coded_sample = 16;avist->pal_offset = avio_tell(pb) + 40;ff_put_bmp_header(pb, par, 0, 0, avi->flipped_raw_rgb);pix_fmt = avpriv_find_pix_fmt(avpriv_pix_fmt_bps_avi,par->bits_per_coded_sample);if (   !par->codec_tag&& par->codec_id == AV_CODEC_ID_RAWVIDEO&& par->format != pix_fmt&& par->format != AV_PIX_FMT_NONE)av_log(s, AV_LOG_ERROR, "%s rawvideo cannot be written to avi, output file will be unreadable\n",av_get_pix_fmt_name(par->format));if (par->format == AV_PIX_FMT_PAL8) {if (par->bits_per_coded_sample < 0 || par->bits_per_coded_sample > 8) {av_log(s, AV_LOG_ERROR, "PAL8 with %d bps is not allowed\n", par->bits_per_coded_sample);return AVERROR(EINVAL);}}break;case AVMEDIA_TYPE_AUDIO:flags = (avi->write_channel_mask == 0) ? FF_PUT_WAV_HEADER_SKIP_CHANNELMASK : 0;if ((ret = ff_put_wav_header(s, pb, par, flags)) < 0)return ret;break;default:av_log(s, AV_LOG_ERROR,"Invalid or not supported codec type '%s' found in the input\n",(char *)av_x_if_null(av_get_media_type_string(par->codec_type), "?"));return AVERROR(EINVAL);}ff_end_tag(pb, strf);if ((t = av_dict_get(st->metadata, "title", NULL, 0))) {ff_riff_write_info_tag(s->pb, "strn", t->value);t = NULL;}if (par->codec_id == AV_CODEC_ID_XSUB&& (t = av_dict_get(s->streams[i]->metadata, "language", NULL, 0))) {const char* langstr = ff_convert_lang_to(t->value, AV_LANG_ISO639_1);t = NULL;if (langstr) {char* str = av_asprintf("Subtitle - %s-xx;02", langstr);if (!str)return AVERROR(ENOMEM);ff_riff_write_info_tag(s->pb, "strn", str);av_free(str);}}}if (pb->seekable & AVIO_SEEKABLE_NORMAL) {write_odml_master(s, i);}if (par->codec_type == AVMEDIA_TYPE_VIDEO   &&st->sample_aspect_ratio.num > 0 &&st->sample_aspect_ratio.den > 0) {int vprp       = ff_start_tag(pb, "vprp");AVRational dar = av_mul_q(st->sample_aspect_ratio,(AVRational) { par->width,par->height });int num, den, fields, i;av_reduce(&num, &den, dar.num, dar.den, 0xFFFF);if (par->field_order == AV_FIELD_TT || par->field_order == AV_FIELD_BB ||par->field_order == AV_FIELD_TB || par->field_order == AV_FIELD_BT) {fields = 2; // interlaced} else {fields = 1; // progressive}avio_wl32(pb, 0); // video format   = unknownavio_wl32(pb, 0); // video standard = unknown// TODO: should be avg_frame_rateavio_wl32(pb, (2LL*st->time_base.den + st->time_base.num - 1) / (2LL * st->time_base.num));avio_wl32(pb, par->width);avio_wl32(pb, par->height);avio_wl16(pb, den);avio_wl16(pb, num);avio_wl32(pb, par->width);avio_wl32(pb, par->height);avio_wl32(pb, fields); // fields per framefor (i = 0; i < fields; i++) {int start_line;// OpenDML v1.02 is not very specific on what value to use for// start_line when frame data is not coming from a capturing device,// so just use 0/1 depending on the field order for interlaced framesif (par->field_order == AV_FIELD_TT || par->field_order == AV_FIELD_TB) {start_line = (i == 0) ? 0 : 1;} else if (par->field_order == AV_FIELD_BB || par->field_order == AV_FIELD_BT) {start_line = (i == 0) ? 1 : 0;} else {start_line = 0;}avio_wl32(pb, par->height / fields); // compressed bitmap heightavio_wl32(pb, par->width);           // compressed bitmap widthavio_wl32(pb, par->height / fields); // valid bitmap heightavio_wl32(pb, par->width);           // valid bitmap widthavio_wl32(pb, 0);                    // valid bitmap X offsetavio_wl32(pb, 0);                    // valid bitmap Y offsetavio_wl32(pb, 0);                    // valid X offset in Tavio_wl32(pb, start_line);           // valid Y start line}ff_end_tag(pb, vprp);}ff_end_tag(pb, list2);}if (pb->seekable & AVIO_SEEKABLE_NORMAL) {/* AVI could become an OpenDML one, if it grows beyond 2Gb range */avi->odml_list = ff_start_tag(pb, "JUNK");ffio_wfourcc(pb, "odml");ffio_wfourcc(pb, "dmlh");avio_wl32(pb, 248);for (i = 0; i < 248; i += 4)avio_wl32(pb, 0);ff_end_tag(pb, avi->odml_list);}ff_end_tag(pb, list1);ff_riff_write_info(s);padding = s->metadata_header_padding;if (padding < 0)padding = 1016;/* some padding for easier tag editing */if (padding) {list2 = ff_start_tag(pb, "JUNK");for (i = padding; i > 0; i -= 4)avio_wl32(pb, 0);ff_end_tag(pb, list2);}avi->movi_list = ff_start_tag(pb, "LIST");ffio_wfourcc(pb, "movi");return 0;
}

sample例子

void long2str(unsigned char *dst, int n)
{dst[0] = (n    )&0xff;dst[1] = (n>> 8)&0xff;dst[2] = (n>>16)&0xff;dst[3] = (n>>24)&0xff;
}
#define OUT4CC(s) \
if(nhb<=HEADERBYTES-4) memcpy(AVI_header+nhb,s,4); nhb += 4#define OUTLONG(n) \
if(nhb<=HEADERBYTES-4) long2str(AVI_header+nhb,n); nhb += 4int avi_update_header(avi_t *AVI, u_8 type)
{int njunk, sampsize, hasIndex, ms_per_frame, frate, flag;int movi_len, hdrl_start, strl_start, j;unsigned char AVI_header[HEADERBYTES];long nhb;//assume max sizemovi_len = AVI_MAX_LEN - HEADERBYTES + 4;//assume index will be writtenhasIndex=1;if(AVI->fps < 0.001) {frate=0;ms_per_frame=0;} else {frate = (int) (FRAME_RATE_SCALE*AVI->fps + 0.5);ms_per_frame=(int) (1000000/AVI->fps + 0.5);}/* Prepare the file header */nhb = 0;/* The RIFF header */OUT4CC ("RIFF");OUTLONG(movi_len);    // assume max sizeOUT4CC ("AVI ");/* Start the header list */OUT4CC ("LIST");OUTLONG(0);        /* Length of list in bytes, don't know yet */hdrl_start = nhb;  /* Store start position */OUT4CC ("hdrl");/* The main AVI header *//* The Flags in AVI File header */#define AVIF_HASINDEX           0x00000010      /* Index at end of file */
#define AVIF_MUSTUSEINDEX       0x00000020
#define AVIF_ISINTERLEAVED      0x00000100
#define AVIF_TRUSTCKTYPE        0x00000800      /* Use CKType to find key frames */
#define AVIF_WASCAPTUREFILE     0x00010000
#define AVIF_COPYRIGHTED        0x00020000OUT4CC ("avih");OUTLONG(56);                 /* # of bytes to follow */OUTLONG(ms_per_frame);       /* Microseconds per frame *///ThOe ->0 //   OUTLONG(10000000);           /* MaxBytesPerSec, I hope this will never be used */OUTLONG(0);OUTLONG(0);                  /* PaddingGranularity (whatever that might be) *//* Other sources call it 'reserved' */flag = AVIF_ISINTERLEAVED;if(hasIndex) flag |= AVIF_HASINDEX;if(hasIndex && AVI->must_use_index) flag |= AVIF_MUSTUSEINDEX;OUTLONG(flag);               /* Flags */OUTLONG(0);                  // no frames yetOUTLONG(0);                  /* InitialFrames */OUTLONG(AVI->anum+1);OUTLONG(0);                  /* SuggestedBufferSize */OUTLONG(AVI->width);         /* Width */OUTLONG(AVI->height);        /* Height *//* MS calls the following 'reserved': */OUTLONG(0);                  /* TimeScale:  Unit used to measure time */OUTLONG(0);                  /* DataRate:   Data rate of playback     */OUTLONG(0);                  /* StartTime:  Starting time of AVI data */OUTLONG(0);                  /* DataLength: Size of AVI data chunk    *//* Start the video stream list ---------------------------------- */OUT4CC ("LIST");OUTLONG(0);        /* Length of list in bytes, don't know yet */strl_start = nhb;  /* Store start position */OUT4CC ("strl");/* The video stream header */OUT4CC ("strh");OUTLONG(56);                 /* # of bytes to follow */OUT4CC ("vids");             /* Type */OUT4CC (AVI->compressor);    /* Handler */OUTLONG(0);                  /* Flags */OUTLONG(0);                  /* Reserved, MS says: wPriority, wLanguage */OUTLONG(0);                  /* InitialFrames */OUTLONG(FRAME_RATE_SCALE);              /* Scale */OUTLONG(frate);              /* Rate: Rate/Scale == samples/second */OUTLONG(0);                  /* Start */OUTLONG(0);                  // no frames yetOUTLONG(0);                  /* SuggestedBufferSize */OUTLONG(-1);                 /* Quality */OUTLONG(0);                  /* SampleSize */OUTLONG(0);                  /* Frame */OUTLONG(0);                  /* Frame *///   OUTLONG(0);                  /* Frame *///OUTLONG(0);                  /* Frame *//* The video stream format */OUT4CC ("strf");OUTLONG(40);                 /* # of bytes to follow */OUTLONG(40);                 /* Size */OUTLONG(AVI->width);         /* Width */OUTLONG(AVI->height);        /* Height */OUTSHRT(1); OUTSHRT(24);     /* Planes, Count */OUT4CC (AVI->compressor);    /* Compression */// ThOe (*3)OUTLONG(AVI->width*AVI->height*3);  /* SizeImage (in bytes?) */OUTLONG(0);                  /* XPelsPerMeter */OUTLONG(0);                  /* YPelsPerMeter */OUTLONG(0);                  /* ClrUsed: Number of colors used */OUTLONG(0);                  /* ClrImportant: Number of colors important *//* Finish stream list, i.e. put number of bytes in the list to proper pos */long2str(AVI_header+strl_start-4,nhb-strl_start);/* Start the audio stream list ---------------------------------- */for(j=0; j<AVI->anum; ++j) {sampsize = avi_sampsize(AVI, j);OUT4CC ("LIST");OUTLONG(0);        /* Length of list in bytes, don't know yet */strl_start = nhb;  /* Store start position */OUT4CC ("strl");/* The audio stream header */OUT4CC ("strh");OUTLONG(56);            /* # of bytes to follow */OUT4CC ("auds");// -----------// ThOeOUTLONG(0);             /* Format (Optionally) */// -----------OUTLONG(0);             /* Flags */OUTLONG(0);             /* Reserved, MS says: wPriority, wLanguage */OUTLONG(0);             /* InitialFrames */// ThOe /4OUTLONG(sampsize/4);      /* Scale */OUTLONG(1000*AVI->track[j].mp3rate/8);OUTLONG(0);             /* Start */OUTLONG(4*AVI->track[j].audio_bytes/sampsize);   /* Length */OUTLONG(0);             /* SuggestedBufferSize */OUTLONG(-1);            /* Quality */// ThOe /4OUTLONG(sampsize/4);    /* SampleSize */OUTLONG(0);             /* Frame */OUTLONG(0);             /* Frame *///       OUTLONG(0);             /* Frame *///OUTLONG(0);             /* Frame *//* The audio stream format */OUT4CC ("strf");OUTLONG(16);                   /* # of bytes to follow */OUTSHRT(AVI->track[j].a_fmt);           /* Format */OUTSHRT(AVI->track[j].a_chans);         /* Number of channels */OUTLONG(AVI->track[j].a_rate);          /* SamplesPerSec */// ThOeOUTLONG(1000*AVI->track[j].mp3rate/8);//ThOe (/4)OUTSHRT(sampsize/4);           /* BlockAlign */OUTSHRT(AVI->track[j].a_bits);          /* BitsPerSample *//* Finish stream list, i.e. put number of bytes in the list to proper pos */long2str(AVI_header+strl_start-4,nhb-strl_start);}/* Finish header list */long2str(AVI_header+hdrl_start-4,nhb-hdrl_start);/* Calculate the needed amount of junk bytes, output junk */njunk = HEADERBYTES - nhb - 8 - 12;/* Safety first: if njunk <= 0, somebody has played withHEADERBYTES without knowing what (s)he did.This is a fatal error */if(njunk<=0){fprintf(stderr,"AVI_close_output_file: # of header bytes too small\n");exit(1);}OUT4CC ("JUNK");OUTLONG(njunk);BSJ_AssertCheck((u_32)nhb+njunk < sizeof(AVI_header));memset(AVI_header+nhb,0,njunk);//2001-11-14 added id string if(njunk > (int)strlen(id_str)+8) {//BSJ_snprintf(id_str, "%s-%s", PACKAGE, VERSION);//BSJ_memcpy(AVI_header+nhb, id_str, strlen(id_str), HEADERBYTES-nhb);}nhb += njunk;/* Start the movi list */OUT4CC ("LIST");OUTLONG(movi_len); /* Length of list in bytes */OUT4CC ("movi");/* Output the header, truncate the file to the number of bytesactually written, report an error if someting goes wrong */if(type == 1) {if ( lseek(AVI->fdes,0,SEEK_SET)<0 ||avi_write_fd(AVI->fdes,(char *)AVI_header,HEADERBYTES,type)!=HEADERBYTES ||lseek(AVI->fdes,AVI->pos,SEEK_SET)<0){AVI_errno = AVI_ERR_CLOSE;return -1;}}else{if (avi_add_sendBuf(AVI,AVI_header,HEADERBYTES)!=0){AVI_errno = AVI_ERR_CLOSE;return -1;}    }return 0;
}

ffmpeg h264转avi学习笔记相关推荐

  1. ffmpeg h264转avi

    将h264转换到avi格式: ffmpeg -i input.264 -s 640x480 output.avi -s : 为重新设置分辨率 -r  : 为帧率设置

  2. ffmpeg+dxva2 +D3D9显示 学习笔记

    去年因为需要基于ffmpeg开发了一个解码库,当时解码高清视频9路CPU占用基本达到100%了(笔记本  i7处理器)不过在台式机上表现还可以.也就没管,也没深入研究.今年新上了一批PC,配置很差,满 ...

  3. H264解码的学习笔记

    解码图片由三部分组成:1个luma采样数组,2个chroma采样数组 Chroma Format ChromaFormatFactor monochrome 1 4:2:0 1.5 4:2:2 2 4 ...

  4. FFmpeg基础到工程-多路H265监控录放开发学习笔记

    多路H265监控录放开发学习笔记 课程涉及:FFmpeg,WebRTC,SRS,Nginx,Darwin,Live555,等.包括:音视频.流媒体.直播.Android.视频监控28181.等. 具体 ...

  5. NDK学习笔记:RtmpPusher之利用rtmpdump推h264/aac码流

    NDK学习笔记:RtmpPusher之利用rtmpdump推h264/aac码流 本篇将是 RtmpPusher 的最后一篇.在之前的3篇文章里,我们已经把原生的视频YUV格式编码成h264,把音频的 ...

  6. NDK学习笔记:FFmpeg解压MP34提取音频PCM(swrContext、swr_alloc_set_opts)

    NDK学习笔记:FFmpeg解压MP34提取音频PCM 承接 FFmpeg解压MP4提取视频YUV ,这次我们需要提取的是音频原始数据PCM.代码流程大同小异,主要区别就是AVFrame->PC ...

  7. H264和H265的学习笔记

    H264和H265的学习笔记记录分享 一.H264的组成: 二.H265的组成: 三.H264和H265由es打包为pes再打包为ps的代码思路如下: 四.补充说明 一.H264的组成: 1.H264 ...

  8. FFMPEG h264 ACC 合成 mkv ts;h264 mp3 合成 MP4 avi flv

    FFMPEG h264 ACC 合成 mkv ts:h264 mp3 合成 MP4 avi flv #include <stdio.h>#include <cstdio>#in ...

  9. 学习笔记(2):基于NDK、C++、FFmpeg的android视频播放器开发实战-音视频基础知识Mpeg4封装格式音视频编码格式讲解...

    立即学习:https://edu.csdn.net/course/play/7417/151027?utm_source=blogtoedu 封装:将音视频从文件中读出来 解码:解压出来,转换成显卡支 ...

最新文章

  1. 更改git bash默认的路径
  2. 你面试稳了!通关LeetCode刷题完整攻略,省时又高效
  3. 软考高项之各大管理计划内容-攻坚记忆
  4. php curl伪造referer与来源IP实例
  5. windows server2008无法将本地文件复制到远程计算机,windows2008/2012无法从本地复制文件到远程服务器处理方法...
  6. hashtable和hashmap的区别?
  7. SilkTest 对 Excel 表操作的两种方式
  8. IP地址聚合-路由汇聚_共同前缀(1.相似部分2.最后一组二进制比较,取相同,算位数3.转十进制,加位数)
  9. 网站漏洞修复公司 对网站上传文件漏洞的修复与安全加固
  10. 6月3日 徒步虎跳峡——第一日
  11. Java集成华为云对象存储
  12. python--定义新矩阵、矩阵赋值、改变类型
  13. 雀巢普瑞纳亮相亚宠展,加码在华宠物护理业务
  14. RGB图像转换为BGR
  15. matlab水力学工具箱,水工设计工具箱免费版
  16. Spring Boot 静态资源修改立即生效
  17. 项目经理之成功项目经理手册
  18. PDF如何去水印?PDF去水印的基础操作
  19. 3DMax提示缺少Vrey的DLL
  20. 三维建模之曲面的数学模型

热门文章

  1. 出门刷卡要小心!一种可以从POS机终端收集信用卡信息的恶意软件出现了
  2. Instance Segmentation 和 Semantic Segmentation
  3. 2022-2028全球与中国智慧灯杆市场现状及未来发展趋势
  4. 创建一个中国象棋的阿法狗——阿法象(0)
  5. 如何免费恢复u盘误删文件?
  6. Fingerprintjs2:一款开源设备指纹采集器
  7. nubia ui 5.0 android,nubia Z9 mini的手机系统是什么?能升级安卓5.0吗?
  8. DC-DC电源模块输出先放大电容还是小电容
  9. 网易笔试题之DFS回溯法求解黑白棋(翻翻棋)
  10. angular数据交互