Skip to content

Instantly share code, notes, and snippets.

@hjhee
Created July 20, 2017 03:51
Show Gist options
  • Save hjhee/5625ac15238b95502c49192f9b1fb980 to your computer and use it in GitHub Desktop.
Save hjhee/5625ac15238b95502c49192f9b1fb980 to your computer and use it in GitHub Desktop.
an example for rtsp to mp4 remuxing without transcoding
#include <libavutil/timestamp.h>
#include <libavformat/avformat.h>
#include <signal.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
static volatile int keep_running=1;
static AVOutputFormat *ofmt=NULL;
static AVFormatContext *ifmt_ctx=NULL, *ofmt_ctx=NULL;
static AVPacket pkt;
static AVCodecContext *video_dec_ctx=NULL;
static AVStream *in_stream=NULL,*out_stream=NULL;
const char src_filename[]="rtsp://user:aaafff@192.168.67.61/stream1";
const char dst_filename[]="test.mp4";
static int video_stream_idx=-1;
static int width, height;
static enum AVPixelFormat pix_fmt;
static void int_handler(int dummy){
keep_running=0;
fprintf(stderr, "\ncatch SIGINT, exiting...\n");
}
static int find_video_stream(int *idx, AVFormatContext *fmt,
enum AVMediaType type){
int ret, stream_index;
ret=av_find_best_stream(ifmt_ctx, type, -1, -1, NULL, 0);
if(ret<0){
fprintf(stderr, "Could not find %s stream"
" in input file '%s'\n",
av_get_media_type_string(type),
src_filename
);
return ret;
}else{
*idx=ret;
}
return 0;
}
void *timer_thread(void *arg){
fprintf(stderr, "Starting countdown...\n");
sleep(10);
fprintf(stderr, "Countdown complete\n");
keep_running=0;
pthread_exit(0);
}
int main(int argc, char **argv){
int ret;
signal(SIGINT, int_handler);
AVDictionary *opts=NULL;
av_register_all();
avformat_network_init();
av_dict_set(&opts, "buffer_size", "655360", 0);
if(avformat_open_input(&ifmt_ctx, src_filename, NULL, &opts)<0){
fprintf(stderr, "Could not open source file %s\n",
src_filename);
goto end;
}
av_dict_free(&opts);
if(avformat_find_stream_info(ifmt_ctx, NULL)<0){
fprintf(stderr, "Could not find stream information\n");
goto end;
}
if(find_video_stream(&video_stream_idx, ifmt_ctx,
AVMEDIA_TYPE_VIDEO)<0){
goto end;
}
fprintf(stderr, "Input format context:\n");
av_dump_format(ifmt_ctx, 0, src_filename, 0);
avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, dst_filename);
if(!ofmt_ctx){
fprintf(stderr, "Could not create output context!\n");
goto end;
}
ofmt=ofmt_ctx->oformat;
out_stream=avformat_new_stream(ofmt_ctx, NULL);
if(!out_stream){
fprintf(stderr, "Failed allocating output stream\n");
goto end;
}
if(avcodec_parameters_copy(out_stream->codecpar,
ifmt_ctx->streams[video_stream_idx]->codecpar)<0){
fprintf(stderr, "Failed to copy codec parameters\n");
goto end;
}
out_stream->codecpar->codec_tag=0;
fprintf(stderr, "Output format context:\n");
av_dump_format(ofmt_ctx, 0, dst_filename, 1);
if(avio_open(&ofmt_ctx->pb, dst_filename, AVIO_FLAG_WRITE)<0){
fprintf(stderr, "Could not open output file '%s'\n",
dst_filename);
goto end;
}
if(avformat_write_header(ofmt_ctx, NULL)<0){
fprintf(stderr, "Error occurred when opening output file\n");
goto end;
}
/*
pthread_t tid;
int err;
err=pthread_create(&tid, NULL, timer_thread, NULL);
if(err){
fprintf(stderr, "%s: %s\n", __func__, strerror(err));
goto end;
}
*/
int found=0;
int pts,dts;
int64_t cnt=0;
fprintf(stderr, "Start remuxing...\n");
while(keep_running){
if(av_read_frame(ifmt_ctx, &pkt)<0)
break;
if(pkt.stream_index!=video_stream_idx){
av_packet_unref(&pkt);
continue;
}
if(found==0&&pkt.flags&AV_PKT_FLAG_KEY){
// continue;
pts=pkt.pts;
dts=pkt.dts;
found=1;
fprintf(stderr, "cnt=%lld\n", cnt);
}
pkt.pts=cnt;
pkt.dts=cnt;
pkt.stream_index=0;
cnt+=1;
/*
in_stream=ifmt_ctx->streams[pkt.stream_index];
pkt.stream_index=0;
out_stream=ofmt_ctx->streams[pkt.stream_index];
*/
/*
pkt.pts=av_rescale_q_rnd(pkt.pts, in_stream->time_base,
out_stream->time_base,
AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
pkt.dts=av_rescale_q_rnd(pkt.dts, in_stream->time_base,
out_stream->time_base,
AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
pkt.duration=av_rescale_q(pkt.duration, in_stream->time_base,
out_stream->time_base);
pkt.pos=-1;
*/
/*
fprintf(stderr, "\n");
fprintf(stderr, "pkt.pts=%lld\n", pkt.pts);
fprintf(stderr, "pkt.dts=%lld\n", pkt.dts);
fprintf(stderr, "pkt.duration=%lld\n", pkt.duration);
*/
if(av_interleaved_write_frame(ofmt_ctx, &pkt)<0){
fprintf(stderr, "Error muxing packet\n");
break;
}
av_packet_unref(&pkt);
}
av_write_trailer(ofmt_ctx);
fprintf(stderr, "remuxing completed!\n");
end:
avformat_close_input(&ifmt_ctx);
if(ofmt_ctx)
avio_closep(&ofmt_ctx->pb);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment