/* * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the MPEG TS, PS and ES tools. * * The Initial Developer of the Original Code is Amino Communications Ltd. * Portions created by the Initial Developer are Copyright (C) 2008 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Gareth Bailey (gb@kynesim.co.uk), Kynesim, Cambridge, UK * * ***** END LICENSE BLOCK ***** */ #include #include #include #include #include #include #include #include #define TS_PACKET_SIZE 188 #define DBG_INFO(x) printf x #define TO_BE16(from,to) *to = (0xFF & (from>>8)); *(to+1) = (0xFF & from); static uint8_t *create_out_packet(char *in_data,int in_len,uint16_t pid) { uint8_t *out_packet = malloc(TS_PACKET_SIZE); uint8_t *ptr = out_packet; if (!ptr) return NULL; if (in_len > (TS_PACKET_SIZE - 4)) return NULL; *ptr = 0x47; ptr++; /* Transport Error Indicator */ uint16_t flags = 0<<15; /* Payload Unit Start Indicator */ flags = flags | 0<<14; /* Transport Priority */ flags = flags | 0<<13; uint16_t flags_pid = flags | pid; TO_BE16(flags_pid,ptr); ptr+=2; *ptr = 0x11; ptr++; memcpy(ptr,in_data,in_len); ptr+=in_len; memset(ptr,0xFF,TS_PACKET_SIZE-(ptr-out_packet)); ptr+=TS_PACKET_SIZE-(ptr-out_packet); assert((ptr-TS_PACKET_SIZE) == out_packet); int i; ptr = out_packet; DBG_INFO(("Packet to be written is:\n")); for (i=0;i [switches]\n" "\n" ); printf("\tInsert TS packets into a Transport Stream at a positions " "\n\tspecified by the user.\n\n" ); printf("Input:\n" "\t\t A H.222.0 TS stream.\n\n" ); printf("Switches:\n" "\t-p [positions]\t This a a colon (':') delimited string of numbers\n" "\t\t\t between 0 and 1, representing how far through to put \n" "\t\t\t each ts packet. E.g. -p 0.1:0.4:0.7:0.9 will insert\n" "\t\t\t 4 packets at 10%%, 40%%, 70%% and 90%% through the file.\n" "\n" ); printf("\t-pid [pid]\t The inserted packets will have the pid specfied.\n" "\n" ); printf("\t-s [string]\t The inserted packets will contain [string] as it's\n" "\t\t\t payload.\n" "\n" ); printf("\t-o [output file] The new TS file will be written out to the file\n" "\t\t\t specified. (defaults to out.ts)\n" "\n" ); printf("\t-h (--help) \t This message." "\n\n" ); printf("Example:\n" "\tts_packet_insert -p 0.3:0.6 -o out.ts -pid 89 -s \"AD=start\" in.ts" "\n\n" ); } /* bubble sort */ static void sort_positions(double *in_array,int size) { int sorted=0; while (!sorted) { int i; /* asume sorted */ sorted++; for (i=0;iin_array[i+1]) { double tmp; tmp = in_array[i]; in_array[i] = in_array[i+1]; in_array[i+1] = tmp; /* damn, go round again */ sorted=0; } } } } int main(int argc, char **argv) { char *output_file_path = "./__out.ts"; char *in_file_path = NULL; long in_file_size=0; /*an array of floats for the positions of packets to insert,valuse of 0-1*/ double *positions=NULL; int *packet_numbers=NULL; int n_pos = 0; int argno = 1; int arg_counter = 0; int pid=0; char * out_string=NULL; if (argc < 2) { print_usage(); return 0; } while (argno < argc) { if (argv[argno][0] == '-') { if (!strcmp("-p",argv[argno])) { char *endptr; ++argno; free(positions); n_pos = (num_char_in_string(argv[argno],':')+1); positions = malloc(n_pos * sizeof(double)); if (!positions) { fprintf(stderr,"malloc failed"); exit(1); } char * position_string = strtok(argv[argno],":"); int pos_index=0; DBG_INFO(("Adding new packets at\n")); while(1) { if(!position_string) break; positions[pos_index] = strtod(position_string,&endptr); if (endptr == position_string || positions[pos_index]>1 || positions[pos_index]<0) { fprintf(stderr,"\nNot a valid floating point number for position (argument %d)\n",argno); exit(1); } DBG_INFO(("\t%d%%\n",(int)(positions[pos_index]*100))); position_string = strtok(NULL,":"); pos_index++; } DBG_INFO(("\n")); sort_positions(positions,n_pos); assert(pos_index == n_pos); } else if (!strcmp("-pid",argv[argno])) { pid = atoi(argv[++argno]); DBG_INFO(("Will insert packets with a pid of 0x%x\n",pid)); } else if (!strcmp("-o",argv[argno])) { output_file_path = argv[++argno]; } else if (!strcmp("-s",argv[argno])) { out_string = argv[++argno]; DBG_INFO(("Output string will be:\t%s\n",out_string)); } else if (!strcmp("-h",argv[argno]) || !strcmp("--help",argv[argno])) { print_usage(); return 0; } else { DBG_INFO(("\n *** Unknown option %s, ignoring.\n\n",argv[argno])); } } else { if (arg_counter == 0) { in_file_path = argv[argno]; arg_counter++; } } argno++; } if (!in_file_path) { fprintf(stderr,"Error: No input file specified.\n"); exit(1); } DBG_INFO(("Writing to file: \t%s\n",output_file_path)); DBG_INFO(("Reading from: \t\t%s\n",in_file_path)); { /* open files*/ int in_file = open(in_file_path,O_RDONLY); int out_file = open(output_file_path,O_WRONLY | O_TRUNC | O_CREAT,0644); if (in_file<0) { fprintf(stderr,"Error: couldn't open %s for reading\n",in_file_path); exit(1); } if (out_file<0) { fprintf(stderr,"Error: couldn't open %s for reading\n",output_file_path); exit(1); } in_file_size = get_file_size(in_file); if (in_file_size % TS_PACKET_SIZE) { fprintf(stderr,"Error: ts file length is not a multiple of 188 bytes\n"); exit(1); } { int num_pack = in_file_size / TS_PACKET_SIZE; int i; DBG_INFO(("\nIn file is %ld bytes long with ",in_file_size)); DBG_INFO(("%d TS packets\n",num_pack)); packet_numbers = malloc(n_pos * sizeof(int)); /* Find out which packets we insert before */ for (i=0;i