[Libav-user] Simple packet-by-packet copy does not work for h264+mp4

ALESSANDRO PAGANELLI 83670 at studenti.unimore.it
Thu Mar 1 12:45:10 CET 2012


Hello everybody,

since I'm trying to understand how to properly manipulate mp4 formatted
files containing h264 coded content, I resorted on the "output-example.c"
file found inside Libav 0.7.3 package.
To understand the very basics of how to properly setup the output contexts,
formats and codecs for h264 + mp4, I wrote a simple program that does just
the following three steps:

1) It opens the source mp4 file, encoded with h264, and saves the contexts
of interest in temporary variables.
2) It opens the target output contexts, configuring them exactly as in the
respective source context (with the exception of pointer variables).
3) It performs a packet-by-packet read over the source file, followed by a
copy of what has been read to the output file, as reported in the following
code:

  AVPacket readPacket;
  AVPacket outputPacket;
  AVStream currentStream;
  int returnCode = 0;

  currentStream = *(g_outputFormatContext->streams[0]);

  while (1)
    {
      returnCode = av_read_frame(g_inputFormatContext, &readPacket);
      if (returnCode != 0)
        {
          /* EOF has been reached - exit from the loop */
          av_close_input_file(g_inputFormatContext);
          break;
        }

      /* EOF has NOT been reached, continue */
      av_init_packet(&outputPacket);

      outputPacket.pts = readPacket.pts;
      outputPacket.dts = readPacket.dts;
      outputPacket.stream_index= currentStream.index;
      outputPacket.data= readPacket.data;
      outputPacket.size= readPacket.size;

      returnCode = av_write_frame(g_outputFormatContext, &outputPacket);
      if (returnCode != 0)
        {
          printf("Error on write - exiting\n");
          exit(1);
        }

      av_free_packet(&readPacket);
      av_free_packet(&outputPacket);
    }

  /* Close everything */
  av_write_trailer(g_outputFormatContext);
  if (!(g_outputFormat->flags & AVFMT_NOFILE))
    {
      /* close the output file */
      avio_close(g_outputFormatContext->pb);
    }
  av_free(g_outputFormatContext);


Even if this code is very simple (i.e., it just copies the content of a
file into another one), it does not provide satisfactory results, since the
output file can't be played.
Please, could someone tell me if the previous code is "reasonable" or not??

Moreover, by comparing with "ffprobe -show_streams" the original file with
the copy one, width, height and other important parameters look as if they
have not been properly copied, even if they have been set with:

outputStream->codec->bit_rate = g_inputCodecContext->bit_rate;
outputStream->codec->width = g_inputCodecContext->width;
outputStream->codec->height = g_inputCodecContext->height;
outputStream->codec->has_b_frames = g_inputCodecContext->has_b_frames;
outputStream->codec->sample_aspect_ratio =
outputStream->sample_aspect_ratio; // WARNING
outputStream->codec->level = g_inputCodecContext->level;

where g_inputCodecContext is the AVCodecContext of the original file.
Is it possible that AVPacket settings could interfere with the stream and
format's configurations??

ANY suggestion is very welcome.

Thank you in advance,
kind regards.

Alessandro

-- 
______________________________________________

Ing. Alessandro Paganelli, Ph. D. Student, 25th Cycle

Department of Information Engineering
University of Modena and Reggio Emilia
via Vignolese 905, 41125 Modena (MO), ITALY

E-mail: alessandro.paganelli at unimore.it
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20120301/80f99387/attachment.html>


More information about the Libav-user mailing list