static int hevc_handle_packet(AVFormatContext *ctx, PayloadContext *rtp_hevc_ctx,

                              AVStream *st, AVPacket *pkt, uint32_t *timestamp,

                              const uint8_t *buf, int len, uint16_t seq,

                              int flags)

{

    const uint8_t *rtp_pl = buf;

    int tid, lid, nal_type;

    int first_fragment, last_fragment, fu_type;

    uint8_t new_nal_header[2];

    int res = 0;



    /* sanity check for size of input packet: 1 byte payload at least */

    if (len < RTP_HEVC_PAYLOAD_HEADER_SIZE + 1) {

        av_log(ctx, AV_LOG_ERROR, "Too short RTP/HEVC packet, got %d bytes\n", len);

        return AVERROR_INVALIDDATA;

    }



    /*

      decode the HEVC payload header according to section 4 of draft version 6:



         0                   1

         0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5

        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

        |F|   Type    |  LayerId  | TID |

        +-------------+-----------------+



           Forbidden zero (F): 1 bit

           NAL unit type (Type): 6 bits

           NUH layer ID (LayerId): 6 bits

           NUH temporal ID plus 1 (TID): 3 bits

    */

    nal_type =  (buf[0] >> 1) & 0x3f;

    lid  = ((buf[0] << 5) & 0x20) | ((buf[1] >> 3) & 0x1f);

    tid  =   buf[1] & 0x07;



    /* sanity check for correct layer ID */

    if (lid) {

        /* future scalable or 3D video coding extensions */

        avpriv_report_missing_feature(ctx, "Multi-layer HEVC coding\n");

        return AVERROR_PATCHWELCOME;

    }



    /* sanity check for correct temporal ID */

    if (!tid) {

        av_log(ctx, AV_LOG_ERROR, "Illegal temporal ID in RTP/HEVC packet\n");

        return AVERROR_INVALIDDATA;

    }



    /* sanity check for correct NAL unit type */

    if (nal_type > 50) {

        av_log(ctx, AV_LOG_ERROR, "Unsupported (HEVC) NAL type (%d)\n", nal_type);

        return AVERROR_INVALIDDATA;

    }



    switch (nal_type) {

    /* aggregated packets (AP) */

    case 48:

        /* pass the HEVC payload header */

        buf += RTP_HEVC_PAYLOAD_HEADER_SIZE;

        len -= RTP_HEVC_PAYLOAD_HEADER_SIZE;



        /* pass the HEVC DONL field */

        if (rtp_hevc_ctx->using_donl_field) {

            buf += RTP_HEVC_DONL_FIELD_SIZE;

            len -= RTP_HEVC_DONL_FIELD_SIZE;

        }



        /* fall-through */

    /* video parameter set (VPS) */

    case 32:

    /* sequence parameter set (SPS) */

    case 33:

    /* picture parameter set (PPS) */

    case 34:

    /*  supplemental enhancement information (SEI) */

    case 39:

    /* single NAL unit packet */

    default:

        /* sanity check for size of input packet: 1 byte payload at least */

        if (len < 1) {

            av_log(ctx, AV_LOG_ERROR,

                   "Too short RTP/HEVC packet, got %d bytes of NAL unit type %d\n",

                   len, nal_type);

            return AVERROR_INVALIDDATA;

        }



        /* create A/V packet */

        if ((res = av_new_packet(pkt, sizeof(start_sequence) + len)) < 0)

            return res;

        /* A/V packet: copy start sequence */

        memcpy(pkt->data, start_sequence, sizeof(start_sequence));

        /* A/V packet: copy NAL unit data */

        memcpy(pkt->data + sizeof(start_sequence), buf, len);



        break;

    /* fragmentation unit (FU) */

    case 49:

        /* pass the HEVC payload header */

        buf += RTP_HEVC_PAYLOAD_HEADER_SIZE;

        len -= RTP_HEVC_PAYLOAD_HEADER_SIZE;



        if (len < 1)

            return AVERROR_INVALIDDATA;

        /*

             decode the FU header



              0 1 2 3 4 5 6 7

             +-+-+-+-+-+-+-+-+

             |S|E|  FuType   |

             +---------------+



                Start fragment (S): 1 bit

                End fragment (E): 1 bit

                FuType: 6 bits

        */

        first_fragment = buf[0] & 0x80;

        last_fragment  = buf[0] & 0x40;

        fu_type        = buf[0] & 0x3f;



        /* pass the HEVC FU header */

        buf += RTP_HEVC_FU_HEADER_SIZE;

        len -= RTP_HEVC_FU_HEADER_SIZE;



        /* pass the HEVC DONL field */

        if (rtp_hevc_ctx->using_donl_field) {

            buf += RTP_HEVC_DONL_FIELD_SIZE;

            len -= RTP_HEVC_DONL_FIELD_SIZE;

        }



        av_dlog(ctx, " FU type %d with %d bytes\n", fu_type, len);



        if (len > 0) {

            new_nal_header[0] = (rtp_pl[0] & 0x81) | (fu_type << 1);

            new_nal_header[1] = rtp_pl[1];



            /* start fragment vs. subsequent fragments */

            if (first_fragment) {

                if (!last_fragment) {

                    /* create A/V packet which is big enough */

                    if ((res = av_new_packet(pkt, sizeof(start_sequence) + sizeof(new_nal_header) + len)) < 0)

                        return res;

                    /* A/V packet: copy start sequence */

                    memcpy(pkt->data, start_sequence, sizeof(start_sequence));

                    /* A/V packet: copy new NAL header */

                    memcpy(pkt->data + sizeof(start_sequence), new_nal_header, sizeof(new_nal_header));

                    /* A/V packet: copy NAL unit data */

                    memcpy(pkt->data + sizeof(start_sequence) + sizeof(new_nal_header), buf, len);

                } else {

                    av_log(ctx, AV_LOG_ERROR, "Illegal combination of S and E bit in RTP/HEVC packet\n");

                    res = AVERROR_INVALIDDATA;

                }

            } else {

                /* create A/V packet */

                if ((res = av_new_packet(pkt, len)) < 0)

                    return res;

                /* A/V packet: copy NAL unit data */

                memcpy(pkt->data, buf, len);

            }

        } else {

            /* sanity check for size of input packet: 1 byte payload at least */

            av_log(ctx, AV_LOG_ERROR,

                   "Too short RTP/HEVC packet, got %d bytes of NAL unit type %d\n",

                   len, nal_type);

            res = AVERROR_INVALIDDATA;

        }



        break;

    /* PACI packet */

    case 50:

        /* Temporal scalability control information (TSCI) */

        avpriv_report_missing_feature(ctx, "PACI packets for RTP/HEVC\n");

        res = AVERROR_PATCHWELCOME;

        break;

    }



    pkt->stream_index = st->index;



    return res;

}

static int hevc_handle_packet(AVFormatContext *ctx, PayloadContext *rtp_hevc_ctx,

                              AVStream *st, AVPacket *pkt, uint32_t *timestamp,

                              const uint8_t *buf, int len, uint16_t seq,

                              int flags)

{

    const uint8_t *rtp_pl = buf;

    int tid, lid, nal_type;

    int first_fragment, last_fragment, fu_type;

    uint8_t new_nal_header[2];

    int res = 0;



    

    if (len < RTP_HEVC_PAYLOAD_HEADER_SIZE + 1) {

        av_log(ctx, AV_LOG_ERROR, "Too short RTP/HEVC packet, got %d bytes\n", len);

        return AVERROR_INVALIDDATA;

    }



    



























    nal_type =  (buf[0] >> 1) & 0x3f;

    lid  = ((buf[0] << 5) & 0x20) | ((buf[1] >> 3) & 0x1f);

    tid  =   buf[1] & 0x07;



    

    if (lid) {

        

        avpriv_report_missing_feature(ctx, "Multi-layer HEVC coding\n");

        return AVERROR_PATCHWELCOME;

    }



    

    if (!tid) {

        av_log(ctx, AV_LOG_ERROR, "Illegal temporal ID in RTP/HEVC packet\n");

        return AVERROR_INVALIDDATA;

    }



    

    if (nal_type > 50) {

        av_log(ctx, AV_LOG_ERROR, "Unsupported (HEVC) NAL type (%d)\n", nal_type);

        return AVERROR_INVALIDDATA;

    }



    switch (nal_type) {

    

    case 48:

        

        buf += RTP_HEVC_PAYLOAD_HEADER_SIZE;

        len -= RTP_HEVC_PAYLOAD_HEADER_SIZE;



        

        if (rtp_hevc_ctx->using_donl_field) {

            buf += RTP_HEVC_DONL_FIELD_SIZE;

            len -= RTP_HEVC_DONL_FIELD_SIZE;

        }



        

    

    case 32:

    

    case 33:

    

    case 34:

    

    case 39:

    

    default:

        

        if (len < 1) {

            av_log(ctx, AV_LOG_ERROR,

                   "Too short RTP/HEVC packet, got %d bytes of NAL unit type %d\n",

                   len, nal_type);

            return AVERROR_INVALIDDATA;

        }



        

        if ((res = av_new_packet(pkt, sizeof(start_sequence) + len)) < 0)

            return res;

        

        memcpy(pkt->data, start_sequence, sizeof(start_sequence));

        

        memcpy(pkt->data + sizeof(start_sequence), buf, len);



        break;

    

    case 49:

        

        buf += RTP_HEVC_PAYLOAD_HEADER_SIZE;

        len -= RTP_HEVC_PAYLOAD_HEADER_SIZE;



        if (len < 1)

            return AVERROR_INVALIDDATA;

        























        first_fragment = buf[0] & 0x80;

        last_fragment  = buf[0] & 0x40;

        fu_type        = buf[0] & 0x3f;



        

        buf += RTP_HEVC_FU_HEADER_SIZE;

        len -= RTP_HEVC_FU_HEADER_SIZE;



        

        if (rtp_hevc_ctx->using_donl_field) {

            buf += RTP_HEVC_DONL_FIELD_SIZE;

            len -= RTP_HEVC_DONL_FIELD_SIZE;

        }



        av_dlog(ctx, " FU type %d with %d bytes\n", fu_type, len);



        if (len > 0) {

            new_nal_header[0] = (rtp_pl[0] & 0x81) | (fu_type << 1);

            new_nal_header[1] = rtp_pl[1];



            

            if (first_fragment) {

                if (!last_fragment) {

                    

                    if ((res = av_new_packet(pkt, sizeof(start_sequence) + sizeof(new_nal_header) + len)) < 0)

                        return res;

                    

                    memcpy(pkt->data, start_sequence, sizeof(start_sequence));

                    

                    memcpy(pkt->data + sizeof(start_sequence), new_nal_header, sizeof(new_nal_header));

                    

                    memcpy(pkt->data + sizeof(start_sequence) + sizeof(new_nal_header), buf, len);

                } else {

                    av_log(ctx, AV_LOG_ERROR, "Illegal combination of S and E bit in RTP/HEVC packet\n");

                    res = AVERROR_INVALIDDATA;

                }

            } else {

                

                if ((res = av_new_packet(pkt, len)) < 0)

                    return res;

                

                memcpy(pkt->data, buf, len);

            }

        } else {

            

            av_log(ctx, AV_LOG_ERROR,

                   "Too short RTP/HEVC packet, got %d bytes of NAL unit type %d\n",

                   len, nal_type);

            res = AVERROR_INVALIDDATA;

        }



        break;

    

    case 50:

        

        avpriv_report_missing_feature(ctx, "PACI packets for RTP/HEVC\n");

        res = AVERROR_PATCHWELCOME;

        break;

    }



    pkt->stream_index = st->index;



    return res;

}

static int FUNC_0(AVFormatContext *VAR_0, PayloadContext *VAR_1,

                              AVStream *VAR_2, AVPacket *VAR_3, uint32_t *VAR_4,

                              const uint8_t *VAR_5, int VAR_6, uint16_t VAR_7,

                              int VAR_8)

{

    const uint8_t *VAR_9 = VAR_5;

    int VAR_10, VAR_11, VAR_12;

    int VAR_13, VAR_14, VAR_15;

    uint8_t new_nal_header[2];

    int VAR_16 = 0;



    

    if (VAR_6 < RTP_HEVC_PAYLOAD_HEADER_SIZE + 1) {

        av_log(VAR_0, AV_LOG_ERROR, "Too short RTP/HEVC packet, got %d bytes\n", VAR_6);

        return AVERROR_INVALIDDATA;

    }



    



























    VAR_12 =  (VAR_5[0] >> 1) & 0x3f;

    VAR_11  = ((VAR_5[0] << 5) & 0x20) | ((VAR_5[1] >> 3) & 0x1f);

    VAR_10  =   VAR_5[1] & 0x07;



    

    if (VAR_11) {

        

        avpriv_report_missing_feature(VAR_0, "Multi-layer HEVC coding\n");

        return AVERROR_PATCHWELCOME;

    }



    

    if (!VAR_10) {

        av_log(VAR_0, AV_LOG_ERROR, "Illegal temporal ID in RTP/HEVC packet\n");

        return AVERROR_INVALIDDATA;

    }



    

    if (VAR_12 > 50) {

        av_log(VAR_0, AV_LOG_ERROR, "Unsupported (HEVC) NAL type (%d)\n", VAR_12);

        return AVERROR_INVALIDDATA;

    }



    switch (VAR_12) {

    

    case 48:

        

        VAR_5 += RTP_HEVC_PAYLOAD_HEADER_SIZE;

        VAR_6 -= RTP_HEVC_PAYLOAD_HEADER_SIZE;



        

        if (VAR_1->using_donl_field) {

            VAR_5 += RTP_HEVC_DONL_FIELD_SIZE;

            VAR_6 -= RTP_HEVC_DONL_FIELD_SIZE;

        }



        

    

    case 32:

    

    case 33:

    

    case 34:

    

    case 39:

    

    default:

        

        if (VAR_6 < 1) {

            av_log(VAR_0, AV_LOG_ERROR,

                   "Too short RTP/HEVC packet, got %d bytes of NAL unit type %d\n",

                   VAR_6, VAR_12);

            return AVERROR_INVALIDDATA;

        }



        

        if ((VAR_16 = av_new_packet(VAR_3, sizeof(start_sequence) + VAR_6)) < 0)

            return VAR_16;

        

        memcpy(VAR_3->data, start_sequence, sizeof(start_sequence));

        

        memcpy(VAR_3->data + sizeof(start_sequence), VAR_5, VAR_6);



        break;

    

    case 49:

        

        VAR_5 += RTP_HEVC_PAYLOAD_HEADER_SIZE;

        VAR_6 -= RTP_HEVC_PAYLOAD_HEADER_SIZE;



        if (VAR_6 < 1)

            return AVERROR_INVALIDDATA;

        























        VAR_13 = VAR_5[0] & 0x80;

        VAR_14  = VAR_5[0] & 0x40;

        VAR_15        = VAR_5[0] & 0x3f;



        

        VAR_5 += RTP_HEVC_FU_HEADER_SIZE;

        VAR_6 -= RTP_HEVC_FU_HEADER_SIZE;



        

        if (VAR_1->using_donl_field) {

            VAR_5 += RTP_HEVC_DONL_FIELD_SIZE;

            VAR_6 -= RTP_HEVC_DONL_FIELD_SIZE;

        }



        av_dlog(VAR_0, " FU type %d with %d bytes\n", VAR_15, VAR_6);



        if (VAR_6 > 0) {

            new_nal_header[0] = (VAR_9[0] & 0x81) | (VAR_15 << 1);

            new_nal_header[1] = VAR_9[1];



            

            if (VAR_13) {

                if (!VAR_14) {

                    

                    if ((VAR_16 = av_new_packet(VAR_3, sizeof(start_sequence) + sizeof(new_nal_header) + VAR_6)) < 0)

                        return VAR_16;

                    

                    memcpy(VAR_3->data, start_sequence, sizeof(start_sequence));

                    

                    memcpy(VAR_3->data + sizeof(start_sequence), new_nal_header, sizeof(new_nal_header));

                    

                    memcpy(VAR_3->data + sizeof(start_sequence) + sizeof(new_nal_header), VAR_5, VAR_6);

                } else {

                    av_log(VAR_0, AV_LOG_ERROR, "Illegal combination of S and E bit in RTP/HEVC packet\n");

                    VAR_16 = AVERROR_INVALIDDATA;

                }

            } else {

                

                if ((VAR_16 = av_new_packet(VAR_3, VAR_6)) < 0)

                    return VAR_16;

                

                memcpy(VAR_3->data, VAR_5, VAR_6);

            }

        } else {

            

            av_log(VAR_0, AV_LOG_ERROR,

                   "Too short RTP/HEVC packet, got %d bytes of NAL unit type %d\n",

                   VAR_6, VAR_12);

            VAR_16 = AVERROR_INVALIDDATA;

        }



        break;

    

    case 50:

        

        avpriv_report_missing_feature(VAR_0, "PACI packets for RTP/HEVC\n");

        VAR_16 = AVERROR_PATCHWELCOME;

        break;

    }



    VAR_3->stream_index = VAR_2->index;



    return VAR_16;

}

static int FUNC_0(AVFormatContext *VAR_0, PayloadContext *VAR_1,
AVStream *VAR_2, AVPacket *VAR_3, uint32_t *VAR_4,
const uint8_t *VAR_5, int VAR_6, uint16_t VAR_7,
int VAR_8)
{ const uint8_t *VAR_9 = VAR_5; int VAR_10, VAR_11, VAR_12; int VAR_13, VAR_14, VAR_15; uint8_t new_nal_header[2]; int VAR_16 = 0; if (VAR_6 < RTP_HEVC_PAYLOAD_HEADER_SIZE + 1) { av_log(VAR_0, AV_LOG_ERROR, "Too short RTP/HEVC packet, got %d bytes\n", VAR_6); return AVERROR_INVALIDDATA; } VAR_12 =  (VAR_5[0] >> 1) & 0x3f; VAR_11  = ((VAR_5[0] << 5) & 0x20) | ((VAR_5[1] >> 3) & 0x1f); VAR_10  =   VAR_5[1] & 0x07; if (VAR_11) { avpriv_report_missing_feature(VAR_0, "Multi-layer HEVC coding\n"); return AVERROR_PATCHWELCOME; } if (!VAR_10) { av_log(VAR_0, AV_LOG_ERROR, "Illegal temporal ID in RTP/HEVC packet\n"); return AVERROR_INVALIDDATA; } if (VAR_12 > 50) { av_log(VAR_0, AV_LOG_ERROR, "Unsupported (HEVC) NAL type (%d)\n", VAR_12); return AVERROR_INVALIDDATA; } switch (VAR_12) { case 48:
VAR_5 += RTP_HEVC_PAYLOAD_HEADER_SIZE; VAR_6 -= RTP_HEVC_PAYLOAD_HEADER_SIZE; if (VAR_1->using_donl_field) { VAR_5 += RTP_HEVC_DONL_FIELD_SIZE; VAR_6 -= RTP_HEVC_DONL_FIELD_SIZE; } case 32:
case 33:
case 34:
case 39:
default:
if (VAR_6 < 1) { av_log(VAR_0, AV_LOG_ERROR,
"Too short RTP/HEVC packet, got %d bytes of NAL unit type %d\n",
VAR_6, VAR_12); return AVERROR_INVALIDDATA; } if ((VAR_16 = av_new_packet(VAR_3, sizeof(start_sequence) + VAR_6)) < 0)
return VAR_16; memcpy(VAR_3->data, start_sequence, sizeof(start_sequence)); memcpy(VAR_3->data + sizeof(start_sequence), VAR_5, VAR_6); break; case 49:
VAR_5 += RTP_HEVC_PAYLOAD_HEADER_SIZE; VAR_6 -= RTP_HEVC_PAYLOAD_HEADER_SIZE; if (VAR_6 < 1)
return AVERROR_INVALIDDATA; VAR_13 = VAR_5[0] & 0x80; VAR_14  = VAR_5[0] & 0x40; VAR_15        = VAR_5[0] & 0x3f; VAR_5 += RTP_HEVC_FU_HEADER_SIZE; VAR_6 -= RTP_HEVC_FU_HEADER_SIZE; if (VAR_1->using_donl_field) { VAR_5 += RTP_HEVC_DONL_FIELD_SIZE; VAR_6 -= RTP_HEVC_DONL_FIELD_SIZE; } av_dlog(VAR_0, " FU type %d with %d bytes\n", VAR_15, VAR_6); if (VAR_6 > 0) { new_nal_header[0] = (VAR_9[0] & 0x81) | (VAR_15 << 1); new_nal_header[1] = VAR_9[1]; if (VAR_13) { if (!VAR_14) { if ((VAR_16 = av_new_packet(VAR_3, sizeof(start_sequence) + sizeof(new_nal_header) + VAR_6)) < 0)
return VAR_16; memcpy(VAR_3->data, start_sequence, sizeof(start_sequence)); memcpy(VAR_3->data + sizeof(start_sequence), new_nal_header, sizeof(new_nal_header)); memcpy(VAR_3->data + sizeof(start_sequence) + sizeof(new_nal_header), VAR_5, VAR_6); } else { av_log(VAR_0, AV_LOG_ERROR, "Illegal combination of S and E bit in RTP/HEVC packet\n"); VAR_16 = AVERROR_INVALIDDATA; } } else { if ((VAR_16 = av_new_packet(VAR_3, VAR_6)) < 0)
return VAR_16; memcpy(VAR_3->data, VAR_5, VAR_6); } } else { av_log(VAR_0, AV_LOG_ERROR,
"Too short RTP/HEVC packet, got %d bytes of NAL unit type %d\n",
VAR_6, VAR_12); VAR_16 = AVERROR_INVALIDDATA; } break; case 50:
avpriv_report_missing_feature(VAR_0, "PACI packets for RTP/HEVC\n"); VAR_16 = AVERROR_PATCHWELCOME; break; } VAR_3->stream_index = VAR_2->index; return VAR_16; }