ffmpeg提取H264视频数据
方法1:命令提取
ffmpeg -i input.mp4 -an -vcodec copy out.h264 ffmpeg -i input.mp4 -an -vcodec copy -bsf: h264_mp4toannexb out1.h264
方法2:代码提取
main.c
#include "libavutil/log.h" #include "libavformat/avformat.h" #include "libavutil/avutil.h" #include "libavcodec/avcodec.h" int main(int argc, char **argv) { av_log_set_level(AV_LOG_DEBUG); if (argc < 3) { av_log(NULL, AV_LOG_ERROR, "Usage: %s inputFile outputFile\n", argv[0]); return -1; } const char *inputFile = argv[1]; const char *outputFile = argv[2]; AVFormatContext *fCtx = NULL; int ret = avformat_open_input(&fCtx, inputFile, NULL, NULL); if (ret != 0) { av_log(NULL, AV_LOG_ERROR, "Open input file %s failed: %s\n", inputFile, av_err2str(ret)); return -1; } ret = avformat_find_stream_info(fCtx, NULL); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Find input file stream info failed: %s\n", av_err2str(ret)); avformat_close_input(&fCtx); return -1; } int videoIndex = av_find_best_stream(fCtx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0); if (videoIndex < 0) { av_log(NULL, AV_LOG_ERROR, "Find best stream failed: %d\n", videoIndex); avformat_close_input(&fCtx); return -1; } av_log(NULL, AV_LOG_INFO, "videoIndex=%d\n", videoIndex); FILE *dst = fopen(outputFile, "wb"); if (dst == NULL) { av_log(NULL, AV_LOG_ERROR, "Open output file: %s failed\n", outputFile); avformat_close_input(&fCtx); return -1; } AVPacket *packet = av_packet_alloc(); packet->data = NULL; packet->size = 0; const AVBitStreamFilter *bsf = av_bsf_get_by_name("h264_mp4toannexb"); if (bsf == NULL) { av_log(NULL, AV_LOG_ERROR, "av_bsf_get_by_name failed\n"); avformat_close_input(&fCtx); return -1; } AVBSFContext *absCtx = NULL; av_bsf_alloc(bsf, &absCtx); avcodec_parameters_copy(absCtx->par_in, fCtx->streams[videoIndex]->codecpar); av_bsf_init(absCtx); while (av_read_frame(fCtx, packet) == 0) { if (packet->stream_index == videoIndex) { size_t size; if (av_bsf_send_packet(absCtx, packet) == 0) { while (av_bsf_receive_packet(absCtx, packet) == 0) { size = fwrite(packet->data, sizeof(uint8_t), packet->size, dst); if (size != packet->size) { av_log(NULL, AV_LOG_ERROR, "Write size: %zu, packet size: %d\n", size, packet->size); fclose(dst); avformat_close_input(&fCtx); av_packet_unref(packet); return -1; } } } } av_packet_unref(packet); } if (fCtx != NULL) { avformat_close_input(&fCtx); } if (absCtx != NULL) { av_bsf_free(&absCtx); } fclose(dst); return 0; }
Makefile
TARGET=main SRC=main.c CC=gcc CFLAGS=-I /usr/local/ffmpeg/include LDFLAGS=-L /usr/local/ffmpeg/lib LDFLAGS+= -lavutil -lavformat -lavcodec all:$(TARGET) $(TARGET):$(SRC) $(CC) $(SRC) $(CFLAGS) $(LDFLAGS) -o $(TARGET) clean: rm -rf $(TARGET)