| 1 | #include <QTime>
|
|---|
| 2 | #include "converter.h"
|
|---|
| 3 | #include "loadershell.h"
|
|---|
| 4 |
|
|---|
| 5 | using namespace std;
|
|---|
| 6 |
|
|---|
| 7 | QString Converter::m_outputName;
|
|---|
| 8 | QFile Converter::fileOutput;
|
|---|
| 9 |
|
|---|
| 10 | Converter::Converter(QObject *parent) : QThread(parent)
|
|---|
| 11 | {
|
|---|
| 12 | m_bytesTotal = 0;
|
|---|
| 13 | m_bytesReceived = 0;
|
|---|
| 14 | hasAudio = false;
|
|---|
| 15 | hasVideo = false;
|
|---|
| 16 | bufferData = nullptr;
|
|---|
| 17 | bufferData_input = nullptr;
|
|---|
| 18 | avio_ctx = nullptr;
|
|---|
| 19 | avio_ctx_input = nullptr;
|
|---|
| 20 | fmt_ctx = nullptr;
|
|---|
| 21 | ofmt_ctx = nullptr;
|
|---|
| 22 |
|
|---|
| 23 | streamAudio = nullptr;
|
|---|
| 24 | out_stream_audio = nullptr;
|
|---|
| 25 | decoderAudio_ctx = nullptr;
|
|---|
| 26 | encoderAudio_ctx = nullptr;
|
|---|
| 27 | decoderAudio = nullptr;
|
|---|
| 28 | encoderAudio = nullptr;
|
|---|
| 29 | frame = nullptr;
|
|---|
| 30 | swrContext = nullptr;
|
|---|
| 31 | output_audio_frame = nullptr;
|
|---|
| 32 | output_audio_packet = nullptr;
|
|---|
| 33 | audioSampleBuffer = nullptr;
|
|---|
| 34 |
|
|---|
| 35 | streamVideo = nullptr;
|
|---|
| 36 | out_stream_video = nullptr;
|
|---|
| 37 | decoderVideo_ctx = nullptr;
|
|---|
| 38 | encoderVideo_ctx = nullptr;
|
|---|
| 39 | decoderVideo = nullptr;
|
|---|
| 40 | encoderVideo = nullptr;
|
|---|
| 41 |
|
|---|
| 42 | audio_stream_index = -1;
|
|---|
| 43 | video_stream_index = -1;
|
|---|
| 44 | output_audio_stream_index = -1;
|
|---|
| 45 | output_video_stream_index = -1;
|
|---|
| 46 |
|
|---|
| 47 | m_handle = Q_NULLPTR;
|
|---|
| 48 | m_bytesTotal = 0;
|
|---|
| 49 | m_bytesReceived = 0;
|
|---|
| 50 | m_downloadProgress = 0.0f;
|
|---|
| 51 |
|
|---|
| 52 | connect(this, &Converter::finished, &LoaderShell::get(), &LoaderShell::convertFinished);
|
|---|
| 53 | connect(this, &Converter::finished, this, &QObject::deleteLater);
|
|---|
| 54 | }
|
|---|
| 55 |
|
|---|
| 56 | void Converter::setTorrentHandle(TorrentHandle *value) {
|
|---|
| 57 | if(m_handle != value) {
|
|---|
| 58 | m_handle = value;
|
|---|
| 59 | if(m_handle) {
|
|---|
| 60 | setBytesTotal(m_handle->bytesTotal());
|
|---|
| 61 | }
|
|---|
| 62 | }
|
|---|
| 63 | }
|
|---|
| 64 |
|
|---|
| 65 | void Converter::run()
|
|---|
| 66 | {
|
|---|
| 67 | if(!m_handle) {
|
|---|
| 68 | qDebug() << "Error: Converter::run handle is NULL";
|
|---|
| 69 | return;
|
|---|
| 70 | }
|
|---|
| 71 | if(m_inputName.isEmpty()) return;
|
|---|
| 72 | if(m_outputName.isEmpty()) return;
|
|---|
| 73 | while(false == QFileInfo::exists(m_inputName) ||
|
|---|
| 74 | m_downloadProgress < 0.02f ||
|
|---|
| 75 | !m_handle->firstLastBlocksFinsihed())
|
|---|
| 76 | {
|
|---|
| 77 | sleep(5);
|
|---|
| 78 | }
|
|---|
| 79 |
|
|---|
| 80 | qDebug() << "Converter wait m_downloadProgress="<<m_downloadProgress
|
|---|
| 81 | << "file::exists(" << m_inputName
|
|---|
| 82 | << ")=" << QFileInfo::exists(m_inputName);
|
|---|
| 83 |
|
|---|
| 84 | // QTime time;
|
|---|
| 85 | // time.start();
|
|---|
| 86 |
|
|---|
| 87 | logFile.open("log.txt");
|
|---|
| 88 | int ret = 0;
|
|---|
| 89 |
|
|---|
| 90 | qDebug() << "inputName="<<m_inputName;
|
|---|
| 91 | qDebug() << "m_outputName="<<m_outputName;
|
|---|
| 92 |
|
|---|
| 93 | if (open(m_inputName.toStdString().c_str()) != 0 ||
|
|---|
| 94 | open_destination (m_outputName.toStdString().c_str()) != 0)
|
|---|
| 95 | {
|
|---|
| 96 | return;
|
|---|
| 97 | }
|
|---|
| 98 |
|
|---|
| 99 | logFile << "\n"<< "open files end";
|
|---|
| 100 |
|
|---|
| 101 | transcode();
|
|---|
| 102 | logFile << "\n"<< "transcode end";
|
|---|
| 103 |
|
|---|
| 104 | writeBuffer(bufferData);
|
|---|
| 105 |
|
|---|
| 106 |
|
|---|
| 107 | avformat_close_input(&fmt_ctx);
|
|---|
| 108 | avformat_free_context(ofmt_ctx);
|
|---|
| 109 |
|
|---|
| 110 | //close file
|
|---|
| 111 | fileOutput.close();
|
|---|
| 112 |
|
|---|
| 113 |
|
|---|
| 114 | // av_freep(&stream_mapping);
|
|---|
| 115 |
|
|---|
| 116 | logFile << "\n"<< "close end";
|
|---|
| 117 | // qDebug() << "time.elapsed(ms) = "<< time.elapsed();
|
|---|
| 118 | // qDebug() << "time.elapsed = "<< QTime::fromMSecsSinceStartOfDay(time.elapsed());
|
|---|
| 119 |
|
|---|
| 120 | qDebug() << "\n"<< "close end";
|
|---|
| 121 | }
|
|---|
| 122 |
|
|---|
| 123 |
|
|---|
| 124 | bool Converter::writeBuffer(BufferData *bufferData)
|
|---|
| 125 | {
|
|---|
| 126 | if(!bufferData) {
|
|---|
| 127 | qDebug()<< "writeBuffer bufferData is NULL";
|
|---|
| 128 | return false;
|
|---|
| 129 | }
|
|---|
| 130 |
|
|---|
| 131 | // qDebug() << "isOpen ? "<< fileOutput.isOpen();
|
|---|
| 132 | if(!fileOutput.isOpen()) {
|
|---|
| 133 | fileOutput.setFileName(m_outputName);
|
|---|
| 134 | if( !fileOutput.open(QIODevice::WriteOnly | QIODevice::Truncate) ) {
|
|---|
| 135 | return -1;
|
|---|
| 136 | }
|
|---|
| 137 | }
|
|---|
| 138 |
|
|---|
| 139 | LoaderShell::get().sendData(bufferData->data, bufferData->fullsize);
|
|---|
| 140 | fileOutput.write(bufferData->data);
|
|---|
| 141 | bufferData->writeSize = 0;
|
|---|
| 142 | bufferData->data.clear();
|
|---|
| 143 |
|
|---|
| 144 | qDebug()<<"FILE SIZE = " << fileOutput.size()/1024/1024;
|
|---|
| 145 | return true;
|
|---|
| 146 | }
|
|---|
| 147 |
|
|---|
| 148 |
|
|---|
| 149 | int Converter::read_packet_to_buffer(void *opaque, uint8_t *buf, int buf_size)
|
|---|
| 150 | {
|
|---|
| 151 | qDebug() << "read_packet_to_buffer buf_size"<<buf_size;
|
|---|
| 152 | BufferData *bufData = static_cast<BufferData*>(opaque);
|
|---|
| 153 |
|
|---|
| 154 | if(!bufData) {
|
|---|
| 155 | qDebug()<< "Error bufferData NULL";
|
|---|
| 156 | return buf_size;
|
|---|
| 157 | }
|
|---|
| 158 | bufData->fullsize += buf_size;
|
|---|
| 159 | qDebug()<<"read fullsize="<<bufData->fullsize/1024/1024 << "Mb";
|
|---|
| 160 |
|
|---|
| 161 | bufData->data.append((const char*)buf, buf_size);
|
|---|
| 162 | return buf_size;
|
|---|
| 163 | }
|
|---|
| 164 |
|
|---|
| 165 | int Converter::write_packet_to_buffer(void *opaque, uint8_t *buf, int buf_size)
|
|---|
| 166 | {
|
|---|
| 167 | // qDebug() << "write_packet_to_buffer buf_size"<<buf_size;
|
|---|
| 168 | BufferData *bufData = static_cast<BufferData*>(opaque);
|
|---|
| 169 |
|
|---|
| 170 | if(!bufData) {
|
|---|
| 171 | qDebug()<< "Error bufferData NULL";
|
|---|
| 172 | return buf_size;
|
|---|
| 173 | }
|
|---|
| 174 | bufData->fullsize += buf_size;
|
|---|
| 175 | bufData->writeSize += buf_size;
|
|---|
| 176 | // qDebug()<<"write fullsize="<<bufData->fullsize/1024/1024 << "Mb";
|
|---|
| 177 | // bufferData->stream << "write: "<<buf_size <<" full: " << bufferData->fullsize << endl;
|
|---|
| 178 |
|
|---|
| 179 | bufData->data.append((const char*)buf, buf_size);
|
|---|
| 180 | qDebug() << "writeBuffer = "<<QByteArray((const char*)buf, buf_size).toHex();
|
|---|
| 181 |
|
|---|
| 182 |
|
|---|
| 183 | // bufferData->stream << "write: "<<buf_size <<" full: " << bufferData->data.size() << endl;
|
|---|
| 184 |
|
|---|
| 185 | if(bufData->writeSize >= 1024*1024) {
|
|---|
| 186 | qDebug() << "writeFIle";
|
|---|
| 187 | writeBuffer(bufData);
|
|---|
| 188 | }
|
|---|
| 189 |
|
|---|
| 190 | return buf_size;
|
|---|
| 191 | }
|
|---|
| 192 |
|
|---|
| 193 |
|
|---|
| 194 | void Converter::createBufferInput(const char* input_filename)
|
|---|
| 195 | {
|
|---|
| 196 | //---------------------- BUFFER -------------------------
|
|---|
| 197 | qDebug() << "createBufferInput "<<input_filename;
|
|---|
| 198 | uint8_t* buffer = nullptr;
|
|---|
| 199 | uint8_t* avio_ctx_buffer = nullptr;
|
|---|
| 200 | size_t buffer_size;
|
|---|
| 201 | size_t avio_ctx_buffer_size = 4096;
|
|---|
| 202 | /* fill opaque structure used by the AVIOContext write callback */
|
|---|
| 203 |
|
|---|
| 204 | av_file_map(input_filename, &buffer, &buffer_size, 0, NULL);
|
|---|
| 205 | qDebug() << "createBufferInput av_file_map";
|
|---|
| 206 |
|
|---|
| 207 | avio_ctx_buffer = (uint8_t*)av_malloc(avio_ctx_buffer_size);
|
|---|
| 208 | if (!avio_ctx_buffer) return;
|
|---|
| 209 |
|
|---|
| 210 | if(bufferData_input) delete bufferData_input;
|
|---|
| 211 | bufferData_input = new BufferData();
|
|---|
| 212 | avio_ctx_input = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size,
|
|---|
| 213 | 1, bufferData_input,
|
|---|
| 214 | &Converter::read_packet_to_buffer,
|
|---|
| 215 | NULL, NULL);
|
|---|
| 216 | //------------------------------------------------------
|
|---|
| 217 | }
|
|---|
| 218 |
|
|---|
| 219 | void Converter::createBuffer()
|
|---|
| 220 | {
|
|---|
| 221 | //---------------------- BUFFER -------------------------
|
|---|
| 222 | uint8_t *avio_ctx_buffer = nullptr;
|
|---|
| 223 | const size_t avio_ctx_buffer_size = 4096;
|
|---|
| 224 | /* fill opaque structure used by the AVIOContext write callback */
|
|---|
| 225 | avio_ctx_buffer = (uint8_t*)av_malloc(avio_ctx_buffer_size);
|
|---|
| 226 | if (!avio_ctx_buffer) return;
|
|---|
| 227 |
|
|---|
| 228 | if(bufferData) delete bufferData;
|
|---|
| 229 | bufferData = new BufferData();
|
|---|
| 230 | qDebug()<<"byteArray =" << &bufferData;
|
|---|
| 231 | avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size,
|
|---|
| 232 | 1, bufferData, NULL,
|
|---|
| 233 | &Converter::write_packet_to_buffer, NULL);
|
|---|
| 234 | //------------------------------------------------------
|
|---|
| 235 | }
|
|---|
| 236 |
|
|---|
| 237 | void Converter::createSWR()
|
|---|
| 238 | {
|
|---|
| 239 | if(!hasAudio) return;
|
|---|
| 240 | swrContext = swr_alloc_set_opts(nullptr,
|
|---|
| 241 | encoderAudio_ctx->channel_layout,
|
|---|
| 242 | encoderAudio_ctx->sample_fmt,
|
|---|
| 243 | encoderAudio_ctx->sample_rate,
|
|---|
| 244 | decoderAudio_ctx->channel_layout,
|
|---|
| 245 | decoderAudio_ctx->sample_fmt,
|
|---|
| 246 | decoderAudio_ctx->sample_rate,
|
|---|
| 247 | 0, nullptr );
|
|---|
| 248 |
|
|---|
| 249 | // swrContext = swr_alloc();
|
|---|
| 250 | // if (!swrContext) {
|
|---|
| 251 | // logFile << "\n"<<"Could not allocate resampler context";
|
|---|
| 252 | // }
|
|---|
| 253 | // //in
|
|---|
| 254 | // av_opt_set_int(swrContext, "in_channel_count", decoderAudio_ctx->channels, 0);
|
|---|
| 255 | // av_opt_set_int(swrContext, "in_sample_rate", decoderAudio_ctx->sample_rate, 0);
|
|---|
| 256 | // av_opt_set_sample_fmt(swrContext, "in_sample_fmt", decoderAudio_ctx->sample_fmt, 0);
|
|---|
| 257 | // //out
|
|---|
| 258 | // av_opt_set_int(swrContext, "out_channel_count", encoderAudio_ctx->channels, 0);
|
|---|
| 259 | // av_opt_set_int(swrContext, "out_sample_rate", encoderAudio_ctx->sample_rate, 0);
|
|---|
| 260 | // av_opt_set_sample_fmt(swrContext, "out_sample_fmt", encoderAudio_ctx->sample_fmt, 0);
|
|---|
| 261 |
|
|---|
| 262 | // char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
|
|---|
| 263 | int res = 0;
|
|---|
| 264 | if ((res = swr_init(swrContext)) < 0) {
|
|---|
| 265 | logFile << "\n"<<"Audio Error: Unable to swr_init for capture, error ="<<res;
|
|---|
| 266 | return;
|
|---|
| 267 | }
|
|---|
| 268 |
|
|---|
| 269 | // Create a tempory audio frame to write the resampled data to.
|
|---|
| 270 | output_audio_frame = av_frame_alloc();
|
|---|
| 271 | output_audio_frame->pts = 0;
|
|---|
| 272 | output_audio_frame->nb_samples = encoderAudio_ctx->sample_rate;
|
|---|
| 273 | output_audio_frame->channels = encoderAudio_ctx->channels;
|
|---|
| 274 | output_audio_frame->channel_layout = encoderAudio_ctx->channel_layout;
|
|---|
| 275 | output_audio_frame->format = encoderAudio_ctx->sample_fmt;
|
|---|
| 276 | output_audio_frame->sample_rate = encoderAudio_ctx->sample_rate;
|
|---|
| 277 | output_audio_packet = av_packet_alloc();
|
|---|
| 278 |
|
|---|
| 279 | if(av_frame_get_buffer(output_audio_frame, 0) < 0)
|
|---|
| 280 | qDebug("Could not allocate audio frame data.");
|
|---|
| 281 |
|
|---|
| 282 |
|
|---|
| 283 | audioSampleBuffer = av_audio_fifo_alloc(encoderAudio_ctx->sample_fmt,
|
|---|
| 284 | encoderAudio_ctx->channels,
|
|---|
| 285 | encoderAudio_ctx->frame_size);
|
|---|
| 286 | }
|
|---|
| 287 |
|
|---|
| 288 | /**
|
|---|
| 289 | * Open video source and setup for demuxing and transcoding.
|
|---|
| 290 | * Returns non-zero on error.
|
|---|
| 291 | */
|
|---|
| 292 | int Converter::open(const char* source)
|
|---|
| 293 | {
|
|---|
| 294 | int ret = 0;
|
|---|
| 295 |
|
|---|
| 296 | //ожидание скачивания 2%
|
|---|
| 297 | while(!QFileInfo::exists(source) && m_downloadProgress < 0.02) {
|
|---|
| 298 | sleep(5);
|
|---|
| 299 | }
|
|---|
| 300 |
|
|---|
| 301 | //проверка на открытие - если данных недостатончно может не открыться
|
|---|
| 302 | while(avformat_open_input (&fmt_ctx, source, NULL, NULL) < 0)
|
|---|
| 303 | {
|
|---|
| 304 | qDebug() << "currentdir = "<<QDir::currentPath();
|
|---|
| 305 | fprintf (stderr, "could not open %s\n", source);
|
|---|
| 306 | sleep(5);
|
|---|
| 307 | }
|
|---|
| 308 |
|
|---|
| 309 | // find stream information
|
|---|
| 310 | if (avformat_find_stream_info (fmt_ctx, NULL) < 0)
|
|---|
| 311 | {
|
|---|
| 312 | fprintf (stderr, "could not find stream information\n");
|
|---|
| 313 | return 1;
|
|---|
| 314 | }
|
|---|
| 315 |
|
|---|
| 316 | qDebug() << "fmt_ctx->duration = "<<fmt_ctx->duration;
|
|---|
| 317 |
|
|---|
| 318 | for (int i=0; i<fmt_ctx->nb_streams; i++)
|
|---|
| 319 | {
|
|---|
| 320 | AVStream *in_stream = fmt_ctx->streams[i];
|
|---|
| 321 | AVCodecParameters *in_codecpar = in_stream->codecpar;
|
|---|
| 322 |
|
|---|
| 323 | if (in_codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
|
|---|
| 324 | {
|
|---|
| 325 | if(streamAudio) continue;
|
|---|
| 326 | streamAudio = fmt_ctx->streams[i];
|
|---|
| 327 | decoderAudio_ctx = streamAudio->codec;
|
|---|
| 328 | decoderAudio = avcodec_find_decoder(streamAudio->codec->codec_id);
|
|---|
| 329 | audio_stream_index = i;
|
|---|
| 330 |
|
|---|
| 331 | if (!decoderAudio) {
|
|---|
| 332 | qDebug("could not find audio decoder");
|
|---|
| 333 | return -1;
|
|---|
| 334 | }
|
|---|
| 335 |
|
|---|
| 336 | // open codec
|
|---|
| 337 | if ((ret = avcodec_open2 (decoderAudio_ctx, decoderAudio, NULL)) < 0) {
|
|---|
| 338 | qDebug("failed to open audio codec");
|
|---|
| 339 | return ret;
|
|---|
| 340 | }
|
|---|
| 341 | }
|
|---|
| 342 | else if (in_codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
|
|---|
| 343 | {
|
|---|
| 344 | // get decode
|
|---|
| 345 | if(streamVideo) continue;
|
|---|
| 346 | streamVideo = fmt_ctx->streams[i];
|
|---|
| 347 | decoderVideo_ctx = streamVideo->codec;
|
|---|
| 348 | decoderVideo = avcodec_find_decoder(decoderVideo_ctx->codec_id);
|
|---|
| 349 |
|
|---|
| 350 | video_stream_index = i;
|
|---|
| 351 |
|
|---|
| 352 | qDebug()<<"\n stream = "<<streamVideo;
|
|---|
| 353 | qDebug()<<"decoder_ctx = "<<decoderVideo_ctx;
|
|---|
| 354 | qDebug()<<"decoder " <<decoderVideo;
|
|---|
| 355 |
|
|---|
| 356 | if (!decoderVideo) {
|
|---|
| 357 | qDebug("could not find audio decoder");
|
|---|
| 358 | return -1;
|
|---|
| 359 | }
|
|---|
| 360 |
|
|---|
| 361 | // open codec
|
|---|
| 362 | if ((ret = avcodec_open2 (decoderVideo_ctx, decoderVideo, NULL)) < 0) {
|
|---|
| 363 | qDebug("failed to open video codec");
|
|---|
| 364 | return ret;
|
|---|
| 365 | }
|
|---|
| 366 | }
|
|---|
| 367 | }
|
|---|
| 368 |
|
|---|
| 369 | // createBufferInput(source);
|
|---|
| 370 | if(avio_ctx_input) fmt_ctx->pb = avio_ctx_input;
|
|---|
| 371 |
|
|---|
| 372 | // dump information to stderr
|
|---|
| 373 | av_dump_format (fmt_ctx, 0, source, 0);
|
|---|
| 374 |
|
|---|
| 375 | // allocate frame
|
|---|
| 376 | frame = av_frame_alloc ();
|
|---|
| 377 | if (!frame)
|
|---|
| 378 | {
|
|---|
| 379 | fprintf (stderr, "failed to allocate frame\n");
|
|---|
| 380 | return 1;
|
|---|
| 381 | }
|
|---|
| 382 |
|
|---|
| 383 | // init packet struct
|
|---|
| 384 | av_init_packet (&packet);
|
|---|
| 385 | packet.size = 0;
|
|---|
| 386 | packet.data = NULL;
|
|---|
| 387 |
|
|---|
| 388 | return 0;
|
|---|
| 389 | }
|
|---|
| 390 |
|
|---|
| 391 | bool Converter::createAudioEncoder()
|
|---|
| 392 | {
|
|---|
| 393 | encoderAudio = avcodec_find_encoder(AV_CODEC_ID_OPUS);
|
|---|
| 394 | if (!encoderAudio) qDebug("ERROR: could not create avcodec_find_encoder(AV_CODEC_ID_OPUS)");
|
|---|
| 395 |
|
|---|
| 396 | encoderAudio_ctx = avcodec_alloc_context3(encoderAudio);
|
|---|
| 397 | if(!encoderAudio_ctx) return false;
|
|---|
| 398 |
|
|---|
| 399 | out_stream_audio = avformat_new_stream (ofmt_ctx, encoderAudio);
|
|---|
| 400 | output_audio_stream_index = out_stream_audio->index;
|
|---|
| 401 |
|
|---|
| 402 | // if(decoderAudio_ctx->channels && !decoderAudio_ctx->channel_layout) {
|
|---|
| 403 | // decoderAudio_ctx->channel_layout = av_get_default_channel_layout(decoderAudio_ctx->channels);
|
|---|
| 404 | // }
|
|---|
| 405 |
|
|---|
| 406 | //opus fmt[0] = AV_SAMPLE_FMT_S16
|
|---|
| 407 | //opus fmt[1] = AV_SAMPLE_FMT_FLT
|
|---|
| 408 | encoderAudio_ctx->sample_fmt = encoderAudio->sample_fmts[0];
|
|---|
| 409 | encoderAudio_ctx->bit_rate = decoderAudio_ctx->bit_rate;
|
|---|
| 410 | encoderAudio_ctx->channel_layout = AV_CH_LAYOUT_STEREO;
|
|---|
| 411 | encoderAudio_ctx->channels = av_get_channel_layout_nb_channels(encoderAudio_ctx->channel_layout);
|
|---|
| 412 | encoderAudio_ctx->sample_rate = 48000;
|
|---|
| 413 |
|
|---|
| 414 | qDebug() << "decoderAudio_ctx->bit_rate =" << decoderAudio_ctx->bit_rate;
|
|---|
| 415 | qDebug() << "decoderAudio_ctx->sample_fmt =" << decoderAudio_ctx->sample_fmt;
|
|---|
| 416 | qDebug() << "decoderAudio_ctx->channel_layout =" << decoderAudio_ctx->channel_layout;
|
|---|
| 417 | qDebug() << "decoderAudio_ctx->channels =" << decoderAudio_ctx->channels;
|
|---|
| 418 | qDebug() << "decoderAudio_ctx->frame_size =" << decoderAudio_ctx->frame_size;
|
|---|
| 419 |
|
|---|
| 420 | qDebug() << "encoderAudio->bit_rate =" << encoderAudio_ctx->bit_rate;
|
|---|
| 421 | qDebug() << "encoderAudio->sample_fmt =" << encoderAudio_ctx->sample_fmt;
|
|---|
| 422 | qDebug() << "encoderAudio->channel_layout =" << encoderAudio_ctx->channel_layout;
|
|---|
| 423 | qDebug() << "encoderAudio->channels =" << encoderAudio_ctx->channels;
|
|---|
| 424 | qDebug() << "encoderAudio->frame_size =" << encoderAudio_ctx->frame_size;
|
|---|
| 425 |
|
|---|
| 426 |
|
|---|
| 427 |
|
|---|
| 428 | if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
|
|---|
| 429 | encoderAudio_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
|---|
| 430 |
|
|---|
| 431 | if (avcodec_open2 (encoderAudio_ctx, encoderAudio, nullptr) < 0)
|
|---|
| 432 | qDebug("could not open encoderAudio", 1);
|
|---|
| 433 |
|
|---|
| 434 | avcodec_parameters_from_context(out_stream_audio->codecpar, encoderAudio_ctx);
|
|---|
| 435 | hasAudio = true;
|
|---|
| 436 | return true;
|
|---|
| 437 | }
|
|---|
| 438 |
|
|---|
| 439 | bool Converter::createVideoEncoder()
|
|---|
| 440 | {
|
|---|
| 441 | encoderVideo = avcodec_find_encoder(AV_CODEC_ID_VP8);
|
|---|
| 442 | encoderVideo_ctx = avcodec_alloc_context3(encoderVideo);
|
|---|
| 443 | qDebug()<< "encoder_ctx=" << encoderVideo_ctx;
|
|---|
| 444 |
|
|---|
| 445 | out_stream_video = avformat_new_stream (ofmt_ctx, encoderVideo);
|
|---|
| 446 | if (!out_stream_video) qDebug("could not add new stream", 1);
|
|---|
| 447 |
|
|---|
| 448 | // out_stream_video->index = AVMEDIA_TYPE_VIDEO;
|
|---|
| 449 | output_video_stream_index = out_stream_video->index;
|
|---|
| 450 |
|
|---|
| 451 | // qDebug() << "encoder->id = "<< encoderVideo->id;
|
|---|
| 452 | // qDebug() << "out_stream->codecpar->codec_id = "<<out_stream_video->codecpar->codec_id;
|
|---|
| 453 |
|
|---|
| 454 | // encoder_ctx = out_stream->codec;
|
|---|
| 455 | encoderVideo_ctx->height = decoderVideo_ctx->height;
|
|---|
| 456 | encoderVideo_ctx->width = decoderVideo_ctx->width;
|
|---|
| 457 | encoderVideo_ctx->time_base = decoderVideo_ctx->time_base;
|
|---|
| 458 | encoderVideo_ctx->sample_aspect_ratio = decoderVideo_ctx->sample_aspect_ratio;
|
|---|
| 459 | encoderVideo_ctx->pix_fmt = encoderVideo->pix_fmts[0];
|
|---|
| 460 | encoderVideo_ctx->bit_rate = decoderVideo_ctx->bit_rate;
|
|---|
| 461 |
|
|---|
| 462 |
|
|---|
| 463 | // -deadline realtime -cpu-used -16
|
|---|
| 464 | AVDictionary *opt = NULL;
|
|---|
| 465 | // av_dict_set(&opt, "deadline", "realtime", 0);
|
|---|
| 466 | av_dict_set(&opt, "b:v", "", 0);
|
|---|
| 467 | //// av_dict_set(&opt, "c:v", "", 0); //constant bitrate
|
|---|
| 468 | av_dict_set(&opt, "crf", "20", 0); //0-63 - lower - better quality
|
|---|
| 469 | av_dict_set(&opt, "threads", "6", 0);
|
|---|
| 470 | av_dict_set(&opt, "cpu-used", "10", 0);
|
|---|
| 471 |
|
|---|
| 472 |
|
|---|
| 473 | // av_dict_set(&opt, "usetoc", "0", 0);
|
|---|
| 474 |
|
|---|
| 475 |
|
|---|
| 476 |
|
|---|
| 477 | if (avcodec_open2 (encoderVideo_ctx, encoderVideo, &opt) < 0)
|
|---|
| 478 | qDebug("could not open encoder", 1);
|
|---|
| 479 | av_dict_free(&opt);
|
|---|
| 480 |
|
|---|
| 481 |
|
|---|
| 482 | if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER) {
|
|---|
| 483 | encoderVideo_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
|---|
| 484 | }
|
|---|
| 485 |
|
|---|
| 486 | avcodec_parameters_from_context(out_stream_video->codecpar, encoderVideo_ctx);
|
|---|
| 487 | out_stream_video->time_base = streamVideo->time_base;
|
|---|
| 488 | hasVideo = true;
|
|---|
| 489 | return true;
|
|---|
| 490 | }
|
|---|
| 491 |
|
|---|
| 492 | /**
|
|---|
| 493 | * Open destination file for writing.
|
|---|
| 494 | */
|
|---|
| 495 | int Converter::open_destination (const char* destination)
|
|---|
| 496 | {
|
|---|
| 497 | avformat_alloc_output_context2 (&ofmt_ctx, NULL, NULL, destination);
|
|---|
| 498 | if (!ofmt_ctx) {
|
|---|
| 499 | qDebug("ERROR: could not open destination");
|
|---|
| 500 | return -1;
|
|---|
| 501 | }
|
|---|
| 502 |
|
|---|
| 503 | ofmt_ctx->duration = fmt_ctx->duration;
|
|---|
| 504 | ofmt_ctx->flags |= AVFMT_FLAG_NOBUFFER | AVFMT_FLAG_FLUSH_PACKETS | AVFMT_FLAG_CUSTOM_IO;
|
|---|
| 505 |
|
|---|
| 506 | av_dict_copy( &(ofmt_ctx->metadata), fmt_ctx->metadata, 0);
|
|---|
| 507 | av_dict_set( &(ofmt_ctx->metadata), "Author", "Kolomietc Vadim", 0 );
|
|---|
| 508 |
|
|---|
| 509 | qDebug() << "ofmt_ctx->duration = "<<ofmt_ctx->duration;
|
|---|
| 510 |
|
|---|
| 511 |
|
|---|
| 512 | if(video_stream_index>=0) createVideoEncoder();
|
|---|
| 513 | if(audio_stream_index>=0) createAudioEncoder();
|
|---|
| 514 |
|
|---|
| 515 | if(!hasVideo) {
|
|---|
| 516 | qDebug() << "Torrent haven't video so exit";
|
|---|
| 517 | // return -1;
|
|---|
| 518 | }
|
|---|
| 519 |
|
|---|
| 520 | av_dump_format (ofmt_ctx, 0, destination, 1);
|
|---|
| 521 | createBuffer();
|
|---|
| 522 |
|
|---|
| 523 | if(avio_ctx) {
|
|---|
| 524 | ofmt_ctx->pb = avio_ctx;
|
|---|
| 525 | // ofmt_ctx->flags |= AVFMT_FLAG_CUSTOM_IO;
|
|---|
| 526 | }
|
|---|
| 527 | else {
|
|---|
| 528 | if(avio_open (&ofmt_ctx->pb, destination, AVIO_FLAG_WRITE) < 0) {
|
|---|
| 529 | qDebug("could open file for writing");
|
|---|
| 530 | return -1;
|
|---|
| 531 | }
|
|---|
| 532 | }
|
|---|
| 533 |
|
|---|
| 534 | qDebug() << "ofmt_ctx->duration = "<<ofmt_ctx->duration;
|
|---|
| 535 |
|
|---|
| 536 | // Prepare resampling
|
|---|
| 537 | createSWR();
|
|---|
| 538 |
|
|---|
| 539 | if(avformat_write_header (ofmt_ctx, NULL) < 0) {
|
|---|
| 540 | qDebug("error writing header");
|
|---|
| 541 | return -1;
|
|---|
| 542 | }
|
|---|
| 543 |
|
|---|
| 544 | if(decoderAudio_ctx && encoderAudio_ctx) {
|
|---|
| 545 | printf("Input Code Ctx Frame size: %d\n", decoderAudio_ctx->frame_size);
|
|---|
| 546 | printf("Output Code Ctx Frame size: %d\n", encoderAudio_ctx->frame_size);
|
|---|
| 547 | }
|
|---|
| 548 |
|
|---|
| 549 | qDebug() << "ofmt_ctx->duration = "<<ofmt_ctx->duration;
|
|---|
| 550 | return 0;
|
|---|
| 551 | }
|
|---|
| 552 |
|
|---|
| 553 | void Converter::createStreamList() {
|
|---|
| 554 | //------------------------ Stream list ----------------------------
|
|---|
| 555 | int *stream_mapping = NULL;
|
|---|
| 556 | int stream_mapping_size = 0;
|
|---|
| 557 | stream_mapping_size = fmt_ctx->nb_streams;
|
|---|
| 558 | stream_mapping = (int*)av_mallocz_array(stream_mapping_size, sizeof(*stream_mapping));
|
|---|
| 559 | //-------------------------------------------------------------------
|
|---|
| 560 | }
|
|---|
| 561 |
|
|---|
| 562 | int Converter::encode(AVFrame *enc_frame, AVMediaType type)
|
|---|
| 563 | {
|
|---|
| 564 | int ret = 0;
|
|---|
| 565 |
|
|---|
| 566 | // qDebug() << "encode";
|
|---|
| 567 | if(enc_frame) {
|
|---|
| 568 | // logFile << "\n\n"<<"############ start encode ###########";
|
|---|
| 569 | // qDebug() << "\n"<<"encode frame.dts="<<enc_frame->pkt_dts <<"pts=" << enc_frame->pts;
|
|---|
| 570 | // logFile << "\n"<<"encode frame.nb_samples="<<enc_frame->nb_samples;
|
|---|
| 571 | }
|
|---|
| 572 |
|
|---|
| 573 | if(type == AVMEDIA_TYPE_AUDIO)
|
|---|
| 574 | {
|
|---|
| 575 | if(!hasAudio) return 0;
|
|---|
| 576 | // qDebug() << "\n"<<"encode audio frame.dts="<<enc_frame->pkt_dts <<"pts=" << enc_frame->pts;
|
|---|
| 577 |
|
|---|
| 578 | // AVPacket *enc_pkt = av_packet_alloc();
|
|---|
| 579 |
|
|---|
| 580 | if ((ret = avcodec_send_frame(encoderAudio_ctx, enc_frame)) < 0) {
|
|---|
| 581 | // qDebug()<< "\n"<< "Error during encoding ret" <<ret;
|
|---|
| 582 | return -1;
|
|---|
| 583 | }
|
|---|
| 584 | while (ret >=0) {
|
|---|
| 585 | av_init_packet(output_audio_packet);
|
|---|
| 586 | ret = avcodec_receive_packet(encoderAudio_ctx, output_audio_packet);
|
|---|
| 587 | if(ret < 0) break;
|
|---|
| 588 |
|
|---|
| 589 | output_audio_packet->stream_index = output_audio_stream_index;
|
|---|
| 590 | av_packet_rescale_ts(output_audio_packet, encoderAudio_ctx->time_base,
|
|---|
| 591 | out_stream_audio->time_base);
|
|---|
| 592 |
|
|---|
| 593 | // output_audio_packet->dts = output_audio_packet->pts;
|
|---|
| 594 |
|
|---|
| 595 | // logFile << "\n"<<"output_audio_packet->duration = " << output_audio_packet->duration;
|
|---|
| 596 | // qDebug() << "\n"<<"output_audio_packet->pts = " << output_audio_packet->pts;
|
|---|
| 597 | // qDebug() << "\n"<<"output_audio_packet->dts = " << output_audio_packet->dts;
|
|---|
| 598 |
|
|---|
| 599 | // Write packet to stream for muxing
|
|---|
| 600 | if(av_interleaved_write_frame(ofmt_ctx, output_audio_packet) < 0)
|
|---|
| 601 | qDebug("Could not write audio frame");
|
|---|
| 602 |
|
|---|
| 603 | av_packet_unref(output_audio_packet);
|
|---|
| 604 | }
|
|---|
| 605 | }
|
|---|
| 606 | else if(type == AVMEDIA_TYPE_VIDEO)
|
|---|
| 607 | {
|
|---|
| 608 | if(!hasVideo) return 0;
|
|---|
| 609 | // qDebug() << "\n"<<"encode video frame.dts="<<enc_frame->pkt_dts <<"pts=" << enc_frame->pts
|
|---|
| 610 | // <<"pkt_pts=" << enc_frame->pkt_pts << "duration="<<enc_frame->pkt_duration;
|
|---|
| 611 |
|
|---|
| 612 |
|
|---|
| 613 | AVPacket enc_pkt;
|
|---|
| 614 | av_init_packet(&enc_pkt);
|
|---|
| 615 | // enc_pkt.data = NULL;
|
|---|
| 616 | // enc_pkt.size = 0;
|
|---|
| 617 |
|
|---|
| 618 | // if(enc_frame->pts == AV_NOPTS_VALUE) {
|
|---|
| 619 | enc_pkt.dts = enc_frame->pkt_dts;
|
|---|
| 620 | enc_pkt.pts = enc_frame->pkt_dts;
|
|---|
| 621 | enc_frame->pts = enc_frame->pkt_dts;
|
|---|
| 622 | enc_frame->pkt_pts = enc_frame->pkt_dts;
|
|---|
| 623 |
|
|---|
| 624 | // }
|
|---|
| 625 | // qDebug() <<"encode video pakect.dts="<<enc_pkt.dts <<"pts=" << enc_pkt.pts;
|
|---|
| 626 |
|
|---|
| 627 | // if(enc_pkt.pts == 0 && enc_pkt.pts != enc_frame->pkt_pts)
|
|---|
| 628 | // enc_pkt.pts = enc_frame->pkt_pts;
|
|---|
| 629 | // if(enc_pkt.dts == 0 && enc_pkt.dts != enc_frame->pkt_dts)
|
|---|
| 630 | // enc_pkt.dts = enc_frame->pkt_dts;
|
|---|
| 631 |
|
|---|
| 632 |
|
|---|
| 633 | if ((ret = avcodec_send_frame(encoderVideo_ctx, enc_frame)) < 0) {
|
|---|
| 634 | qDebug()<< "Error during encoding";
|
|---|
| 635 | }
|
|---|
| 636 | while (1) {
|
|---|
| 637 | ret = avcodec_receive_packet(encoderVideo_ctx, &enc_pkt);
|
|---|
| 638 | if (ret == AVERROR(EAGAIN)) break;
|
|---|
| 639 | else if(ret < 0) break;
|
|---|
| 640 |
|
|---|
| 641 |
|
|---|
| 642 |
|
|---|
| 643 | // enc_pkt.stream_index = stream_mapping[pkt.stream_index];
|
|---|
| 644 | // qDebug()<<"enc_pkt.stream_index = "<<enc_pkt.stream_index;
|
|---|
| 645 | // AVStream *in_stream = fmt_ctx->streams[enc_pkt.stream_index];
|
|---|
| 646 | // enc_pkt.stream_index = output_video_stream_index;
|
|---|
| 647 | // av_packet_rescale_ts(&enc_pkt, out_stream->codec->time_base, out_stream->time_base);
|
|---|
| 648 |
|
|---|
| 649 |
|
|---|
| 650 | AVStream *inStream = fmt_ctx->streams[enc_pkt.stream_index];
|
|---|
| 651 | // av_packet_rescale_ts(&enc_pkt, encoderVideo_ctx->time_base, out_stream_video->time_base);
|
|---|
| 652 |
|
|---|
| 653 | enc_pkt.pts = av_rescale_q_rnd(enc_pkt.pts,
|
|---|
| 654 | streamVideo->time_base,
|
|---|
| 655 | out_stream_video->time_base,
|
|---|
| 656 | AVRounding(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
|
|---|
| 657 |
|
|---|
| 658 | enc_pkt.dts = av_rescale_q_rnd(enc_pkt.dts,
|
|---|
| 659 | streamVideo->time_base,
|
|---|
| 660 | out_stream_video->time_base,
|
|---|
| 661 | AVRounding(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
|
|---|
| 662 |
|
|---|
| 663 | // enc_pkt.duration = 1;
|
|---|
| 664 | enc_pkt.duration = av_rescale_q(enc_pkt.duration,
|
|---|
| 665 | streamVideo->time_base,
|
|---|
| 666 | out_stream_video->time_base);
|
|---|
| 667 |
|
|---|
| 668 | // qDebug() << "inStream->time_base="<< streamVideo->time_base.den << streamVideo->time_base.num;
|
|---|
| 669 | // qDebug() << "out_stream_video->time_base="<< out_stream_video->time_base.den << out_stream_video->time_base.num;
|
|---|
| 670 | // qDebug() << "enc_pkt.duration="<< enc_pkt.duration;
|
|---|
| 671 |
|
|---|
| 672 | // qDebug() << "\n"<<"video dts=" <<enc_pkt.dts;
|
|---|
| 673 | // logFile << "\n"<<"video pts=" <<enc_pkt.pts;
|
|---|
| 674 | // enc_pkt.pos = -1;
|
|---|
| 675 |
|
|---|
| 676 | av_interleaved_write_frame(ofmt_ctx, &enc_pkt);
|
|---|
| 677 | // av_packet_unref(&enc_pkt);
|
|---|
| 678 | }
|
|---|
| 679 | }
|
|---|
| 680 |
|
|---|
| 681 | return 0;
|
|---|
| 682 | }
|
|---|
| 683 |
|
|---|
| 684 | void Converter::flushVideo()
|
|---|
| 685 | {
|
|---|
| 686 | qDebug() << "FLUSH VIDEO!!!!!!!!!!";
|
|---|
| 687 | if(!hasVideo) return;
|
|---|
| 688 | int ret = avcodec_send_packet(decoderVideo_ctx, NULL);
|
|---|
| 689 | if (ret < 0) {
|
|---|
| 690 | fprintf(stderr, "Error sending a packet for decoding\n");
|
|---|
| 691 | if (ret < 0) fprintf(stderr, "Error during decoding\n");
|
|---|
| 692 |
|
|---|
| 693 | return;
|
|---|
| 694 | }
|
|---|
| 695 |
|
|---|
| 696 | qDebug()<<"avcodec_send_packet" << ret;
|
|---|
| 697 |
|
|---|
| 698 | AVFrame *frame;
|
|---|
| 699 | while (ret >= 0) {
|
|---|
| 700 | if (!(frame = av_frame_alloc())) {
|
|---|
| 701 | qDebug() << "Error av_frame_alloc";
|
|---|
| 702 | return;
|
|---|
| 703 | }
|
|---|
| 704 | qDebug()<<"avcodec_receive_frame start";
|
|---|
| 705 | ret = avcodec_receive_frame(decoderVideo_ctx, frame);
|
|---|
| 706 | qDebug()<<"avcodec_receive_frame "<<ret;
|
|---|
| 707 | if (ret < 0) fprintf(stderr, "Error during decoding\n");
|
|---|
| 708 | encode(frame, AVMEDIA_TYPE_VIDEO);
|
|---|
| 709 | av_frame_free(&frame);
|
|---|
| 710 | }
|
|---|
| 711 |
|
|---|
| 712 | // encode(NULL, AVMEDIA_TYPE_VIDEO);
|
|---|
| 713 | }
|
|---|
| 714 |
|
|---|
| 715 | void Converter::flushAudio(long audio_pts)
|
|---|
| 716 | {
|
|---|
| 717 | if(!hasAudio) return;
|
|---|
| 718 | logFile << "\n ##################### flushAudio #######################";
|
|---|
| 719 | int ret = 0;
|
|---|
| 720 |
|
|---|
| 721 | if((ret = avcodec_send_packet(decoderAudio_ctx, NULL)) < 0) {
|
|---|
| 722 | qDebug()<< "reading_input=false Error sending a packet for decoding ret =" << ret;
|
|---|
| 723 | return;
|
|---|
| 724 | }
|
|---|
| 725 |
|
|---|
| 726 | AVFrame *frame;
|
|---|
| 727 | frame = av_frame_alloc();
|
|---|
| 728 | if(!frame) {
|
|---|
| 729 | qDebug()<<"\n"<<"Error av_frame_alloc";
|
|---|
| 730 | return;
|
|---|
| 731 | }
|
|---|
| 732 |
|
|---|
| 733 | bool receiveFrame = true;
|
|---|
| 734 | while(receiveFrame) {
|
|---|
| 735 | receiveFrame = (avcodec_receive_frame(decoderAudio_ctx, frame) >= 0);
|
|---|
| 736 | if(swrContext) {
|
|---|
| 737 | output_audio_frame->nb_samples = encoderAudio_ctx->frame_size;
|
|---|
| 738 | int64_t delay = swr_get_delay(swrContext, encoderAudio_ctx->sample_rate);
|
|---|
| 739 | qDebug() << "delay = "<<delay;
|
|---|
| 740 | if(delay > 0) {
|
|---|
| 741 | swr_convert_frame(swrContext, output_audio_frame, NULL);
|
|---|
| 742 | output_audio_frame->pts = audio_pts;
|
|---|
| 743 | audio_pts += output_audio_frame->nb_samples;
|
|---|
| 744 | encode(output_audio_frame, AVMEDIA_TYPE_AUDIO);
|
|---|
| 745 | }
|
|---|
| 746 | }
|
|---|
| 747 | }
|
|---|
| 748 | }
|
|---|
| 749 |
|
|---|
| 750 |
|
|---|
| 751 | /**
|
|---|
| 752 | * Transcode the stream.
|
|---|
| 753 | * Takes a function pointer to a store function.
|
|---|
| 754 | */
|
|---|
| 755 | void Converter::transcode()
|
|---|
| 756 | {
|
|---|
| 757 | long audio_pts = 0;
|
|---|
| 758 | int frame_count = 0;
|
|---|
| 759 | int ret = 0;
|
|---|
| 760 | // start transcoding
|
|---|
| 761 | qint64 fullSize = 0;
|
|---|
| 762 |
|
|---|
| 763 | qint64 fullDelay = 0;
|
|---|
| 764 |
|
|---|
| 765 | bool reading_input = true;
|
|---|
| 766 |
|
|---|
| 767 | while(reading_input)
|
|---|
| 768 | {
|
|---|
| 769 | if(m_handle) {
|
|---|
| 770 | const bool blocksFinished = m_handle->checkBlockRangeDownloaded(fmt_ctx->pb->pos, fmt_ctx->pb->buffer_size);
|
|---|
| 771 | if(blocksFinished == false) {
|
|---|
| 772 | qDebug() << "\n\n\n BLOCK NOT FINISHED WAIT BLOCK!";
|
|---|
| 773 | sleep(5);
|
|---|
| 774 | continue;
|
|---|
| 775 | }
|
|---|
| 776 | }
|
|---|
| 777 |
|
|---|
| 778 | // qDebug() << "check range PASSED";
|
|---|
| 779 |
|
|---|
| 780 | // if(fmt_ctx->pb->pos + fmt_ctx->pb->buffer_size >= m_bytesReceived)
|
|---|
| 781 | // {
|
|---|
| 782 | // sleep(5);
|
|---|
| 783 | // continue;
|
|---|
| 784 | // }
|
|---|
| 785 |
|
|---|
| 786 | // qDebug() << "check bytes PASSED";
|
|---|
| 787 |
|
|---|
| 788 |
|
|---|
| 789 |
|
|---|
| 790 | // qDebug() << "m_bytesReceived=" << m_bytesReceived
|
|---|
| 791 | // << "m_bytesTotal=" << m_bytesTotal
|
|---|
| 792 | // << "pos=" << fmt_ctx->pb->pos
|
|---|
| 793 | // << "buffer_size=" << fmt_ctx->pb->buffer_size;
|
|---|
| 794 | // qDebug() << "run m_downloadProgress="<<m_downloadProgress;
|
|---|
| 795 |
|
|---|
| 796 | const int readFrameResult = av_read_frame(fmt_ctx, &packet);
|
|---|
| 797 | reading_input = (readFrameResult >= 0);
|
|---|
| 798 | if(!reading_input && m_downloadProgress < 1.0) {
|
|---|
| 799 | if(readFrameResult == AVERROR(EAGAIN)) qDebug() << "av_read_frame EAGAIN";
|
|---|
| 800 | else if(readFrameResult == AVERROR_EOF) {
|
|---|
| 801 | qDebug() << "av_read_frame AVERROR_EOF";
|
|---|
| 802 | }
|
|---|
| 803 | else qDebug() << "av_read_frame UNKNOWN";
|
|---|
| 804 |
|
|---|
| 805 | reading_input = true;
|
|---|
| 806 | sleep(5);
|
|---|
| 807 | // av_usleep(5000);
|
|---|
| 808 | continue;
|
|---|
| 809 | }
|
|---|
| 810 |
|
|---|
| 811 | // if(packet.size <= 0) {
|
|---|
| 812 | // qDebug() << "packet.size == 0";
|
|---|
| 813 | // reading_input = true;
|
|---|
| 814 | // av_packet_unref(&packet);
|
|---|
| 815 | // sleep(5);
|
|---|
| 816 | // continue;
|
|---|
| 817 | // }
|
|---|
| 818 |
|
|---|
| 819 | if(packet.stream_index >= fmt_ctx->nb_streams) {
|
|---|
| 820 | av_packet_unref(&packet);
|
|---|
| 821 | continue;
|
|---|
| 822 | }
|
|---|
| 823 |
|
|---|
| 824 | AVCodecParameters *out_codecpar = fmt_ctx->streams[packet.stream_index]->codecpar;
|
|---|
| 825 | if (out_codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
|
|---|
| 826 | {
|
|---|
| 827 | if(!hasAudio) continue;
|
|---|
| 828 | if(audio_stream_index != packet.stream_index) continue;
|
|---|
| 829 | if((ret = avcodec_send_packet(decoderAudio_ctx, &packet)) < 0) {
|
|---|
| 830 | qDebug() << "reading_input=true Error sending a audio packet for decoding ret = "<<ret;
|
|---|
| 831 | fprintf(stderr, "\n");
|
|---|
| 832 | av_packet_unref(&packet);
|
|---|
| 833 | continue;
|
|---|
| 834 | }
|
|---|
| 835 |
|
|---|
| 836 | AVFrame *frame = av_frame_alloc();
|
|---|
| 837 | if(!frame) {
|
|---|
| 838 | qDebug()<<"\n"<<"Error av_frame_alloc";
|
|---|
| 839 | av_frame_free(&frame);
|
|---|
| 840 | av_packet_unref(&packet);
|
|---|
| 841 | continue;
|
|---|
| 842 | }
|
|---|
| 843 |
|
|---|
| 844 | while ( avcodec_receive_frame(decoderAudio_ctx, frame) >= 0) {
|
|---|
| 845 | // qDebug() << "frame->pts =" << frame->pts;
|
|---|
| 846 | // qDebug() << "frame->data =" << frame->data;
|
|---|
| 847 | // qDebug() << "frame->format =" << frame->format;
|
|---|
| 848 | // qDebug() << "frame->pkt_dts =" << frame->pkt_dts;
|
|---|
| 849 | // qDebug() << "frame->sample_rate =" << frame->sample_rate;
|
|---|
| 850 | // qDebug() << "frame->nb_samples =" << frame->nb_samples;
|
|---|
| 851 |
|
|---|
| 852 | if(swrContext) {
|
|---|
| 853 | output_audio_frame->nb_samples = encoderAudio_ctx->frame_size;
|
|---|
| 854 | int64_t delay = swr_get_delay(swrContext, encoderAudio_ctx->sample_rate);
|
|---|
| 855 | swr_convert_frame(swrContext, output_audio_frame, frame);
|
|---|
| 856 | output_audio_frame->pts = audio_pts;
|
|---|
| 857 | audio_pts += output_audio_frame->nb_samples;
|
|---|
| 858 |
|
|---|
| 859 | fullDelay += delay;
|
|---|
| 860 | // logFile << "\n delay ="<< delay;
|
|---|
| 861 | encode(output_audio_frame, out_codecpar->codec_type);
|
|---|
| 862 |
|
|---|
| 863 | if(delay >= 960) {
|
|---|
| 864 | swr_convert_frame(swrContext, output_audio_frame, NULL);
|
|---|
| 865 | output_audio_frame->pts = audio_pts;
|
|---|
| 866 | audio_pts += output_audio_frame->nb_samples;
|
|---|
| 867 | encode(output_audio_frame, out_codecpar->codec_type);
|
|---|
| 868 | }
|
|---|
| 869 | }
|
|---|
| 870 | }
|
|---|
| 871 | av_frame_free(&frame);
|
|---|
| 872 | }
|
|---|
| 873 | else if(out_codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
|
|---|
| 874 | {
|
|---|
| 875 | if(!hasVideo) continue;
|
|---|
| 876 | if(video_stream_index != packet.stream_index) continue;
|
|---|
| 877 |
|
|---|
| 878 |
|
|---|
| 879 | // qDebug() << "packet.duration="<< packet.duration;
|
|---|
| 880 |
|
|---|
| 881 | ret = avcodec_send_packet(decoderVideo_ctx, &packet);
|
|---|
| 882 | if (ret < 0) {
|
|---|
| 883 | qDebug() << "Error sending a video packet for decoding" << ret;
|
|---|
| 884 | // av_packet_unref(&packet);
|
|---|
| 885 | continue;
|
|---|
| 886 | }
|
|---|
| 887 | // qDebug() << "packet.duration="<< packet.duration;
|
|---|
| 888 |
|
|---|
| 889 | AVFrame *frame;
|
|---|
| 890 | while (ret >= 0) {
|
|---|
| 891 | if (!(frame = av_frame_alloc())) {
|
|---|
| 892 | qDebug() << "Error av_frame_alloc";
|
|---|
| 893 | return;
|
|---|
| 894 | }
|
|---|
| 895 | ret = avcodec_receive_frame(decoderVideo_ctx, frame);
|
|---|
| 896 | if (ret < 0) {
|
|---|
| 897 | // if(ret == AVERROR(EAGAIN)) qDebug() << "Error during decoding EAGAIN";
|
|---|
| 898 | // else if(ret == AVERROR_EOF) qDebug() << "Error during decoding AVERROR_EOF";
|
|---|
| 899 | // else qDebug() << "Error during decoding UNKNOWN";
|
|---|
| 900 |
|
|---|
| 901 | av_frame_free(&frame);
|
|---|
| 902 | break;
|
|---|
| 903 | }
|
|---|
| 904 | encode(frame, out_codecpar->codec_type);
|
|---|
| 905 | av_frame_free(&frame);
|
|---|
| 906 | }
|
|---|
| 907 |
|
|---|
| 908 | // qDebug() << "end transcode packet";
|
|---|
| 909 | }
|
|---|
| 910 | av_packet_unref(&packet);
|
|---|
| 911 | }
|
|---|
| 912 |
|
|---|
| 913 |
|
|---|
| 914 | // flushAudio(audio_pts);
|
|---|
| 915 | // flushVideo();
|
|---|
| 916 |
|
|---|
| 917 | av_write_trailer(ofmt_ctx);
|
|---|
| 918 | qDebug() << "RESULT fullSize= "<< fullSize;
|
|---|
| 919 | }
|
|---|