* Parse the display segment packet. * * The display segment controls the updating of the display. * * @param avctx contains the current codec context * @param data pointer to the data pertaining the subtitle to display * @param buf pointer to the packet to process * @param buf_size size of packet to process */
| 495 | * @param buf_size size of packet to process |
| 496 | */ |
| 497 | static int display_end_segment(AVCodecContext *avctx, AVSubtitle *sub, |
| 498 | const uint8_t *buf, int buf_size) |
| 499 | { |
| 500 | PGSSubContext *ctx = avctx->priv_data; |
| 501 | int64_t pts; |
| 502 | PGSSubPalette *palette; |
| 503 | int i, ret; |
| 504 | |
| 505 | pts = ctx->presentation.pts != AV_NOPTS_VALUE ? ctx->presentation.pts : sub->pts; |
| 506 | memset(sub, 0, sizeof(*sub)); |
| 507 | sub->pts = pts; |
| 508 | ctx->presentation.pts = AV_NOPTS_VALUE; |
| 509 | sub->start_display_time = 0; |
| 510 | // There is no explicit end time for PGS subtitles. The end time |
| 511 | // is defined by the start of the next sub which may contain no |
| 512 | // objects (i.e. clears the previous sub) |
| 513 | sub->end_display_time = UINT32_MAX; |
| 514 | sub->format = 0; |
| 515 | |
| 516 | // Blank if last object_count was 0. |
| 517 | if (!ctx->presentation.object_count) |
| 518 | return 1; |
| 519 | sub->rects = av_calloc(ctx->presentation.object_count, sizeof(*sub->rects)); |
| 520 | if (!sub->rects) { |
| 521 | return AVERROR(ENOMEM); |
| 522 | } |
| 523 | palette = find_palette(ctx->presentation.palette_id, &ctx->palettes); |
| 524 | if (!palette) { |
| 525 | // Missing palette. Should only happen with damaged streams. |
| 526 | av_log(avctx, AV_LOG_ERROR, "Invalid palette id %d\n", |
| 527 | ctx->presentation.palette_id); |
| 528 | avsubtitle_free(sub); |
| 529 | return AVERROR_INVALIDDATA; |
| 530 | } |
| 531 | for (i = 0; i < ctx->presentation.object_count; i++) { |
| 532 | AVSubtitleRect *const rect = av_mallocz(sizeof(*rect)); |
| 533 | PGSSubObject *object; |
| 534 | |
| 535 | if (!rect) |
| 536 | return AVERROR(ENOMEM); |
| 537 | sub->rects[sub->num_rects++] = rect; |
| 538 | rect->type = SUBTITLE_BITMAP; |
| 539 | |
| 540 | /* Process bitmap */ |
| 541 | object = find_object(ctx->presentation.objects[i].id, &ctx->objects); |
| 542 | if (!object) { |
| 543 | // Missing object. Should only happen with damaged streams. |
| 544 | av_log(avctx, AV_LOG_ERROR, "Invalid object id %d\n", |
| 545 | ctx->presentation.objects[i].id); |
| 546 | if (avctx->err_recognition & AV_EF_EXPLODE) |
| 547 | return AVERROR_INVALIDDATA; |
| 548 | // Leaves rect empty with 0 width and height. |
| 549 | continue; |
| 550 | } |
| 551 | if (ctx->presentation.objects[i].composition_flag & 0x40) |
| 552 | rect->flags |= AV_SUBTITLE_FLAG_FORCED; |
| 553 | |
| 554 | rect->x = ctx->presentation.objects[i].x; |
no test coverage detected