コード例 #1
0
ファイル: mpeg.c プロジェクト: szatmary/libcaption
void sei_dump_messages(sei_message_t* head, double timestamp)
{
    cea708_t cea708;
    sei_message_t* msg;
    cea708_init(&cea708, timestamp);

    for (msg = head; msg; msg = sei_message_next(msg)) {
        uint8_t* data = sei_message_data(msg);
        size_t size = sei_message_size(msg);
        fprintf(stderr, "-- Message %p\n-- Message Type: %d\n-- Message Size: %d\n", data, sei_message_type(msg), (int)size);

        while (size) {
            fprintf(stderr, "%02X ", *data);
            ++data;
            --size;
        }

        fprintf(stderr, "\n");

        if (sei_type_user_data_registered_itu_t_t35 == sei_message_type(msg)) {
            if (LIBCAPTION_OK != cea708_parse_h262(sei_message_data(msg), sei_message_size(msg), &cea708)) {
                fprintf(stderr, "cea708_parse error\n");
            } else {
                cea708_dump(&cea708);
            }
        }
    }
}
コード例 #2
0
ファイル: avc.c プロジェクト: Fishrock123/obs-studio
void sei_dump_messages (sei_message_t* head)
{
    cea708_t cea708;
    sei_message_t* msg;
    cea708_init (&cea708);

    for (msg = head ; msg ; msg = sei_message_next (msg)) {
        uint8_t* data = sei_message_data (msg);
        size_t size =  sei_message_size (msg);
        fprintf (stderr,"-- Message %p\n-- Message Type: %d\n-- Message Size: %d\n", data, sei_message_type (msg), (int) size);

        while (size) {
            fprintf (stderr,"%02X ", *data);
            ++data; --size;
        }

        fprintf (stderr,"\n");

        if (sei_type_user_data_registered_itu_t_t35 == sei_message_type (msg)) {
            cea708_parse (sei_message_data (msg), sei_message_size (msg), &cea708);
            cea708_dump (&cea708);
        }


    }
}
コード例 #3
0
ファイル: avc.c プロジェクト: Fishrock123/obs-studio
sei_message_t* sei_message_new (sei_msgtype_t type, uint8_t* data, size_t size)
{
    struct _sei_message_t* msg = (struct _sei_message_t*) malloc (sizeof (struct _sei_message_t) + size);
    msg->next = 0; msg->type = type; msg->size = size;

    if (data) {
        memcpy (sei_message_data (msg), data, size);
    } else {
        memset (sei_message_data (msg), 0, size);
    }

    return (sei_message_t*) msg;
}
コード例 #4
0
ファイル: mpeg.c プロジェクト: szatmary/libcaption
void sei_append_708(sei_t* sei, cea708_t* cea708)
{
    sei_message_t* msg = sei_message_new(sei_type_user_data_registered_itu_t_t35, 0, CEA608_MAX_SIZE);
    msg->size = cea708_render(cea708, sei_message_data(msg), sei_message_size(msg));
    sei_message_append(sei, msg);
    cea708_init(cea708, sei->timestamp); // will confgure using HLS compatiable defaults
}
コード例 #5
0
ファイル: mpeg.c プロジェクト: szatmary/libcaption
libcaption_stauts_t sei_parse(sei_t* sei, const uint8_t* data, size_t size, double timestamp)
{
    sei_init(sei, timestamp);
    int ret = 0;

    // SEI may contain more than one payload
    while (1 < size) {
        size_t payloadType = 0;
        size_t payloadSize = 0;

        while (0 < size && 255 == (*data)) {
            payloadType += 255;
            ++data, --size;
        }

        if (0 == size) {
            return LIBCAPTION_ERROR;
        }

        payloadType += (*data);
        ++data, --size;

        while (0 < size && 255 == (*data)) {
            payloadSize += 255;
            ++data, --size;
        }

        if (0 == size) {
            return LIBCAPTION_ERROR;
        }

        payloadSize += (*data);
        ++data, --size;

        if (payloadSize) {
            sei_message_t* msg = sei_message_new((sei_msgtype_t)payloadType, 0, payloadSize);
            uint8_t* payloadData = sei_message_data(msg);
            size_t bytes = _copy_to_rbsp(payloadData, payloadSize, data, size);
            sei_message_append(sei, msg);

            if (bytes < payloadSize) {
                return LIBCAPTION_ERROR;
            }

            data += bytes;
            size -= bytes;
            ++ret;
        }
    }

    // There should be one trailing byte, 0x80. But really, we can just ignore that fact.
    return LIBCAPTION_OK;
}
コード例 #6
0
ファイル: mpeg.c プロジェクト: szatmary/libcaption
// we can safely assume sei_render_size() bytes have been allocated for data
size_t sei_render(sei_t* sei, uint8_t* data)
{
    if (!sei || !sei->head) {
        return 0;
    }

    size_t escaped_size, size = 2; // nalu_type + stop bit
    sei_message_t* msg;
    (*data) = 6;
    ++data;

    for (msg = sei_message_head(sei); msg; msg = sei_message_next(msg)) {
        int payloadType = sei_message_type(msg);
        int payloadSize = (int)sei_message_size(msg);
        uint8_t* payloadData = sei_message_data(msg);

        while (255 <= payloadType) {
            (*data) = 255;
            ++data;
            ++size;
            payloadType -= 255;
        }

        (*data) = payloadType;
        ++data;
        ++size;

        while (255 <= payloadSize) {
            (*data) = 255;
            ++data;
            ++size;
            payloadSize -= 255;
        }

        (*data) = payloadSize;
        ++data;
        ++size;

        if (0 >= (escaped_size = _copy_from_rbsp(data, payloadData, payloadSize))) {
            return 0;
        }

        data += escaped_size;
        size += escaped_size;
    }

    // write stop bit and return
    (*data) = 0x80;
    return size;
}
コード例 #7
0
ファイル: mpeg.c プロジェクト: szatmary/libcaption
libcaption_stauts_t sei_to_caption_frame(sei_t* sei, caption_frame_t* frame)
{
    cea708_t cea708;
    sei_message_t* msg;
    libcaption_stauts_t status = LIBCAPTION_OK;

    cea708_init(&cea708, frame->timestamp);

    for (msg = sei_message_head(sei); msg; msg = sei_message_next(msg)) {
        if (sei_type_user_data_registered_itu_t_t35 == sei_message_type(msg)) {
            cea708_parse_h264(sei_message_data(msg), sei_message_size(msg), &cea708);
            status = libcaption_status_update(status, cea708_to_caption_frame(frame, &cea708));
        }
    }

    if (LIBCAPTION_READY == status) {
        frame->timestamp = sei->timestamp;
    }

    return status;
}
コード例 #8
0
ファイル: mpeg.c プロジェクト: szatmary/libcaption
size_t mpeg_bitstream_parse(mpeg_bitstream_t* packet, caption_frame_t* frame, const uint8_t* data, size_t size, unsigned stream_type, double dts, double cts)
{
    if (MAX_NALU_SIZE <= packet->size) {
        packet->status = LIBCAPTION_ERROR;
        // fprintf(stderr, "LIBCAPTION_ERROR\n");
        return 0;
    }

    // consume upto MAX_NALU_SIZE bytes
    if (MAX_NALU_SIZE <= packet->size + size) {
        size = MAX_NALU_SIZE - packet->size;
    }

    sei_t sei;
    size_t header_size, scpos;
    packet->status = LIBCAPTION_OK;
    memcpy(&packet->data[packet->size], data, size);
    packet->size += size;

    while (packet->status == LIBCAPTION_OK && 0 < (scpos = find_start_code(&packet->data[0], packet->size))) {
        switch (mpeg_bitstream_packet_type(packet, stream_type)) {
        default:
            break;
        case H262_SEI_PACKET:
            header_size = 4;
            if (STREAM_TYPE_H262 == stream_type && scpos > header_size) {
                cea708_t* cea708 = _mpeg_bitstream_cea708_emplace_back(packet, dts + cts);
                packet->status = libcaption_status_update(packet->status, cea708_parse_h262(&packet->data[header_size], scpos - header_size, cea708));
                _mpeg_bitstream_cea708_sort_flush(packet, frame, dts);
            }
            break;
        case H264_SEI_PACKET:
        case H265_SEI_PACKET:
            header_size = STREAM_TYPE_H264 == stream_type ? 4 : STREAM_TYPE_H265 == stream_type ? 5 : 0;
            if (header_size && scpos > header_size) {
                packet->status = libcaption_status_update(packet->status, sei_parse(&sei, &packet->data[header_size], scpos - header_size, dts + cts));
                for (sei_message_t* msg = sei_message_head(&sei); msg; msg = sei_message_next(msg)) {
                    if (sei_type_user_data_registered_itu_t_t35 == sei_message_type(msg)) {
                        cea708_t* cea708 = _mpeg_bitstream_cea708_emplace_back(packet, dts + cts);
                        packet->status = libcaption_status_update(packet->status, cea708_parse_h264(sei_message_data(msg), sei_message_size(msg), cea708));
                        _mpeg_bitstream_cea708_sort_flush(packet, frame, dts);
                    }
                }
                sei_free(&sei);
            }
            break;
        }

        packet->size -= scpos;
        memmove(&packet->data[0], &packet->data[scpos], packet->size);
    }

    return size;
}
コード例 #9
0
ファイル: avc.c プロジェクト: Fishrock123/obs-studio
int sei_parse_nalu (sei_t* sei, const uint8_t* data, size_t size, double dts, double cts)
{
    assert (0<=cts); // cant present before decode
    sei->dts = dts;
    sei->cts = cts;
    int ret = 0;

    if (0 == data || 0 == size) {
        return 0;
    }

    uint8_t nal_unit_type = (*data) & 0x1F;
    ++data; --size;

    if (6 != nal_unit_type) {
        return 0;
    }

    // SEI may contain more than one payload
    while (1<size) {
        int payloadType = 0;
        int payloadSize = 0;

        while (0 < size && 255 == (*data)) {
            payloadType += 255;
            ++data; --size;
        }

        if (0 == size) {
            goto error;
        }

        payloadType += (*data);
        ++data; --size;

        while (0 < size && 255 == (*data)) {
            payloadSize += 255;
            ++data; --size;
        }

        if (0 == size) {
            goto error;
        }

        payloadSize += (*data);
        ++data; --size;

        if (payloadSize) {
            sei_message_t* msg = sei_message_new ( (sei_msgtype_t) payloadType, 0, payloadSize);
            uint8_t* payloadData = sei_message_data (msg);
            size_t bytes = _copy_to_rbsp (payloadData, payloadSize, data, size);
            sei_message_append (sei, msg);

            if ( (int) bytes < payloadSize) {
                goto error;
            }

            data += bytes; size -= bytes;
            ++ret;
        }
    }

    // There should be one trailing byte, 0x80. But really, we can just ignore that fact.
    return ret;
error:
    sei_init (sei);
    return 0;
}