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 Libav-user@ffmpeg.org http://ffmpeg.org/mailman/listinfo/libav-user