Guest User

Untitled

a guest
Dec 28th, 2017
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.71 KB | None | 0 0
  1. #include <libavutil/timestamp.h>
  2. #include <libavformat/avformat.h>
  3.  
  4. static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket
  5. *pkt, const char *tag)
  6. {
  7. AVRational *time_base = &fmt_ctx->streams[pkt->stream_index]->time_base;
  8.  
  9. printf("%s: pts:%s pts_time:%s dts:%s dts_time:%s duration:%s
  10. duration_time:%s stream_index:%d\n",
  11. tag,
  12. av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, time_base),
  13. av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, time_base),
  14. av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, time_base),
  15. pkt->stream_index);
  16. }
  17.  
  18.  
  19. int main(int argc, char **argv)
  20. {
  21. AVOutputFormat *ofmt = NULL;
  22. AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
  23. AVPacket pkt;
  24. const char *in_filename, *out_filename;
  25. int ret, i;
  26. int stream_index = 0;
  27. int *stream_mapping = NULL;
  28. int stream_mapping_size = 0;
  29. AVRational mux_timebase;
  30. int64_t start_time = 0; //(of->start_time == AV_NOPTS_VALUE) ? 0 :
  31. of->start_time;
  32. int64_t ost_tb_start_time = 0; //av_rescale_q(start_time,
  33. AV_TIME_BASE_Q, ost->mux_timebase);
  34.  
  35. if (argc < 3) {
  36. printf("usage: %s input output\n"
  37. "API example program to remux a media file with
  38. libavformat and libavcodec.\n"
  39. "The output format is guessed according to the file extension.\n"
  40. "\n", argv[0]);
  41. return 1;
  42. }
  43.  
  44. in_filename = argv[1];
  45. out_filename = argv[2];
  46.  
  47. av_register_all();
  48. avcodec_register_all();
  49. avformat_network_init();
  50.  
  51. if ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, 0)) < 0) {
  52. fprintf(stderr, "Could not open input file '%s'", in_filename);
  53. goto end;
  54. }
  55.  
  56. if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0) {
  57. fprintf(stderr, "Failed to retrieve input stream information");
  58. goto end;
  59. }
  60.  
  61. av_dump_format(ifmt_ctx, 0, in_filename, 0);
  62.  
  63. avformat_alloc_output_context2(&ofmt_ctx, NULL, "rtp_mpegts", out_filename);
  64. if (!ofmt_ctx) {
  65. fprintf(stderr, "Could not create output context\n");
  66. ret = AVERROR_UNKNOWN;
  67. goto end;
  68. }
  69.  
  70. stream_mapping_size = ifmt_ctx->nb_streams;
  71. stream_mapping = av_mallocz_array(stream_mapping_size,
  72. sizeof(*stream_mapping));
  73. if (!stream_mapping) {
  74. ret = AVERROR(ENOMEM);
  75. goto end;
  76. }
  77.  
  78. ofmt = ofmt_ctx->oformat;
  79.  
  80. for (i = 0; i < ifmt_ctx->nb_streams; i++)
  81. {
  82. AVStream *out_stream;
  83. AVStream *in_stream = ifmt_ctx->streams[i];
  84. AVCodecParameters *in_codecpar = in_stream->codecpar;
  85.  
  86. if (in_codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
  87. in_codecpar->codec_type != AVMEDIA_TYPE_VIDEO &&
  88. in_codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) {
  89. stream_mapping[i] = -1;
  90. continue;
  91. }
  92.  
  93. stream_mapping[i] = stream_index++;
  94.  
  95.  
  96. out_stream = avformat_new_stream(ofmt_ctx, NULL);
  97. if (!out_stream) {
  98. fprintf(stderr, "Failed allocating output stream\n");
  99. ret = AVERROR_UNKNOWN;
  100. goto end;
  101. }
  102.  
  103. //out_stream->codecpar->codec_tag = 0;
  104. if (0 == out_stream->codecpar->codec_tag)
  105. {
  106. unsigned int codec_tag_tmp;
  107.  
  108. if (!out_stream->codecpar->codec_tag ||
  109. av_codec_get_id (ofmt->codec_tag,
  110. in_codecpar->codec_tag) == in_codecpar->codec_id ||
  111. !av_codec_get_tag2(ofmt->codec_tag,
  112. in_codecpar->codec_id, &codec_tag_tmp))
  113. out_stream->codecpar->codec_tag = in_codecpar->codec_tag;
  114. }
  115. //ret = avcodec_parameters_to_context(ost->enc_ctx, ist->st->codecpar);
  116.  
  117. ret = avcodec_parameters_copy(out_stream->codecpar, in_codecpar);
  118. if (ret < 0) {
  119. fprintf(stderr, "Failed to copy codec parameters\n");
  120. goto end;
  121. }
  122. //out_stream->codecpar->codec_tag = codec_tag;
  123. // copy timebase while removing common factors
  124.  
  125. printf("bit_rate %lld sample_rate %d frame_size %d\n",
  126. in_codecpar->bit_rate, in_codecpar->sample_rate,
  127. in_codecpar->frame_size);
  128.  
  129. out_stream->avg_frame_rate = in_stream->avg_frame_rate;
  130.  
  131. ret = avformat_transfer_internal_stream_timing_info(ofmt,
  132.  
  133. out_stream, in_stream,
  134. AVFMT_TBCF_AUTO);
  135. if (ret < 0) {
  136. fprintf(stderr,
  137. "avformat_transfer_internal_stream_timing_info failed\n");
  138. goto end;
  139. }
  140.  
  141. if (out_stream->time_base.num <= 0 || out_stream->time_base.den <= 0)
  142. out_stream->time_base =
  143. av_add_q(av_stream_get_codec_timebase(out_stream), (AVRational){0,
  144. 1});
  145.  
  146. // copy estimated duration as a hint to the muxer
  147. if (out_stream->duration <= 0 && in_stream->duration > 0)
  148. out_stream->duration = av_rescale_q(in_stream->duration,
  149. in_stream->time_base, out_stream->time_base);
  150.  
  151. // copy disposition
  152. out_stream->disposition = in_stream->disposition;
  153.  
  154. out_stream->sample_aspect_ratio = in_stream->sample_aspect_ratio;
  155. out_stream->avg_frame_rate = in_stream->avg_frame_rate;
  156. out_stream->r_frame_rate = in_stream->r_frame_rate;
  157.  
  158. if ( in_codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
  159. {
  160.  
  161. mux_timebase = in_stream->time_base;
  162. }
  163.  
  164.  
  165. if (in_stream->nb_side_data) {
  166. for (i = 0; i < in_stream->nb_side_data; i++) {
  167. const AVPacketSideData *sd_src = &in_stream->side_data[i];
  168. uint8_t *dst_data;
  169.  
  170. dst_data = av_stream_new_side_data(out_stream,
  171. sd_src->type, sd_src->size);
  172. if (!dst_data)
  173. return AVERROR(ENOMEM);
  174. memcpy(dst_data, sd_src->data, sd_src->size);
  175. }
  176. }
  177. }
  178.  
  179. av_dump_format(ofmt_ctx, 0, out_filename, 1);
  180.  
  181. start_time = ofmt_ctx->duration;
  182. ost_tb_start_time = av_rescale_q(ofmt_ctx->duration,
  183. AV_TIME_BASE_Q, mux_timebase);
  184.  
  185. if (!(ofmt->flags & AVFMT_NOFILE))
  186. {
  187. ret = avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE);
  188. if (ret < 0) {
  189. fprintf(stderr, "Could not open output file '%s'", out_filename);
  190. goto end;
  191. }
  192. }
  193.  
  194. ret = avformat_write_header(ofmt_ctx, NULL);
  195. if (ret < 0) {
  196. fprintf(stderr, "Error occurred when opening output file\n");
  197. goto end;
  198. }
  199.  
  200. while (1)
  201. {
  202. AVStream *in_stream, *out_stream;
  203.  
  204. ret = av_read_frame(ifmt_ctx, &pkt);
  205. if (ret < 0)
  206. break;
  207.  
  208. in_stream = ifmt_ctx->streams[pkt.stream_index];
  209. if (pkt.stream_index >= stream_mapping_size ||
  210. stream_mapping[pkt.stream_index] < 0) {
  211. av_packet_unref(&pkt);
  212. continue;
  213. }
  214.  
  215. pkt.stream_index = stream_mapping[pkt.stream_index];
  216. out_stream = ofmt_ctx->streams[pkt.stream_index];
  217.  
  218. //log_packet(ifmt_ctx, &pkt, "in");
  219.  
  220.  
  221. //ofmt_ctx->bit_rate = ifmt_ctx->bit_rate;
  222. ofmt_ctx->duration = ifmt_ctx->duration;
  223. /* copy packet */
  224. //pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base,
  225. out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
  226. //pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base,
  227. out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
  228.  
  229. if (pkt.pts != AV_NOPTS_VALUE)
  230. pkt.pts = av_rescale_q(pkt.pts,
  231. in_stream->time_base,mux_timebase) - ost_tb_start_time;
  232. else
  233. pkt.pts = AV_NOPTS_VALUE;
  234.  
  235. if (pkt.dts == AV_NOPTS_VALUE)
  236. pkt.dts = av_rescale_q(pkt.dts, AV_TIME_BASE_Q, mux_timebase);
  237. else
  238. pkt.dts = av_rescale_q(pkt.dts, in_stream->time_base, mux_timebase);
  239. pkt.dts -= ost_tb_start_time;
  240.  
  241. pkt.duration = av_rescale_q(pkt.duration,
  242. in_stream->time_base, mux_timebase);
  243. //pkt.duration = av_rescale_q(1,
  244. av_inv_q(out_stream->avg_frame_rate), mux_timebase);
  245. pkt.pos = -1;
  246. //log_packet(ofmt_ctx, &pkt, "out");
  247.  
  248.  
  249. ret = av_interleaved_write_frame(ofmt_ctx, &pkt);
  250. if (ret < 0) {
  251. fprintf(stderr, "Error muxing packet\n");
  252. break;
  253. }
  254. av_packet_unref(&pkt);
  255. }
  256.  
  257. av_write_trailer(ofmt_ctx);
  258. end:
  259.  
  260. avformat_close_input(&ifmt_ctx);
  261.  
  262. /* close output */
  263. if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
  264. avio_closep(&ofmt_ctx->pb);
  265. avformat_free_context(ofmt_ctx);
  266.  
  267. av_freep(&stream_mapping);
  268.  
  269. if (ret < 0 && ret != AVERROR_EOF) {
  270. fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
  271. return 1;
  272. }
  273.  
  274. return 0;
  275. }
Add Comment
Please, Sign In to add comment