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 21#include "config.h" 22#include <limits.h> 23#include <fcntl.h> 24#include <stdio.h> 25#include <stdlib.h> 26#include <string.h> 27#if HAVE_UNISTD_H 28#include <unistd.h> 29#endif 30#if HAVE_IO_H 31#include <io.h> 32#endif 33 34#include "libavutil/avstring.h" 35#include "libavutil/time.h" 36#include "libavformat/avformat.h" 37 38#define FILENAME_BUF_SIZE 4096 39#define PKTFILESUFF "_%08" PRId64 "_%02d_%010" PRId64 "_%06d_%c.bin" 40 41static int usage(int ret) 42{ 43 fprintf(stderr, "Dump (up to maxpkts) AVPackets as they are demuxed by libavformat.\n"); 44 fprintf(stderr, "Each packet is dumped in its own file named like\n"); 45 fprintf(stderr, "$(basename file.ext)_$PKTNUM_$STREAMINDEX_$STAMP_$SIZE_$FLAGS.bin\n"); 46 fprintf(stderr, "pktdumper [-nw] file [maxpkts]\n"); 47 fprintf(stderr, "-n\twrite No file at all, only demux.\n"); 48 fprintf(stderr, "-w\tWait at end of processing instead of quitting.\n"); 49 return ret; 50} 51 52int main(int argc, char **argv) 53{ 54 char fntemplate[FILENAME_BUF_SIZE]; 55 char pktfilename[FILENAME_BUF_SIZE]; 56 AVFormatContext *fctx = NULL; 57 AVPacket pkt; 58 int64_t pktnum = 0; 59 int64_t maxpkts = 0; 60 int donotquit = 0; 61 int nowrite = 0; 62 int err; 63 64 if ((argc > 1) && !strncmp(argv[1], "-", 1)) { 65 if (strchr(argv[1], 'w')) 66 donotquit = 1; 67 if (strchr(argv[1], 'n')) 68 nowrite = 1; 69 argv++; 70 argc--; 71 } 72 if (argc < 2) 73 return usage(1); 74 if (argc > 2) 75 maxpkts = atoi(argv[2]); 76 av_strlcpy(fntemplate, argv[1], sizeof(fntemplate)); 77 if (strrchr(argv[1], '/')) 78 av_strlcpy(fntemplate, strrchr(argv[1], '/') + 1, sizeof(fntemplate)); 79 if (strrchr(fntemplate, '.')) 80 *strrchr(fntemplate, '.') = '\0'; 81 if (strchr(fntemplate, '%')) { 82 fprintf(stderr, "cannot use filenames containing '%%'\n"); 83 return usage(1); 84 } 85 if (strlen(fntemplate) + sizeof(PKTFILESUFF) >= sizeof(fntemplate) - 1) { 86 fprintf(stderr, "filename too long\n"); 87 return usage(1); 88 } 89 strcat(fntemplate, PKTFILESUFF); 90 printf("FNTEMPLATE: '%s'\n", fntemplate); 91 92 // register all file formats 93 av_register_all(); 94 95 err = avformat_open_input(&fctx, argv[1], NULL, NULL); 96 if (err < 0) { 97 fprintf(stderr, "cannot open input: error %d\n", err); 98 return 1; 99 } 100 101 err = avformat_find_stream_info(fctx, NULL); 102 if (err < 0) { 103 fprintf(stderr, "avformat_find_stream_info: error %d\n", err); 104 return 1; 105 } 106 107 av_init_packet(&pkt); 108 109 while ((err = av_read_frame(fctx, &pkt)) >= 0) { 110 int fd; 111 snprintf(pktfilename, sizeof(pktfilename), fntemplate, pktnum, 112 pkt.stream_index, pkt.pts, pkt.size, 113 (pkt.flags & AV_PKT_FLAG_KEY) ? 'K' : '_'); 114 printf(PKTFILESUFF "\n", pktnum, pkt.stream_index, pkt.pts, pkt.size, 115 (pkt.flags & AV_PKT_FLAG_KEY) ? 'K' : '_'); 116 if (!nowrite) { 117 fd = open(pktfilename, O_WRONLY | O_CREAT, 0644); 118 err = write(fd, pkt.data, pkt.size); 119 if (err < 0) { 120 fprintf(stderr, "write: error %d\n", err); 121 return 1; 122 } 123 close(fd); 124 } 125 av_free_packet(&pkt); 126 pktnum++; 127 if (maxpkts && (pktnum >= maxpkts)) 128 break; 129 } 130 131 avformat_close_input(&fctx); 132 133 while (donotquit) 134 av_usleep(60 * 1000000); 135 136 return 0; 137} 138