pktdumper.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /*
  2. * Copyright (c) 2005 Francois Revol
  3. *
  4. * This file is part of FFmpeg.
  5. *
  6. * FFmpeg is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * FFmpeg is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with FFmpeg; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #include "config.h"
  21. #include <limits.h>
  22. #include <fcntl.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #if HAVE_UNISTD_H
  27. #include <unistd.h>
  28. #endif
  29. #if HAVE_IO_H
  30. #include <io.h>
  31. #endif
  32. #include "libavutil/avstring.h"
  33. #include "libavutil/time.h"
  34. #include "libavformat/avformat.h"
  35. #define FILENAME_BUF_SIZE 4096
  36. #define PKTFILESUFF "_%08" PRId64 "_%02d_%010" PRId64 "_%06d_%c.bin"
  37. static int usage(int ret)
  38. {
  39. fprintf(stderr, "Dump (up to maxpkts) AVPackets as they are demuxed by libavformat.\n");
  40. fprintf(stderr, "Each packet is dumped in its own file named like\n");
  41. fprintf(stderr, "$(basename file.ext)_$PKTNUM_$STREAMINDEX_$STAMP_$SIZE_$FLAGS.bin\n");
  42. fprintf(stderr, "pktdumper [-nw] file [maxpkts]\n");
  43. fprintf(stderr, "-n\twrite No file at all, only demux.\n");
  44. fprintf(stderr, "-w\tWait at end of processing instead of quitting.\n");
  45. return ret;
  46. }
  47. int main(int argc, char **argv)
  48. {
  49. char fntemplate[FILENAME_BUF_SIZE];
  50. char pktfilename[FILENAME_BUF_SIZE];
  51. AVFormatContext *fctx = NULL;
  52. AVPacket *pkt;
  53. int64_t pktnum = 0;
  54. int64_t maxpkts = 0;
  55. int donotquit = 0;
  56. int nowrite = 0;
  57. int err;
  58. if ((argc > 1) && !strncmp(argv[1], "-", 1)) {
  59. if (strchr(argv[1], 'w'))
  60. donotquit = 1;
  61. if (strchr(argv[1], 'n'))
  62. nowrite = 1;
  63. argv++;
  64. argc--;
  65. }
  66. if (argc < 2)
  67. return usage(1);
  68. if (argc > 2)
  69. maxpkts = atoi(argv[2]);
  70. av_strlcpy(fntemplate, argv[1], sizeof(fntemplate));
  71. if (strrchr(argv[1], '/'))
  72. av_strlcpy(fntemplate, strrchr(argv[1], '/') + 1, sizeof(fntemplate));
  73. if (strrchr(fntemplate, '.'))
  74. *strrchr(fntemplate, '.') = '\0';
  75. if (strchr(fntemplate, '%')) {
  76. fprintf(stderr, "cannot use filenames containing '%%'\n");
  77. return usage(1);
  78. }
  79. if (strlen(fntemplate) + sizeof(PKTFILESUFF) >= sizeof(fntemplate) - 1) {
  80. fprintf(stderr, "filename too long\n");
  81. return usage(1);
  82. }
  83. strcat(fntemplate, PKTFILESUFF);
  84. printf("FNTEMPLATE: '%s'\n", fntemplate);
  85. err = avformat_open_input(&fctx, argv[1], NULL, NULL);
  86. if (err < 0) {
  87. fprintf(stderr, "cannot open input: error %d\n", err);
  88. return 1;
  89. }
  90. err = avformat_find_stream_info(fctx, NULL);
  91. if (err < 0) {
  92. fprintf(stderr, "avformat_find_stream_info: error %d\n", err);
  93. return 1;
  94. }
  95. pkt = av_packet_alloc();
  96. if (!pkt) {
  97. fprintf(stderr, "av_packet_alloc: error %d\n", AVERROR(ENOMEM));
  98. return 1;
  99. }
  100. while ((err = av_read_frame(fctx, pkt)) >= 0) {
  101. int fd;
  102. snprintf(pktfilename, sizeof(pktfilename), fntemplate, pktnum,
  103. pkt->stream_index, pkt->pts, pkt->size,
  104. (pkt->flags & AV_PKT_FLAG_KEY) ? 'K' : '_');
  105. printf(PKTFILESUFF "\n", pktnum, pkt->stream_index, pkt->pts, pkt->size,
  106. (pkt->flags & AV_PKT_FLAG_KEY) ? 'K' : '_');
  107. if (!nowrite) {
  108. fd = open(pktfilename, O_WRONLY | O_CREAT, 0644);
  109. err = write(fd, pkt->data, pkt->size);
  110. if (err < 0) {
  111. fprintf(stderr, "write: error %d\n", err);
  112. return 1;
  113. }
  114. close(fd);
  115. }
  116. av_packet_unref(pkt);
  117. pktnum++;
  118. if (maxpkts && (pktnum >= maxpkts))
  119. break;
  120. }
  121. av_packet_free(&pkt);
  122. avformat_close_input(&fctx);
  123. while (donotquit)
  124. av_usleep(60 * 1000000);
  125. return 0;
  126. }