如何将Base64字节数据转为AVSubtitle并编码封装进MPEG-TS?
问题描述
我需要将Base64编码后的字节数据封装到MPEG-TS容器中,但找不到将这些数据编码为AVPacket的方法。使用avcodec_encode_subtitle需要构造包含有效数据的AVSubtitle,但不知道如何用自有数据创建/分配AVSubtitle。
更新:尝试实现后报错
我在Kotlin(项目为KMP)中编写了一段实现代码,但编码时出现Invalid data found when processing input错误,代码如下:
val data = AVSubtitleRect() data.type(SUBTITLE_ASS) data.ass(BytePointer(buffer)) val subtitle = AVSubtitle() val pointerPointer = PointerPointer<AVSubtitleRect>(1) pointerPointer.put(data) subtitle.rects(pointerPointer) subtitle.pts(packet.pts()) val bufferSize = 1024 * 1024 val encodedBuffer = BytePointer(av_malloc(bufferSize.toLong())) val result = avcodec_encode_subtitle(subtitleContext, encodedBuffer, bufferSize, subtitle) if (result >= 0) { val outSubtitlePacket = AVPacket() outSubtitlePacket.apply { data(encodedBuffer) outSubtitlePacket.size(result) outSubtitlePacket.stream_index(subtitleStreamIndex) duration(packet.duration()) dts(packet.dts()) pts(packet.pts()) pos(packet.pos()) } av_interleaved_write_frame(avOutputCtx, outSubtitlePacket) av_packet_unref(outSubtitlePacket) av_free(encodedBuffer) }
对应的C语言等效代码:
// Allocate the subtitle rect AVSubtitleRect *data = av_mallocz(sizeof(AVSubtitleRect)); if (!data) { fprintf(stderr, "Could not allocate AVSubtitleRect.\n"); return AVERROR(ENOMEM); } data->type = SUBTITLE_ASS; data->ass = av_strdup(buffer); if (!data->ass) { fprintf(stderr, "Could not allocate ASS buffer.\n"); av_free(data); return AVERROR(ENOMEM); } // Allocate the subtitle AVSubtitle subtitle; memset(&subtitle, 0, sizeof(subtitle)); subtitle.rects = av_mallocz(sizeof(*subtitle.rects)); if (!subtitle.rects) { fprintf(stderr, "Could not allocate AVSubtitle rects.\n"); av_free(data->ass); av_free(data); return AVERROR(ENOMEM); } subtitle.rects[0] = data; subtitle.num_rects = 1; subtitle.pts = packet->pts; // Allocate buffer for encoded subtitle int bufferSize = 1024 * 1024; uint8_t *encodedBuffer = av_malloc(bufferSize); if (!encodedBuffer) { fprintf(stderr, "Could not allocate buffer for encoded subtitle.\n"); av_free(subtitle.rects); av_free(data->ass); av_free(data); return AVERROR(ENOMEM); } // Encode the subtitle int result = avcodec_encode_subtitle(subtitleContext, encodedBuffer, bufferSize, &subtitle); if (result >= 0) { // Create the output subtitle packet AVPacket outSubtitlePacket; av_init_packet(&outSubtitlePacket); outSubtitlePacket.data = encodedBuffer; outSubtitlePacket.size = result; outSubtitlePacket.stream_index = subtitleStreamIndex; outSubtitlePacket.duration = packet->duration; outSubtitlePacket.dts = packet->dts; outSubtitlePacket.pts = packet->pts; outSubtitlePacket.pos = packet->pos; // Write the subtitle packet result = av_interleaved_write_frame(avOutputCtx, &outSubtitlePacket); if (result < 0) { fprintf(stderr, "Error while writing subtitle packet: %s\n", av_err2str(result)); } av_packet_unref(&outSubtitlePacket); av_free(encodedBuffer); } else { fprintf(stderr, "Failed to encode subtitles. Reason: %s\n", av_err2str(result)); av_free(encodedBuffer); } av_free(subtitle.rects); av_free(data->ass); av_free(data);
内容的提问来源于stack exchange,提问作者Алексей Красноноженко
相关产品推荐
相关产品推荐

