ffmpeg rtsp
来源:互联网 发布:网络政治参与图片 编辑:程序博客网 时间:2024/06/06 07:00
#include <libavcodec/avcodec.h>#include <libavdevice/avdevice.h>#include <libavformat/avformat.h>#include <libavfilter/avfilter.h>#include <libavutil/avutil.h>#include <libswscale/swscale.h>#include "x264_config.h"#include <stdlib.h>#include <stdio.h>#include <string.h>#include <unistd.h>#include <math.h>#include <time.h>#include <sys/time.h>#include <jni.h>#include <android/log.h> #define LOG_TAG "librtsp0"#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))static AVFormatContext *i_fmt_ctx;static AVStream *i_video_stream;static AVFormatContext *o_fmt_ctx;static AVStream *o_video_stream;signed char bStop = 0;signed char rtsp2mp4(const char *psdp, const char *pfile){ unsigned i; int ret; const char *rtspUrl = psdp; const char *filename = pfile; //注册FFmpeg所有编解码器 avcodec_register_all(); av_register_all(); //rtsp需网络支持 avformat_network_init(); /* should set to NULL so that avformat_open_input() allocate a new one */ i_fmt_ctx = NULL; //根据输入,初始化输入视频码流的AVFormatContext if(avformat_open_input(&i_fmt_ctx, rtspUrl, NULL, NULL)!=0) { LOGI(" could not open input file "); return -1; } //从输入AVFormatContext查找stream if(avformat_find_stream_info(i_fmt_ctx, NULL)<0) { LOGI(" could not find stream info "); return -1; } LOGI(" start "); //av_dump_format(i_fmt_ctx, 0, rtspUrl, 0); /* find first video stream */ for (i=0; i<i_fmt_ctx->nb_streams; i++) { if (i_fmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { i_video_stream = i_fmt_ctx->streams[i]; //找到具体的video stream, i 即为stream index break; } } if (i_video_stream == NULL) { LOGI(" didn't find any video stream "); return -1; } LOGI(" start 1 "); //根据输出文嘉类型创建相应的输出AVFormatContext avformat_alloc_output_context2(&o_fmt_ctx, NULL, NULL, filename); /* * since all input files are supposed to be identical (framerate, dimension, color format, ...) * we can safely set output codec values from first input file */ //根据输出的AVFormatContext创建相应的输出stream o_video_stream = avformat_new_stream(o_fmt_ctx, NULL); //拷贝输入视频码流的AVCodecContex的数值t到输出视频的AVCodecContext ret = avcodec_copy_context(out_stream->codec, in_stream->codec); if (ret < 0) { LOGI("Failed to copy context from input to output stream codec context\n"); return -1; } /* LOGI(" start 2 "); { AVCodecContext *c; c = o_video_stream->codec; c->bit_rate = 400000; c->codec_id = i_video_stream->codec->codec_id; c->codec_type = i_video_stream->codec->codec_type; c->time_base.num = i_video_stream->time_base.num; c->time_base.den = i_video_stream->time_base.den; c->width = i_video_stream->codec->width; c->height = i_video_stream->codec->height; c->pix_fmt = i_video_stream->codec->pix_fmt; c->flags = i_video_stream->codec->flags; c->flags |= CODEC_FLAG_GLOBAL_HEADER; c->me_range = i_video_stream->codec->me_range; c->max_qdiff = i_video_stream->codec->max_qdiff; c->qmin = i_video_stream->codec->qmin; //量化参数min c->qmax = i_video_stream->codec->qmax; //量化参数max c->qcompress = i_video_stream->codec->qcompress; LOGI(" c->codec_id = %d, num = %d, den = %d ", c->codec_id, c->time_base.num, c->time_base.den); } */ avio_open(&o_fmt_ctx->pb, filename, AVIO_FLAG_WRITE); ret = avformat_write_header(o_fmt_ctx, NULL); LOGI(" c->width = %d, c->height = %d, c->pix_fmt= %d ", i_video_stream->codec->width, i_video_stream->codec->height, i_video_stream->codec->pix_fmt); int last_pts = 0; int last_dts = 0; int64_t pts, dts; int num_rec = 0; while (bStop==0) { AVPacket i_pkt; av_init_packet(&i_pkt); i_pkt.size = 0; i_pkt.data = NULL; if (av_read_frame(i_fmt_ctx, &i_pkt) <0 ) //读取帧填入AVPacket break; /* * pts and dts should increase monotonically * pts should be >= dts */ i_pkt.flags |= AV_PKT_FLAG_KEY; pts = i_pkt.pts; i_pkt.pts += last_pts; dts = i_pkt.dts; i_pkt.dts += last_dts; i_pkt.stream_index = 0; static int num = 1; num++; if(++num_rec>40){ num_rec = 0; LOGI(" num = %d ", num); } av_interleaved_write_frame(o_fmt_ctx, &i_pkt); //av_free_packet(&i_pkt); usleep(25000); } last_dts += dts; last_pts += pts; avformat_close_input(&i_fmt_ctx); //关闭输入端的AVFormatContext,对应avformat_open_input函数 av_write_trailer(o_fmt_ctx); avcodec_close(o_fmt_ctx->streams[0]->codec); av_freep(&o_fmt_ctx->streams[0]->codec); av_freep(&o_fmt_ctx->streams[0]); avio_close(o_fmt_ctx->pb); //关闭输出端的AVFormatContext probe功能,对应avio_open函数 av_free(o_fmt_ctx); LOGI(" End "); return 0;}JNIEXPORT void JNICALL Java_com_example_myrtsp0_MainActivity_RtspMp4Start (JNIEnv *env, jclass clz, jstring sdp, jstring mp4) { const char* sdp_title = (*env)->GetStringUTFChars(env, sdp, NULL); const char* mp4_title = (*env)->GetStringUTFChars(env, mp4, NULL); bStop = 0; signed char ret = rtsp2mp4(sdp_title, mp4_title); LOGI(" RtspMp4 = %d ", ret); (*env)->ReleaseStringUTFChars(env, sdp, sdp_title); (*env)->ReleaseStringUTFChars(env, mp4, mp4_title); }//视频录制结束调用JNIEXPORT void Java_com_example_myrtsp0_MainActivity_RtspMp4End(JNIEnv *env, jclass clz){ bStop = 1; LOGI(" RtspMp4End ");}
0 0
- ffmpeg+rtsp
- ffmpeg+rtsp
- ffmpeg rtsp
- ffmpeg+rtsp+dss
- ffmpeg+rtsp+dss
- 使用FFmpeg播放rtsp
- ffmpeg RTSP流拉取
- ffmpeg rtsp 解析
- FFMPEG发布RTSP流
- ffmpeg之rtsp分析流程
- 转 ffmpeg rtsp一些内容
- ffmpeg ffserver 作为 rtsp 服务器
- ffmpeg之rtsp分析流程
- ffmpeg之rtsp分析流程
- Android版 RTSP客户端 ffmpeg
- 使用FFMPEG发布RTSP流
- [FFMPEG-代码分析]rtsp客户端
- ffmpeg API录制rtsp视频流
- 算法导论 练习题 13.1-2
- 15个高级Java多线程面试题及回答
- 欢迎使用CSDN-markdown编辑器
- XMind思维导图软件中的实用小功能
- 基于java+play的相关数据库的查询和多表查询问题
- ffmpeg rtsp
- sed与awk学习笔记(一)
- Java泛型详解
- 集合框架示意图
- Callable、Future和FutureTask
- 数据结构List实例(三):寻找倒数第k个结点值
- 读取excel标题、内容
- Nova 中的一些基本概念(1)
- 安卓自测试题——第一期