File: subtitle_stream.cpp

package info (click to toggle)
pytorch-vision 0.21.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 20,228 kB
  • sloc: python: 65,904; cpp: 11,406; ansic: 2,459; java: 550; sh: 265; xml: 79; objc: 56; makefile: 33
file content (97 lines) | stat: -rw-r--r-- 2,413 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include "subtitle_stream.h"
#include <c10/util/Logging.h>
#include <limits>
#include "util.h"

namespace ffmpeg {
const AVRational timeBaseQ = AVRational{1, AV_TIME_BASE};

SubtitleStream::SubtitleStream(
    AVFormatContext* inputCtx,
    int index,
    bool convertPtsToWallTime,
    const SubtitleFormat& format)
    : Stream(
          inputCtx,
          MediaFormat::makeMediaFormat(format, index),
          convertPtsToWallTime,
          0) {
  memset(&sub_, 0, sizeof(sub_));
}

void SubtitleStream::releaseSubtitle() {
  if (sub_.release) {
    avsubtitle_free(&sub_);
    memset(&sub_, 0, sizeof(sub_));
  }
}

SubtitleStream::~SubtitleStream() {
  releaseSubtitle();
  sampler_.shutdown();
}

int SubtitleStream::initFormat() {
  if (!codecCtx_->subtitle_header) {
    LOG(ERROR) << "No subtitle header found";
  } else {
    VLOG(1) << "Subtitle header found!";
  }
  return 0;
}

int SubtitleStream::analyzePacket(const AVPacket* packet, bool* gotFrame) {
  // clean-up
  releaseSubtitle();

  // FIXME: should this even be created?
  AVPacket* avPacket;
  avPacket = av_packet_alloc();
  if (avPacket == nullptr) {
    LOG(ERROR)
        << "decoder as not able to allocate the subtitle-specific packet.";
    // alternative to ENOMEM
    return AVERROR_BUFFER_TOO_SMALL;
  }
  avPacket->data = nullptr;
  avPacket->size = 0;
  // check flush packet
  auto pkt = packet ? packet : avPacket;

  int gotFramePtr = 0;
  // is these a better way than cast from const?
  int result =
      avcodec_decode_subtitle2(codecCtx_, &sub_, &gotFramePtr, (AVPacket*)pkt);

  if (result < 0) {
    LOG(ERROR) << "avcodec_decode_subtitle2 failed, err: "
               << Util::generateErrorDesc(result);
    // free the packet we've created
    av_packet_free(&avPacket);
    return result;
  } else if (result == 0) {
    result = pkt->size; // discard the rest of the package
  }

  sub_.release = gotFramePtr;
  *gotFrame = gotFramePtr > 0;

  // set proper pts in us
  if (gotFramePtr) {
    sub_.pts = av_rescale_q(
        pkt->pts, inputCtx_->streams[format_.stream]->time_base, timeBaseQ);
  }

  av_packet_free(&avPacket);
  return result;
}

int SubtitleStream::copyFrameBytes(ByteStorage* out, bool flush) {
  return sampler_.sample(flush ? nullptr : &sub_, out);
}

void SubtitleStream::setFramePts(DecoderHeader* header, bool) {
  header->pts = sub_.pts; // already in us
}

} // namespace ffmpeg