With some sample code I was able to come up with some code. But I still have
some problems with it. When calling av_write_header I get the message: "Codec
for stream 0 does not use global headers but container format requires global
headers". And the file written is not playable.
I'm using av_read_frame and av_write_frame. But as I understand it these
methods will encode/decode my movie right? But I don't wan't that, I just wan't
to copy the encoded data from the MPEG-TS to the mp4 container. Can someone
please give me some advice what I'm doing wrong here ?
AVOutputFormat *outputFmt = av_guess_format("mp4", NULL, NULL);
if (!outputFmt) {
NSLog(@"Error getting output format");
return;
}
AVFormatContext *outputContext = avformat_alloc_context();
if (!outputContext) {
NSLog(@"Could not init output context");
return;
}
outputContext->oformat = outputFmt;
snprintf(outputContext->filename, sizeof(outputContext->filename), "%s",
outputFilepathCString);
//open input
AVFormatContext *inputContext;
int ret = av_open_input_file(&inputContext, firstInputFileCString, NULL, 0,
NULL);
if (ret != 0) {
NSLog(@"Erroro opening input");
}
NSMutableArray *streams = [[NSMutableArray alloc] init];
NSUInteger i;
for (i = 0; i < inputContext->nb_streams; i++) {
AVStream inputStream = *inputContext->streams[i];
[streams addObject:[NSValue valueWithPointer:&inputStream]];
}
dump_format(inputContext, 0, firstInputFileCString, false);
for (NSValue *stream in streams) {
AVStream *avStream = [stream pointerValue];
AVStream *outputStream = av_new_stream(outputContext, avStream->id);
if (!outputStream) {
NSLog(@"Could not init new output stream");
}
memcpy(outputStream->language, avStream->language,
sizeof(avStream->language));
switch (avStream->codec->codec_type) {
case CODEC_TYPE_VIDEO:
{
avcodec_get_context_defaults2(outputStream->codec,
CODEC_TYPE_VIDEO);
outputStream->codec->codec_type = CODEC_TYPE_VIDEO;
outputStream->codec->width = 640;//avStream->codec->width;
outputStream->codec->height = 480;// avStream->codec->height;
break;
}
case CODEC_TYPE_AUDIO:
{
avcodec_get_context_defaults2(outputStream->codec,
CODEC_TYPE_AUDIO);
outputStream->codec->codec_type = CODEC_TYPE_AUDIO;
outputStream->codec->channels = avStream->codec->channels;
outputStream->codec->sample_rate = avStream->codec->sample_rate;
outputStream->codec->frame_size = avStream->codec->frame_size;
outputStream->codec->block_align = avStream->codec->block_align;
break;
}
default:
return;
}
outputStream->codec->codec_id = avStream->codec->codec_id;
outputStream->codec->codec_tag = avStream->codec->codec_tag;
outputStream->codec->bit_rate = avStream->codec->bit_rate;
outputStream->codec->extradata = avStream->codec->extradata;
outputStream->codec->extradata_size = avStream->codec->extradata_size;
if (av_q2d(avStream->codec->time_base) > av_q2d(avStream->time_base) &&
av_q2d(avStream->time_base) < 1.0/1000)
outputStream->codec->time_base = avStream->codec->time_base;
else
outputStream->codec->time_base = avStream->time_base;
}
AVFormatParameters formatParams;
memset(&formatParams, 0, sizeof(AVFormatParameters));
ret = av_set_parameters(outputContext, &formatParams);
if (ret !=0) {
NSLog(@"Unable to set Format Parameters");
}
//open output
ret = url_fopen(&outputContext->pb, outputContext->filename, URL_WRONLY);
if (ret != 0) {
NSLog(@"Could not open output file %s",outputContext->filename);
}
dump_format(outputContext, 0, outputContext->filename, true);
ret = av_write_header(outputContext);
if (ret != 0) {
NSLog(@"Could not write header to output file");
}
while (YES) {
AVPacket packet;
ret = av_read_frame(inputContext, &packet);
if (ret < 0) {
if (ret == -1) {
NSLog(@"Reached EOF");
} else {
NSLog(@"Failed to read a frame");
}
break;
}
av_write_frame(outputContext, &packet);
}
ret = av_write_trailer(outputContext);
if (ret != 0) {
NSLog(@"Could not write trailer to output file");
}
av_close_input_file(inputContext);
ret = url_fclose(outputContext->pb);
if (ret != 0) {
NSLog(@"Error on closing output file");
}
av_free(outputContext);
On 14.07.2010, at 10:05, Thomas Post wrote:
> Hi there,
>
> I'm totally new to the ffmpeg libs. So I'm a real newbie!
> First I'd like to do soemthing like this: "ffmpeg -i input.ts -acodec copy
> -vcodec copy output.mp4" but programmatically. So I tried to do this:
> - open an input file with av_open_input_file
> - read it's content with av_read_frame
> - write the frame to the output with av_write_frame. But here the problem
> starts. How can I get an AVFormatContext to a new .mp4 file?
>
> Second I'd like to do this with a series of .ts files. Multiple .ts files
> into one .mp4 file. But I think that won't be such a problem when I got the
> thing above working.
>
_______________________________________________
libav-user mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/libav-user