<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">On 08/22/2013 06:21 PM, Nisar Ahmed
      wrote:<br>
    </div>
    <blockquote
cite="mid:CAL1+ejjbJ4pdN49JhupHer+PgvxPvJG+zZsSuFsPPecxr7DaDQ@mail.gmail.com"
      type="cite">
      <div dir="ltr">Coming back to this issue, I have tested 2
        scenarios
        <div><br>
        </div>
        <div>a. I am simply setting pts to the timestamp received from
          encoder and dts to 0 but the resulting file is showing very
          large frame rate value.</div>
        <div><br>
        </div>
        <div>b. Setting pts to the timestamp received from encoder but
          this time setting dts with an increment of 1001 starting from
          -1001 (2002/-1001, 0/0, 1001/1001, 5005/2002, 3003/3003). The
          framerate is correct this time but the quicktime player
          displays a white frame at the start of the movie. I
          investigated this issue further by using libav demuxer sample
          and the pts/dts have been changed from what I set and
          start_time is also not 0. VLC plays fine but I also want
          Quicktime player to play the file normally as well.<br>
        </div>
        <div><br>
        </div>
        <div>The movies created by the software which ships with he
          encoder shows correct frame rate and start time of 0, also the
          pts/dts investigated with the demuxing sample are in the same
          sequence as described in the second scenario.</div>
        <div><br>
        </div>
        <div>I really need to understand why my pts/dts are changed by
          the muxer to different values, may be it is trying to guess
          correct values based on the inputs I provided. Which inputs
          matter in this kind of scenarios and how they relate to each
          other?</div>
        <div><br>
        </div>
        <div>Thanks in advance</div>
        <div>Nisar</div>
      </div>
      <div class="gmail_extra"><br>
        <br>
        <div class="gmail_quote">On Sat, Aug 17, 2013 at 11:05 AM, Nisar
          Ahmed <span dir="ltr"><<a moz-do-not-send="true"
              href="mailto:nisar.med@gmail.com" target="_blank">nisar.med@gmail.com</a>></span>
          wrote:<br>
          <blockquote class="gmail_quote" style="margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex">
            <div dir="ltr">Thanks for your answer, when I set timestamp
              of decoder, the frame rate jumps up to a very large value
              <div>
                <br>
              </div>
              <div><span
                  style="font-family:arial,sans-serif;font-size:13px">pts/dts
                  = (2002/0, 0/0, 1001/0, 5005/0, 3003/0...)</span><br>
              </div>
              <div><span
                  style="font-family:arial,sans-serif;font-size:13px"><br>
                </span></div>
              <div><span
                  style="font-family:arial,sans-serif;font-size:13px">am
                  I setting the time_base to correct values 1001/30000
                  and pkt.duration = 1001? the timescale of the
                  timestamp is also 30000</span></div>
            </div>
            <div class="HOEnZb">
              <div class="h5">
                <div class="gmail_extra"><br>
                  <br>
                  <div class="gmail_quote">On Sat, Aug 17, 2013 at 2:10
                    AM, Anshul maheshwari <span dir="ltr"><<a
                        moz-do-not-send="true"
                        href="mailto:er.anshul.maheshwari@gmail.com"
                        target="_blank">er.anshul.maheshwari@gmail.com</a>></span>
                    wrote:<br>
                    <blockquote class="gmail_quote" style="margin:0 0 0
                      .8ex;border-left:1px #ccc solid;padding-left:1ex">
                      <p>-</p>
                      <div>
                        <div><br>
                          On Aug 16, 2013 7:30 PM, "Nisar Ahmed" <<a
                            moz-do-not-send="true"
                            href="mailto:nisar.med@gmail.com"
                            target="_blank">nisar.med@gmail.com</a>>
                          wrote:<br>
                          ><br>
                          > I am muxing h264/aac stream to mp4 coming
                          from an encoder and having issues syncing
                          audio and video streams.<br>
                          ><br>
                          > I suspect that the problem is with PTS
                          and DTS but I am not sure what values should i
                          set to properly sync both streams.<br>
                          ><br>
                          > I have set the time_base of video
                          stream's AVCodecContext to 1001/30000 and each
                          AVPacket gets a duration of 1001<br>
                          ><br>
                          > I am recieving time stamps from the
                          encoder with each NAL packet which is set as
                          PTS of the AVPacket. the sequence of PTS/DTS I
                          set is (2002/0, 0/1001, 1001/2002, 5005/3003,
                          3003/4004...)<br>
                          ><br>
                          > Audio stream AVCodecContext sample rate
                          is 48000 and PTS/DTS are simply multiples of
                          1024 starting from 0 and AVPacket duration is
                          1024.<br>
                          ><br>
                          > The output movie 's frame rate is 20fps
                          when it should be 29.97fps as it is ntsc.<br>
                          ><br>
                          > Please tell me how to debug this problem
                          and what are the guidelines of creating
                          pts/dts for both video and audio in my case<br>
                          ><br>
                        </div>
                      </div>
                      >
                      _______________________________________________<br>
                      > Libav-user mailing list<br>
                      > <a moz-do-not-send="true"
                        href="mailto:Libav-user@ffmpeg.org"
                        target="_blank">Libav-user@ffmpeg.org</a><br>
                      > <a moz-do-not-send="true"
                        href="http://ffmpeg.org/mailman/listinfo/libav-user"
                        target="_blank">http://ffmpeg.org/mailman/listinfo/libav-user</a><br>
                      ><br>
                      Hi naseer
                      <p>If you are getting timestamp with encoder,  i
                        would suggest "dont try to manuplate that" you
                        may set that same timestamp as presentation
                        timestamp (pts) if your video is realtime then
                        try not to generate B type video frame hence no
                        need to set dts.<br>
                        Whatever clock is set by encoder try generating
                        the pts of audio according to that.</p>
                      <p>@enjoy<span><font color="#888888"><br>
                            Anshul</font></span></p>
                      <br>
                      _______________________________________________<br>
                      Libav-user mailing list<br>
                      <a moz-do-not-send="true"
                        href="mailto:Libav-user@ffmpeg.org"
                        target="_blank">Libav-user@ffmpeg.org</a><br>
                      <a moz-do-not-send="true"
                        href="http://ffmpeg.org/mailman/listinfo/libav-user"
                        target="_blank">http://ffmpeg.org/mailman/listinfo/libav-user</a><br>
                      <br>
                    </blockquote>
                  </div>
                  <br>
                </div>
              </div>
            </div>
          </blockquote>
        </div>
        <br>
      </div>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap="">_______________________________________________
Libav-user mailing list
<a class="moz-txt-link-abbreviated" href="mailto:Libav-user@ffmpeg.org">Libav-user@ffmpeg.org</a>
<a class="moz-txt-link-freetext" href="http://ffmpeg.org/mailman/listinfo/libav-user">http://ffmpeg.org/mailman/listinfo/libav-user</a>
</pre>
    </blockquote>
    please don't top post over here,<br>
    <br>
    >I really need to understand why my pts/dts are changed by the
    muxer to different values, may be it is trying to guess correct
    values based on the inputs I provided. Which <br>
    >inputs matter in this kind of scenarios and how they relate to
    each other?<br>
    <br>
    Muxer does not change the pts or dts if you have provided by your
    own, may be you are unable to set pts, dts in your muxer.<br>
    please refer below code, it is not kind of tutorial but  extract
    needed part.<br>
    <br>
    Note: your a part wont work because your h264 elementary stream
    contain b frame, where dts is important part.<br>
                and your b part wont work, there might be simple reason
    for that it does not calculate start time properly, so when it is 0
    as with your software <br>
                then it work.<br>
    <br>
    Below is very badly written code, but its work :)<br>
    <br>
    #include <stdlib.h><br>
    #include <stdio.h><br>
    #include <string.h><br>
    #include <math.h><br>
    #include <libavutil/mathematics.h><br>
    #include <libavformat/avformat.h><br>
    #include <libxml/tree.h><br>
    #define MAX_STREAM 2<br>
    #define BUFF_SIZE ( 1920 *1080 )<br>
    #define STREAM_DURATION   ( 200.0 )<br>
    #define STREAM_FRAME_RATE ( 25 )<br>
    #define AUDIO_BITRATE ( 64000 )<br>
    #define AUDIO_CHANNEL ( 2 )<br>
    #define FRAME_SIZE ( 1024 )<br>
    #define VIDEO_BITRATE ( 400000 )<br>
    #define VIDEO_WIDTH ( 1920 )<br>
    #define VIDEO_HEIGHT ( 1080 )<br>
    #define VIDEO_GOP ( 12 )<br>
    #define OUTPUT_CONTEXT_FORMAT "mpegts"<br>
    #define HLS_NUM_CALLBACKS 2<br>
    <br>
    typedef int (*callbackFn)(void *);<br>
    <br>
    struct mux_cfg<br>
    {<br>
        int no_of_stream;<br>
        enum AVCodecID  codec_id[MAX_STREAM];<br>
        int audio_sample_rate;<br>
        int video_frame_rate;<br>
    <br>
        AVStream *st[MAX_STREAM];<br>
        AVFormatContext *oc;<br>
        unsigned char *obuffer;<br>
    <br>
        //user specific buffer<br>
        unsigned char uobuffer[BUFF_SIZE];<br>
        int uosize;<br>
        int64_t uopts;<br>
    <br>
        int pts_generator;<br>
    <br>
    };<br>
    <br>
    enum MediaType {<br>
        VIDEO,<br>
        AUDIO<br>
    };<br>
    <br>
    struct mediaBuffer{<br>
        int size;<br>
        unsigned char *data ;<br>
        enum MediaType mtype;<br>
        int64_t pts;<br>
        int64_t dts;<br>
    };<br>
    <br>
    int init(char *xml);<br>
    int start(void);<br>
    int get_buffer(void *pOutputData);<br>
    int put_buffer(void *pInputData);<br>
    int stop(void);<br>
    int deinit(void);<br>
    <br>
    struct mux_cfg glb_cfg;<br>
    <br>
    static int mux_write(void* opaque, char*buf, int size);<br>
    static int parse_xml(char*xml,struct mux_cfg *cfg);<br>
    static int update_input_param(xmlNodePtr ParentNode, struct mux_cfg
    *cfg,xmlDocPtr doc);<br>
    <br>
    static int Muxer_init(struct mux_cfg *loc_cfg, char *xml);<br>
    static int Muxer_get_buffer(struct mux_cfg *loc_cfg,void
    *pOutputData);<br>
    static int Muxer_put_buffer(struct mux_cfg *loc_cfg,void
    *pInputData);<br>
    static int Muxer_dinit(struct mux_cfg *loc_cfg);<br>
    <br>
    <br>
    int init(char *xml)<br>
    {<br>
        return Muxer_init(&glb_cfg,xml);<br>
    }<br>
    <br>
    int start(void)<br>
    {<br>
        return 0;<br>
    }<br>
    <br>
    int getCallbackFns(int no, callbackFn* ptr)<br>
    {<br>
    <br>
        int retValue = -1;<br>
    <br>
        if (no != HLS_NUM_CALLBACKS)<br>
        {<br>
            printf("Error: Invalid input callback number: %d\n", no);<br>
            return retValue;<br>
        }<br>
    <br>
        if (ptr)<br>
        {<br>
            ptr[0] = put_buffer;<br>
            ptr[1] = get_buffer;<br>
            retValue = 0;<br>
        }<br>
        else<br>
        {<br>
            printf("Error: Invalid pointer passed for callback!\n");<br>
            return retValue;<br>
    <br>
        }<br>
    <br>
        return retValue;<br>
    }<br>
    <br>
    int get_buffer(void *pOutputData)<br>
    {<br>
        return Muxer_get_buffer(&glb_cfg,pOutputData);<br>
    }<br>
    <br>
    int put_buffer(void *pInputData)<br>
    {<br>
        return Muxer_put_buffer(&glb_cfg,pInputData);<br>
    }<br>
    <br>
    int stop(void)<br>
    {<br>
        return 0;<br>
    }<br>
    <br>
    int deinit(void)<br>
    {<br>
        return Muxer_dinit(&glb_cfg);<br>
    }<br>
    <br>
    static AVStream *add_stream(AVFormatContext *oc, AVCodec **codec,<br>
                                struct mux_cfg *loc_cfg)<br>
    {<br>
        AVCodecContext *c;<br>
        AVStream *st;<br>
    <br>
        st = avformat_new_stream(oc, *codec);<br>
        if (!st)<br>
        {<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>
        switch ((*codec)->type)<br>
        {<br>
            case AVMEDIA_TYPE_AUDIO:<br>
                c->codec_id = loc_cfg->codec_id[AUDIO];<br>
                c->sample_fmt = AV_SAMPLE_FMT_S16;<br>
                c->bit_rate = AUDIO_BITRATE;<br>
                c->sample_rate = loc_cfg->audio_sample_rate;<br>
                c->channels = AUDIO_CHANNEL;<br>
                c->frame_size = FRAME_SIZE;<br>
    <br>
                break;<br>
    <br>
            case AVMEDIA_TYPE_VIDEO:<br>
                c->codec_id = loc_cfg->codec_id[VIDEO];<br>
    <br>
                c->bit_rate = VIDEO_BITRATE;<br>
                c->width = VIDEO_WIDTH;<br>
                c->height = VIDEO_HEIGHT;<br>
                c->time_base.den = loc_cfg->video_frame_rate;<br>
                c->time_base.num = 1;<br>
                c->gop_size = VIDEO_GOP; /* emit one intra frame
    every twelve frames at most */<br>
                c->pix_fmt = AV_PIX_FMT_YUV420P;<br>
                break;<br>
    <br>
            default:<br>
                break;<br>
        }<br>
    <br>
        return st;<br>
    }<br>
    <br>
    static int Muxer_init(struct mux_cfg *loc_cfg, char *xml)<br>
    {<br>
        int i = 0;<br>
        int ret = 0;<br>
        AVCodec *codec[MAX_STREAM];<br>
    <br>
        memset(loc_cfg, 0, sizeof(*loc_cfg));<br>
        /* Initialize libavcodec, and register all codecs and formats.
    */<br>
        av_register_all();<br>
    <br>
        parse_xml(xml,loc_cfg);<br>
    <br>
        /* allocate the output media context */<br>
        avformat_alloc_output_context2(&loc_cfg->oc,
    NULL,OUTPUT_CONTEXT_FORMAT, NULL );<br>
        if (!loc_cfg->oc)<br>
        {<br>
            fprintf(stderr,"unable to allocate allocate context\n");<br>
        }<br>
    <br>
        loc_cfg->obuffer = malloc(BUFF_SIZE);<br>
    <br>
        loc_cfg->oc->pb = avio_alloc_context(loc_cfg->obuffer,
    BUFF_SIZE, AVIO_FLAG_WRITE,<br>
                                        (void*) loc_cfg,NULL, (void*)
    mux_write, NULL );<br>
        for (i = 0; i < loc_cfg->no_of_stream; i++)<br>
        {<br>
            codec[i] = avcodec_find_encoder(loc_cfg->codec_id[i]);<br>
            if (!(codec[i]))<br>
            {<br>
                fprintf(stderr, "Could not find encoder for '%s'\n",<br>
                        avcodec_get_name(loc_cfg->codec_id[i]));<br>
                return -1;<br>
            }<br>
    <br>
            loc_cfg->st[i] = add_stream(loc_cfg->oc,
    &codec[i], loc_cfg);<br>
        }<br>
    <br>
        ret = avformat_write_header(loc_cfg->oc, NULL );<br>
        if (ret < 0)<br>
        {<br>
            fprintf(stderr, "Error occurred when opening output file:
    %s\n",<br>
                    av_err2str(ret));<br>
            return 1;<br>
        }<br>
    <br>
        return 0;<br>
    }<br>
    <br>
    static int Muxer_get_buffer(struct mux_cfg *loc_cfg,void
    *pOutputData)<br>
    {<br>
    <br>
        struct mediaBuffer *buf = (void*) pOutputData;<br>
    <br>
        if(!loc_cfg)<br>
        {<br>
            errno = EINVAL;<br>
            return -1;<br>
        }<br>
    <br>
        if(loc_cfg->pts_generator)<br>
        {<br>
            buf->pts = loc_cfg->uopts;<br>
            buf->dts = 0;<br>
    <br>
        }<br>
        else<br>
        {<br>
            buf->pts = 0;<br>
            buf->dts = 0;<br>
        }<br>
    <br>
        if (loc_cfg->uosize == 0)<br>
        {<br>
            return 0;<br>
        }<br>
    <br>
        buf->data = loc_cfg->uobuffer;<br>
        buf->size = loc_cfg->uosize;<br>
    <br>
        loc_cfg->uosize = 0;<br>
    <br>
        return buf->size;<br>
    }<br>
    static int Muxer_put_buffer(struct mux_cfg *loc_cfg,void
    *pInputData)<br>
    {<br>
        struct mediaBuffer *buf = (void*) pInputData;<br>
        int ret;<br>
        AVPacket pkt;<br>
    <br>
        av_init_packet(&pkt);<br>
    <br>
        if(!loc_cfg)<br>
            return -1;<br>
    <br>
        if(!loc_cfg->pts_generator)<br>
        {<br>
            pkt.pts = buf->pts;<br>
            pkt.dts = buf->dts;<br>
        }<br>
        else<br>
        {<br>
    //        pkt.pts = 0;<br>
    //        pkt.dts = 0;<br>
        }<br>
        pkt.data = buf->data;<br>
        pkt.size = buf->size;<br>
    <br>
        pkt.stream_index = buf->mtype;<br>
    <br>
         ret = av_interleaved_write_frame(loc_cfg->oc, &pkt);<br>
        if (ret < 0)<br>
        {<br>
            fprintf(stderr, "av_interleaved_write_frame : %s\n",
    av_err2str(ret));<br>
        }<br>
        loc_cfg->uopts = pkt.pts;<br>
        return ret;<br>
    }<br>
    <br>
    static int mux_write(void* opaque, char*buf, int size)<br>
    {<br>
        struct mux_cfg *loc_cfg = opaque;<br>
        memcpy(loc_cfg->uobuffer + loc_cfg->uosize, buf, size);<br>
        loc_cfg->uosize += size;<br>
        return 0;<br>
    <br>
    }<br>
    <br>
    int Muxer_dinit(struct mux_cfg *loc_cfg)<br>
    {<br>
        int i = 0;<br>
        av_write_trailer(loc_cfg->oc);<br>
    <br>
    <br>
        for(i = 0;i< loc_cfg->no_of_stream ;i++)<br>
        {<br>
            avcodec_close(loc_cfg->st[i]->codec);<br>
        }<br>
        av_free(loc_cfg->oc->pb);<br>
        /* free the stream */<br>
        avformat_free_context(loc_cfg->oc);<br>
    <br>
        return 0;<br>
    <br>
    }<br>
    <br>
    <br>
    static int parse_xml(char*xml,struct mux_cfg *cfg)<br>
    {<br>
        int ret = 0;<br>
        xmlDocPtr doc;<br>
        xmlNodePtr nl1;<br>
    <br>
        if(!xml || !cfg)<br>
        {<br>
            ret= -1;<br>
            return ret;<br>
        }<br>
        doc = xmlParseFile(xml);<br>
        if (doc == NULL)<br>
        {<br>
            ret= -1;<br>
            return ret;<br>
    <br>
        }<br>
        for (nl1 = doc->children; nl1 != NULL; nl1 = nl1->next)<br>
        {<br>
            ret = xmlStrcmp(nl1->name, (const xmlChar *) "INPUT");<br>
            if (ret == 0)<br>
            {<br>
                update_input_param(nl1,cfg,doc);<br>
            }<br>
        }<br>
    <br>
        xmlFreeDoc(doc);<br>
        return ret;<br>
    }<br>
    static int update_input_param(xmlNodePtr ParentNode, struct mux_cfg
    *cfg,xmlDocPtr doc)<br>
    {<br>
    <br>
        xmlNodePtr nl = ParentNode->children;<br>
        char *pXmlGetString = NULL;<br>
    <br>
        int ret = 0;<br>
        for (; nl != NULL; nl = nl->next)<br>
        {<br>
            ret = xmlStrcmp(nl->name, (const xmlChar *)
    "no_of_elem_stream");<br>
            if (ret == 0)<br>
            {<br>
                pXmlGetString = (char *) xmlNodeListGetString(doc,<br>
                                                             
    nl->xmlChildrenNode, 1);<br>
                sscanf(pXmlGetString, "%d", &cfg->no_of_stream);<br>
                xmlFree(pXmlGetString);<br>
    <br>
            }<br>
    <br>
            ret = xmlStrcmp(nl->name, (const xmlChar *)
    "audio_codec");<br>
            if (ret == 0)<br>
            {<br>
                pXmlGetString = (char *) xmlNodeListGetString(doc,<br>
                                                             
    nl->xmlChildrenNode, 1);<br>
                if(!strcmp(pXmlGetString,"aac"))<br>
                {<br>
                    cfg->codec_id[AUDIO] = AV_CODEC_ID_AAC;<br>
                }<br>
                xmlFree(pXmlGetString);<br>
            }<br>
    <br>
            ret = xmlStrcmp(nl->name, (const xmlChar *)
    "video_codec");<br>
            if (ret == 0)<br>
            {<br>
                pXmlGetString = (char *) xmlNodeListGetString(doc,<br>
                                                             
    nl->xmlChildrenNode, 1);<br>
                if(!strcmp(pXmlGetString,"h264"))<br>
                {<br>
                    cfg->codec_id[VIDEO] = AV_CODEC_ID_H264;<br>
                }<br>
                xmlFree(pXmlGetString);<br>
    <br>
            }<br>
    <br>
            ret = xmlStrcmp(nl->name, (const xmlChar *)
    "audio_sample_rate");<br>
            if (ret == 0)<br>
            {<br>
                pXmlGetString = (char *) xmlNodeListGetString(doc,<br>
                                                             
    nl->xmlChildrenNode, 1);<br>
                sscanf(pXmlGetString, "%d",
    &cfg->audio_sample_rate);<br>
                xmlFree(pXmlGetString);<br>
    <br>
            }<br>
    <br>
            ret = xmlStrcmp(nl->name, (const xmlChar *)
    "video_frame_rate");<br>
            if (ret == 0)<br>
            {<br>
                pXmlGetString = (char *) xmlNodeListGetString(doc,<br>
                                                             
    nl->xmlChildrenNode, 1);<br>
                sscanf(pXmlGetString, "%d",
    &cfg->video_frame_rate);<br>
                xmlFree(pXmlGetString);<br>
    <br>
            }<br>
    <br>
            ret = xmlStrcmp(nl->name, (const xmlChar *)
    "pts_generator");<br>
            if (ret == 0)<br>
            {<br>
                pXmlGetString = (char *) xmlNodeListGetString(doc,<br>
                                                             
    nl->xmlChildrenNode, 1);<br>
                if(!strcmp(pXmlGetString,"TRUE") ||
    !strcmp(pXmlGetString,"true"))<br>
                {<br>
                    cfg->pts_generator = 1;<br>
                }<br>
                xmlFree(pXmlGetString);<br>
    <br>
            }<br>
    <br>
    <br>
        }<br>
        return ret;<br>
    }<br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
    <br>
  </body>
</html>