Beispiel #1
0
/*****************************************************************************
 * handle_psi_packet
 *****************************************************************************/
static void handle_psi_packet(uint8_t *p_ts)
{
    uint16_t i_pid = ts_get_pid(p_ts);
    ts_pid_t *p_pid = &p_pids[i_pid];
    uint8_t i_cc = ts_get_cc(p_ts);
    const uint8_t *p_payload;
    uint8_t i_length;

    if (ts_check_duplicate(i_cc, p_pid->i_last_cc) || !ts_has_payload(p_ts))
        return;

    if (p_pid->i_last_cc != -1
          && ts_check_discontinuity(i_cc, p_pid->i_last_cc))
        psi_assemble_reset(&p_pid->p_psi_buffer, &p_pid->i_psi_buffer_used);

    p_payload = ts_section(p_ts);
    i_length = p_ts + TS_SIZE - p_payload;

    if (!psi_assemble_empty(&p_pid->p_psi_buffer, &p_pid->i_psi_buffer_used)) {
        uint8_t *p_section = psi_assemble_payload(&p_pid->p_psi_buffer,
                                                  &p_pid->i_psi_buffer_used,
                                                  &p_payload, &i_length);
        if (p_section != NULL)
            handle_section(i_pid, p_section);
    }

    p_payload = ts_next_section( p_ts );
    i_length = p_ts + TS_SIZE - p_payload;

    while (i_length) {
        uint8_t *p_section = psi_assemble_payload(&p_pid->p_psi_buffer,
                                                  &p_pid->i_psi_buffer_used,
                                                  &p_payload, &i_length);
        if (p_section != NULL)
            handle_section(i_pid, p_section);
    }
}
Beispiel #2
0
int mediainfo (char *uri)
{
    int i;
    struct sockaddr_in si_other;
    struct ip_mreq group;
    int s, slen = sizeof (si_other);
    char *server;
    int port;
    time_t start_time;

    if (strncmp (uri, "udp://", 6) != 0) {
        exit (1);
    }
    server = uri + 6;
    for (i = 6; i < strlen (uri); i++) {
        if (*(uri + i) == ':') {
            *(uri + i) = '\0';
        }
        port = atoi (uri + i + 1);
    }
    if (i == strlen (uri)) {
        exit (1);
    }
    setvbuf(stdout, NULL, _IOLBF, 0);
    memset(p_pids, 0, sizeof(p_pids));

    if ((s = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
        exit (1);
    }

    if (is_multicast (uri) == 1) {
        int reuse = 1;
        if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) < 0){
            perror("Setting SO_REUSEADDR error");
            close(s);
            exit(1);
        }
    }

    memset ((char *)&si_other, 0, sizeof (si_other));
    si_other.sin_family = AF_INET;
    si_other.sin_port = htons (port);
    if (is_multicast (uri) == 1) {
        si_other.sin_addr.s_addr = INADDR_ANY;
    } else {
        if (inet_aton (server, &si_other.sin_addr) == 0) {
            exit (1);
        }    
    }
    if (bind (s, (struct sockaddr *)&si_other, sizeof (si_other)) == -1) {
        exit (1);
    }

    if (is_multicast (uri) == 1) {
        group.imr_multiaddr.s_addr = inet_addr(server);
        //group.imr_interface.s_addr = inet_addr("172.16.0.10");
        if(setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&group, sizeof(group)) < 0){
            perror("Adding multicast group error");
            close(s);
            exit(1);
        }
    }

    for (i = 0; i < 8192; i++) {
        p_pids[i].i_last_cc = -1;
        psi_assemble_init(&p_pids[i].p_psi_buffer,
                          &p_pids[i].i_psi_buffer_used);
    }

    p_pids[PAT_PID].i_psi_refcount++;
    p_pids[TSDT_PID].i_psi_refcount++;
    p_pids[NIT_PID].i_psi_refcount++;
    p_pids[SDT_PID].i_psi_refcount++;

    psi_table_init(pp_current_pat_sections);
    psi_table_init(pp_next_pat_sections);
    psi_table_init(pp_current_tsdt_sections);
    psi_table_init(pp_next_tsdt_sections);
    psi_table_init(pp_current_nit_sections);
    psi_table_init(pp_next_nit_sections);
    psi_table_init(pp_current_sdt_sections);
    psi_table_init(pp_next_sdt_sections);
    for (i = 0; i < TABLE_END; i++)
        pb_print_table[i] = true;

    printf("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
    printf("<TS>\n");

    start_time = time (NULL);
    while (got_pmt == 0) {
        uint8_t p_ts[TS_SIZE*10];
        uint8_t *p;
        size_t i_ret = recvfrom (s, p_ts, sizeof (p_ts), MSG_CMSG_CLOEXEC | MSG_DONTWAIT, (struct sockaddr *)&si_other, &slen);
        if (i_ret == -1) {
            usleep (10000);
        }

        p = p_ts;
        while (p < p_ts + i_ret) {
            if (!ts_validate(p)) {
                printf("<ERROR type=\"invalid_ts\"/>\n");
            } else {
                uint16_t i_pid = ts_get_pid(p);
                ts_pid_t *p_pid = &p_pids[i_pid];
                if (p_pid->i_psi_refcount)
                    handle_psi_packet(p);
                p_pid->i_last_cc = ts_get_cc(p);
            }
            p = p + TS_SIZE;
        }
        if (difftime (time (NULL), start_time) > 60) {
            printf ("Timeout\n");
            break;
        }
    }

    printf("</TS>\n");

    if (iconv_handle != (iconv_t)-1)
    iconv_close(iconv_handle);

    psi_table_free(pp_current_pat_sections);
    psi_table_free(pp_next_pat_sections);
    psi_table_free(pp_current_tsdt_sections);
    psi_table_free(pp_next_tsdt_sections);
    psi_table_free(pp_current_nit_sections);
    psi_table_free(pp_next_nit_sections);
    psi_table_free(pp_current_sdt_sections);
    psi_table_free(pp_next_sdt_sections);

    for (i = 0; i < i_nb_sids; i++) {
        psi_table_free(pp_sids[i]->pp_eit_sections);
        free(pp_sids[i]->p_current_pmt);
        free(pp_sids[i]);
    }
    free(pp_sids);

    for (i = 0; i < 8192; i++)
        psi_assemble_reset(&p_pids[i].p_psi_buffer,
                           &p_pids[i].i_psi_buffer_used);

    close (s);
    return EXIT_SUCCESS;
}
Beispiel #3
0
int main(int i_argc, char **ppsz_argv)
{   
    int c;
    FILE *inputfile=stdin;
    FILE *outputfile=stdout;
    int offset=12, pid=0x0426;
    int i_last_cc = -1;
    
    static const struct option long_options[] = {
        { "pid",           required_argument, NULL, 'p' },
        { "offset",            required_argument,       NULL, 's' },
        { "input",         required_argument,       NULL, 'i' },
        { "output",          required_argument,       NULL, 'o' },
        { 0, 0, 0, 0 }
    };
    
    while ((c = getopt_long(i_argc, ppsz_argv, "p:s:i:o:h", long_options, NULL)) != -1)
    {
        switch (c) {
        case 'p':
            pid=strtoul(optarg, NULL, 0);
            if(pid >= 8192) {
                ERROR("bad pid value: %d!", pid);
                exit(1);
            }
            break;

        case 's':
            offset=strtol(optarg, NULL, 0);
            if(offset >= 184 || offset <= -4) {
                ERROR("bad offset value: %d!", offset);
                exit(1);
            }
            break;

        case 'i':
            inputfile = fopen(optarg, "r");
            if(!inputfile) {
                ERROR("cant open input file!");
                exit(1);
            }
            break;

        case 'o':
            outputfile = fopen(optarg, "w");
            if(!outputfile) {
                ERROR("cant open output file!");
                exit(1);
            }
            break;


        case 'h':
        default:
            usage(ppsz_argv[0]);
        }
    }


    INFO("Using pid: 0x%04x (%d)", pid, pid);
    unsigned long int packets=0;
    while (!feof(inputfile) && !ferror(inputfile)) {
        uint8_t p_ts[TS_SIZE];
        size_t i_ret = fread(p_ts, TS_SIZE, 1, inputfile);
        if (i_ret != 1) {
        	WARN("Can't read input ts");
        	break;
        }
        if (ts_validate(p_ts)) {
            if(offset >= 0 &&  ts_get_pid(p_ts)==pid) {
            	if(i_last_cc > 0 && (0x0f & (i_last_cc+1)) != ts_get_cc(p_ts)) {
            		WARN("TS Discontinuity");
            	}
            	i_last_cc = ts_get_cc(p_ts);
            	uint8_t *payload = ts_payload(p_ts);
            	if(offset) {
            		payload+=offset;
            	}

            	if(p_ts+TS_SIZE < payload) {
                	ERROR("payload is out of ts by %ld bytes", payload-p_ts+TS_SIZE);
                	break;
            	}

            	size_t o_ret = fwrite(payload, p_ts+TS_SIZE-payload, 1, outputfile);
                if (o_ret != 1) {
                	WARN("Can't write output ts");
                	break;
                }
                packets++;
            } else if(offset < 0) {
            	uint8_t *payload = &p_ts[TS_HEADER_SIZE + offset];
            	if(p_ts+TS_SIZE < payload || p_ts > payload) {
                	ERROR("payload is out of ts by %ld bytes", payload-p_ts+TS_SIZE);
                	break;
            	}

            	size_t o_ret = fwrite(payload, p_ts+TS_SIZE-payload, 1, outputfile);
                if (o_ret != 1) {
                	WARN("Can't write output ts");
                	break;
                }
                packets++;
            }
        } else {
            do {
                memmove(p_ts, &p_ts[1], TS_SIZE-1);
                size_t i_ret = fread(&p_ts[TS_SIZE-1], 1, 1, inputfile);
                if (i_ret != 1) {
                	WARN("Can't read input ts");
                	break;
                }
            } while (!ts_validate(p_ts) && !feof(inputfile) && !ferror(inputfile));
        }
    }

    if(packets){
    	INFO("Successfuly readed %ld ts-packets", packets);
    }


//mainErr:
    fclose(inputfile);
    fclose(outputfile);
    return 0;
}