ffmpeg转码之TS转PS

Remux:无损的取出HD-DVD和BluRay-DVD里面的视频和音频数据,重新封装到另一种容器。

根据ffmpeg的sample例子remuxing写了一个ts转ps的例子。


写了一个ts转ps的demo。ts数据从文件中读取。

ffmpeg怎么从从内存中获取看这篇博文http://blog.csdn.net/rootusers/article/details/42551935

然后将ts流转换为ps流,存储在内存中。

下面是代码:

  1. <pre name= "code" class= "cpp"> extern "C"
  2. {
  3. #include "libavformat/avformat.h"
  4. }
  5. FILE *file = NULL;
  6. int write_packet(void *opaque, uint8_t *buf, int buf_size)
  7. {
  8. //printf("write data\n");
  9. if (file)
  10. fwrite(buf, buf_size, 1, file); //可以写文件,也可以通过协议发出去
  11. return 0;
  12. }
  13. int main(int argc, char **argv)
  14. {
  15. fopen_s(&file, "output.dat", "ab+"); //输出ps数据到文件
  16. if (file == NULL)
  17. printf( "open output file failed\n");
  18. AVIOContext* pb = NULL;
  19. AVOutputFormat *ofmt = (AVOutputFormat*)av_mallocz( sizeof(AVOutputFormat)); //输出格式
  20. AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
  21. AVPacket pkt;
  22. const char *in_filename, *out_filename;
  23. int ret, i;
  24. in_filename = "nihao.ts"; //源文件
  25. av_register_all();
  26. if ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, 0)) < 0) {
  27. fprintf( stderr, "Could not open input file '%s'", in_filename);
  28. goto end;
  29. }
  30. if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0) {
  31. fprintf( stderr, "Failed to retrieve input stream information");
  32. goto end;
  33. }
  34. av_dump_format(ifmt_ctx, 0, in_filename, 0);
  35. uint8_t* buf = ( uint8_t*)av_mallocz( sizeof( uint8_t)* 32768);
  36. pb = avio_alloc_context(buf, 32768, 0, NULL, NULL, write_packet, NULL); //
  37. avformat_alloc_output_context2(&ofmt_ctx, NULL, "dvd", NULL /*out_filename*/); //设置输出视频的格式为Mpegs-ps,在ffmpeg定义为dvd
  38. if (!ofmt_ctx) {
  39. fprintf( stderr, "Could not create output context\n");
  40. ret = AVERROR_UNKNOWN;
  41. goto end;
  42. }
  43. ofmt_ctx->pb = pb; //这个是关键,指定ps输出的方式
  44. //ofmt_ctx->flags = AVFMT_FLAG_CUSTOM_IO;
  45. //dvd
  46. printf( "output format:%s[%s]\n", ofmt_ctx->oformat->name, ofmt_ctx->oformat->long_name);
  47. ofmt = ofmt_ctx->oformat;
  48. //输出环境上下文的初始化
  49. for (i = 0; i < ifmt_ctx->nb_streams; i++) {
  50. AVStream *in_stream = ifmt_ctx->streams[i];
  51. //Add a new stream to a media file
  52. AVStream *out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);
  53. if (!out_stream) {
  54. fprintf( stderr, "Failed allocating output stream\n");
  55. ret = AVERROR_UNKNOWN;
  56. goto end;
  57. }
  58. ret = avcodec_copy_context(out_stream->codec, in_stream->codec);
  59. if (ret < 0) {
  60. fprintf( stderr, "Failed to copy context from input to output stream codec context\n");
  61. goto end;
  62. }
  63. out_stream->codec->codec_tag = 0;
  64. if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
  65. out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
  66. }
  67. av_dump_format(ofmt_ctx, 0, NULL, 1);
  68. ret = avformat_write_header(ofmt_ctx, NULL);
  69. if (ret < 0) {
  70. fprintf( stderr, "Error occurred when opening output file\n");
  71. goto end;
  72. }
  73. //实现REMUXING
  74. while ( 1) {
  75. AVStream *in_stream, *out_stream;
  76. ret = av_read_frame(ifmt_ctx, &pkt);
  77. if (ret < 0)
  78. break;
  79. in_stream = ifmt_ctx->streams[pkt.stream_index];
  80. out_stream = ofmt_ctx->streams[pkt.stream_index];
  81. pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
  82. pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
  83. pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
  84. pkt.pos = -1;
  85. ret = av_interleaved_write_frame(ofmt_ctx, &pkt);
  86. if (ret < 0) {
  87. fprintf( stderr, "Error muxing packet\n");
  88. break;
  89. }
  90. av_free_packet(&pkt);
  91. }
  92. av_write_trailer(ofmt_ctx);
  93. end:
  94. avformat_close_input(&ifmt_ctx);
  95. /* close output */
  96. if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
  97. avio_close(ofmt_ctx->pb);
  98. avformat_free_context(ofmt_ctx);
  99. if (ret < 0 && ret != AVERROR_EOF) {
  100. return 1;
  101. }
  102. return 0;
  103. }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值