<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>