<div dir="ltr"><div><div><div><div><div><div><div><div>Hi all!<br><br></div>I am writing a small test program that will convert .SRT subtitle file to .ASS format.<br><br>original SRT file (subtitle.srt):<br><br>1<br>00:00:02,000 --> 00:00:06,000<br>
Hello<br><br>2<br>00:00:15,000 --> 00:00:20,000<br>World<br><br>3<br>00:01:00,000 --> 00:01:10,000<br>!!Again!!<br><br></div>Demo code:<br><br>#include "stdafx.h"<br><br>//using namespace std;<br><br>#include <iostream><br>
#include <fstream><br><br>#include <string><br>#include <vector><br>#include <map><br>//#include <DShow.h><br>#include <conio.h><br><br>#include <deque><br>#include <queue><br>
<br>#include <math.h><br>#include <stdlib.h><br>#include <stdio.h><br>#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000<br>extern "C"<br>{<br>#include "libavcodec/avcodec.h"<br>#include "libavformat/avformat.h"<br>
#include "libavdevice/avdevice.h"<br>#include "libswscale/swscale.h"<br>#include "libavutil/dict.h"<br>#include "libavutil/error.h"<br>#include "libavutil/opt.h"<br>#include <libavutil/fifo.h><br>
#include <libavutil/imgutils.h><br>#include <libavutil/samplefmt.h><br>#include <libavutil/time.h><br>#include <libavformat/avio.h><br>#include <libavutil/avstring.h><br>#include <libavutil/mathematics.h><br>
#include "libavfilter/avfiltergraph.h"<br>#include "libavfilter/avcodec.h"<br>#include "libavfilter/buffersink.h"<br>#include "libavfilter/buffersrc.h"<br><br>#include <libswresample/swresample.h><br>
}<br><br>//++decoder++//<br>AVFormatContext *pFormatCtx = 0;<br>int subtitleIndex = -1;<br>AVPacket packet;<br>AVCodecContext *pCodecCtxSubtitle = 0;<br>AVCodec *pCodecSubtitle = 0;<br>
AVSubtitle subtitle;<br>//--decoder--<br><br>//++encoder++<br>AVFormatContext *pOutputFormatCtx=0;<br>AVStream *subtitle_st=0;<br>AVOutputFormat *outputFmt=0;<br>AVCodec *subtitle_codec=0;<br>
/* Add an output stream. */<br>AVStream *add_stream(AVFormatContext *oc, AVCodec **codec,<br> enum AVCodecID codec_id)<br>{<br> AVCodecContext *c;<br> AVStream *st;<br><br> /* find the encoder */<br> *codec = avcodec_find_encoder(codec_id);<br>
if (!(*codec)) {<br> fprintf(stderr, "Could not find encoder for '%s'\n",<br> avcodec_get_name(codec_id));<br> exit(1);<br> }<br><br> st = avformat_new_stream(oc, *codec);<br>
if (!st) {<br> fprintf(stderr, "Could not allocate stream\n");<br> exit(1);<br> }<br> st->id = oc->nb_streams-1;<br> c = st->codec;<br><br> avcodec_get_context_defaults3( c, *codec);<br>
<br> switch ((*codec)->type) <br> {<br> case AVMEDIA_TYPE_SUBTITLE:<br> break;<br> default:<br> break;<br> }<br><br> /* Some formats want stream headers to be separate. */<br> if (oc->oformat->flags & AVFMT_GLOBALHEADER)<br>
c->flags |= CODEC_FLAG_GLOBAL_HEADER;<br><br> return st;<br>}<br><br>void open_subtitle(AVFormatContext *oc, AVCodec *codec, AVStream *st)<br>{<br> int ret;<br> AVCodecContext *c = st->codec;<br><br>
/* open the codec */<br> ret = avcodec_open2(c, codec, NULL);<br> if (ret < 0) <br> {<br> exit(1);<br> }<br>}<br>//--encoder--<br><br>int main (int argc, char **argv)<br>{<br> av_register_all();<br>
avcodec_register_all();<br> avfilter_register_all();<br><br> char inputFilename[90]="subtitle.srt";<br> char outputFilename[90]="temp.ass";<br> int rv = 0;<br><br> // ++decoder++<br>
int got_subtitle = 0;<br> pFormatCtx = avformat_alloc_context();<br><br> rv = avformat_open_input(&pFormatCtx, inputFilename, NULL, NULL);<br><br> for(int i=0; i < pFormatCtx->nb_streams; i++)<br> {<br>
if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_SUBTITLE) <br> {<br> subtitleIndex = i;<br> }<br> }<br> if ( subtitleIndex >= 0 )<br> {<br> pCodecCtxSubtitle=pFormatCtx->streams[subtitleIndex]->codec;<br>
<br> pCodecSubtitle = avcodec_find_decoder(pCodecCtxSubtitle->codec_id);<br> if(pCodecSubtitle==NULL) <br> {<br> return -1; // Codec not found<br> }<br> // Open codec<br> AVDictionary *codecDictOptions = NULL;<br>
if(avcodec_open2(pCodecCtxSubtitle, pCodecSubtitle, &codecDictOptions) < 0 )//error<br> {<br> }<br> }<br> //--decoder--<br><br> //++encoder++<br> int ret;<br> avformat_alloc_output_context2(&pOutputFormatCtx, NULL, NULL, outputFilename);<br>
if (!pOutputFormatCtx) <br> {<br> rv = 1;<br> }<br> //outputFmt = pOutputFormatCtx->oformat;<br> outputFmt = av_guess_format( NULL, outputFilename, NULL );<br> if (outputFmt->subtitle_codec != AV_CODEC_ID_NONE) <br>
{<br> subtitle_st = add_stream(pOutputFormatCtx, &subtitle_codec, outputFmt->subtitle_codec);<br> }<br><br> if (subtitle_st)<br> open_subtitle(pOutputFormatCtx, subtitle_codec, subtitle_st);<br>
<br> av_dump_format(pOutputFormatCtx, 0, outputFilename, 1);<br> /* open the output file, if needed */<br> if (!(outputFmt->flags & AVFMT_NOFILE)) <br> {<br> if (avio_open(&pOutputFormatCtx->pb, outputFilename, AVIO_FLAG_WRITE) < 0) <br>
{<br> rv = 1;<br> }<br> else<br> {<br> /* Write the stream header, if any. */<br> if (avformat_write_header(pOutputFormatCtx, NULL) < 0) <br> {<br>
rv = 1;<br> }<br> }<br> }<br><br> AVCodecContext *c = subtitle_st->codec;<br> //--encoder--<br><br> while( av_read_frame( pFormatCtx, &packet ) >= 0 )<br> {<br> if(packet.stream_index != subtitle_st->index)<br>
continue;<br> int gotSubtitle = 0;<br> rv = avcodec_decode_subtitle2( pCodecCtxSubtitle, &subtitle, &gotSubtitle, &packet );<br> uint64_t bufferSize = 1024 * 1024 ;<br> uint8_t *buffer = new uint8_t[bufferSize];<br>
memset(buffer, 0, bufferSize);<br> if( rv >= 0 )<br> {<br> rv = avcodec_encode_subtitle( subtitle_st->codec, buffer, bufferSize, &subtitle );<br> if ( rv >= 0 )<br>
{<br> AVPacket outPacket;<br> av_init_packet(&outPacket);<br> outPacket.data = buffer;<br> outPacket.size = strlen((const char*)buffer);<br> rv = av_interleaved_write_frame(pOutputFormatCtx, &outPacket);<br>
av_free_packet(&outPacket);<br> }<br> }<br> delete [] buffer;<br> }<br><br> if ( pCodecCtxSubtitle) <br> {<br> avcodec_close(pCodecCtxSubtitle);<br> pCodecCtxSubtitle= NULL;<br>
}<br> if ( pCodecSubtitle ) <br> {<br> av_free(pCodecSubtitle);<br> pCodecSubtitle= NULL;<br> }<br> if ( pFormatCtx )<br> {<br> avformat_close_input(&pFormatCtx);<br>
avformat_free_context(pFormatCtx);<br> pFormatCtx = NULL;<br> }<br> avcodec_close(subtitle_st->codec);<br> return rv;<br>}<br><br></div>PTS values are not calculated still, it is work in progress; but the above code gives me this output:<br>
<br></div>output temp.ass file:<br><br>Dialogue: 0,0:00:00.00,0:00:00.00,Default,Hello<br>Dialogue: 0,0:00:00.00,0:00:00.00,Default,World<br>Dialogue: 0,0:00:00.00,0:00:00.00,Default,!!Again!!<br><br></div>It is clearly missing all header information.<br>
<br>When i run ffmpeg command line to convert orignal SRT file using:<br><br>ffmpeg -i subtitle.srt temp.ass<br><br></div>I get:<br><br>[Script Info]<br>ScriptType: v4.00+<br><br>[V4+ Styles]<br>Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, AlphaLevel, Encoding<br>
Style: Default,Arial,16,&Hffffff,&Hffffff,&H0,&H0,0,0,0,1,1,0,2,10,10,10,0,0<br><br>[Events]<br>Format: Layer, Start, End, Style, Text<br>Dialogue: 0,0:00:02.00,0:00:06.00,Default,Hello<br>Dialogue: 0,0:00:15.00,0:00:20.00,Default,World<br>
Dialogue: 0,0:01:00.00,0:01:10.00,Default,!!Again!!<br><br></div>so my question is, even though I am calling avformat_write_header() function, why isn't this header information being written through my code?<br><br></div>
Thanks in advance...<br></div>