⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 input.c

📁 vlc stand 0.1.99 ist sehr einfach
💻 C
📖 第 1 页 / 共 4 页
字号:
    /* Extract flags values from TS common header. */    b_unit_start = (p[1] & 0x40);    b_adaption = (p[3] & 0x20);    b_payload = (p[3] & 0x10);    /* Extract adaption field informations if any */    if( !b_adaption )    {        /* We don't have any adaptation_field, so payload start immediately           after the 4 byte TS header */        p_ts_packet->i_payload_start = 4;    }    else    {        /* p[4] is adaptation_field_length minus one */        p_ts_packet->i_payload_start = 5 + p[4];        /* The adaption field can be limited to the adaptation_field_length byte,           so that there is nothing to do: skip this possibility */        if( p[4] )        {            /* If the packet has both adaptation_field and payload, adaptation_field               cannot be more than 182 bytes long; if there is only an               adaptation_field, it must fill the next 183 bytes. */            if( b_payload ? (p[4] > 182) : (p[4] != 183) )            {                intf_DbgMsg("input debug: invalid TS adaptation field (%p)\n",                            p_ts_packet);#ifdef STATS                p_es_descriptor->c_invalid_packets++;#endif                b_trash = 1;            }            /* No we are sure that the byte containing flags is present: read it */            else            {                /* discontinuity_indicator */                if( p[5] & 0x80 )                {                    intf_DbgMsg("discontinuity_indicator encountered by TS demux " \                                "(position read: %d, saved: %d)\n", p[5] & 0x80,                                p_es_descriptor->i_continuity_counter);                    /* If the PID carries the PCR, there will be a system time-base                       discontinuity. We let the PCR decoder handle that. */                    p_es_descriptor->b_discontinuity = 1;                    /* There also may be a continuity_counter discontinuity:               resynchronise our counter with the one of the stream */                    p_es_descriptor->i_continuity_counter = (p[3] & 0x0f) - 1;                }                /* random_access_indicator */                p_es_descriptor->b_random |= p[5] & 0x40;                /* If this is a PCR_PID, and this TS packet contains a PCR,           we pass it along to the PCR decoder. */                if( (p_es_descriptor->b_pcr) && (p[5] & 0x10) )                {                    /* There should be a PCR field in the packet, check if the               adaption field is long enough to carry it */                    if( p[4] >= 7 )                    {                        /* Call the PCR decoder */                        input_PcrDecode( p_input, p_es_descriptor, &p[6] );                    }                }            }        }    }    /* Check the continuity of the stream. */    i_dummy = ((p[3] & 0x0f) - p_es_descriptor->i_continuity_counter) & 0x0f;    if( i_dummy == 1 )    {        /* Everything is ok, just increase our counter */        p_es_descriptor->i_continuity_counter++;    }    else    {        if( !b_payload && i_dummy == 0 )        {            /* This is a packet without payload, this is allowed by the draft               As there is nothing interesting in this packet (except PCR that               have already been handled), we can trash the packet. */            intf_DbgMsg("Packet without payload received by TS demux\n");            b_trash = 1;        }        else if( i_dummy <= 0 )        {            /* Duplicate packet: mark it as being to be trashed. */            intf_DbgMsg("Duplicate packet received by TS demux\n");            b_trash = 1;        }        else if( p_es_descriptor->i_continuity_counter == 0xFF )        {            /* This means that the packet is the first one we receive for this               ES since the continuity counter ranges between 0 and 0x0F               excepts when it has been initialized by the input: Init the               counter to the correct value. */            intf_DbgMsg("First packet for PID %d received by TS demux\n",                        p_es_descriptor->i_id);            p_es_descriptor->i_continuity_counter = (p[3] & 0x0f);        }        else        {            /* This can indicate that we missed a packet or that the               continuity_counter wrapped and we received a dup packet: as we               don't know, do as if we missed a packet to be sure to recover               from this situation */            intf_DbgMsg("Packet lost by TS demux: current %d, packet %d\n",                        p_es_descriptor->i_continuity_counter & 0x0f,                        p[3] & 0x0f);            b_lost = 1;            p_es_descriptor->i_continuity_counter = p[3] & 0x0f;        }    }    /* Trash the packet if it has no payload or if it is bad */    if( b_trash )    {        input_NetlistFreeTS( p_input, p_ts_packet );#ifdef STATS        p_input->c_packets_trashed++;#endif    }    else    {        if( p_es_descriptor->b_psi )        {            /* The payload contains PSI tables */            input_DemuxPSI( p_input, p_ts_packet, p_es_descriptor,                            b_unit_start, b_lost );        }        else        {            /* The payload carries a PES stream */            input_DemuxPES( p_input, p_ts_packet, p_es_descriptor,                            b_unit_start, b_lost );        }    }#undef p}/***************************************************************************** * input_DemuxPES: ***************************************************************************** * Gather a PES packet. *****************************************************************************/static __inline__ void input_DemuxPES( input_thread_t *p_input,                                       ts_packet_t *p_ts_packet,                                       es_descriptor_t *p_es_descriptor,                                       boolean_t b_unit_start,                                       boolean_t b_packet_lost ){    int                         i_dummy;    pes_packet_t*               p_last_pes;    ts_packet_t *               p_ts;    int                         i_ts_payload_size;#define p_pes (p_es_descriptor->p_pes_packet)    ASSERT(p_input);    ASSERT(p_ts_packet);    ASSERT(p_es_descriptor);    //intf_DbgMsg("PES-demultiplexing %p (%p)\n", p_ts_packet, p_pes);    /* If we lost data, discard the PES packet we are trying to reassemble       if any and wait for the beginning of a new one in order to synchronise       again */    if( b_packet_lost && p_pes != NULL )    {        intf_DbgMsg("PES %p trashed because of packet lost\n", p_pes);        input_NetlistFreePES( p_input, p_pes );        p_pes = NULL;    }    /* If the TS packet contains the begining of a new PES packet, and if we       were reassembling a PES packet, then the PES should be complete now,       so parse its header and give it to the decoders */    if( b_unit_start && p_pes != NULL )    {        /* Parse the header. The header has a variable length, but in order           to improve the algorithm, we will read the 14 bytes we may be           interested in */        /* If this part of the header did not fit in the current TS packet,           copy the part of the header we are interested in to the           p_pes_header_save buffer. The buffer is dynamicly allocated if           needed so it's time expensive but this situation almost never           occurs. */        p_ts = p_pes->p_first_ts;        i_ts_payload_size = p_ts->i_payload_end - p_ts->i_payload_start;        if(i_ts_payload_size < PES_HEADER_SIZE)        {            intf_DbgMsg("Code never tested encountered, WARNING ! (benny)\n");            if( !p_pes->p_pes_header_save )            {                p_pes->p_pes_header_save = malloc(PES_HEADER_SIZE);            }            i_dummy = 0;            do            {                memcpy(p_pes->p_pes_header_save + i_dummy,                       &p_ts->buffer[p_ts->i_payload_start], i_ts_payload_size);                i_dummy += i_ts_payload_size;                p_ts = p_ts->p_next_ts;                if(!p_ts)                {                  /* The payload of the PES packet is shorter than the 14 bytes                     we would read. This means that high packet lost occured                     so the PES won't be useful for any decoder. Moreover,                     this should never happen so we can trash the packet and                     exit roughly without regrets */                  intf_DbgMsg("PES packet too short: trashed\n");                  input_NetlistFreePES( p_input, p_pes );                  p_pes = NULL;                  /* Stats XXX?? */                  return;                }                i_ts_payload_size = p_ts->i_payload_end - p_ts->i_payload_start;            }            while(i_ts_payload_size + i_dummy < PES_HEADER_SIZE);            /* This last TS packet is partly header, partly payload, so just               copy the header part */            memcpy(p_pes->p_pes_header_save + i_dummy,                   &p_ts->buffer[p_ts->i_payload_start],                   PES_HEADER_SIZE - i_dummy);            /* The header must be read in the buffer not in any TS packet */            p_pes->p_pes_header = p_pes->p_pes_header_save;            /* Get the PES size if defined */            if( (i_dummy = U16_AT(p_pes->p_pes_header + 4)) )            {                p_pes->i_pes_real_size = i_dummy + 6;            }        }        /* Now we have the part of the PES header we were interested in:           p_pes_header and i_pes_real_size ; we can parse it */        input_ParsePES( p_input, p_es_descriptor );    }    /* If we are at the beginning of a new PES packet, we must fetch a new       PES buffer to begin with the reassembly of this PES packet. This is       also here that we can synchronise with the stream if we we lost       packets or if the decoder has just started */    if( b_unit_start )    {        p_last_pes = p_pes;        /* Get a new one PES from the PES netlist. */        if( (p_pes = input_NetlistGetPES( p_input )) == (NULL) )        {            /* PES netlist is empty ! */            p_input->b_error = 1;        }        else        {            //intf_DbgMsg("New PES packet %p (first TS: %p)\n", p_pes, p_ts_packet);            /* Init the PES fields so that the first TS packet could be             * correctly added to the PES packet (see below) */            p_pes->p_first_ts = p_ts_packet;            p_pes->p_last_ts = NULL;            /* If the last pes packet was null, this means that the             * synchronization was lost and so warn the decoder that he             * will have to find a way to recover */            if( !p_last_pes )                p_pes->b_data_loss = 1;            /* Read the b_random_access flag status and then reinit it */            p_pes->b_random_access = p_es_descriptor->b_random;            p_es_descriptor->b_random = 0;        }        /* If the PES header fits in the first TS packet, we can         * already set p_pes->p_pes_header, and in all cases we	 * set p_pes->i_pes_real_size */        if( p_ts_packet->i_payload_end - p_ts_packet->i_payload_start                >= PES_HEADER_SIZE )        {            p_pes->p_pes_header = &(p_ts_packet->buffer[p_ts_packet->i_payload_start]);            if( (i_dummy = U16_AT(p_pes->p_pes_header + 4)) )            {                p_pes->i_pes_real_size = i_dummy + 6;            }        }    }    /* If we are synchronized with the stream, and so if we are ready to       receive correctly the data, add the TS packet to the current PES       packet */    if( p_pes != NULL )    {        //intf_DbgMsg("Adding TS %p to PES %p\n", p_ts_packet, p_pes);        /* Size of the payload carried in the TS packet */        i_ts_payload_size = p_ts_packet->i_payload_end -                            p_ts_packet->i_payload_start;        /* Update the relations between the TS packets */        p_ts_packet->p_prev_ts = p_pes->p_last_ts;        p_ts_packet->p_next_ts = NULL;        if( p_pes->i_ts_packets != 0 )        {            /* Regarder si il serait pas plus efficace de ne creer que             * les liens precedent->suivant pour le moment, et les             * liens suivant->precedent quand le paquet est termine */            /* Otherwise it is the first TS packet. */            p_pes->p_last_ts->p_next_ts = p_ts_packet;        }        /* Now add the TS to the PES packet */        p_pes->p_last_ts = p_ts_packet;        p_pes->i_ts_packets++;        p_pes->i_pes_size += i_ts_payload_size;        /* Stats */#ifdef STATS        i_dummy = p_ts_packet->i_payload_end - p_ts_packet->i_payload_start;        p_es_descriptor->c_payload_bytes += i_dummy;#endif        /* We can check if the packet is finished */        if( p_pes->i_pes_size == p_pes->i_pes_real_size )        {            /* The packet is finished, parse it */            input_ParsePES( p_input, p_es_descriptor );            /* Tell the Demux we have parsed this PES, no need to redo it */            p_pes = NULL;        }    }    else    {        /* Since we don't use the TS packet to build a PES packet, we don't           need it anymore, so give it back to the netlist */        //intf_DbgMsg("Trashing TS %p: no PES being build\n", p_ts_packet);        input_NetlistFreeTS( p_input, p_ts_packet );    }#undef p_pes}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -