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

Reply via email to