Sven,
This is how I add my video stream to the output encoder
-(AVStream*) addVideoStream:(enum CodecID)codec_id
{
AVCodecContext *c;
AVStream *st;
st = av_new_stream(pFmtCtx, 0);
if (!st)
{
NSLog(@"Could not alloc stream");
return nil;
}
c = st->codec;
c->codec_id = codec_id;
c->codec_type = AVMEDIA_TYPE_VIDEO;
if(codec_id == CODEC_ID_H264)
{
// H264 ENCODER SETTINGS FROM SVEN
c->coder_type = 0;
c->flags |= CODEC_FLAG_LOOP_FILTER;
c->me_cmp |= 1;
c->partitions |=
X264_PART_I8X8+X264_PART_I4X4+X264_PART_P8X8+X264_PART_B8X8;
c->me_method = ME_HEX;
c->me_subpel_quality = 2;
//c->me_range = 16;
c->keyint_min = 25;
//c->scenechange_threshold=40;
//c->qcompress = 0.6;
c->qmin = 10;
c->qmax = 51;
c->max_qdiff = 4;
c->max_b_frames = 0;
c->refs = 1;
//c->directpred = 1;
//c->trellis = 1;
c->flags2 |=
CODEC_FLAG2_BPYRAMID+CODEC_FLAG2_MIXED_REFS+CODEC_FLAG2_WPRED+CODEC_FLAG2_8X8DCT+CODEC_FLAG2_FASTPSKIP+CODEC_FLAG2_INTRA_REFRESH;
//c->weighted_p_pred = 2;
c->crf = 24;
c->rc_lookahead = 0;
}
// put sample parameters
c->bit_rate = 4000000;
// resolution must be a multiple of two
c->width = outputWidth;
c->height = outputHeight;
// time base: this is the fundamental unit of time (in seconds) in terms
// of which frame timestamps are represented. for fixed-fps content,
// timebase should be 1/framerate and timestamp increments should be
// identically 1.
c->time_base.den = streamFrameRate;
c->time_base.num = 1;
c->gop_size = 250; // emit one intra frame every twelve frames at most
c->pix_fmt = STREAM_PIX_FMT;
// some formats want stream headers to be separate
if(pFmtCtx->oformat->flags & AVFMT_GLOBALHEADER)
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
encodedFrames = 0;
return st;
}
I also have another question,
I am currently encoding one stream of audio along with these video
frames. How do I go about muxing a second audio from another audio
source onto the output file?
Thanks
Gautam
On Thu, Feb 3, 2011 at 1:04 AM, Sven Alisch <[email protected]> wrote:
> Gautam,,
>
> your code looks ok, also for h.264. My code does not really differ.
>
>> doesn't seem to add up.
>
> Do you mean, you are missing some pictures? Than yes, please tell me. I had
> the same problem and I working currently at a function to solve this. By the
> way, please post me your encoding options for h.264. Maybe you missed an
> encoding option.
>
> Does ffmpeg post any error warnings while your encoding process? If not the
> please add the line av_log_set_level(AV_LOG_VERBOSE);
>
> So we can see if there is an another problem.
>
> regards,
> Sven
>
>> Thanks
>> Gautam
>>
>> On Tue, Feb 1, 2011 at 12:11 PM, Sven Alisch <[email protected]> wrote:
>>> Dear Gautam,
>>>
>>> This really no problem, because I was a bloody beginner and the people here
>>> helped me very much. If you need code, don't hestitate to post it and ask.
>>>
>>> regards,
>>> Sven
>>>
>>> Am 01.02.2011 um 21:04 schrieb Gautam Muralidhar:
>>>
>>>> Sven,
>>>> This is great, thanks again. Please excuse me for beginner questions.
>>>> I may have to bother you in the near future with more info :)
>>>> Thanks in advance
>>>> Gautam
>>>>
>>>> On Tue, Feb 1, 2011 at 12:03 PM, Sven Alisch <[email protected]> wrote:
>>>>> Gautam,
>>>>>
>>>>>> my case I dont cut frames at all. So I assume that the calculation of
>>>>>> my pts and dts would be something like frameNR*40*90 like in your
>>>>>> case?
>>>>>
>>>>> For the dts you have got right. The pts you don't need to calculate
>>>>> because you get the pts as a present by avcodec_encode_video-function.
>>>>>
>>>>> regards,
>>>>> Sven
>>>>>
>>>>>> Thanks
>>>>>> Gautam
>>>>>>
>>>>>> On Tue, Feb 1, 2011 at 11:53 AM, Sven Alisch <[email protected]> wrote:
>>>>>>> Gautam,
>>>>>>>
>>>>>>>> What are your magic numbers in your math? 40*90 and 120*90?
>>>>>>>
>>>>>>> Sorry for the hard coded magic numbers. My code is quick and dirty. I
>>>>>>> have to do a finetuning now.
>>>>>>>
>>>>>>> 40*90 means 40 ms (because in germany the duration of a frame is 40 ms)
>>>>>>> and 90 because of the 90kHz by the standard for PTS-values.
>>>>>>>
>>>>>>>> Also where do you get decodeToFrame value?
>>>>>>>
>>>>>>> Oh this is my own variable. The background is following. My program
>>>>>>> should cut not only at keyframes. If I cut not at a keyframe, then I
>>>>>>> reencode my "open" GOP. So decodeToFrame tells me, how many frames to
>>>>>>> decode till the position where I have to reencode my stream.
>>>>>>>
>>>>>>> Example:
>>>>>>>
>>>>>>> My GOP structure
>>>>>>>
>>>>>>> IBPBPBPPP...
>>>>>>>
>>>>>>> Lets assume I want to cut my videofile at the 3'rd position. Now
>>>>>>> decodeToFrame is 3. But I have to decode the whole GOP including the
>>>>>>> first key frame. At the 3'rd frame I reencode and create a new coded
>>>>>>> shorter sequence. My english is bad, but did you understand?
>>>>>>>
>>>>>>> regards,
>>>>>>> Sven
>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On Tue, Feb 1, 2011 at 11:34 AM, Sven Alisch <[email protected]> wrote:
>>>>>>>>> Dear Gautam, dear Max,
>>>>>>>>>
>>>>>>>>> Thank you for your proposals. Now it works. The main problem (I
>>>>>>>>> think) depends on the avframe. This avframe was the direct output
>>>>>>>>> from the decoder. So this avframe contains many informations that
>>>>>>>>> disturbs the encoder. I show the solution (quick and dirty code! No
>>>>>>>>> memory cleanup and so on... ) at the end of my mail.
>>>>>>>>>
>>>>>>>>> @Max
>>>>>>>>>
>>>>>>>>> You've got right. It is better to comment the last one out.
>>>>>>>>>
>>>>>>>>> @Gautam
>>>>>>>>>
>>>>>>>>> Yes of course. No problem. Here is my code.
>>>>>>>>>
>>>>>>>>> if (frameFinished)
>>>>>>>>>
>>>>>>>>> // Here the decoder is finished and
>>>>>>>>> decode a frame from an existent h.264 stream
>>>>>>>>> {
>>>>>>>>> frameNr++;
>>>>>>>>>
>>>>>>>>> if (frameNr >= decodeToFrame)
>>>>>>>>> {
>>>>>>>>> AVCodecContext* c = t->streamContext->codec;
>>>>>>>>>
>>>>>>>>> AVFrame* newFrame = avcodec_alloc_frame();
>>>>>>>>>
>>>>>>>>> // Initialize a new frame
>>>>>>>>> int size = avpicture_get_size(c->pix_fmt, c->width,
>>>>>>>>> c->height);
>>>>>>>>> uint8_t* picture_buf = av_malloc(size);
>>>>>>>>> avpicture_fill((AVPicture *)newFrame, picture_buf,
>>>>>>>>> c->pix_fmt, c->width, c->height);
>>>>>>>>> av_picture_copy((AVPicture*)newFrame,
>>>>>>>>> (AVPicture*)avframe, c->pix_fmt, c->width, c->height); // Copy
>>>>>>>>> only the frame content without any other disturbing stuff
>>>>>>>>>
>>>>>>>>> newFrame->pts = (frameNr - decodeToFrame)*40*90;
>>>>>>>>>
>>>>>>>>> // Setting correct pts
>>>>>>>>>
>>>>>>>>> int out_size = avcodec_encode_video(c, video_outbuf,
>>>>>>>>> video_outbuf_size, newFrame);
>>>>>>>>> if (out_size > 0)
>>>>>>>>> {
>>>>>>>>> av_init_packet(&tmp_packet);
>>>>>>>>>
>>>>>>>>> if (c->coded_frame->pts != AV_NOPTS_VALUE)
>>>>>>>>> {
>>>>>>>>> tmp_packet.pts =
>>>>>>>>> av_rescale_q(c->coded_frame->pts,
>>>>>>>>>
>>>>>>>>> c->time_base,
>>>>>>>>>
>>>>>>>>> c->time_base) + 120*90;
>>>>>>>>> tmp_packet.dts = encodedFrames*40*90;
>>>>>>>>> }
>>>>>>>>> if(c->coded_frame->key_frame)
>>>>>>>>> tmp_packet.flags |= AV_PKT_FLAG_KEY;
>>>>>>>>> tmp_packet.stream_index=
>>>>>>>>> t->streamContext->index;
>>>>>>>>> tmp_packet.data= video_outbuf;
>>>>>>>>> tmp_packet.size= out_size;
>>>>>>>>> av_interleaved_write_frame(formatContext,
>>>>>>>>> &tmp_packet);
>>>>>>>>> encodedFrames++;
>>>>>>>>> }
>>>>>>>>> }
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> regards,
>>>>>>>>> Sven
>>>>>>>>>
>>>>>>>>> Am 01.02.2011 um 18:36 schrieb Gautam Muralidhar:
>>>>>>>>>
>>>>>>>>>> Sven,
>>>>>>>>>> I am seeing similar issues. How exactly are you writing your frames?
>>>>>>>>>> Do you think you can share your code inside the
>>>>>>>>>> if(outsize >0)
>>>>>>>>>> {
>>>>>>>>>>
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> Thanks
>>>>>>>>>> Gautam
>>>>>>>>>> On Tue, Feb 1, 2011 at 6:15 AM, Max The Quantum
>>>>>>>>>> <[email protected]> wrote:
>>>>>>>>>>> I've tried your config, but uncommented all lines except
>>>>>>>>>>> //c->flags2|=CODEC_FLAG2_8X8DCT;
>>>>>>>>>>> //c->flags2^=CODEC_FLAG2_8X8DCT; // flags2=-dct8x8
>>>>>>>>>>> and commented out
>>>>>>>>>>> c->crf = 22;
>>>>>>>>>>>
>>>>>>>>>>> It seems that problem is caused by wrong value of c->keyint_min.
>>>>>>>>>>> What is
>>>>>>>>>>> default value for it?
>>>>>>>>>>> Try to set it manually to, say, 25 :)
>>>>>>>>>>>
>>>>>>>>>>> 2011/2/1 Sven Alisch <[email protected]>
>>>>>>>>>>>
>>>>>>>>>>>> Hello list,
>>>>>>>>>>>>
>>>>>>>>>>>> I want to (re-) encode some pictures I decoded with libav. The
>>>>>>>>>>>> following
>>>>>>>>>>>> code shows how I do that:
>>>>>>>>>>>>
>>>>>>>>>>>> First I decode an h.264 Stream and get pictures in an AVFrame
>>>>>>>>>>>> structure.
>>>>>>>>>>>> After doing this I want to encode them into an h.264 stream.
>>>>>>>>>>>> <snip>
>>>>>>>>>>>> bytesDecoded =
>>>>>>>>>>>> avcodec_decode_video2(m->videofile->VideoTrack->codec_context,
>>>>>>>>>>>> avframe,
>>>>>>>>>>>> &frameFinished, &packet);
>>>>>>>>>>>>
>>>>>>>>>>>> if (frameFinished)
>>>>>>>>>>>> {
>>>>>>>>>>>> frameNr++;
>>>>>>>>>>>>
>>>>>>>>>>>> if (frameNr >= decodeToFrame)
>>>>>>>>>>>> {
>>>>>>>>>>>> AVCodecContext* c = t->streamContext->codec;
>>>>>>>>>>>> avframe->pts = (frameNr - decodeToFrame)*40*90;
>>>>>>>>>>>> int out_size = avcodec_encode_video(c, video_outbuf,
>>>>>>>>>>>> video_outbuf_size, avframe);
>>>>>>>>>>>> if (out_size > 0)
>>>>>>>>>>>> {
>>>>>>>>>>>> ...
>>>>>>>>>>>> }
>>>>>>>>>>>> <snap>
>>>>>>>>>>>>
>>>>>>>>>>>> My Encoding parameters for x264 are set in a function like this:
>>>>>>>>>>>>
>>>>>>>>>>>> bool h264_initEncoder(AVFormatContext* fc, tavtrack_t* track)
>>>>>>>>>>>> {
>>>>>>>>>>>> AVCodec* codec = NULL;
>>>>>>>>>>>> AVCodecContext* c = NULL;
>>>>>>>>>>>>
>>>>>>>>>>>> c = track->streamContext->codec;
>>>>>>>>>>>> c->profile = track->codec_context->profile; // original
>>>>>>>>>>>> set by
>>>>>>>>>>>> libavformat/libavcodec
>>>>>>>>>>>> c->level = track->codec_context->level; // original
>>>>>>>>>>>> set by
>>>>>>>>>>>> libavformat/libavcodec
>>>>>>>>>>>>
>>>>>>>>>>>> // Medium Profile
>>>>>>>>>>>> // libx264-medium.ffpreset preset
>>>>>>>>>>>> c->coder_type = FF_CODER_TYPE_AC; // coder = 1
>>>>>>>>>>>> c->flags |= CODEC_FLAG_LOOP_FILTER; // flags=+loop
>>>>>>>>>>>> c->me_cmp|= 1; //
>>>>>>>>>>>> cmp=+chroma, where CHROMA = 1
>>>>>>>>>>>> c->partitions |=
>>>>>>>>>>>> X264_PART_I8X8+X264_PART_I4X4+X264_PART_P8X8+X264_PART_B8X8;
>>>>>>>>>>>>
>>>>>>>>>>>> // partitions=+parti8x8+parti4x4+partp8x8+partb8x8
>>>>>>>>>>>> c->me_method=ME_HEX; //
>>>>>>>>>>>> me_method=hex
>>>>>>>>>>>> c->me_subpel_quality = 7; // subq=7
>>>>>>>>>>>> c->me_range = 16; //
>>>>>>>>>>>> me_range=16
>>>>>>>>>>>> //c->gop_size = 250; //
>>>>>>>>>>>> g=250
>>>>>>>>>>>> //c->keyint_min = 25; //
>>>>>>>>>>>> keyint_min=25
>>>>>>>>>>>> c->scenechange_threshold = 40; // sc_threshold=40
>>>>>>>>>>>> //c->i_quant_factor = 0.71; //
>>>>>>>>>>>> i_qfactor=0.71
>>>>>>>>>>>> //c->b_frame_strategy = 1; //
>>>>>>>>>>>> b_strategy=1
>>>>>>>>>>>> c->qcompress = 0.6; //
>>>>>>>>>>>> qcomp=0.6
>>>>>>>>>>>> c->qmin = 10; //
>>>>>>>>>>>> qmin=10
>>>>>>>>>>>> c->qmax = 51; //
>>>>>>>>>>>> qmax=51
>>>>>>>>>>>> c->max_qdiff = 4; //
>>>>>>>>>>>> qdiff=4
>>>>>>>>>>>> c->max_b_frames = 3; // bf=3
>>>>>>>>>>>> c->refs = 3; //
>>>>>>>>>>>> refs=3
>>>>>>>>>>>> //c->directpred = 1; //
>>>>>>>>>>>> directpred=1
>>>>>>>>>>>> //c->trellis = 1;
>>>>>>>>>>>> //
>>>>>>>>>>>> trellis=1
>>>>>>>>>>>> c->flags2 |=
>>>>>>>>>>>> CODEC_FLAG2_BPYRAMID+CODEC_FLAG2_MIXED_REFS+CODEC_FLAG2_WPRED+CODEC_FLAG2_8X8DCT+CODEC_FLAG2_FASTPSKIP;
>>>>>>>>>>>>
>>>>>>>>>>>> // flags2=+bpyramid+mixed_refs+wpred+dct8x8+fastpskip
>>>>>>>>>>>> c->weighted_p_pred = 2; // wpredp=2
>>>>>>>>>>>>
>>>>>>>>>>>> // libx264-main.ffpreset preset
>>>>>>>>>>>> //c->flags2|=CODEC_FLAG2_8X8DCT;
>>>>>>>>>>>> //c->flags2^=CODEC_FLAG2_8X8DCT; //
>>>>>>>>>>>> flags2=-dct8x8
>>>>>>>>>>>> c->crf = 22;
>>>>>>>>>>>> codec = avcodec_find_encoder(c->codec_id);
>>>>>>>>>>>> if (!codec)
>>>>>>>>>>>> return false;
>>>>>>>>>>>>
>>>>>>>>>>>> if (avcodec_open(c, codec) < 0)
>>>>>>>>>>>> return false;
>>>>>>>>>>>>
>>>>>>>>>>>> return true;
>>>>>>>>>>>> }
>>>>>>>>>>>>
>>>>>>>>>>>> The Problem is, that the avcode_encode_video( ... ) works but no
>>>>>>>>>>>> frame will
>>>>>>>>>>>> be compressed. I get strange errors like this:
>>>>>>>>>>>>
>>>>>>>>>>>> [libx264 @ 0x101003600] specified frame type (5) at 0 is not
>>>>>>>>>>>> compatible
>>>>>>>>>>>> with keyframe interval
>>>>>>>>>>>> [libx264 @ 0x101003600] specified frame type (5) at 1 is not
>>>>>>>>>>>> compatible
>>>>>>>>>>>> with keyframe interval
>>>>>>>>>>>> [libx264 @ 0x101003600] specified frame type (3) at 2 is not
>>>>>>>>>>>> compatible
>>>>>>>>>>>> with keyframe interval
>>>>>>>>>>>>
>>>>>>>>>>>> I get no frame. But why? Does anybody has an hint for me? Are my
>>>>>>>>>>>> parameters
>>>>>>>>>>>> wrong?
>>>>>>>>>>>>
>>>>>>>>>>>> regards,
>>>>>>>>>>>> Sven
>>>>>>>>>>>> _______________________________________________
>>>>>>>>>>>> libav-user mailing list
>>>>>>>>>>>> [email protected]
>>>>>>>>>>>> https://lists.mplayerhq.hu/mailman/listinfo/libav-user
>>>>>>>>>>>>
>>>>>>>>>>> _______________________________________________
>>>>>>>>>>> libav-user mailing list
>>>>>>>>>>> [email protected]
>>>>>>>>>>> https://lists.mplayerhq.hu/mailman/listinfo/libav-user
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> Gautam Muralidhar
>>>>>>>>>> Code Particle Inc.
>>>>>>>>>> (805)-501-0700
>>>>>>>>>> _______________________________________________
>>>>>>>>>> libav-user mailing list
>>>>>>>>>> [email protected]
>>>>>>>>>> https://lists.mplayerhq.hu/mailman/listinfo/libav-user
>>>>>>>>>
>>>>>>>>> _______________________________________________
>>>>>>>>> libav-user mailing list
>>>>>>>>> [email protected]
>>>>>>>>> https://lists.mplayerhq.hu/mailman/listinfo/libav-user
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Gautam Muralidhar
>>>>>>>> Code Particle Inc.
>>>>>>>> (805)-501-0700
>>>>>>>> _______________________________________________
>>>>>>>> libav-user mailing list
>>>>>>>> [email protected]
>>>>>>>> https://lists.mplayerhq.hu/mailman/listinfo/libav-user
>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> libav-user mailing list
>>>>>>> [email protected]
>>>>>>> https://lists.mplayerhq.hu/mailman/listinfo/libav-user
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Gautam Muralidhar
>>>>>> Code Particle Inc.
>>>>>> (805)-501-0700
>>>>>> _______________________________________________
>>>>>> libav-user mailing list
>>>>>> [email protected]
>>>>>> https://lists.mplayerhq.hu/mailman/listinfo/libav-user
>>>>>
>>>>> _______________________________________________
>>>>> libav-user mailing list
>>>>> [email protected]
>>>>> https://lists.mplayerhq.hu/mailman/listinfo/libav-user
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Gautam Muralidhar
>>>> Code Particle Inc.
>>>> (805)-501-0700
>>>> _______________________________________________
>>>> libav-user mailing list
>>>> [email protected]
>>>> https://lists.mplayerhq.hu/mailman/listinfo/libav-user
>>>
>>> _______________________________________________
>>> libav-user mailing list
>>> [email protected]
>>> https://lists.mplayerhq.hu/mailman/listinfo/libav-user
>>>
>>
>>
>>
>> --
>> Gautam Muralidhar
>> Code Particle Inc.
>> (805)-501-0700
>> _______________________________________________
>> libav-user mailing list
>> [email protected]
>> https://lists.mplayerhq.hu/mailman/listinfo/libav-user
>
> _______________________________________________
> libav-user mailing list
> [email protected]
> https://lists.mplayerhq.hu/mailman/listinfo/libav-user
>
--
Gautam Muralidhar
Code Particle Inc.
(805)-501-0700
_______________________________________________
libav-user mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/libav-user