static void encode_blind_full_flush(struct encoder_state *const s) { encode_flush(s,Z_FULL_FLUSH); // When there are no bits pending, Z_FULL_FLUSH is 5 bytes s->zlib.next_out -= 5; s->zlib.avail_out += 5; }
static int encode_end(struct encoder_state *s) { // Perform sync flush. It allows to transmit whole packet and // also provides a marker (00 00 FF FF) between packets. encode_flush(s, Z_SYNC_FLUSH); return s->size - s->zlib.avail_out; }
int seg_write_tailer(Segment_U * seg_union){ Output_Context *ptr_output_ctx = seg_union->output_ctx; chris_printf("before flush ,ptr_output_ctx->ptr_format_ctx->nb_streams = %d \n\n" ,ptr_output_ctx->ptr_format_ctx->nb_streams); encode_flush(ptr_output_ctx ,ptr_output_ctx->ptr_format_ctx->nb_streams); write_m3u8_tailer(ptr_output_ctx); chris_printf("before wirite tailer ...\n\n"); av_write_trailer(ptr_output_ctx->ptr_format_ctx ); return 0; }
int main(int argc ,char *argv[]){ /*first ,open input file ,and obtain input file information*/ INPUT_CONTEXT *ptr_input_ctx; if( (ptr_input_ctx = malloc (sizeof(INPUT_CONTEXT))) == NULL){ printf("ptr_input_ctx malloc failed .\n"); exit(MEMORY_MALLOC_FAIL); } /*second ,open output file ,and set output file information*/ OUTPUT_CONTEXT *ptr_output_ctx; if( (ptr_output_ctx = malloc (sizeof(OUTPUT_CONTEXT))) == NULL){ printf("ptr_output_ctx malloc failed .\n"); exit(MEMORY_MALLOC_FAIL); } //init inputfile ,and get input file information init_input(ptr_input_ctx ,argv[1]); //init oputfile ,and set output file information init_output(ptr_output_ctx ,argv[2] ,ptr_input_ctx); //open video and audio ,set video_out_buf and audio_out_buf open_stream_codec(ptr_output_ctx); // open the output file, if needed if (!(ptr_output_ctx->fmt->flags & AVFMT_NOFILE)) { //for mp4 or mpegts ,this must be performed if (avio_open(&ptr_output_ctx->ptr_format_ctx->pb, argv[2], AVIO_FLAG_WRITE) < 0) { fprintf(stderr, "Could not open '%s'\n", argv[2]); exit(OPEN_MUX_FILE_FAIL); } } // write the stream header, if any avformat_write_header(ptr_output_ctx->ptr_format_ctx ,NULL); printf("ptr_output_ctx->ptr_format_ctx->nb_streams = %d \n\n" ,ptr_output_ctx->ptr_format_ctx->nb_streams); //streams number in output file ptr_output_ctx->img_convert_ctx = sws_getContext( ptr_input_ctx->video_codec_ctx->width ,ptr_input_ctx->video_codec_ctx->height ,PIX_FMT_YUV420P, ptr_output_ctx->video_stream->codec->width ,ptr_output_ctx->video_stream->codec->height ,PIX_FMT_YUV420P , SWS_BICUBIC ,NULL ,NULL ,NULL); printf("src_width = %d ,src_height = %d \n" ,ptr_input_ctx->video_codec_ctx->width ,ptr_input_ctx->video_codec_ctx->height); printf("dts_width = %d ,dts_height = %d \n" ,ptr_output_ctx->video_stream->codec->width , ptr_output_ctx->video_stream->codec->height); // while(1); printf("before av_read_frame ...\n"); /*************************************************************************************/ /*decoder loop*/ // // //***********************************************************************************/ while(av_read_frame(ptr_input_ctx->ptr_format_ctx ,&ptr_input_ctx->pkt) >= 0){ if (ptr_input_ctx->pkt.stream_index == ptr_input_ctx->video_index) { #if 1 //decode video packet int got_picture = 0; ptr_input_ctx->mark_have_frame = 0; avcodec_decode_video2(ptr_input_ctx->video_codec_ctx, ptr_input_ctx->yuv_frame, &got_picture, &ptr_input_ctx->pkt); if (got_picture) { //encode video ptr_output_ctx->sync_ipts = av_q2d(ptr_input_ctx->ptr_format_ctx->streams[ptr_input_ctx->video_index]->time_base) * (ptr_input_ctx->yuv_frame->best_effort_timestamp ) - (double)ptr_input_ctx->ptr_format_ctx->start_time / AV_TIME_BASE; //first swscale sws_scale(ptr_output_ctx->img_convert_ctx , (const uint8_t* const*)ptr_input_ctx->yuv_frame->data ,ptr_input_ctx->yuv_frame->linesize , 0 , ptr_input_ctx->video_codec_ctx->height , ptr_output_ctx->encoded_yuv_pict->data ,ptr_output_ctx->encoded_yuv_pict->linesize); //second swscale encode_video_frame(ptr_output_ctx , ptr_output_ctx->encoded_yuv_pict ,ptr_input_ctx); } #endif } else if (ptr_input_ctx->pkt.stream_index == ptr_input_ctx->audio_index) { #if 1 //decode audio packet while (ptr_input_ctx->pkt.size > 0) { int got_frame = 0; int len = avcodec_decode_audio4(ptr_input_ctx->audio_codec_ctx, ptr_input_ctx->audio_decode_frame, &got_frame, &ptr_input_ctx->pkt); if (len < 0) { //decode failed ,skip frame fprintf(stderr, "Error while decoding audio frame\n"); break; } if (got_frame) { //acquire the large of the decoded audio info... int data_size = av_samples_get_buffer_size(NULL, ptr_input_ctx->audio_codec_ctx->channels, ptr_input_ctx->audio_decode_frame->nb_samples, ptr_input_ctx->audio_codec_ctx->sample_fmt, 1); ptr_input_ctx->audio_size = data_size; //audio data size //encode audio int frame_bytes = ptr_output_ctx->audio_stream->codec->frame_size * av_get_bytes_per_sample(ptr_output_ctx->audio_stream->codec->sample_fmt) * ptr_output_ctx->audio_stream->codec->channels; uint8_t * audio_buf = ptr_input_ctx->audio_decode_frame->data[0]; while (data_size >= frame_bytes) { encode_audio_frame(ptr_output_ctx ,audio_buf ,frame_bytes /*data_size*/); // data_size -= frame_bytes; audio_buf += frame_bytes; } } else { //no data printf("======>avcodec_decode_audio4 ,no data ..\n"); continue; } ptr_input_ctx->pkt.size -= len; ptr_input_ctx->pkt.data += len; } #endif } }//endwhile printf("before flush ,ptr_output_ctx->ptr_format_ctx->nb_streams = %d \n\n" ,ptr_output_ctx->ptr_format_ctx->nb_streams); encode_flush(ptr_output_ctx ,ptr_output_ctx->ptr_format_ctx->nb_streams); printf("before wirite tailer ...\n\n"); av_write_trailer(ptr_output_ctx->ptr_format_ctx ); /*free memory*/ }
/* Process a buffer (including reencoding or encoding, if desired). * Returns: >0 - success * 0 - shout error occurred * -1 - no data produced * -2 - fatal error occurred */ int process_and_send_buffer(stream_description *sdsc, ref_buffer *buffer) { if(sdsc->reenc) { unsigned char *buf; int buflen,ret; ret = reencode_page(sdsc->reenc, buffer, &buf, &buflen); if(ret > 0) { ret = stream_send_data(sdsc, buf, buflen); free(buf); return ret; } else if(ret==0) /* No data produced by reencode */ return -1; else { LOG_ERROR0("Fatal reencoding error encountered"); return -2; } } else if (sdsc->enc) { ogg_page og; int be = (sdsc->input->subtype == INPUT_PCM_BE_16)?1:0; int ret=1; /* We use critical as a flag to say 'start a new stream' */ if(buffer->critical) { if(sdsc->resamp) { resample_finish(sdsc->resamp); encode_data_float(sdsc->enc, sdsc->resamp->buffers, sdsc->resamp->buffill); resample_clear(sdsc->resamp); sdsc->resamp = resample_initialise (sdsc->stream->channels, sdsc->stream->resampleinrate, sdsc->stream->resampleoutrate); } encode_finish(sdsc->enc); while(encode_flush(sdsc->enc, &og) != 0) { if ((ret = stream_send_data(sdsc, og.header, og.header_len)) == 0) return 0; if ((ret = stream_send_data(sdsc, og.body, og.body_len)) == 0) return 0; } encode_clear(sdsc->enc); if(sdsc->input->metadata_update) { vorbis_comment_clear(&sdsc->vc); vorbis_comment_init(&sdsc->vc); sdsc->input->metadata_update(sdsc->input->internal, &sdsc->vc); } sdsc->enc = encode_initialise(sdsc->stream->channels, sdsc->stream->samplerate, sdsc->stream->managed, sdsc->stream->min_br, sdsc->stream->nom_br, sdsc->stream->max_br, sdsc->stream->quality, &sdsc->vc); if(!sdsc->enc) { LOG_ERROR0("Failed to initialise encoder"); return -2; } sdsc->enc->max_samples_ppage = sdsc->stream->max_samples_ppage; } if(sdsc->downmix) { downmix_buffer(sdsc->downmix, (signed char *)buffer->buf, buffer->len, be); if(sdsc->resamp) { resample_buffer_float(sdsc->resamp, &sdsc->downmix->buffer, buffer->len/4); encode_data_float(sdsc->enc, sdsc->resamp->buffers, sdsc->resamp->buffill); } else encode_data_float(sdsc->enc, &sdsc->downmix->buffer, buffer->len/4); } else if(sdsc->resamp) { resample_buffer(sdsc->resamp, (signed char *)buffer->buf, buffer->len, be); encode_data_float(sdsc->enc, sdsc->resamp->buffers, sdsc->resamp->buffill); } else { encode_data(sdsc->enc, (signed char *)(buffer->buf), buffer->len, be); } while(encode_dataout(sdsc->enc, &og) > 0) { if ((ret = stream_send_data(sdsc, og.header, og.header_len)) == 0) return 0; if ((ret = stream_send_data(sdsc, og.body, og.body_len)) == 0) return 0; } return ret; } else return stream_send_data(sdsc, buffer->buf, buffer->len); }
int main(int argc ,char *argv[]){ /*first ,open input file ,and obtain input file information*/ INPUT_CONTEXT *ptr_input_ctx; if( (ptr_input_ctx = malloc (sizeof(INPUT_CONTEXT))) == NULL){ printf("ptr_input_ctx malloc failed .\n"); exit(MEMORY_MALLOC_FAIL); } /*second ,open output file ,and set output file information*/ OUTPUT_CONTEXT *ptr_output_ctx; if( (ptr_output_ctx = malloc (sizeof(OUTPUT_CONTEXT))) == NULL){ printf("ptr_output_ctx malloc failed .\n"); exit(MEMORY_MALLOC_FAIL); } //init inputfile ,and get input file information init_input(ptr_input_ctx ,argv[1]); //init oputfile ,and set output file information init_output(ptr_output_ctx ,argv[2] ,ptr_input_ctx); ptr_output_ctx->fifo = av_fifo_alloc(1024); if (!ptr_output_ctx->fifo) { exit (1); } av_log(NULL, AV_LOG_WARNING ,"--av_fifo_size(ost->fifo) = %d \n" ,av_fifo_size(ptr_output_ctx->fifo)); //输出是0?! //open video and audio ,set video_out_buf and audio_out_buf open_stream_codec(ptr_output_ctx); // open the output file, if needed if (!(ptr_output_ctx->fmt->flags & AVFMT_NOFILE)) { //for mp4 or mpegts ,this must be performed if (avio_open(&ptr_output_ctx->ptr_format_ctx->pb, argv[2], AVIO_FLAG_WRITE) < 0) { fprintf(stderr, "Could not open '%s'\n", argv[2]); exit(OPEN_MUX_FILE_FAIL); } } // write the stream header, if any avformat_write_header(ptr_output_ctx->ptr_format_ctx ,NULL); printf("ptr_output_ctx->ptr_format_ctx->nb_streams = %d \n\n" ,ptr_output_ctx->ptr_format_ctx->nb_streams); //streams number in output file // while(1); printf("before av_read_frame ...\n"); /*************************************************************************************/ /*decoder loop*/ // // //***********************************************************************************/ while(av_read_frame(ptr_input_ctx->ptr_format_ctx ,&ptr_input_ctx->pkt) >= 0){ if (ptr_input_ctx->pkt.stream_index == ptr_input_ctx->audio_index) { // printf("HAHA.................\n"); #if 1 //decode audio packet while (ptr_input_ctx->pkt.size > 0) { int got_frame = 0; int len = avcodec_decode_audio4(ptr_input_ctx->audio_codec_ctx, ptr_input_ctx->audio_decode_frame, &got_frame, &ptr_input_ctx->pkt); if (len < 0) { //decode failed ,skip frame fprintf(stderr, "Error while decoding audio frame\n"); break; } if (got_frame) { //encode the audio data ,and write the data into the output do_audio_out(ptr_output_ctx ,ptr_input_ctx ,ptr_input_ctx->audio_decode_frame); } else { //no data printf("======>avcodec_decode_audio4 ,no data ..\n"); continue; } ptr_input_ctx->pkt.size -= len; ptr_input_ctx->pkt.data += len; } #endif } }//endwhile printf("before flush ,ptr_output_ctx->ptr_format_ctx->nb_streams = %d \n\n" ,ptr_output_ctx->ptr_format_ctx->nb_streams); encode_flush(ptr_output_ctx ,ptr_output_ctx->ptr_format_ctx->nb_streams); printf("before wirite tailer ...\n\n"); av_write_trailer(ptr_output_ctx->ptr_format_ctx ); /*free memory*/ }
static void encode(struct encoder_state *s, void *src, const int n) { s->zlib.next_in = src; s->zlib.avail_in = n; encode_flush(s, Z_NO_FLUSH); }
int seg_transcode_main(Segment_U * seg_union){ Output_Context *ptr_output_ctx = seg_union->output_ctx; if (!(ptr_output_ctx->fmt->flags & AVFMT_NOFILE)) { //for mp4 or mpegts ,this must be performed if (avio_open(&(ptr_output_ctx->ptr_format_ctx->pb), seg_union->ts_name, AVIO_FLAG_WRITE) < 0) { fprintf(stderr, "Could not open '%s'\n", seg_union->ts_name); exit(OPEN_MUX_FILE_FAIL); } } // write the stream header, if any avformat_write_header(ptr_output_ctx->ptr_format_ctx ,NULL); write_m3u8_header(ptr_output_ctx); int i ; for(i = 0 ; i < seg_union->input_nb ; i ++){ /*initialize input file information*/ init_input( seg_union->input_ctx ,seg_union->input_file[i]); Input_Context *ptr_input_ctx = seg_union->input_ctx; ptr_output_ctx->img_convert_ctx = sws_getContext( ptr_input_ctx->video_codec_ctx->width ,ptr_input_ctx->video_codec_ctx->height ,PIX_FMT_YUV420P, ptr_output_ctx->video_stream->codec->width ,ptr_output_ctx->video_stream->codec->height ,PIX_FMT_YUV420P , SWS_BICUBIC ,NULL ,NULL ,NULL); printf("src_width = %d ,src_height = %d \n" ,ptr_input_ctx->video_codec_ctx->width ,ptr_input_ctx->video_codec_ctx->height); printf("dts_width = %d ,dts_height = %d \n" ,ptr_output_ctx->video_stream->codec->width , ptr_output_ctx->video_stream->codec->height); printf("before av_read_frame ...\n"); /*************************************************************************************/ /*decoder loop*/ // // //***********************************************************************************/ while(av_read_frame(ptr_input_ctx->ptr_format_ctx ,&ptr_input_ctx->pkt) >= 0){ if (ptr_input_ctx->pkt.stream_index == ptr_input_ctx->video_index) { //decode video packet int got_picture = 0; avcodec_decode_video2(ptr_input_ctx->video_codec_ctx, ptr_input_ctx->yuv_frame, &got_picture, &ptr_input_ctx->pkt); if (got_picture) { //encode video //input stream 的问题。 ptr_output_ctx->sync_ipts = av_q2d(ptr_input_ctx->ptr_format_ctx->streams[ptr_input_ctx->video_index]->time_base) * (ptr_input_ctx->yuv_frame->best_effort_timestamp ) - (double)ptr_input_ctx->ptr_format_ctx->start_time / AV_TIME_BASE + ptr_output_ctx->base_ipts; //current packet time in second //printf("ptr_output_ctx->sync_ipts = %f \n" ,ptr_output_ctx->sync_ipts); //first swscale sws_scale(ptr_output_ctx->img_convert_ctx , (const uint8_t* const*)ptr_input_ctx->yuv_frame->data ,ptr_input_ctx->yuv_frame->linesize , 0 , ptr_input_ctx->video_codec_ctx->height , ptr_output_ctx->encoded_yuv_pict->data ,ptr_output_ctx->encoded_yuv_pict->linesize); //second swscale encode_video_frame(ptr_output_ctx , ptr_output_ctx->encoded_yuv_pict ,ptr_input_ctx ); } } else if (ptr_input_ctx->pkt.stream_index == ptr_input_ctx->audio_index) { //printf("audio ...\n"); //decode audio packet uint8_t *tmp_data = ptr_input_ctx->pkt.data; int tmp_size = ptr_input_ctx->pkt.size; while (ptr_input_ctx->pkt.size > 0) { int got_frame = 0; int len = avcodec_decode_audio4(ptr_input_ctx->audio_codec_ctx, ptr_input_ctx->audio_decode_frame, &got_frame, &ptr_input_ctx->pkt); if (len < 0) { //decode failed ,skip frame fprintf(stderr, "Error while decoding audio frame\n"); break; } if (got_frame) { //encode the audio data ,and write the data into the output // do_audio_out(ptr_output_ctx ,ptr_input_ctx ,ptr_input_ctx->audio_decode_frame); } else { //no data printf("======>avcodec_decode_audio4 ,no data ..\n"); continue; } ptr_input_ctx->pkt.size -= len; ptr_input_ctx->pkt.data += len; } //renew ptr_input_ctx->pkt.size = tmp_size; ptr_input_ctx->pkt.data = tmp_data; } if(&ptr_input_ctx->pkt) av_free_packet(&ptr_input_ctx->pkt); }//endwhile double file_duration = ptr_input_ctx->ptr_format_ctx->duration / AV_TIME_BASE + (double)( ptr_input_ctx->ptr_format_ctx->duration % AV_TIME_BASE ) / AV_TIME_BASE; ptr_output_ctx->base_ipts += file_duration; //completed files sum time duration printf("end while ......,time_base = %f .............> \n" ,ptr_output_ctx->base_ipts ); ptr_output_ctx->audio_resample = 0; sws_freeContext(ptr_output_ctx->img_convert_ctx); free_input(ptr_input_ctx); } //end for printf("before flush ,ptr_output_ctx->ptr_format_ctx->nb_streams = %d \n\n" ,ptr_output_ctx->ptr_format_ctx->nb_streams); encode_flush(ptr_output_ctx ,ptr_output_ctx->ptr_format_ctx->nb_streams); write_m3u8_tailer(ptr_output_ctx); printf("before wirite tailer ...\n\n"); av_write_trailer(ptr_output_ctx->ptr_format_ctx ); return 0; }