Hello list readers,
I'm trying to interleave some continuous private data into an MPEG-TS
container alongside to some audio data. As far as I know, MPEG-TS
supports private streams, but I can not get it, to work cleanly.
I've attached a little working example to show, what I've got so far
and what problems I've encountered.
The example file works like this:
* Muxing:
* Open a format context for the MPEG-TS container.
* Add a stream with codec-type AVMEDIA_TYPE_DATA.
* Open file, write header.
* Fill packets with 1024 bytes of random data (either only digits '0'
to '9', or char (0 - 255), and write them to the container.
* Write trailer, close file, free format context.
* Demuxing:
* Open format context and file.
* Find and write out stream info.
* Read packets and write out some info.
* Free format context.
Results, when running the example:
* With digit-only data ('0' - '9'):
* Stream's codec-type is AVMEDIA_TYPE_UNKNOWN
* Packet sizes are correct 1024 bytes, as generated while muxing.
* Using full bytes:
* Stream's codec-type is AVMEDIA_TYPE_AUDIO
* I guess FFMPEG tries to decode the not-audio data using either mp3
(FFMPEG 2.2.3) or aac (FFMPEG 2.4.1).
* Packet sizes are not preserved. :-(
I can work around these problems, by ignoring all warning and error
messages, as well as the codec-types. I can just use a dedicated stream
ID identify the data stream. I can put the size of each packet at the
beginning of each packet, to demangle the package data. But I'd rather
have a cleaner solution, where the codec-type is set correctly and
FFMPEG does not try to decode my data.
So... What have I done wrong? What is the correct way to achieve this?
Thanks,
Wolfgang
#include <libavformat/avformat.h>
#include <libavformat/avio.h>
#include <stdio.h>
void writeFile(char * fileName, char digits)
{
AVFormatContext * formatContext = NULL;
AVStream * stream = NULL;
AVRational refTimeBase = {1, 100};
int c, d;
/* set up container */
avformat_alloc_output_context2(&formatContext,
NULL,
"mpegts",
fileName);
/* set up stream */
stream = avformat_new_stream(formatContext,
NULL);
stream->codec->time_base = refTimeBase;
stream->codec->codec_type = AVMEDIA_TYPE_DATA;
stream->codec->bit_rate = 81920;
stream->time_base = refTimeBase;
stream->id = 0x1001;
/* open output file */
avio_open(&(formatContext->pb),
fileName,
AVIO_FLAG_WRITE);
avformat_write_header(formatContext,
NULL);
for(c = 0; c < 100; ++c)
{
AVPacket packet = {0};
av_init_packet(&packet);
packet.data = 0;
packet.size = 0;
av_grow_packet(&packet, 1024);
packet.stream_index = 0;
packet.duration = 1 * refTimeBase.num * stream->time_base.den / refTimeBase.den / stream->time_base.num;
packet.pts = c * refTimeBase.num * stream->time_base.den / refTimeBase.den / stream->time_base.num;;
packet.dts = packet.pts;
/* fill packet */
for(d = 0; d < 1024; ++d)
{
if(digits)
{
packet.data[d] = (char) (rand() % 10) + '0';
}else
{
packet.data[d] = (char) (rand() % 0x100);
}
}
/* write packet */
av_interleaved_write_frame(formatContext, &packet);
/* free packet */
av_free_packet(&packet);
}
av_write_trailer(formatContext);
avio_close(formatContext->pb);
avformat_free_context(formatContext);
}
void readFile(char * fileName)
{
AVFormatContext * formatContext = NULL;
AVPacket packet = {0};
int c;
/* open file */
avformat_open_input(&formatContext,
fileName,
NULL,
NULL);
/* stream info */
avformat_find_stream_info(formatContext,
NULL);
for(c = 0; c < formatContext->nb_streams; ++c)
{
printf("Stream: %d, id: %d, codec type: ", c, formatContext->streams[c]->id);
switch(formatContext->streams[c]->codec->codec_type)
{
case AVMEDIA_TYPE_DATA:
printf("Data");
break;
case AVMEDIA_TYPE_UNKNOWN:
printf("Unknown");
break;
case AVMEDIA_TYPE_AUDIO:
printf("Audio");
break;
default:
printf("Something else");
}
printf("\n");
}
/* packet info */
av_init_packet(&packet);
packet.data = 0;
packet.size = 0;
while((c = av_read_frame(formatContext, &packet)) >= 0)
{
printf("Packet at %d*%d/%d: size: %d\n",
packet.pts,
formatContext->streams[packet.stream_index]->time_base.num,
formatContext->streams[packet.stream_index]->time_base.den,
packet.size);
av_free_packet(&packet);
packet.data = 0;
packet.size = 0;
}
avformat_free_context(formatContext);
}
int main(int argc, char ** argv)
{
int c;
int digits = 0;
for(c = 1; c < argc; ++c)
{
if(strcmp(argv[c], "--help") == 0 || strcmp(argv[c], "-h") == 0)
{
printf("Usage: %s --help | --only-digits\n", argv[0]);
return EXIT_SUCCESS;
}else if(strcmp(argv[c], "--only-digits") == 0 || strcmp(argv[c], "-d") == 0)
{
digits = 1;
}else
{
fprintf(stderr, "Unknown command line option: %s\nCall %s --help\n", argv[c], argv[0]);
return EXIT_FAILURE;
}
}
/* register stuff */
av_register_all();
avcodec_register_all();
writeFile("testfile.ts", digits);
readFile("testfile.ts");
return EXIT_SUCCESS;
}
_______________________________________________
Libav-user mailing list
[email protected]
http://ffmpeg.org/mailman/listinfo/libav-user